(function (g, f) {
    if ("object" == typeof exports && "object" == typeof module) {
      module.exports = f();
    } else if ("function" == typeof define && define.amd) {
      define("agCharts", [], f);
    } else if ("object" == typeof exports) {
      exports["agCharts"] = f();
    } else {
      g["agCharts"] = f();
    }
  }(this, () => {
var exports = {};
var module = { exports };
if (typeof require === 'undefined') {
    function require(name) {
        
        throw new Error('Unknown module: ' + name);
    }
}
        
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from3, except, desc) => {
  if (from3 && typeof from3 === "object" || typeof from3 === "function") {
    for (let key of __getOwnPropNames(from3))
      if (!__hasOwnProp.call(to, key) && key !== except)
        __defProp(to, key, { get: () => from3[key], enumerable: !(desc = __getOwnPropDesc(from3, key)) || desc.enumerable });
  }
  return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __decorateClass = (decorators, target, key, kind) => {
  var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
  for (var i = decorators.length - 1, decorator; i >= 0; i--)
    if (decorator = decorators[i])
      result = (kind ? decorator(target, key, result) : decorator(result)) || result;
  if (kind && result)
    __defProp(target, key, result);
  return result;
};

// packages/ag-charts-enterprise/src/main-umd.ts
var main_umd_exports = {};
__export(main_umd_exports, {
  AG_CHARTS_LOCALE_EN_US: () => AG_CHARTS_LOCALE_EN_US,
  AgCharts: () => AgCharts,
  AgChartsCommunityModule: () => AgChartsCommunityModule,
  AgChartsEnterpriseModule: () => AgChartsEnterpriseModule,
  AgTooltipAnchorToType: () => AgTooltipAnchorToType,
  AgTooltipPlacementType: () => AgTooltipPlacementType,
  AllCartesianAxesModule: () => AllCartesianAxesModule2,
  AllCartesianModule: () => AllCartesianModule2,
  AllCartesianSeriesModule: () => AllCartesianSeriesModule2,
  AllCommunityModule: () => AllCommunityModule,
  AllEnterpriseModule: () => AllEnterpriseModule,
  AllGaugeModule: () => AllGaugeModule,
  AllMapSeriesModule: () => AllMapSeriesModule,
  AllPolarModule: () => AllPolarModule2,
  AngleCategoryAxisModule: () => AngleCategoryAxisModule,
  AngleNumberAxisModule: () => AngleNumberAxisModule,
  AnimationModule: () => AnimationModule,
  AnnotationsModule: () => AnnotationsModule,
  AreaSeriesModule: () => AreaSeriesModule,
  BandHighlightModule: () => BandHighlightModule,
  BarSeriesModule: () => BarSeriesModule,
  BoxPlotSeriesModule: () => BoxPlotSeriesModule,
  BubbleSeriesModule: () => BubbleSeriesModule,
  CandlestickSeriesModule: () => CandlestickSeriesModule,
  CartesianChartModule: () => CartesianChartModule,
  CategoryAxisModule: () => CategoryAxisModule,
  ChartToolbarModule: () => ChartToolbarModule,
  ChordSeriesModule: () => ChordSeriesModule,
  ConeFunnelSeriesModule: () => ConeFunnelSeriesModule,
  ContextMenuModule: () => ContextMenuModule,
  CrosshairModule: () => CrosshairModule,
  DataSourceModule: () => DataSourceModule,
  DonutSeriesModule: () => DonutSeriesModule,
  ErrorBarsModule: () => ErrorBarsModule,
  FinancialChartModule: () => FinancialChartModule,
  FlashOnUpdateModule: () => FlashOnUpdateModule,
  FunnelSeriesModule: () => FunnelSeriesModule,
  GradientLegendModule: () => GradientLegendModule,
  GroupedCategoryAxisModule: () => GroupedCategoryAxisModule,
  HeatmapSeriesModule: () => HeatmapSeriesModule,
  HistogramSeriesModule: () => HistogramSeriesModule,
  LegendModule: () => LegendModule,
  LicenseManager: () => LicenseManager2,
  LineSeriesModule: () => LineSeriesModule,
  LinearGaugeModule: () => LinearGaugeModule,
  LocaleModule: () => LocaleModule,
  LogAxisModule: () => LogAxisModule,
  MapLineBackgroundSeriesModule: () => MapLineBackgroundSeriesModule,
  MapLineSeriesModule: () => MapLineSeriesModule,
  MapMarkerSeriesModule: () => MapMarkerSeriesModule,
  MapShapeBackgroundSeriesModule: () => MapShapeBackgroundSeriesModule,
  MapShapeSeriesModule: () => MapShapeSeriesModule,
  ModuleRegistry: () => moduleRegistry_exports,
  NavigatorModule: () => NavigatorModule,
  NightingaleSeriesModule: () => NightingaleSeriesModule,
  NumberAxisModule: () => NumberAxisModule,
  OhlcSeriesModule: () => OhlcSeriesModule,
  OrdinalTimeAxisModule: () => OrdinalTimeAxisModule,
  PieSeriesModule: () => PieSeriesModule,
  PolarChartModule: () => PolarChartModule,
  PyramidSeriesModule: () => PyramidSeriesModule,
  RadarAreaSeriesModule: () => RadarAreaSeriesModule,
  RadarLineSeriesModule: () => RadarLineSeriesModule,
  RadialBarSeriesModule: () => RadialBarSeriesModule,
  RadialColumnSeriesModule: () => RadialColumnSeriesModule,
  RadialGaugeModule: () => RadialGaugeModule,
  RadiusCategoryAxisModule: () => RadiusCategoryAxisModule,
  RadiusNumberAxisModule: () => RadiusNumberAxisModule,
  RangeAreaSeriesModule: () => RangeAreaSeriesModule,
  RangeBarSeriesModule: () => RangeBarSeriesModule,
  RangesModule: () => RangesModule,
  SankeySeriesModule: () => SankeySeriesModule,
  ScatterSeriesModule: () => ScatterSeriesModule,
  ScrollbarModule: () => ScrollbarModule,
  SparklinePresetModule: () => SparklinePresetModule,
  StatusBarModule: () => StatusBarModule,
  SunburstSeriesModule: () => SunburstSeriesModule,
  SyncModule: () => SyncModule,
  TimeAxisModule: () => TimeAxisModule,
  TreemapSeriesModule: () => TreemapSeriesModule,
  UnitTimeAxisModule: () => UnitTimeAxisModule,
  VERSION: () => VERSION,
  WaterfallSeriesModule: () => WaterfallSeriesModule,
  ZoomModule: () => ZoomModule,
  _ModuleSupport: () => module_support_exports,
  _Scene: () => integrated_charts_scene_exports,
  _Theme: () => integrated_charts_theme_exports,
  _Util: () => integrated_charts_util_exports,
  _Widget: () => exports_exports,
  time: () => time
});
module.exports = __toCommonJS(main_umd_exports);

// packages/ag-charts-core/src/main.ts
var main_exports = {};
__export(main_exports, {
  AGGREGATION_INDEX_UNSET: () => AGGREGATION_INDEX_UNSET,
  AGGREGATION_INDEX_X_MAX: () => AGGREGATION_INDEX_X_MAX,
  AGGREGATION_INDEX_X_MIN: () => AGGREGATION_INDEX_X_MIN,
  AGGREGATION_INDEX_Y_MAX: () => AGGREGATION_INDEX_Y_MAX,
  AGGREGATION_INDEX_Y_MIN: () => AGGREGATION_INDEX_Y_MIN,
  AGGREGATION_MAX_POINTS: () => AGGREGATION_MAX_POINTS,
  AGGREGATION_MIN_RANGE: () => AGGREGATION_MIN_RANGE,
  AGGREGATION_SPAN: () => AGGREGATION_SPAN,
  AGGREGATION_THRESHOLD: () => AGGREGATION_THRESHOLD,
  AbstractModuleInstance: () => AbstractModuleInstance,
  ActionOnSet: () => ActionOnSet,
  AdjacencyListGraph: () => AdjacencyListGraph,
  AsyncAwaitQueue: () => AsyncAwaitQueue,
  BASE_FONT_SIZE: () => BASE_FONT_SIZE,
  BREAK_TRANSFORM_CHAIN: () => BREAK_TRANSFORM_CHAIN,
  BaseProperties: () => BaseProperties,
  Border: () => Border,
  CANVAS_HEIGHT: () => CANVAS_HEIGHT,
  CANVAS_TO_BUFFER_DEFAULTS: () => CANVAS_TO_BUFFER_DEFAULTS,
  CANVAS_WIDTH: () => CANVAS_WIDTH,
  CARTESIAN_AXIS_TYPE: () => CARTESIAN_AXIS_TYPE,
  CARTESIAN_POSITION: () => CARTESIAN_POSITION,
  CallbackCache: () => CallbackCache,
  ChangeDetectableProperties: () => ChangeDetectableProperties,
  ChartAxisDirection: () => ChartAxisDirection,
  ChartUpdateType: () => ChartUpdateType,
  CleanupRegistry: () => CleanupRegistry,
  Color: () => Color,
  ConfiguredCanvasMixin: () => ConfiguredCanvasMixin,
  DEFAULT_ANNOTATION_HANDLE_FILL: () => DEFAULT_ANNOTATION_HANDLE_FILL,
  DEFAULT_ANNOTATION_STATISTICS_COLOR: () => DEFAULT_ANNOTATION_STATISTICS_COLOR,
  DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE: () => DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE,
  DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL: () => DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL,
  DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE: () => DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE,
  DEFAULT_ANNOTATION_STATISTICS_FILL: () => DEFAULT_ANNOTATION_STATISTICS_FILL,
  DEFAULT_ANNOTATION_STATISTICS_STROKE: () => DEFAULT_ANNOTATION_STATISTICS_STROKE,
  DEFAULT_CAPTION_ALIGNMENT: () => DEFAULT_CAPTION_ALIGNMENT,
  DEFAULT_CAPTION_LAYOUT_STYLE: () => DEFAULT_CAPTION_LAYOUT_STYLE,
  DEFAULT_FIBONACCI_STROKES: () => DEFAULT_FIBONACCI_STROKES,
  DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL: () => DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL,
  DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR: () => DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR,
  DEFAULT_POLAR_SERIES_STROKE: () => DEFAULT_POLAR_SERIES_STROKE,
  DEFAULT_SHADOW_COLOUR: () => DEFAULT_SHADOW_COLOUR,
  DEFAULT_SPARKLINE_CROSSHAIR_STROKE: () => DEFAULT_SPARKLINE_CROSSHAIR_STROKE,
  DEFAULT_TEXTBOX_COLOR: () => DEFAULT_TEXTBOX_COLOR,
  DEFAULT_TEXTBOX_FILL: () => DEFAULT_TEXTBOX_FILL,
  DEFAULT_TEXTBOX_STROKE: () => DEFAULT_TEXTBOX_STROKE,
  DEFAULT_TEXT_ANNOTATION_COLOR: () => DEFAULT_TEXT_ANNOTATION_COLOR,
  DEFAULT_TOOLBAR_POSITION: () => DEFAULT_TOOLBAR_POSITION,
  DIRECTION_SWAP_AXES: () => DIRECTION_SWAP_AXES,
  Debug: () => debugLogger_exports,
  DebugMetrics: () => debugMetrics_exports,
  DeclaredSceneChangeDetection: () => DeclaredSceneChangeDetection,
  DeclaredSceneObjectChangeDetection: () => DeclaredSceneObjectChangeDetection,
  Deprecated: () => Deprecated,
  DeprecatedAndRenamedTo: () => DeprecatedAndRenamedTo,
  EllipsisChar: () => EllipsisChar,
  ErrorType: () => ErrorType,
  EventEmitter: () => EventEmitter,
  FILL_GRADIENT_BLANK_DEFAULTS: () => FILL_GRADIENT_BLANK_DEFAULTS,
  FILL_GRADIENT_CONIC_SERIES_DEFAULTS: () => FILL_GRADIENT_CONIC_SERIES_DEFAULTS,
  FILL_GRADIENT_LINEAR_DEFAULTS: () => FILL_GRADIENT_LINEAR_DEFAULTS,
  FILL_GRADIENT_LINEAR_HIERARCHY_DEFAULTS: () => FILL_GRADIENT_LINEAR_HIERARCHY_DEFAULTS,
  FILL_GRADIENT_LINEAR_KEYED_DEFAULTS: () => FILL_GRADIENT_LINEAR_KEYED_DEFAULTS,
  FILL_GRADIENT_LINEAR_SINGLE_DEFAULTS: () => FILL_GRADIENT_LINEAR_SINGLE_DEFAULTS,
  FILL_GRADIENT_RADIAL_DEFAULTS: () => FILL_GRADIENT_RADIAL_DEFAULTS,
  FILL_GRADIENT_RADIAL_REVERSED_DEFAULTS: () => FILL_GRADIENT_RADIAL_REVERSED_DEFAULTS,
  FILL_GRADIENT_RADIAL_REVERSED_SERIES_DEFAULTS: () => FILL_GRADIENT_RADIAL_REVERSED_SERIES_DEFAULTS,
  FILL_GRADIENT_RADIAL_SERIES_DEFAULTS: () => FILL_GRADIENT_RADIAL_SERIES_DEFAULTS,
  FILL_IMAGE_BLANK_DEFAULTS: () => FILL_IMAGE_BLANK_DEFAULTS,
  FILL_IMAGE_DEFAULTS: () => FILL_IMAGE_DEFAULTS,
  FILL_PATTERN_BLANK_DEFAULTS: () => FILL_PATTERN_BLANK_DEFAULTS,
  FILL_PATTERN_DEFAULTS: () => FILL_PATTERN_DEFAULTS,
  FILL_PATTERN_HIERARCHY_DEFAULTS: () => FILL_PATTERN_HIERARCHY_DEFAULTS,
  FILL_PATTERN_KEYED_DEFAULTS: () => FILL_PATTERN_KEYED_DEFAULTS,
  FILL_PATTERN_SINGLE_DEFAULTS: () => FILL_PATTERN_SINGLE_DEFAULTS,
  FONT_SIZE: () => FONT_SIZE,
  FONT_SIZE_RATIO: () => FONT_SIZE_RATIO,
  IS_DARK_THEME: () => IS_DARK_THEME,
  InterpolationProperties: () => InterpolationProperties,
  LABEL_BOXING_DEFAULTS: () => LABEL_BOXING_DEFAULTS,
  LEGEND_CONTAINER_THEME: () => LEGEND_CONTAINER_THEME,
  LRUCache: () => LRUCache,
  LineSplitter: () => LineSplitter,
  Logger: () => logger_exports,
  MARKER_SERIES_HIGHLIGHT_STYLE: () => MARKER_SERIES_HIGHLIGHT_STYLE,
  MULTI_SERIES_HIGHLIGHT_STYLE: () => MULTI_SERIES_HIGHLIGHT_STYLE,
  MementoCaretaker: () => MementoCaretaker,
  ModuleRegistry: () => moduleRegistry_exports,
  ModuleType: () => ModuleType,
  ObserveChanges: () => ObserveChanges,
  PALETTE_ALT_DOWN_FILL: () => PALETTE_ALT_DOWN_FILL,
  PALETTE_ALT_DOWN_STROKE: () => PALETTE_ALT_DOWN_STROKE,
  PALETTE_ALT_NEUTRAL_FILL: () => PALETTE_ALT_NEUTRAL_FILL,
  PALETTE_ALT_NEUTRAL_STROKE: () => PALETTE_ALT_NEUTRAL_STROKE,
  PALETTE_ALT_UP_FILL: () => PALETTE_ALT_UP_FILL,
  PALETTE_ALT_UP_STROKE: () => PALETTE_ALT_UP_STROKE,
  PALETTE_DOWN_FILL: () => PALETTE_DOWN_FILL,
  PALETTE_DOWN_STROKE: () => PALETTE_DOWN_STROKE,
  PALETTE_NEUTRAL_FILL: () => PALETTE_NEUTRAL_FILL,
  PALETTE_NEUTRAL_STROKE: () => PALETTE_NEUTRAL_STROKE,
  PALETTE_UP_FILL: () => PALETTE_UP_FILL,
  PALETTE_UP_STROKE: () => PALETTE_UP_STROKE,
  PART_WHOLE_HIGHLIGHT_STYLE: () => PART_WHOLE_HIGHLIGHT_STYLE,
  POLAR_AXIS_SHAPE: () => POLAR_AXIS_SHAPE,
  POLAR_AXIS_TYPE: () => POLAR_AXIS_TYPE,
  PREV_NEXT_KEYS: () => PREV_NEXT_KEYS,
  Padding: () => Padding,
  ParallelStateMachine: () => ParallelStateMachine,
  PolarZIndexMap: () => PolarZIndexMap,
  PropertiesArray: () => PropertiesArray,
  Property: () => addFakeTransformToInstanceProperty,
  ProxyOnWrite: () => ProxyOnWrite,
  ProxyProperty: () => ProxyProperty,
  ProxyPropertyOnWrite: () => ProxyPropertyOnWrite,
  SAFE_FILLS_OPERATION: () => SAFE_FILLS_OPERATION,
  SAFE_FILL_OPERATION: () => SAFE_FILL_OPERATION,
  SAFE_RANGE2_OPERATION: () => SAFE_RANGE2_OPERATION,
  SAFE_STROKE_FILL_OPERATION: () => SAFE_STROKE_FILL_OPERATION,
  SEGMENTATION_DEFAULTS: () => SEGMENTATION_DEFAULTS,
  SINGLE_SERIES_HIGHLIGHT_STYLE: () => SINGLE_SERIES_HIGHLIGHT_STYLE,
  SKIP_JS_BUILTINS: () => SKIP_JS_BUILTINS,
  ScaleAlignment: () => ScaleAlignment,
  SceneArrayChangeDetection: () => SceneArrayChangeDetection,
  SceneChangeDetection: () => SceneChangeDetection,
  SceneObjectChangeDetection: () => SceneObjectChangeDetection,
  SceneRefChangeDetection: () => SceneRefChangeDetection,
  SeriesContentZIndexMap: () => SeriesContentZIndexMap,
  SeriesZIndexMap: () => SeriesZIndexMap,
  SimpleCache: () => SimpleCache,
  SpanJoin: () => SpanJoin,
  StateMachine: () => StateMachine,
  StateMachineProperty: () => StateMachineProperty,
  TRIPLE_EQ: () => TRIPLE_EQ,
  TextMeasurer: () => TextMeasurer,
  TickIntervals: () => TickIntervals,
  TrimCharsRegex: () => TrimCharsRegex,
  TrimEdgeGuard: () => TrimEdgeGuard,
  UNIT_MAX: () => UNIT_MAX,
  UNIT_MIN: () => UNIT_MIN,
  UnknownError: () => UnknownError,
  ValidationError: () => ValidationError,
  Vec2: () => vector_exports,
  Vec4: () => vector4_exports,
  Vertex: () => Vertex,
  WeakCache: () => WeakCache,
  ZIndexMap: () => ZIndexMap,
  addEscapeEventListener: () => addEscapeEventListener,
  addFakeTransformToInstanceProperty: () => addFakeTransformToInstanceProperty,
  addMouseCloseListener: () => addMouseCloseListener,
  addObserverToInstanceProperty: () => addObserverToInstanceProperty,
  addOverrideFocusVisibleEventListener: () => addOverrideFocusVisibleEventListener,
  addTouchCloseListener: () => addTouchCloseListener,
  addTransformToInstanceProperty: () => addTransformToInstanceProperty,
  aggregationBucketForDatum: () => aggregationBucketForDatum,
  aggregationDatumMatchesIndex: () => aggregationDatumMatchesIndex,
  aggregationDomain: () => aggregationDomain,
  aggregationIndexForXRatio: () => aggregationIndexForXRatio,
  aggregationRangeFittingPoints: () => aggregationRangeFittingPoints,
  aggregationXRatioForDatumIndex: () => aggregationXRatioForDatumIndex,
  aggregationXRatioForXValue: () => aggregationXRatioForXValue,
  and: () => and,
  angleBetween: () => angleBetween,
  angularPadding: () => angularPadding,
  appendEllipsis: () => appendEllipsis,
  applySkiaPatches: () => applySkiaPatches,
  arcDistanceSquared: () => arcDistanceSquared,
  areScalingEqual: () => areScalingEqual,
  array: () => array,
  arrayLength: () => arrayLength,
  arrayOf: () => arrayOf,
  arrayOfDefs: () => arrayOfDefs,
  arraysEqual: () => arraysEqual,
  assignIfNotStrictlyEqual: () => assignIfNotStrictlyEqual,
  attachDescription: () => attachDescription,
  attachListener: () => attachListener,
  autoSizedLabelOptionsDefs: () => autoSizedLabelOptionsDefs,
  barHighlightOptionsDef: () => barHighlightOptionsDef,
  bezier2DDistance: () => bezier2DDistance,
  bezier2DExtrema: () => bezier2DExtrema,
  boolean: () => boolean,
  borderOptionsDef: () => borderOptionsDef,
  boxCollides: () => boxCollides,
  boxContains: () => boxContains,
  boxEmpty: () => boxEmpty,
  boxesEqual: () => boxesEqual,
  buildDateFormatter: () => buildDateFormatter,
  cachedTextMeasurer: () => cachedTextMeasurer,
  calcLineHeight: () => calcLineHeight,
  calculatePlacement: () => calculatePlacement,
  callWithContext: () => callWithContext,
  callback: () => callback,
  callbackDefs: () => callbackDefs,
  callbackOf: () => callbackOf,
  ceilTo: () => ceilTo,
  checkDatum: () => checkDatum,
  circularSliceArray: () => circularSliceArray,
  clamp: () => clamp,
  clampArray: () => clampArray,
  clipLines: () => clipLines,
  clipSpanX: () => clipSpanX,
  collapseSpanToPoint: () => collapseSpanToPoint,
  collectAggregationLevels: () => collectAggregationLevels,
  color: () => color,
  colorStopsOrderValidator: () => colorStopsOrderValidator,
  colorUnion: () => colorUnion,
  commonChartOptionsDefs: () => commonChartOptionsDefs,
  commonSeriesOptionsDefs: () => commonSeriesOptionsDefs,
  commonSeriesThemeableOptionsDefs: () => commonSeriesThemeableOptionsDefs,
  compactAggregationIndices: () => compactAggregationIndices,
  compareDates: () => compareDates,
  computeExtremesAggregation: () => computeExtremesAggregation,
  computeExtremesAggregationPartial: () => computeExtremesAggregationPartial,
  constant: () => constant,
  contextMenuItemsArray: () => contextMenuItemsArray,
  countFractionDigits: () => countFractionDigits,
  countLines: () => countLines,
  createAggregationIndices: () => createAggregationIndices,
  createButton: () => createButton,
  createCanvasContext: () => createCanvasContext,
  createCheckbox: () => createCheckbox,
  createDeprecationWarning: () => createDeprecationWarning,
  createElement: () => createElement,
  createElementId: () => createElementId,
  createIcon: () => createIcon,
  createId: () => createId,
  createIdsGenerator: () => createIdsGenerator,
  createNumberFormatter: () => createNumberFormatter,
  createSelect: () => createSelect,
  createSvgElement: () => createSvgElement,
  createTextArea: () => createTextArea,
  createTicks: () => createTicks,
  date: () => date,
  dateToNumber: () => dateToNumber,
  dateTruncationForDomain: () => dateTruncationForDomain,
  datesSortOrder: () => datesSortOrder,
  debounce: () => debounce,
  decodeIntervalValue: () => decodeIntervalValue,
  deepClone: () => deepClone,
  deepFreeze: () => deepFreeze,
  defaultEpoch: () => defaultEpoch,
  defined: () => defined,
  definedZoomState: () => definedZoomState,
  diffArrays: () => diffArrays,
  distribute: () => distribute,
  downloadUrl: () => downloadUrl,
  dropFirstWhile: () => dropFirstWhile,
  dropLastWhile: () => dropLastWhile,
  durationDay: () => durationDay,
  durationHour: () => durationHour,
  durationMinute: () => durationMinute,
  durationMonth: () => durationMonth,
  durationSecond: () => durationSecond,
  durationWeek: () => durationWeek,
  durationYear: () => durationYear,
  easeIn: () => easeIn,
  easeInOut: () => easeInOut,
  easeInOutQuad: () => easeInOutQuad,
  easeInQuad: () => easeInQuad,
  easeOut: () => easeOut,
  easeOutQuad: () => easeOutQuad,
  encodedToTimestamp: () => encodedToTimestamp,
  enterpriseRegistry: () => enterpriseRegistry,
  entries: () => entries,
  errorBarOptionsDefs: () => errorBarOptionsDefs,
  errorBarThemeableOptionsDefs: () => errorBarThemeableOptionsDefs,
  estimateTickCount: () => estimateTickCount,
  evaluateBezier: () => evaluateBezier,
  every: () => every,
  expandLegendPosition: () => expandLegendPosition,
  extent: () => extent,
  extractDecoratedProperties: () => extractDecoratedProperties,
  extractDomain: () => extractDomain,
  fillGradientDefaults: () => fillGradientDefaults,
  fillImageDefaults: () => fillImageDefaults,
  fillOptionsDef: () => fillOptionsDef,
  fillPatternDefaults: () => fillPatternDefaults,
  findMaxIndex: () => findMaxIndex,
  findMaxValue: () => findMaxValue,
  findMinIndex: () => findMinIndex,
  findMinMax: () => findMinMax,
  findMinValue: () => findMinValue,
  findRangeExtent: () => findRangeExtent,
  first: () => first,
  flush: () => flush,
  focusCursorAtEnd: () => focusCursorAtEnd,
  fontFamilyFull: () => fontFamilyFull,
  fontOptionsDef: () => fontOptionsDef,
  fontWeight: () => fontWeight,
  formatNumber: () => formatNumber,
  formatObjectValidator: () => formatObjectValidator,
  formatPercent: () => formatPercent,
  formatValue: () => formatValue,
  fromPairs: () => fromPairs,
  generateUUID: () => generateUUID,
  geoJson: () => geoJson,
  getAngleRatioRadians: () => getAngleRatioRadians,
  getAttribute: () => getAttribute,
  getDOMMatrix: () => getDOMMatrix,
  getDocument: () => getDocument,
  getElementBBox: () => getElementBBox,
  getIconClassNames: () => getIconClassNames,
  getImage: () => getImage,
  getLastFocus: () => getLastFocus,
  getMaxInnerRectSize: () => getMaxInnerRectSize,
  getMidpointsForIndices: () => getMidpointsForIndices,
  getMinOuterRectSize: () => getMinOuterRectSize,
  getOffscreenCanvas: () => getOffscreenCanvas,
  getPath: () => getPath,
  getPath2D: () => getPath2D,
  getResizeObserver: () => getResizeObserver,
  getSequentialColors: () => getSequentialColors,
  getTickTimeInterval: () => getTickTimeInterval,
  getWindow: () => getWindow,
  googleFont: () => googleFont,
  gradientColorStops: () => gradientColorStops,
  gradientStrict: () => gradientStrict,
  greaterThan: () => greaterThan,
  groupBy: () => groupBy,
  guardTextEdges: () => guardTextEdges,
  hasNoModifiers: () => hasNoModifiers,
  hasRequiredInPath: () => hasRequiredInPath,
  highlightOptionsDef: () => highlightOptionsDef,
  htmlElement: () => htmlElement,
  inRange: () => inRange,
  initRovingTabIndex: () => initRovingTabIndex,
  insertListItemsSorted: () => insertListItemsSorted,
  instanceOf: () => instanceOf,
  interpolationOptionsDefs: () => interpolationOptionsDefs,
  intervalCeil: () => intervalCeil,
  intervalEpoch: () => intervalEpoch,
  intervalExtent: () => intervalExtent,
  intervalFloor: () => intervalFloor,
  intervalHierarchy: () => intervalHierarchy,
  intervalMilliseconds: () => intervalMilliseconds,
  intervalNext: () => intervalNext,
  intervalPrevious: () => intervalPrevious,
  intervalRange: () => intervalRange,
  intervalRangeCount: () => intervalRangeCount,
  intervalRangeNumeric: () => intervalRangeNumeric,
  intervalRangeStartIndex: () => intervalRangeStartIndex,
  intervalStep: () => intervalStep,
  intervalUnit: () => intervalUnit,
  inverseEaseOut: () => inverseEaseOut,
  isArray: () => isArray,
  isBetweenAngles: () => isBetweenAngles,
  isBoolean: () => isBoolean,
  isButtonClickEvent: () => isButtonClickEvent,
  isColor: () => isColor,
  isContinuous: () => isContinuous,
  isDate: () => isDate,
  isDecoratedObject: () => isDecoratedObject,
  isDefined: () => isDefined,
  isDenseInterval: () => isDenseInterval,
  isDocumentFragment: () => isDocumentFragment,
  isElement: () => isElement,
  isEmptyObject: () => isEmptyObject,
  isEnumKey: () => isEnumKey,
  isEnumValue: () => isEnumValue,
  isFiniteNumber: () => isFiniteNumber,
  isFunction: () => isFunction,
  isGradientFill: () => isGradientFill,
  isGradientFillArray: () => isGradientFillArray,
  isGradientOrPatternFill: () => isGradientOrPatternFill,
  isHTMLElement: () => isHTMLElement,
  isHtmlElement: () => isHtmlElement,
  isImageFill: () => isImageFill,
  isInputPending: () => isInputPending,
  isInteger: () => isInteger,
  isKeyOf: () => isKeyOf,
  isNegative: () => isNegative,
  isNode: () => isNode,
  isNumber: () => isNumber,
  isNumberEqual: () => isNumberEqual,
  isNumberObject: () => isNumberObject,
  isObject: () => isObject,
  isObjectLike: () => isObjectLike,
  isObjectWithProperty: () => isObjectWithProperty,
  isObjectWithStringProperty: () => isObjectWithStringProperty,
  isPatternFill: () => isPatternFill,
  isPlainObject: () => isPlainObject,
  isPointLabelDatum: () => isPointLabelDatum,
  isProperties: () => isProperties,
  isRegExp: () => isRegExp,
  isScaleValid: () => isScaleValid,
  isSegmentTruncated: () => isSegmentTruncated,
  isString: () => isString,
  isStringFillArray: () => isStringFillArray,
  isStringObject: () => isStringObject,
  isSymbol: () => isSymbol,
  isTextTruncated: () => isTextTruncated,
  isTruncated: () => isTruncated,
  isUnitTimeCategoryScaling: () => isUnitTimeCategoryScaling,
  isValidDate: () => isValidDate,
  isValidNumberFormat: () => isValidNumberFormat,
  iterate: () => iterate,
  joinFormatted: () => joinFormatted,
  jsonApply: () => jsonApply,
  jsonDiff: () => jsonDiff,
  jsonPropertyCompare: () => jsonPropertyCompare,
  jsonWalk: () => jsonWalk,
  kebabCase: () => kebabCase,
  labelBoxOptionsDef: () => labelBoxOptionsDef,
  legendPositionValidator: () => legendPositionValidator,
  lessThan: () => lessThan,
  lessThanOrEqual: () => lessThanOrEqual,
  levenshteinDistance: () => levenshteinDistance,
  lineDashOptionsDef: () => lineDashOptionsDef,
  lineDistanceSquared: () => lineDistanceSquared,
  lineHighlightOptionsDef: () => lineHighlightOptionsDef,
  lineSegmentOptions: () => lineSegmentOptions,
  lineSegmentation: () => lineSegmentation,
  linear: () => linear,
  linearGaugeSeriesOptionsDef: () => linearGaugeSeriesOptionsDef,
  linearGaugeSeriesThemeableOptionsDef: () => linearGaugeSeriesThemeableOptionsDef,
  linearGaugeTargetOptionsDef: () => linearGaugeTargetOptionsDef,
  linearPoints: () => linearPoints,
  listDecoratedProperties: () => listDecoratedProperties,
  lowestGranularityForInterval: () => lowestGranularityForInterval,
  lowestGranularityUnitForTicks: () => lowestGranularityUnitForTicks,
  lowestGranularityUnitForValue: () => lowestGranularityUnitForValue,
  makeAccessibleClickListener: () => makeAccessibleClickListener,
  mapValues: () => mapValues,
  markerOptionsDefs: () => markerOptionsDefs,
  markerStyleOptionsDefs: () => markerStyleOptionsDefs,
  measureTextSegments: () => measureTextSegments,
  memo: () => memo,
  merge: () => merge,
  mergeArrayDefaults: () => mergeArrayDefaults,
  mergeDefaults: () => mergeDefaults,
  modulus: () => modulus,
  multiSeriesHighlightOptionsDef: () => multiSeriesHighlightOptionsDef,
  nearestSquared: () => nearestSquared,
  nearestSquaredInContainer: () => nearestSquaredInContainer,
  nextPowerOf2: () => nextPowerOf2,
  niceTicksDomain: () => niceTicksDomain,
  normalisedExtentWithMetadata: () => normalisedExtentWithMetadata,
  normalisedTimeExtentWithMetadata: () => normalisedTimeExtentWithMetadata,
  normalizeAngle180: () => normalizeAngle180,
  normalizeAngle360: () => normalizeAngle360,
  normalizeAngle360FromDegrees: () => normalizeAngle360FromDegrees,
  normalizeAngle360Inclusive: () => normalizeAngle360Inclusive,
  number: () => number,
  numberFormatValidator: () => numberFormatValidator,
  numberMin: () => numberMin,
  numberRange: () => numberRange,
  object: () => object,
  objectsEqual: () => objectsEqual,
  objectsEqualWith: () => objectsEqualWith,
  optionsDefs: () => optionsDefs,
  or: () => or,
  padding: () => padding,
  paddingOptions: () => paddingOptions,
  parseNumberFormat: () => parseNumberFormat,
  partialAssign: () => partialAssign,
  pause: () => pause,
  pick: () => pick,
  placeLabels: () => placeLabels,
  positiveNumber: () => positiveNumber,
  positiveNumberNonZero: () => positiveNumberNonZero,
  previousPowerOf2: () => previousPowerOf2,
  radialGaugeSeriesOptionsDef: () => radialGaugeSeriesOptionsDef,
  radialGaugeSeriesThemeableOptionsDef: () => radialGaugeSeriesThemeableOptionsDef,
  radialGaugeTargetOptionsDef: () => radialGaugeTargetOptionsDef,
  range: () => range,
  rangeValidator: () => rangeValidator,
  ratio: () => ratio,
  readIntegratedWrappedValue: () => readIntegratedWrappedValue,
  record: () => record,
  required: () => required,
  rescaleSpan: () => rescaleSpan,
  rescaleVisibleRange: () => rescaleVisibleRange,
  resetIds: () => resetIds,
  rotatePoint: () => rotatePoint,
  roundTo: () => roundTo,
  safeCall: () => safeCall,
  seriesLabelOptionsDefs: () => seriesLabelOptionsDefs,
  seriesTooltipRangeValidator: () => seriesTooltipRangeValidator,
  setAttribute: () => setAttribute,
  setAttributes: () => setAttributes,
  setDocument: () => setDocument,
  setElementBBox: () => setElementBBox,
  setElementStyle: () => setElementStyle,
  setElementStyles: () => setElementStyles,
  setPath: () => setPath,
  setWindow: () => setWindow,
  shadowOptionsDefs: () => shadowOptionsDefs,
  shallowClone: () => shallowClone,
  shapeHighlightOptionsDef: () => shapeHighlightOptionsDef,
  shapeSegmentOptions: () => shapeSegmentOptions,
  shapeSegmentation: () => shapeSegmentation,
  shapeValidator: () => shapeValidator,
  simpleMemorize: () => simpleMemorize,
  simpleMemorize2: () => simpleMemorize2,
  smoothPoints: () => smoothPoints,
  solveBezier: () => solveBezier,
  sortAndUniqueDates: () => sortAndUniqueDates,
  sortBasedOnArray: () => sortBasedOnArray,
  spanRange: () => spanRange,
  splitBezier2D: () => splitBezier2D,
  stepPoints: () => stepPoints,
  stopPageScrolling: () => stopPageScrolling,
  strictObjectKeys: () => strictObjectKeys,
  strictUnion: () => strictUnion,
  string: () => string,
  stringLength: () => stringLength,
  stringifyValue: () => stringifyValue,
  strokeOptionsDef: () => strokeOptionsDef,
  textOrSegments: () => textOrSegments,
  themeOperator: () => themeOperator,
  throttle: () => throttle,
  tickFormat: () => tickFormat,
  tickStep: () => tickStep,
  toArray: () => toArray,
  toDegrees: () => toDegrees,
  toFontString: () => toFontString,
  toIterable: () => toIterable,
  toPlainText: () => toPlainText,
  toRadians: () => toRadians,
  toTextString: () => toTextString,
  toolbarButtonOptionsDefs: () => toolbarButtonOptionsDefs,
  tooltipOptionsDefs: () => tooltipOptionsDefs,
  tooltipOptionsDefsWithArea: () => tooltipOptionsDefsWithArea,
  transformIntegratedCategoryValue: () => transformIntegratedCategoryValue,
  truncateLine: () => truncateLine,
  typeUnion: () => typeUnion,
  undocumented: () => undocumented,
  unguardTextEdges: () => unguardTextEdges,
  union: () => union,
  unionSymbol: () => unionSymbol,
  unique: () => unique,
  validate: () => validate,
  withTimeout: () => withTimeout,
  without: () => without,
  wrapLines: () => wrapLines,
  wrapText: () => wrapText,
  wrapTextOrSegments: () => wrapTextOrSegments,
  wrapTextSegments: () => wrapTextSegments
});

// packages/ag-charts-core/src/modules/moduleDefinition.ts
var ModuleType = /* @__PURE__ */ ((ModuleType2) => {
  ModuleType2["Chart"] = "chart";
  ModuleType2["Axis"] = "axis";
  ModuleType2["Series"] = "series";
  ModuleType2["Plugin"] = "plugin";
  ModuleType2["AxisPlugin"] = "axis:plugin";
  ModuleType2["SeriesPlugin"] = "series:plugin";
  ModuleType2["Preset"] = "preset";
  return ModuleType2;
})(ModuleType || {});

// packages/ag-charts-core/src/types/scales.ts
function extractDomain(value) {
  return value.domain;
}
var ScaleAlignment = /* @__PURE__ */ ((ScaleAlignment2) => {
  ScaleAlignment2[ScaleAlignment2["Leading"] = 0] = "Leading";
  ScaleAlignment2[ScaleAlignment2["Trailing"] = 1] = "Trailing";
  ScaleAlignment2[ScaleAlignment2["Interpolate"] = 2] = "Interpolate";
  return ScaleAlignment2;
})(ScaleAlignment || {});

// packages/ag-charts-core/src/structures/eventEmitter.ts
var EventEmitter = class {
  constructor() {
    this.events = /* @__PURE__ */ new Map();
  }
  /**
   * Registers an event listener.
   * @param eventName The event name to listen for.
   * @param listener The callback to be invoked on the event.
   * @returns A function to unregister the listener.
   */
  on(eventName, listener) {
    if (!this.events.has(eventName)) {
      this.events.set(eventName, /* @__PURE__ */ new Set());
    }
    this.events.get(eventName)?.add(listener);
    return () => this.off(eventName, listener);
  }
  /**
   * Unregisters an event listener.
   * @param eventName The event name to stop listening for.
   * @param listener The callback to be removed.
   */
  off(eventName, listener) {
    const eventListeners = this.events.get(eventName);
    if (eventListeners) {
      eventListeners.delete(listener);
      if (eventListeners.size === 0) {
        this.events.delete(eventName);
      }
    }
  }
  /**
   * Emits an event to all registered listeners.
   * @param eventName The name of the event to emit.
   * @param event The event payload.
   */
  emit(eventName, event) {
    const listeners = this.events.get(eventName);
    if (listeners) {
      for (const callback2 of listeners) {
        callback2(event);
      }
    }
  }
  /**
   * Clears all listeners for a specific event or all events if no event name is provided.
   * @param eventName (Optional) The name of the event to clear listeners for. If not provided, all listeners for all events are cleared.
   */
  clear(eventName) {
    if (eventName) {
      this.events.delete(eventName);
    } else {
      this.events.clear();
    }
  }
};

// packages/ag-charts-core/src/structures/lruCache.ts
var LRUCache = class {
  constructor(maxCacheSize) {
    this.maxCacheSize = maxCacheSize;
    this.store = /* @__PURE__ */ new Map();
    if (maxCacheSize <= 0) {
      throw new Error("LRUCache size must be greater than 0");
    }
  }
  get(key) {
    if (!this.store.has(key))
      return;
    const value = this.store.get(key);
    this.store.delete(key);
    this.store.set(key, value);
    return value;
  }
  has(key) {
    return this.store.has(key);
  }
  set(key, value) {
    this.store.set(key, value);
    if (this.store.size > this.maxCacheSize) {
      this.store.delete(this.store.keys().next().value);
    }
    return value;
  }
  clear() {
    this.store.clear();
  }
};

// packages/ag-charts-core/src/logging/debugLogger.ts
var debugLogger_exports = {};
__export(debugLogger_exports, {
  Time: () => Time,
  check: () => check,
  create: () => create,
  inDevelopmentMode: () => inDevelopmentMode
});

// packages/ag-charts-core/src/utils/data/arrays.ts
function toArray(value) {
  if (value === void 0) {
    return [];
  }
  return Array.isArray(value) ? value : [value];
}
function unique(array2) {
  return Array.from(new Set(array2));
}
function groupBy(array2, iteratee) {
  return array2.reduce((result, item) => {
    const groupKey = iteratee(item);
    result[groupKey] ?? (result[groupKey] = []);
    result[groupKey].push(item);
    return result;
  }, {});
}
function arraysEqual(a, b) {
  if (a == null || b == null || a.length !== b.length) {
    return false;
  }
  for (let i = 0; i < a.length; i++) {
    if (Array.isArray(a[i]) && Array.isArray(b[i])) {
      if (!arraysEqual(a[i], b[i])) {
        return false;
      }
    } else if (a[i] !== b[i]) {
      return false;
    }
  }
  return true;
}
function circularSliceArray(data, size, offset = 0) {
  if (data.length === 0) {
    return [];
  }
  const result = [];
  for (let i = 0; i < size; i++) {
    result.push(data.at((i + offset) % data.length));
  }
  return result;
}
function sortBasedOnArray(baseArray, orderArray) {
  const orderMap = /* @__PURE__ */ new Map();
  for (const [index, item] of orderArray.entries()) {
    orderMap.set(item, index);
  }
  return baseArray.sort((a, b) => {
    const indexA = orderMap.get(a) ?? Infinity;
    const indexB = orderMap.get(b) ?? Infinity;
    return indexA - indexB;
  });
}
function dropFirstWhile(array2, cond) {
  let i = 0;
  while (i < array2.length && cond(array2[i])) {
    i += 1;
  }
  const deleteCount = i;
  if (deleteCount !== 0)
    array2.splice(0, deleteCount);
}
function dropLastWhile(array2, cond) {
  let i = array2.length - 1;
  while (i >= 0 && cond(array2[i])) {
    i -= 1;
  }
  const deleteCount = array2.length - 1 - i;
  if (deleteCount !== 0)
    array2.splice(array2.length - deleteCount, deleteCount);
}
function distribute(min, max, maxCount) {
  const values = [min];
  const step = Math.round((max - min) / (maxCount - 1));
  if (step > 0) {
    for (let i = min + step; i < max; i += step) {
      const length2 = values.push(i);
      if (length2 >= maxCount - 1)
        break;
    }
  }
  values.push(max);
  return values;
}

// packages/ag-charts-core/src/utils/dom/globalsProxy.ts
var verifiedGlobals = {};
if (typeof globalThis.window !== "undefined") {
  verifiedGlobals.window = globalThis.window;
}
if (typeof document !== "undefined") {
  verifiedGlobals.document = document;
} else if (typeof globalThis.global !== "undefined") {
  verifiedGlobals.document = globalThis.document;
}
function getDocument(propertyName) {
  return propertyName ? verifiedGlobals.document?.[propertyName] : verifiedGlobals.document;
}
function getWindow(propertyName) {
  return propertyName ? verifiedGlobals.window?.[propertyName] : verifiedGlobals.window;
}
function setDocument(document2) {
  verifiedGlobals.document = document2;
}
function setWindow(window) {
  verifiedGlobals.window = window;
}
function getOffscreenCanvas() {
  return verifiedGlobals.window?.OffscreenCanvas ?? globalThis.OffscreenCanvas;
}
function getPath2D() {
  return verifiedGlobals.window?.Path2D ?? globalThis.Path2D;
}
function getDOMMatrix() {
  return verifiedGlobals.window?.DOMMatrix ?? globalThis.DOMMatrix;
}
function getImage() {
  return verifiedGlobals.window?.Image ?? globalThis.Image;
}
function getResizeObserver() {
  return verifiedGlobals.window?.ResizeObserver ?? globalThis.ResizeObserver;
}
var ELEMENT_NODE = 1;
var DOCUMENT_FRAGMENT_NODE = 11;
function isNode(obj) {
  return obj != null && typeof obj.nodeType === "number";
}
function isElement(obj) {
  return obj != null && obj.nodeType === ELEMENT_NODE;
}
function isDocumentFragment(obj) {
  return obj != null && obj.nodeType === DOCUMENT_FRAGMENT_NODE;
}
function isHTMLElement(obj) {
  return obj != null && obj.nodeType === ELEMENT_NODE && "style" in obj;
}

// packages/ag-charts-core/src/logging/logger.ts
var logger_exports = {};
__export(logger_exports, {
  error: () => error,
  errorOnce: () => errorOnce,
  log: () => log,
  logGroup: () => logGroup,
  reset: () => reset,
  table: () => table,
  warn: () => warn,
  warnOnce: () => warnOnce
});
var doOnceCache = /* @__PURE__ */ new Set();
function log(...logContent) {
  console.log(...logContent);
}
function warn(message, ...logContent) {
  console.warn(`AG Charts - ${message}`, ...logContent);
}
function error(message, ...logContent) {
  if (typeof message === "object") {
    console.error(`AG Charts error`, message, ...logContent);
  } else {
    console.error(`AG Charts - ${message}`, ...logContent);
  }
}
function table(...logContent) {
  console.table(...logContent);
}
function guardOnce(messageOrError, prefix, cb) {
  let message;
  if (messageOrError instanceof Error) {
    message = messageOrError.message;
  } else if (typeof messageOrError === "string") {
    message = messageOrError;
  } else if (typeof messageOrError === "object") {
    message = JSON.stringify(messageOrError);
  } else {
    message = String(messageOrError);
  }
  const cacheKey = `${prefix}: ${message}`;
  if (doOnceCache.has(cacheKey))
    return;
  cb(messageOrError);
  doOnceCache.add(cacheKey);
}
function warnOnce(messageOrError, ...logContent) {
  guardOnce(messageOrError, "Logger.warn", (message) => warn(message, ...logContent));
}
function errorOnce(messageOrError, ...logContent) {
  guardOnce(messageOrError, "Logger.error", (message) => error(message, ...logContent));
}
function reset() {
  doOnceCache.clear();
}
function logGroup(name, cb) {
  console.groupCollapsed(name);
  try {
    return cb();
  } finally {
    console.groupEnd();
  }
}

// packages/ag-charts-core/src/logging/debugLogger.ts
var LongTimePeriodThreshold = 2e3;
var timeOfLastLog = Date.now();
function logTimeGap() {
  const timeSinceLastLog = Date.now() - timeOfLastLog;
  if (timeSinceLastLog > LongTimePeriodThreshold) {
    const prettyDuration = (Math.floor(timeSinceLastLog / 100) / 10).toFixed(1);
    log(`**** ${prettyDuration}s since last log message ****`);
  }
  timeOfLastLog = Date.now();
}
function create(...debugSelectors) {
  const resultFn = (...logContent) => {
    if (check(...debugSelectors)) {
      if (typeof logContent[0] === "function") {
        logContent = toArray(logContent[0]());
      }
      logTimeGap();
      log(...logContent);
    }
  };
  return Object.assign(resultFn, {
    check: () => check(...debugSelectors),
    group: (name, cb) => {
      if (check(...debugSelectors)) {
        return logGroup(name, cb);
      }
      return cb();
    }
  });
}
function check(...debugSelectors) {
  if (debugSelectors.length === 0) {
    debugSelectors.push(true);
  }
  const chartDebug = toArray(getWindow("agChartsDebug"));
  return chartDebug.some((selector) => debugSelectors.includes(selector));
}
function inDevelopmentMode(fn) {
  if (check("dev")) {
    return fn();
  }
}
function Time(name, opts = {}) {
  const { logResult = true, logStack = false, logArgs = false, logData } = opts;
  return function(_target, _propertyKey, descriptor) {
    const method = descriptor.value;
    descriptor.value = function(...args) {
      const start2 = performance.now();
      const result = method.apply(this, args);
      const duration = performance.now() - start2;
      const logMessage = { duration };
      if (logResult)
        logMessage.result = result;
      if (logArgs)
        logMessage.args = args;
      if (logStack)
        logMessage.stack = new Error("Stack trace for timing debug").stack;
      if (logData)
        logMessage.logData = logData(this);
      log(name, logMessage);
      return result;
    };
  };
}

// packages/ag-charts-core/src/logging/debugMetrics.ts
var debugMetrics_exports = {};
__export(debugMetrics_exports, {
  flush: () => flush,
  record: () => record
});
var metrics = /* @__PURE__ */ new Map();
function record(key, value) {
  if (!check("scene:stats:verbose"))
    return;
  metrics.set(key, value);
}
function flush() {
  const result = Object.fromEntries(metrics);
  metrics.clear();
  return result;
}

// packages/ag-charts-core/src/modules/enterpriseRegistry.ts
var enterpriseRegistry = {};

// packages/ag-charts-core/src/modules/moduleRegistry.ts
var moduleRegistry_exports = {};
__export(moduleRegistry_exports, {
  RegistryMode: () => RegistryMode,
  getAxisModule: () => getAxisModule,
  getChartModule: () => getChartModule,
  getPresetModule: () => getPresetModule,
  getSeriesModule: () => getSeriesModule,
  hasModule: () => hasModule,
  isEnterprise: () => isEnterprise,
  isIntegrated: () => isIntegrated,
  isModuleType: () => isModuleType,
  isUmd: () => isUmd,
  listModules: () => listModules,
  listModulesByType: () => listModulesByType,
  register: () => register,
  registerModules: () => registerModules,
  reset: () => reset2,
  setRegistryMode: () => setRegistryMode
});
var RegistryMode = /* @__PURE__ */ ((RegistryMode2) => {
  RegistryMode2["Enterprise"] = "enterprise";
  RegistryMode2["Integrated"] = "integrated";
  RegistryMode2["UMD"] = "umd";
  return RegistryMode2;
})(RegistryMode || {});
var registeredModes = /* @__PURE__ */ new Set();
var registeredModules = /* @__PURE__ */ new Map();
function registerModuleDefinition(def) {
  registeredModules.set(def.name, def);
  if (def.dependencies) {
    for (const dependency of def.dependencies) {
      register(dependency);
    }
  }
}
function register(def) {
  const existingDefinition = registeredModules.get(def.name);
  if (!existingDefinition) {
    registerModuleDefinition(def);
    return;
  }
  if (existingDefinition.version === def.version) {
    if (!existingDefinition.enterprise && def.enterprise) {
      registerModuleDefinition(def);
    }
    return;
  }
  throw new Error(
    [
      `AG Charts - Module '${def.name}' already registered with different version:`,
      `${existingDefinition.version} vs ${def.version}`,
      ``,
      `Check your package.json for conflicting dependencies - depending on your package manager`,
      `one of these commands may help:`,
      `- npm ls ag-charts-community`,
      `- yarn why ag-charts-community`
    ].join("\n")
  );
}
function registerModules(definitions) {
  for (const definition of definitions.flat()) {
    register(definition);
  }
}
function reset2() {
  registeredModes.clear();
  registeredModules.clear();
}
function hasModule(moduleName) {
  return registeredModules.has(moduleName);
}
function* listModules() {
  for (const definition of registeredModules.values()) {
    yield definition;
  }
}
function* listModulesByType(moduleType) {
  for (const definition of registeredModules.values()) {
    if (isModuleType(moduleType, definition)) {
      yield definition;
    }
  }
}
function getAxisModule(moduleName) {
  const definition = registeredModules.get(moduleName);
  if (isModuleType("axis" /* Axis */, definition)) {
    return definition;
  }
}
function getChartModule(moduleName) {
  const definition = registeredModules.get(moduleName);
  if (isModuleType("chart" /* Chart */, definition)) {
    return definition;
  }
  throw new Error(
    `AG Charts - Unknown chart type; Check options are correctly structured and series types are specified`
  );
}
function getPresetModule(moduleName) {
  const definition = registeredModules.get(moduleName);
  if (isModuleType("preset" /* Preset */, definition)) {
    return definition;
  }
}
function getSeriesModule(moduleName) {
  const definition = registeredModules.get(moduleName);
  if (isModuleType("series" /* Series */, definition)) {
    return definition;
  }
}
function setRegistryMode(registryFlag) {
  registeredModes.add(registryFlag);
}
function isEnterprise() {
  return registeredModes.has("enterprise" /* Enterprise */);
}
function isIntegrated() {
  return registeredModes.has("integrated" /* Integrated */);
}
function isUmd() {
  return registeredModes.has("umd" /* UMD */);
}
function isModuleType(moduleType, definition) {
  return definition?.type === moduleType;
}

// packages/ag-charts-core/src/state/cleanupRegistry.ts
var CleanupRegistry = class {
  constructor() {
    this.callbacks = /* @__PURE__ */ new Set();
  }
  flush() {
    for (const cb of this.callbacks) {
      cb();
    }
    this.callbacks.clear();
  }
  merge(registry) {
    for (const cb of registry.callbacks) {
      this.callbacks.add(cb);
    }
  }
  register(...callbacks) {
    for (const cb of callbacks) {
      if (!cb)
        continue;
      this.callbacks.add(cb);
    }
  }
};

// packages/ag-charts-core/src/modules/moduleInstance.ts
var AbstractModuleInstance = class {
  constructor() {
    this.cleanup = new CleanupRegistry();
  }
  destroy() {
    this.cleanup.flush();
  }
};

// packages/ag-charts-types/src/chart/navigatorOptions.ts
var __MINI_CHART_SERIES_OPTIONS = void 0;
var __VERIFY_MINI_CHART_SERIES_OPTIONS = void 0;
__VERIFY_MINI_CHART_SERIES_OPTIONS = __MINI_CHART_SERIES_OPTIONS;

// packages/ag-charts-types/src/chart/themeOptions.ts
var __THEME_OVERRIDES = void 0;
var __VERIFY_THEME_OVERRIDES = void 0;
__VERIFY_THEME_OVERRIDES = __THEME_OVERRIDES;

// packages/ag-charts-types/src/chart/tooltipOptions.ts
var AgTooltipAnchorToType = /* @__PURE__ */ ((AgTooltipAnchorToType2) => {
  AgTooltipAnchorToType2["POINTER"] = "pointer";
  AgTooltipAnchorToType2["NODE"] = "node";
  AgTooltipAnchorToType2["CHART"] = "chart";
  return AgTooltipAnchorToType2;
})(AgTooltipAnchorToType || {});
var AgTooltipPlacementType = /* @__PURE__ */ ((AgTooltipPlacementType2) => {
  AgTooltipPlacementType2["TOP"] = "top";
  AgTooltipPlacementType2["RIGHT"] = "right";
  AgTooltipPlacementType2["BOTTOM"] = "bottom";
  AgTooltipPlacementType2["LEFT"] = "left";
  AgTooltipPlacementType2["TOP_RIGHT"] = "top-right";
  AgTooltipPlacementType2["BOTTOM_RIGHT"] = "bottom-right";
  AgTooltipPlacementType2["BOTTOM_LEFT"] = "bottom-left";
  AgTooltipPlacementType2["TOP_LEFT"] = "top-left";
  AgTooltipPlacementType2["CENTER"] = "center";
  return AgTooltipPlacementType2;
})(AgTooltipPlacementType || {});

// packages/ag-charts-types/src/presets/gauge/commonOptions.ts
var __THEMEABLE_OPTIONS = void 0;
var __VERIFY_THEMEABLE_OPTIONS = void 0;
__VERIFY_THEMEABLE_OPTIONS = __THEMEABLE_OPTIONS;
var __AXIS_LABEL_OPTIONS = void 0;
var __VERIFY_AXIS_LABEL_OPTIONS = void 0;
__VERIFY_AXIS_LABEL_OPTIONS = __AXIS_LABEL_OPTIONS;

// packages/ag-charts-core/src/types/text.ts
var EllipsisChar = "\u2026";
var LineSplitter = /\r?\n/g;
var TrimEdgeGuard = "\u200B";
var TrimCharsRegex = /[\s.,;:-]{1,5}$/;

// packages/ag-charts-core/src/utils/dom/domUtils.ts
var style;
function parseColor(color2) {
  if (style == null) {
    const OptionConstructor = getWindow("Option");
    style = new OptionConstructor().style;
  }
  style.color = color2;
  const result = style.color || null;
  style.color = "";
  return result;
}

// packages/ag-charts-core/src/utils/types/typeGuards.ts
function isDefined(val) {
  return val != null;
}
function isArray(value) {
  return Array.isArray(value);
}
function isBoolean(value) {
  return typeof value === "boolean";
}
function isDate(value) {
  return value instanceof Date;
}
function isValidDate(value) {
  return isDate(value) && !Number.isNaN(Number(value));
}
function isRegExp(value) {
  return value instanceof RegExp;
}
function isFunction(value) {
  return typeof value === "function";
}
function isObject(value) {
  return typeof value === "object" && value !== null && !isArray(value);
}
function isObjectLike(value) {
  return isArray(value) || isPlainObject(value);
}
function isPlainObject(value) {
  return typeof value === "object" && value !== null && value.constructor?.name === "Object";
}
function isEmptyObject(value) {
  if (typeof value !== "object" || value === null)
    return false;
  for (const _ in value) {
    return false;
  }
  return true;
}
function isString(value) {
  return typeof value === "string";
}
function isNumber(value) {
  return typeof value === "number";
}
function isFiniteNumber(value) {
  return Number.isFinite(value);
}
function isHtmlElement(value) {
  return value != null && value.nodeType === 1 && "style" in value;
}
function isEnumKey(enumObject, enumKey) {
  return isString(enumKey) && Object.keys(enumObject).includes(enumKey);
}
function isEnumValue(enumObject, enumValue) {
  return Object.values(enumObject).includes(enumValue);
}
function isSymbol(value) {
  return typeof value === "symbol";
}
function isColor(value) {
  return isString(value) && (value === "none" || parseColor(value) != null);
}
function isKeyOf(value, container) {
  return value in container;
}

// packages/ag-charts-core/src/utils/text/textUtils.ts
function toFontString({ fontSize, fontStyle, fontWeight: fontWeight2, fontFamily }) {
  let fontString = "";
  if (fontStyle && fontStyle !== "normal") {
    fontString += `${fontStyle} `;
  }
  if (fontWeight2 && fontWeight2 !== "normal" && fontWeight2 !== 400) {
    fontString += `${fontWeight2} `;
  }
  fontString += `${fontSize}px`;
  fontString += ` ${fontFamily}`;
  return fontString;
}
function calcLineHeight(fontSize, lineHeightRatio = 1.15) {
  return Math.round(fontSize * lineHeightRatio);
}
function toTextString(value) {
  return String(value ?? "");
}
function appendEllipsis(text2) {
  return text2.replace(TrimCharsRegex, "") + EllipsisChar;
}
function guardTextEdges(str) {
  return TrimEdgeGuard + str + TrimEdgeGuard;
}
function unguardTextEdges(str) {
  return str.replaceAll(TrimEdgeGuard, "");
}
function isTruncated(value) {
  return isArray(value) ? isSegmentTruncated(value.at(-1)) : isTextTruncated(toTextString(value));
}
function isTextTruncated(str) {
  return str.endsWith(EllipsisChar);
}
function isSegmentTruncated(segment) {
  return toTextString(segment?.text).endsWith(EllipsisChar);
}

// packages/ag-charts-core/src/utils/data/strings.ts
function joinFormatted(values, conjunction = "and", format = String, maxItems = Infinity) {
  if (values.length === 0) {
    return "";
  } else if (values.length === 1) {
    return format(values[0]);
  }
  values = values.map(format);
  const lastValue = values.pop();
  if (values.length >= maxItems) {
    const remainingCount = values.length - (maxItems - 1);
    return `${values.slice(0, maxItems - 1).join(", ")}, and ${remainingCount} more ${conjunction} ${lastValue}`;
  }
  return `${values.join(", ")} ${conjunction} ${lastValue}`;
}
function stringifyValue(value, maxLength = Infinity) {
  if (typeof value === "number") {
    if (Number.isNaN(value)) {
      return "NaN";
    } else if (value === Infinity) {
      return "Infinity";
    } else if (value === -Infinity) {
      return "-Infinity";
    }
  }
  const strValue = JSON.stringify(value) ?? typeof value;
  if (strValue.length > maxLength) {
    return `${strValue.slice(0, maxLength)}... (+${strValue.length - maxLength} characters)`;
  }
  return strValue;
}
function countLines(text2) {
  let count = 1;
  for (let i = 0; i < text2.length; i++) {
    if (text2.codePointAt(i) === 10) {
      count++;
    }
  }
  return count;
}
function levenshteinDistance(a, b) {
  if (a === b)
    return 0;
  const [shorter, longer] = a.length < b.length ? [a, b] : [b, a];
  const m = shorter.length;
  const n = longer.length;
  let prevRow = new Array(m + 1).fill(0).map((_, i) => i);
  let currRow = new Array(m + 1);
  for (let i = 1; i <= n; i++) {
    currRow[0] = i;
    for (let j = 1; j <= m; j++) {
      const cost = longer[i - 1] === shorter[j - 1] ? 0 : 1;
      currRow[j] = Math.min(
        prevRow[j] + 1,
        // Deletion
        currRow[j - 1] + 1,
        // Insertion
        prevRow[j - 1] + cost
        // Substitution
      );
    }
    [prevRow, currRow] = [currRow, prevRow];
  }
  return prevRow[m];
}
function kebabCase(a) {
  return a.replaceAll(KEBAB_CASE_REGEX, (match, offset) => (offset > 0 ? "-" : "") + match.toLowerCase());
}
var KEBAB_CASE_REGEX = /[A-Z]+(?![a-z])|[A-Z]/g;
function toPlainText(text2, fallback = "") {
  if (text2 == null) {
    return fallback;
  } else if (isArray(text2)) {
    return text2.map((segment) => toTextString(segment.text)).join("");
  } else if (isString(text2)) {
    return text2;
  } else {
    return String(text2);
  }
}

// packages/ag-charts-core/src/utils/functions.ts
function debounce(callback2, waitMs = 0, options) {
  const { leading = false, trailing = true, maxWait = Infinity } = options ?? {};
  let timerId;
  let startTime;
  if (maxWait < waitMs) {
    throw new Error("Value of maxWait cannot be lower than waitMs.");
  }
  function debounceCallback(...args) {
    if (leading && !startTime) {
      startTime = Date.now();
      timerId = setTimeout(() => startTime = null, waitMs);
      callback2(...args);
      return;
    }
    let adjustedWaitMs = waitMs;
    if (maxWait !== Infinity && startTime) {
      const elapsedTime = Date.now() - startTime;
      if (waitMs > maxWait - elapsedTime) {
        adjustedWaitMs = maxWait - elapsedTime;
      }
    }
    clearTimeout(timerId);
    startTime ?? (startTime = Date.now());
    timerId = setTimeout(() => {
      startTime = null;
      if (trailing) {
        callback2(...args);
      }
    }, adjustedWaitMs);
  }
  return Object.assign(debounceCallback, {
    cancel() {
      clearTimeout(timerId);
      startTime = null;
    }
  });
}
function throttle(callback2, waitMs, options) {
  const { leading = true, trailing = true } = options ?? {};
  let timerId;
  let lastArgs;
  let shouldWait = false;
  function timeoutHandler() {
    if (trailing && lastArgs) {
      timerId = setTimeout(timeoutHandler, waitMs);
      callback2(...lastArgs);
    } else {
      shouldWait = false;
    }
    lastArgs = null;
  }
  function throttleCallback(...args) {
    if (shouldWait) {
      lastArgs = args;
    } else {
      shouldWait = true;
      timerId = setTimeout(timeoutHandler, waitMs);
      if (leading) {
        callback2(...args);
      } else {
        lastArgs = args;
      }
    }
  }
  return Object.assign(throttleCallback, {
    cancel() {
      clearTimeout(timerId);
      shouldWait = false;
      lastArgs = null;
    }
  });
}
function safeCall(callback2, args, errorPath = "") {
  try {
    return callback2(...args);
  } catch (error2) {
    const postfix = errorPath ? ` \`${errorPath}\`` : "";
    warnOnce(`Uncaught exception in user callback${postfix}`, error2);
  }
}

// packages/ag-charts-core/src/state/validation.ts
var descriptionSymbol = Symbol("description");
var requiredSymbol = Symbol("required");
var markedSymbol = Symbol("marked");
var undocumentedSymbol = Symbol("undocumented");
var unionSymbol = Symbol("union");
var similarOptionsMap = [
  ["placement", "position"],
  ["padding", "spacing", "gap"],
  ["color", "fill", "stroke"],
  ["whisker", "wick"],
  ["src", "url"],
  ["width", "thickness"]
].reduce((map, words) => {
  for (const word of words) {
    map.set(word.toLowerCase(), new Set(words.filter((w) => w !== word)));
  }
  return map;
}, /* @__PURE__ */ new Map());
var ErrorType = /* @__PURE__ */ ((ErrorType2) => {
  ErrorType2["Invalid"] = "invalid";
  ErrorType2["Required"] = "required";
  ErrorType2["Unknown"] = "unknown";
  return ErrorType2;
})(ErrorType || {});
function extendPath(path, key) {
  if (isFiniteNumber(key)) {
    return `${path}[${key}]`;
  }
  return path ? `${path}.${key}` : key;
}
var ValidationError = class {
  constructor(type, description, value, path, key) {
    this.type = type;
    this.description = description;
    this.value = value;
    this.path = path;
    this.key = key;
  }
  setUnionType(unionType, path) {
    if (this.path.startsWith(path)) {
      const suffix = this.path.slice(path.length);
      this.altPath = `${path}[type=${unionType}]${suffix}`;
    }
  }
  getPrefix() {
    const { altPath: path = this.path, key } = this;
    if (!path && !key)
      return "Value";
    return `Option \`${key ? extendPath(path, key) : path}\``;
  }
  toString() {
    const { description = "unknown", type, value } = this;
    if (type === "required" /* Required */ && value == null) {
      return `${this.getPrefix()} is required and has not been provided; expecting ${description}, ignoring.`;
    }
    return `${this.getPrefix()} cannot be set to \`${stringifyValue(value, 50)}\`; expecting ${description}, ignoring.`;
  }
};
var UnknownError = class extends ValidationError {
  constructor(suggestions, value, path, key) {
    super("unknown" /* Unknown */, void 0, value, path, key);
    this.suggestions = suggestions;
    this.key = key;
  }
  getPrefix() {
    return `Unknown option \`${extendPath(this.altPath ?? this.path, this.key)}\``;
  }
  getPostfix() {
    const suggestions = joinFormatted(findSuggestions(this.key, this.suggestions), "or", (val) => `\`${val}\``);
    return suggestions ? `; Did you mean ${suggestions}? Ignoring.` : ", ignoring.";
  }
  toString() {
    return `${this.getPrefix()}${this.getPostfix()}`;
  }
};
function validate(options, optionsDefs2, path = "") {
  if (!isObject(options)) {
    return { cleared: null, invalid: [new ValidationError("required" /* Required */, "an object", options, path)] };
  }
  const cleared = {};
  const invalid = [];
  const optionsKeys = new Set(Object.keys(options));
  const unusedKeys = [];
  if (unionSymbol in optionsDefs2) {
    const validTypes = Object.keys(optionsDefs2);
    const defaultType = optionsDefs2[unionSymbol];
    if (options.type != null && validTypes.includes(options.type) || options.type == null && defaultType != null) {
      const { type = defaultType, ...rest } = options;
      const nestedResult = validate(rest, optionsDefs2[type], path);
      Object.assign(cleared, { type }, nestedResult.cleared);
      for (const error2 of nestedResult.invalid) {
        error2.setUnionType(type, path);
      }
      invalid.push(...nestedResult.invalid);
    } else {
      const keywords = joinFormatted(validTypes, "or", (val) => `'${val}'`);
      invalid.push(
        new ValidationError("required" /* Required */, `a keyword such as ${keywords}`, options.type, path, "type")
      );
    }
    return { cleared, invalid };
  }
  for (const key of Object.keys(optionsDefs2)) {
    const validatorOrDefs = optionsDefs2[key];
    const required3 = validatorOrDefs[requiredSymbol];
    const value = options[key];
    optionsKeys.delete(key);
    if (value === void 0) {
      if (!validatorOrDefs[undocumentedSymbol]) {
        unusedKeys.push(key);
      }
      if (!required3)
        continue;
    }
    const keyPath = extendPath(path, key);
    if (isFunction(validatorOrDefs)) {
      const context = { options, path: keyPath };
      const validatorResult = validatorOrDefs(value, context);
      const objectResult = typeof validatorResult === "object";
      if (objectResult) {
        invalid.push(...validatorResult.invalid);
        if (validatorResult.valid) {
          cleared[key] = validatorResult.cleared;
          continue;
        } else if (hasRequiredInPath(validatorResult.invalid, keyPath)) {
          continue;
        }
      } else if (validatorResult) {
        cleared[key] = value;
        continue;
      }
      invalid.push(
        new ValidationError(
          required3 ? "required" /* Required */ : "invalid" /* Invalid */,
          validatorOrDefs[descriptionSymbol],
          value,
          path,
          key
        )
      );
    } else {
      const nestedResult = validate(value, validatorOrDefs, keyPath);
      if (nestedResult.cleared != null) {
        cleared[key] = nestedResult.cleared;
      }
      invalid.push(...nestedResult.invalid);
    }
  }
  for (const key of optionsKeys) {
    const value = options[key];
    if (value === void 0)
      continue;
    invalid.push(new UnknownError(unusedKeys, value, path, key));
  }
  return { cleared, invalid };
}
function findSuggestions(value, suggestions, maxDistance = 2) {
  const lowerCaseValue = value.toLowerCase();
  const similarValues = similarOptionsMap.get(lowerCaseValue);
  return suggestions.filter((key) => {
    const lowerCaseKey = key.toLowerCase();
    return similarValues?.has(key) === true || lowerCaseKey.includes(lowerCaseValue) || levenshteinDistance(lowerCaseValue, lowerCaseKey) <= maxDistance;
  });
}
function attachDescription(validatorOrDefs, description) {
  if (isFunction(validatorOrDefs)) {
    let clonedValidator2 = function(value, context) {
      return validatorOrDefs(value, context);
    };
    var clonedValidator = clonedValidator2;
    clonedValidator2[descriptionSymbol] = description;
    return clonedValidator2;
  } else {
    return { ...validatorOrDefs, [descriptionSymbol]: description };
  }
}
function required(validatorOrDefs) {
  return Object.assign(
    isFunction(validatorOrDefs) ? (value, context) => validatorOrDefs(value, context) : optionsDefs(validatorOrDefs),
    { [requiredSymbol]: true, [descriptionSymbol]: validatorOrDefs[descriptionSymbol] }
  );
}
function undocumented(validatorOrDefs) {
  return Object.assign(
    isFunction(validatorOrDefs) ? (value, context) => validatorOrDefs(value, context) : optionsDefs(validatorOrDefs),
    { [undocumentedSymbol]: true, [descriptionSymbol]: validatorOrDefs[descriptionSymbol] }
  );
}
var optionsDefs = (defs, description = "an object", failAll = false) => attachDescription((value, context) => {
  const result = validate(value, defs, context.path);
  const valid = !hasRequiredInPath(result.invalid, context.path);
  return { valid, cleared: valid || !failAll ? result.cleared : null, invalid: result.invalid };
}, description);
var typeUnion = (defs, description, defaultType) => ({
  ...defs,
  [descriptionSymbol]: description,
  [unionSymbol]: defaultType
});
var and = (...validators) => attachDescription(
  (value, context) => {
    const invalid = [];
    for (const validator of validators) {
      const result = validator(value, context);
      if (typeof result === "object") {
        invalid.push(...result.invalid);
        if (!result.valid) {
          return { valid: false, cleared: value, invalid };
        }
        value = result.cleared;
      } else if (!result) {
        return false;
      }
    }
    return { valid: true, cleared: value, invalid };
  },
  joinFormatted(
    validators.filter((v) => !v[undocumentedSymbol]).map((v) => v[descriptionSymbol]).filter(isDefined),
    "and"
  )
);
var or = (...validators) => attachDescription(
  (value, context) => {
    for (const validator of validators) {
      const result = validator(value, context);
      if (typeof result === "object" ? result.valid : result) {
        return result;
      }
    }
    return false;
  },
  joinFormatted(
    validators.filter((v) => !v[undocumentedSymbol]).map((v) => v[descriptionSymbol]).filter(isDefined),
    "or"
  )
);
var isComparable = (value) => isFiniteNumber(value) || isValidDate(value);
var isValidDateValue = (value) => isDate(value) || (isFiniteNumber(value) || isString(value)) && isValidDate(new Date(value));
var array = attachDescription(isArray, "an array");
var boolean = attachDescription(isBoolean, "a boolean");
var callback = attachDescription(isFunction, "a function");
var color = attachDescription(isColor, "a color string");
var date = attachDescription(isValidDateValue, "a date");
var defined = attachDescription(isDefined, "a defined value");
var number = attachDescription(isFiniteNumber, "a number");
var object = attachDescription(isObject, "an object");
var string = attachDescription(isString, "a string");
var htmlElement = attachDescription(isHtmlElement, "an html element");
var arrayLength = (minLength, maxLength = Infinity) => {
  let message;
  if (maxLength === Infinity) {
    message = `an array of at least ${minLength} items`;
  } else if (minLength === maxLength) {
    message = `an array of exactly ${minLength} items`;
  } else if (minLength === 0) {
    message = `an array of no more than ${maxLength} items`;
  } else {
    message = `an array of at least ${minLength} and no more than ${maxLength} items`;
  }
  return attachDescription(
    (value) => isArray(value) && value.length >= minLength && value.length <= maxLength,
    message
  );
};
var stringLength = (minLength, maxLength = Infinity) => {
  let message;
  if (maxLength === Infinity) {
    message = `a string of at least ${minLength} characters`;
  } else if (minLength === maxLength) {
    message = `an string of exactly ${minLength} characters`;
  } else if (minLength === 0) {
    message = `an string of no more than ${maxLength} characters`;
  } else {
    message = `an string of at least ${minLength} and no more than ${maxLength} characters`;
  }
  return attachDescription(
    (value) => isString(value) && value.length >= minLength && value.length <= maxLength,
    message
  );
};
var numberMin = (min, inclusive = true) => attachDescription(
  (value) => isFiniteNumber(value) && (value > min || inclusive && value === min),
  `a number greater than ${inclusive ? "or equal to " : ""}${min}`
);
var numberRange = (min, max) => attachDescription(
  (value) => isFiniteNumber(value) && value >= min && value <= max,
  `a number between ${min} and ${max} inclusive`
);
var positiveNumber = numberMin(0);
var positiveNumberNonZero = numberMin(0, false);
var ratio = numberRange(0, 1);
var lessThan = (otherField) => attachDescription(
  (value, { options }) => !isComparable(value) || !isComparable(options[otherField]) || value < options[otherField],
  `the value to be less than \`${otherField}\``
);
var lessThanOrEqual = (otherField) => attachDescription(
  (value, { options }) => !isComparable(value) || !isComparable(options[otherField]) || value <= options[otherField],
  `the value to be less than or equal to \`${otherField}\``
);
var greaterThan = (otherField) => attachDescription(
  (value, { options }) => !isComparable(value) || !isComparable(options[otherField]) || value > options[otherField],
  `the value to be greater than \`${otherField}\``
);
function union(...allowed) {
  if (isObject(allowed[0])) {
    allowed = Object.values(allowed[0]);
  }
  const keywords = joinFormatted(allowed, "or", (value) => `'${value}'`);
  return attachDescription((value) => allowed.includes(value), `a keyword such as ${keywords}`);
}
function strictUnion() {
  return union;
}
var constant = (allowed) => attachDescription((value) => allowed === value, `the value ${JSON.stringify(allowed)}`);
var instanceOf = (instanceType, description) => attachDescription((value) => value instanceof instanceType, description ?? `an instance of ${instanceType.name}`);
var arrayOf = (validator, description, strict = true) => attachDescription(
  (value, context) => {
    if (!isArray(value))
      return false;
    let valid = strict;
    const cleared = [];
    const invalid = [];
    const updateValidity = (result) => {
      valid = strict ? valid && result : valid || result;
    };
    if (value.length === 0) {
      return { valid: true, cleared, invalid };
    }
    for (let i = 0; i < value.length; i++) {
      const options = value[i];
      const result = validator(options, { options, path: `${context.path}[${i}]` });
      if (typeof result === "object") {
        updateValidity(result.valid);
        invalid.push(...result.invalid);
        if (result.cleared != null) {
          cleared.push(result.cleared);
        }
      } else {
        updateValidity(result);
        if (result) {
          cleared.push(options);
        }
      }
    }
    return { valid, cleared: valid || !strict ? cleared : null, invalid };
  },
  description ?? `${validator[descriptionSymbol]} array`
);
var arrayOfDefs = (defs, description = "an object array") => attachDescription((value, context) => {
  if (!isArray(value))
    return false;
  const cleared = [];
  const invalid = [];
  for (let i = 0; i < value.length; i++) {
    const indexPath = `${context.path}[${i}]`;
    const result = validate(value[i], defs, indexPath);
    if (!hasRequiredInPath(result.invalid, indexPath)) {
      cleared.push(result.cleared);
    }
    invalid.push(...result.invalid);
  }
  return { valid: true, cleared, invalid };
}, description);
var callbackOf = (validator, description) => attachDescription((value, context) => {
  if (!isFunction(value))
    return false;
  if (markedSymbol in value)
    return true;
  const validatorDescription = description ?? validator[descriptionSymbol];
  const cbWithValidation = Object.assign(
    (...args) => {
      const result = safeCall(value, args);
      if (result == null)
        return;
      const validatorResult = validator(result, { options: result, path: "" });
      if (typeof validatorResult === "object") {
        warnCallbackErrors(validatorResult, context, validatorDescription, result);
        if (validatorResult.valid) {
          return validatorResult.cleared;
        }
      } else if (validatorResult) {
        return result;
      } else {
        warnOnce(
          `Callback \`${context.path}\` returned an invalid value \`${stringifyValue(result, 50)}\`; expecting ${validatorDescription}, ignoring.`
        );
      }
    },
    { [markedSymbol]: true }
  );
  return { valid: true, cleared: cbWithValidation, invalid: [] };
}, "a function");
var callbackDefs = (defs, description = "an object") => attachDescription((value, context) => {
  if (!isFunction(value))
    return false;
  if (markedSymbol in value)
    return true;
  const validatorDescription = description;
  const cbWithValidation = Object.assign(
    (...args) => {
      const result = safeCall(value, args, context.path);
      if (result == null)
        return;
      const validatorResult = validate(result, defs);
      warnCallbackErrors(validatorResult, context, validatorDescription, result);
      return validatorResult.cleared;
    },
    { [markedSymbol]: true }
  );
  return { valid: true, cleared: cbWithValidation, invalid: [] };
}, "a function");
function hasRequiredInPath(errors, rootPath) {
  return errors.some((error2) => error2.type === "required" /* Required */ && error2.path === rootPath);
}
function warnCallbackErrors(validatorResult, context, description, result) {
  if (validatorResult.invalid.length === 0)
    return;
  if (isArray(result)) {
    const expectedDescription = description ?? validatorResult.invalid[0]?.description ?? "a valid value";
    return warnOnce(
      `Callback \`${context.path}\` returned an invalid value \`${stringifyValue(result, 50)}\`; expecting ${expectedDescription}, ignoring.`
    );
  }
  for (const error2 of validatorResult.invalid) {
    if (error2 instanceof UnknownError) {
      return warnOnce(
        `Callback \`${context.path}\` returned an unknown property \`${extendPath(error2.path, error2.key)}\`${error2.getPostfix()}`
      );
    }
    const errorValue = stringifyValue(error2.value, 50);
    warnOnce(
      error2.key ? `Callback \`${context.path}\` returned an invalid property \`${extendPath(error2.path, error2.key)}\`: \`${errorValue}\`; expecting ${error2.description}, ignoring.` : `Callback \`${context.path}\` returned an invalid value \`${errorValue}\`; expecting ${description ?? error2.description}, ignoring.`
    );
  }
}

// packages/ag-charts-core/src/utils/data/numbers.ts
function clamp(min, value, max) {
  return Math.min(max, Math.max(min, value));
}
function inRange(value, range3, epsilon = 1e-10) {
  return value >= range3[0] - epsilon && value <= range3[1] + epsilon;
}
function isNumberEqual(a, b, epsilon = 1e-10) {
  return a === b || Math.abs(a - b) < epsilon;
}
function isNegative(value) {
  return Math.sign(value) === -1 || Object.is(value, -0);
}
function isInteger(value) {
  return value % 1 === 0;
}
function roundTo(value, decimals = 2) {
  const base = 10 ** decimals;
  return Math.round(value * base) / base;
}
function ceilTo(value, decimals = 2) {
  const base = 10 ** decimals;
  return Math.ceil(value * base) / base;
}
function modulus(n, m) {
  return Math.floor(n % m + (n < 0 ? Math.abs(m) : 0));
}
function countFractionDigits(value) {
  if (Math.floor(value) === value) {
    return 0;
  }
  let valueString = String(value);
  let exponent = 0;
  if (value < 1e-6 || value >= 1e21) {
    let exponentString;
    [valueString, exponentString] = valueString.split("e");
    if (exponentString != null) {
      exponent = Number(exponentString);
    }
  }
  const decimalPlaces2 = valueString.split(".")[1]?.length ?? 0;
  return Math.max(decimalPlaces2 - exponent, 0);
}

// packages/ag-charts-core/src/utils/format/numberFormat.ts
var formatRegEx = /^(?:(.)?([<>=^]))?([+\-( ])?([$€£¥₣₹#])?(0)?(\d+)?(,)?(?:\.(\d+))?(~)?([%a-z])?$/i;
var surroundedRegEx = /^((?:[^#]|#[^{])*)#{([^}]+)}(.*)$/;
function isValidNumberFormat(value) {
  if (!isString(value))
    return false;
  const match = surroundedRegEx.exec(value);
  return formatRegEx.test(match ? match[2] : value);
}
function parseNumberFormat(format) {
  let prefix;
  let suffix;
  const surrounded = surroundedRegEx.exec(format);
  if (surrounded) {
    [, prefix, format, suffix] = surrounded;
  }
  const match = formatRegEx.exec(format);
  if (!match) {
    warnOnce(`The number formatter is invalid: ${format}`);
    return;
  }
  const [, fill, align2, sign, symbol, zero, width2, comma, precision, trim, type] = match;
  return {
    fill,
    align: align2,
    sign,
    symbol,
    zero,
    width: Number.parseInt(width2),
    comma,
    precision: Number.parseInt(precision),
    trim: Boolean(trim),
    type,
    prefix,
    suffix
  };
}
function createNumberFormatter(format) {
  const options = typeof format === "string" ? parseNumberFormat(format) : format;
  if (options == null)
    return;
  const { fill, align: align2, sign = "-", symbol, zero, width: width2, comma, type, prefix = "", suffix = "", precision } = options;
  let { trim } = options;
  const precisionIsNaN = precision == null || Number.isNaN(precision);
  let formatBody;
  if (!type) {
    formatBody = decimalTypes["g"];
    trim = true;
  } else if (type in decimalTypes && type in integerTypes) {
    formatBody = precisionIsNaN ? integerTypes[type] : decimalTypes[type];
  } else if (type in decimalTypes) {
    formatBody = decimalTypes[type];
  } else if (type in integerTypes) {
    formatBody = integerTypes[type];
  } else {
    throw new Error(`The number formatter type is invalid: ${type}`);
  }
  const defaultFormatterPrecision = type ? 6 : 12;
  let formatterPrecision;
  if (!precisionIsNaN) {
    formatterPrecision = precision;
  }
  let padAlign = align2;
  let padFill = fill;
  if (zero) {
    padFill ?? (padFill = "0");
    padAlign ?? (padAlign = "=");
  }
  return (n, fractionDigits) => {
    let effectivePrecision;
    if (formatterPrecision != null) {
      effectivePrecision = formatterPrecision;
    } else if (type === "f" || type === "%") {
      effectivePrecision = fractionDigits ?? defaultFormatterPrecision;
    } else if (type) {
      effectivePrecision = defaultFormatterPrecision;
    } else {
      effectivePrecision = fractionDigits ?? defaultFormatterPrecision;
    }
    let result = formatBody(n, effectivePrecision);
    if (trim) {
      result = removeTrailingZeros(result);
    }
    if (comma) {
      result = insertSeparator(result, comma);
    }
    const symbolPrefix = getSymbolPrefix(symbol, type);
    const symbolPrefixLength = symbolPrefix?.length ?? 0;
    if (symbolPrefix) {
      result = `${symbolPrefix}${result}`;
    }
    if (type === "s") {
      result = `${result}${getSIPrefix(n)}`;
    }
    if (type === "%" || type === "p") {
      result = `${result}%`;
    }
    const { value: signedResult, prefixLength: signPrefixLength } = addSign(n, result, sign);
    const totalPrefixLength = signPrefixLength + symbolPrefixLength;
    let output = signedResult;
    if (width2 != null && !Number.isNaN(width2)) {
      output = addPadding(output, width2, padFill ?? " ", padAlign, totalPrefixLength);
    }
    output = `${prefix}${output}${suffix}`;
    return output;
  };
}
var integerTypes = {
  b: (n) => absFloor(n).toString(2),
  c: (n) => String.fromCodePoint(n),
  d: (n) => Math.round(Math.abs(n)).toFixed(0),
  o: (n) => absFloor(n).toString(8),
  x: (n) => absFloor(n).toString(16),
  X: (n) => integerTypes.x(n).toUpperCase(),
  n: (n) => integerTypes.d(n),
  "%": (n) => `${absFloor(n * 100).toFixed(0)}`
};
var decimalTypes = {
  e: (n, f) => Math.abs(n).toExponential(f),
  E: (n, f) => decimalTypes.e(n, f).toUpperCase(),
  f: (n, f) => Math.abs(n).toFixed(f),
  F: (n, f) => decimalTypes.f(n, f).toUpperCase(),
  g: (n, f) => {
    if (n === 0) {
      return "0";
    }
    const a = Math.abs(n);
    const p = Math.floor(Math.log10(a));
    if (p >= -4 && p < f) {
      return a.toFixed(f - 1 - p);
    }
    return a.toExponential(f - 1);
  },
  G: (n, f) => decimalTypes.g(n, f).toUpperCase(),
  n: (n, f) => decimalTypes.g(n, f),
  p: (n, f) => decimalTypes.r(n * 100, f),
  r: (n, f) => {
    if (n === 0) {
      return "0";
    }
    const a = Math.abs(n);
    const p = Math.floor(Math.log10(a));
    const q = p - (f - 1);
    if (q <= 0) {
      return a.toFixed(-q);
    }
    const x = 10 ** q;
    return (Math.round(a / x) * x).toFixed();
  },
  s: (n, f) => {
    const p = getSIPrefixPower(n);
    return decimalTypes.r(n / 10 ** p, f);
  },
  "%": (n, f) => decimalTypes.f(n * 100, f)
};
var minSIPrefix = -24;
var maxSIPrefix = 24;
var siPrefixes = {
  [minSIPrefix]: "y",
  [-21]: "z",
  [-18]: "a",
  [-15]: "f",
  [-12]: "p",
  [-9]: "n",
  [-6]: "\xB5",
  [-3]: "m",
  [0]: "",
  [3]: "k",
  [6]: "M",
  [9]: "G",
  [12]: "T",
  [15]: "P",
  [18]: "E",
  [21]: "Z",
  [maxSIPrefix]: "Y"
};
var minusSign = "\u2212";
function absFloor(n) {
  return Math.floor(Math.abs(n));
}
function removeTrailingZeros(numString) {
  if (!numString.endsWith("0") || !numString.includes("."))
    return numString;
  let endIndex = numString.length - 1;
  while (endIndex > 0) {
    if (numString[endIndex] == "0") {
      endIndex -= 1;
    } else if (numString[endIndex] == ".") {
      endIndex -= 1;
      break;
    } else {
      break;
    }
  }
  return numString.substring(0, endIndex + 1);
}
function insertSeparator(numString, separator) {
  let dotIndex = numString.indexOf(".");
  if (dotIndex < 0) {
    dotIndex = numString.length;
  }
  const integerChars = numString.substring(0, dotIndex).split("");
  const fractionalPart = numString.substring(dotIndex);
  for (let i = integerChars.length - 3; i > 0; i -= 3) {
    integerChars.splice(i, 0, separator);
  }
  return `${integerChars.join("")}${fractionalPart}`;
}
function getSIPrefix(n) {
  return siPrefixes[getSIPrefixPower(n)];
}
function getSIPrefixPower(n) {
  return clamp(minSIPrefix, n ? Math.floor(Math.log10(Math.abs(n)) / 3) * 3 : 0, maxSIPrefix);
}
function addSign(num, numString, signType = "") {
  if (signType === "(") {
    if (num >= 0) {
      return { value: numString, prefixLength: 0 };
    }
    return { value: `(${numString})`, prefixLength: 1 };
  }
  let signPrefix = "";
  if (num < 0) {
    signPrefix = minusSign;
  } else if (signType === "+") {
    signPrefix = "+";
  } else if (signType === " ") {
    signPrefix = " ";
  }
  return { value: `${signPrefix}${numString}`, prefixLength: signPrefix.length };
}
function addPadding(numString, width2, fill = " ", align2 = ">", prefixLength = 0) {
  const padSize = width2 - numString.length;
  if (padSize <= 0) {
    return numString;
  }
  const padding2 = fill.repeat(padSize);
  if (align2 === "=") {
    const clampedPrefix = Math.min(Math.max(prefixLength, 0), numString.length);
    const start2 = numString.slice(0, clampedPrefix);
    const rest = numString.slice(clampedPrefix);
    return `${start2}${padding2}${rest}`;
  }
  if (align2 === ">" || !align2) {
    return padding2 + numString;
  } else if (align2 === "<") {
    return `${numString}${padding2}`;
  } else if (align2 === "^") {
    const padLeft = Math.ceil(padSize / 2);
    const padRight = Math.floor(padSize / 2);
    return `${fill.repeat(padLeft)}${numString}${fill.repeat(padRight)}`;
  }
  return padding2 + numString;
}
function getSymbolPrefix(symbol, type) {
  if (symbol === "#") {
    switch (type) {
      case "b":
        return "0b";
      case "o":
        return "0o";
      case "x":
        return "0x";
      case "X":
        return "0X";
      default:
        return "";
    }
  }
  return symbol ?? "";
}

// packages/ag-charts-core/src/config/optionsDefaults.ts
var themeOperator = (value) => {
  if (!isObject(value))
    return false;
  const keys = Object.keys(value);
  return keys.length === 1 && keys[0].startsWith("$");
};
var colorStop = optionsDefs({ color, stop: ratio }, "");
var colorStopsOrderValidator = attachDescription((value) => {
  let lastStop = -Infinity;
  for (const item of value) {
    if (item?.stop != null) {
      if (item.stop < lastStop) {
        return false;
      }
      lastStop = item.stop;
    }
  }
  return true;
}, "colour stops to be defined in ascending order");
var gradientColorStops = and(arrayLength(2), arrayOf(colorStop), colorStopsOrderValidator);
var gradientBounds = union("axis", "item", "series");
var gradientStrictDefs = {
  type: required(constant("gradient")),
  colorStops: required(gradientColorStops),
  rotation: number,
  // @ts-expect-error undocumented option
  gradient: undocumented(union("linear", "radial", "conic")),
  bounds: undocumented(gradientBounds),
  reverse: undocumented(boolean),
  colorSpace: undocumented(union("rgb", "oklch"))
};
var gradientStrict = optionsDefs(
  gradientStrictDefs,
  "a gradient object with colour stops"
);
var strokeOptionsDef = {
  stroke: color,
  strokeWidth: positiveNumber,
  strokeOpacity: ratio
};
var fillGradientDefaults = optionsDefs({
  type: required(constant("gradient")),
  gradient: required(union("linear", "radial", "conic")),
  bounds: required(gradientBounds),
  colorStops: required(or(gradientColorStops, and(arrayLength(2), arrayOf(color)))),
  rotation: required(number),
  reverse: required(boolean),
  colorSpace: required(union("rgb", "oklch"))
});
var fillPatternDefaults = optionsDefs({
  type: required(constant("pattern")),
  pattern: required(
    union(
      "vertical-lines",
      "horizontal-lines",
      "forward-slanted-lines",
      "backward-slanted-lines",
      "circles",
      "squares",
      "triangles",
      "diamonds",
      "stars",
      "hearts",
      "crosses"
    )
  ),
  path: stringLength(2),
  width: required(positiveNumber),
  height: required(positiveNumber),
  fill: required(color),
  fillOpacity: required(ratio),
  backgroundFill: required(color),
  backgroundFillOpacity: required(ratio),
  padding: required(positiveNumber),
  rotation: required(number),
  scale: required(positiveNumber),
  stroke: required(color),
  strokeWidth: required(positiveNumber),
  strokeOpacity: required(ratio)
});
var fillImageDefaults = optionsDefs({
  type: required(constant("image")),
  url: string,
  width: positiveNumber,
  height: positiveNumber,
  rotation: required(number),
  backgroundFill: required(color),
  backgroundFillOpacity: ratio,
  fit: required(union("stretch", "contain", "cover")),
  repeat: required(union("repeat", "repeat-x", "repeat-y", "no-repeat"))
});
var colorObjectDefs = {
  // @ts-expect-error undocumented option
  gradient: {
    colorStops: gradientColorStops,
    rotation: number,
    gradient: undocumented(union("linear", "radial", "conic")),
    bounds: undocumented(gradientBounds),
    reverse: undocumented(boolean),
    colorSpace: undocumented(union("rgb", "oklch"))
  },
  pattern: {
    pattern: union(
      "vertical-lines",
      "horizontal-lines",
      "forward-slanted-lines",
      "backward-slanted-lines",
      "circles",
      "squares",
      "triangles",
      "diamonds",
      "stars",
      "hearts",
      "crosses"
    ),
    path: stringLength(2),
    width: positiveNumber,
    height: positiveNumber,
    rotation: number,
    scale: positiveNumber,
    fill: color,
    fillOpacity: ratio,
    backgroundFill: color,
    backgroundFillOpacity: ratio,
    ...strokeOptionsDef,
    padding: undocumented(positiveNumber)
  },
  image: {
    url: required(string),
    backgroundFill: color,
    backgroundFillOpacity: ratio,
    width: positiveNumber,
    height: positiveNumber,
    fit: union("stretch", "contain", "cover", "none"),
    repeat: union("repeat", "repeat-x", "repeat-y", "no-repeat"),
    rotation: number
  }
};
var colorObject = typeUnion(colorObjectDefs, "a color object");
var colorUnion = or(color, optionsDefs(colorObject, "a color object"));
var fillOptionsDef = {
  fill: colorUnion,
  fillOpacity: ratio
};
fillOptionsDef.fillGradientDefaults = undocumented(fillGradientDefaults);
fillOptionsDef.fillPatternDefaults = undocumented(fillPatternDefaults);
fillOptionsDef.fillImageDefaults = undocumented(fillImageDefaults);
var lineDashOptionsDef = {
  lineDash: arrayOf(positiveNumber),
  lineDashOffset: number
};
var barHighlightOptionsDef = {
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  opacity: ratio,
  cornerRadius: positiveNumber
};
var lineHighlightOptionsDef = {
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  opacity: ratio
};
var shapeHighlightOptionsDef = {
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  opacity: ratio
};
function highlightOptionsDef(itemHighlightOptionsDef) {
  return {
    enabled: boolean,
    range: union("tooltip", "node"),
    highlightedItem: itemHighlightOptionsDef,
    unhighlightedItem: itemHighlightOptionsDef
  };
}
function multiSeriesHighlightOptionsDef(itemHighlightOptionsDef, seriesHighlightOptionsDef) {
  return {
    enabled: boolean,
    range: union("tooltip", "node"),
    highlightedItem: itemHighlightOptionsDef,
    unhighlightedItem: itemHighlightOptionsDef,
    highlightedSeries: seriesHighlightOptionsDef,
    unhighlightedSeries: seriesHighlightOptionsDef,
    bringToFront: boolean
  };
}
var shapeSegmentOptions = {
  start: defined,
  stop: defined,
  ...strokeOptionsDef,
  ...fillOptionsDef,
  ...lineDashOptionsDef
};
var lineSegmentOptions = {
  start: defined,
  stop: defined,
  ...strokeOptionsDef,
  ...lineDashOptionsDef
};
var shapeSegmentation = optionsDefs(
  {
    enabled: boolean,
    key: required(union("x", "y")),
    segments: arrayOfDefs(shapeSegmentOptions, "path segments array")
  },
  "a segmentation object",
  true
);
var lineSegmentation = optionsDefs(
  {
    enabled: boolean,
    key: required(union("x", "y")),
    segments: arrayOfDefs(lineSegmentOptions, "path segments array")
  },
  "a segmentation object",
  true
);
var googleFont = optionsDefs({ googleFont: string }, "google font");
var fontFamilyFull = or(string, themeOperator, googleFont, arrayOf(or(string, googleFont)));
var fontWeight = or(positiveNumber, union("normal", "bold", "bolder", "lighter"));
var fontOptionsDef = {
  color,
  fontFamily: fontFamilyFull,
  fontSize: positiveNumber,
  fontStyle: union("normal", "italic", "oblique"),
  fontWeight
};
var paddingOptions = optionsDefs(
  { top: number, right: number, bottom: number, left: number },
  "padding object"
);
var padding = or(number, paddingOptions);
var borderOptionsDef = {
  enabled: boolean,
  stroke: color,
  strokeWidth: positiveNumber,
  strokeOpacity: ratio
};
var labelBoxOptionsDef = {
  border: borderOptionsDef,
  cornerRadius: number,
  padding,
  ...fillOptionsDef
};

// packages/ag-charts-core/src/config/chartDefaults.ts
var legendPlacementLiterals = [
  "top",
  "top-right",
  "top-left",
  "bottom",
  "bottom-right",
  "bottom-left",
  "right",
  "right-top",
  "right-bottom",
  "left",
  "left-top",
  "left-bottom"
];
var legendPositionOptionsDef = {
  floating: boolean,
  placement: union(...legendPlacementLiterals),
  xOffset: number,
  yOffset: number
};
var legendPositionValidator = attachDescription(
  (value, context) => {
    let result;
    if (typeof value === "string") {
      const allowedValues = legendPlacementLiterals;
      if (allowedValues.includes(value)) {
        result = true;
      } else {
        result = { valid: false, invalid: [], cleared: null };
        result.invalid.push(
          new ValidationError(
            "invalid" /* Invalid */,
            `a legend placement string: ["${legendPlacementLiterals.join('", "')}"]`,
            value,
            context.path
          )
        );
      }
    } else {
      const { cleared, invalid } = validate(value, legendPositionOptionsDef);
      result = { valid: invalid.length === 0, cleared, invalid };
    }
    return result;
  },
  `a legend position object or placement string`
);
var shapeValidator = or(
  union("circle", "cross", "diamond", "heart", "plus", "pin", "square", "star", "triangle"),
  callback
);
var textWrapValidator = union("never", "always", "hyphenate", "on-space");
var tooltipPlacementValidator = union(
  "top",
  "right",
  "bottom",
  "left",
  "top-right",
  "bottom-right",
  "bottom-left",
  "top-left",
  "center"
);
var rangeValidator = or(positiveNumber, union("exact", "nearest", "area"));
var seriesTooltipRangeValidator = or(positiveNumber, union("exact", "nearest"));
var textOrSegments = or(
  string,
  number,
  date,
  arrayOfDefs(
    {
      text: required(string),
      ...fontOptionsDef
    },
    "text segments array"
  )
);
var chartCaptionOptionsDefs = {
  enabled: boolean,
  text: textOrSegments,
  textAlign: union("left", "center", "right"),
  wrapping: union("never", "always", "hyphenate", "on-space"),
  spacing: positiveNumber,
  maxWidth: positiveNumber,
  maxHeight: positiveNumber,
  ...fontOptionsDef
};
chartCaptionOptionsDefs.padding = undocumented(positiveNumber);
var chartOverlayOptionsDefs = {
  enabled: boolean,
  text: textOrSegments,
  renderer: callbackOf(or(string, htmlElement))
};
var contextMenuItemLiterals = [
  "defaults",
  "download",
  "zoom-to-cursor",
  "pan-to-cursor",
  "reset-zoom",
  "toggle-series-visibility",
  "toggle-other-series",
  "separator"
];
var contextMenuItemObjectDef = {
  type: union("action", "separator"),
  showOn: union("always", "series-area", "series-node", "legend-item"),
  label: required(string),
  enabled: boolean,
  action: callback,
  items: (value, context) => contextMenuItemsArray(value, context)
};
contextMenuItemObjectDef.iconUrl = undocumented(string);
var contextMenuItemObjectValidator = optionsDefs(contextMenuItemObjectDef);
var contextMenuItemValidator = attachDescription(
  (value, context) => {
    let result;
    if (typeof value === "string") {
      const allowedValues = contextMenuItemLiterals;
      if (allowedValues.includes(value)) {
        result = true;
      } else {
        result = { valid: false, invalid: [], cleared: null };
        result.invalid.push(
          new ValidationError(
            "invalid" /* Invalid */,
            `a context menu item string alias: ["${contextMenuItemLiterals.join('", "')}"]`,
            value,
            context.path
          )
        );
      }
    } else {
      result = contextMenuItemObjectValidator(value, context);
    }
    return result;
  },
  `a context menu item object or string alias: [${contextMenuItemLiterals.join(", ")}]`
);
var contextMenuItemsArray = arrayOf(contextMenuItemValidator, "a menu items array", false);
var toolbarButtonOptionsDefs = {
  label: string,
  ariaLabel: string,
  tooltip: string,
  icon: union(
    "align-center",
    "align-left",
    "align-right",
    "arrow-drawing",
    "arrow-down-drawing",
    "arrow-up-drawing",
    "callout-annotation",
    "candlestick-series",
    "close",
    "comment-annotation",
    "date-range-drawing",
    "date-price-range-drawing",
    "delete",
    "disjoint-channel-drawing",
    "drag-handle",
    "fill-color",
    "line-style-solid",
    "line-style-dashed",
    "line-style-dotted",
    "high-low-series",
    "hlc-series",
    "hollow-candlestick-series",
    "horizontal-line-drawing",
    "line-color",
    "line-series",
    "line-with-markers-series",
    "locked",
    "measurer-drawing",
    "note-annotation",
    "ohlc-series",
    "pan-end",
    "pan-left",
    "pan-right",
    "pan-start",
    "parallel-channel-drawing",
    "position-bottom",
    "position-center",
    "position-top",
    "price-label-annotation",
    "price-range-drawing",
    "reset",
    "settings",
    "step-line-series",
    "text-annotation",
    "trend-line-drawing",
    "fibonacci-retracement-drawing",
    "fibonacci-retracement-trend-based-drawing",
    "unlocked",
    "vertical-line-drawing",
    "zoom-in",
    "zoom-out"
  )
};
var formatter = or(string, callbackOf(textOrSegments));
var formatObjectValidator = optionsDefs({
  x: formatter,
  y: formatter,
  angle: formatter,
  radius: formatter,
  size: formatter,
  color: formatter,
  label: formatter,
  secondaryLabel: formatter,
  sectorLabel: formatter,
  calloutLabel: formatter,
  legendItem: formatter
});
var numberFormatValidator = attachDescription(isValidNumberFormat, "a valid number format string");
var commonChartOptionsDefs = {
  width: positiveNumber,
  height: positiveNumber,
  minWidth: positiveNumber,
  minHeight: positiveNumber,
  suppressFieldDotNotation: boolean,
  title: chartCaptionOptionsDefs,
  subtitle: chartCaptionOptionsDefs,
  footnote: chartCaptionOptionsDefs,
  padding: {
    top: positiveNumber,
    right: positiveNumber,
    bottom: positiveNumber,
    left: positiveNumber
  },
  seriesArea: {
    border: borderOptionsDef,
    clip: boolean,
    cornerRadius: number,
    padding
  },
  legend: {
    enabled: boolean,
    position: legendPositionValidator,
    orientation: union("horizontal", "vertical"),
    maxWidth: positiveNumber,
    maxHeight: positiveNumber,
    spacing: positiveNumber,
    border: borderOptionsDef,
    cornerRadius: number,
    padding,
    fill: colorUnion,
    fillOpacity: ratio,
    preventHidingAll: boolean,
    reverseOrder: boolean,
    toggleSeries: boolean,
    item: {
      marker: {
        size: positiveNumber,
        shape: shapeValidator,
        padding: positiveNumber,
        strokeWidth: positiveNumber
      },
      line: {
        length: positiveNumber,
        strokeWidth: positiveNumber
      },
      label: {
        maxLength: positiveNumber,
        formatter: callback,
        ...fontOptionsDef
      },
      maxWidth: positiveNumber,
      paddingX: positiveNumber,
      paddingY: positiveNumber,
      showSeriesStroke: boolean
    },
    pagination: {
      marker: {
        size: positiveNumber,
        shape: shapeValidator,
        padding: positiveNumber
      },
      activeStyle: {
        ...fillOptionsDef,
        ...strokeOptionsDef
      },
      inactiveStyle: {
        ...fillOptionsDef,
        ...strokeOptionsDef
      },
      highlightStyle: {
        ...fillOptionsDef,
        ...strokeOptionsDef
      },
      label: fontOptionsDef
    },
    listeners: {
      legendItemClick: callback,
      legendItemDoubleClick: callback
    }
  },
  gradientLegend: {
    enabled: boolean,
    position: legendPositionValidator,
    spacing: positiveNumber,
    reverseOrder: boolean,
    border: borderOptionsDef,
    cornerRadius: number,
    padding,
    fill: colorUnion,
    fillOpacity: ratio,
    gradient: {
      preferredLength: positiveNumber,
      thickness: positiveNumber
    },
    scale: {
      label: {
        ...fontOptionsDef,
        minSpacing: positiveNumber,
        format: numberFormatValidator,
        formatter: callback
      },
      padding: positiveNumber,
      interval: {
        step: number,
        values: array,
        minSpacing: and(positiveNumber, lessThan("maxSpacing")),
        maxSpacing: and(positiveNumber, greaterThan("minSpacing"))
      }
    }
  },
  listeners: {
    seriesNodeClick: callback,
    seriesNodeDoubleClick: callback,
    seriesVisibilityChange: callback,
    activeChange: callback,
    click: callback,
    doubleClick: callback,
    annotations: callback,
    zoom: callback
  },
  loadGoogleFonts: boolean,
  highlight: {
    drawingMode: union("overlay", "cutout"),
    range: union("tooltip", "node")
  },
  overlays: {
    loading: chartOverlayOptionsDefs,
    noData: chartOverlayOptionsDefs,
    noVisibleSeries: chartOverlayOptionsDefs,
    unsupportedBrowser: chartOverlayOptionsDefs
  },
  tooltip: {
    enabled: boolean,
    showArrow: boolean,
    pagination: boolean,
    delay: positiveNumber,
    range: rangeValidator,
    wrapping: textWrapValidator,
    mode: union("single", "shared", "compact"),
    position: {
      anchorTo: union("pointer", "node", "chart"),
      placement: or(tooltipPlacementValidator, arrayOf(tooltipPlacementValidator)),
      xOffset: number,
      yOffset: number
    }
  },
  animation: defined,
  contextMenu: defined,
  context: () => true,
  dataSource: {
    getData: callback
  },
  keyboard: {
    enabled: boolean,
    tabIndex: number
  },
  touch: {
    dragAction: union("none", "drag", "hover")
  },
  ranges: {
    enabled: boolean,
    buttons: arrayOfDefs(
      {
        ...toolbarButtonOptionsDefs,
        value: or(number, and(arrayOf(or(number, date)), arrayLength(2, 2)), callback)
      },
      "range button options array"
    )
  },
  // modules
  locale: {
    localeText: object,
    getLocaleText: callbackOf(string)
  },
  background: {
    visible: boolean,
    fill: color,
    // enterprise
    image: {
      url: required(string),
      top: number,
      right: number,
      bottom: number,
      left: number,
      width: positiveNumber,
      height: positiveNumber,
      opacity: ratio
    }
  },
  styleNonce: string,
  sync: defined,
  zoom: defined,
  scrollbar: defined,
  formatter: or(callbackOf(textOrSegments), formatObjectValidator)
};
commonChartOptionsDefs.flashOnUpdate = undocumented(defined);
commonChartOptionsDefs.dataSource.requestThrottle = undocumented(positiveNumber);
commonChartOptionsDefs.dataSource.updateThrottle = undocumented(positiveNumber);
commonChartOptionsDefs.dataSource.updateDuringInteraction = undocumented(boolean);
commonChartOptionsDefs.statusBar = undocumented(defined);
commonChartOptionsDefs.foreground = undocumented({
  visible: boolean,
  text: string,
  image: {
    url: string,
    top: number,
    right: number,
    bottom: number,
    left: number,
    width: positiveNumber,
    height: positiveNumber,
    opacity: ratio
  },
  ...fillOptionsDef
});
commonChartOptionsDefs.overrideDevicePixelRatio = undocumented(number);
commonChartOptionsDefs.sync.domainMode = undocumented(union("direction", "position", "key"));
commonChartOptionsDefs.displayNullData = undocumented(boolean);
var commonSeriesThemeableOptionsDefs = {
  cursor: string,
  context: () => true,
  showInLegend: boolean,
  nodeClickRange: rangeValidator,
  listeners: {
    seriesNodeClick: callback,
    seriesNodeDoubleClick: callback
  },
  highlight: highlightOptionsDef(shapeHighlightOptionsDef)
};
commonSeriesThemeableOptionsDefs.allowNullKeys = undocumented(boolean);
var commonSeriesOptionsDefs = {
  ...commonSeriesThemeableOptionsDefs,
  id: string,
  visible: boolean,
  context: () => true,
  data: array
};
commonSeriesOptionsDefs.seriesGrouping = undocumented(defined);
var markerStyleOptionsDefs = {
  shape: shapeValidator,
  size: positiveNumber,
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef
};
var markerOptionsDefs = {
  enabled: boolean,
  itemStyler: callbackDefs({
    ...fillOptionsDef,
    ...strokeOptionsDef,
    ...lineDashOptionsDef,
    shape: shapeValidator,
    size: positiveNumber
  }),
  ...markerStyleOptionsDefs
};
var seriesLabelOptionsDefs = {
  enabled: boolean,
  formatter: callbackOf(textOrSegments),
  format: numberFormatValidator,
  itemStyler: callbackDefs({
    enabled: boolean,
    ...labelBoxOptionsDef,
    ...fontOptionsDef
  }),
  ...labelBoxOptionsDef,
  ...fontOptionsDef
};
var autoSizedLabelOptionsDefs = {
  ...seriesLabelOptionsDefs,
  lineHeight: positiveNumber,
  minimumFontSize: positiveNumber,
  wrapping: textWrapValidator,
  overflowStrategy: union("ellipsis", "hide")
};
var errorBarThemeableOptionsDefs = {
  visible: boolean,
  cap: {
    visible: boolean,
    length: positiveNumber,
    lengthRatio: ratio,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  },
  ...strokeOptionsDef,
  ...lineDashOptionsDef
};
var errorBarOptionsDefs = {
  ...errorBarThemeableOptionsDefs,
  xLowerKey: string,
  xUpperKey: string,
  yLowerKey: string,
  yUpperKey: string,
  xLowerName: string,
  xUpperName: string,
  yLowerName: string,
  yUpperName: string,
  itemStyler: callbackDefs({
    visible: boolean,
    ...strokeOptionsDef,
    ...lineDashOptionsDef,
    cap: {
      visible: boolean,
      length: positiveNumber,
      lengthRatio: ratio,
      ...strokeOptionsDef,
      ...lineDashOptionsDef
    }
  })
};
var tooltipOptionsDefs = {
  enabled: boolean,
  showArrow: boolean,
  range: seriesTooltipRangeValidator,
  renderer: callbackOf(
    or(
      string,
      number,
      date,
      optionsDefs(
        {
          heading: string,
          title: string,
          symbol: {
            marker: {
              enabled: boolean,
              shape: shapeValidator,
              ...fillOptionsDef,
              stroke: color,
              strokeOpacity: ratio,
              strokeWidth: positiveNumber,
              ...lineDashOptionsDef
            },
            line: {
              enabled: boolean,
              stroke: color,
              strokeWidth: positiveNumber,
              strokeOpacity: ratio,
              ...lineDashOptionsDef
            }
          },
          data: arrayOfDefs({
            label: required(string),
            value: required(or(string, number, date))
          })
        },
        "tooltip renderer result object"
      )
    )
  ),
  position: {
    anchorTo: union("node", "pointer", "chart"),
    placement: or(tooltipPlacementValidator, arrayOf(tooltipPlacementValidator)),
    xOffset: number,
    yOffset: number
  },
  interaction: {
    enabled: boolean
  }
};
var tooltipOptionsDefsWithArea = {
  ...tooltipOptionsDefs,
  range: rangeValidator
};
var shadowOptionsDefs = {
  enabled: boolean,
  xOffset: number,
  yOffset: number,
  blur: positiveNumber,
  color
};
var interpolationOptionsDefs = typeUnion(
  {
    linear: {},
    smooth: {
      tension: ratio
    },
    step: {
      position: union("start", "middle", "end")
    }
  },
  "interpolation line options"
);

// packages/ag-charts-core/src/utils/types/decorator.ts
var BREAK_TRANSFORM_CHAIN = Symbol("BREAK");
var CONFIG_KEY = "__decorator_config";
var ACCESSORS_KEY = "__decorator_accessors";
function addFakeTransformToInstanceProperty(target, propertyKeyOrSymbol) {
  initialiseConfig(target, propertyKeyOrSymbol).optional = true;
}
function initialiseConfig(target, propertyKeyOrSymbol) {
  if (Object.getOwnPropertyDescriptor(target, CONFIG_KEY) == null) {
    Object.defineProperty(target, CONFIG_KEY, { value: {} });
  }
  if (Object.getOwnPropertyDescriptor(target, ACCESSORS_KEY) == null) {
    const parentAccessors = Object.getPrototypeOf(target)?.[ACCESSORS_KEY];
    const accessors = parentAccessors?.slice() ?? [];
    Object.defineProperty(target, ACCESSORS_KEY, { value: accessors });
  }
  const config = target[CONFIG_KEY];
  const propertyKey = propertyKeyOrSymbol.toString();
  if (config[propertyKey] != null) {
    return config[propertyKey];
  }
  config[propertyKey] = { setters: [], getters: [], observers: [] };
  const descriptor = Object.getOwnPropertyDescriptor(target, propertyKeyOrSymbol);
  let prevGet = descriptor?.get;
  let prevSet = descriptor?.set;
  if (prevGet == null || prevSet == null) {
    const accessors = target[ACCESSORS_KEY];
    let index = accessors.indexOf(propertyKeyOrSymbol);
    if (index === -1) {
      index = accessors.push(propertyKeyOrSymbol) - 1;
    }
    prevGet ?? (prevGet = function() {
      let accessorValues = this.__accessors;
      if (accessorValues == null) {
        accessorValues = accessors.slice().fill(void 0);
        Object.defineProperty(this, "__accessors", { value: accessorValues });
      }
      return accessorValues[index];
    });
    prevSet ?? (prevSet = function(value) {
      let accessorValues = this.__accessors;
      if (accessorValues == null) {
        accessorValues = accessors.slice().fill(void 0);
        Object.defineProperty(this, "__accessors", { value: accessorValues });
      }
      accessorValues[index] = value;
    });
  }
  const getter = function() {
    let value = prevGet.call(this);
    for (const transformFn of config[propertyKey].getters) {
      value = transformFn(this, propertyKeyOrSymbol, value);
      if (value === BREAK_TRANSFORM_CHAIN) {
        return;
      }
    }
    return value;
  };
  const setter = function(value) {
    const { setters, observers } = config[propertyKey];
    let oldValue;
    if (setters.some((f) => f.length > 2)) {
      oldValue = prevGet.call(this);
    }
    for (const transformFn of setters) {
      value = transformFn(this, propertyKeyOrSymbol, value, oldValue);
      if (value === BREAK_TRANSFORM_CHAIN) {
        return;
      }
    }
    prevSet.call(this, value);
    for (const observerFn of observers) {
      observerFn(this, value, oldValue);
    }
  };
  Object.defineProperty(target, propertyKeyOrSymbol, {
    set: setter,
    get: getter,
    enumerable: true,
    configurable: false
  });
  return config[propertyKey];
}
function addTransformToInstanceProperty(setTransform, getTransform, configMetadata) {
  return (target, propertyKeyOrSymbol) => {
    const config = initialiseConfig(target, propertyKeyOrSymbol);
    config.setters.push(setTransform);
    if (getTransform) {
      config.getters.unshift(getTransform);
    }
    if (configMetadata) {
      Object.assign(config, configMetadata);
    }
  };
}
function addObserverToInstanceProperty(setObserver) {
  return (target, propertyKeyOrSymbol) => {
    initialiseConfig(target, propertyKeyOrSymbol).observers.push(setObserver);
  };
}
function isDecoratedObject(target) {
  return target !== void 0 && CONFIG_KEY in target;
}
function listDecoratedProperties(target) {
  const targets = /* @__PURE__ */ new Set();
  while (isDecoratedObject(target)) {
    targets.add(target?.[CONFIG_KEY]);
    target = Object.getPrototypeOf(target);
  }
  return Array.from(targets).flatMap((configMap) => Object.keys(configMap));
}
function extractDecoratedProperties(target) {
  return listDecoratedProperties(target).reduce((result, key) => {
    result[String(key)] = target[key] ?? null;
    return result;
  }, {});
}

// packages/ag-charts-core/src/utils/data/iterators.ts
function* iterate(...items) {
  for (const item of items) {
    if (item == null)
      continue;
    if (item[Symbol.iterator]) {
      yield* item;
    } else {
      yield item;
    }
  }
}
function toIterable(value) {
  return value != null && typeof value === "object" && Symbol.iterator in value ? value : [value];
}
function first(iterable) {
  for (const value of iterable) {
    return value;
  }
  throw new Error("AG Charts - no first() value found");
}
function* entries(obj) {
  const resultTuple = [void 0, void 0];
  for (const key of Object.keys(obj)) {
    resultTuple[0] = key;
    resultTuple[1] = obj[key];
    yield resultTuple;
  }
}

// packages/ag-charts-core/src/utils/data/object.ts
function strictObjectKeys(o) {
  return Object.keys(o);
}
function objectsEqual(a, b) {
  if (Array.isArray(a)) {
    if (!Array.isArray(b))
      return false;
    if (a.length !== b.length)
      return false;
    return a.every((av, i) => objectsEqual(av, b[i]));
  } else if (isPlainObject(a)) {
    if (!isPlainObject(b))
      return false;
    return objectsEqualWith(a, b, objectsEqual);
  }
  return a === b;
}
function objectsEqualWith(a, b, cmp2) {
  if (Object.is(a, b))
    return true;
  for (const key of Object.keys(b)) {
    if (!(key in a))
      return false;
  }
  for (const key of Object.keys(a)) {
    if (!(key in b))
      return false;
    if (!cmp2(a[key], b[key]))
      return false;
  }
  return true;
}
function mergeDefaults(...sources) {
  const target = {};
  for (const source of sources) {
    if (!isObject(source))
      continue;
    const keys = isDecoratedObject(source) ? listDecoratedProperties(source) : Object.keys(source);
    for (const key of keys) {
      if (isPlainObject(target[key]) && isPlainObject(source[key])) {
        target[key] = mergeDefaults(target[key], source[key]);
      } else {
        target[key] ?? (target[key] = source[key]);
      }
    }
  }
  return target;
}
function merge(...sources) {
  const target = {};
  for (const source of sources) {
    if (!isObject(source))
      continue;
    const keys = isDecoratedObject(source) ? listDecoratedProperties(source) : Object.keys(source);
    for (const key of keys) {
      if (isPlainObject(target[key]) && isPlainObject(source[key])) {
        target[key] = merge(target[key], source[key]);
      } else if (!(key in target)) {
        target[key] ?? (target[key] = source[key]);
      }
    }
  }
  return target;
}
function mergeArrayDefaults(dataArray, ...itemDefaults) {
  if (itemDefaults && isArray(dataArray)) {
    return dataArray.map((item) => mergeDefaults(item, ...itemDefaults));
  }
  return dataArray;
}
function mapValues(object2, mapper) {
  const result = {};
  for (const [key, value] of entries(object2)) {
    result[key] = mapper(value, key, object2);
  }
  return result;
}
function without(object2, keys) {
  const clone2 = { ...object2 };
  for (const key of keys) {
    delete clone2[key];
  }
  return clone2;
}
function pick(object2, keys) {
  if (object2 == null)
    return;
  const picked = {};
  for (const key of keys) {
    if (Object.hasOwn(object2, key)) {
      picked[key] = object2[key];
    }
  }
  return picked;
}
function every(object2, fn) {
  if (object2 == null)
    return true;
  for (const [key, value] of entries(object2)) {
    if (!fn(key, value))
      return false;
  }
  return true;
}
function fromPairs(pairs) {
  const object2 = {};
  if (pairs == null)
    return object2;
  for (const [key, value] of pairs) {
    object2[key] = value;
  }
  return object2;
}
function getPath(object2, path) {
  const pathArray = isArray(path) ? path : path.split(".");
  return pathArray.reduce((value, pathKey) => value[pathKey], object2);
}
var SKIP_JS_BUILTINS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
function setPath(object2, path, newValue) {
  const pathArray = isArray(path) ? path.slice() : path.split(".");
  const lastKey = pathArray.pop();
  if (pathArray.some((p) => SKIP_JS_BUILTINS.has(p)))
    return;
  const lastObject = pathArray.reduce((value, pathKey) => value[pathKey], object2);
  lastObject[lastKey] = newValue;
  return lastObject[lastKey];
}
function partialAssign(keysToCopy, target, source) {
  if (source === void 0) {
    return target;
  }
  for (const key of keysToCopy) {
    const value = source[key];
    if (value !== void 0) {
      target[key] = value;
    }
  }
  return target;
}
function assignIfNotStrictlyEqual(target, source, keys) {
  const sourceKeys = keys ?? Object.keys(source);
  for (let i = 0, len = sourceKeys.length; i < len; i++) {
    const key = sourceKeys[i];
    const newValue = source[key];
    if (target[key] !== newValue) {
      target[key] = newValue;
    }
  }
  return target;
}
function deepFreeze(obj) {
  if (obj == null || typeof obj !== "object" || !isPlainObject(obj)) {
    return obj;
  }
  Object.freeze(obj);
  for (const prop of Object.getOwnPropertyNames(obj)) {
    const value = obj[prop];
    if (value !== null && (typeof value === "object" || typeof value === "function") && !Object.isFrozen(value)) {
      deepFreeze(value);
    }
  }
  return obj;
}
function isObjectWithProperty(obj, key) {
  return isPlainObject(obj) && key in obj;
}
function isObjectWithStringProperty(obj, key) {
  return isObjectWithProperty(obj, key) && typeof obj[key] === "string";
}

// packages/ag-charts-core/src/config/gaugePreset.ts
var fillsOptionsDef = {
  fills: and(
    arrayLength(2),
    arrayOf(optionsDefs({ color, stop: number }, "")),
    colorStopsOrderValidator
  ),
  fillMode: union("continuous", "discrete")
};
var linearGaugeTargetOptionsDef = {
  value: required(number),
  text: string,
  shape: or(
    union("circle", "cross", "diamond", "heart", "plus", "pin", "square", "star", "triangle", "line"),
    callback
  ),
  placement: union("before", "after", "middle"),
  spacing: positiveNumber,
  size: positiveNumber,
  rotation: number,
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef
};
var radialGaugeTargetOptionsDef = {
  value: required(number),
  text: string,
  shape: or(
    union("circle", "cross", "diamond", "heart", "plus", "pin", "square", "star", "triangle", "line"),
    callback
  ),
  placement: union("inside", "outside", "middle"),
  spacing: positiveNumber,
  size: positiveNumber,
  rotation: number,
  label: {
    ...seriesLabelOptionsDefs,
    spacing: positiveNumber
  },
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef
};
var linearGaugeSeriesThemeableOptionsDef = {
  ...without(commonSeriesThemeableOptionsDefs, ["listeners"]),
  direction: union("horizontal", "vertical"),
  cornerMode: union("container", "item"),
  cornerRadius: positiveNumber,
  thickness: positiveNumber,
  segmentation: {
    enabled: boolean,
    spacing: positiveNumber,
    interval: {
      values: arrayOf(number),
      step: number,
      count: number
    }
  },
  bar: {
    enabled: boolean,
    thickness: positiveNumber,
    thicknessRatio: ratio,
    ...fillsOptionsDef,
    ...fillOptionsDef,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  },
  label: {
    ...autoSizedLabelOptionsDefs,
    text: string,
    spacing: positiveNumber,
    avoidCollisions: boolean,
    placement: union(
      "inside-start",
      "outside-start",
      "inside-end",
      "outside-end",
      "inside-center",
      "bar-inside",
      "bar-inside-end",
      "bar-outside-end",
      "bar-end"
    )
  },
  tooltip: tooltipOptionsDefs
};
var linearGaugeSeriesOptionsDef = {
  ...without(commonSeriesOptionsDefs, ["listeners"]),
  ...linearGaugeSeriesThemeableOptionsDef,
  type: required(constant("linear-gauge")),
  value: required(number),
  scale: {
    min: and(number, lessThan("max")),
    max: and(number, greaterThan("min")),
    label: {
      enabled: boolean,
      formatter: callback,
      rotation: number,
      spacing: positiveNumber,
      minSpacing: positiveNumber,
      placement: union("before", "after"),
      avoidCollisions: boolean,
      format: numberFormatValidator,
      ...fontOptionsDef
    },
    interval: {
      values: arrayOf(number),
      step: number
    },
    ...fillsOptionsDef,
    ...fillOptionsDef,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  },
  targets: arrayOfDefs(linearGaugeTargetOptionsDef, "target options array")
};
linearGaugeSeriesOptionsDef.margin = undocumented(number);
linearGaugeSeriesOptionsDef.defaultColorRange = undocumented(arrayOf(color));
linearGaugeSeriesOptionsDef.defaultTarget = undocumented({
  ...linearGaugeTargetOptionsDef,
  value: number,
  label: {
    ...seriesLabelOptionsDefs,
    spacing: number
  }
});
linearGaugeSeriesOptionsDef.defaultScale = undocumented(linearGaugeSeriesOptionsDef.scale);
linearGaugeSeriesOptionsDef.scale.defaultFill = undocumented(color);
var radialGaugeSeriesThemeableOptionsDef = {
  ...without(commonSeriesThemeableOptionsDefs, ["listeners"]),
  outerRadius: positiveNumber,
  innerRadius: positiveNumber,
  outerRadiusRatio: ratio,
  innerRadiusRatio: ratio,
  startAngle: number,
  endAngle: number,
  spacing: positiveNumber,
  cornerMode: union("container", "item"),
  cornerRadius: positiveNumber,
  scale: {
    min: and(number, lessThan("max")),
    max: and(number, greaterThan("min")),
    label: {
      enabled: boolean,
      formatter: callback,
      rotation: number,
      spacing: positiveNumber,
      minSpacing: positiveNumber,
      avoidCollisions: boolean,
      format: numberFormatValidator,
      ...fontOptionsDef
    },
    interval: {
      values: arrayOf(number),
      step: number
    },
    ...fillsOptionsDef,
    ...fillOptionsDef,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  },
  segmentation: {
    enabled: boolean,
    spacing: positiveNumber,
    interval: {
      values: arrayOf(number),
      step: number,
      count: number
    }
  },
  bar: {
    enabled: boolean,
    ...fillsOptionsDef,
    ...fillOptionsDef,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  },
  needle: {
    enabled: boolean,
    spacing: positiveNumber,
    radiusRatio: ratio,
    ...fillOptionsDef,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  },
  label: {
    text: string,
    spacing: positiveNumber,
    ...autoSizedLabelOptionsDefs
  },
  secondaryLabel: {
    text: string,
    ...autoSizedLabelOptionsDefs
  },
  tooltip: tooltipOptionsDefs
};
var radialGaugeSeriesOptionsDef = {
  ...without(commonSeriesOptionsDefs, ["listeners"]),
  ...radialGaugeSeriesThemeableOptionsDef,
  type: required(constant("radial-gauge")),
  value: required(number),
  targets: arrayOfDefs(radialGaugeTargetOptionsDef, "target options array")
};
radialGaugeSeriesOptionsDef.defaultColorRange = undocumented(arrayOf(color));
radialGaugeSeriesOptionsDef.defaultTarget = undocumented({
  ...radialGaugeTargetOptionsDef,
  value: number,
  label: {
    ...seriesLabelOptionsDefs,
    spacing: number
  }
});
radialGaugeSeriesOptionsDef.scale.defaultFill = undocumented(color);

// packages/ag-charts-core/src/types/themeConstants.ts
var FONT_SIZE = /* @__PURE__ */ ((FONT_SIZE2) => {
  FONT_SIZE2[FONT_SIZE2["SMALLEST"] = 8] = "SMALLEST";
  FONT_SIZE2[FONT_SIZE2["SMALLER"] = 10] = "SMALLER";
  FONT_SIZE2[FONT_SIZE2["SMALL"] = 12] = "SMALL";
  FONT_SIZE2[FONT_SIZE2["MEDIUM"] = 13] = "MEDIUM";
  FONT_SIZE2[FONT_SIZE2["LARGE"] = 14] = "LARGE";
  FONT_SIZE2[FONT_SIZE2["LARGEST"] = 17] = "LARGEST";
  return FONT_SIZE2;
})(FONT_SIZE || {});
var BASE_FONT_SIZE = 12 /* SMALL */;
var FONT_SIZE_RATIO = {
  SMALLEST: 8 /* SMALLEST */ / BASE_FONT_SIZE,
  SMALLER: 10 /* SMALLER */ / BASE_FONT_SIZE,
  SMALL: 12 /* SMALL */ / BASE_FONT_SIZE,
  MEDIUM: 13 /* MEDIUM */ / BASE_FONT_SIZE,
  LARGE: 14 /* LARGE */ / BASE_FONT_SIZE,
  LARGEST: 17 /* LARGEST */ / BASE_FONT_SIZE
};
var CARTESIAN_POSITION = /* @__PURE__ */ ((CARTESIAN_POSITION2) => {
  CARTESIAN_POSITION2["TOP"] = "top";
  CARTESIAN_POSITION2["TOP_RIGHT"] = "top-right";
  CARTESIAN_POSITION2["TOP_LEFT"] = "top-left";
  CARTESIAN_POSITION2["RIGHT"] = "right";
  CARTESIAN_POSITION2["RIGHT_TOP"] = "right-top";
  CARTESIAN_POSITION2["RIGHT_BOTTOM"] = "right-bottom";
  CARTESIAN_POSITION2["BOTTOM"] = "bottom";
  CARTESIAN_POSITION2["BOTTOM_RIGHT"] = "bottom-right";
  CARTESIAN_POSITION2["BOTTOM_LEFT"] = "bottom-left";
  CARTESIAN_POSITION2["LEFT"] = "left";
  CARTESIAN_POSITION2["LEFT_TOP"] = "left-top";
  CARTESIAN_POSITION2["LEFT_BOTTOM"] = "left-bottom";
  return CARTESIAN_POSITION2;
})(CARTESIAN_POSITION || {});
var CARTESIAN_AXIS_TYPE = /* @__PURE__ */ ((CARTESIAN_AXIS_TYPE2) => {
  CARTESIAN_AXIS_TYPE2["CATEGORY"] = "category";
  CARTESIAN_AXIS_TYPE2["GROUPED_CATEGORY"] = "grouped-category";
  CARTESIAN_AXIS_TYPE2["ORDINAL_TIME"] = "ordinal-time";
  CARTESIAN_AXIS_TYPE2["UNIT_TIME"] = "unit-time";
  CARTESIAN_AXIS_TYPE2["TIME"] = "time";
  CARTESIAN_AXIS_TYPE2["NUMBER"] = "number";
  CARTESIAN_AXIS_TYPE2["LOG"] = "log";
  return CARTESIAN_AXIS_TYPE2;
})(CARTESIAN_AXIS_TYPE || {});
var POLAR_AXIS_TYPE = /* @__PURE__ */ ((POLAR_AXIS_TYPE2) => {
  POLAR_AXIS_TYPE2["ANGLE_CATEGORY"] = "angle-category";
  POLAR_AXIS_TYPE2["ANGLE_NUMBER"] = "angle-number";
  POLAR_AXIS_TYPE2["RADIUS_CATEGORY"] = "radius-category";
  POLAR_AXIS_TYPE2["RADIUS_NUMBER"] = "radius-number";
  return POLAR_AXIS_TYPE2;
})(POLAR_AXIS_TYPE || {});
var POLAR_AXIS_SHAPE = /* @__PURE__ */ ((POLAR_AXIS_SHAPE2) => {
  POLAR_AXIS_SHAPE2["CIRCLE"] = "circle";
  POLAR_AXIS_SHAPE2["POLYGON"] = "polygon";
  return POLAR_AXIS_SHAPE2;
})(POLAR_AXIS_SHAPE || {});

// packages/ag-charts-core/src/utils/format/color.ts
var lerp = (x, y, t) => x * (1 - t) + y * t;
var srgbToLinear = (value) => {
  const sign = value < 0 ? -1 : 1;
  const abs = Math.abs(value);
  if (abs <= 0.04045)
    return value / 12.92;
  return sign * ((abs + 0.055) / 1.055) ** 2.4;
};
var srgbFromLinear = (value) => {
  const sign = value < 0 ? -1 : 1;
  const abs = Math.abs(value);
  if (abs > 31308e-7) {
    return sign * (1.055 * abs ** (1 / 2.4) - 0.055);
  }
  return 12.92 * value;
};
var _Color = class _Color {
  /**
   * Every color component should be in the [0, 1] range.
   * Some easing functions (such as elastic easing) can overshoot the target value by some amount.
   * So, when animating colors, if the source or target color components are already near
   * or at the edge of the allowed [0, 1] range, it is possible for the intermediate color
   * component value to end up outside of that range mid-animation. For this reason the constructor
   * performs range checking/constraining.
   * @param r Red component.
   * @param g Green component.
   * @param b Blue component.
   * @param a Alpha (opacity) component.
   */
  constructor(r, g, b, a = 1) {
    this.r = clamp(0, r || 0, 1);
    this.g = clamp(0, g || 0, 1);
    this.b = clamp(0, b || 0, 1);
    this.a = clamp(0, a || 0, 1);
  }
  /**
   * A color string can be in one of the following formats to be valid:
   * - #rgb
   * - #rrggbb
   * - rgb(r, g, b)
   * - rgba(r, g, b, a)
   * - CSS color name such as 'white', 'orange', 'cyan', etc.
   */
  static validColorString(str) {
    if (str.includes("#")) {
      return !!_Color.parseHex(str);
    }
    if (str.includes("rgb")) {
      return !!_Color.stringToRgba(str);
    }
    return _Color.nameToHex.has(str.toLowerCase());
  }
  /**
   * The given string can be in one of the following formats:
   * - #rgb
   * - #rrggbb
   * - rgb(r, g, b)
   * - rgba(r, g, b, a)
   * - CSS color name such as 'white', 'orange', 'cyan', etc.
   * @param str
   */
  static fromString(str) {
    if (str.includes("#")) {
      return _Color.fromHexString(str);
    }
    const hex = _Color.nameToHex.get(str.toLowerCase());
    if (hex) {
      return _Color.fromHexString(hex);
    }
    if (str.includes("rgb")) {
      return _Color.fromRgbaString(str);
    }
    throw new Error(`Invalid color string: '${str}'`);
  }
  // See https://drafts.csswg.org/css-color/#hex-notation
  static parseHex(input) {
    input = input.replaceAll(" ", "").slice(1);
    let parts;
    switch (input.length) {
      case 6:
      case 8:
        parts = [];
        for (let i = 0; i < input.length; i += 2) {
          parts.push(Number.parseInt(`${input[i]}${input[i + 1]}`, 16));
        }
        break;
      case 3:
      case 4:
        parts = input.split("").map((p) => Number.parseInt(p, 16)).map((p) => p + p * 16);
        break;
    }
    if (parts?.length >= 3 && parts.every((p) => p >= 0)) {
      if (parts.length === 3) {
        parts.push(255);
      }
      return parts;
    }
  }
  static fromHexString(str) {
    const values = _Color.parseHex(str);
    if (values) {
      const [r, g, b, a] = values;
      return new _Color(r / 255, g / 255, b / 255, a / 255);
    }
    throw new Error(`Malformed hexadecimal color string: '${str}'`);
  }
  static stringToRgba(str) {
    let po = -1;
    let pc = -1;
    for (let i = 0; i < str.length; i++) {
      const c = str[i];
      if (po === -1 && c === "(") {
        po = i;
      } else if (c === ")") {
        pc = i;
        break;
      }
    }
    if (po === -1 || pc === -1)
      return;
    const contents = str.substring(po + 1, pc);
    const parts = contents.split(",");
    const rgba = [];
    for (let i = 0; i < parts.length; i++) {
      const part = parts[i];
      let value = Number.parseFloat(part);
      if (!Number.isFinite(value)) {
        return;
      }
      if (part.includes("%")) {
        value = clamp(0, value, 100);
        value /= 100;
      } else if (i === 3) {
        value = clamp(0, value, 1);
      } else {
        value = clamp(0, value, 255);
        value /= 255;
      }
      rgba.push(value);
    }
    return rgba;
  }
  static fromRgbaString(str) {
    const rgba = _Color.stringToRgba(str);
    if (rgba) {
      if (rgba.length === 3) {
        return new _Color(rgba[0], rgba[1], rgba[2]);
      } else if (rgba.length === 4) {
        return new _Color(rgba[0], rgba[1], rgba[2], rgba[3]);
      }
    }
    throw new Error(`Malformed rgb/rgba color string: '${str}'`);
  }
  static fromArray(arr) {
    if (arr.length === 4) {
      return new _Color(arr[0], arr[1], arr[2], arr[3]);
    }
    if (arr.length === 3) {
      return new _Color(arr[0], arr[1], arr[2]);
    }
    throw new Error("The given array should contain 3 or 4 color components (numbers).");
  }
  static fromHSB(h, s, b, alpha = 1) {
    const rgb = _Color.HSBtoRGB(h, s, b);
    return new _Color(rgb[0], rgb[1], rgb[2], alpha);
  }
  static fromHSL(h, s, l, alpha = 1) {
    const rgb = _Color.HSLtoRGB(h, s, l);
    return new _Color(rgb[0], rgb[1], rgb[2], alpha);
  }
  static fromOKLCH(l, c, h, alpha = 1) {
    const rgb = _Color.OKLCHtoRGB(l, c, h);
    return new _Color(rgb[0], rgb[1], rgb[2], alpha);
  }
  static padHex(str) {
    return str.length === 1 ? "0" + str : str;
  }
  toHexString() {
    let hex = "#" + _Color.padHex(Math.round(this.r * 255).toString(16)) + _Color.padHex(Math.round(this.g * 255).toString(16)) + _Color.padHex(Math.round(this.b * 255).toString(16));
    if (this.a < 1) {
      hex += _Color.padHex(Math.round(this.a * 255).toString(16));
    }
    return hex;
  }
  toRgbaString(fractionDigits = 3) {
    const components = [Math.round(this.r * 255), Math.round(this.g * 255), Math.round(this.b * 255)];
    const k = Math.pow(10, fractionDigits);
    if (this.a !== 1) {
      components.push(Math.round(this.a * k) / k);
      return `rgba(${components.join(", ")})`;
    }
    return `rgb(${components.join(", ")})`;
  }
  toString() {
    if (this.a === 1) {
      return this.toHexString();
    }
    return this.toRgbaString();
  }
  toHSB() {
    return _Color.RGBtoHSB(this.r, this.g, this.b);
  }
  static RGBtoOKLCH(r, g, b) {
    const LSRGB0 = srgbToLinear(r);
    const LSRGB1 = srgbToLinear(g);
    const LSRGB2 = srgbToLinear(b);
    const LMS0 = Math.cbrt(0.4122214708 * LSRGB0 + 0.5363325363 * LSRGB1 + 0.0514459929 * LSRGB2);
    const LMS1 = Math.cbrt(0.2119034982 * LSRGB0 + 0.6806995451 * LSRGB1 + 0.1073969566 * LSRGB2);
    const LMS2 = Math.cbrt(0.0883024619 * LSRGB0 + 0.2817188376 * LSRGB1 + 0.6299787005 * LSRGB2);
    const OKLAB0 = 0.2104542553 * LMS0 + 0.793617785 * LMS1 - 0.0040720468 * LMS2;
    const OKLAB1 = 1.9779984951 * LMS0 - 2.428592205 * LMS1 + 0.4505937099 * LMS2;
    const OKLAB2 = 0.0259040371 * LMS0 + 0.7827717662 * LMS1 - 0.808675766 * LMS2;
    const hue = Math.atan2(OKLAB2, OKLAB1) * 180 / Math.PI;
    const OKLCH0 = OKLAB0;
    const OKLCH1 = Math.hypot(OKLAB1, OKLAB2);
    const OKLCH2 = hue >= 0 ? hue : hue + 360;
    return [OKLCH0, OKLCH1, OKLCH2];
  }
  static OKLCHtoRGB(l, c, h) {
    const OKLAB0 = l;
    const OKLAB1 = c * Math.cos(h * Math.PI / 180);
    const OKLAB2 = c * Math.sin(h * Math.PI / 180);
    const LMS0 = (OKLAB0 + 0.3963377774 * OKLAB1 + 0.2158037573 * OKLAB2) ** 3;
    const LMS1 = (OKLAB0 - 0.1055613458 * OKLAB1 - 0.0638541728 * OKLAB2) ** 3;
    const LMS2 = (OKLAB0 - 0.0894841775 * OKLAB1 - 1.291485548 * OKLAB2) ** 3;
    const LSRGB0 = 4.0767416621 * LMS0 - 3.3077115913 * LMS1 + 0.2309699292 * LMS2;
    const LSRGB1 = -1.2684380046 * LMS0 + 2.6097574011 * LMS1 - 0.3413193965 * LMS2;
    const LSRGB2 = -0.0041960863 * LMS0 - 0.7034186147 * LMS1 + 1.707614701 * LMS2;
    const SRGB0 = srgbFromLinear(LSRGB0);
    const SRGB1 = srgbFromLinear(LSRGB1);
    const SRGB2 = srgbFromLinear(LSRGB2);
    return [SRGB0, SRGB1, SRGB2];
  }
  static RGBtoHSL(r, g, b) {
    const min = Math.min(r, g, b);
    const max = Math.max(r, g, b);
    const l = (max + min) / 2;
    let h;
    let s;
    if (max === min) {
      h = 0;
      s = 0;
    } else {
      const delta5 = max - min;
      s = l > 0.5 ? delta5 / (2 - max - min) : delta5 / (max + min);
      if (max === r) {
        h = (g - b) / delta5 + (g < b ? 6 : 0);
      } else if (max === g) {
        h = (b - r) / delta5 + 2;
      } else {
        h = (r - g) / delta5 + 4;
      }
      h *= 360 / 6;
    }
    return [h, s, l];
  }
  static HSLtoRGB(h, s, l) {
    h = (h % 360 + 360) % 360;
    if (s === 0) {
      return [l, l, l];
    }
    const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
    const p = 2 * l - q;
    function hueToRgb(t) {
      if (t < 0)
        t += 1;
      if (t > 1)
        t -= 1;
      if (t < 1 / 6)
        return p + (q - p) * 6 * t;
      if (t < 1 / 2)
        return q;
      if (t < 2 / 3)
        return p + (q - p) * (2 / 3 - t) * 6;
      return p;
    }
    const r = hueToRgb(h / 360 + 1 / 3);
    const g = hueToRgb(h / 360);
    const b = hueToRgb(h / 360 - 1 / 3);
    return [r, g, b];
  }
  /**
   * Converts the given RGB triple to an array of HSB (HSV) components.
   */
  static RGBtoHSB(r, g, b) {
    const min = Math.min(r, g, b);
    const max = Math.max(r, g, b);
    const S = max === 0 ? 0 : (max - min) / max;
    let H = 0;
    if (min !== max) {
      const delta5 = max - min;
      const rc = (max - r) / delta5;
      const gc = (max - g) / delta5;
      const bc = (max - b) / delta5;
      if (r === max) {
        H = bc - gc;
      } else if (g === max) {
        H = 2 + rc - bc;
      } else {
        H = 4 + gc - rc;
      }
      H /= 6;
      if (H < 0) {
        H = H + 1;
      }
    }
    return [H * 360, S, max];
  }
  /**
   * Converts the given HSB (HSV) triple to an array of RGB components.
   */
  static HSBtoRGB(H, S, B) {
    H = (H % 360 + 360) % 360 / 360;
    let r = 0;
    let g = 0;
    let b = 0;
    if (S === 0) {
      r = g = b = B;
    } else {
      const h = (H - Math.floor(H)) * 6;
      const f = h - Math.floor(h);
      const p = B * (1 - S);
      const q = B * (1 - S * f);
      const t = B * (1 - S * (1 - f));
      switch (Math.trunc(h)) {
        case 0:
          r = B;
          g = t;
          b = p;
          break;
        case 1:
          r = q;
          g = B;
          b = p;
          break;
        case 2:
          r = p;
          g = B;
          b = t;
          break;
        case 3:
          r = p;
          g = q;
          b = B;
          break;
        case 4:
          r = t;
          g = p;
          b = B;
          break;
        case 5:
          r = B;
          g = p;
          b = q;
          break;
      }
    }
    return [r, g, b];
  }
  static mix(c0, c1, t) {
    return new _Color(lerp(c0.r, c1.r, t), lerp(c0.g, c1.g, t), lerp(c0.b, c1.b, t), lerp(c0.a, c1.a, t));
  }
  static lighten(c, t) {
    const oklch = _Color.RGBtoOKLCH(c.r, c.g, c.b);
    return _Color.fromOKLCH(clamp(0, oklch[0] + t, 1), oklch[1], oklch[2]);
  }
  static darken(c, t) {
    const oklch = _Color.RGBtoOKLCH(c.r, c.g, c.b);
    return _Color.fromOKLCH(clamp(0, oklch[0] - t, 1), oklch[1], oklch[2]);
  }
  static interpolate(colors, count) {
    const step = 1 / (colors.length - 1);
    const oklchColors = colors.map((c) => _Color.RGBtoOKLCH(c.r, c.g, c.b));
    return Array.from({ length: count }, (_, i) => {
      const t = i / (count - 1);
      const index = colors.length <= 2 ? 0 : Math.min(Math.floor(t * (colors.length - 1)), colors.length - 2);
      const q = (t - index * step) / step;
      const c0 = oklchColors[index];
      const c1 = oklchColors[index + 1];
      return _Color.fromOKLCH(lerp(c0[0], c1[0], q), lerp(c0[1], c1[1], q), lerp(c0[2], c1[2], q));
    });
  }
};
/**
 * CSS Color Module Level 4:
 * https://drafts.csswg.org/css-color/#named-colors
 */
_Color.nameToHex = /* @__PURE__ */ new Map([
  ["aliceblue", "#F0F8FF"],
  ["antiquewhite", "#FAEBD7"],
  ["aqua", "#00FFFF"],
  ["aquamarine", "#7FFFD4"],
  ["azure", "#F0FFFF"],
  ["beige", "#F5F5DC"],
  ["bisque", "#FFE4C4"],
  ["black", "#000000"],
  ["blanchedalmond", "#FFEBCD"],
  ["blue", "#0000FF"],
  ["blueviolet", "#8A2BE2"],
  ["brown", "#A52A2A"],
  ["burlywood", "#DEB887"],
  ["cadetblue", "#5F9EA0"],
  ["chartreuse", "#7FFF00"],
  ["chocolate", "#D2691E"],
  ["coral", "#FF7F50"],
  ["cornflowerblue", "#6495ED"],
  ["cornsilk", "#FFF8DC"],
  ["crimson", "#DC143C"],
  ["cyan", "#00FFFF"],
  ["darkblue", "#00008B"],
  ["darkcyan", "#008B8B"],
  ["darkgoldenrod", "#B8860B"],
  ["darkgray", "#A9A9A9"],
  ["darkgreen", "#006400"],
  ["darkgrey", "#A9A9A9"],
  ["darkkhaki", "#BDB76B"],
  ["darkmagenta", "#8B008B"],
  ["darkolivegreen", "#556B2F"],
  ["darkorange", "#FF8C00"],
  ["darkorchid", "#9932CC"],
  ["darkred", "#8B0000"],
  ["darksalmon", "#E9967A"],
  ["darkseagreen", "#8FBC8F"],
  ["darkslateblue", "#483D8B"],
  ["darkslategray", "#2F4F4F"],
  ["darkslategrey", "#2F4F4F"],
  ["darkturquoise", "#00CED1"],
  ["darkviolet", "#9400D3"],
  ["deeppink", "#FF1493"],
  ["deepskyblue", "#00BFFF"],
  ["dimgray", "#696969"],
  ["dimgrey", "#696969"],
  ["dodgerblue", "#1E90FF"],
  ["firebrick", "#B22222"],
  ["floralwhite", "#FFFAF0"],
  ["forestgreen", "#228B22"],
  ["fuchsia", "#FF00FF"],
  ["gainsboro", "#DCDCDC"],
  ["ghostwhite", "#F8F8FF"],
  ["gold", "#FFD700"],
  ["goldenrod", "#DAA520"],
  ["gray", "#808080"],
  ["green", "#008000"],
  ["greenyellow", "#ADFF2F"],
  ["grey", "#808080"],
  ["honeydew", "#F0FFF0"],
  ["hotpink", "#FF69B4"],
  ["indianred", "#CD5C5C"],
  ["indigo", "#4B0082"],
  ["ivory", "#FFFFF0"],
  ["khaki", "#F0E68C"],
  ["lavender", "#E6E6FA"],
  ["lavenderblush", "#FFF0F5"],
  ["lawngreen", "#7CFC00"],
  ["lemonchiffon", "#FFFACD"],
  ["lightblue", "#ADD8E6"],
  ["lightcoral", "#F08080"],
  ["lightcyan", "#E0FFFF"],
  ["lightgoldenrodyellow", "#FAFAD2"],
  ["lightgray", "#D3D3D3"],
  ["lightgreen", "#90EE90"],
  ["lightgrey", "#D3D3D3"],
  ["lightpink", "#FFB6C1"],
  ["lightsalmon", "#FFA07A"],
  ["lightseagreen", "#20B2AA"],
  ["lightskyblue", "#87CEFA"],
  ["lightslategray", "#778899"],
  ["lightslategrey", "#778899"],
  ["lightsteelblue", "#B0C4DE"],
  ["lightyellow", "#FFFFE0"],
  ["lime", "#00FF00"],
  ["limegreen", "#32CD32"],
  ["linen", "#FAF0E6"],
  ["magenta", "#FF00FF"],
  ["maroon", "#800000"],
  ["mediumaquamarine", "#66CDAA"],
  ["mediumblue", "#0000CD"],
  ["mediumorchid", "#BA55D3"],
  ["mediumpurple", "#9370DB"],
  ["mediumseagreen", "#3CB371"],
  ["mediumslateblue", "#7B68EE"],
  ["mediumspringgreen", "#00FA9A"],
  ["mediumturquoise", "#48D1CC"],
  ["mediumvioletred", "#C71585"],
  ["midnightblue", "#191970"],
  ["mintcream", "#F5FFFA"],
  ["mistyrose", "#FFE4E1"],
  ["moccasin", "#FFE4B5"],
  ["navajowhite", "#FFDEAD"],
  ["navy", "#000080"],
  ["oldlace", "#FDF5E6"],
  ["olive", "#808000"],
  ["olivedrab", "#6B8E23"],
  ["orange", "#FFA500"],
  ["orangered", "#FF4500"],
  ["orchid", "#DA70D6"],
  ["palegoldenrod", "#EEE8AA"],
  ["palegreen", "#98FB98"],
  ["paleturquoise", "#AFEEEE"],
  ["palevioletred", "#DB7093"],
  ["papayawhip", "#FFEFD5"],
  ["peachpuff", "#FFDAB9"],
  ["peru", "#CD853F"],
  ["pink", "#FFC0CB"],
  ["plum", "#DDA0DD"],
  ["powderblue", "#B0E0E6"],
  ["purple", "#800080"],
  ["rebeccapurple", "#663399"],
  ["red", "#FF0000"],
  ["rosybrown", "#BC8F8F"],
  ["royalblue", "#4169E1"],
  ["saddlebrown", "#8B4513"],
  ["salmon", "#FA8072"],
  ["sandybrown", "#F4A460"],
  ["seagreen", "#2E8B57"],
  ["seashell", "#FFF5EE"],
  ["sienna", "#A0522D"],
  ["silver", "#C0C0C0"],
  ["skyblue", "#87CEEB"],
  ["slateblue", "#6A5ACD"],
  ["slategray", "#708090"],
  ["slategrey", "#708090"],
  ["snow", "#FFFAFA"],
  ["springgreen", "#00FF7F"],
  ["steelblue", "#4682B4"],
  ["tan", "#D2B48C"],
  ["teal", "#008080"],
  ["thistle", "#D8BFD8"],
  ["tomato", "#FF6347"],
  ["transparent", "#00000000"],
  ["turquoise", "#40E0D0"],
  ["violet", "#EE82EE"],
  ["wheat", "#F5DEB3"],
  ["white", "#FFFFFF"],
  ["whitesmoke", "#F5F5F5"],
  ["yellow", "#FFFF00"],
  ["yellowgreen", "#9ACD32"]
]);
var Color = _Color;

// packages/ag-charts-core/src/config/themeUtil.ts
var DIRECTION_SWAP_AXES = {
  x: {
    position: "bottom" /* BOTTOM */,
    type: {
      $if: [
        { $eq: [{ $path: ["/series/0/direction", void 0] }, "horizontal"] },
        "number" /* NUMBER */,
        "category" /* CATEGORY */
      ]
    }
  },
  y: {
    position: "left" /* LEFT */,
    type: {
      $if: [
        { $eq: [{ $path: ["/series/0/direction", void 0] }, "horizontal"] },
        "category" /* CATEGORY */,
        "number" /* NUMBER */
      ]
    }
  }
};
var SAFE_FILL_OPERATION = {
  $if: [
    {
      $or: [
        { $isGradient: { $palette: "fill" } },
        { $isPattern: { $palette: "fill" } },
        { $isImage: { $value: "$1" } }
      ]
    },
    { $palette: "fillFallback" },
    { $palette: "fill" }
  ]
};
var SAFE_FILLS_OPERATION = {
  $if: [
    {
      $or: [
        { $isGradient: { $palette: "fill" } },
        { $isPattern: { $palette: "fill" } },
        { $isImage: { $value: "$1" } }
      ]
    },
    { $palette: "fillsFallback" },
    { $palette: "fills" }
  ]
};
var SAFE_STROKE_FILL_OPERATION = {
  $if: [
    { $isGradient: { $palette: "fill" } },
    { $palette: "fillFallback" },
    {
      $if: [
        { $isPattern: { $palette: "fill" } },
        { $path: ["/stroke", { $palette: "fillFallback" }, { $palette: "fill" }] },
        { $palette: "fill" }
      ]
    }
  ]
};
var SAFE_RANGE2_OPERATION = {
  $if: [
    {
      $or: [
        { $isGradient: { $palette: "fill" } },
        { $isPattern: { $palette: "fill" } },
        { $isImage: { $value: "$1" } }
      ]
    },
    [{ $palette: "fillFallback" }, { $palette: "fillFallback" }],
    { $palette: "range2" }
  ]
};
var FILL_GRADIENT_BLANK_DEFAULTS = {
  type: "gradient",
  gradient: "linear",
  bounds: "item",
  colorStops: [{ color: "black" }],
  rotation: 0,
  reverse: false,
  colorSpace: "rgb"
};
var FILL_GRADIENT_LINEAR_DEFAULTS = {
  type: "gradient",
  gradient: "linear",
  bounds: "item",
  colorStops: { $shallow: { $map: [{ color: { $value: "$1" } }, { $palette: "gradient" }] } },
  rotation: 0,
  reverse: false,
  colorSpace: "rgb"
};
var FILL_GRADIENT_LINEAR_HIERARCHY_DEFAULTS = {
  ...FILL_GRADIENT_LINEAR_DEFAULTS,
  colorStops: {
    $shallow: [
      {
        color: {
          $mix: [{ $path: ["/1", { $palette: "fill" }, { $palette: "hierarchyColors" }] }, "black", 0.15]
        }
      },
      {
        color: {
          $mix: [{ $path: ["/1", { $palette: "fill" }, { $palette: "hierarchyColors" }] }, "white", 0.15]
        }
      }
    ]
  }
};
var FILL_GRADIENT_LINEAR_SINGLE_DEFAULTS = {
  ...FILL_GRADIENT_LINEAR_DEFAULTS,
  colorStops: {
    $map: [{ color: { $value: "$1" } }, { $path: ["/0", void 0, { $palette: "gradients" }] }]
  }
};
var FILL_GRADIENT_LINEAR_KEYED_DEFAULTS = (key) => ({
  ...FILL_GRADIENT_LINEAR_DEFAULTS,
  colorStops: {
    $shallow: {
      $if: [
        {
          $or: [
            { $isGradient: { $palette: `${key}.fill` } },
            { $isPattern: { $palette: `${key}.fill` } },
            { $isImage: { $palette: `${key}.fill` } }
          ]
        },
        { $path: ["/colorStops", void 0, { $palette: `${key}.fill` }] },
        [
          { color: { $mix: [{ $palette: `${key}.fill` }, "black", 0.15] } },
          { color: { $mix: [{ $palette: `${key}.fill` }, "white", 0.15] } }
        ]
      ]
    }
  }
});
var FILL_GRADIENT_RADIAL_DEFAULTS = {
  type: "gradient",
  gradient: "radial",
  bounds: "item",
  colorStops: { $shallow: { $map: [{ color: { $value: "$1" } }, { $palette: "gradient" }] } },
  rotation: 0,
  reverse: false,
  colorSpace: "rgb"
};
var FILL_GRADIENT_RADIAL_REVERSED_DEFAULTS = {
  ...FILL_GRADIENT_RADIAL_DEFAULTS,
  reverse: true
};
var FILL_GRADIENT_RADIAL_SERIES_DEFAULTS = {
  ...FILL_GRADIENT_RADIAL_DEFAULTS,
  bounds: "series"
};
var FILL_GRADIENT_RADIAL_REVERSED_SERIES_DEFAULTS = {
  ...FILL_GRADIENT_RADIAL_DEFAULTS,
  bounds: "series",
  reverse: true
};
var FILL_GRADIENT_CONIC_SERIES_DEFAULTS = {
  type: "gradient",
  gradient: "conic",
  bounds: "series",
  colorStops: { $map: [{ color: { $value: "$1" } }, { $palette: "gradient" }] },
  rotation: 0,
  reverse: false,
  colorSpace: "rgb"
};
var FILL_PATTERN_DEFAULTS = {
  type: "pattern",
  pattern: "forward-slanted-lines",
  width: { $isUserOption: ["./height", { $path: "./height" }, 10] },
  height: { $isUserOption: ["./width", { $path: "./width" }, 10] },
  padding: 2,
  fill: {
    $if: [
      {
        $or: [{ $isGradient: { $palette: "fill" } }, { $isImage: { $palette: "fill" } }]
      },
      { $palette: "fillFallback" },
      {
        $if: [
          { $isPattern: { $palette: "fill" } },
          { $path: ["/fill", { $palette: "fillFallback" }, { $palette: "fill" }] },
          { $palette: "fill" }
        ]
      }
    ]
  },
  fillOpacity: 1,
  stroke: SAFE_STROKE_FILL_OPERATION,
  strokeOpacity: 1,
  strokeWidth: {
    $switch: [
      { $path: "./pattern" },
      0,
      [["backward-slanted-lines", "forward-slanted-lines", "horizontal-lines", "vertical-lines"], 4]
    ]
  },
  backgroundFill: "none",
  backgroundFillOpacity: 1,
  rotation: 0,
  scale: 1
};
var FILL_PATTERN_SINGLE_DEFAULTS = {
  ...FILL_PATTERN_DEFAULTS,
  stroke: {
    $if: [
      { $isGradient: { $palette: "fill" } },
      { $path: ["/0", void 0, { $palette: "fillsFallback" }] },
      {
        $if: [
          { $isPattern: { $palette: "fill" } },
          {
            $path: [
              "/stroke",
              { $path: ["/0", void 0, { $palette: "fillsFallback" }] },
              { $path: ["/0", void 0, { $palette: "fills" }] }
            ]
          },
          { $path: ["/0", void 0, { $palette: "fills" }] }
        ]
      }
    ]
  },
  fill: {
    $if: [
      {
        $or: [{ $isGradient: { $palette: "fill" } }, { $isImage: { $palette: "fill" } }]
      },
      { $path: ["/0", void 0, { $palette: "fillsFallback" }] },
      {
        $if: [
          { $isPattern: { $palette: "fill" } },
          {
            $path: [
              "/fill",
              { $path: ["/0", void 0, { $palette: "fillsFallback" }] },
              { $path: ["/0", void 0, { $palette: "fills" }] }
            ]
          },
          { $path: ["/0", void 0, { $palette: "fills" }] }
        ]
      }
    ]
  }
};
var FILL_PATTERN_BLANK_DEFAULTS = {
  type: "pattern",
  pattern: "forward-slanted-lines",
  width: 8,
  height: 8,
  padding: 1,
  fill: "black",
  fillOpacity: 1,
  backgroundFill: "white",
  backgroundFillOpacity: 1,
  stroke: "black",
  strokeOpacity: 1,
  strokeWidth: 1,
  rotation: 0,
  scale: 1
};
var FILL_PATTERN_HIERARCHY_DEFAULTS = {
  ...FILL_PATTERN_DEFAULTS,
  fill: { $path: ["/1", { $palette: "fill" }, { $palette: "hierarchyColors" }] },
  stroke: { $path: ["/1", { $palette: "fill" }, { $palette: "hierarchyColors" }] }
};
var FILL_PATTERN_KEYED_DEFAULTS = (key) => ({
  ...FILL_PATTERN_DEFAULTS,
  stroke: {
    $if: [
      { $isGradient: { $palette: `${key}.fill` } },
      { $palette: "fillFallback" },
      {
        $if: [
          { $isPattern: { $palette: `${key}.fill` } },
          { $path: ["/stroke", { $palette: "fillFallback" }, { $palette: `${key}.fill` }] },
          { $palette: `${key}.fill` }
        ]
      }
    ]
  }
});
var FILL_IMAGE_DEFAULTS = {
  type: "image",
  backgroundFill: { $palette: "fillFallback" },
  backgroundFillOpacity: 1,
  repeat: "no-repeat",
  fit: "contain",
  rotation: 0
};
var FILL_IMAGE_BLANK_DEFAULTS = {
  type: "image",
  backgroundFill: "black",
  backgroundFillOpacity: 1,
  rotation: 0,
  repeat: "no-repeat",
  fit: "contain",
  width: 8,
  height: 8
};
function getSequentialColors(colors) {
  return mapValues(colors, (value) => {
    const color2 = Color.fromString(value);
    return [Color.darken(color2, 0.15).toString(), value, Color.lighten(color2, 0.15).toString()];
  });
}
var LABEL_BOXING_DEFAULTS = {
  padding: 8,
  cornerRadius: 4,
  fill: {
    $if: [
      {
        $and: [
          { $eq: [{ $path: "./fill/type" }, "image"] },
          { $isUserOption: ["./fill/backgroundFill", false, true] }
        ]
      },
      { backgroundFill: "transparent" },
      void 0
    ]
  },
  border: {
    enabled: { $isUserOption: ["../border", true, false] },
    strokeWidth: 1,
    stroke: { $foregroundOpacity: 0.08 }
  }
};
var MULTI_SERIES_HIGHLIGHT_STYLE = {
  enabled: true,
  unhighlightedItem: {
    opacity: 0.6
  },
  unhighlightedSeries: {
    opacity: 0.2
  }
};
var MARKER_SERIES_HIGHLIGHT_STYLE = {
  enabled: true,
  unhighlightedSeries: {
    opacity: 0.2
  }
};
var PART_WHOLE_HIGHLIGHT_STYLE = {
  enabled: true,
  unhighlightedItem: {
    opacity: 0.2
  },
  unhighlightedSeries: {
    opacity: 0.2
  }
};
var SINGLE_SERIES_HIGHLIGHT_STYLE = {
  enabled: true,
  unhighlightedItem: {
    opacity: 0.2
  }
};
var LEGEND_CONTAINER_THEME = {
  border: {
    enabled: false,
    stroke: { $foregroundBackgroundMix: 0.25 },
    strokeOpacity: 1,
    strokeWidth: 1
  },
  cornerRadius: 4,
  fillOpacity: 1,
  padding: {
    $if: [{ $eq: [{ $path: "./border/enabled" }, true] }, 5, { $isUserOption: ["./fill", 5, 0] }]
  }
};
var SEGMENTATION_DEFAULTS = {
  enabled: false,
  key: "x",
  segments: {
    $apply: {
      fill: {
        $applySwitch: [
          { $path: "type" },
          { $path: "../../../fill" },
          ["gradient", FILL_GRADIENT_LINEAR_DEFAULTS],
          ["image", FILL_IMAGE_DEFAULTS],
          ["pattern", FILL_PATTERN_DEFAULTS]
        ]
      },
      stroke: { $path: "../../../stroke" },
      fillOpacity: { $path: "../../../fillOpacity" },
      strokeWidth: {
        $isUserOption: [
          "./stroke",
          {
            $isUserOption: [
              "../../../strokeWidth",
              { $path: "../../../strokeWidth" },
              {
                $if: [
                  { $greaterThan: [{ $path: "../../../strokeWidth" }, 0] },
                  { $path: "../../../strokeWidth" },
                  2
                ]
              }
            ]
          },
          { $path: "../../../strokeWidth" }
        ]
      },
      strokeOpacity: { $path: "../../../strokeOpacity" },
      lineDash: { $path: "../../../lineDash" },
      lineDashOffset: { $path: "../../../lineDashOffset" }
    }
  }
};

// packages/ag-charts-core/src/state/memento.ts
var MementoCaretaker = class _MementoCaretaker {
  constructor(version) {
    this.version = version.split("-")[0];
  }
  save(...originators) {
    const packet = { version: this.version };
    for (const originator of Object.values(originators)) {
      packet[originator.mementoOriginatorKey] = this.encode(originator, originator.createMemento());
    }
    return packet;
  }
  restore(blob, ...originators) {
    if (typeof blob !== "object") {
      warnOnce(`Could not restore data of type [${typeof blob}], expecting an object, ignoring.`);
      return;
    }
    if (blob == null) {
      warnOnce(`Could not restore data of type [null], expecting an object, ignoring.`);
      return;
    }
    if (!("version" in blob) || typeof blob.version !== "string") {
      warnOnce(`Could not restore data, missing [version] string in object, ignoring.`);
      return;
    }
    for (const originator of originators) {
      const memento = this.decode(originator, blob[originator.mementoOriginatorKey]);
      const messages = [];
      if (!originator.guardMemento(memento, messages)) {
        const messagesString = messages.length > 0 ? `

${messages.join("\n\n")}

` : "";
        warnOnce(
          `Could not restore [${originator.mementoOriginatorKey}] data, value was invalid, ignoring.${messagesString}`,
          memento
        );
        return;
      }
      originator.restoreMemento(this.version, blob.version, memento);
    }
  }
  /**
   * Encode a memento as a serializable object, encoding any non-serializble types.
   */
  encode(originator, memento) {
    try {
      return JSON.parse(JSON.stringify(memento, _MementoCaretaker.encodeTypes));
    } catch (error2) {
      throw new Error(`Failed to encode [${originator.mementoOriginatorKey}] value [${error2}].`, {
        cause: error2
      });
    }
  }
  /**
   * Decode an encoded memento, decoding any non-serializable types.
   */
  decode(originator, encoded) {
    if (encoded == null)
      return encoded;
    try {
      return JSON.parse(JSON.stringify(encoded), _MementoCaretaker.decodeTypes);
    } catch (error2) {
      throw new Error(`Failed to decode [${originator.mementoOriginatorKey}] value [${error2}].`, {
        cause: error2
      });
    }
  }
  static encodeTypes(key, value) {
    if (isDate(this[key])) {
      return { __type: "date", value: this[key].toISOString() };
    }
    return value;
  }
  static decodeTypes(key, value) {
    if (isObject(this[key]) && "__type" in this[key] && this[key].__type === "date") {
      return new Date(this[key].value);
    }
    return value;
  }
};

// packages/ag-charts-core/src/types/axisDirection.ts
var ChartAxisDirection = /* @__PURE__ */ ((ChartAxisDirection4) => {
  ChartAxisDirection4["X"] = "x";
  ChartAxisDirection4["Y"] = "y";
  ChartAxisDirection4["Angle"] = "angle";
  ChartAxisDirection4["Radius"] = "radius";
  return ChartAxisDirection4;
})(ChartAxisDirection || {});

// packages/ag-charts-core/src/types/updateType.ts
var ChartUpdateType = /* @__PURE__ */ ((ChartUpdateType2) => {
  ChartUpdateType2[ChartUpdateType2["FULL"] = 0] = "FULL";
  ChartUpdateType2[ChartUpdateType2["UPDATE_DATA"] = 1] = "UPDATE_DATA";
  ChartUpdateType2[ChartUpdateType2["PROCESS_DATA"] = 2] = "PROCESS_DATA";
  ChartUpdateType2[ChartUpdateType2["PROCESS_DOMAIN"] = 3] = "PROCESS_DOMAIN";
  ChartUpdateType2[ChartUpdateType2["PROCESS_RANGE"] = 4] = "PROCESS_RANGE";
  ChartUpdateType2[ChartUpdateType2["PERFORM_LAYOUT"] = 5] = "PERFORM_LAYOUT";
  ChartUpdateType2[ChartUpdateType2["PRE_SERIES_UPDATE"] = 6] = "PRE_SERIES_UPDATE";
  ChartUpdateType2[ChartUpdateType2["SERIES_UPDATE"] = 7] = "SERIES_UPDATE";
  ChartUpdateType2[ChartUpdateType2["PRE_SCENE_RENDER"] = 8] = "PRE_SCENE_RENDER";
  ChartUpdateType2[ChartUpdateType2["SCENE_RENDER"] = 9] = "SCENE_RENDER";
  ChartUpdateType2[ChartUpdateType2["NONE"] = 10] = "NONE";
  return ChartUpdateType2;
})(ChartUpdateType || {});

// packages/ag-charts-core/src/types/zIndexMap.ts
var ZIndexMap = /* @__PURE__ */ ((ZIndexMap2) => {
  ZIndexMap2[ZIndexMap2["CHART_BACKGROUND"] = 0] = "CHART_BACKGROUND";
  ZIndexMap2[ZIndexMap2["AXIS_BAND_HIGHLIGHT"] = 1] = "AXIS_BAND_HIGHLIGHT";
  ZIndexMap2[ZIndexMap2["AXIS_GRID"] = 2] = "AXIS_GRID";
  ZIndexMap2[ZIndexMap2["AXIS"] = 3] = "AXIS";
  ZIndexMap2[ZIndexMap2["SERIES_AREA_CONTAINER"] = 4] = "SERIES_AREA_CONTAINER";
  ZIndexMap2[ZIndexMap2["ZOOM_SELECTION"] = 5] = "ZOOM_SELECTION";
  ZIndexMap2[ZIndexMap2["SERIES_CROSSLINE_RANGE"] = 6] = "SERIES_CROSSLINE_RANGE";
  ZIndexMap2[ZIndexMap2["SERIES_LAYER"] = 7] = "SERIES_LAYER";
  ZIndexMap2[ZIndexMap2["AXIS_FOREGROUND"] = 8] = "AXIS_FOREGROUND";
  ZIndexMap2[ZIndexMap2["SERIES_CROSSHAIR"] = 9] = "SERIES_CROSSHAIR";
  ZIndexMap2[ZIndexMap2["SERIES_CROSSLINE_LINE"] = 10] = "SERIES_CROSSLINE_LINE";
  ZIndexMap2[ZIndexMap2["SERIES_ANNOTATION"] = 11] = "SERIES_ANNOTATION";
  ZIndexMap2[ZIndexMap2["CHART_ANNOTATION"] = 12] = "CHART_ANNOTATION";
  ZIndexMap2[ZIndexMap2["CHART_ANNOTATION_FOCUSED"] = 13] = "CHART_ANNOTATION_FOCUSED";
  ZIndexMap2[ZIndexMap2["STATUS_BAR"] = 14] = "STATUS_BAR";
  ZIndexMap2[ZIndexMap2["SERIES_LABEL"] = 15] = "SERIES_LABEL";
  ZIndexMap2[ZIndexMap2["LEGEND"] = 16] = "LEGEND";
  ZIndexMap2[ZIndexMap2["NAVIGATOR"] = 17] = "NAVIGATOR";
  ZIndexMap2[ZIndexMap2["FOREGROUND"] = 18] = "FOREGROUND";
  return ZIndexMap2;
})(ZIndexMap || {});
var SeriesZIndexMap = /* @__PURE__ */ ((SeriesZIndexMap2) => {
  SeriesZIndexMap2[SeriesZIndexMap2["BACKGROUND"] = 0] = "BACKGROUND";
  SeriesZIndexMap2[SeriesZIndexMap2["ANY_CONTENT"] = 1] = "ANY_CONTENT";
  return SeriesZIndexMap2;
})(SeriesZIndexMap || {});
var SeriesContentZIndexMap = /* @__PURE__ */ ((SeriesContentZIndexMap2) => {
  SeriesContentZIndexMap2[SeriesContentZIndexMap2["FOREGROUND"] = 0] = "FOREGROUND";
  SeriesContentZIndexMap2[SeriesContentZIndexMap2["HIGHLIGHT"] = 1] = "HIGHLIGHT";
  SeriesContentZIndexMap2[SeriesContentZIndexMap2["LABEL"] = 2] = "LABEL";
  return SeriesContentZIndexMap2;
})(SeriesContentZIndexMap || {});
var PolarZIndexMap = /* @__PURE__ */ ((PolarZIndexMap2) => {
  PolarZIndexMap2[PolarZIndexMap2["BACKGROUND"] = 0] = "BACKGROUND";
  PolarZIndexMap2[PolarZIndexMap2["FOREGROUND"] = 1] = "FOREGROUND";
  PolarZIndexMap2[PolarZIndexMap2["HIGHLIGHT"] = 2] = "HIGHLIGHT";
  PolarZIndexMap2[PolarZIndexMap2["LABEL"] = 3] = "LABEL";
  return PolarZIndexMap2;
})(PolarZIndexMap || {});

// packages/ag-charts-core/src/chart/legendUtil.ts
function expandLegendPosition(position) {
  const {
    placement = "bottom",
    floating = false,
    xOffset = 0,
    yOffset = 0
  } = typeof position === "string" ? { placement: position, floating: false } : position;
  return { placement, floating, xOffset, yOffset };
}

// packages/ag-charts-core/src/state/properties.ts
var BaseProperties = class {
  handleUnknownProperties(_unknownKeys, _properties) {
  }
  set(properties) {
    const { className = this.constructor.name } = this.constructor;
    if (properties == null) {
      this.clear();
      return this;
    }
    if (typeof properties !== "object") {
      warn(`unable to set ${className} - expecting a properties object`);
      return this;
    }
    const keys = new Set(Object.keys(properties));
    for (const propertyKey of listDecoratedProperties(this)) {
      if (keys.has(propertyKey)) {
        const value = properties[propertyKey];
        const self = this;
        if (isProperties(self[propertyKey])) {
          if (self[propertyKey] instanceof PropertiesArray) {
            const array2 = self[propertyKey].reset(value);
            if (array2 == null) {
              warn(`unable to set [${String(propertyKey)}] - expecting a properties array`);
            } else {
              self[propertyKey] = array2;
            }
          } else {
            self[propertyKey].set(value);
          }
        } else if (isPlainObject(value)) {
          self[propertyKey] = merge(value, self[propertyKey] ?? {});
        } else {
          self[propertyKey] = value;
        }
        keys.delete(propertyKey);
      }
    }
    this.handleUnknownProperties(keys, properties);
    for (const unknownKey of keys) {
      warn(`unable to set [${String(unknownKey)}] in ${className} - property is unknown`);
    }
    return this;
  }
  clear() {
    for (const propertyKey of listDecoratedProperties(this)) {
      const currentValue = this[propertyKey];
      if (isProperties(currentValue)) {
        currentValue.clear();
      } else {
        this[propertyKey] = void 0;
      }
    }
    return this;
  }
  toJson() {
    return listDecoratedProperties(this).reduce((object2, propertyKey) => {
      const propertyValue = this[propertyKey];
      object2[String(propertyKey)] = isProperties(propertyValue) ? propertyValue.toJson() : propertyValue;
      return object2;
    }, {});
  }
};
var PropertiesArray = class _PropertiesArray extends Array {
  constructor(itemFactory, ...properties) {
    super(properties.length);
    const isConstructor = (value2) => Boolean(value2?.prototype?.constructor?.name);
    const value = isConstructor(itemFactory) ? (params) => new itemFactory().set(params) : itemFactory;
    Object.defineProperty(this, "itemFactory", { value, enumerable: false, configurable: false });
    this.set(properties);
  }
  set(properties) {
    if (isArray(properties)) {
      this.length = properties.length;
      for (let i = 0; i < properties.length; i++) {
        this[i] = this.itemFactory(properties[i]);
      }
    }
    return this;
  }
  reset(properties) {
    if (Array.isArray(properties)) {
      return new _PropertiesArray(this.itemFactory, ...properties);
    }
  }
  toJson() {
    return this.map((value) => value?.toJson?.() ?? value);
  }
};
function isProperties(value) {
  return value instanceof BaseProperties || value instanceof PropertiesArray;
}

// packages/ag-charts-core/src/chart/interpolationProperties.ts
var InterpolationProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.type = "linear";
    this.tension = 1;
    this.position = "end";
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], InterpolationProperties.prototype, "type", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], InterpolationProperties.prototype, "tension", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], InterpolationProperties.prototype, "position", 2);

// packages/ag-charts-core/src/utils/data/numberArray.ts
function clampArray(value, array2) {
  const [min, max] = findMinMax(array2);
  return clamp(min, value, max);
}
function findMinMax(array2) {
  if (array2.length === 0)
    return [];
  const result = [Infinity, -Infinity];
  for (const val of array2) {
    if (val < result[0])
      result[0] = val;
    if (val > result[1])
      result[1] = val;
  }
  return result;
}
function findRangeExtent(array2) {
  const [min, max] = findMinMax(array2);
  return max - min;
}
function nextPowerOf2(value) {
  value = Math.trunc(value);
  if (value <= 0)
    return 1;
  if (value === 1)
    return 2;
  return 1 << 32 - Math.clz32(value - 1);
}
function previousPowerOf2(value) {
  value = Math.trunc(value);
  if (value <= 0)
    return 0;
  if (value === 1)
    return 1;
  return 1 << 31 - Math.clz32(value);
}

// packages/ag-charts-core/src/utils/aggregation.ts
var AGGREGATION_INDEX_X_MIN = 0;
var AGGREGATION_INDEX_X_MAX = 1;
var AGGREGATION_INDEX_Y_MIN = 2;
var AGGREGATION_INDEX_Y_MAX = 3;
var AGGREGATION_SPAN = 4;
var AGGREGATION_THRESHOLD = 1e3;
var AGGREGATION_MAX_POINTS = 10;
var AGGREGATION_MIN_RANGE = 64;
var AGGREGATION_INDEX_UNSET = 4294967295;
var SMALLEST_INTERVAL_MIN_RECURSE = 3;
var SMALLEST_INTERVAL_RECURSE_LIMIT = 20;
var SMALLEST_INTERVAL_MAX_INDEX_ADJUSTMENTS = 100;
function estimateSmallestPixelIntervalIter(xValues, d0, d1, startDatumIndex, endDatumIndex, currentSmallestInterval, depth, xNeedsValueOf) {
  let indexAdjustments = 0;
  while (indexAdjustments < SMALLEST_INTERVAL_MAX_INDEX_ADJUSTMENTS && xValues[startDatumIndex] == null && startDatumIndex < endDatumIndex) {
    startDatumIndex += 1;
    indexAdjustments += 1;
  }
  while (indexAdjustments < SMALLEST_INTERVAL_MAX_INDEX_ADJUSTMENTS && xValues[endDatumIndex] == null && endDatumIndex > startDatumIndex) {
    endDatumIndex -= 1;
    indexAdjustments += 1;
  }
  if (indexAdjustments >= SMALLEST_INTERVAL_MAX_INDEX_ADJUSTMENTS || startDatumIndex >= endDatumIndex) {
    return currentSmallestInterval;
  }
  const ratio2 = Number.isFinite(d0) ? aggregationXRatioForXValue(xValues[endDatumIndex], d0, d1, xNeedsValueOf) - aggregationXRatioForXValue(xValues[startDatumIndex], d0, d1, xNeedsValueOf) : aggregationXRatioForDatumIndex(endDatumIndex, xValues.length) - aggregationXRatioForDatumIndex(startDatumIndex, xValues.length);
  if (ratio2 === 0 || !Number.isFinite(ratio2))
    return currentSmallestInterval;
  const currentInterval = Math.abs(ratio2) / (endDatumIndex - startDatumIndex);
  let recurse;
  if (depth < SMALLEST_INTERVAL_MIN_RECURSE) {
    recurse = true;
  } else if (depth > SMALLEST_INTERVAL_RECURSE_LIMIT) {
    recurse = false;
  } else {
    recurse = currentInterval <= currentSmallestInterval;
  }
  currentSmallestInterval = Math.min(currentSmallestInterval, currentInterval);
  if (!recurse)
    return currentSmallestInterval;
  const midIndex = Math.floor((startDatumIndex + endDatumIndex) / 2);
  const leadingInterval = estimateSmallestPixelIntervalIter(
    xValues,
    d0,
    d1,
    startDatumIndex,
    midIndex,
    currentSmallestInterval,
    depth + 1,
    xNeedsValueOf
  );
  const trailingInterval = estimateSmallestPixelIntervalIter(
    xValues,
    d0,
    d1,
    midIndex + 1,
    endDatumIndex,
    currentSmallestInterval,
    depth + 1,
    xNeedsValueOf
  );
  return Math.min(leadingInterval, trailingInterval, currentSmallestInterval);
}
function estimateSmallestPixelInterval(xValues, d0, d1, xNeedsValueOf) {
  return estimateSmallestPixelIntervalIter(
    xValues,
    d0,
    d1,
    0,
    xValues.length - 1,
    1 / (xValues.length - 1),
    0,
    xNeedsValueOf
  );
}
function aggregationRangeFittingPoints(xValues, d0, d1, opts) {
  if (Number.isFinite(d0)) {
    const smallestKeyInterval = opts?.smallestKeyInterval;
    const xNeedsValueOf = opts?.xNeedsValueOf ?? true;
    const smallestPixelInterval = smallestKeyInterval == null ? estimateSmallestPixelInterval(xValues, d0, d1, xNeedsValueOf) : smallestKeyInterval / (d1 - d0);
    return nextPowerOf2(Math.trunc(1 / smallestPixelInterval)) >> 3;
  } else {
    let power = Math.ceil(Math.log2(xValues.length)) - 1;
    power = Math.min(Math.max(power, 0), 24);
    return Math.trunc(2 ** power);
  }
}
function aggregationDomain(scale2, domainInput) {
  const { domain, sortMetadata } = domainInput;
  switch (scale2) {
    case "category":
      return [Number.NaN, Number.NaN];
    case "number":
    case "time":
    case "ordinal-time":
    case "unit-time": {
      if (domain.length === 0)
        return [Infinity, -Infinity];
      if (sortMetadata?.sortOrder === 1) {
        return [Number(domain[0]), Number(domain.at(-1))];
      }
      if (sortMetadata?.sortOrder === -1) {
        return [Number(domain.at(-1)), Number(domain[0])];
      }
      let min = Infinity;
      let max = -Infinity;
      for (const d of domain) {
        const value = Number(d);
        min = Math.min(min, value);
        max = Math.max(max, value);
      }
      return [min, max];
    }
    case "color":
    case "log":
    case "mercator":
      return [0, 0];
  }
}
function aggregationXRatioForDatumIndex(datumIndex, domainCount) {
  return datumIndex / domainCount;
}
function aggregationXRatioForXValue(xValue, d0, d1, xNeedsValueOf) {
  if (xNeedsValueOf) {
    return (xValue.valueOf() - d0) / (d1 - d0);
  }
  return (xValue - d0) / (d1 - d0);
}
function aggregationIndexForXRatio(xRatio, maxRange) {
  return Math.trunc(Math.min(Math.floor(xRatio * maxRange), maxRange - 1) * AGGREGATION_SPAN);
}
function aggregationBucketForDatum(xValues, d0, d1, maxRange, datumIndex, { xNeedsValueOf = true, xValuesLength } = {}) {
  const xValue = xValues[datumIndex];
  if (xValue == null)
    return -1;
  const length2 = xValuesLength ?? xValues.length;
  const xRatio = Number.isFinite(d0) ? aggregationXRatioForXValue(xValue, d0, d1, xNeedsValueOf) : aggregationXRatioForDatumIndex(datumIndex, length2);
  return aggregationIndexForXRatio(xRatio, maxRange);
}
function aggregationDatumMatchesIndex(indexData, aggIndex, datumIndex, offsets) {
  for (const offset of offsets) {
    if (datumIndex === indexData[aggIndex + offset]) {
      return true;
    }
  }
  return false;
}
function createAggregationIndices(xValues, yMaxValues, yMinValues, d0, d1, maxRange, {
  positive,
  split = false,
  xNeedsValueOf = true,
  yNeedsValueOf = true,
  // Optional pre-allocated arrays to reuse (must be correct size: maxRange * AGGREGATION_SPAN)
  reuseIndexData,
  reuseValueData,
  reuseNegativeIndexData,
  reuseNegativeValueData
} = {}) {
  const nan = Number.NaN;
  const requiredSize = maxRange * AGGREGATION_SPAN;
  const indexData = reuseIndexData?.length === requiredSize ? reuseIndexData : new Uint32Array(requiredSize);
  const valueData = reuseValueData?.length === requiredSize ? reuseValueData : new Float64Array(requiredSize);
  let negativeIndexData;
  let negativeValueData;
  if (split) {
    if (reuseNegativeIndexData?.length === requiredSize) {
      negativeIndexData = reuseNegativeIndexData;
    } else {
      negativeIndexData = new Uint32Array(requiredSize);
    }
    if (reuseNegativeValueData?.length === requiredSize) {
      negativeValueData = reuseNegativeValueData;
    } else {
      negativeValueData = new Float64Array(requiredSize);
    }
  }
  const continuous = Number.isFinite(d0) && Number.isFinite(d1);
  const domainCount = xValues.length;
  if (continuous) {
    valueData.fill(nan);
    indexData.fill(AGGREGATION_INDEX_UNSET);
    if (split) {
      negativeValueData.fill(nan);
      negativeIndexData.fill(AGGREGATION_INDEX_UNSET);
    }
  }
  const scaleFactor = continuous ? maxRange / (d1 - d0) : maxRange * (1 / domainCount);
  let lastAggIndex = -1;
  let cachedXMinIndex = -1;
  let cachedXMinValue = nan;
  let cachedXMaxIndex = -1;
  let cachedXMaxValue = nan;
  let cachedYMinIndex = -1;
  let cachedYMinValue = nan;
  let cachedYMaxIndex = -1;
  let cachedYMaxValue = nan;
  let negLastAggIndex = -1;
  let negCachedXMinIndex = -1;
  let negCachedXMinValue = nan;
  let negCachedXMaxIndex = -1;
  let negCachedXMaxValue = nan;
  let negCachedYMinIndex = -1;
  let negCachedYMinValue = nan;
  let negCachedYMaxIndex = -1;
  let negCachedYMaxValue = nan;
  const xValuesLength = xValues.length;
  const yArraysSame = yMaxValues === yMinValues;
  for (let datumIndex = 0; datumIndex < xValuesLength; datumIndex++) {
    const xValue = xValues[datumIndex];
    if (xValue == null)
      continue;
    const yMaxValue = yMaxValues[datumIndex];
    const yMinValue = yArraysSame ? yMaxValue : yMinValues[datumIndex];
    let yMax;
    let yMin;
    if (yNeedsValueOf) {
      yMax = yMaxValue == null ? nan : yMaxValue.valueOf();
      yMin = yMinValue == null ? nan : yMinValue.valueOf();
    } else {
      yMax = yMaxValue ?? nan;
      yMin = yMinValue ?? nan;
    }
    let isPositiveDatum = true;
    if (split) {
      isPositiveDatum = yMax >= 0;
    } else if (positive != null && yMax >= 0 !== positive) {
      continue;
    }
    let scaledX;
    if (continuous) {
      if (xNeedsValueOf) {
        scaledX = (xValue.valueOf() - d0) * scaleFactor;
      } else {
        scaledX = (xValue - d0) * scaleFactor;
      }
    } else {
      scaledX = datumIndex * scaleFactor;
    }
    const bucketIndex = Math.floor(scaledX);
    const aggIndex = (bucketIndex < maxRange ? bucketIndex : maxRange - 1) << 2;
    if (isPositiveDatum) {
      if (aggIndex !== lastAggIndex) {
        if (lastAggIndex !== -1) {
          indexData[lastAggIndex] = cachedXMinIndex;
          indexData[lastAggIndex + 1] = cachedXMaxIndex;
          indexData[lastAggIndex + 2] = cachedYMinIndex;
          indexData[lastAggIndex + 3] = cachedYMaxIndex;
          valueData[lastAggIndex] = cachedXMinValue;
          valueData[lastAggIndex + 1] = cachedXMaxValue;
          valueData[lastAggIndex + 2] = cachedYMinValue;
          valueData[lastAggIndex + 3] = cachedYMaxValue;
        }
        lastAggIndex = aggIndex;
        cachedXMinIndex = -1;
        cachedXMinValue = nan;
        cachedXMaxIndex = -1;
        cachedXMaxValue = nan;
        cachedYMinIndex = -1;
        cachedYMinValue = nan;
        cachedYMaxIndex = -1;
        cachedYMaxValue = nan;
      }
      const yMinValid = yMin === yMin;
      const yMaxValid = yMax === yMax;
      if (cachedXMinIndex === -1) {
        cachedXMinIndex = datumIndex;
        cachedXMinValue = scaledX;
        cachedXMaxIndex = datumIndex;
        cachedXMaxValue = scaledX;
        if (yMinValid) {
          cachedYMinIndex = datumIndex;
          cachedYMinValue = yMin;
        }
        if (yMaxValid) {
          cachedYMaxIndex = datumIndex;
          cachedYMaxValue = yMax;
        }
      } else {
        if (scaledX < cachedXMinValue) {
          cachedXMinIndex = datumIndex;
          cachedXMinValue = scaledX;
        }
        if (scaledX > cachedXMaxValue) {
          cachedXMaxIndex = datumIndex;
          cachedXMaxValue = scaledX;
        }
        if (yMinValid && yMin < cachedYMinValue) {
          cachedYMinIndex = datumIndex;
          cachedYMinValue = yMin;
        }
        if (yMaxValid && yMax > cachedYMaxValue) {
          cachedYMaxIndex = datumIndex;
          cachedYMaxValue = yMax;
        }
      }
    } else {
      if (aggIndex !== negLastAggIndex) {
        if (negLastAggIndex !== -1) {
          negativeIndexData[negLastAggIndex] = negCachedXMinIndex;
          negativeIndexData[negLastAggIndex + 1] = negCachedXMaxIndex;
          negativeIndexData[negLastAggIndex + 2] = negCachedYMinIndex;
          negativeIndexData[negLastAggIndex + 3] = negCachedYMaxIndex;
          negativeValueData[negLastAggIndex] = negCachedXMinValue;
          negativeValueData[negLastAggIndex + 1] = negCachedXMaxValue;
          negativeValueData[negLastAggIndex + 2] = negCachedYMinValue;
          negativeValueData[negLastAggIndex + 3] = negCachedYMaxValue;
        }
        negLastAggIndex = aggIndex;
        negCachedXMinIndex = -1;
        negCachedXMinValue = nan;
        negCachedXMaxIndex = -1;
        negCachedXMaxValue = nan;
        negCachedYMinIndex = -1;
        negCachedYMinValue = nan;
        negCachedYMaxIndex = -1;
        negCachedYMaxValue = nan;
      }
      const yMinValid = yMin === yMin;
      const yMaxValid = yMax === yMax;
      if (negCachedXMinIndex === -1) {
        negCachedXMinIndex = datumIndex;
        negCachedXMinValue = scaledX;
        negCachedXMaxIndex = datumIndex;
        negCachedXMaxValue = scaledX;
        if (yMinValid) {
          negCachedYMinIndex = datumIndex;
          negCachedYMinValue = yMin;
        }
        if (yMaxValid) {
          negCachedYMaxIndex = datumIndex;
          negCachedYMaxValue = yMax;
        }
      } else {
        if (scaledX < negCachedXMinValue) {
          negCachedXMinIndex = datumIndex;
          negCachedXMinValue = scaledX;
        }
        if (scaledX > negCachedXMaxValue) {
          negCachedXMaxIndex = datumIndex;
          negCachedXMaxValue = scaledX;
        }
        if (yMinValid && yMin < negCachedYMinValue) {
          negCachedYMinIndex = datumIndex;
          negCachedYMinValue = yMin;
        }
        if (yMaxValid && yMax > negCachedYMaxValue) {
          negCachedYMaxIndex = datumIndex;
          negCachedYMaxValue = yMax;
        }
      }
    }
  }
  if (lastAggIndex !== -1) {
    indexData[lastAggIndex] = cachedXMinIndex;
    indexData[lastAggIndex + 1] = cachedXMaxIndex;
    indexData[lastAggIndex + 2] = cachedYMinIndex;
    indexData[lastAggIndex + 3] = cachedYMaxIndex;
    valueData[lastAggIndex] = cachedXMinValue;
    valueData[lastAggIndex + 1] = cachedXMaxValue;
    valueData[lastAggIndex + 2] = cachedYMinValue;
    valueData[lastAggIndex + 3] = cachedYMaxValue;
  }
  if (split && negLastAggIndex !== -1) {
    negativeIndexData[negLastAggIndex] = negCachedXMinIndex;
    negativeIndexData[negLastAggIndex + 1] = negCachedXMaxIndex;
    negativeIndexData[negLastAggIndex + 2] = negCachedYMinIndex;
    negativeIndexData[negLastAggIndex + 3] = negCachedYMaxIndex;
    negativeValueData[negLastAggIndex] = negCachedXMinValue;
    negativeValueData[negLastAggIndex + 1] = negCachedXMaxValue;
    negativeValueData[negLastAggIndex + 2] = negCachedYMinValue;
    negativeValueData[negLastAggIndex + 3] = negCachedYMaxValue;
  }
  return { indexData, valueData, negativeIndexData, negativeValueData };
}
function compactAggregationIndices(indexData, valueData, maxRange, {
  inPlace = false,
  midpointData,
  reuseIndexData,
  reuseValueData
} = {}) {
  const nextMaxRange = Math.trunc(maxRange / 2);
  const requiredSize = nextMaxRange * AGGREGATION_SPAN;
  let nextIndexData;
  if (inPlace) {
    nextIndexData = indexData;
  } else if (reuseIndexData?.length === requiredSize) {
    nextIndexData = reuseIndexData;
  } else {
    nextIndexData = new Uint32Array(requiredSize);
  }
  let nextValueData;
  if (inPlace) {
    nextValueData = valueData;
  } else if (reuseValueData?.length === requiredSize) {
    nextValueData = reuseValueData;
  } else {
    nextValueData = new Float64Array(requiredSize);
  }
  const nextMidpointData = midpointData ?? new Uint32Array(nextMaxRange);
  for (let i = 0; i < nextMaxRange; i += 1) {
    const aggIndex = Math.trunc(i * AGGREGATION_SPAN);
    const index0 = Math.trunc(aggIndex * 2);
    const index1 = Math.trunc(index0 + AGGREGATION_SPAN);
    const index1Unset = indexData[index1 + AGGREGATION_INDEX_X_MIN] === AGGREGATION_INDEX_UNSET;
    const xMinAggIndex = index1Unset || valueData[index0 + AGGREGATION_INDEX_X_MIN] < valueData[index1 + AGGREGATION_INDEX_X_MIN] ? index0 : index1;
    const xMinIndex = indexData[xMinAggIndex + AGGREGATION_INDEX_X_MIN];
    nextIndexData[aggIndex + AGGREGATION_INDEX_X_MIN] = xMinIndex;
    nextValueData[aggIndex + AGGREGATION_INDEX_X_MIN] = valueData[xMinAggIndex + AGGREGATION_INDEX_X_MIN];
    const xMaxAggIndex = index1Unset || valueData[index0 + AGGREGATION_INDEX_X_MAX] > valueData[index1 + AGGREGATION_INDEX_X_MAX] ? index0 : index1;
    const xMaxIndex = indexData[xMaxAggIndex + AGGREGATION_INDEX_X_MAX];
    nextIndexData[aggIndex + AGGREGATION_INDEX_X_MAX] = xMaxIndex;
    nextValueData[aggIndex + AGGREGATION_INDEX_X_MAX] = valueData[xMaxAggIndex + AGGREGATION_INDEX_X_MAX];
    nextMidpointData[i] = xMinIndex + xMaxIndex >> 1;
    const yMinAggIndex = index1Unset || valueData[index0 + AGGREGATION_INDEX_Y_MIN] < valueData[index1 + AGGREGATION_INDEX_Y_MIN] ? index0 : index1;
    nextIndexData[aggIndex + AGGREGATION_INDEX_Y_MIN] = indexData[yMinAggIndex + AGGREGATION_INDEX_Y_MIN];
    nextValueData[aggIndex + AGGREGATION_INDEX_Y_MIN] = valueData[yMinAggIndex + AGGREGATION_INDEX_Y_MIN];
    const yMaxAggIndex = index1Unset || valueData[index0 + AGGREGATION_INDEX_Y_MAX] > valueData[index1 + AGGREGATION_INDEX_Y_MAX] ? index0 : index1;
    nextIndexData[aggIndex + AGGREGATION_INDEX_Y_MAX] = indexData[yMaxAggIndex + AGGREGATION_INDEX_Y_MAX];
    nextValueData[aggIndex + AGGREGATION_INDEX_Y_MAX] = valueData[yMaxAggIndex + AGGREGATION_INDEX_Y_MAX];
  }
  return {
    maxRange: nextMaxRange,
    indexData: nextIndexData,
    valueData: nextValueData,
    midpointData: nextMidpointData
  };
}
function getMidpointsForIndices(maxRange, indexData, reuseMidpointData, xMinOffset = AGGREGATION_INDEX_X_MIN, xMaxOffset = AGGREGATION_INDEX_X_MAX, invalidSentinel = -1) {
  const midpoints = reuseMidpointData?.length === maxRange ? reuseMidpointData : new Uint32Array(maxRange);
  for (let i = 0, offset = 0; i < maxRange; i += 1, offset += AGGREGATION_SPAN) {
    const xMin = indexData[offset + xMinOffset];
    const xMax = indexData[offset + xMaxOffset];
    midpoints[i] = xMin === invalidSentinel ? invalidSentinel : xMin + xMax >> 1;
  }
  return midpoints;
}
function collectAggregationLevels(state, {
  collectLevel,
  shouldContinue,
  minRange = AGGREGATION_MIN_RANGE,
  compactInPlace = false
}) {
  let aggregationState = state;
  let level = collectLevel(aggregationState);
  const levels = [level];
  while (aggregationState.maxRange > minRange && shouldContinue(level, aggregationState)) {
    const compacted = compactAggregationIndices(
      aggregationState.indexData,
      aggregationState.valueData,
      aggregationState.maxRange,
      { inPlace: compactInPlace }
    );
    aggregationState = {
      maxRange: compacted.maxRange,
      indexData: compacted.indexData,
      valueData: compacted.valueData,
      midpointData: compacted.midpointData
    };
    level = collectLevel(aggregationState);
    levels.push(level);
  }
  levels.reverse();
  return levels;
}
function computeExtremesAggregation(domain, xValues, highValues, lowValues, options) {
  if (xValues.length < AGGREGATION_THRESHOLD)
    return;
  const [d0, d1] = domain;
  const { smallestKeyInterval, xNeedsValueOf, yNeedsValueOf, existingFilters } = options;
  let maxRange = aggregationRangeFittingPoints(xValues, d0, d1, { smallestKeyInterval, xNeedsValueOf });
  const existingFilter = existingFilters?.find((f) => f.maxRange === maxRange);
  let { indexData, valueData } = createAggregationIndices(xValues, highValues, lowValues, d0, d1, maxRange, {
    xNeedsValueOf,
    yNeedsValueOf,
    reuseIndexData: existingFilter?.indexData,
    reuseValueData: existingFilter?.valueData
  });
  let midpointIndices = getMidpointsForIndices(maxRange, indexData, existingFilter?.midpointIndices);
  const filters = [
    {
      maxRange,
      indexData,
      valueData,
      midpointIndices
    }
  ];
  while (maxRange > AGGREGATION_MIN_RANGE) {
    const currentMaxRange = maxRange;
    const nextMaxRange = Math.trunc(currentMaxRange / 2);
    const nextExistingFilter = existingFilters?.find((f) => f.maxRange === nextMaxRange);
    const compacted = compactAggregationIndices(indexData, valueData, currentMaxRange, {
      reuseIndexData: nextExistingFilter?.indexData,
      reuseValueData: nextExistingFilter?.valueData
    });
    maxRange = compacted.maxRange;
    indexData = compacted.indexData;
    valueData = compacted.valueData;
    midpointIndices = compacted.midpointData ?? getMidpointsForIndices(maxRange, indexData, nextExistingFilter?.midpointIndices);
    filters.push({
      maxRange,
      indexData,
      valueData,
      midpointIndices
    });
  }
  filters.reverse();
  return filters;
}
function computeExtremesAggregationPartial(domain, xValues, highValues, lowValues, options) {
  if (xValues.length < AGGREGATION_THRESHOLD)
    return;
  const [d0, d1] = domain;
  const { smallestKeyInterval, targetRange, xNeedsValueOf, yNeedsValueOf, existingFilters } = options;
  const finestMaxRange = aggregationRangeFittingPoints(xValues, d0, d1, { smallestKeyInterval, xNeedsValueOf });
  const targetMaxRange = Math.min(finestMaxRange, nextPowerOf2(Math.max(targetRange, AGGREGATION_MIN_RANGE)));
  const existingFilter = existingFilters?.find((f) => f.maxRange === targetMaxRange);
  const { indexData, valueData } = createAggregationIndices(xValues, highValues, lowValues, d0, d1, targetMaxRange, {
    xNeedsValueOf,
    yNeedsValueOf,
    reuseIndexData: existingFilter?.indexData,
    reuseValueData: existingFilter?.valueData
  });
  const midpointIndices = getMidpointsForIndices(targetMaxRange, indexData, existingFilter?.midpointIndices);
  const immediateLevel = {
    maxRange: targetMaxRange,
    indexData,
    valueData,
    midpointIndices
  };
  function computeRemaining() {
    const allLevels = computeExtremesAggregation([d0, d1], xValues, highValues, lowValues, {
      smallestKeyInterval,
      xNeedsValueOf,
      yNeedsValueOf,
      existingFilters
    });
    return allLevels?.filter((level) => level.maxRange !== targetMaxRange) ?? [];
  }
  return { immediate: [immediateLevel], computeRemaining };
}

// packages/ag-charts-core/src/types/themeSymbols.ts
var IS_DARK_THEME = Symbol("is-dark-theme");
var DEFAULT_SHADOW_COLOUR = Symbol("default-shadow-colour");
var DEFAULT_CAPTION_LAYOUT_STYLE = Symbol("default-caption-layout-style");
var DEFAULT_CAPTION_ALIGNMENT = Symbol("default-caption-alignment");
var PALETTE_UP_STROKE = Symbol("palette-up-stroke");
var PALETTE_DOWN_STROKE = Symbol("palette-down-stroke");
var PALETTE_UP_FILL = Symbol("palette-up-fill");
var PALETTE_DOWN_FILL = Symbol("palette-down-fill");
var PALETTE_NEUTRAL_STROKE = Symbol("palette-neutral-stroke");
var PALETTE_NEUTRAL_FILL = Symbol("palette-neutral-fill");
var PALETTE_ALT_UP_STROKE = Symbol("palette-alt-up-stroke");
var PALETTE_ALT_DOWN_STROKE = Symbol("palette-alt-down-stroke");
var PALETTE_ALT_UP_FILL = Symbol("palette-alt-up-fill");
var PALETTE_ALT_DOWN_FILL = Symbol("palette-alt-down-fill");
var PALETTE_ALT_NEUTRAL_FILL = Symbol("palette-gray-fill");
var PALETTE_ALT_NEUTRAL_STROKE = Symbol("palette-gray-stroke");
var DEFAULT_POLAR_SERIES_STROKE = Symbol("default-polar-series-stroke");
var DEFAULT_SPARKLINE_CROSSHAIR_STROKE = Symbol("default-sparkline-crosshair-stroke");
var DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR = Symbol(
  "default-financial-charts-annotation-stroke"
);
var DEFAULT_FIBONACCI_STROKES = Symbol("default-hierarchy-strokes");
var DEFAULT_TEXT_ANNOTATION_COLOR = Symbol("default-text-annotation-color");
var DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL = Symbol(
  "default-financial-charts-annotation-background-fill"
);
var DEFAULT_ANNOTATION_HANDLE_FILL = Symbol("default-annotation-handle-fill");
var DEFAULT_ANNOTATION_STATISTICS_FILL = Symbol("default-annotation-statistics-fill");
var DEFAULT_ANNOTATION_STATISTICS_STROKE = Symbol("default-annotation-statistics-stroke");
var DEFAULT_ANNOTATION_STATISTICS_COLOR = Symbol("default-annotation-statistics-color");
var DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE = Symbol(
  "default-annotation-statistics-divider-stroke"
);
var DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL = Symbol(
  "default-annotation-statistics-fill"
);
var DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE = Symbol(
  "default-annotation-statistics-stroke"
);
var DEFAULT_TEXTBOX_FILL = Symbol("default-textbox-fill");
var DEFAULT_TEXTBOX_STROKE = Symbol("default-textbox-stroke");
var DEFAULT_TEXTBOX_COLOR = Symbol("default-textbox-color");
var DEFAULT_TOOLBAR_POSITION = Symbol("default-toolbar-position");

// packages/ag-charts-core/src/state/callbackCache.ts
function needsContext(caller, _params) {
  return "context" in caller;
}
function maybeSetContext(caller, params) {
  if (caller != null && needsContext(caller, params)) {
    if (params != null && typeof params === "object" && params.context === void 0) {
      params.context = caller.context;
      return true;
    }
  }
  return false;
}
function callWithContext(callers, fn, params) {
  if (Array.isArray(callers)) {
    for (const caller of callers) {
      if (maybeSetContext(caller, params)) {
        break;
      }
    }
  } else {
    maybeSetContext(callers, params);
  }
  return fn(params);
}
var CallbackCache = class {
  constructor() {
    this.cache = /* @__PURE__ */ new WeakMap();
  }
  call(callers, fn, params) {
    let serialisedParams;
    let paramCache = this.cache.get(fn);
    try {
      serialisedParams = JSON.stringify(params);
    } catch {
      return this.invoke(callers, fn, paramCache, void 0, params);
    }
    if (paramCache == null) {
      paramCache = /* @__PURE__ */ new Map();
      this.cache.set(fn, paramCache);
    }
    if (!paramCache.has(serialisedParams)) {
      return this.invoke(callers, fn, paramCache, serialisedParams, params);
    }
    return paramCache.get(serialisedParams);
  }
  invoke(callers, fn, paramCache, serialisedParams, params) {
    try {
      const result = callWithContext(callers, fn, params);
      if (paramCache && serialisedParams != null) {
        paramCache.set(serialisedParams, result);
      }
      return result;
    } catch (e) {
      warnOnce(`User callback errored, ignoring`, e);
      return;
    }
  }
  invalidateCache() {
    this.cache = /* @__PURE__ */ new WeakMap();
  }
};

// packages/ag-charts-core/src/utils/dom/domUtil.ts
function setElementBBox(element2, bbox) {
  if (!element2)
    return;
  const { x, y, width: width2, height: height2 } = normalizeBounds(bbox);
  setPixelValue(element2.style, "width", width2);
  setPixelValue(element2.style, "height", height2);
  setPixelValue(element2.style, "left", x);
  setPixelValue(element2.style, "top", y);
}
function getElementBBox(element2) {
  const styleWidth = Number.parseFloat(element2.style.width);
  const styleHeight = Number.parseFloat(element2.style.height);
  const styleX = Number.parseFloat(element2.style.left);
  const styleY = Number.parseFloat(element2.style.top);
  const width2 = Number.isFinite(styleWidth) ? styleWidth : element2.offsetWidth;
  const height2 = Number.isFinite(styleHeight) ? styleHeight : element2.offsetHeight;
  const x = Number.isFinite(styleX) ? styleX : element2.offsetLeft;
  const y = Number.isFinite(styleY) ? styleY : element2.offsetTop;
  return { x, y, width: width2, height: height2 };
}
function focusCursorAtEnd(element2) {
  element2.focus({ preventScroll: true });
  if (element2.lastChild?.textContent == null)
    return;
  const range3 = getDocument().createRange();
  range3.setStart(element2.lastChild, element2.lastChild.textContent.length);
  range3.setEnd(element2.lastChild, element2.lastChild.textContent.length);
  const selection = getWindow().getSelection();
  selection?.removeAllRanges();
  selection?.addRange(range3);
}
function isInputPending() {
  const navigator = getWindow("navigator");
  if ("scheduling" in navigator) {
    const scheduling = navigator.scheduling;
    if ("isInputPending" in scheduling) {
      return scheduling.isInputPending({ includeContinuous: true });
    }
  }
  return false;
}
function getIconClassNames(icon) {
  return `ag-charts-icon ag-charts-icon-${icon}`;
}
function normalizeBounds(bbox) {
  let { x, y, width: width2, height: height2 } = bbox;
  if ((width2 == null || width2 > 0) && (height2 == null || height2 > 0)) {
    return bbox;
  }
  if (x != null && width2 != null && width2 < 0) {
    width2 = -width2;
    x = x - width2;
  }
  if (y != null && height2 != null && height2 < 0) {
    height2 = -height2;
    y = y - height2;
  }
  return { x, y, width: width2, height: height2 };
}
function setPixelValue(style2, key, value) {
  if (value == null) {
    style2.removeProperty(key);
  } else {
    style2.setProperty(key, `${value}px`);
  }
}

// packages/ag-charts-core/src/utils/geometry/math/shapeUtils.ts
function getMaxInnerRectSize(rotationDeg, containerWidth, containerHeight = Infinity) {
  const W = containerWidth;
  const H = containerHeight;
  const angle2 = rotationDeg % 180 * (Math.PI / 180);
  const sin = Math.abs(Math.sin(angle2));
  const cos = Math.abs(Math.cos(angle2));
  if (sin === 0)
    return { width: W, height: H };
  if (cos === 0)
    return { width: H, height: W };
  if (!Number.isFinite(H)) {
    const r = cos / sin;
    const width2 = W / (cos + r * sin);
    return { width: width2, height: r * width2 };
  }
  const denominator = cos * cos - sin * sin;
  if (denominator === 0) {
    const side = Math.min(W, H) / Math.SQRT2;
    return { width: side, height: side };
  }
  return {
    width: Math.abs((W * cos - H * sin) / denominator),
    height: Math.abs((H * cos - W * sin) / denominator)
  };
}
function getMinOuterRectSize(rotationDeg, innerWidth, innerHeight = Infinity) {
  const w = innerWidth;
  const h = innerHeight;
  const angle2 = rotationDeg % 180 * (Math.PI / 180);
  const sin = Math.abs(Math.sin(angle2));
  const cos = Math.abs(Math.cos(angle2));
  if (sin === 0)
    return { width: w, height: h };
  if (cos === 0)
    return { width: h, height: w };
  return {
    width: w * cos + h * sin,
    height: w * sin + h * cos
  };
}
function rotatePoint(x, y, angle2, originX = 0, originY = 0) {
  const cos = Math.cos(angle2);
  const sin = Math.sin(angle2);
  const dx2 = x - originX;
  const dy2 = y - originY;
  return {
    x: originX + dx2 * cos - dy2 * sin,
    y: originY + dx2 * sin + dy2 * cos
  };
}

// packages/ag-charts-core/src/utils/geometry/angle.ts
var twoPi = Math.PI * 2;
var halfPi = Math.PI / 2;
function normalizeAngle360(radians) {
  radians %= twoPi;
  radians += twoPi;
  radians %= twoPi;
  return radians;
}
function normalizeAngle360Inclusive(radians) {
  radians %= twoPi;
  radians += twoPi;
  if (radians !== twoPi) {
    radians %= twoPi;
  }
  return radians;
}
function normalizeAngle180(radians) {
  radians %= twoPi;
  if (radians < -Math.PI) {
    radians += twoPi;
  } else if (radians >= Math.PI) {
    radians -= twoPi;
  }
  return radians;
}
function isBetweenAngles(targetAngle, startAngle, endAngle) {
  const t = normalizeAngle360(targetAngle);
  const a0 = normalizeAngle360(startAngle);
  const a1 = normalizeAngle360(endAngle);
  if (a0 < a1) {
    return a0 <= t && t <= a1;
  } else if (a0 > a1) {
    return a0 <= t || t <= a1;
  } else {
    return startAngle !== endAngle;
  }
}
function toRadians(degrees) {
  return degrees / 180 * Math.PI;
}
function toDegrees(radians) {
  return radians / Math.PI * 180;
}
function angleBetween(angle0, angle1) {
  angle0 = normalizeAngle360(angle0);
  angle1 = normalizeAngle360(angle1);
  return angle1 - angle0 + (angle0 > angle1 ? twoPi : 0);
}
function getAngleRatioRadians(angle2) {
  const normalizedAngle = normalizeAngle360(angle2);
  if (normalizedAngle <= halfPi) {
    return normalizedAngle / halfPi;
  } else if (normalizedAngle <= Math.PI) {
    return (Math.PI - normalizedAngle) / halfPi;
  } else if (normalizedAngle <= 1.5 * Math.PI) {
    return (normalizedAngle - Math.PI) / halfPi;
  } else {
    return (twoPi - normalizedAngle) / halfPi;
  }
}
function angularPadding(hPadding, vPadding, angle2) {
  const angleRatio = getAngleRatioRadians(angle2);
  return hPadding * angleRatio + vPadding * Math.abs(1 - angleRatio);
}
function normalizeAngle360FromDegrees(degrees) {
  return degrees ? normalizeAngle360(toRadians(degrees)) : 0;
}

// packages/ag-charts-core/src/utils/async.ts
var AsyncAwaitQueue = class {
  constructor() {
    this.queue = [];
  }
  /** Await another async process to call notify(). */
  waitForCompletion(timeout = 50) {
    const queue = this.queue;
    function createCompletionPromise(resolve) {
      function successFn() {
        clearTimeout(timeoutHandle);
        resolve(true);
      }
      function timeoutFn() {
        const queueIndex = queue.indexOf(successFn);
        if (queueIndex < 0)
          return;
        queue.splice(queueIndex, 1);
        resolve(false);
      }
      const timeoutHandle = setTimeout(timeoutFn, timeout);
      queue.push(successFn);
    }
    return new Promise(createCompletionPromise);
  }
  /** Trigger any await()ing async processes to continue. */
  notify() {
    for (const cb of this.queue.splice(0)) {
      cb();
    }
  }
};
function pause(delayMilliseconds = 0) {
  function resolveAfterDelay(resolve) {
    setTimeout(resolve, delayMilliseconds);
  }
  return new Promise(resolveAfterDelay);
}
async function withTimeout(promise, timeoutMs, errorMessage = `Timeout after ${timeoutMs}ms`) {
  let timer;
  const timeoutPromise = new Promise((_, reject) => {
    timer = setTimeout(() => reject(new Error(errorMessage)), timeoutMs);
  });
  try {
    return await Promise.race([promise, timeoutPromise]);
  } finally {
    clearTimeout(timer);
  }
}

// packages/ag-charts-core/src/utils/dom/attributeUtil.ts
function booleanParser(value) {
  return value === "true";
}
function numberParser(value) {
  return Number(value);
}
function stringParser(value) {
  return value;
}
var AttributeTypeParsers = {
  role: stringParser,
  "aria-checked": booleanParser,
  "aria-controls": stringParser,
  "aria-describedby": stringParser,
  "aria-disabled": booleanParser,
  "aria-expanded": booleanParser,
  "aria-haspopup": stringParser,
  "aria-hidden": booleanParser,
  "aria-label": stringParser,
  "aria-labelledby": stringParser,
  "aria-live": stringParser,
  "aria-orientation": stringParser,
  "aria-selected": booleanParser,
  "data-focus-override": booleanParser,
  "data-focus-visible-override": booleanParser,
  "data-preventdefault": booleanParser,
  class: stringParser,
  for: stringParser,
  id: stringParser,
  tabindex: numberParser,
  title: stringParser,
  placeholder: stringParser
};
function setAttribute(e, qualifiedName, value) {
  if (value == null || value === "" || value === "") {
    e?.removeAttribute(qualifiedName);
  } else {
    e?.setAttribute(qualifiedName, value.toString());
  }
}
function setAttributes(e, attrs) {
  if (attrs == null)
    return;
  for (const [key, value] of entries(attrs)) {
    if (key === "class")
      continue;
    setAttribute(e, key, value);
  }
}
function getAttribute(e, qualifiedName, defaultValue) {
  if (!isHTMLElement(e))
    return void 0;
  const value = e.getAttribute(qualifiedName);
  if (value === null)
    return defaultValue;
  return AttributeTypeParsers[qualifiedName]?.(value) ?? void 0;
}
function setElementStyle(e, property, value) {
  if (e == null)
    return;
  if (value == null) {
    e.style.removeProperty(property);
  } else {
    e.style.setProperty(property, value.toString());
  }
}
function setElementStyles(e, styles) {
  for (const [key, value] of entries(styles)) {
    setElementStyle(e, key, value);
  }
}

// packages/ag-charts-core/src/state/proxy.ts
function ProxyProperty(proxyPath, configMetadata) {
  const pathArray = Array.isArray(proxyPath) ? proxyPath : proxyPath.split(".");
  if (pathArray.length === 1) {
    const [property] = pathArray;
    return addTransformToInstanceProperty(
      (target, _, value) => target[property] = value,
      (target) => target[property],
      configMetadata
    );
  }
  return addTransformToInstanceProperty(
    (target, _, value) => setPath(target, pathArray, value),
    (target) => getPath(target, pathArray),
    configMetadata
  );
}
function ProxyOnWrite(proxyProperty) {
  return addTransformToInstanceProperty((target, _, value) => target[proxyProperty] = value);
}
function ProxyPropertyOnWrite(childName, childProperty) {
  return addTransformToInstanceProperty((target, key, value) => target[childName][childProperty ?? key] = value);
}
function ActionOnSet(opts) {
  const { newValue: newValueFn, oldValue: oldValueFn, changeValue: changeValueFn } = opts;
  return addTransformToInstanceProperty((target, _, newValue, oldValue) => {
    if (newValue !== oldValue) {
      if (oldValue !== void 0) {
        oldValueFn?.call(target, oldValue);
      }
      if (newValue !== void 0) {
        newValueFn?.call(target, newValue);
      }
      changeValueFn?.call(target, newValue, oldValue);
    }
    return newValue;
  });
}
function ObserveChanges(observerFn) {
  return addObserverToInstanceProperty(observerFn);
}

// packages/ag-charts-core/src/utils/geometry/border.ts
var Border = class extends BaseProperties {
  constructor(node) {
    super();
    this.node = node;
    this.enabled = false;
    this.stroke = "black";
    this.strokeOpacity = 1;
    this.strokeWidth = 1;
  }
};
__decorateClass([
  ActionOnSet({
    changeValue(newValue) {
      if (newValue) {
        this.node.strokeWidth = this.strokeWidth;
      } else {
        this.node.strokeWidth = 0;
      }
    }
  }),
  addFakeTransformToInstanceProperty
], Border.prototype, "enabled", 2);
__decorateClass([
  ProxyPropertyOnWrite("node", "stroke"),
  addFakeTransformToInstanceProperty
], Border.prototype, "stroke", 2);
__decorateClass([
  ProxyPropertyOnWrite("node", "strokeOpacity"),
  addFakeTransformToInstanceProperty
], Border.prototype, "strokeOpacity", 2);
__decorateClass([
  ActionOnSet({
    changeValue(newValue) {
      if (this.enabled) {
        this.node.strokeWidth = newValue;
      } else {
        this.node.strokeWidth = 0;
      }
    }
  }),
  addFakeTransformToInstanceProperty
], Border.prototype, "strokeWidth", 2);

// packages/ag-charts-core/src/utils/geometry/boxBounds.ts
function boxCollides(b, x, y, w, h) {
  return x < b.x + b.width && x + w > b.x && y < b.y + b.height && y + h > b.y;
}
function boxContains(b, x, y, w = 0, h = 0) {
  return x >= b.x && x + w <= b.x + b.width && y >= b.y && y + h <= b.y + b.height;
}
function boxEmpty(b) {
  return b == null || b.height === 0 || b.width === 0 || Number.isNaN(b.height) || Number.isNaN(b.width);
}
function boxesEqual(a, b) {
  if (a === b)
    return true;
  if (a == null || b == null)
    return false;
  return a.x === b.x && a.y === b.y && a.width === b.width && a.height === b.height;
}

// packages/ag-charts-core/src/utils/data/binarySearch.ts
function findMaxIndex(min, max, iteratee) {
  if (min > max)
    return;
  let found;
  while (max >= min) {
    const index = Math.floor((max + min) / 2);
    const value = iteratee(index);
    if (value) {
      found = index;
      min = index + 1;
    } else {
      max = index - 1;
    }
  }
  return found;
}
function findMinIndex(min, max, iteratee) {
  if (min > max)
    return;
  let found;
  while (max >= min) {
    const index = Math.floor((max + min) / 2);
    const value = iteratee(index);
    if (value) {
      found = index;
      max = index - 1;
    } else {
      min = index + 1;
    }
  }
  return found;
}
function findMaxValue(min, max, iteratee) {
  if (min > max)
    return;
  let found;
  while (max >= min) {
    const index = Math.floor((max + min) / 2);
    const value = iteratee(index);
    if (value == null) {
      max = index - 1;
    } else {
      found = value;
      min = index + 1;
    }
  }
  return found;
}
function findMinValue(min, max, iteratee) {
  if (min > max)
    return;
  let found;
  while (max >= min) {
    const index = Math.floor((max + min) / 2);
    const value = iteratee(index);
    if (value == null) {
      min = index + 1;
    } else {
      found = value;
      max = index - 1;
    }
  }
  return found;
}

// packages/ag-charts-core/src/utils/canvas.ts
function createCanvasContext(width2 = 0, height2 = 0) {
  const OffscreenCanvasCtor = getOffscreenCanvas();
  return new OffscreenCanvasCtor(width2, height2).getContext("2d");
}

// packages/ag-charts-core/src/utils/configuredCanvasMixin.ts
var CANVAS_WIDTH = 800;
var CANVAS_HEIGHT = 600;
var CANVAS_TO_BUFFER_DEFAULTS = { quality: 1 };
function ConfiguredCanvasMixin(Base) {
  const ConfiguredCanvasClass = class ConfiguredCanvas extends Base {
    constructor(...args) {
      super(...args);
      this.gpu = false;
    }
    toBuffer(format, options) {
      return super.toBuffer(format, { ...options, msaa: false });
    }
    transferToImageBitmap() {
      const { width: width2, height: height2 } = this;
      const bitmap = new ConfiguredCanvasClass(Math.max(1, width2), Math.max(1, height2));
      if (width2 > 0 && height2 > 0) {
        bitmap.getContext("2d").drawCanvas(this, 0, 0, width2, height2);
      }
      Object.defineProperty(bitmap, "close", {
        value: () => {
        }
      });
      return bitmap;
    }
  };
  return ConfiguredCanvasClass;
}
var patchesApplied = false;
function applySkiaPatches(CanvasRenderingContext2D, DOMMatrix) {
  if (patchesApplied)
    return;
  patchesApplied = true;
  const superCreateConicGradient = CanvasRenderingContext2D.prototype.createConicGradient;
  Object.defineProperty(CanvasRenderingContext2D.prototype, "createConicGradient", {
    value: function(angle2, x, y) {
      return superCreateConicGradient.call(this, angle2 + Math.PI / 2, x, y);
    },
    writable: true,
    configurable: true
  });
  Object.defineProperty(CanvasRenderingContext2D.prototype, "fillText", {
    value: function(text2, x, y) {
      let path2d = this.outlineText(text2);
      path2d = path2d.transform(new DOMMatrix([1, 0, 0, 1, x, y]));
      this.fill(path2d);
    },
    writable: true,
    configurable: true
  });
}

// packages/ag-charts-core/src/state/caching.ts
var SimpleCache = class {
  constructor(getter) {
    this.getter = getter;
  }
  get() {
    this.result ?? (this.result = this.getter());
    return this.result;
  }
  clear() {
    this.result = void 0;
  }
};
var WeakCache = class {
  constructor(getter) {
    this.getter = getter;
  }
  get() {
    let result = this.result?.deref();
    if (result)
      return result;
    result = this.getter();
    this.result = new WeakRef(result);
    return result;
  }
  clear() {
    this.result = void 0;
  }
};

// packages/ag-charts-core/src/utils/time/date.ts
function compareDates(a, b) {
  return a.valueOf() - b.valueOf();
}
function deduplicateSortedArray(values) {
  let v0 = Number.NaN;
  const out = [];
  for (const v of values) {
    const v1 = v.valueOf();
    if (v0 !== v1)
      out.push(v);
    v0 = v1;
  }
  return out;
}
function sortAndUniqueDates(values) {
  const sortedValues = values.slice().sort(compareDates);
  return datesSortOrder(sortedValues) == null ? deduplicateSortedArray(sortedValues) : sortedValues;
}
function datesSortOrder(d) {
  if (d.length === 0)
    return 1;
  const sign = Number(d.at(-1)) > Number(d[0]) ? 1 : -1;
  let v0 = -Infinity * sign;
  for (const v of d) {
    const v1 = v.valueOf();
    if (Math.sign(v1 - v0) !== sign)
      return;
    v0 = v1;
  }
  return sign;
}

// packages/ag-charts-core/src/utils/deprecation.ts
function createDeprecationWarning() {
  return (key, message) => {
    const msg = [`Property [${key}] is deprecated.`, message].filter(Boolean).join(" ");
    warnOnce(msg);
  };
}
function Deprecated(message, opts) {
  const warnDeprecated = createDeprecationWarning();
  const def = opts?.default;
  return addTransformToInstanceProperty((_, key, value) => {
    if (value !== def) {
      warnDeprecated(key.toString(), message);
    }
    return value;
  });
}
function DeprecatedAndRenamedTo(newPropName, mapValue) {
  const warnDeprecated = createDeprecationWarning();
  return addTransformToInstanceProperty(
    (target, key, value) => {
      if (value !== target[newPropName]) {
        warnDeprecated(key.toString(), `Use [${newPropName}] instead.`);
        setPath(target, newPropName, mapValue ? mapValue(value) : value);
      }
      return BREAK_TRANSFORM_CHAIN;
    },
    (target, key) => {
      warnDeprecated(key.toString(), `Use [${newPropName}] instead.`);
      return getPath(target, newPropName);
    }
  );
}

// packages/ag-charts-core/src/utils/data/diff.ts
function diffArrays(previous, current) {
  const size = Math.max(previous.length, current.length);
  const added = /* @__PURE__ */ new Set();
  const removed = /* @__PURE__ */ new Set();
  for (let i = 0; i < size; i++) {
    const prev = previous[i];
    const curr = current[i];
    if (prev === curr)
      continue;
    if (removed.has(curr)) {
      removed.delete(curr);
    } else if (curr) {
      added.add(curr);
    }
    if (added.has(prev)) {
      added.delete(prev);
    } else if (prev) {
      removed.add(prev);
    }
  }
  return { changed: added.size > 0 || removed.size > 0, added, removed };
}

// packages/ag-charts-core/src/utils/geometry/distance.ts
function pointsDistanceSquared(x1, y1, x2, y2) {
  const dx2 = x1 - x2;
  const dy2 = y1 - y2;
  return dx2 * dx2 + dy2 * dy2;
}
function lineDistanceSquared(x, y, x1, y1, x2, y2, best) {
  if (x1 === x2 && y1 === y2) {
    return Math.min(best, pointsDistanceSquared(x, y, x1, y1));
  }
  const dx2 = x2 - x1;
  const dy2 = y2 - y1;
  const t = Math.max(0, Math.min(1, ((x - x1) * dx2 + (y - y1) * dy2) / (dx2 * dx2 + dy2 * dy2)));
  const ix = x1 + t * dx2;
  const iy = y1 + t * dy2;
  return Math.min(best, pointsDistanceSquared(x, y, ix, iy));
}
function arcDistanceSquared(x, y, cx, cy, radius, startAngle, endAngle, counterClockwise, best) {
  if (counterClockwise) {
    [endAngle, startAngle] = [startAngle, endAngle];
  }
  const angle2 = Math.atan2(y - cy, x - cx);
  if (!isBetweenAngles(angle2, startAngle, endAngle)) {
    const startX = cx + Math.cos(startAngle) * radius;
    const startY = cy + Math.sin(startAngle) * radius;
    const endX = cx + Math.cos(startAngle) * radius;
    const endY = cy + Math.sin(startAngle) * radius;
    return Math.min(best, pointsDistanceSquared(x, y, startX, startY), pointsDistanceSquared(x, y, endX, endY));
  }
  const distToArc = radius - Math.sqrt(pointsDistanceSquared(x, y, cx, cy));
  return Math.min(best, distToArc * distToArc);
}

// packages/ag-charts-core/src/utils/data/extent.ts
function extent(values, sortOrder) {
  if (values.length === 0) {
    return null;
  }
  if (sortOrder !== void 0) {
    const first2 = values.at(0);
    const last = values.at(-1);
    const v0 = first2 instanceof Date ? first2.getTime() : first2;
    const v1 = last instanceof Date ? last.getTime() : last;
    if (typeof v0 === "number" && typeof v1 === "number") {
      return sortOrder === 1 ? [v0, v1] : [v1, v0];
    }
  }
  let min = Infinity;
  let max = -Infinity;
  for (const n of values) {
    const v = n instanceof Date ? n.getTime() : n;
    if (typeof v !== "number")
      continue;
    if (v < min) {
      min = v;
    }
    if (v > max) {
      max = v;
    }
  }
  const result = [min, max];
  return result.every(Number.isFinite) ? result : null;
}
function normalisedExtentWithMetadata(d, min, max, preferredMin, preferredMax, toValue, sortOrder) {
  let clipped = false;
  const domainExtentNumbers = extent(d, sortOrder);
  const domainExtent = domainExtentNumbers && toValue ? [toValue(domainExtentNumbers[0]), toValue(domainExtentNumbers[1])] : domainExtentNumbers;
  if (domainExtent == null) {
    let nullExtent;
    if (min != null && max != null && min <= max) {
      nullExtent = [min, max];
    } else if (preferredMin != null && preferredMax != null && preferredMin <= preferredMax) {
      nullExtent = [preferredMin, preferredMax];
    }
    return { extent: nullExtent ?? [], clipped: false };
  }
  let [d0, d1] = domainExtent;
  if (min != null) {
    clipped || (clipped = min > d0);
    d0 = min;
  } else if (preferredMin != null && preferredMin < d0) {
    d0 = preferredMin;
  }
  if (max != null) {
    clipped || (clipped = max < d1);
    d1 = max;
  } else if (preferredMax != null && preferredMax > d1) {
    d1 = preferredMax;
  }
  if (d0 > d1) {
    return { extent: [], clipped: false };
  }
  return { extent: [d0, d1], clipped };
}
function normalisedTimeExtentWithMetadata(input, min, max, preferredMin, preferredMax) {
  const { extent: e, clipped } = normalisedExtentWithMetadata(
    input.domain,
    isNumber(min) ? new Date(min) : min,
    isNumber(max) ? new Date(max) : max,
    isNumber(preferredMin) ? new Date(preferredMin) : preferredMin,
    isNumber(preferredMax) ? new Date(preferredMax) : preferredMax,
    (x) => new Date(x),
    input.sortMetadata?.sortOrder
  );
  return { extent: e.map((x) => new Date(x)), clipped };
}

// packages/ag-charts-core/src/utils/format/format.util.ts
var percentFormatter = new Intl.NumberFormat("en-US", { style: "percent" });
function formatValue(value, maximumFractionDigits = 2) {
  if (typeof value === "number") {
    return formatNumber(value, maximumFractionDigits);
  }
  return typeof value === "string" ? value : String(value ?? "");
}
function formatPercent(value) {
  return percentFormatter.format(value);
}
var numberFormatters = (/* @__PURE__ */ new Map()).set(
  2,
  new Intl.NumberFormat("en-US", { maximumFractionDigits: 2, useGrouping: false })
);
function formatNumber(value, maximumFractionDigits) {
  let formatter2 = numberFormatters.get(maximumFractionDigits);
  if (!formatter2) {
    formatter2 = new Intl.NumberFormat("en-US", { maximumFractionDigits, useGrouping: false });
    numberFormatters.set(maximumFractionDigits, formatter2);
  }
  return formatter2.format(value);
}

// packages/ag-charts-core/src/utils/geojson.ts
function isValidCoordinate(value) {
  return Array.isArray(value) && value.length >= 2 && value.every(isFiniteNumber);
}
function isValidCoordinates(value) {
  return Array.isArray(value) && value.length >= 2 && value.every(isValidCoordinate);
}
function hasSameStartEndPoint(c) {
  const start2 = c[0];
  const end3 = c.at(-1);
  if (end3 === void 0)
    return false;
  return isNumberEqual(start2[0], end3[0], 1e-3) && isNumberEqual(start2[1], end3[1], 1e-3);
}
function isValidPolygon(value) {
  return Array.isArray(value) && value.every(isValidCoordinates) && value.every(hasSameStartEndPoint);
}
function isValidGeometry(value) {
  if (value === null)
    return true;
  if (!isObject(value) || value.type == null)
    return false;
  const { type, coordinates } = value;
  switch (type) {
    case "GeometryCollection":
      return Array.isArray(value.geometries) && value.geometries.every(isValidGeometry);
    case "MultiPolygon":
      return Array.isArray(coordinates) && coordinates.every(isValidPolygon);
    case "Polygon":
      return isValidPolygon(coordinates);
    case "MultiLineString":
      return Array.isArray(coordinates) && coordinates.every(isValidCoordinates);
    case "LineString":
      return isValidCoordinates(coordinates);
    case "MultiPoint":
      return isValidCoordinates(coordinates);
    case "Point":
      return isValidCoordinate(coordinates);
    default:
      return false;
  }
}
function isValidFeature(value) {
  return isObject(value) && value.type === "Feature" && isValidGeometry(value.geometry);
}
function isValidFeatureCollection(value) {
  return isObject(value) && value.type === "FeatureCollection" && Array.isArray(value.features) && value.features.every(isValidFeature);
}
var geoJson = attachDescription(isValidFeatureCollection, "a GeoJSON object");

// packages/ag-charts-core/src/structures/graph.ts
var AdjacencyListGraph = class {
  constructor(cachedNeighboursEdge, processedEdge, singleValueEdges) {
    this._vertexCount = 0;
    this._edgeCount = 0;
    this.pendingProcessingEdgesFrom = [];
    this.pendingProcessingEdgesTo = [];
    this.cachedNeighboursEdge = cachedNeighboursEdge;
    this.processedEdge = processedEdge;
    this.singleValueEdges = singleValueEdges;
  }
  clear() {
    this._vertexCount = 0;
    this._edgeCount = 0;
    this.pendingProcessingEdgesFrom = [];
    this.pendingProcessingEdgesTo = [];
    this.singleValueEdges?.clear();
  }
  getVertexCount() {
    return this._vertexCount;
  }
  getEdgeCount() {
    return this._edgeCount;
  }
  addVertex(value) {
    const vertex = new Vertex(value);
    this._vertexCount++;
    return vertex;
  }
  addEdge(from3, to, edge) {
    if (edge === this.cachedNeighboursEdge) {
      from3.updateCachedNeighbours().set(to.value, to);
    } else if (edge === this.processedEdge) {
      this.pendingProcessingEdgesFrom.push(from3);
      this.pendingProcessingEdgesTo.push(to);
    }
    const { edges } = from3;
    const vertices = edges.get(edge);
    if (!vertices) {
      edges.set(edge, [to]);
      this._edgeCount++;
    } else if (!vertices.includes(to)) {
      if (this.singleValueEdges?.has(edge)) {
        edges.set(edge, [to]);
      } else {
        vertices.push(to);
        this._edgeCount++;
      }
    }
  }
  removeVertex(vertex) {
    this._vertexCount--;
    const edges = vertex.edges;
    if (!edges)
      return;
    for (const [, adjacentVertices] of edges) {
      this._vertexCount -= adjacentVertices.length;
    }
    vertex.clear();
  }
  removeEdge(from3, to, edge) {
    const neighbours = from3.edges.get(edge);
    if (!neighbours)
      return;
    const index = neighbours.indexOf(to);
    if (index === -1)
      return;
    neighbours.splice(index, 1);
    if (neighbours.length === 0) {
      from3.edges.delete(edge);
    }
    this._edgeCount--;
    if (edge === this.cachedNeighboursEdge) {
      from3.readCachedNeighbours()?.delete(to.value);
    }
  }
  removeEdges(from3, edgeValue) {
    from3.edges.delete(edgeValue);
  }
  getVertexValue(vertex) {
    return vertex.value;
  }
  // Iterate all the neighbours of a given vertex.
  *neighbours(from3) {
    for (const [, adjacentVertices] of from3.edges) {
      for (const adjacentVertex of adjacentVertices) {
        yield adjacentVertex;
      }
    }
  }
  // Iterate all the neighbours and their edges of a given vertex
  *neighboursAndEdges(from3) {
    for (const [edge, adjacentVertices] of from3.edges) {
      for (const adjacentVertex of adjacentVertices) {
        yield [adjacentVertex, edge];
      }
    }
  }
  // Get the set of neighbours along a given edge.
  neighboursWithEdgeValue(from3, edgeValue) {
    return from3.edges.get(edgeValue);
  }
  // Find the first neighbour along the given edge.
  findNeighbour(from3, edgeValue) {
    return from3.edges.get(edgeValue)?.[0];
  }
  // Find the value of the first neighbour along the given edge.
  findNeighbourValue(from3, edgeValue) {
    const neighbour = this.findNeighbour(from3, edgeValue);
    if (!neighbour)
      return;
    return this.getVertexValue(neighbour);
  }
  // Find the first neighbour with a given value, optionally along a given edge.
  findNeighbourWithValue(from3, value, edgeValue) {
    const neighbours = edgeValue == null ? this.neighbours(from3) : this.neighboursWithEdgeValue(from3, edgeValue);
    if (!neighbours)
      return;
    for (const neighbour of neighbours) {
      if (this.getVertexValue(neighbour) === value) {
        return neighbour;
      }
    }
  }
  // Find a vertex by iterating an array of vertex values along a given edge.
  findVertexAlongEdge(from3, findValues, edgeValue) {
    if (edgeValue === this.cachedNeighboursEdge) {
      let found2;
      for (const value of findValues) {
        found2 = (found2 ?? from3).readCachedNeighbours()?.get(value);
        if (!found2)
          return;
      }
      return found2;
    }
    if (findValues.length === 0)
      return;
    let found = from3;
    for (const value of findValues) {
      const neighbours = found ? this.neighboursWithEdgeValue(found, edgeValue) : void 0;
      if (!neighbours)
        return;
      found = neighbours.find((n) => n.value === value);
    }
    return found;
  }
  adjacent(from3, to) {
    for (const [, adjacentVertices] of from3.edges) {
      if (adjacentVertices.includes(to))
        return true;
    }
    return false;
  }
};
var Vertex = class {
  constructor(value) {
    this.value = value;
    this.edges = /* @__PURE__ */ new Map();
  }
  readCachedNeighbours() {
    return this._cachedNeighbours;
  }
  updateCachedNeighbours() {
    this._cachedNeighbours ?? (this._cachedNeighbours = /* @__PURE__ */ new Map());
    return this._cachedNeighbours;
  }
  clear() {
    this.edges.clear();
    this._cachedNeighbours?.clear();
  }
};

// packages/ag-charts-core/src/utils/data/json.ts
var CLASS_INSTANCE_TYPE = "class-instance";
function jsonDiff(source, target, shallow) {
  if (isArray(target)) {
    if (!isArray(source) || source.length !== target.length || target.some((v, i) => jsonDiff(source[i], v, shallow) != null)) {
      return target;
    }
  } else if (isPlainObject(target)) {
    if (!isPlainObject(source)) {
      return target;
    }
    const result = {};
    const allKeys = /* @__PURE__ */ new Set([
      ...Object.keys(source),
      ...Object.keys(target)
    ]);
    for (const key of allKeys) {
      if (source[key] === target[key]) {
        continue;
      } else if (shallow?.has(key)) {
        result[key] = target[key];
      } else if (typeof source[key] === typeof target[key]) {
        const diff9 = jsonDiff(source[key], target[key], shallow);
        if (diff9 !== null) {
          result[key] = diff9;
        }
      } else {
        result[key] = target[key];
      }
    }
    return Object.keys(result).length ? result : null;
  } else if (source !== target) {
    return target;
  }
  return null;
}
function jsonPropertyCompare(source, target) {
  for (const key of Object.keys(source)) {
    if (source[key] === target?.[key])
      continue;
    return false;
  }
  return true;
}
function deepClone(source, opts) {
  if (isArray(source)) {
    return cloneArray(source, opts);
  }
  if (isPlainObject(source)) {
    return clonePlainObject(source, opts);
  }
  if (source instanceof Map) {
    return new Map(deepClone(Array.from(source)));
  }
  return shallowClone(source);
}
function cloneArray(source, opts) {
  const result = [];
  const seen = opts?.seen;
  for (const item of source) {
    if (typeof item === "object" && seen?.includes(item)) {
      warn("cycle detected in array", item);
      continue;
    }
    seen?.push(item);
    result.push(deepClone(item, opts));
    seen?.pop();
  }
  return result;
}
function clonePlainObject(source, opts) {
  const target = {};
  for (const key of Object.keys(source)) {
    if (opts?.assign?.has(key)) {
      target[key] = source[key];
    } else if (opts?.shallow?.has(key)) {
      target[key] = shallowClone(source[key]);
    } else {
      target[key] = deepClone(source[key], opts);
    }
  }
  return target;
}
function shallowClone(source) {
  if (isArray(source)) {
    return source.slice(0);
  }
  if (isPlainObject(source)) {
    return { ...source };
  }
  if (isDate(source)) {
    return new Date(source);
  }
  if (isRegExp(source)) {
    return new RegExp(source.source, source.flags);
  }
  return source;
}
function jsonWalk(json, visit, skip, parallelJson, ctx, acc) {
  if (isArray(json)) {
    acc = visit(json, parallelJson, ctx, acc);
    let index = 0;
    for (const node of json) {
      acc = jsonWalk(node, visit, skip, parallelJson?.[index], ctx, acc);
      index++;
    }
  } else if (isPlainObject(json)) {
    acc = visit(json, parallelJson, ctx, acc);
    for (const key of Object.keys(json)) {
      if (skip?.has(key)) {
        continue;
      }
      const value = json[key];
      acc = jsonWalk(value, visit, skip, parallelJson?.[key], ctx, acc);
    }
  }
  return acc;
}
function jsonApply(target, source, params = {}) {
  const { path, matcherPath = path?.replace(/(\[[0-9+]+])/i, "[]"), skip = [] } = params;
  if (target == null) {
    throw new Error(`AG Charts - target is uninitialised: ${path ?? "<root>"}`);
  }
  if (source == null) {
    return target;
  }
  if (isProperties(target)) {
    return target.set(source);
  }
  const targetAny = target;
  const targetType = classify(target);
  for (const property of Object.keys(source)) {
    if (SKIP_JS_BUILTINS.has(property))
      continue;
    const propertyMatcherPath = `${matcherPath ? matcherPath + "." : ""}${property}`;
    if (skip.includes(propertyMatcherPath))
      continue;
    const newValue = source[property];
    const propertyPath = `${path ? path + "." : ""}${property}`;
    const targetClass = targetAny.constructor;
    const currentValue = targetAny[property];
    try {
      const currentValueType = classify(currentValue);
      const newValueType = classify(newValue);
      if (targetType === CLASS_INSTANCE_TYPE && !(property in target || property === "context")) {
        if (newValue === void 0)
          continue;
        warn(`unable to set [${propertyPath}] in ${targetClass?.name} - property is unknown`);
        continue;
      }
      if (currentValueType != null && newValueType != null && newValueType !== currentValueType && (currentValueType !== CLASS_INSTANCE_TYPE || newValueType !== "object")) {
        warn(
          `unable to set [${propertyPath}] in ${targetClass?.name} - can't apply type of [${newValueType}], allowed types are: [${currentValueType}]`
        );
        continue;
      }
      if (isProperties(currentValue)) {
        if (newValue === void 0) {
          currentValue.clear();
        } else {
          currentValue.set(newValue);
        }
      } else if (newValueType === "object" && property !== "context") {
        if (!(property in targetAny)) {
          warn(`unable to set [${propertyPath}] in ${targetClass?.name} - property is unknown`);
          continue;
        }
        if (currentValue == null) {
          targetAny[property] = newValue;
        } else {
          jsonApply(currentValue, newValue, {
            ...params,
            path: propertyPath,
            matcherPath: propertyMatcherPath
          });
        }
      } else {
        targetAny[property] = newValue;
      }
    } catch (error2) {
      warn(`unable to set [${propertyPath}] in [${targetClass?.name}]; nested error is: ${error2.message}`);
    }
  }
  return target;
}
function classify(value) {
  if (value == null) {
    return null;
  }
  if (isHtmlElement(value) || isDate(value)) {
    return "primitive";
  }
  if (isArray(value)) {
    return "array";
  }
  if (isObject(value)) {
    return isPlainObject(value) ? "object" : CLASS_INSTANCE_TYPE;
  }
  if (isFunction(value)) {
    return "function";
  }
  return "primitive";
}

// packages/ag-charts-core/src/utils/dom/domEvents.ts
function attachListener(element2, eventName, handler, options) {
  element2.addEventListener(eventName, handler, options);
  return () => element2.removeEventListener(eventName, handler, options);
}

// packages/ag-charts-core/src/utils/dom/keynavUtil.ts
function addEscapeEventListener(elem, onEscape, keyCodes = ["Escape"]) {
  return attachListener(elem, "keydown", (event) => {
    if (matchesKey(event, ...keyCodes)) {
      onEscape(event);
    }
  });
}
function addMouseCloseListener(menu, hideCallback) {
  const removeEvent = attachListener(getWindow(), "mousedown", (event) => {
    if ([0, 2].includes(event.button) && !containsEvent(menu, event)) {
      hideCallback();
      removeEvent();
    }
  });
  return removeEvent;
}
function addTouchCloseListener(menu, hideCallback) {
  const removeEvent = attachListener(getWindow(), "touchstart", (event) => {
    const touches = Array.from(event.targetTouches);
    if (touches.some((touch) => !containsEvent(menu, touch))) {
      hideCallback();
      removeEvent();
    }
  });
  return removeEvent;
}
function containsEvent(container, event) {
  if (isElement(event.target) && event.target.shadowRoot != null) {
    return true;
  }
  return isNode(event.target) && container.contains(event.target);
}
function addOverrideFocusVisibleEventListener(menu, buttons, overrideFocusVisible) {
  const setFocusVisible = (value) => {
    for (const btn of buttons) {
      setAttribute(btn, "data-focus-visible-override", value);
    }
  };
  setFocusVisible(overrideFocusVisible);
  return attachListener(menu, "keydown", () => setFocusVisible(true), { once: true });
}
function hasNoModifiers(event) {
  return !(event.shiftKey || event.altKey || event.ctrlKey || event.metaKey);
}
function matchesKey(event, ...keys) {
  return hasNoModifiers(event) && keys.includes(event.key);
}
function linkTwoButtons(src, dst, key) {
  return attachListener(src, "keydown", (event) => {
    if (matchesKey(event, key)) {
      dst.focus();
    }
  });
}
var PREV_NEXT_KEYS = {
  horizontal: { nextKey: "ArrowRight", prevKey: "ArrowLeft" },
  vertical: { nextKey: "ArrowDown", prevKey: "ArrowUp" }
};
function initRovingTabIndex(opts) {
  const { orientation, buttons, wrapAround = false, onEscape, onFocus, onBlur } = opts;
  const { nextKey, prevKey } = PREV_NEXT_KEYS[orientation];
  const setTabIndices = (event) => {
    if (event.target && "tabIndex" in event.target) {
      for (const b of buttons) {
        b.tabIndex = -1;
      }
      event.target.tabIndex = 0;
    }
  };
  const [c, m] = wrapAround ? [buttons.length, buttons.length] : [0, Infinity];
  const cleanup = new CleanupRegistry();
  for (let i = 0; i < buttons.length; i++) {
    const prev = buttons[(c + i - 1) % m];
    const curr = buttons[i];
    const next = buttons[(c + i + 1) % m];
    cleanup.register(
      attachListener(curr, "focus", setTabIndices),
      onFocus && attachListener(curr, "focus", onFocus),
      onBlur && attachListener(curr, "blur", onBlur),
      onEscape && addEscapeEventListener(curr, onEscape),
      prev && linkTwoButtons(curr, prev, prevKey),
      next && linkTwoButtons(curr, next, nextKey),
      attachListener(curr, "keydown", (event) => {
        if (matchesKey(event, nextKey, prevKey)) {
          event.preventDefault();
        }
      })
    );
    curr.tabIndex = i === 0 ? 0 : -1;
  }
  return cleanup;
}
function makeAccessibleClickListener(element2, onclick) {
  return (event) => {
    if (element2.ariaDisabled === "true") {
      return event.preventDefault();
    }
    onclick(event);
  };
}
function isButtonClickEvent(event) {
  if ("button" in event) {
    return event.button === 0;
  }
  return hasNoModifiers(event) && (event.code === "Space" || event.key === "Enter");
}
function getLastFocus(sourceEvent) {
  const target = sourceEvent?.target;
  if (isElement(target) && "tabindex" in target.attributes) {
    return target;
  }
  return void 0;
}
function stopPageScrolling(element2) {
  return attachListener(element2, "keydown", (event) => {
    if (event.defaultPrevented)
      return;
    const shouldPrevent = getAttribute(event.target, "data-preventdefault", true);
    if (shouldPrevent && matchesKey(event, "ArrowRight", "ArrowLeft", "ArrowDown", "ArrowUp")) {
      event.preventDefault();
    }
  });
}

// packages/ag-charts-core/src/identity/id.ts
var ID_MAP = /* @__PURE__ */ new Map();
var nextElementID = 1;
function resetIds() {
  ID_MAP.clear();
  nextElementID = 1;
}
function createId(instance) {
  const constructor = instance.constructor;
  let className = Object.hasOwn(constructor, "className") ? constructor.className : constructor.name;
  inDevelopmentMode(() => {
    if (!className) {
      throw new Error(`The ${String(constructor)} is missing the 'className' property.`);
    }
  });
  className ?? (className = "Unknown");
  const nextId = (ID_MAP.get(className) ?? 0) + 1;
  ID_MAP.set(className, nextId);
  return `${className}-${nextId}`;
}
function createElementId() {
  return `ag-charts-${nextElementID++}`;
}
function generateUUID() {
  return crypto.randomUUID?.() ?? generateUUIDv4();
}
function generateUUIDv4() {
  const uuidArray = new Uint8Array(16);
  crypto.getRandomValues(uuidArray);
  uuidArray[6] = uuidArray[6] & 15 | 64;
  uuidArray[8] = uuidArray[8] & 63 | 128;
  let uuid = "";
  for (let i = 0; i < uuidArray.length; i++) {
    if (i === 4 || i === 6 || i === 8 || i === 10) {
      uuid += "-";
    }
    uuid += uuidArray[i].toString(16).padStart(2, "0");
  }
  return uuid;
}

// packages/ag-charts-core/src/utils/data/linkedList.ts
function insertListItemsSorted(list, items, cmp2) {
  let head = list;
  let current = head;
  for (const value of items) {
    if (head == null || cmp2(head.value, value) > 0) {
      head = { value, next: head };
      current = head;
    } else {
      current = current;
      while (current.next != null && cmp2(current.next.value, value) <= 0) {
        current = current.next;
      }
      current.next = { value, next: current.next };
    }
  }
  return head;
}

// packages/ag-charts-core/src/state/memo.ts
var memorizedFns = /* @__PURE__ */ new WeakMap();
function memo(params, fnGenerator) {
  const serialisedParams = JSON.stringify(params, null, 0);
  if (!memorizedFns.has(fnGenerator)) {
    memorizedFns.set(fnGenerator, /* @__PURE__ */ new Map());
  }
  if (!memorizedFns.get(fnGenerator)?.has(serialisedParams)) {
    memorizedFns.get(fnGenerator)?.set(serialisedParams, fnGenerator(params));
  }
  return memorizedFns.get(fnGenerator)?.get(serialisedParams);
}
var MemoizeNode = class {
  constructor() {
    this.weak = /* @__PURE__ */ new WeakMap();
    this.strong = /* @__PURE__ */ new Map();
    this.set = false;
    this.value = void 0;
  }
};
function simpleMemorize2(fn, cacheCallback2) {
  let root = new MemoizeNode();
  const memoised = (...p) => {
    let current = root;
    for (const param of p) {
      const target = typeof param === "object" || typeof param === "symbol" ? current.weak : current.strong;
      let next = target.get(param);
      if (next == null) {
        next = new MemoizeNode();
        target.set(param, next);
      }
      current = next;
    }
    if (current.set) {
      cacheCallback2?.("hit", fn, p);
      return current.value;
    } else {
      const out = fn(...p);
      current.set = true;
      current.value = out;
      cacheCallback2?.("miss", fn, p);
      return out;
    }
  };
  memoised.reset = () => {
    root = new MemoizeNode();
  };
  return memoised;
}
function simpleMemorize(fn, cacheCallback2) {
  const primitiveCache = /* @__PURE__ */ new Map();
  const paramsToKeys = (...params) => {
    return params.map((v) => {
      if (typeof v === "object")
        return v;
      if (typeof v === "symbol")
        return v;
      if (!primitiveCache.has(v)) {
        primitiveCache.set(v, { v });
      }
      return primitiveCache.get(v);
    });
  };
  const empty = {};
  const cache = /* @__PURE__ */ new WeakMap();
  return (...p) => {
    const keys = p.length === 0 ? [empty] : paramsToKeys(...p);
    let currentCache = cache;
    for (const key of keys.slice(0, -1)) {
      if (!currentCache.has(key)) {
        currentCache.set(key, /* @__PURE__ */ new WeakMap());
      }
      currentCache = currentCache.get(key);
    }
    const finalKey = keys.at(-1);
    let cachedValue = currentCache.get(finalKey);
    if (cachedValue) {
      cacheCallback2?.("hit", fn, p);
    } else {
      cachedValue = fn(...p);
      currentCache.set(finalKey, cachedValue);
      cacheCallback2?.("miss", fn, p);
    }
    return cachedValue;
  };
}

// packages/ag-charts-core/src/utils/data/nearest.ts
function nearestSquared(x, y, objects, maxDistanceSquared = Infinity) {
  const result = { nearest: void 0, distanceSquared: maxDistanceSquared };
  for (const obj of objects) {
    const thisDistance = obj.distanceSquared(x, y);
    if (thisDistance === 0) {
      return { nearest: obj, distanceSquared: 0 };
    } else if (thisDistance < result.distanceSquared) {
      result.nearest = obj;
      result.distanceSquared = thisDistance;
    }
  }
  return result;
}
function nearestSquaredInContainer(x, y, container, maxDistanceSquared = Infinity) {
  const { x: tx = x, y: ty = y } = container.transformPoint?.(x, y) ?? {};
  const result = { nearest: void 0, distanceSquared: maxDistanceSquared };
  for (const child of container.children) {
    const { nearest, distanceSquared: distanceSquared2 } = child.nearestSquared(tx, ty, result.distanceSquared);
    if (distanceSquared2 === 0) {
      return { nearest, distanceSquared: distanceSquared2 };
    } else if (distanceSquared2 < result.distanceSquared) {
      result.nearest = nearest;
      result.distanceSquared = distanceSquared2;
    }
  }
  return result;
}

// packages/ag-charts-core/src/utils/geometry/padding.ts
var Padding = class extends BaseProperties {
  constructor(top = 0, right = top, bottom = top, left = right) {
    super();
    this.top = top;
    this.right = right;
    this.bottom = bottom;
    this.left = left;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], Padding.prototype, "top", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Padding.prototype, "right", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Padding.prototype, "bottom", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Padding.prototype, "left", 2);

// packages/ag-charts-core/src/utils/geometry/placement.ts
function calculatePlacement(naturalWidth, naturalHeight, container, bounds) {
  let { top, right, bottom, left, width: width2, height: height2 } = bounds;
  if (left != null) {
    if (width2 != null) {
      right = container.width - left + width2;
    } else if (right != null) {
      width2 = container.width - left - right;
    }
  } else if (right != null && width2 != null) {
    left = container.width - right - width2;
  }
  if (top != null) {
    if (height2 != null) {
      bottom = container.height - top - height2;
    } else if (bottom != null) {
      height2 = container.height - bottom - top;
    }
  } else if (bottom != null && height2 != null) {
    top = container.height - bottom - height2;
  }
  if (width2 == null) {
    if (height2 == null) {
      height2 = naturalHeight;
      width2 = naturalWidth;
    } else {
      width2 = Math.ceil(naturalWidth * height2 / naturalHeight);
    }
  } else {
    height2 ?? (height2 = Math.ceil(naturalHeight * width2 / naturalWidth));
  }
  if (left == null) {
    if (right == null) {
      left = Math.floor((container.width - width2) / 2);
    } else {
      left = container.width - right - width2;
    }
  }
  if (top == null) {
    if (bottom == null) {
      top = Math.floor((container.height - height2) / 2);
    } else {
      top = container.height - height2 - bottom;
    }
  }
  return { x: left, y: top, width: width2, height: height2 };
}

// packages/ag-charts-core/src/state/stateMachine.ts
var debugColor = "color: green";
var debugQuietColor = "color: grey";
function StateMachineProperty() {
  return addObserverToInstanceProperty(() => {
  });
}
function applyProperties(parentState, childState) {
  const childProperties = listDecoratedProperties(childState);
  if (childProperties.length === 0)
    return;
  const properties = extractDecoratedProperties(parentState);
  for (const property of childProperties) {
    if (property in properties) {
      childState[property] = properties[property];
    }
  }
}
var AbstractStateMachine = class {
  transitionRoot(event, data) {
    if (this.parent) {
      this.parent.transitionRoot(event, data);
    } else {
      this.transition(event, data);
    }
  }
};
var _StateMachine = class _StateMachine extends AbstractStateMachine {
  constructor(defaultState, states, enterEach) {
    super();
    this.defaultState = defaultState;
    this.states = states;
    this.enterEach = enterEach;
    this.debug = create(true, "animation");
    this.state = defaultState;
    this.debug(`%c${this.constructor.name} | init -> ${defaultState}`, debugColor);
  }
  // TODO: handle events which do not require data without requiring `undefined` to be passed as as parameter, while
  // also still requiring data to be passed to those events which do require it.
  transition(event, data) {
    const shouldTransitionSelf = this.transitionChild(event, data);
    if (!shouldTransitionSelf || this.state === _StateMachine.child || this.state === _StateMachine.parent) {
      return;
    }
    const currentState = this.state;
    const currentStateConfig = this.states[this.state];
    let destination = currentStateConfig[event];
    const debugPrefix = `%c${this.constructor.name} | ${this.state} -> ${event} ->`;
    if (Array.isArray(destination)) {
      destination = destination.find((transition) => {
        if (!transition.guard)
          return true;
        const valid = transition.guard(data);
        if (!valid) {
          this.debug(`${debugPrefix} (guarded)`, transition.target, debugQuietColor);
        }
        return valid;
      });
    } else if (typeof destination === "object" && !(destination instanceof _StateMachine) && destination.guard && !destination.guard(data)) {
      this.debug(`${debugPrefix} (guarded)`, destination.target, debugQuietColor);
      return;
    }
    if (!destination) {
      this.debug(`${debugPrefix} ${this.state}`, debugQuietColor);
      return;
    }
    const destinationState = this.getDestinationState(destination);
    const exitFn = destinationState === this.state ? void 0 : currentStateConfig.onExit;
    this.debug(`${debugPrefix} ${destinationState}`, debugColor);
    this.state = destinationState;
    if (typeof destination === "function") {
      destination(data);
    } else if (typeof destination === "object" && !(destination instanceof _StateMachine)) {
      destination.action?.(data);
    }
    exitFn?.();
    this.enterEach?.(currentState, destinationState);
    if (destinationState !== currentState && destinationState !== _StateMachine.child && destinationState !== _StateMachine.parent) {
      this.states[destinationState].onEnter?.(currentState, data);
    }
  }
  transitionAsync(event, data) {
    setTimeout(() => {
      this.transition(event, data);
    }, 0);
  }
  is(value) {
    if (this.state === _StateMachine.child && this.childState) {
      return this.childState.is(value);
    }
    return this.state === value;
  }
  resetHierarchy() {
    this.debug(
      `%c${this.constructor.name} | ${this.state} -> [resetHierarchy] -> ${this.defaultState}`,
      "color: green"
    );
    this.state = this.defaultState;
  }
  transitionChild(event, data) {
    if (this.state !== _StateMachine.child || !this.childState)
      return true;
    applyProperties(this, this.childState);
    this.childState.transition(event, data);
    if (!this.childState.is(_StateMachine.parent))
      return true;
    this.debug(`%c${this.constructor.name} | ${this.state} -> ${event} -> ${this.defaultState}`, debugColor);
    this.state = this.defaultState;
    this.states[this.state].onEnter?.();
    this.childState.resetHierarchy();
    return false;
  }
  getDestinationState(destination) {
    let state = this.state;
    if (typeof destination === "string") {
      state = destination;
    } else if (destination instanceof _StateMachine) {
      this.childState = destination;
      this.childState.parent = this;
      state = _StateMachine.child;
    } else if (typeof destination === "object") {
      if (destination.target instanceof _StateMachine) {
        this.childState = destination.target;
        this.childState.parent = this;
        state = _StateMachine.child;
      } else if (destination.target != null) {
        state = destination.target;
      }
    }
    return state;
  }
};
_StateMachine.child = "__child";
_StateMachine.parent = "__parent";
var StateMachine = _StateMachine;
var ParallelStateMachine = class extends AbstractStateMachine {
  constructor(...stateMachines) {
    super();
    this.stateMachines = stateMachines;
    for (const stateMachine of stateMachines) {
      stateMachine.parent = this;
    }
  }
  transition(event, data) {
    for (const stateMachine of this.stateMachines) {
      applyProperties(this, stateMachine);
      stateMachine.transition(event, data);
    }
  }
  transitionAsync(event, data) {
    for (const stateMachine of this.stateMachines) {
      applyProperties(this, stateMachine);
      stateMachine.transitionAsync(event, data);
    }
  }
};

// packages/ag-charts-core/src/rendering/textMeasurer.ts
var TextMeasurer = class {
  constructor(ctx, measureTextCached) {
    this.ctx = ctx;
    this.measureTextCached = measureTextCached;
    this.baselineMap = /* @__PURE__ */ new Map();
    this.charMap = /* @__PURE__ */ new Map();
    this.lineHeightCache = null;
  }
  baselineDistance(textBaseline) {
    if (textBaseline === "alphabetic")
      return 0;
    if (this.baselineMap.has(textBaseline)) {
      return this.baselineMap.get(textBaseline);
    }
    this.ctx.textBaseline = textBaseline;
    const { alphabeticBaseline } = this.ctx.measureText("");
    this.baselineMap.set(textBaseline, alphabeticBaseline);
    this.ctx.textBaseline = "alphabetic";
    return alphabeticBaseline;
  }
  lineHeight() {
    this.lineHeightCache ?? (this.lineHeightCache = this.measureText("").height);
    return this.lineHeightCache;
  }
  measureText(text2) {
    const m = this.measureTextCached?.(text2) ?? this.ctx.measureText(text2);
    const {
      width: width2,
      // Apply fallbacks for environments like `node-canvas` where some metrics may be missing.
      fontBoundingBoxAscent: ascent = m.emHeightAscent,
      fontBoundingBoxDescent: descent = m.emHeightDescent
    } = m;
    const height2 = ascent + descent;
    return { width: width2, height: height2, ascent, descent };
  }
  measureLines(text2) {
    const lines = typeof text2 === "string" ? text2.split(LineSplitter) : text2;
    let width2 = 0;
    let height2 = 0;
    const lineMetrics = lines.map((line) => {
      const b = this.measureText(line);
      if (width2 < b.width) {
        width2 = b.width;
      }
      height2 += b.height;
      return { text: line, ...b };
    });
    return { width: width2, height: height2, lineMetrics };
  }
  textWidth(text2, estimate) {
    if (estimate) {
      let estimatedWidth = 0;
      for (let i = 0; i < text2.length; i++) {
        estimatedWidth += this.textWidth(text2.charAt(i));
      }
      return estimatedWidth;
    }
    if (text2.length > 1) {
      return this.ctx.measureText(text2).width;
    }
    return this.charMap.get(text2) ?? this.charWidth(text2);
  }
  charWidth(char) {
    const { width: width2 } = this.ctx.measureText(char);
    this.charMap.set(char, width2);
    return width2;
  }
};
var instanceMap = new LRUCache(50);
function cachedTextMeasurer(font3) {
  if (typeof font3 === "object") {
    font3 = toFontString(font3);
  }
  let cachedMeasurer = instanceMap.get(font3);
  if (cachedMeasurer)
    return cachedMeasurer;
  const cachedTextMetrics = new LRUCache(1e4);
  const ctx = createCanvasContext();
  ctx.font = font3;
  cachedMeasurer = new TextMeasurer(ctx, (text2) => {
    let textMetrics = cachedTextMetrics.get(text2);
    if (textMetrics)
      return textMetrics;
    textMetrics = ctx.measureText(text2);
    cachedTextMetrics.set(text2, textMetrics);
    return textMetrics;
  });
  instanceMap.set(font3, cachedMeasurer);
  return cachedMeasurer;
}
cachedTextMeasurer.clear = () => instanceMap.clear();
function measureTextSegments(textSegments, defaultFont) {
  let currentLine = { segments: [], width: 0, height: 0, ascent: 0, descent: 0 };
  const lineMetrics = [currentLine];
  for (const segment of textSegments) {
    const {
      text: text2,
      fontSize = defaultFont.fontSize,
      fontStyle = defaultFont.fontStyle,
      fontWeight: fontWeight2 = defaultFont.fontWeight,
      fontFamily = defaultFont.fontFamily,
      ...rest
    } = segment;
    const font3 = { fontSize, fontStyle, fontWeight: fontWeight2, fontFamily };
    const measurer3 = cachedTextMeasurer(font3);
    const textLines = toTextString(text2).split(LineSplitter);
    for (let i = 0; i < textLines.length; i++) {
      const textLine = textLines[i];
      const textMetrics = measurer3.measureText(textLine);
      if (i > 0) {
        currentLine = { segments: [], width: 0, height: 0, ascent: 0, descent: 0 };
        lineMetrics.push(currentLine);
      }
      if (textLine) {
        currentLine.width += textMetrics.width;
        currentLine.ascent = Math.max(currentLine.ascent, textMetrics.ascent);
        currentLine.descent = Math.max(currentLine.descent, textMetrics.descent);
        currentLine.height = Math.max(currentLine.height, currentLine.ascent + currentLine.descent);
        currentLine.segments.push({ ...font3, ...rest, text: textLine, textMetrics });
      }
    }
  }
  let maxWidth = 0;
  let totalHeight = 0;
  for (const line of lineMetrics) {
    maxWidth = Math.max(maxWidth, line.width);
    totalHeight += line.height;
  }
  return { width: maxWidth, height: totalHeight, lineMetrics };
}

// packages/ag-charts-core/src/utils/dom/domElements.ts
function createElement(tagName, className, style2) {
  const element2 = getDocument().createElement(tagName);
  if (typeof className === "object") {
    style2 = className;
    className = void 0;
  }
  if (className) {
    for (const name of className.split(" ")) {
      element2.classList.add(name);
    }
  }
  if (style2) {
    Object.assign(element2.style, style2);
  }
  return element2;
}
function createSvgElement(elementName) {
  return getDocument().createElementNS("http://www.w3.org/2000/svg", elementName);
}

// packages/ag-charts-core/src/utils/dom/domDownload.ts
function downloadUrl(dataUrl, fileName) {
  const body = getDocument("body");
  const element2 = createElement("a", { display: "none" });
  element2.href = dataUrl;
  element2.download = fileName;
  body.appendChild(element2);
  element2.click();
  setTimeout(() => element2.remove());
}

// packages/ag-charts-core/src/utils/text/textWrapper.ts
function shouldHideOverflow(clippedResult, options) {
  return options.overflow === "hide" && clippedResult.some(isTextTruncated);
}
function wrapTextOrSegments(input, options) {
  return isArray(input) ? wrapTextSegments(input, options) : wrapLines(toTextString(input), options).join("\n");
}
function wrapText(text2, options) {
  return wrapLines(text2, options).join("\n");
}
function wrapLines(text2, options) {
  return textWrap(text2, options);
}
function truncateLine(text2, measurer3, maxWidth, ellipsisForce) {
  const ellipsisWidth = measurer3.textWidth(EllipsisChar);
  let estimatedWidth = 0;
  let i = 0;
  for (; i < text2.length; i++) {
    const charWidth = measurer3.textWidth(text2.charAt(i));
    if (estimatedWidth + charWidth > maxWidth)
      break;
    estimatedWidth += charWidth;
  }
  if (text2.length === i && (!ellipsisForce || estimatedWidth + ellipsisWidth <= maxWidth)) {
    return ellipsisForce ? appendEllipsis(text2) : text2;
  }
  text2 = text2.slice(0, i).trimEnd();
  while (text2.length && measurer3.textWidth(text2) + ellipsisWidth > maxWidth) {
    text2 = text2.slice(0, -1).trimEnd();
  }
  return appendEllipsis(text2);
}
function textWrap(text2, options, widthOffset = 0) {
  const lines = text2.split(LineSplitter);
  const measurer3 = cachedTextMeasurer(options.font);
  const result = [];
  if (options.textWrap === "never") {
    for (const line of lines) {
      const truncatedLine = truncateLine(line.trimEnd(), measurer3, Math.max(0, options.maxWidth - widthOffset));
      if (!truncatedLine)
        break;
      result.push(truncatedLine);
      widthOffset = 0;
    }
    return shouldHideOverflow(result, options) ? [] : result;
  }
  const wrapHyphenate = options.textWrap === "hyphenate";
  const wrapOnSpace = options.textWrap == null || options.textWrap === "on-space";
  for (const untrimmedLine of lines) {
    let line = untrimmedLine.trimEnd();
    if (line === "") {
      result.push(line);
      continue;
    }
    let i = 0;
    let estimatedWidth = 0;
    let lastSpaceIndex = 0;
    if (!result.length) {
      estimatedWidth = widthOffset;
    }
    while (i < line.length) {
      const char = line.charAt(i);
      if (char === " ") {
        lastSpaceIndex = i;
      }
      estimatedWidth += measurer3.textWidth(char);
      if (estimatedWidth > options.maxWidth) {
        if (i === 0) {
          line = "";
          break;
        }
        let actualWidth = measurer3.textWidth(line.slice(0, i + 1));
        if (!result.length) {
          actualWidth += widthOffset;
        }
        if (actualWidth <= options.maxWidth) {
          estimatedWidth = actualWidth;
          i++;
          continue;
        }
        if (lastSpaceIndex) {
          const nextWord = getWordAt(line, lastSpaceIndex + 1);
          const textWidth = measurer3.textWidth(nextWord);
          if (textWidth <= options.maxWidth) {
            result.push(line.slice(0, lastSpaceIndex).trimEnd());
            line = line.slice(lastSpaceIndex).trimStart();
            i = 0;
            estimatedWidth = 0;
            lastSpaceIndex = 0;
            continue;
          } else if (wrapOnSpace && textWidth > options.maxWidth) {
            result.push(
              line.slice(0, lastSpaceIndex).trimEnd(),
              truncateLine(line.slice(lastSpaceIndex).trimStart(), measurer3, options.maxWidth, true)
            );
          }
        } else if (wrapOnSpace) {
          const newLine2 = truncateLine(line, measurer3, options.maxWidth, true);
          if (newLine2) {
            result.push(newLine2);
          }
        }
        if (wrapOnSpace) {
          line = "";
          break;
        }
        const postfix = wrapHyphenate ? "-" : "";
        let newLine = line.slice(0, i).trim();
        while (newLine.length && measurer3.textWidth(newLine + postfix) > options.maxWidth) {
          newLine = newLine.slice(0, -1).trimEnd();
        }
        if (newLine && newLine !== TrimEdgeGuard) {
          result.push(newLine + postfix);
        } else {
          line = "";
          break;
        }
        line = line.slice(newLine.length).trimStart();
        i = -1;
        estimatedWidth = 0;
        lastSpaceIndex = 0;
      }
      i++;
    }
    if (line) {
      result.push(line);
    }
  }
  avoidOrphans(result, measurer3, options);
  const clippedResult = clipLines(result, measurer3, options);
  return shouldHideOverflow(clippedResult, options) ? [] : clippedResult;
}
function getWordAt(text2, position) {
  const nextSpaceIndex = text2.indexOf(" ", position);
  return nextSpaceIndex === -1 ? text2.slice(position) : text2.slice(position, nextSpaceIndex);
}
function clipLines(lines, measurer3, options) {
  if (!isFiniteNumber(options.maxHeight)) {
    return lines;
  }
  const { height: height2, lineMetrics } = measurer3.measureLines(lines);
  if (height2 <= options.maxHeight) {
    return lines;
  }
  for (let i = 0, cumulativeHeight = 0; i < lineMetrics.length; i++) {
    cumulativeHeight += lineMetrics[i].height;
    if (cumulativeHeight > options.maxHeight) {
      if (options.overflow === "hide" || i === 0)
        return [];
      const clippedResults = lines.slice(0, i);
      const lastLine = clippedResults.pop();
      return clippedResults.concat(
        isTextTruncated(lastLine) ? lastLine : truncateLine(lastLine, measurer3, options.maxWidth, true)
      );
    }
  }
  return lines;
}
function avoidOrphans(lines, measurer3, options) {
  if (options.avoidOrphans === false || lines.length < 2)
    return;
  const { length: length2 } = lines;
  const lastLine = lines[length2 - 1];
  const beforeLast = lines[length2 - 2];
  if (beforeLast.length < lastLine.length)
    return;
  const lastSpaceIndex = beforeLast.lastIndexOf(" ");
  if (lastSpaceIndex === -1 || lastSpaceIndex === beforeLast.indexOf(" ") || lastLine.includes(" "))
    return;
  const lastWord = beforeLast.slice(lastSpaceIndex + 1);
  if (measurer3.textWidth(lastLine + lastWord) <= options.maxWidth) {
    lines[length2 - 2] = beforeLast.slice(0, lastSpaceIndex);
    lines[length2 - 1] = lastWord + " " + lastLine;
  }
}
function wrapTextSegments(textSegments, options) {
  const { maxHeight = Infinity } = options;
  const result = [];
  let lineWidth = 0;
  let totalHeight = 0;
  function truncateLastSegment() {
    const lastSegment = result.pop();
    if (!lastSegment)
      return;
    const measurer3 = cachedTextMeasurer(lastSegment);
    const truncatedText = truncateLine(lastSegment.text, measurer3, options.maxWidth, true);
    const textMetrics = measurer3.measureText(truncatedText);
    result.push({ ...lastSegment, text: truncatedText, textMetrics });
  }
  for (const { width: width2, height: height2, segments } of measureTextSegments(textSegments, options.font).lineMetrics) {
    if (totalHeight + height2 > maxHeight) {
      if (result.length) {
        truncateLastSegment();
      }
      break;
    }
    if (lineWidth + width2 <= options.maxWidth) {
      lineWidth += width2;
      totalHeight += height2;
      result.push(...segments);
      continue;
    }
    for (const segment of segments) {
      if (lineWidth + segment.textMetrics.width <= options.maxWidth) {
        lineWidth += segment.textMetrics.width;
        result.push(segment);
        continue;
      }
      const measurer3 = cachedTextMeasurer(segment);
      const guardedText = guardTextEdges(segment.text);
      const wrapOptions = { ...options, font: segment, maxHeight: maxHeight - totalHeight };
      let wrappedLines = textWrap(guardedText, { ...wrapOptions, overflow: "hide" }, lineWidth);
      if (wrappedLines.length === 0) {
        if (options.textWrap === "never") {
          wrappedLines = textWrap(guardedText, wrapOptions, lineWidth);
        } else {
          wrappedLines = textWrap(guardedText, wrapOptions);
          const lastSegment = result.at(-1);
          if (lastSegment) {
            lastSegment.text += "\n";
            lineWidth = 0;
          }
        }
      }
      if (wrappedLines.length === 0) {
        truncateLastSegment();
        break;
      }
      const truncationIndex = wrappedLines.findIndex(isTextTruncated);
      if (truncationIndex !== -1) {
        wrappedLines = wrappedLines.slice(0, truncationIndex + 1);
      }
      const lastLine = wrappedLines.at(-1);
      for (const wrappedLine of wrappedLines) {
        const cleanLine = unguardTextEdges(wrappedLine);
        const textMetrics = measurer3.measureText(cleanLine);
        const subSegment = { ...segment, text: cleanLine, textMetrics };
        if (wrappedLine === lastLine) {
          lineWidth += textMetrics.width;
        } else {
          subSegment.text += "\n";
          lineWidth = 0;
        }
        totalHeight += textMetrics.height;
        result.push(subSegment);
      }
      if (truncationIndex !== -1)
        break;
    }
  }
  return result;
}

// packages/ag-charts-core/src/utils/data/visibleRange.ts
function rescaleVisibleRange(visibleRange, [s0, s1], [d0, d1]) {
  const dr = d1 - d0;
  const vr = s1 - s0;
  const vd0 = s0 + vr * visibleRange[0];
  const vd1 = s0 + vr * visibleRange[1];
  return [(vd0 - d0) / dr, (vd1 - d0) / dr];
}

// packages/ag-charts-core/src/utils/time/time/duration.ts
var durationSecond = 1e3;
var durationMinute = durationSecond * 60;
var durationHour = durationMinute * 60;
var durationDay = durationHour * 24;
var durationWeek = durationDay * 7;
var durationMonth = durationDay * 30;
var durationYear = durationDay * 365;

// packages/ag-charts-core/src/utils/time/time/encoding.ts
var tzOffset = (/* @__PURE__ */ new Date()).getTimezoneOffset() * durationMinute;
var unitEncoding = {
  millisecond: {
    milliseconds: 1,
    hierarchy: "day",
    encode(date2) {
      return date2.getTime();
    },
    decode(encoded) {
      return new Date(encoded);
    }
  },
  second: {
    milliseconds: durationSecond,
    hierarchy: "day",
    encode(date2, utc) {
      const offset = utc ? 0 : tzOffset;
      return Math.floor((date2.getTime() - offset) / durationSecond);
    },
    decode(encoded, utc) {
      const offset = utc ? 0 : tzOffset;
      return new Date(offset + encoded * durationSecond);
    }
  },
  minute: {
    milliseconds: durationMinute,
    hierarchy: "day",
    encode(date2, utc) {
      const offset = utc ? 0 : tzOffset;
      return Math.floor((date2.getTime() - offset) / durationMinute);
    },
    decode(encoded, utc) {
      const offset = utc ? 0 : tzOffset;
      return new Date(offset + encoded * durationMinute);
    }
  },
  hour: {
    milliseconds: durationHour,
    hierarchy: "day",
    encode(date2, utc) {
      const offset = utc ? 0 : tzOffset;
      return Math.floor((date2.getTime() - offset) / durationHour);
    },
    decode(encoded, utc) {
      const offset = utc ? 0 : tzOffset;
      return new Date(offset + encoded * durationHour);
    }
  },
  day: {
    milliseconds: durationDay,
    hierarchy: "month",
    encode(date2, utc) {
      const tzOffsetMs2 = utc ? 0 : date2.getTimezoneOffset() * durationMinute;
      return Math.floor((date2.getTime() - tzOffsetMs2) / durationDay);
    },
    decode(encoded, utc) {
      let d;
      if (utc) {
        d = /* @__PURE__ */ new Date(0);
        d.setUTCDate(d.getUTCDate() + encoded);
        d.setUTCHours(0, 0, 0, 0);
      } else {
        d = new Date(1970, 0, 1);
        d.setDate(d.getDate() + encoded);
      }
      return d;
    }
  },
  month: {
    milliseconds: durationMonth,
    hierarchy: "year",
    encode(date2, utc) {
      if (utc) {
        return date2.getUTCFullYear() * 12 + date2.getUTCMonth();
      } else {
        return date2.getFullYear() * 12 + date2.getMonth();
      }
    },
    decode(encoded, utc) {
      if (utc) {
        const year = Math.floor(encoded / 12);
        const m = encoded - year * 12;
        return new Date(Date.UTC(year, m, 1));
      } else {
        const y = Math.floor(encoded / 12);
        const month = encoded - y * 12;
        return new Date(y, month, 1);
      }
    }
  },
  year: {
    milliseconds: durationYear,
    hierarchy: void 0,
    encode(date2, utc) {
      if (utc) {
        return date2.getUTCFullYear();
      } else {
        return date2.getFullYear();
      }
    },
    decode(encoded, utc) {
      let d;
      if (utc) {
        d = /* @__PURE__ */ new Date();
        d.setUTCFullYear(encoded);
        d.setUTCMonth(0, 1);
        d.setUTCHours(0, 0, 0, 0);
      } else {
        d = new Date(encoded, 0, 1, 0, 0, 0, 0);
      }
      return d;
    }
  }
};

// packages/ag-charts-core/src/utils/time/time/range.ts
function timeInterval(interval) {
  return typeof interval === "string" ? { unit: interval, step: 1, epoch: void 0, utc: false } : {
    unit: interval.unit,
    step: interval.step ?? 1,
    epoch: interval.epoch,
    utc: interval.utc ?? false
  };
}
function getOffset(unit, step, epoch, utc) {
  if (epoch == null)
    return 0;
  const encoding = unitEncoding[unit];
  return Math.floor(encoding.encode(new Date(epoch), utc)) % step;
}
function encode(d, unit, step, utc, offset) {
  const encoding = unitEncoding[unit];
  return Math.floor((encoding.encode(new Date(d), utc) - offset) / step);
}
function decode(encoded, unit, step, utc, offset) {
  const encoding = unitEncoding[unit];
  return encoding.decode(encoded * step + offset, utc);
}
function encodingFloor(date2, unit, step, utc, offset) {
  const d = new Date(date2);
  const e = encode(d, unit, step, utc, offset);
  return decode(e, unit, step, utc, offset);
}
function encodingCeil(date2, unit, step, utc, offset) {
  const d = new Date(Number(date2) - 1);
  const e = encode(d, unit, step, utc, offset);
  return decode(e + 1, unit, step, utc, offset);
}
function intervalFloor(interval, date2) {
  const { unit, step, epoch, utc } = timeInterval(interval);
  const offset = getOffset(unit, step, epoch, utc);
  return encodingFloor(date2, unit, step, utc, offset);
}
function intervalCeil(interval, date2) {
  const { unit, step, epoch, utc } = timeInterval(interval);
  const offset = getOffset(unit, step, epoch, utc);
  return encodingCeil(date2, unit, step, utc, offset);
}
function intervalPrevious(interval, date2) {
  const { unit, step, epoch, utc } = timeInterval(interval);
  const offset = getOffset(unit, step, epoch, utc);
  return decode(
    encode(encodingCeil(date2, unit, step, utc, offset), unit, step, utc, offset) - 1,
    unit,
    step,
    utc,
    offset
  );
}
function intervalNext(interval, date2) {
  const { unit, step, epoch, utc } = timeInterval(interval);
  const offset = getOffset(unit, step, epoch, utc);
  return decode(
    encode(encodingFloor(date2, unit, step, utc, offset), unit, step, utc, offset) + 1,
    unit,
    step,
    utc,
    offset
  );
}
function intervalExtent(start2, stop, visibleRange) {
  if (start2.valueOf() > stop.valueOf()) {
    [start2, stop] = [stop, start2];
    if (visibleRange != null) {
      visibleRange = [1 - visibleRange[1], 1 - visibleRange[0]];
    }
  }
  if (visibleRange != null) {
    const delta5 = stop.valueOf() - start2.valueOf();
    const t0 = start2.valueOf();
    start2 = new Date(t0 + visibleRange[0] * delta5);
    stop = new Date(t0 + visibleRange[1] * delta5);
  }
  return [new Date(start2), new Date(stop)];
}
function rangeData(interval, start2, stop, { extend = false, visibleRange = [0, 1], limit, defaultAlignment = "start" } = {}) {
  const params = timeInterval(interval);
  const { unit, step, utc } = params;
  let epoch;
  if (params.epoch != null) {
    epoch = params.epoch;
  } else if (defaultAlignment === "interval") {
    epoch = void 0;
  } else if (start2.valueOf() > stop.valueOf()) {
    epoch = stop;
  } else {
    epoch = start2;
  }
  const offset = getOffset(params.unit, params.step, epoch, params.utc);
  let [d0, d1] = intervalExtent(start2, stop, visibleRange);
  d0 = extend ? encodingFloor(d0, unit, step, utc, offset) : encodingCeil(d0, unit, step, utc, offset);
  d1 = extend ? encodingCeil(d1, unit, step, utc, offset) : encodingFloor(d1, unit, step, utc, offset);
  const e0 = encode(d0, unit, step, utc, offset);
  let e1 = encode(d1, unit, step, utc, offset);
  if (limit != null && e1 - e0 > limit) {
    e1 = e0 + limit;
  }
  return {
    range: [e0, e1],
    unit,
    step,
    utc,
    offset
  };
}
function intervalRangeCount(interval, start2, stop, params) {
  const {
    range: [e0, e1]
  } = rangeData(interval, start2, stop, params);
  return Math.abs(e1 - e0);
}
function intervalRange(interval, start2, stop, params) {
  const {
    range: [e0, e1],
    unit,
    step,
    utc,
    offset
  } = rangeData(interval, start2, stop, params);
  const values = [];
  for (let e = e0; e <= e1; e += 1) {
    const d = decode(e, unit, step, utc, offset);
    values.push(d);
  }
  return values;
}
function intervalRangeNumeric(interval, start2, stop, params) {
  const {
    range: [e0, e1],
    unit,
    step,
    utc,
    offset
  } = rangeData(interval, start2, stop, params);
  const count = Math.max(0, e1 - e0 + 1);
  const encodedValues = new Array(count);
  for (let i = 0; i < count; i++) {
    encodedValues[i] = e0 + i;
  }
  return {
    encodedValues,
    encodingParams: { unit, step, utc, offset }
  };
}
function decodeIntervalValue(encoded, encodingParams) {
  return decode(encoded, encodingParams.unit, encodingParams.step, encodingParams.utc, encodingParams.offset);
}
var tzOffsetMs = (/* @__PURE__ */ new Date()).getTimezoneOffset() * 6e4;
var DURATION_SECOND = 1e3;
var DURATION_MINUTE = 6e4;
var DURATION_HOUR = 36e5;
function encodedToTimestamp(encoded, encodingParams) {
  const { unit, step, utc, offset } = encodingParams;
  const rawEncoded = encoded * step + offset;
  switch (unit) {
    case "millisecond":
      return rawEncoded;
    case "second": {
      const tzOffset2 = utc ? 0 : tzOffsetMs;
      return tzOffset2 + rawEncoded * DURATION_SECOND;
    }
    case "minute": {
      const tzOffset2 = utc ? 0 : tzOffsetMs;
      return tzOffset2 + rawEncoded * DURATION_MINUTE;
    }
    case "hour": {
      const tzOffset2 = utc ? 0 : tzOffsetMs;
      return tzOffset2 + rawEncoded * DURATION_HOUR;
    }
    default: {
      const encoding = unitEncoding[unit];
      return encoding.decode(rawEncoded, utc).valueOf();
    }
  }
}
function intervalRangeStartIndex(interval, start2, stop, { extend, visibleRange, limit, defaultAlignment } = {}) {
  const {
    range: [s]
  } = rangeData(interval, start2, stop, { extend, visibleRange, limit, defaultAlignment });
  const {
    range: [s0]
  } = rangeData(interval, start2, stop, { extend, limit, defaultAlignment });
  return s - s0;
}

// packages/ag-charts-core/src/utils/time/time/index.ts
function intervalUnit(interval) {
  return typeof interval === "string" ? interval : interval.unit;
}
function intervalStep(interval) {
  return typeof interval === "string" ? 1 : interval.step ?? 1;
}
function intervalEpoch(interval) {
  return typeof interval === "string" ? void 0 : interval.epoch;
}
function intervalHierarchy(interval) {
  return unitEncoding[intervalUnit(interval)].hierarchy;
}
function intervalMilliseconds(interval) {
  const step = intervalStep(interval);
  return step * unitEncoding[intervalUnit(interval)].milliseconds;
}

// packages/ag-charts-core/src/utils/time/ticks.ts
var tInterval = (timeInterval3, step) => ({
  duration: intervalMilliseconds(timeInterval3) * step,
  timeInterval: timeInterval3,
  step
});
var TickIntervals = [
  tInterval({ unit: "second" }, 1),
  tInterval({ unit: "second" }, 5),
  tInterval({ unit: "second" }, 15),
  tInterval({ unit: "second" }, 30),
  tInterval({ unit: "minute" }, 1),
  tInterval({ unit: "minute" }, 5),
  tInterval({ unit: "minute" }, 15),
  tInterval({ unit: "minute" }, 30),
  tInterval({ unit: "hour" }, 1),
  tInterval({ unit: "hour" }, 3),
  tInterval({ unit: "hour" }, 6),
  tInterval({ unit: "hour" }, 12),
  tInterval({ unit: "day" }, 1),
  tInterval({ unit: "day" }, 2),
  tInterval({ unit: "day", step: 7 }, 1),
  tInterval({ unit: "day", step: 7 }, 2),
  tInterval({ unit: "day", step: 7 }, 3),
  tInterval({ unit: "month" }, 1),
  tInterval({ unit: "month" }, 2),
  tInterval({ unit: "month" }, 3),
  tInterval({ unit: "month" }, 4),
  tInterval({ unit: "month" }, 6),
  tInterval({ unit: "year" }, 1)
];
var TickMultipliers = [1, 2, 5, 10];
function isCloseToInteger(n, delta5) {
  return Math.abs(Math.round(n) - n) < delta5;
}
function countTicks(d0, d1, step) {
  const extent2 = Math.abs(d1 - d0);
  return extent2 >= step ? Math.abs(d1 - d0) / step + 1 : 1;
}
function createTicks(start2, stop, count, minCount, maxCount, visibleRange) {
  if (start2 === stop)
    return { ticks: [start2], count: 1, firstTickIndex: 0 };
  if (count < 2)
    return { ticks: [start2, stop], count: 2, firstTickIndex: 0 };
  const step = tickStep(start2, stop, count, minCount, maxCount);
  if (!Number.isFinite(step))
    return { ticks: [], count: 0, firstTickIndex: void 0 };
  let d0 = start2;
  let d1 = stop;
  if (!isCloseToInteger(d0 / step, 1e-12)) {
    d0 = Math.ceil(d0 / step) * step;
  }
  if (!isCloseToInteger(d1 / step, 1e-12)) {
    d1 = Math.floor(d1 / step) * step;
  }
  if (visibleRange != null) {
    visibleRange = rescaleVisibleRange(visibleRange, [start2, stop], [d0, d1]);
  }
  const { ticks } = range(d0, d1, step, visibleRange);
  const firstTick = ticks.at(0);
  return {
    ticks,
    count: countTicks(d0, d1, step),
    firstTickIndex: firstTick == null ? void 0 : Math.round((firstTick - d0) / step)
  };
}
var minPrimaryTickRatio = Math.floor(2 * durationWeek / durationMonth * 10) / 10;
function isPrimaryTickInterval({ timeInterval: timeInterval3, step }) {
  const milliseconds = intervalMilliseconds(timeInterval3) * step;
  const hierarchy = intervalHierarchy(timeInterval3);
  const hierarchyMilliseconds = hierarchy ? intervalMilliseconds(hierarchy) : void 0;
  return milliseconds <= (hierarchyMilliseconds ?? Infinity) * minPrimaryTickRatio;
}
function defaultEpoch(timeInterval3, { weekStart }) {
  if (timeInterval3.unit === "day" && timeInterval3.step === 7) {
    return weekStart;
  }
}
function getTickTimeInterval(start2, stop, count, minCount, maxCount, {
  weekStart,
  primaryOnly = false,
  targetInterval
}) {
  if (count <= 0)
    return;
  const target = targetInterval ?? Math.abs(stop - start2) / Math.max(count, 1);
  const i0 = TickIntervals.findLast((t) => (!primaryOnly || isPrimaryTickInterval(t)) && target > t.duration);
  const i1 = TickIntervals.find((t) => (!primaryOnly || isPrimaryTickInterval(t)) && target <= t.duration);
  if (i0 == null) {
    const step2 = Math.max(tickStep(start2, stop, count, minCount, maxCount), 1);
    return { unit: "millisecond", step: step2 };
  } else if (i1 == null) {
    const step2 = targetInterval == null ? tickStep(start2 / durationYear, stop / durationYear, count, minCount, maxCount) : 1;
    return { unit: "year", step: step2 };
  }
  const { timeInterval: timeInterval3, step } = target - i0.duration < i1.duration - target ? i0 : i1;
  return {
    unit: timeInterval3.unit,
    step: intervalStep(timeInterval3) * step,
    epoch: defaultEpoch(timeInterval3, { weekStart })
  };
}
function tickStep(start2, end3, count, minCount = 0, maxCount = Infinity) {
  if (start2 === end3) {
    return clamp(1, minCount, maxCount);
  } else if (count < 1) {
    return Number.NaN;
  }
  const extent2 = Math.abs(end3 - start2);
  const step = 10 ** Math.floor(Math.log10(extent2 / count));
  let m = Number.NaN, minDiff = Infinity, isInBounds = false;
  for (const multiplier of TickMultipliers) {
    const c = Math.ceil(extent2 / (multiplier * step));
    const validBounds = c >= minCount && c <= maxCount;
    if (isInBounds && !validBounds)
      continue;
    const diffCount = Math.abs(c - count);
    if (minDiff > diffCount || isInBounds !== validBounds) {
      isInBounds || (isInBounds = validBounds);
      minDiff = diffCount;
      m = multiplier;
    }
  }
  return m * step;
}
function decimalPlaces(decimal) {
  for (let i = decimal.length - 1; i >= 0; i -= 1) {
    if (decimal[i] !== "0") {
      return i + 1;
    }
  }
  return 0;
}
function tickFormat(ticks, format) {
  const options = parseNumberFormat(format ?? ",f");
  if (options == null)
    return;
  if (options.precision == null || Number.isNaN(options.precision)) {
    if (!options.type || "eEFgGnprs".includes(options.type)) {
      options.precision = Math.max(
        ...ticks.map((x) => {
          if (!Number.isFinite(x))
            return 0;
          const [integer, decimal] = x.toExponential((options.type ? 6 : 12) - 1).split(/[.e]/g);
          return (integer !== "1" && integer !== "-1" ? 1 : 0) + decimalPlaces(decimal) + 1;
        })
      );
    } else if ("f%".includes(options.type)) {
      options.precision = Math.max(
        ...ticks.map((x) => {
          if (!Number.isFinite(x) || x === 0)
            return 0;
          const l = Math.floor(Math.log10(Math.abs(x)));
          const digits = options.type ? 6 : 12;
          const decimal = x.toExponential(digits - 1).split(/[.e]/g)[1];
          const decimalLength = decimalPlaces(decimal);
          return Math.max(0, decimalLength - l);
        })
      );
    }
  }
  const formatter2 = createNumberFormatter(options);
  return (n) => formatter2(Number(n));
}
function range(start2, end3, step, visibleRange) {
  if (!Number.isFinite(step) || step <= 0) {
    return { ticks: [], count: 0, firstTickIndex: void 0 };
  } else if (start2 === end3) {
    return { ticks: [start2], count: 1, firstTickIndex: 0 };
  }
  const f = 10 ** countFractionDigits(step);
  const d0 = Math.min(start2, end3);
  const d1 = Math.max(start2, end3);
  let vd0;
  let vd1;
  if (visibleRange != null && (visibleRange[0] !== 0 || visibleRange[1] !== 1)) {
    const rangeExtent = end3 - start2;
    const adjustedStart = start2 + rangeExtent * visibleRange[0];
    const adjustedEnd = end3 - rangeExtent * (1 - visibleRange[1]);
    vd0 = Math.min(adjustedStart, adjustedEnd);
    vd1 = Math.max(adjustedStart, adjustedEnd);
  } else {
    vd0 = d0;
    vd1 = d1;
  }
  vd0 = Math.floor(vd0 * f) / f;
  vd1 = Math.ceil(vd1 * f) / f;
  const ticks = [];
  for (let i = 0; ; i += 1) {
    const p = Math.round((d0 + step * i) * f) / f;
    if (p > d1)
      break;
    if (p >= vd0 && p <= vd1) {
      ticks.push(p);
    }
  }
  const firstTick = ticks.at(0);
  return {
    ticks,
    count: countTicks(d0, d1, step),
    firstTickIndex: firstTick == null ? void 0 : Math.round((firstTick - d0) / step)
  };
}
function isDenseInterval(count, availableRange) {
  if (count >= availableRange) {
    warnOnce(
      `the configured interval results in more than 1 item per pixel, ignoring. Supply a larger interval or omit this configuration`
    );
    return true;
  }
  return false;
}
function niceTicksDomain(start2, end3) {
  const extent2 = Math.abs(end3 - start2);
  const step = 10 ** Math.floor(Math.log10(extent2));
  let minError = Infinity, ticks = [start2, end3];
  for (const multiplier of TickMultipliers) {
    const m = multiplier * step;
    const d0 = Math.floor(start2 / m) * m;
    const d1 = Math.ceil(end3 / m) * m;
    const error2 = 1 - extent2 / Math.abs(d1 - d0);
    if (minError > error2) {
      minError = error2;
      ticks = [d0, d1];
    }
  }
  return ticks;
}
function estimateTickCount(rangeExtent, zoomExtent, minSpacing, maxSpacing, defaultTickCount, defaultMinSpacing) {
  if (rangeExtent <= 0) {
    return { minTickCount: 0, maxTickCount: 0, tickCount: 0 };
  }
  defaultMinSpacing = Math.max(defaultMinSpacing, rangeExtent / (defaultTickCount + 1));
  minSpacing ?? (minSpacing = defaultMinSpacing);
  maxSpacing ?? (maxSpacing = rangeExtent);
  if (minSpacing > maxSpacing) {
    if (minSpacing === defaultMinSpacing) {
      minSpacing = maxSpacing;
    } else {
      maxSpacing = minSpacing;
    }
  }
  minSpacing = Math.max(minSpacing, 1);
  const maxTickCount = Math.max(1, Math.floor(rangeExtent / (zoomExtent * minSpacing)));
  const minTickCount = Math.min(maxTickCount, Math.ceil(rangeExtent / (zoomExtent * maxSpacing)));
  const tickCount = clamp(minTickCount, Math.floor(defaultTickCount / zoomExtent), maxTickCount);
  return { minTickCount, maxTickCount, tickCount };
}

// packages/ag-charts-core/src/utils/time/timeFormatDefaults.ts
function dateToNumber(value) {
  return value instanceof Date ? value.getTime() : value;
}
function lowestGranularityForInterval(interval) {
  if (interval < durationSecond) {
    return "millisecond";
  } else if (interval < durationMinute) {
    return "second";
  } else if (interval < durationHour) {
    return "minute";
  } else if (interval < durationHour * 23) {
    return "hour";
  } else if (interval < 28 * durationDay) {
    return "day";
  } else if (interval < durationYear) {
    return "month";
  } else {
    return "year";
  }
}
function lowestGranularityUnitForTicks(ticks) {
  if (ticks.length === 0) {
    return "millisecond";
  } else if (ticks.length === 1) {
    return lowestGranularityUnitForValue(ticks[0]);
  }
  let minInterval = Infinity;
  for (let i = 1; i < ticks.length; i++) {
    minInterval = Math.min(minInterval, Math.abs(ticks[i].valueOf() - ticks[i - 1].valueOf()));
  }
  return lowestGranularityForInterval(minInterval);
}
function lowestGranularityUnitForValue(value) {
  if (intervalFloor("second", value) < value) {
    return "millisecond";
  } else if (intervalFloor("minute", value) < value) {
    return "second";
  } else if (intervalFloor("hour", value) < value) {
    return "minute";
  } else if (intervalFloor("day", value) < value) {
    return "hour";
  } else if (intervalFloor("month", value) < value) {
    return "day";
  } else if (intervalFloor("year", value) < value) {
    return "month";
  }
  return "year";
}
function dateTruncationForDomain(domain) {
  const [d0, d1] = domain.length === 0 ? [0, 0] : findMinMax([domain[0].valueOf(), domain.at(-1).valueOf()]);
  const startYear = new Date(d0).getFullYear();
  const stopYear = new Date(d1).getFullYear();
  if (startYear !== stopYear)
    return;
  const startMonth = new Date(d0).getMonth();
  const stopMonth = new Date(d1).getMonth();
  if (startMonth !== stopMonth)
    return "year";
  const startDate = new Date(d0).getDate();
  const stopDate = new Date(d1).getDate();
  if (startDate !== stopDate)
    return "month";
  return "day";
}

// packages/ag-charts-core/src/identity/idGenerator.ts
function createIdsGenerator() {
  const idsCounter = /* @__PURE__ */ new Map();
  return (name) => {
    const counter = idsCounter.get(name);
    if (counter) {
      idsCounter.set(name, counter + 1);
      return `${name}_${counter}`;
    }
    idsCounter.set(name, 1);
    return name;
  };
}

// packages/ag-charts-core/src/utils/data/value.ts
function isStringObject(value) {
  return value != null && Object.hasOwn(value, "toString") && isString(value.toString());
}
function isNumberObject(value) {
  return value != null && Object.hasOwn(value, "valueOf") && isFiniteNumber(value.valueOf());
}
function isContinuous(value) {
  return isFiniteNumber(value) || isValidDate(value) || isNumberObject(value);
}
function checkDatum(value, isContinuousScale) {
  return value != null && (!isContinuousScale || isContinuous(value));
}
function transformIntegratedCategoryValue(value) {
  if (isStringObject(value) && Object.hasOwn(value, "id")) {
    return value.id;
  }
  return value;
}
function readIntegratedWrappedValue(value) {
  if (isStringObject(value) && Object.hasOwn(value, "value")) {
    return value.value;
  }
  return value;
}

// packages/ag-charts-core/src/utils/geometry/vector.ts
var vector_exports = {};
__export(vector_exports, {
  add: () => add,
  angle: () => angle,
  apply: () => apply,
  distance: () => distance,
  distanceSquared: () => distanceSquared,
  equal: () => equal,
  from: () => from,
  gradient: () => gradient,
  intercept: () => intercept,
  intersectAtX: () => intersectAtX,
  intersectAtY: () => intersectAtY,
  length: () => length,
  lengthSquared: () => lengthSquared,
  multiply: () => multiply,
  normalized: () => normalized,
  origin: () => origin,
  required: () => required2,
  rotate: () => rotate,
  round: () => round,
  sub: () => sub
});
function add(a, b) {
  if (typeof b === "number") {
    return { x: a.x + b, y: a.y + b };
  }
  return { x: a.x + b.x, y: a.y + b.y };
}
function sub(a, b) {
  if (typeof b === "number") {
    return { x: a.x - b, y: a.y - b };
  }
  return { x: a.x - b.x, y: a.y - b.y };
}
function multiply(a, b) {
  if (typeof b === "number") {
    return { x: a.x * b, y: a.y * b };
  }
  return { x: a.x * b.x, y: a.y * b.y };
}
function length(a) {
  return Math.hypot(a.x, a.y);
}
function lengthSquared(a) {
  return a.x * a.x + a.y * a.y;
}
function distance(a, b) {
  return length(sub(a, b));
}
function distanceSquared(a, b) {
  return lengthSquared(sub(a, b));
}
function normalized(a) {
  const l = length(a);
  return { x: a.x / l, y: a.y / l };
}
function angle(a, b) {
  if (b == null)
    return Math.atan2(a.y, a.x);
  return Math.atan2(a.y, a.x) - Math.atan2(b.y, b.x);
}
function rotate(a, theta, b = origin()) {
  const l = length(a);
  return { x: b.x + l * Math.cos(theta), y: b.y + l * Math.sin(theta) };
}
function gradient(a, b, reflection) {
  const dx2 = b.x - a.x;
  const dy2 = reflection == null ? b.y - a.y : reflection - b.y - (reflection - a.y);
  return dy2 / dx2;
}
function intercept(a, gradient2, reflection) {
  const y = reflection == null ? a.y : reflection - a.y;
  return y - gradient2 * a.x;
}
function intersectAtY(gradient2, coefficient, y = 0, reflection) {
  return {
    x: gradient2 === Infinity ? Infinity : (y - coefficient) / gradient2,
    y: reflection == null ? y : reflection - y
  };
}
function intersectAtX(gradient2, coefficient, x = 0, reflection) {
  const y = gradient2 === Infinity ? Infinity : gradient2 * x + coefficient;
  return { x, y: reflection == null ? y : reflection - y };
}
function round(a, decimals = 2) {
  return { x: roundTo(a.x, decimals), y: roundTo(a.y, decimals) };
}
function equal(a, b) {
  return a.x === b.x && a.y === b.y;
}
function from(a, b) {
  if (typeof a === "number") {
    return { x: a, y: b };
  }
  if ("currentX" in a) {
    return { x: a.currentX, y: a.currentY };
  }
  if ("offsetWidth" in a) {
    return { x: a.offsetWidth, y: a.offsetHeight };
  }
  if ("width" in a) {
    return [
      { x: a.x, y: a.y },
      { x: a.x + a.width, y: a.y + a.height }
    ];
  }
  if ("x1" in a) {
    return [
      { x: a.x1, y: a.y1 },
      { x: a.x2, y: a.y2 }
    ];
  }
  throw new Error(`Values can not be converted into a vector: [${JSON.stringify(a)}] [${b}]`);
}
function apply(a, b) {
  a.x = b.x;
  a.y = b.y;
  return a;
}
function required2(a) {
  return { x: a?.x ?? 0, y: a?.y ?? 0 };
}
function origin() {
  return { x: 0, y: 0 };
}

// packages/ag-charts-core/src/utils/geometry/vector4.ts
var vector4_exports = {};
__export(vector4_exports, {
  bottomCenter: () => bottomCenter,
  center: () => center,
  clone: () => clone,
  collides: () => collides,
  end: () => end,
  from: () => from2,
  height: () => height,
  normalise: () => normalise,
  origin: () => origin2,
  round: () => round2,
  start: () => start,
  topCenter: () => topCenter,
  width: () => width
});
function start(a) {
  return { x: a.x1, y: a.y1 };
}
function end(a) {
  return { x: a.x2, y: a.y2 };
}
function topCenter(a) {
  return { x: (a.x1 + a.x2) / 2, y: Math.min(a.y1, a.y2) };
}
function center(a) {
  return { x: (a.x1 + a.x2) / 2, y: (a.y1 + a.y2) / 2 };
}
function bottomCenter(a) {
  return { x: (a.x1 + a.x2) / 2, y: Math.max(a.y1, a.y2) };
}
function width(a) {
  return Math.abs(a.x2 - a.x1);
}
function height(a) {
  return Math.abs(a.y2 - a.y1);
}
function round2(a) {
  return { x1: Math.round(a.x1), y1: Math.round(a.y1), x2: Math.round(a.x2), y2: Math.round(a.y2) };
}
function clone(a) {
  return { x1: a.x1, y1: a.y1, x2: a.x2, y2: a.y2 };
}
function collides(a, b) {
  const an = normalise(a);
  const bn = normalise(b);
  return an.x1 <= bn.x2 && an.x2 >= bn.x1 && an.y1 <= bn.y2 && an.y2 >= bn.y1;
}
function normalise(a) {
  return {
    x1: Math.min(a.x1, a.x2),
    x2: Math.max(a.x1, a.x2),
    y1: Math.min(a.y1, a.y2),
    y2: Math.max(a.y1, a.y2)
  };
}
function from2(a, b, c, d) {
  if (typeof a === "number") {
    return { x1: a, y1: b, x2: c, y2: d };
  }
  if ("width" in a) {
    return normalise({
      x1: a.x,
      y1: a.y,
      x2: a.x + a.width,
      y2: a.y + a.height
    });
  }
  throw new Error(`Values can not be converted into a vector4: [${JSON.stringify(a)}] [${b}] [${c}] [${d}]`);
}
function origin2() {
  return { x1: 0, y1: 0, x2: 0, y2: 0 };
}

// packages/ag-charts-core/src/utils/geometry/fill.ts
function isGradientFill(fill) {
  return isObject(fill) && fill.type == "gradient";
}
function isGradientFillArray(fills) {
  return isArray(fills) && fills.every(isGradientFill);
}
function isStringFillArray(fills) {
  return isArray(fills) && fills.every((fill) => typeof fill === "string");
}
function isPatternFill(fill) {
  return fill !== null && isObject(fill) && fill.type == "pattern";
}
function isImageFill(fill) {
  return fill !== null && isObject(fill) && fill.type == "image";
}
function isGradientOrPatternFill(fill) {
  return isGradientFill(fill) || isPatternFill(fill);
}

// packages/ag-charts-core/src/utils/geometry/bezier.ts
function evaluateBezier(p0, p1, p2, p3, t) {
  return (1 - t) ** 3 * p0 + 3 * (1 - t) ** 2 * t * p1 + 3 * (1 - t) * t ** 2 * p2 + t ** 3 * p3;
}
function solveBezier(p0, p1, p2, p3, value) {
  if (value <= Math.min(p0, p3)) {
    return p0 < p3 ? 0 : 1;
  } else if (value >= Math.max(p0, p3)) {
    return p0 < p3 ? 1 : 0;
  }
  let t0 = 0;
  let t1 = 1;
  let t = Number.NaN;
  for (let i = 0; i < 12; i += 1) {
    t = (t0 + t1) / 2;
    const curveValue = evaluateBezier(p0, p1, p2, p3, t);
    if (curveValue < value) {
      t0 = t;
    } else {
      t1 = t;
    }
  }
  return t;
}
function splitBezier2D(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y, t) {
  const x01 = (1 - t) * p0x + t * p1x;
  const y01 = (1 - t) * p0y + t * p1y;
  const x12 = (1 - t) * p1x + t * p2x;
  const y12 = (1 - t) * p1y + t * p2y;
  const x23 = (1 - t) * p2x + t * p3x;
  const y23 = (1 - t) * p2y + t * p3y;
  const x012 = (1 - t) * x01 + t * x12;
  const y012 = (1 - t) * y01 + t * y12;
  const x123 = (1 - t) * x12 + t * x23;
  const y123 = (1 - t) * y12 + t * y23;
  const x0123 = (1 - t) * x012 + t * x123;
  const y0123 = (1 - t) * y012 + t * y123;
  return [
    [
      { x: p0x, y: p0y },
      { x: x01, y: y01 },
      { x: x012, y: y012 },
      { x: x0123, y: y0123 }
    ],
    [
      { x: x0123, y: y0123 },
      { x: x123, y: y123 },
      { x: x23, y: y23 },
      { x: p3x, y: p3y }
    ]
  ];
}
function calculateDerivativeExtrema(p0, p1, p2, p3) {
  const a = -p0 + 3 * p1 - 3 * p2 + p3;
  const b = 2 * (p0 - 2 * p1 + p2);
  const c = -p0 + p1;
  if (a === 0) {
    if (b !== 0) {
      const t = -c / b;
      if (t > 0 && t < 1) {
        return [t];
      }
    }
    return [];
  }
  const discriminant = b * b - 4 * a * c;
  if (discriminant >= 0) {
    const sqrtDiscriminant = Math.sqrt(discriminant);
    const t1 = (-b + sqrtDiscriminant) / (2 * a);
    const t2 = (-b - sqrtDiscriminant) / (2 * a);
    return [t1, t2].filter((t) => t > 0 && t < 1);
  }
  return [];
}
function bezier2DExtrema(cp0x, cp0y, cp1x, cp1y, cp2x, cp2y, cp3x, cp3y) {
  const tx = calculateDerivativeExtrema(cp0x, cp1x, cp2x, cp3x);
  const ty = calculateDerivativeExtrema(cp0y, cp1y, cp2y, cp3y);
  return [...tx, ...ty];
}
function bezierCandidate(points, x, y) {
  const midX = evaluateBezier(points[0].x, points[1].x, points[2].x, points[3].x, 0.5);
  const midY = evaluateBezier(points[0].y, points[1].y, points[2].y, points[3].y, 0.5);
  const distance2 = Math.hypot(midX - x, midY - y);
  const minDistance = Math.min(
    Math.hypot(points[0].x - x, points[0].y - y),
    Math.hypot(points[1].x - x, points[1].y - y),
    Math.hypot(points[2].x - x, points[2].y - y),
    Math.hypot(points[3].x - x, points[3].y - y)
  );
  return { points, distance: distance2, minDistance };
}
function bezier2DDistance(cp0x, cp0y, cp1x, cp1y, cp2x, cp2y, cp3x, cp3y, x, y, precision = 1) {
  const points0 = [
    { x: cp0x, y: cp0y },
    { x: cp1x, y: cp1y },
    { x: cp2x, y: cp2y },
    { x: cp3x, y: cp3y }
  ];
  let queue = {
    value: bezierCandidate(points0, x, y),
    next: null
  };
  let bestResult;
  while (queue != null) {
    const { points, distance: distance2, minDistance } = queue.value;
    queue = queue.next;
    if (bestResult == null || distance2 < bestResult.distance) {
      bestResult = { distance: distance2, minDistance };
    }
    if (bestResult != null && bestResult.distance - minDistance <= precision) {
      continue;
    }
    const [leftPoints, rightPoints] = splitBezier2D(
      points[0].x,
      points[0].y,
      points[1].x,
      points[1].y,
      points[2].x,
      points[2].y,
      points[3].x,
      points[3].y,
      0.5
    );
    const newCandidates = [bezierCandidate(leftPoints, x, y), bezierCandidate(rightPoints, x, y)].sort(
      bezierCandidateCmp
    );
    queue = insertListItemsSorted(queue, newCandidates, bezierCandidateCmp);
  }
  return bestResult?.distance ?? Infinity;
}
var bezierCandidateCmp = (a, b) => b.minDistance - a.minDistance;

// packages/ag-charts-core/src/utils/geometry/labelPlacement.ts
function circleRectOverlap({ point: c, anchor: unitCenter }, x, y, w, h) {
  if (c.size === 0) {
    return false;
  }
  let cx = c.x;
  let cy = c.y;
  if (unitCenter != null) {
    cx -= (unitCenter.x - 0.5) * c.size;
    cy -= (unitCenter.y - 0.5) * c.size;
  }
  let edgeX = cx;
  if (cx < x) {
    edgeX = x;
  } else if (cx > x + w) {
    edgeX = x + w;
  }
  let edgeY = cy;
  if (cy < y) {
    edgeY = y;
  } else if (cy > y + h) {
    edgeY = y + h;
  }
  const dx2 = cx - edgeX;
  const dy2 = cy - edgeY;
  const d = Math.hypot(dx2, dy2);
  return d <= c.size / 2;
}
function isPointLabelDatum(x) {
  return x != null && typeof x.point === "object" && typeof x.label === "object";
}
var labelPlacements = {
  top: { x: 0, y: -1 },
  bottom: { x: 0, y: 1 },
  left: { x: -1, y: 0 },
  right: { x: 1, y: 0 },
  "top-left": { x: -1, y: -1 },
  "top-right": { x: 1, y: -1 },
  "bottom-left": { x: -1, y: 1 },
  "bottom-right": { x: 1, y: 1 }
};
function placeLabels(data, bounds, padding2 = 5) {
  const result = /* @__PURE__ */ new Map();
  const previousResults = [];
  const sortedDataClone = new Map(
    Array.from(data.entries(), ([k, d]) => [k, d.toSorted((a, b) => b.point.size - a.point.size)])
  );
  const dataValues = [...sortedDataClone.values()].flat();
  for (const [seriesId, datums] of sortedDataClone.entries()) {
    const labels = [];
    if (!datums[0]?.label)
      continue;
    for (let index = 0, ln = datums.length; index < ln; index++) {
      const d = datums[index];
      const { point, label, anchor } = d;
      const { text: text2, width: width2, height: height2 } = label;
      const r = point.size / 2;
      let dx2 = 0;
      let dy2 = 0;
      if (r > 0 && d.placement != null) {
        const placement = labelPlacements[d.placement];
        dx2 = (width2 / 2 + r + padding2) * placement.x;
        dy2 = (height2 / 2 + r + padding2) * placement.y;
      }
      let x = point.x - width2 / 2 + dx2;
      let y = point.y - height2 / 2 + dy2;
      if (anchor) {
        x -= (anchor.x - 0.5) * point.size;
        y -= (anchor.y - 0.5) * point.size;
      }
      if (boxContains(bounds, x, y, width2, height2) && !dataValues.some((dataDatum) => circleRectOverlap(dataDatum, x, y, width2, height2)) && !previousResults.some((pr) => boxCollides(pr, x, y, width2, height2))) {
        const resultDatum = { index, text: text2, x, y, width: width2, height: height2, datum: d };
        labels.push(resultDatum);
        previousResults.push(resultDatum);
      }
    }
    result.set(seriesId, labels);
  }
  return result;
}

// packages/ag-charts-core/src/utils/geometry/scaling.ts
function isContinuousScaling(scaling) {
  return scaling.type === "continuous" || scaling.type === "log";
}
function isCategoryScaling(scaling) {
  return scaling.type === "category";
}
function isUnitTimeCategoryScaling(scaling) {
  return "variant" in scaling && scaling.variant === "unit-time";
}
function isStandardCategoryScaling(scaling) {
  return !("variant" in scaling);
}
function areScalingEqual(a, b) {
  if (a === void 0 || b === void 0) {
    return a !== void 0 || b !== void 0;
  }
  if (isContinuousScaling(a) && isContinuousScaling(b)) {
    return a.type === b.type && arraysEqual(a.domain, b.domain) && arraysEqual(a.range, b.range);
  }
  if (isCategoryScaling(a) && isCategoryScaling(b)) {
    if (isUnitTimeCategoryScaling(a) && isUnitTimeCategoryScaling(b)) {
      return a.firstBandTime === b.firstBandTime && a.lastBandTime === b.lastBandTime && a.bandCount === b.bandCount && a.intervalMs === b.intervalMs && a.inset === b.inset && a.step === b.step;
    }
    if (isStandardCategoryScaling(a) && isStandardCategoryScaling(b)) {
      return a.inset === b.inset && a.step === b.step && arraysEqual(a.domain, b.domain);
    }
    return false;
  }
  return false;
}
function isScaleValid(scale2) {
  if (scale2 == null)
    return false;
  if (scale2.type === "category") {
    if (isUnitTimeCategoryScaling(scale2)) {
      return Number.isFinite(scale2.firstBandTime) && Number.isFinite(scale2.lastBandTime) && Number.isFinite(scale2.bandCount) && scale2.bandCount > 0;
    }
    return scale2.domain.every((v) => v != null);
  }
  return scale2.domain.every((v) => Number.isFinite(v) || v instanceof Date) && scale2.range.every((v) => Number.isFinite(v));
}

// packages/ag-charts-core/src/utils/geometry/lineInterpolation.ts
function spanRange(span) {
  switch (span.type) {
    case "linear":
    case "step":
    case "multi-line":
      return [
        { x: span.x0, y: span.y0 },
        { x: span.x1, y: span.y1 }
      ];
    case "cubic":
      return [
        { x: span.cp0x, y: span.cp0y },
        { x: span.cp3x, y: span.cp3y }
      ];
  }
}
function spanRangeNormalized(span) {
  const range3 = spanRange(span);
  if (range3[0].x > range3[1].x) {
    range3.reverse();
  }
  return range3;
}
function collapseSpanToPoint(span, point) {
  const { x, y } = point;
  switch (span.type) {
    case "linear":
      return {
        type: "linear",
        moveTo: span.moveTo,
        x0: x,
        y0: y,
        x1: x,
        y1: y
      };
    case "step":
      return {
        type: "step",
        moveTo: span.moveTo,
        x0: x,
        y0: y,
        x1: x,
        y1: y,
        stepX: x
      };
    case "cubic":
      return {
        type: "cubic",
        moveTo: span.moveTo,
        cp0x: x,
        cp0y: y,
        cp1x: x,
        cp1y: y,
        cp2x: x,
        cp2y: y,
        cp3x: x,
        cp3y: y
      };
    case "multi-line":
      return {
        type: "multi-line",
        moveTo: span.moveTo,
        x0: x,
        y0: y,
        x1: x,
        y1: y,
        midPoints: span.midPoints.map(() => ({ x, y }))
      };
  }
}
function rescaleSpan(span, nextStart, nextEnd) {
  const [prevStart, prevEnd] = spanRange(span);
  const widthScale = prevEnd.x === prevStart.x ? 0 : (nextEnd.x - nextStart.x) / (prevEnd.x - prevStart.x);
  const heightScale = prevEnd.y === prevStart.y ? 0 : (nextEnd.y - nextStart.y) / (prevEnd.y - prevStart.y);
  switch (span.type) {
    case "linear":
      return {
        type: "linear",
        moveTo: span.moveTo,
        x0: nextStart.x,
        y0: nextStart.y,
        x1: nextEnd.x,
        y1: nextEnd.y
      };
    case "cubic":
      return {
        type: "cubic",
        moveTo: span.moveTo,
        cp0x: nextStart.x,
        cp0y: nextStart.y,
        cp1x: nextEnd.x - (span.cp2x - prevStart.x) * widthScale,
        cp1y: nextEnd.y - (span.cp2y - prevStart.y) * heightScale,
        cp2x: nextEnd.x - (span.cp1x - prevStart.x) * widthScale,
        cp2y: nextEnd.y - (span.cp1y - prevStart.y) * heightScale,
        cp3x: nextEnd.x,
        cp3y: nextEnd.y
      };
    case "step":
      return {
        type: "step",
        moveTo: span.moveTo,
        x0: nextStart.x,
        y0: nextStart.y,
        x1: nextEnd.x,
        y1: nextEnd.y,
        stepX: nextEnd.x - (span.stepX - prevStart.x) * widthScale
      };
    case "multi-line":
      return {
        type: "multi-line",
        moveTo: span.moveTo,
        x0: nextStart.x,
        y0: nextStart.y,
        x1: nextEnd.x,
        y1: nextEnd.y,
        midPoints: span.midPoints.map((midPoint) => ({
          x: nextStart.x + (midPoint.x - prevStart.x) * widthScale,
          y: nextStart.y + (midPoint.y - prevStart.y) * heightScale
        }))
      };
  }
}
function clipSpanX(span, x0, x1) {
  const { moveTo: moveTo2 } = span;
  const [start2, end3] = spanRangeNormalized(span);
  const { x: spanX0, y: spanY0 } = start2;
  const { x: spanX1, y: spanY1 } = end3;
  if (x1 < spanX0) {
    return rescaleSpan(span, start2, start2);
  } else if (x0 > spanX1) {
    return rescaleSpan(span, end3, end3);
  }
  switch (span.type) {
    case "linear": {
      const m = spanY0 === spanY1 ? void 0 : (spanY1 - spanY0) / (spanX1 - spanX0);
      const y0 = m == null ? spanY0 : m * (x0 - spanX0) + spanY0;
      const y1 = m == null ? spanY0 : m * (x1 - spanX0) + spanY0;
      return { type: "linear", moveTo: moveTo2, x0, y0, x1, y1 };
    }
    case "step":
      if (x1 <= span.stepX) {
        const y = span.y0;
        return { type: "step", moveTo: moveTo2, x0, y0: y, x1, y1: y, stepX: x1 };
      } else if (x0 >= span.stepX) {
        const y = span.y1;
        return { type: "step", moveTo: moveTo2, x0, y0: y, x1, y1: y, stepX: x0 };
      } else {
        const { y0, y1, stepX } = span;
        return { type: "step", moveTo: moveTo2, x0, y0, x1, y1, stepX };
      }
    case "cubic": {
      const t0 = solveBezier(span.cp0x, span.cp1x, span.cp2x, span.cp3x, x0);
      let [_unused, bezier] = splitBezier2D(
        span.cp0x,
        span.cp0y,
        span.cp1x,
        span.cp1y,
        span.cp2x,
        span.cp2y,
        span.cp3x,
        span.cp3y,
        t0
      );
      const t1 = solveBezier(bezier[0].x, bezier[1].x, bezier[2].x, bezier[3].x, x1);
      [bezier, _unused] = splitBezier2D(
        bezier[0].x,
        bezier[0].y,
        bezier[1].x,
        bezier[1].y,
        bezier[2].x,
        bezier[2].y,
        bezier[3].x,
        bezier[3].y,
        t1
      );
      return {
        type: "cubic",
        moveTo: moveTo2,
        cp0x: bezier[0].x,
        cp0y: bezier[0].y,
        cp1x: bezier[1].x,
        cp1y: bezier[1].y,
        cp2x: bezier[2].x,
        cp2y: bezier[2].y,
        cp3x: bezier[3].x,
        cp3y: bezier[3].y
      };
    }
    case "multi-line": {
      const { midPoints } = span;
      const midPointStartIndex = midPoints.findLastIndex((midPoint) => midPoint.x <= x0);
      let midPointEndIndex = midPoints.findIndex((midPoint) => midPoint.x >= x1);
      if (midPointEndIndex === -1)
        midPointEndIndex = midPoints.length;
      const startPoint = midPointStartIndex >= 0 ? midPoints[midPointStartIndex] : void 0;
      const startX = startPoint?.x ?? spanX0;
      const startY = startPoint?.y ?? spanY0;
      const endPoint = midPointEndIndex < midPoints.length ? midPoints[midPointEndIndex] : void 0;
      const endX = endPoint?.x ?? spanX1;
      const endY = endPoint?.y ?? spanY1;
      const m = startY === endY ? void 0 : (endY - startY) / (endX - startX);
      const y0 = m == null ? startY : m * (startX - spanX0) + startY;
      const y1 = m == null ? startY : m * (endX - spanX0) + startY;
      return {
        type: "multi-line",
        moveTo: moveTo2,
        x0,
        y0,
        x1,
        y1,
        midPoints: midPoints.slice(Math.max(midPointStartIndex, 0), midPointEndIndex)
      };
    }
  }
}
var SpanJoin = /* @__PURE__ */ ((SpanJoin2) => {
  SpanJoin2[SpanJoin2["MoveTo"] = 0] = "MoveTo";
  SpanJoin2[SpanJoin2["LineTo"] = 1] = "LineTo";
  SpanJoin2[SpanJoin2["Skip"] = 2] = "Skip";
  return SpanJoin2;
})(SpanJoin || {});
function linearPoints(points) {
  const spans = [];
  let i = 0;
  let x0 = Number.NaN;
  let y0 = Number.NaN;
  for (const { x: x1, y: y1 } of points) {
    if (i > 0) {
      const moveTo2 = i === 1;
      spans.push({ type: "linear", moveTo: moveTo2, x0, y0, x1, y1 });
    }
    i += 1;
    x0 = x1;
    y0 = y1;
  }
  return spans;
}
var lineSteps = {
  start: 0,
  middle: 0.5,
  end: 1
};
function stepPoints(points, position) {
  const spans = [];
  let i = 0;
  let x0 = Number.NaN;
  let y0 = Number.NaN;
  const p0 = typeof position === "number" ? position : lineSteps[position];
  for (const { x: x1, y: y1 } of points) {
    if (i > 0) {
      const moveTo2 = i === 1;
      const stepX = x0 + (x1 - x0) * p0;
      spans.push({ type: "step", moveTo: moveTo2, x0, y0, x1, y1, stepX });
    }
    i += 1;
    x0 = x1;
    y0 = y1;
  }
  return spans;
}
function smoothPoints(iPoints, tension) {
  const points = Array.isArray(iPoints) ? iPoints : Array.from(iPoints);
  if (points.length <= 1)
    return [];
  const flatnessRatio = 0.05;
  const gradients = points.map((c, i) => {
    const p = i === 0 ? c : points[i - 1];
    const n = i === points.length - 1 ? c : points[i + 1];
    const isTerminalPoint = i === 0 || i === points.length - 1;
    if (Math.sign(p.y - c.y) === Math.sign(n.y - c.y)) {
      return 0;
    }
    if (!isTerminalPoint) {
      const range3 = Math.abs(p.y - n.y);
      const prevRatio = Math.abs(c.y - p.y) / range3;
      const nextRatio = Math.abs(c.y - n.y) / range3;
      if (prevRatio <= flatnessRatio || 1 - prevRatio <= flatnessRatio || nextRatio <= flatnessRatio || 1 - nextRatio <= flatnessRatio) {
        return 0;
      }
    }
    return (n.y - p.y) / (n.x - p.x);
  });
  if (gradients[1] === 0) {
    gradients[0] *= 2;
  }
  if (gradients.at(-2) === 0) {
    gradients[gradients.length - 1] *= 2;
  }
  const spans = [];
  for (let i = 1; i < points.length; i += 1) {
    const prev = points[i - 1];
    const prevM = gradients[i - 1];
    const cur = points[i];
    const curM = gradients[i];
    const dx2 = cur.x - prev.x;
    const dy2 = cur.y - prev.y;
    let dcp1x = dx2 * tension / 3;
    let dcp1y = dx2 * prevM * tension / 3;
    let dcp2x = dx2 * tension / 3;
    let dcp2y = dx2 * curM * tension / 3;
    if (curM === 0 && Math.abs(dcp1y) > Math.abs(dy2)) {
      dcp1x *= Math.abs(dy2 / dcp1y);
      dcp1y = Math.sign(dcp1y) * Math.abs(dy2);
    }
    if (prevM === 0 && Math.abs(dcp2y) > Math.abs(dy2)) {
      dcp2x *= Math.abs(dy2 / dcp2y);
      dcp2y = Math.sign(dcp2y) * Math.abs(dy2);
    }
    spans.push({
      type: "cubic",
      moveTo: i === 1,
      cp0x: prev.x,
      cp0y: prev.y,
      cp1x: prev.x + dcp1x,
      cp1y: prev.y + dcp1y,
      cp2x: cur.x - dcp2x,
      cp2y: cur.y - dcp2y,
      cp3x: cur.x,
      cp3y: cur.y
    });
  }
  return spans;
}

// packages/ag-charts-core/src/utils/zoomUtils.ts
var UNIT_MIN = 0;
var UNIT_MAX = 1;
function definedZoomState(zoom) {
  return {
    x: { min: zoom?.x?.min ?? UNIT_MIN, max: zoom?.x?.max ?? UNIT_MAX },
    y: { min: zoom?.y?.min ?? UNIT_MIN, max: zoom?.y?.max ?? UNIT_MAX }
  };
}

// packages/ag-charts-core/src/rendering/changeDetectableProperties.ts
var ChangeDetectableProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this._dirty = true;
  }
  markDirty() {
    this._dirty = true;
  }
  markClean(_opts) {
    this._dirty = false;
  }
  isDirty() {
    return this._dirty;
  }
  onChangeDetection(_property) {
    this.markDirty();
  }
};

// packages/ag-charts-core/src/utils/format/timeFormat.ts
var CONSTANTS = {
  periods: ["AM", "PM"],
  days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
  shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
  months: [
    "January",
    "February",
    "March",
    "April",
    "May",
    "June",
    "July",
    "August",
    "September",
    "October",
    "November",
    "December"
  ],
  shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
};
function dayOfYear(date2, startOfYear = new Date(date2.getFullYear(), 0, 1)) {
  const startOffset = date2.getTimezoneOffset() - startOfYear.getTimezoneOffset();
  const timeDiff = date2.getTime() - startOfYear.getTime() + startOffset * 6e4;
  const timeOneDay = 36e5 * 24;
  return Math.floor(timeDiff / timeOneDay);
}
function weekOfYear(date2, startDay) {
  const startOfYear = new Date(date2.getFullYear(), 0, 1);
  const startOfYearDay = startOfYear.getDay();
  const firstWeekStartOffset = (startDay - startOfYearDay + 7) % 7;
  const startOffset = new Date(date2.getFullYear(), 0, firstWeekStartOffset + 1);
  if (startOffset <= date2) {
    return Math.floor(dayOfYear(date2, startOffset) / 7) + 1;
  }
  return 0;
}
var SUNDAY = 0;
var MONDAY = 1;
var THURSDAY = 4;
function isoWeekOfYear(date2, year = date2.getFullYear()) {
  const firstOfYear = new Date(year, 0, 1);
  const firstOfYearDay = firstOfYear.getDay();
  const firstThursdayOffset = (THURSDAY - firstOfYearDay + 7) % 7;
  const startOffset = new Date(year, 0, firstThursdayOffset - (THURSDAY - MONDAY) + 1);
  if (startOffset <= date2) {
    return Math.floor(dayOfYear(date2, startOffset) / 7) + 1;
  }
  return isoWeekOfYear(date2, year - 1);
}
function timezone(date2) {
  const offset = date2.getTimezoneOffset();
  const unsignedOffset = Math.abs(offset);
  const sign = offset > 0 ? "-" : "+";
  return `${sign}${pad(Math.floor(unsignedOffset / 60), 2, "0")}${pad(Math.floor(unsignedOffset % 60), 2, "0")}`;
}
var FORMATTERS = {
  a: (d) => CONSTANTS.shortDays[d.getDay()],
  A: (d) => CONSTANTS.days[d.getDay()],
  b: (d) => CONSTANTS.shortMonths[d.getMonth()],
  B: (d) => CONSTANTS.months[d.getMonth()],
  c: "%x, %X",
  d: (d, p) => pad(d.getDate(), 2, p ?? "0"),
  e: "%_d",
  f: (d, p) => pad(d.getMilliseconds() * 1e3, 6, p ?? "0"),
  H: (d, p) => pad(d.getHours(), 2, p ?? "0"),
  I: (d, p) => {
    const hours = d.getHours() % 12;
    return hours === 0 ? "12" : pad(hours, 2, p ?? "0");
  },
  j: (d, p) => pad(dayOfYear(d) + 1, 3, p ?? "0"),
  m: (d, p) => pad(d.getMonth() + 1, 2, p ?? "0"),
  M: (d, p) => pad(d.getMinutes(), 2, p ?? "0"),
  L: (d, p) => pad(d.getMilliseconds(), 3, p ?? "0"),
  p: (d) => d.getHours() < 12 ? "AM" : "PM",
  Q: (d) => String(d.getTime()),
  s: (d) => String(Math.floor(d.getTime() / 1e3)),
  S: (d, p) => pad(d.getSeconds(), 2, p ?? "0"),
  u: (d) => {
    let day = d.getDay();
    if (day < 1)
      day += 7;
    return String(day % 7);
  },
  U: (d, p) => pad(weekOfYear(d, SUNDAY), 2, p ?? "0"),
  V: (d, p) => pad(isoWeekOfYear(d), 2, p ?? "0"),
  w: (d, p) => pad(d.getDay(), 2, p ?? "0"),
  W: (d, p) => pad(weekOfYear(d, MONDAY), 2, p ?? "0"),
  x: "%-m/%-d/%Y",
  X: "%-I:%M:%S %p",
  y: (d, p) => pad(d.getFullYear() % 100, 2, p ?? "0"),
  Y: (d, p) => pad(d.getFullYear(), 4, p ?? "0"),
  Z: (d) => timezone(d),
  "%": () => "%"
};
var PADS = {
  _: " ",
  "0": "0",
  "-": ""
};
function pad(value, size, padChar) {
  const output = String(Math.floor(value));
  if (output.length >= size) {
    return output;
  }
  return `${padChar.repeat(size - output.length)}${output}`;
}
function buildDateFormatter(formatString) {
  const formatParts = [];
  while (formatString.length > 0) {
    let nextEscapeIdx = formatString.indexOf("%");
    if (nextEscapeIdx !== 0) {
      const literalPart = nextEscapeIdx > 0 ? formatString.substring(0, nextEscapeIdx) : formatString;
      formatParts.push(literalPart);
    }
    if (nextEscapeIdx < 0)
      break;
    const maybePadSpecifier = formatString[nextEscapeIdx + 1];
    const maybePad = PADS[maybePadSpecifier];
    if (maybePad != null) {
      nextEscapeIdx++;
    }
    const maybeFormatterSpecifier = formatString[nextEscapeIdx + 1];
    const maybeFormatter = FORMATTERS[maybeFormatterSpecifier];
    if (typeof maybeFormatter === "function") {
      formatParts.push([maybeFormatter, maybePad]);
    } else if (typeof maybeFormatter === "string") {
      const formatter2 = buildDateFormatter(maybeFormatter);
      formatParts.push([formatter2, maybePad]);
    } else {
      formatParts.push(`${maybePad ?? ""}${maybeFormatterSpecifier}`);
    }
    formatString = formatString.substring(nextEscapeIdx + 2);
  }
  return (dateTime) => {
    const dateTimeAsDate = typeof dateTime === "number" ? new Date(dateTime) : dateTime;
    return formatParts.map((c) => typeof c === "string" ? c : c[0](dateTimeAsDate, c[1])).join("");
  };
}

// packages/ag-charts-core/src/rendering/domElements.ts
function createButton(options, attrs) {
  const button = createElement("button", getClassName("ag-charts-input ag-charts-button", attrs));
  if (options.label === void 0) {
    button.append(createIcon(options.icon));
    button.ariaLabel = options.altText;
  } else {
    button.append(options.label);
  }
  button.addEventListener("click", options.onPress);
  setAttributes(button, attrs);
  return button;
}
function createCheckbox(options, attrs) {
  const checkbox = createElement("input", getClassName("ag-charts-input ag-charts-checkbox", attrs));
  checkbox.type = "checkbox";
  checkbox.checked = options.checked;
  checkbox.addEventListener("change", (event) => options.onChange(checkbox.checked, event));
  checkbox.addEventListener("keydown", (event) => {
    if (isButtonClickEvent(event)) {
      event.preventDefault();
      checkbox.click();
    }
  });
  setAttributes(checkbox, attrs);
  return checkbox;
}
function createSelect(options, attrs) {
  const select = createElement("select", getClassName("ag-charts-input ag-charts-select", attrs));
  select.append(
    ...options.options.map((option) => {
      const optionEl = createElement("option");
      optionEl.value = option.value;
      optionEl.textContent = option.label;
      return optionEl;
    })
  );
  setAttribute(select, "data-preventdefault", false);
  select.value = options.value;
  select.addEventListener("change", (event) => options.onChange(select.value, event));
  setAttributes(select, attrs);
  return select;
}
function createTextArea(options, attrs) {
  const textArea = createElement("textarea", getClassName("ag-charts-input ag-charts-textarea", attrs));
  textArea.value = options.value;
  textArea.addEventListener("input", (event) => options.onChange(textArea.value, event));
  setAttributes(textArea, attrs);
  setAttribute(textArea, "data-preventdefault", false);
  return textArea;
}
function createIcon(icon) {
  const el = createElement("span", `ag-charts-icon ag-charts-icon-${icon}`);
  setAttribute(el, "aria-hidden", true);
  return el;
}
function getClassName(baseClass, attrs) {
  if (attrs == null)
    return baseClass;
  return `${baseClass} ${attrs.class}`;
}

// packages/ag-charts-core/src/rendering/easing.ts
var linear = (n) => n;
var easeIn = (n) => 1 - Math.cos(n * Math.PI / 2);
var easeOut = (n) => Math.sin(n * Math.PI / 2);
var easeInOut = (n) => -(Math.cos(n * Math.PI) - 1) / 2;
var easeInQuad = (n) => n * n;
var easeOutQuad = (n) => 1 - (1 - n) ** 2;
var easeInOutQuad = (n) => n < 0.5 ? 2 * n * n : 1 - (-2 * n + 2) ** 2 / 2;
var inverseEaseOut = (x) => 2 * Math.asin(x) / Math.PI;

// packages/ag-charts-core/src/rendering/changeDetectable.ts
var TRIPLE_EQ = (lhs, rhs) => lhs === rhs;
function SceneChangeDetection(opts) {
  return function(target, key) {
    const privateKey = `__${key}`;
    if (target[key])
      return;
    prepareGetSet(target, key, privateKey, opts);
  };
}
function SceneRefChangeDetection(opts) {
  return SceneChangeDetection(opts);
}
function SceneObjectChangeDetection(opts) {
  return SceneChangeDetection(opts);
}
function SceneArrayChangeDetection(opts) {
  const baseOpts = opts ?? {};
  baseOpts.equals = arraysEqual;
  return SceneChangeDetection(opts);
}
function DeclaredSceneChangeDetection(opts) {
  return function(target, key) {
    const privateKey = `__${key}`;
    if (target[key])
      return;
    prepareGetSet(target, key, privateKey, opts);
  };
}
function DeclaredSceneObjectChangeDetection(opts) {
  return function(target, key) {
    const privateKey = `__${key}`;
    if (target[key])
      return;
    prepareGetSet(target, key, privateKey, opts);
  };
}
function prepareGetSet(target, key, privateKey, opts) {
  const { changeCb, convertor, checkDirtyOnAssignment = false } = opts ?? {};
  const requiredOpts = { changeCb, checkDirtyOnAssignment, convertor };
  const setter = buildCheckDirtyChain(
    privateKey,
    buildChangeCallbackChain(
      buildConvertorChain(buildSetter(privateKey, requiredOpts), requiredOpts),
      requiredOpts
    ),
    requiredOpts
  );
  function propertyGetter() {
    return this[privateKey];
  }
  Object.defineProperty(target, key, {
    set: setter,
    get: propertyGetter,
    enumerable: true,
    configurable: true
  });
}
function buildConvertorChain(setterFn, opts) {
  const { convertor } = opts;
  if (convertor) {
    let convertValueAndSet2 = function(value) {
      setterFn.call(this, convertValue(value));
    };
    var convertValueAndSet = convertValueAndSet2;
    const convertValue = convertor;
    return convertValueAndSet2;
  }
  return setterFn;
}
var NO_CHANGE = Symbol("no-change");
function buildChangeCallbackChain(setterFn, opts) {
  const { changeCb } = opts;
  if (changeCb) {
    let invokeChangeCallback2 = function(value) {
      const change = setterFn.call(this, value);
      if (change !== NO_CHANGE) {
        changeCallback.call(this, this);
      }
      return change;
    };
    var invokeChangeCallback = invokeChangeCallback2;
    const changeCallback = changeCb;
    return invokeChangeCallback2;
  }
  return setterFn;
}
function buildCheckDirtyChain(privateKey, setterFn, opts) {
  const { checkDirtyOnAssignment } = opts;
  if (checkDirtyOnAssignment) {
    let checkDirtyOnAssignmentFn2 = function(value) {
      const change = setterFn.call(this, value);
      if (value?._dirty === true) {
        this.markDirty(privateKey);
      }
      return change;
    };
    var checkDirtyOnAssignmentFn = checkDirtyOnAssignmentFn2;
    return checkDirtyOnAssignmentFn2;
  }
  return setterFn;
}
function buildSetter(privateKey, opts) {
  const { equals = TRIPLE_EQ } = opts;
  function setWithChangeDetection(value) {
    const oldValue = this[privateKey];
    if (!equals(value, oldValue)) {
      this[privateKey] = value;
      this.onChangeDetection(privateKey);
      return value;
    }
    return NO_CHANGE;
  }
  return setWithChangeDetection;
}

// packages/ag-charts-locale/src/en-US.ts
var AG_CHARTS_LOCALE_EN_US = {
  // Initial screen reader alt-text of the series area
  ariaInitSeriesArea: "interactive chart",
  // Screen reader announcement when focusing an item in the chart
  ariaAnnounceHoverDatum: "${datum}",
  // Screen reader announcement when focusing a chart
  ariaAnnounceChart: "chart, ${seriesCount}[number] series",
  // Screen reader announcement when focusing a standalone chart (gauges, pyramid)
  ariaAnnounceStandaloneChart: "chart, ${caption}",
  // Screen reader announcement when focusing a hierarchy chart
  ariaAnnounceHierarchyChart: "hierarchy chart, ${caption}",
  // Screen reader announcement when focusing a gauge chart
  ariaAnnounceGaugeChart: "gauge chart, ${caption}",
  // Screen reader announcement when focusing an item in a treemap or sunburst chart
  ariaAnnounceHierarchyDatum: "level ${level}[number], ${count}[number] children, ${description}",
  // Screen reader announcement when focusing a link in a Sankey or chord chart
  ariaAnnounceFlowProportionLink: "link ${index} of ${count}, from ${from} to ${to}, ${sizeName} ${size}",
  // Screen reader announcement when focusing a node in a Sankey or chord chart
  ariaAnnounceFlowProportionNode: "node ${index} of ${count}, ${description}",
  // Screen reader description for legend items
  ariaDescriptionLegendItem: "Press Space or Enter to toggle visibility",
  // Screen reader for the '+' horizontal line button on the Y-axis
  ariaLabelAddHorizontalLine: "Add Horizontal Line",
  // Screen reader text for annotations toolbar
  ariaLabelAnnotationsToolbar: "Annotations",
  // Screen reader text for annotation-options toolbar
  ariaLabelAnnotationOptionsToolbar: "Annotation Options",
  // Screen reader text for annotation-settings dialog
  ariaLabelAnnotationSettingsDialog: "Annotation Settings",
  // Screen reader text for the color-code label in the picker dialog
  ariaLabelColor: "Color",
  // Screen reader text for the color picker dialog
  ariaLabelColorPicker: "Color picker",
  // Screen reader text for the alpha-channel slider label
  ariaLabelColorPickerAlpha: "Transparency",
  // Screen reader text for the hue slider label
  ariaLabelColorPickerHue: "Hue",
  // Screen reader text for when the color-code is multi-colored
  ariaLabelColorPickerMultiColor: "Multi Color",
  // Screen reader text for the 2D palette slider label
  ariaLabelColorPickerPalette: "Palette",
  // Screen reader text for the financial charts toolbar
  ariaLabelFinancialCharts: "Financial Charts",
  // Screen reader text label for the gauge targets
  ariaLabelGaugeTarget: "Target",
  // Screen reader text label for the gauge values
  ariaLabelGaugeValue: "Value",
  // Screen reader text for the legend toolbar
  ariaLabelLegend: "Legend",
  // Screen reader text for the legend pagination button
  ariaLabelLegendPagination: "Legend Pagination",
  // Screen reader text for the previous legend page button
  ariaLabelLegendPagePrevious: "Previous Legend Page",
  // Screen reader text for the next legend page button
  ariaLabelLegendPageNext: "Next Legend Page",
  // Screen reader text for the an item in the legend
  ariaLabelLegendItem: "${label}, Legend item ${index}[number] of ${count}[number]",
  // Screen reader text for the an unknown item in the legend
  ariaLabelLegendItemUnknown: "Unknown legend item",
  // Screen reader text for the navigator element
  ariaLabelNavigator: "Navigator",
  // Screen reader text for an accessibility control that changes the position of the navigator's range
  ariaLabelNavigatorRange: "Range",
  // Screen reader text for the horizontal axis scrollbar
  ariaLabelScrollbarHorizontal: "X-axis scrollbar",
  // Screen reader text for the vertical axis scrollbar
  ariaLabelScrollbarVertical: "Y-axis scrollbar",
  // Screen reader text for an accessibility control that changes the start of the navigator's range
  ariaLabelNavigatorMinimum: "Minimum",
  // Screen reader text for an accessibility control that changes the end of the navigator's range
  ariaLabelNavigatorMaximum: "Maximum",
  // Screen reader text for ranges toolbar
  ariaLabelRangesToolbar: "Ranges",
  // Screen reader text for the settings dialog tab-bar
  ariaLabelSettingsTabBar: "Settings",
  // Screen reader text for zoom toolbar
  ariaLabelZoomToolbar: "Zoom",
  // Aria role description for a 2D role="slider"
  ariaRoleDescription2DSlider: "2D slider",
  // Screen reader text for color picker's 2D slider palette
  ariaValueColorPalette: "s ${s}[percent0to2dp], v ${v}[percent0to2dp]",
  // Screen reader text for color picker's 2D slider palette (when arrowing up or down)
  ariaValueColorPaletteFirstV: "v ${v}[percent0to2dp], s ${s}[percent0to2dp]",
  // Screen reader text for the value of the navigator's range
  ariaValuePanRange: "${min}[percent0to2dp] to ${max}[percent0to2dp]",
  // Alt-text for the solid line dash style menu item icon
  iconAltTextLineStyleSolid: "Solid",
  // Alt-text for the long-dashed line dash style menu item icon
  iconAltTextLineStyleDashed: "Long-dashed",
  // Alt-text for the short-dashed line dash style menu item icon
  iconAltTextLineStyleDotted: "Short-dashed",
  // Alt-text for the 'position-top' icon
  iconAltTextPositionTop: "Top",
  // Alt-text for the 'position-center' icon
  iconAltTextPositionCenter: "Center",
  // Alt-text for the 'position-bottom' icon
  iconAltTextPositionBottom: "Bottom",
  // Alt-text for the 'position-left' icon
  iconAltTextAlignLeft: "Left",
  // Alt-text for the 'align-center' icon
  iconAltTextAlignCenter: "Center",
  // Alt-text for the 'position-right' icon
  iconAltTextAlignRight: "Right",
  // Alt-text for the 'close' icon
  iconAltTextClose: "Close",
  // Default text for the 'loading data' overlay
  overlayLoadingData: "Loading data...",
  // Default text for the 'no data' overlay
  overlayNoData: "No data to display",
  // Default text for the 'no visible series' overlay
  overlayNoVisibleSeries: "No visible series",
  // Default text for the 'unsupported browser' overlay
  overlayUnsupportedBrowser: "Incompatible browser version. Please upgrade your browser.",
  // Text for frequency label in Histogram Series tooltip
  seriesHistogramTooltipFrequency: "Frequency",
  // Text for sum label in Histogram Series tooltip
  seriesHistogramTooltipSum: "${yName} (sum)",
  // Text for sum label in Histogram Series tooltip
  seriesHistogramTooltipCount: "${yName} (count)",
  // Text for sum label in Histogram Series tooltip
  seriesHistogramTooltipMean: "${yName} (mean)",
  // Text for the series type toolbar's chart type button
  toolbarSeriesTypeDropdown: "Chart Type",
  // Text for the series type toolbar's OHLC chart type button
  toolbarSeriesTypeOHLC: "OHLC",
  // Text for the series type toolbar's HLC chart type button
  toolbarSeriesTypeHLC: "HLC",
  // Text for the series type toolbar's high low chart type button
  toolbarSeriesTypeHighLow: "High Low",
  // Text for the series type toolbar's candles chart type button
  toolbarSeriesTypeCandles: "Candles",
  // Text for the series type toolbar's hollow candles chart type button
  toolbarSeriesTypeHollowCandles: "Hollow Candles",
  // Text for the series type toolbar's line chart type button
  toolbarSeriesTypeLine: "Line",
  // Text for the series type toolbar's line with markers chart type button
  toolbarSeriesTypeLineWithMarkers: "Line with Markers",
  // Text for the series type toolbar's line with step line chart type button
  toolbarSeriesTypeStepLine: "Step Line",
  // Text for the annotation toolbar's trend line button
  toolbarAnnotationsTrendLine: "Trend Line",
  // Text for the annotation toolbar's Fibonacci Retracement button
  toolbarAnnotationsFibonacciRetracement: "Fib Retracement",
  // Text for the annotation toolbar's Fibonacci Retracement Trend Based button
  toolbarAnnotationsFibonacciRetracementTrendBased: "Fib Trend Based",
  // Text for the annotation toolbar's horizontal line button
  toolbarAnnotationsHorizontalLine: "Horizontal Line",
  // Text for the annotation toolbar's vertical line button
  toolbarAnnotationsVerticalLine: "Vertical Line",
  // Text for the annotation toolbar's parallel channel button
  toolbarAnnotationsParallelChannel: "Parallel Channel",
  // Text for the annotation toolbar's disjoint channel button
  toolbarAnnotationsDisjointChannel: "Disjoint Channel",
  // Text for the annotation toolbar's clear all button
  toolbarAnnotationsClearAll: "Clear All",
  // Text for the annotation toolbar's fill color picker annotation button
  toolbarAnnotationsFillColor: "Fill Color",
  // Text for the annotation toolbar's line color picker annotation button
  toolbarAnnotationsLineColor: "Line Color",
  // Text for the annotation toolbar's line style type button
  toolbarAnnotationsLineStyle: "Line Style",
  // Text for the annotation toolbar's line stroke width button
  toolbarAnnotationsLineStrokeWidth: "Line Stroke Width",
  // Text for the annotation toolbar's settings annotation button
  toolbarAnnotationsSettings: "Settings",
  // Text for the annotation toolbar's text color picker annotation button
  toolbarAnnotationsTextColor: "Text Color",
  // Text for the annotation toolbar's text size picker annotation button
  toolbarAnnotationsTextSize: "Text Size",
  // Text for the annotation toolbar's lock annotation button
  toolbarAnnotationsLock: "Lock",
  // Text for the annotation toolbar's unlock annotation button
  toolbarAnnotationsUnlock: "Unlock",
  // Text for the annotation toolbar's delete annotation button
  toolbarAnnotationsDelete: "Delete",
  // Text for the annotation toolbar's drag handle
  toolbarAnnotationsDragHandle: "Drag Toolbar",
  // Text for the annotation toolbar's line drawings menu button
  toolbarAnnotationsLineAnnotations: "Trend Lines",
  // Text for the annotation toolbar's Fibonacci drawings menu button
  toolbarAnnotationsFibonacciAnnotations: "Fibonacci",
  // Text for the annotation toolbar's text annotations menu button
  toolbarAnnotationsTextAnnotations: "Text Annotations",
  // Text for the annotation toolbar's shapes menu button
  toolbarAnnotationsShapeAnnotations: "Arrows",
  // Text for the annotation toolbar's measurers menu button
  toolbarAnnotationsMeasurerAnnotations: "Measurers",
  // Text for the annotation toolbar's callout button
  toolbarAnnotationsCallout: "Callout",
  // Text for the annotation toolbar's comment button
  toolbarAnnotationsComment: "Comment",
  // Text for the annotation toolbar's note button
  toolbarAnnotationsNote: "Note",
  // Text for the annotation toolbar's text button
  toolbarAnnotationsText: "Text",
  // Text for the annotation toolbar's arrow button
  toolbarAnnotationsArrow: "Arrow",
  // Text for the annotation toolbar's arrow up button
  toolbarAnnotationsArrowUp: "Arrow Up",
  // Text for the annotation toolbar's arrow down button
  toolbarAnnotationsArrowDown: "Arrow Down",
  // Text for the annotation toolbar's date range button
  toolbarAnnotationsDateRange: "Date Range",
  // Text for the annotation toolbar's price range button
  toolbarAnnotationsPriceRange: "Price Range",
  // Text for the annotation toolbar's date and price range button
  toolbarAnnotationsDatePriceRange: "Date and Price",
  // Text for the annotation toolbar's quick date and price range button
  toolbarAnnotationsQuickDatePriceRange: "Measure",
  // Text for the range toolbar's 1 month button
  toolbarRange1Month: "1M",
  // Aria label for the range toolbar's 1 month button
  toolbarRange1MonthAria: "1 month",
  // Text for the range toolbar's 3 month button
  toolbarRange3Months: "3M",
  // Aria label for the range toolbar's 3 month button
  toolbarRange3MonthsAria: "3 months",
  // Text for the range toolbar's 6 month button
  toolbarRange6Months: "6M",
  // Aria label for the range toolbar's 6 month button
  toolbarRange6MonthsAria: "6 months",
  // Text for the range toolbar's year to date button
  toolbarRangeYearToDate: "YTD",
  // Aria label for the range toolbar's year to date month button
  toolbarRangeYearToDateAria: "Year to date",
  // Text for the range toolbar's 1 year button
  toolbarRange1Year: "1Y",
  // Aria label for the range toolbar's 1 year button
  toolbarRange1YearAria: "1 year",
  // Text for the range toolbar's full range button
  toolbarRangeAll: "All",
  // Aria label for the range toolbar's full range button
  toolbarRangeAllAria: "All",
  // Text for the zoom toolbar's zoom out button
  toolbarZoomZoomOut: "Zoom out",
  // Text for the zoom toolbar's zoom in button
  toolbarZoomZoomIn: "Zoom in",
  // Text for the zoom toolbar's pan left button
  toolbarZoomPanLeft: "Pan left",
  // Text for the zoom toolbar's pan right button
  toolbarZoomPanRight: "Pan right",
  // Text for the zoom toolbar's pan to the start button
  toolbarZoomPanStart: "Pan to the start",
  // Text for the zoom toolbar's pan to the end button
  toolbarZoomPanEnd: "Pan to the end",
  // Text for the zoom toolbar's pan reset button
  toolbarZoomReset: "Reset the zoom",
  // Text for the context menu's download button
  contextMenuDownload: "Download",
  // Text for the context menu's toggle series visibility button
  contextMenuToggleSeriesVisibility: "Toggle Visibility",
  // Text for the context menu's toggle other series visibility button
  contextMenuToggleOtherSeries: "Toggle Other Series",
  // Text for the context menu's zoom to point button
  contextMenuZoomToCursor: "Zoom to here",
  // Text for the context menu's pan to point button
  contextMenuPanToCursor: "Pan to here",
  // Text for the context menu's reset zoom button
  contextMenuResetZoom: "Reset zoom",
  // Text for the annotation dialog's header channel tab label
  dialogHeaderChannel: "Channel",
  // Text for the annotation dialog's header line tab label
  dialogHeaderLine: "Line",
  // Text for the annotation dialog's header fibonacci retracement line tab label
  dialogHeaderFibonacciRange: "Fib Retracement",
  // Text for the annotation dialog's header date range tab label
  dialogHeaderDateRange: "Date Range",
  // Text for the annotation dialog's header price range tab label
  dialogHeaderPriceRange: "Price Range",
  // Text for the annotation dialog's header date and price range tab label
  dialogHeaderDatePriceRange: "Date and Price",
  // Text for the annotation dialog's header text tab label
  dialogHeaderText: "Text",
  // Text for the annotation dialog's text alignment radio label
  dialogInputAlign: "Align",
  // Text for the annotation dialog's color picker label
  dialogInputColorPicker: "Color",
  // Text for the annotation dialog's color picker alt text
  dialogInputColorPickerAltText: "Text Color",
  // Text for the annotation dialog's fill color picker label
  dialogInputFillColorPicker: "Fill",
  // Text for the annotation dialog's fill color picker alt text
  dialogInputFillColorPickerAltText: "Fill Color",
  // Text for the annotation dialog's extend channel start checkbox
  dialogInputExtendChannelStart: "Extend channel start",
  // Text for the annotation dialog's extend channel end checkbox
  dialogInputExtendChannelEnd: "Extend channel end",
  // Text for the annotation dialog's extend line start checkbox
  dialogInputExtendLineStart: "Extend line start",
  // Text for the annotation dialog's extend line end checkbox
  dialogInputExtendLineEnd: "Extend line end",
  // Text for the annotation dialog's extend above checkbox
  dialogInputExtendAbove: "Extend above",
  // Text for the annotation dialog's extend below checkbox
  dialogInputExtendBelow: "Extend below",
  // Text for the annotation dialog's extend left checkbox
  dialogInputExtendLeft: "Extend left",
  // Text for the annotation dialog's extend right checkbox
  dialogInputExtendRight: "Extend right",
  // Text for the annotation dialog's reverse checkbox
  dialogInputReverse: "Reverse",
  // Text for the annotation dialog's show fill checkbox
  dialogInputShowFill: "Show Fill",
  // Text for the annotation dialog's font size select box label
  dialogInputFontSize: "Size",
  // Text for the annotation dialog's font size select box alt text
  dialogInputFontSizeAltText: "Font Size",
  // Text for the annotation dialog's line style radio label
  dialogInputLineStyle: "Dash",
  // Text for the annotation dialog's text position radio label
  dialogInputPosition: "Position",
  // Text for the annotation dialog's stroke width label
  dialogInputStrokeWidth: "Weight",
  // Text for the annotation dialog's stroke width label
  dialogInputStrokeWidthAltText: "Line Weight",
  // Text for the annotation dialog's Fibonacci bands label
  dialogInputFibonacciBands: "Bands",
  // Text for the annotation dialog's Fibonacci bands label
  dialogInputFibonacciBandsAltText: "Fibonacci Bands",
  // Text for text area input placeholders
  inputTextareaPlaceholder: "Add Text",
  // Text for the measurer statistics date range bars value
  measurerDateRangeBars: "${value}[number] bars",
  // Text for the measurer statistics price range value
  measurerPriceRangeValue: "${value}[number]",
  // Text for the measurer statistics price range percentage
  measurerPriceRangePercent: "${value}[percent]",
  // Text for the measurer statistics volume value
  measurerVolume: "Vol ${value}",
  // Status when multiple data are under the cursor, and the user can click to cycle through which one appears in the tooltip
  tooltipPaginationStatus: "${index}[number] of ${count}[number]"
};

// packages/ag-charts-community/src/util/time-interop.ts
function createTimeInterval(unit, step, epoch, utc) {
  return {
    unit,
    step,
    epoch,
    utc,
    every(count) {
      return createTimeInterval(this.unit, (this.step ?? 1) * count, this.epoch, this.utc);
    }
  };
}
var cachedInstances = {};
function getTimeInterval(unit, step = 1, epoch, utc = false) {
  logger_exports.warnOnce("time import is deprecated, use object notation instead");
  const key = `${unit}:${step}:${epoch?.getTime() ?? 0}:${utc}`;
  let instance = cachedInstances[key];
  if (instance == null) {
    instance = createTimeInterval(unit, step, epoch, utc);
    cachedInstances[key] = instance;
  }
  return instance;
}
var time = {
  get millisecond() {
    return getTimeInterval("millisecond");
  },
  get second() {
    return getTimeInterval("second");
  },
  get minute() {
    return getTimeInterval("minute");
  },
  get hour() {
    return getTimeInterval("hour");
  },
  get day() {
    return getTimeInterval("day");
  },
  get monday() {
    return getTimeInterval("day", 7, new Date(1970, 0, 5));
  },
  get tuesday() {
    return getTimeInterval("day", 7, new Date(1970, 0, 6));
  },
  get wednesday() {
    return getTimeInterval("day", 7, new Date(1970, 0, 7));
  },
  get thursday() {
    return getTimeInterval("day", 7, new Date(1970, 0, 1));
  },
  get friday() {
    return getTimeInterval("day", 7, new Date(1970, 0, 2));
  },
  get saturday() {
    return getTimeInterval("day", 7, new Date(1970, 0, 3));
  },
  get sunday() {
    return getTimeInterval("day", 7, new Date(1970, 0, 4));
  },
  get month() {
    return getTimeInterval("month");
  },
  get year() {
    return getTimeInterval("year");
  },
  get utcMillisecond() {
    return getTimeInterval("millisecond", 1, void 0, true);
  },
  get utcSecond() {
    return getTimeInterval("second", 1, void 0, true);
  },
  get utcMinute() {
    return getTimeInterval("minute", 1, void 0, true);
  },
  get utcHour() {
    return getTimeInterval("hour", 1, void 0, true);
  },
  get utcDay() {
    return getTimeInterval("day", 1, void 0, true);
  },
  get utcMonth() {
    return getTimeInterval("month", 1, void 0, true);
  },
  get utcYear() {
    return getTimeInterval("year", 1, void 0, true);
  }
};

// packages/ag-charts-community/src/util/interpolating.ts
var interpolate = Symbol("interpolate");
var isInterpolating = (x) => x[interpolate] != null;

// packages/ag-charts-community/src/scene/bbox.ts
var _BBox = class _BBox {
  constructor(x, y, width2, height2) {
    this.x = x;
    this.y = y;
    this.width = width2;
    this.height = height2;
  }
  static fromObject({ x, y, width: width2, height: height2 }) {
    return new _BBox(x, y, width2, height2);
  }
  static merge(boxes) {
    let left = Infinity;
    let top = Infinity;
    let right = -Infinity;
    let bottom = -Infinity;
    for (const box of boxes) {
      if (box.x < left) {
        left = box.x;
      }
      if (box.y < top) {
        top = box.y;
      }
      if (end2(box.x, box.width) > right) {
        right = end2(box.x, box.width);
      }
      if (end2(box.y, box.height) > bottom) {
        bottom = end2(box.y, box.height);
      }
    }
    return new _BBox(left, top, right - left, bottom - top);
  }
  static nearestBox(x, y, boxes) {
    return nearestSquared(x, y, boxes);
  }
  toDOMRect() {
    return {
      x: this.x,
      y: this.y,
      width: this.width,
      height: this.height,
      top: this.y,
      left: this.x,
      right: end2(this.x, this.width),
      bottom: end2(this.y, this.height),
      toJSON() {
        return {};
      }
    };
  }
  clone() {
    const { x, y, width: width2, height: height2 } = this;
    return new _BBox(x, y, width2, height2);
  }
  equals(other) {
    return boxesEqual(this, other);
  }
  containsPoint(x, y) {
    return boxContains(this, x, y);
  }
  intersection(other) {
    const x0 = Math.max(this.x, other.x);
    const y0 = Math.max(this.y, other.y);
    const x1 = Math.min(end2(this.x, this.width), end2(other.x, other.width));
    const y1 = Math.min(end2(this.y, this.height), end2(other.y, other.height));
    if (x0 > x1 || y0 > y1)
      return;
    return new _BBox(x0, y0, x1 - x0, y1 - y0);
  }
  collidesBBox(other) {
    return this.x < end2(other.x, other.width) && end2(this.x, this.width) > other.x && this.y < end2(other.y, other.height) && end2(this.y, this.height) > other.y;
  }
  computeCenter() {
    return { x: this.x + this.width / 2, y: this.y + this.height / 2 };
  }
  isFinite() {
    return Number.isFinite(this.x) && Number.isFinite(this.y) && Number.isFinite(this.width) && Number.isFinite(this.height);
  }
  distanceSquared(x, y) {
    if (this.containsPoint(x, y)) {
      return 0;
    }
    const dx2 = x - clamp(this.x, x, end2(this.x, this.width));
    const dy2 = y - clamp(this.y, y, end2(this.y, this.height));
    return dx2 * dx2 + dy2 * dy2;
  }
  shrink(amount, position) {
    if (typeof amount === "number") {
      this.applyMargin(amount, position);
    } else {
      for (const key of Object.keys(amount)) {
        const value = amount[key];
        if (typeof value === "number") {
          this.applyMargin(value, key);
        }
      }
    }
    if (this.width < 0) {
      this.width = 0;
    }
    if (this.height < 0) {
      this.height = 0;
    }
    return this;
  }
  grow(amount, position) {
    if (typeof amount === "number") {
      this.applyMargin(-amount, position);
    } else {
      for (const key of Object.keys(amount)) {
        const value = amount[key];
        if (typeof value === "number") {
          this.applyMargin(-value, key);
        }
      }
    }
    return this;
  }
  applyMargin(value, position) {
    switch (position) {
      case "top":
        this.y += value;
      case "bottom":
        this.height -= value;
        break;
      case "left":
        this.x += value;
      case "right":
        this.width -= value;
        break;
      case "vertical":
        this.y += value;
        this.height -= value * 2;
        break;
      case "horizontal":
        this.x += value;
        this.width -= value * 2;
        break;
      case void 0:
        this.x += value;
        this.y += value;
        this.width -= value * 2;
        this.height -= value * 2;
        break;
    }
  }
  translate(x, y) {
    this.x += x;
    this.y += y;
    return this;
  }
  [interpolate](other, d) {
    return new _BBox(
      this.x * (1 - d) + other.x * d,
      this.y * (1 - d) + other.y * d,
      this.width * (1 - d) + other.width * d,
      this.height * (1 - d) + other.height * d
    );
  }
};
_BBox.zero = Object.freeze(new _BBox(0, 0, 0, 0));
_BBox.NaN = Object.freeze(new _BBox(Number.NaN, Number.NaN, Number.NaN, Number.NaN));
var BBox = _BBox;
function end2(x, width2) {
  if (x === -Infinity && width2 === Infinity)
    return Infinity;
  return x + width2;
}

// packages/ag-charts-community/src/scene/canvas/canvasUtil.ts
function clearContext({
  context,
  pixelRatio,
  width: width2,
  height: height2
}) {
  context.save();
  try {
    context.resetTransform();
    context.clearRect(0, 0, Math.ceil(width2 * pixelRatio), Math.ceil(height2 * pixelRatio));
  } finally {
    context.restore();
  }
}
function debugContext(ctx) {
  if (debugLogger_exports.check("canvas")) {
    const save = ctx.save.bind(ctx);
    const restore = ctx.restore.bind(ctx);
    let depth = 0;
    Object.assign(ctx, {
      save() {
        save();
        depth++;
      },
      restore() {
        if (depth === 0) {
          throw new Error("AG Charts - Unable to restore() past depth 0");
        }
        restore();
        depth--;
      },
      verifyDepthZero() {
        if (depth !== 0) {
          throw new Error(`AG Charts - Save/restore depth is non-zero: ${depth}`);
        }
      }
    });
  }
}

// packages/ag-charts-community/src/scene/canvas/hdpiOffscreenCanvas.ts
function canvasDimensions(width2, height2, pixelRatio) {
  return [Math.floor(width2 * pixelRatio), Math.floor(height2 * pixelRatio)];
}
var fallbackCanvas;
function getFallbackCanvas() {
  const OffscreenCanvasCtor = getOffscreenCanvas();
  fallbackCanvas ?? (fallbackCanvas = new OffscreenCanvasCtor(1, 1));
  return fallbackCanvas;
}
var HdpiOffscreenCanvas = class {
  constructor(options) {
    const { width: width2, height: height2, pixelRatio, willReadFrequently = false } = options;
    this.width = width2;
    this.height = height2;
    this.pixelRatio = pixelRatio;
    const [canvasWidth, canvasHeight] = canvasDimensions(width2, height2, pixelRatio);
    const OffscreenCanvasCtor = getOffscreenCanvas();
    this.canvas = new OffscreenCanvasCtor(canvasWidth, canvasHeight);
    this.context = this.canvas.getContext("2d", { willReadFrequently });
    this.context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
    debugContext(this.context);
  }
  drawImage(context, dx2 = 0, dy2 = 0) {
    return context.drawImage(this.canvas, dx2, dy2);
  }
  transferToImageBitmap() {
    if (this.canvas.width < 1 || this.canvas.height < 1) {
      return getFallbackCanvas().transferToImageBitmap();
    }
    return this.canvas.transferToImageBitmap();
  }
  resize(width2, height2, pixelRatio) {
    if (!(width2 > 0 && height2 > 0))
      return;
    const { canvas, context } = this;
    if (width2 !== this.width || height2 !== this.height || pixelRatio !== this.pixelRatio) {
      const [canvasWidth, canvasHeight] = canvasDimensions(width2, height2, pixelRatio);
      canvas.width = canvasWidth;
      canvas.height = canvasHeight;
    }
    context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
    this.width = width2;
    this.height = height2;
    this.pixelRatio = pixelRatio;
  }
  clear() {
    clearContext(this);
  }
  destroy() {
    this.canvas.width = 0;
    this.canvas.height = 0;
    this.context.clearRect(0, 0, 0, 0);
    this.canvas = null;
    this.context = null;
    Object.freeze(this);
  }
};

// packages/ag-charts-community/src/scene/zIndex.ts
var cmp = (a, b) => Math.sign(a - b);
function compareZIndex(a, b) {
  if (typeof a === "number" && typeof b === "number") {
    return cmp(a, b);
  }
  const aArray = typeof a === "number" ? [a] : a;
  const bArray = typeof b === "number" ? [b] : b;
  const length2 = Math.min(aArray.length, bArray.length);
  for (let i = 0; i < length2; i += 1) {
    const diff9 = cmp(aArray[i], bArray[i]);
    if (diff9 !== 0)
      return diff9;
  }
  return cmp(aArray.length, bArray.length);
}

// packages/ag-charts-community/src/scene/node.ts
var PointerEvents = /* @__PURE__ */ ((PointerEvents15) => {
  PointerEvents15[PointerEvents15["All"] = 0] = "All";
  PointerEvents15[PointerEvents15["None"] = 1] = "None";
  return PointerEvents15;
})(PointerEvents || {});
var MAX_ERROR_COUNT = 5;
var _Node = class _Node {
  constructor(options) {
    /** Unique number to allow creation order to be easily determined. */
    this.serialNumber = _Node._nextSerialNumber++;
    this.childNodeCounts = { groups: 0, nonGroups: 0, thisComplexity: 0, complexity: 0 };
    /** Unique node ID in the form `ClassName-NaturalNumber`. */
    this.id = createId(this);
    this.name = void 0;
    this.transitionOut = void 0;
    this.pointerEvents = 0 /* All */;
    this._datum = void 0;
    this._previousDatum = void 0;
    this.scene = void 0;
    this._debugDirtyProperties = void 0;
    this.parentNode = void 0;
    this.cachedBBox = void 0;
    /**
     * To simplify the type system (especially in Selections) we don't have the `Parent` node
     * (one that has children). Instead, we mimic HTML DOM, where any node can have children.
     * But we still need to distinguish regular leaf nodes from container leafs somehow.
     */
    this.isContainerNode = false;
    this.visible = true;
    this.zIndex = 0;
    this.batchLevel = 0;
    this.batchDirty = false;
    this.name = options?.name;
    this.tag = options?.tag ?? Number.NaN;
    this.zIndex = options?.zIndex ?? 0;
    this.scene = options?.scene;
    if (options?.debugDirty ?? _Node._debugEnabled) {
      this._debugDirtyProperties = /* @__PURE__ */ new Map([["__first__", []]]);
    }
  }
  static toSVG(node, width2, height2) {
    const svg = node?.toSVG();
    if (svg == null || !svg.elements.length && !svg.defs?.length)
      return;
    const root = createSvgElement("svg");
    root.setAttribute("width", String(width2));
    root.setAttribute("height", String(height2));
    root.setAttribute("viewBox", `0 0 ${width2} ${height2}`);
    root.setAttribute("overflow", "visible");
    if (svg.defs?.length) {
      const defs = createSvgElement("defs");
      defs.append(...svg.defs);
      root.append(defs);
    }
    root.append(...svg.elements);
    return root.outerHTML;
  }
  static *extractBBoxes(nodes, skipInvisible) {
    for (const n of nodes) {
      if (!skipInvisible || n.visible && !n.transitionOut) {
        const bbox = n.getBBox();
        if (bbox)
          yield bbox;
      }
    }
  }
  /**
   * Some arbitrary data bound to the node.
   */
  get datum() {
    return this._datum;
  }
  set datum(datum) {
    if (this._datum !== datum) {
      this._previousDatum = this._datum;
      this._datum = datum;
    }
  }
  get previousDatum() {
    return this._previousDatum;
  }
  get layerManager() {
    return this.scene?.layersManager;
  }
  get imageLoader() {
    return this.scene?.imageLoader;
  }
  closestDatum() {
    for (const { datum } of this.traverseUp(true)) {
      if (datum != null) {
        return datum;
      }
    }
  }
  /** Perform any pre-rendering initialization. */
  preRender(_renderCtx, thisComplexity = 1) {
    this.childNodeCounts.groups = 0;
    this.childNodeCounts.nonGroups = 1;
    this.childNodeCounts.complexity = thisComplexity;
    this.childNodeCounts.thisComplexity = thisComplexity;
    if (this.batchLevel > 0 || this.batchDirty) {
      throw new Error("AG Charts - illegal rendering state; batched update in progress");
    }
    return this.childNodeCounts;
  }
  /** Guaranteed isolated render - if there is any failure, the Canvas2D context is returned to its prior state. */
  isolatedRender(renderCtx) {
    renderCtx.ctx.save();
    try {
      this.render(renderCtx);
    } catch (e) {
      const errorCount = e.errorCount ?? 1;
      if (errorCount >= MAX_ERROR_COUNT) {
        e.errorCount = errorCount;
        throw e;
      }
      logger_exports.warnOnce("Error during rendering", e, e.stack);
    } finally {
      renderCtx.ctx.restore();
    }
  }
  render(renderCtx) {
    const { stats } = renderCtx;
    this.debugDirtyProperties();
    if (renderCtx.debugNodeSearch) {
      const idOrName = this.name ?? this.id;
      if (renderCtx.debugNodeSearch.some((v) => typeof v === "string" ? v === idOrName : v.test(idOrName))) {
        renderCtx.debugNodes[this.name ?? this.id] = this;
      }
    }
    if (stats) {
      stats.nodesRendered++;
      stats.opsPerformed += this.childNodeCounts.thisComplexity;
    }
  }
  setScene(scene) {
    this.scene = scene;
  }
  *traverseUp(includeSelf) {
    if (includeSelf) {
      yield this;
    }
    let node = this.parentNode;
    while (node) {
      yield node;
      node = node.parentNode;
    }
  }
  /**
   * Checks if the node is the root (has no parent).
   */
  isRoot() {
    return !this.parentNode;
  }
  removeChild(node) {
    throw new Error(
      `AG Charts - internal error, unknown child node ${node.name ?? node.id} in $${this.name ?? this.id}`
    );
  }
  remove() {
    this.parentNode?.removeChild(this);
  }
  destroy() {
    if (this.parentNode) {
      this.remove();
    }
  }
  batchedUpdate(fn) {
    this.batchLevel++;
    try {
      fn();
    } finally {
      this.batchLevel--;
      if (this.batchLevel === 0 && this.batchDirty) {
        this.markDirty();
        this.batchDirty = false;
      }
    }
  }
  setProperties(styles) {
    this.batchLevel++;
    try {
      assignIfNotStrictlyEqual(this, styles);
    } finally {
      this.batchLevel--;
      if (this.batchLevel === 0 && this.batchDirty) {
        this.markDirty();
        this.batchDirty = false;
      }
    }
    return this;
  }
  setPropertiesWithKeys(styles, keys) {
    this.batchLevel++;
    try {
      assignIfNotStrictlyEqual(this, styles, keys);
    } finally {
      this.batchLevel--;
      if (this.batchLevel === 0 && this.batchDirty) {
        this.markDirty();
        this.batchDirty = false;
      }
    }
    return this;
  }
  containsPoint(_x, _y) {
    return false;
  }
  pickNode(x, y) {
    if (this.containsPoint(x, y)) {
      return this;
    }
  }
  pickNodes(x, y, into = []) {
    if (this.containsPoint(x, y)) {
      into.push(this);
    }
    return into;
  }
  getBBox() {
    this.cachedBBox ?? (this.cachedBBox = Object.freeze(this.computeBBox()));
    return this.cachedBBox;
  }
  computeBBox() {
    return;
  }
  onChangeDetection(property) {
    this.markDirty(property);
  }
  markDirtyChildrenOrder() {
    this.cachedBBox = void 0;
  }
  markDirty(property) {
    if (this.batchLevel > 0) {
      this.batchDirty = true;
      return;
    }
    if (property != null && this._debugDirtyProperties) {
      this.markDebugProperties(property);
    }
    this.cachedBBox = void 0;
    this.parentNode?.markDirty();
  }
  markDebugProperties(property) {
    const sources = this._debugDirtyProperties?.get(property) ?? [];
    const caller = new Error("Stack trace for property change tracking").stack?.split("\n").filter((line) => {
      return line !== "Error" && !line.includes(".markDebugProperties") && !line.includes(".markDirty") && !line.includes("Object.assign ") && !line.includes(`${this.constructor.name}.`);
    }) ?? "unknown";
    sources.push(caller[0].replace(" at ", "").trim());
    this._debugDirtyProperties?.set(property, sources);
  }
  debugDirtyProperties() {
    if (this._debugDirtyProperties == null)
      return;
    if (!this._debugDirtyProperties.has("__first__")) {
      for (const [property, sources] of this._debugDirtyProperties.entries()) {
        if (sources.length > 1) {
          logger_exports.logGroup(
            `Property changed multiple times before render: ${this.constructor.name}.${property} (${sources.length}x)`,
            () => {
              for (const source of sources) {
                logger_exports.log(source);
              }
            }
          );
        }
      }
    }
    this._debugDirtyProperties.clear();
  }
  static handleNodeZIndexChange(target) {
    target.onZIndexChange();
  }
  onZIndexChange() {
    this.parentNode?.markDirtyChildrenOrder();
  }
  toSVG() {
    return;
  }
};
_Node.className = "AbstractNode";
_Node._nextSerialNumber = 0;
// eslint-disable-next-line sonarjs/public-static-readonly
_Node._debugEnabled = false;
__decorateClass([
  DeclaredSceneChangeDetection()
], _Node.prototype, "visible", 2);
__decorateClass([
  DeclaredSceneChangeDetection({
    equals: objectsEqual,
    changeCb: _Node.handleNodeZIndexChange
  })
], _Node.prototype, "zIndex", 2);
var Node2 = _Node;

// packages/ag-charts-community/src/scale/abstractScale.ts
var AbstractScale = class {
  ticks(_ticks, _domain, _visibleRange) {
    return void 0;
  }
  niceDomain(_ticks, domain = this.domain) {
    return domain;
  }
  get bandwidth() {
    return void 0;
  }
  get step() {
    return void 0;
  }
  get inset() {
    return void 0;
  }
};

// packages/ag-charts-community/src/scale/invalidating.ts
var Invalidating = (target, propertyKey) => {
  const mappedProperty = Symbol(String(propertyKey));
  target[mappedProperty] = void 0;
  Object.defineProperty(target, propertyKey, {
    get() {
      return this[mappedProperty];
    },
    set(newValue) {
      const oldValue = this[mappedProperty];
      if (oldValue !== newValue) {
        this[mappedProperty] = newValue;
        this.invalid = true;
      }
    },
    enumerable: true,
    configurable: false
  });
};

// packages/ag-charts-community/src/scale/scaleUtil.ts
function visibleTickRange(ticks, reversed, visibleRange) {
  if (visibleRange == null || visibleRange[0] === 0 && visibleRange[1] === 1)
    return;
  const vt0 = clamp(0, Math.floor(visibleRange[0] * ticks.length), ticks.length);
  const vt1 = clamp(0, Math.ceil(visibleRange[1] * ticks.length), ticks.length);
  const t0 = reversed ? ticks.length - vt1 : vt0;
  const t1 = reversed ? ticks.length - vt0 : vt1;
  return [t0, t1];
}
function visibleTickSliceIndices(ticks, reversed, visibleRange) {
  return visibleTickRange(ticks, reversed, visibleRange) ?? [0, ticks.length];
}
function filterVisibleTicks(ticks, reversed, visibleRange) {
  const tickRange = visibleTickRange(ticks, reversed, visibleRange);
  if (tickRange == null)
    return { ticks, count: ticks.length, firstTickIndex: 0 };
  const [t0, t1] = tickRange;
  return {
    ticks: ticks.slice(t0, t1),
    count: ticks.length,
    firstTickIndex: t0
  };
}
function unpackDomainMinMax(domain) {
  const min = readIntegratedWrappedValue(domain.at(0));
  const max = readIntegratedWrappedValue(domain.at(-1));
  return min != void 0 && max != void 0 ? [min, max] : [void 0, void 0];
}

// packages/ag-charts-community/src/scale/colorScale.ts
var convertColorStringToOklcha = (v) => {
  const color2 = Color.fromString(v);
  const [l, c, h] = Color.RGBtoOKLCH(color2.r, color2.g, color2.b);
  return { l, c, h, a: color2.a };
};
var delta = 1e-6;
var isAchromatic = (x) => x.c < delta || x.l < delta || x.l > 1 - delta;
var interpolateOklch = (x, y, d) => {
  d = clamp(0, d, 1);
  let h;
  if (isAchromatic(x)) {
    h = y.h;
  } else if (isAchromatic(y)) {
    h = x.h;
  } else {
    const xH = x.h;
    let yH = y.h;
    const deltaH = y.h - x.h;
    if (deltaH > 180) {
      yH -= 360;
    } else if (deltaH < -180) {
      yH += 360;
    }
    h = xH * (1 - d) + yH * d;
  }
  const c = x.c * (1 - d) + y.c * d;
  const l = x.l * (1 - d) + y.l * d;
  const a = x.a * (1 - d) + y.a * d;
  return Color.fromOKLCH(l, c, h, a);
};
var ColorScale = class extends AbstractScale {
  constructor() {
    super(...arguments);
    this.type = "color";
    this.defaultTickCount = 0;
    this.invalid = true;
    this.domain = [0, 1];
    this.range = ["red", "blue"];
    this.parsedRange = this.range.map(convertColorStringToOklcha);
  }
  update() {
    const { domain, range: range3 } = this;
    if (domain.length < 2) {
      logger_exports.warnOnce("`colorDomain` should have at least 2 values.");
      if (domain.length === 0) {
        domain.push(0, 1);
      } else if (domain.length === 1) {
        domain.push(domain[0] + 1);
      }
    }
    for (let i = 1; i < domain.length; i++) {
      const a = domain[i - 1];
      const b = domain[i];
      if (a > b) {
        logger_exports.warnOnce("`colorDomain` values should be supplied in ascending order.");
        domain.sort((a2, b2) => a2 - b2);
        break;
      }
    }
    if (range3.length < domain.length) {
      for (let i = range3.length; i < domain.length; i++) {
        range3.push(range3.length > 0 ? range3[0] : "black");
      }
    }
    this.parsedRange = this.range.map(convertColorStringToOklcha);
  }
  normalizeDomains(...domains) {
    return { domain: domains.map((d) => d.domain).flat(), animatable: true };
  }
  toDomain() {
    return;
  }
  convert(x) {
    this.refresh();
    const { domain, range: range3, parsedRange } = this;
    const d0 = domain[0];
    const d1 = domain.at(-1);
    const r0 = range3[0];
    const r1 = range3.at(-1);
    if (x <= d0) {
      return r0;
    }
    if (x >= d1) {
      return r1;
    }
    let index;
    let q;
    if (domain.length === 2) {
      const t = (x - d0) / (d1 - d0);
      const step = 1 / (range3.length - 1);
      index = range3.length <= 2 ? 0 : Math.min(Math.floor(t * (range3.length - 1)), range3.length - 2);
      q = (t - index * step) / step;
    } else {
      for (index = 0; index < domain.length - 2; index++) {
        if (x < domain[index + 1]) {
          break;
        }
      }
      const a = domain[index];
      const b = domain[index + 1];
      q = (x - a) / (b - a);
    }
    const c0 = parsedRange[index];
    const c1 = parsedRange[index + 1];
    return interpolateOklch(c0, c1, q).toRgbaString();
  }
  invert() {
    return;
  }
  getDomainMinMax() {
    return unpackDomainMinMax(this.domain);
  }
  refresh() {
    if (!this.invalid)
      return;
    this.invalid = false;
    this.update();
    if (this.invalid) {
      logger_exports.warnOnce("Expected update to not invalidate scale");
    }
  }
};
__decorateClass([
  Invalidating
], ColorScale.prototype, "domain", 2);
__decorateClass([
  Invalidating
], ColorScale.prototype, "range", 2);

// packages/ag-charts-community/src/scene/gradient/gradient.ts
var Gradient = class {
  constructor(colorSpace, stops = [], bbox) {
    this.colorSpace = colorSpace;
    this.stops = stops;
    this.bbox = bbox;
    this._cache = void 0;
  }
  createGradient(ctx, shapeBbox, params) {
    const bbox = this.bbox ?? shapeBbox;
    if (!bbox.isFinite()) {
      return;
    }
    if (this._cache?.ctx === ctx && this._cache.bbox.equals(bbox)) {
      return this._cache.gradient;
    }
    const { stops, colorSpace } = this;
    if (stops.length === 0)
      return;
    if (stops.length === 1)
      return stops[0].color;
    let gradient2 = this.createCanvasGradient(ctx, bbox, params);
    if (gradient2 == null)
      return;
    const isOkLch = colorSpace === "oklch";
    const step = 0.05;
    let c0 = stops[0];
    gradient2.addColorStop(c0.stop, c0.color);
    for (let i = 1; i < stops.length; i += 1) {
      const c1 = stops[i];
      if (isOkLch) {
        const scale2 = new ColorScale();
        scale2.domain = [c0.stop, c1.stop];
        scale2.range = [c0.color, c1.color];
        for (let stop = c0.stop + step; stop < c1.stop; stop += step) {
          gradient2.addColorStop(stop, scale2.convert(stop) ?? "transparent");
        }
      }
      gradient2.addColorStop(c1.stop, c1.color);
      c0 = c1;
    }
    if ("createPattern" in gradient2) {
      gradient2 = gradient2.createPattern();
    }
    this._cache = { ctx, bbox, gradient: gradient2 };
    return gradient2;
  }
  toSvg(shapeBbox) {
    const bbox = this.bbox ?? shapeBbox;
    const gradient2 = this.createSvgGradient(bbox);
    for (const { stop: offset, color: color2 } of this.stops) {
      const stop = createSvgElement("stop");
      stop.setAttribute("offset", `${offset}`);
      stop.setAttribute("stop-color", `${color2}`);
      gradient2.appendChild(stop);
    }
    return gradient2;
  }
};

// packages/ag-charts-community/src/scene/gradient/conicGradient.ts
var ConicGradient = class extends Gradient {
  constructor(colorSpace, stops, angle2 = 0, bbox) {
    super(colorSpace, stops, bbox);
    this.angle = angle2;
  }
  createCanvasGradient(ctx, bbox, params) {
    const angleOffset = -90;
    const { angle: angle2 } = this;
    const radians = normalizeAngle360FromDegrees(angle2 + angleOffset);
    const cx = params?.centerX ?? bbox.x + bbox.width * 0.5;
    const cy = params?.centerY ?? bbox.y + bbox.height * 0.5;
    return ctx.createConicGradient(radians, cx, cy);
  }
  createSvgGradient(_bbox) {
    return createSvgElement("linearGradient");
  }
};

// packages/ag-charts-community/src/scene/gradient/linearGradient.ts
var LinearGradient = class extends Gradient {
  constructor(colorSpace, stops, angle2 = 0, bbox) {
    super(colorSpace, stops, bbox);
    this.angle = angle2;
  }
  getGradientPoints(bbox) {
    const angleOffset = 90;
    const { angle: angle2 } = this;
    const radians = normalizeAngle360FromDegrees(angle2 + angleOffset);
    const cos = Math.cos(radians);
    const sin = Math.sin(radians);
    const w = bbox.width;
    const h = bbox.height;
    const cx = bbox.x + w * 0.5;
    const cy = bbox.y + h * 0.5;
    const diagonal = Math.hypot(h, w) / 2;
    const diagonalAngle = Math.atan2(h, w);
    let quarteredAngle;
    if (radians < Math.PI / 2) {
      quarteredAngle = radians;
    } else if (radians < Math.PI) {
      quarteredAngle = Math.PI - radians;
    } else if (radians < 1.5 * Math.PI) {
      quarteredAngle = radians - Math.PI;
    } else {
      quarteredAngle = 2 * Math.PI - radians;
    }
    const l = diagonal * Math.abs(Math.cos(quarteredAngle - diagonalAngle));
    return { x0: cx + cos * l, y0: cy + sin * l, x1: cx - cos * l, y1: cy - sin * l };
  }
  createCanvasGradient(ctx, bbox) {
    const { x0, y0, x1, y1 } = this.getGradientPoints(bbox);
    if (Number.isNaN(x0) || Number.isNaN(y0) || Number.isNaN(x1) || Number.isNaN(y1)) {
      return void 0;
    }
    return ctx.createLinearGradient(x0, y0, x1, y1);
  }
  createSvgGradient(bbox) {
    const { x0, y0, x1, y1 } = this.getGradientPoints(bbox);
    const gradient2 = createSvgElement("linearGradient");
    gradient2.setAttribute("x1", String(x0));
    gradient2.setAttribute("y1", String(y0));
    gradient2.setAttribute("x2", String(x1));
    gradient2.setAttribute("y2", String(y1));
    gradient2.setAttribute("gradientUnits", "userSpaceOnUse");
    return gradient2;
  }
};

// packages/ag-charts-community/src/scene/gradient/radialGradient.ts
var RadialGradient = class extends Gradient {
  constructor(colorSpace, stops, bbox) {
    super(colorSpace, stops, bbox);
  }
  createCanvasGradient(ctx, bbox, params) {
    const cx = params?.centerX ?? bbox.x + bbox.width * 0.5;
    const cy = params?.centerY ?? bbox.y + bbox.height * 0.5;
    const innerRadius = params?.innerRadius ?? 0;
    const outerRadius = params?.outerRadius ?? Math.hypot(bbox.width * 0.5, bbox.height * 0.5) / Math.SQRT2;
    return ctx.createRadialGradient(cx, cy, innerRadius, cx, cy, outerRadius);
  }
  createSvgGradient(bbox) {
    const cx = bbox.x + bbox.width * 0.5;
    const cy = bbox.y + bbox.height * 0.5;
    const gradient2 = createSvgElement("radialGradient");
    gradient2.setAttribute("cx", String(cx));
    gradient2.setAttribute("cy", String(cy));
    gradient2.setAttribute("r", String(Math.hypot(bbox.width * 0.5, bbox.height * 0.5) / Math.SQRT2));
    gradient2.setAttribute("gradientUnits", "userSpaceOnUse");
    return gradient2;
  }
};

// packages/ag-charts-community/src/scene/gradient/stops.ts
var StopProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.color = "black";
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], StopProperties.prototype, "stop", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], StopProperties.prototype, "color", 2);
function stopsAreAscending(fills) {
  let currentStop;
  for (const fill of fills) {
    if (fill?.stop == null)
      continue;
    if (currentStop != null && fill.stop < currentStop) {
      return false;
    }
    currentStop = fill.stop;
  }
  return true;
}
function discreteColorStops(colorStops) {
  return colorStops.flatMap((colorStop2, i) => {
    const { stop } = colorStop2;
    const nextColor = colorStops.at(i + 1)?.color;
    return nextColor == null ? [colorStop2] : [colorStop2, { stop, color: nextColor }];
  });
}
function getDefaultColorStops(defaultColorStops, fillMode) {
  const stopOffset = fillMode === "discrete" ? 1 : 0;
  const colorStops = defaultColorStops.map(
    (color2, index, { length: length2 }) => ({
      stop: (index + stopOffset) / (length2 - 1 + stopOffset),
      color: color2
    })
  );
  return fillMode === "discrete" ? discreteColorStops(colorStops) : colorStops;
}
function getColorStops(baseFills, defaultColorStops, domain, fillMode = "continuous") {
  const fills = baseFills.map((fill) => typeof fill === "string" ? { color: fill } : fill);
  if (fills.length === 0) {
    return getDefaultColorStops(defaultColorStops, fillMode);
  } else if (!stopsAreAscending(fills)) {
    logger_exports.warnOnce(`[fills] must have the stops defined in ascending order`);
    return [];
  }
  const d0 = Math.min(...domain);
  const d1 = Math.max(...domain);
  const isDiscrete = fillMode === "discrete";
  const stops = new Float64Array(fills.length);
  let previousDefinedStopIndex = 0;
  let nextDefinedStopIndex = -1;
  for (let i = 0; i < fills.length; i += 1) {
    const colorStop2 = fills[i];
    if (i >= nextDefinedStopIndex) {
      nextDefinedStopIndex = fills.length - 1;
      for (let j = i + 1; j < fills.length; j += 1) {
        if (fills[j]?.stop != null) {
          nextDefinedStopIndex = j;
          break;
        }
      }
    }
    let stop = colorStop2?.stop;
    if (stop == null) {
      const stop0 = fills[previousDefinedStopIndex]?.stop;
      const stop1 = fills[nextDefinedStopIndex]?.stop;
      const value0 = stop0 ?? d0;
      const value1 = stop1 ?? d1;
      const stopOffset = isDiscrete && stop0 == null ? 1 : 0;
      stop = value0 + (value1 - value0) * (i - previousDefinedStopIndex + stopOffset) / (nextDefinedStopIndex - previousDefinedStopIndex + stopOffset);
    } else {
      previousDefinedStopIndex = i;
    }
    stops[i] = Math.max(0, Math.min(1, (stop - d0) / (d1 - d0)));
  }
  let lastDefinedColor = fills.find((c) => c.color != null)?.color;
  let colorScale;
  const colorStops = fills.map((fill, i) => {
    let color2 = fill?.color;
    const stop = stops[i];
    if (color2 != null) {
      lastDefinedColor = color2;
    } else if (lastDefinedColor == null) {
      if (colorScale == null) {
        colorScale = new ColorScale();
        colorScale.domain = [0, 1];
        colorScale.range = defaultColorStops;
      }
      color2 = colorScale.convert(stop);
    } else {
      color2 = lastDefinedColor;
    }
    return { stop, color: color2 };
  });
  return fillMode === "discrete" ? discreteColorStops(colorStops) : colorStops;
}

// packages/ag-charts-community/src/scene/image/image.ts
var Image = class {
  constructor(imageLoader, imageOptions) {
    this.imageLoader = imageLoader;
    this._cache = void 0;
    this.url = imageOptions.url;
    this.backgroundFill = imageOptions.backgroundFill ?? "black";
    this.backgroundFillOpacity = imageOptions.backgroundFillOpacity ?? 1;
    this.repeat = imageOptions.repeat ?? "no-repeat";
    this.width = imageOptions.width;
    this.height = imageOptions.height;
    this.fit = imageOptions.fit ?? "stretch";
    this.rotation = imageOptions.rotation ?? 0;
  }
  createCanvasImage(ctx, image, width2, height2) {
    if (!image)
      return null;
    const [renderedWidth, renderedHeight] = this.getSize(image.width, image.height, width2, height2);
    if (renderedWidth < 1 || renderedHeight < 1) {
      logger_exports.warnOnce("Image fill is too small to render, ignoring.");
      return null;
    }
    return ctx.createPattern(image, this.repeat);
  }
  getSize(imageWidth, imageHeight, width2, height2) {
    const { fit } = this;
    let dw = imageWidth;
    let dh = imageHeight;
    let scale2 = 1;
    const shapeAspectRatio = width2 / height2;
    const imageAspectRatio = imageWidth / imageHeight;
    if (fit === "stretch" || imageWidth === 0 || imageHeight === 0) {
      dw = width2;
      dh = height2;
    } else if (fit === "contain") {
      scale2 = imageAspectRatio > shapeAspectRatio ? width2 / imageWidth : height2 / imageHeight;
    } else if (fit === "cover") {
      scale2 = imageAspectRatio > shapeAspectRatio ? height2 / imageHeight : width2 / imageWidth;
    }
    return [Math.max(1, dw * scale2), Math.max(1, dh * scale2)];
  }
  setImageTransform(pattern, bbox) {
    if (typeof pattern === "string")
      return;
    const { url, rotation, width: width2, height: height2 } = this;
    const image = this.imageLoader?.loadImage(url);
    if (!image) {
      return;
    }
    const angle2 = normalizeAngle360FromDegrees(rotation);
    const cos = Math.cos(angle2);
    const sin = Math.sin(angle2);
    const [renderedWidth, renderedHeight] = this.getSize(
      image.width,
      image.height,
      width2 ?? bbox.width,
      height2 ?? bbox.height
    );
    const widthScale = renderedWidth / image.width;
    const heightScale = renderedHeight / image.height;
    const bboxCenterX = bbox.x + bbox.width / 2;
    const bboxCenterY = bbox.y + bbox.height / 2;
    const rotatedW = cos * renderedWidth - sin * renderedHeight;
    const rotatedH = sin * renderedWidth + cos * renderedHeight;
    const shapeCenterX = rotatedW / 2;
    const shapeCenterY = rotatedH / 2;
    const DOMMatrixCtor = getDOMMatrix();
    pattern?.setTransform(
      new DOMMatrixCtor([
        cos * widthScale,
        sin * heightScale,
        -sin * widthScale,
        cos * heightScale,
        bboxCenterX - shapeCenterX,
        bboxCenterY - shapeCenterY
      ])
    );
  }
  createPattern(ctx, shapeWidth, shapeHeight, node) {
    const width2 = this.width ?? shapeWidth;
    const height2 = this.height ?? shapeHeight;
    const cache = this._cache;
    if (cache?.ctx === ctx && cache.width === width2 && cache.height === height2) {
      return cache.pattern;
    }
    const image = this.imageLoader?.loadImage(this.url, node);
    const pattern = this.createCanvasImage(ctx, image, width2, height2);
    if (pattern == null)
      return;
    this._cache = { ctx, pattern, width: width2, height: height2 };
    return pattern;
  }
  toSvg(bbox, pixelRatio) {
    const { url, rotation, backgroundFill, backgroundFillOpacity } = this;
    const { x, y, width: width2, height: height2 } = bbox;
    const pattern = createSvgElement("pattern");
    pattern.setAttribute("viewBox", `0 0 ${width2} ${height2}`);
    pattern.setAttribute("x", String(x));
    pattern.setAttribute("y", String(y));
    pattern.setAttribute("width", String(width2));
    pattern.setAttribute("height", String(height2));
    pattern.setAttribute("patternUnits", "userSpaceOnUse");
    const rect2 = createSvgElement("rect");
    rect2.setAttribute("x", "0");
    rect2.setAttribute("y", "0");
    rect2.setAttribute("width", String(width2));
    rect2.setAttribute("height", String(height2));
    rect2.setAttribute("fill", backgroundFill);
    rect2.setAttribute("fill-opacity", String(backgroundFillOpacity));
    pattern.appendChild(rect2);
    const image = createSvgElement("image");
    image.setAttribute("href", url);
    image.setAttribute("x", "0");
    image.setAttribute("y", "0");
    image.setAttribute("width", String(width2));
    image.setAttribute("height", String(height2));
    image.setAttribute("preserveAspectRatio", "none");
    image.setAttribute("transform", `scale(${1 / pixelRatio}) rotate(${rotation}, ${width2 / 2}, ${height2 / 2})`);
    pattern.appendChild(image);
    return pattern;
  }
};

// packages/ag-charts-community/src/util/svg.ts
var commandEx = /^[\t\n\f\r ]*([achlmqstvz])[\t\n\f\r ]*/i;
var coordinateEx = /^[+-]?((\d*\.\d+)|(\d+\.)|(\d+))(e[+-]?\d+)?/i;
var commaEx = /[\t\n\f\r ]*,?[\t\n\f\r ]*/;
var flagEx = /^[01]/;
var pathParams = {
  z: [],
  h: [coordinateEx],
  v: [coordinateEx],
  m: [coordinateEx, coordinateEx],
  l: [coordinateEx, coordinateEx],
  t: [coordinateEx, coordinateEx],
  s: [coordinateEx, coordinateEx, coordinateEx, coordinateEx],
  q: [coordinateEx, coordinateEx, coordinateEx, coordinateEx],
  c: [coordinateEx, coordinateEx, coordinateEx, coordinateEx, coordinateEx, coordinateEx],
  a: [coordinateEx, coordinateEx, coordinateEx, flagEx, flagEx, coordinateEx, coordinateEx]
};
function parseSvg(d) {
  if (!d)
    return;
  const segments = [];
  let i = 0;
  let currentCommand;
  while (i < d.length) {
    const commandMatch = commandEx.exec(d.slice(i));
    let command;
    if (commandMatch == null) {
      if (!currentCommand) {
        logger_exports.warnOnce(`Invalid SVG path, error at index ${i}: Missing command.`);
        return;
      }
      command = currentCommand;
    } else {
      command = commandMatch[1];
      i += commandMatch[0].length;
    }
    const segment = parseSegment(command, d, i);
    if (!segment)
      return;
    i = segment[0];
    currentCommand = command;
    segments.push(segment[1]);
  }
  return segments;
}
function parseSegment(command, d, index) {
  const params = pathParams[command.toLocaleLowerCase()];
  const pathSeg = { command, params: [] };
  for (const regex of params) {
    const segment = d.slice(index);
    const match = regex.exec(segment);
    if (match != null) {
      pathSeg.params.push(Number.parseFloat(match[0]));
      index += match[0].length;
      const next = commaEx.exec(segment.slice(match[0].length));
      if (next != null) {
        index += next[0].length;
      }
    } else if (pathSeg.params.length === 1) {
      return [index, pathSeg];
    } else {
      logger_exports.warnOnce(
        `Invalid SVG path, error at index ${index}: No path segment parameters for command [${command}]`
      );
      return;
    }
  }
  return [index, pathSeg];
}

// packages/ag-charts-community/src/scene/polyRoots.ts
function linearRoot(a, b) {
  const t = -b / a;
  return a !== 0 && t >= 0 && t <= 1 ? [t] : [];
}
function quadraticRoots(a, b, c, delta5 = 1e-6) {
  if (Math.abs(a) < delta5) {
    return linearRoot(b, c);
  }
  const D = b * b - 4 * a * c;
  const roots = [];
  if (Math.abs(D) < delta5) {
    const t = -b / (2 * a);
    if (t >= 0 && t <= 1) {
      roots.push(t);
    }
  } else if (D > 0) {
    const rD = Math.sqrt(D);
    const t1 = (-b - rD) / (2 * a);
    const t2 = (-b + rD) / (2 * a);
    if (t1 >= 0 && t1 <= 1) {
      roots.push(t1);
    }
    if (t2 >= 0 && t2 <= 1) {
      roots.push(t2);
    }
  }
  return roots;
}
function cubicRoots(a, b, c, d, delta5 = 1e-6) {
  if (Math.abs(a) < delta5) {
    return quadraticRoots(b, c, d, delta5);
  }
  const A = b / a;
  const B = c / a;
  const C2 = d / a;
  const Q = (3 * B - A * A) / 9;
  const R = (9 * A * B - 27 * C2 - 2 * A * A * A) / 54;
  const D = Q * Q * Q + R * R;
  const third = 1 / 3;
  const roots = [];
  if (D >= 0) {
    const rD = Math.sqrt(D);
    const S = Math.sign(R + rD) * Math.pow(Math.abs(R + rD), third);
    const T = Math.sign(R - rD) * Math.pow(Math.abs(R - rD), third);
    const Im = Math.abs(Math.sqrt(3) * (S - T) / 2);
    const t = -third * A + (S + T);
    if (t >= 0 && t <= 1) {
      roots.push(t);
    }
    if (Math.abs(Im) < delta5) {
      const t2 = -third * A - (S + T) / 2;
      if (t2 >= 0 && t2 <= 1) {
        roots.push(t2);
      }
    }
  } else {
    const theta = Math.acos(R / Math.sqrt(-Q * Q * Q));
    const thirdA = third * A;
    const twoSqrtQ = 2 * Math.sqrt(-Q);
    const t1 = twoSqrtQ * Math.cos(third * theta) - thirdA;
    const t2 = twoSqrtQ * Math.cos(third * (theta + 2 * Math.PI)) - thirdA;
    const t3 = twoSqrtQ * Math.cos(third * (theta + 4 * Math.PI)) - thirdA;
    if (t1 >= 0 && t1 <= 1) {
      roots.push(t1);
    }
    if (t2 >= 0 && t2 <= 1) {
      roots.push(t2);
    }
    if (t3 >= 0 && t3 <= 1) {
      roots.push(t3);
    }
  }
  return roots;
}

// packages/ag-charts-community/src/scene/intersection.ts
function segmentIntersection(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2) {
  const d = (ax2 - ax1) * (by2 - by1) - (ay2 - ay1) * (bx2 - bx1);
  if (d === 0) {
    return 0;
  }
  const ua = ((bx2 - bx1) * (ay1 - by1) - (ax1 - bx1) * (by2 - by1)) / d;
  const ub = ((ax2 - ax1) * (ay1 - by1) - (ay2 - ay1) * (ax1 - bx1)) / d;
  if (ua >= 0 && ua <= 1 && ub >= 0 && ub <= 1) {
    return 1;
  }
  return 0;
}
function cubicSegmentIntersections(px1, py1, px2, py2, px3, py3, px4, py4, x1, y1, x2, y2) {
  let intersections = 0;
  const A = y1 - y2;
  const B = x2 - x1;
  const C2 = x1 * (y2 - y1) - y1 * (x2 - x1);
  const bx = bezierCoefficients(px1, px2, px3, px4);
  const by = bezierCoefficients(py1, py2, py3, py4);
  const a = A * bx[0] + B * by[0];
  const b = A * bx[1] + B * by[1];
  const c = A * bx[2] + B * by[2];
  const d = A * bx[3] + B * by[3] + C2;
  const roots = cubicRoots(a, b, c, d);
  for (const t of roots) {
    const tt = t * t;
    const ttt = t * tt;
    const x = bx[0] * ttt + bx[1] * tt + bx[2] * t + bx[3];
    const y = by[0] * ttt + by[1] * tt + by[2] * t + by[3];
    let s;
    if (x1 === x2) {
      s = (y - y1) / (y2 - y1);
    } else {
      s = (x - x1) / (x2 - x1);
    }
    if (s >= 0 && s <= 1) {
      intersections++;
    }
  }
  return intersections;
}
function bezierCoefficients(P1, P2, P3, P4) {
  return [
    // Bézier expressed as matrix operations:
    //                 |-1  3 -3  1| |P1|
    //   [t^3 t^2 t 1] | 3 -6  3  0| |P2|
    //                 |-3  3  0  0| |P3|
    //                 | 1  0  0  0| |P4|
    -P1 + 3 * P2 - 3 * P3 + P4,
    3 * P1 - 6 * P2 + 3 * P3,
    -3 * P1 + 3 * P2,
    P1
  ];
}

// packages/ag-charts-community/src/scene/extendedPath2D.ts
var ExtendedPath2D = class {
  constructor() {
    this.previousCommands = [];
    this.previousParams = [];
    this.previousClosedPath = false;
    this.commands = [];
    this.params = [];
    this.commandsLength = 0;
    this.paramsLength = 0;
    this.cx = Number.NaN;
    this.cy = Number.NaN;
    this.sx = Number.NaN;
    this.sy = Number.NaN;
    this.openedPath = false;
    this.closedPath = false;
    const Path2DCtor = getPath2D();
    this.path2d = new Path2DCtor();
  }
  isEmpty() {
    return this.commandsLength === 0;
  }
  isDirty() {
    return this.closedPath !== this.previousClosedPath || this.previousCommands.length !== this.commandsLength || this.previousParams.length !== this.paramsLength || this.previousCommands.toString() !== this.commands.slice(0, this.commandsLength).toString() || this.previousParams.toString() !== this.params.slice(0, this.paramsLength).toString();
  }
  getPath2D() {
    return this.path2d;
  }
  moveTo(x, y) {
    this.openedPath = true;
    this.sx = x;
    this.sy = y;
    this.cx = x;
    this.cy = y;
    this.path2d.moveTo(x, y);
    this.commands[this.commandsLength++] = 0 /* Move */;
    this.params[this.paramsLength++] = x;
    this.params[this.paramsLength++] = y;
  }
  lineTo(x, y) {
    if (this.openedPath) {
      this.cx = x;
      this.cy = y;
      this.path2d.lineTo(x, y);
      this.commands[this.commandsLength++] = 1 /* Line */;
      this.params[this.paramsLength++] = x;
      this.params[this.paramsLength++] = y;
    } else {
      this.moveTo(x, y);
    }
  }
  cubicCurveTo(cx1, cy1, cx2, cy2, x, y) {
    if (!this.openedPath) {
      this.moveTo(cx1, cy1);
    }
    this.path2d.bezierCurveTo(cx1, cy1, cx2, cy2, x, y);
    this.commands[this.commandsLength++] = 2 /* Curve */;
    this.params[this.paramsLength++] = cx1;
    this.params[this.paramsLength++] = cy1;
    this.params[this.paramsLength++] = cx2;
    this.params[this.paramsLength++] = cy2;
    this.params[this.paramsLength++] = x;
    this.params[this.paramsLength++] = y;
  }
  closePath() {
    if (this.openedPath) {
      this.cx = this.sx;
      this.cy = this.sy;
      this.sx = Number.NaN;
      this.sy = Number.NaN;
      this.path2d.closePath();
      this.commands[this.commandsLength++] = 3 /* ClosePath */;
      this.openedPath = false;
      this.closedPath = true;
    }
  }
  rect(x, y, width2, height2) {
    this.moveTo(x, y);
    this.lineTo(x + width2, y);
    this.lineTo(x + width2, y + height2);
    this.lineTo(x, y + height2);
    this.closePath();
  }
  roundRect(x, y, width2, height2, radii) {
    radii = Math.min(radii, width2 / 2, height2 / 2);
    this.moveTo(x, y + radii);
    this.arc(x + radii, y + radii, radii, Math.PI, 1.5 * Math.PI);
    this.lineTo(x + radii, y);
    this.lineTo(x + width2 - radii, y);
    this.arc(x + width2 - radii, y + radii, radii, 1.5 * Math.PI, 2 * Math.PI);
    this.lineTo(x + width2, y + radii);
    this.lineTo(x + width2, y + height2 - radii);
    this.arc(x + width2 - radii, y + height2 - radii, radii, 0, Math.PI / 2);
    this.lineTo(x + width2 - radii, y + height2);
    this.lineTo(x + radii, y + height2);
    this.arc(x + +radii, y + height2 - radii, radii, Math.PI / 2, Math.PI);
    this.lineTo(x, y + height2 - radii);
    this.closePath();
  }
  ellipse(cx, cy, rx, ry, rotation, sAngle, eAngle, counterClockwise = false) {
    const r = rx;
    const scaleY = ry / rx;
    const mxx = Math.cos(rotation);
    const myx = Math.sin(rotation);
    const mxy = -scaleY * myx;
    const myy = scaleY * mxx;
    const x0 = r * Math.cos(sAngle);
    const y0 = r * Math.sin(sAngle);
    const sx = cx + mxx * x0 + mxy * y0;
    const sy = cy + myx * x0 + myy * y0;
    const distanceSquared2 = (sx - this.cx) ** 2 + (sy - this.cy) ** 2;
    if (!this.openedPath) {
      this.moveTo(sx, sy);
    } else if (distanceSquared2 > 1e-6) {
      this.lineTo(sx, sy);
    }
    let sweep = counterClockwise ? -normalizeAngle360(sAngle - eAngle) : normalizeAngle360(eAngle - sAngle);
    if (Math.abs(Math.abs(eAngle - sAngle) - 2 * Math.PI) < 1e-6 && sweep < 2 * Math.PI) {
      sweep += 2 * Math.PI * (counterClockwise ? -1 : 1);
    }
    const arcSections = Math.max(Math.ceil(Math.abs(sweep) / (Math.PI / 2)), 1);
    const step = sweep / arcSections;
    const h = 4 / 3 * Math.tan(step / 4);
    for (let i = 0; i < arcSections; i += 1) {
      const a0 = sAngle + step * (i + 0);
      const a1 = sAngle + step * (i + 1);
      const rSinStart = r * Math.sin(a0);
      const rCosStart = r * Math.cos(a0);
      const rSinEnd = r * Math.sin(a1);
      const rCosEnd = r * Math.cos(a1);
      const cp1x = rCosStart - h * rSinStart;
      const cp1y = rSinStart + h * rCosStart;
      const cp2x = rCosEnd + h * rSinEnd;
      const cp2y = rSinEnd - h * rCosEnd;
      const cp3x = rCosEnd;
      const cp3y = rSinEnd;
      this.cubicCurveTo(
        cx + mxx * cp1x + mxy * cp1y,
        cy + myx * cp1x + myy * cp1y,
        cx + mxx * cp2x + mxy * cp2y,
        cy + myx * cp2x + myy * cp2y,
        cx + mxx * cp3x + mxy * cp3y,
        cy + myx * cp3x + myy * cp3y
      );
    }
  }
  arc(x, y, r, sAngle, eAngle, counterClockwise) {
    this.ellipse(x, y, r, r, 0, sAngle, eAngle, counterClockwise);
  }
  appendSvg(svg) {
    const parts = parseSvg(svg);
    if (parts == null)
      return false;
    let sx = 0;
    let sy = 0;
    let cx;
    let cy;
    let cpx = 0;
    let cpy = 0;
    for (const { command, params } of parts) {
      cx ?? (cx = params[0]);
      cy ?? (cy = params[1]);
      const relative = command === command.toLowerCase();
      const dx2 = relative ? cx : 0;
      const dy2 = relative ? cy : 0;
      switch (command.toLowerCase()) {
        case "m":
          this.moveTo(dx2 + params[0], dy2 + params[1]);
          cx = dx2 + params[0];
          cy = dy2 + params[1];
          sx = cx;
          sy = cy;
          break;
        case "c":
          this.cubicCurveTo(
            dx2 + params[0],
            dy2 + params[1],
            dx2 + params[2],
            dy2 + params[3],
            dx2 + params[4],
            dy2 + params[5]
          );
          cpx = dx2 + params[2];
          cpy = dy2 + params[3];
          cx = dx2 + params[4];
          cy = dy2 + params[5];
          break;
        case "s":
          this.cubicCurveTo(
            cx + cx - cpx,
            cy + cy - cpy,
            dx2 + params[0],
            dy2 + params[1],
            dx2 + params[2],
            dy2 + params[3]
          );
          cpx = dx2 + params[0];
          cpy = dy2 + params[1];
          cx = dx2 + params[2];
          cy = dy2 + params[3];
          break;
        case "q":
          this.cubicCurveTo(
            (dx2 + 2 * params[0]) / 3,
            (dy2 + 2 * params[1]) / 3,
            (2 * params[0] + params[2]) / 3,
            (2 * params[1] + params[3]) / 3,
            params[2],
            params[3]
          );
          cpx = params[0];
          cpy = params[1];
          cx = params[2];
          cy = params[3];
          break;
        case "t":
          this.cubicCurveTo(
            (cx + 2 * (cx + cx - cpx)) / 3,
            (cy + 2 * (cy + cy - cpy)) / 3,
            (2 * (cx + cx - cpx) + params[0]) / 3,
            (2 * (cy + cy - cpy) + params[1]) / 3,
            params[0],
            params[1]
          );
          cpx = cx + cx - cpx;
          cpy = cy + cy - cpy;
          cx = params[0];
          cy = params[1];
          break;
        case "a":
          this.svgEllipse(
            cx,
            cy,
            params[0],
            params[1],
            params[2] * Math.PI / 180,
            params[3],
            params[4],
            dx2 + params[5],
            dy2 + params[6]
          );
          cx = dx2 + params[5];
          cy = dy2 + params[6];
          break;
        case "h":
          this.lineTo(dx2 + params[0], cy);
          cx = dx2 + params[0];
          break;
        case "l":
          this.lineTo(dx2 + params[0], dy2 + params[1]);
          cx = dx2 + params[0];
          cy = dy2 + params[1];
          break;
        case "v":
          this.lineTo(cx, dy2 + params[0]);
          cy = dy2 + params[0];
          break;
        case "z":
          this.closePath();
          cx = sx;
          cy = sy;
          break;
        default:
          throw new Error(`Could not translate command '${command}' with '${params.join(" ")}'`);
      }
    }
    return true;
  }
  svgEllipse(x1, y1, rx, ry, rotation, fA, fS, x2, y2) {
    rx = Math.abs(rx);
    ry = Math.abs(ry);
    const dx2 = (x1 - x2) / 2;
    const dy2 = (y1 - y2) / 2;
    const sin = Math.sin(rotation);
    const cos = Math.cos(rotation);
    const rotX = cos * dx2 + sin * dy2;
    const rotY = -sin * dx2 + cos * dy2;
    const normX = rotX / rx;
    const normY = rotY / ry;
    let scale2 = normX * normX + normY * normY;
    let cx = (x1 + x2) / 2;
    let cy = (y1 + y2) / 2;
    let cpx = 0;
    let cpy = 0;
    if (scale2 >= 1) {
      scale2 = Math.sqrt(scale2);
      rx *= scale2;
      ry *= scale2;
    } else {
      scale2 = Math.sqrt(1 / scale2 - 1);
      if (fA === fS)
        scale2 = -scale2;
      cpx = scale2 * rx * normY;
      cpy = -scale2 * ry * normX;
      cx += cos * cpx - sin * cpy;
      cy += sin * cpx + cos * cpy;
    }
    const sAngle = Math.atan2((rotY - cpy) / ry, (rotX - cpx) / rx);
    const deltaTheta = Math.atan2((-rotY - cpy) / ry, (-rotX - cpx) / rx) - sAngle;
    const eAngle = sAngle + deltaTheta;
    const counterClockwise = !!(1 - fS);
    this.ellipse(cx, cy, rx, ry, rotation, sAngle, eAngle, counterClockwise);
  }
  clear(trackChanges) {
    if (trackChanges) {
      this.previousCommands = this.commands.slice(0, this.commandsLength);
      this.previousParams = this.params.slice(0, this.paramsLength);
      this.previousClosedPath = this.closedPath;
      this.commands = [];
      this.params = [];
      this.commandsLength = 0;
      this.paramsLength = 0;
    } else {
      this.commandsLength = 0;
      this.paramsLength = 0;
    }
    const Path2DCtor = getPath2D();
    this.path2d = new Path2DCtor();
    this.openedPath = false;
    this.closedPath = false;
  }
  isPointInPath(x, y) {
    const commands = this.commands;
    const params = this.params;
    const cn = this.commandsLength;
    const ox = -1e4;
    const oy = -1e4;
    let sx = Number.NaN;
    let sy = Number.NaN;
    let px = 0;
    let py = 0;
    let intersectionCount = 0;
    for (let ci = 0, pi = 0; ci < cn; ci++) {
      switch (commands[ci]) {
        case 0 /* Move */:
          intersectionCount += segmentIntersection(sx, sy, px, py, ox, oy, x, y);
          px = params[pi++];
          sx = px;
          py = params[pi++];
          sy = py;
          break;
        case 1 /* Line */:
          intersectionCount += segmentIntersection(px, py, params[pi++], params[pi++], ox, oy, x, y);
          px = params[pi - 2];
          py = params[pi - 1];
          break;
        case 2 /* Curve */:
          intersectionCount += cubicSegmentIntersections(
            px,
            py,
            params[pi++],
            params[pi++],
            params[pi++],
            params[pi++],
            params[pi++],
            params[pi++],
            ox,
            oy,
            x,
            y
          );
          px = params[pi - 2];
          py = params[pi - 1];
          break;
        case 3 /* ClosePath */:
          intersectionCount += segmentIntersection(sx, sy, px, py, ox, oy, x, y);
          break;
      }
    }
    return intersectionCount % 2 === 1;
  }
  distanceSquared(x, y) {
    let best = Infinity;
    const commands = this.commands;
    const params = this.params;
    const cn = this.commandsLength;
    let sx = Number.NaN;
    let sy = Number.NaN;
    let cx = 0;
    let cy = 0;
    for (let ci = 0, pi = 0; ci < cn; ci++) {
      switch (commands[ci]) {
        case 0 /* Move */:
          cx = sx = params[pi++];
          cy = sy = params[pi++];
          break;
        case 1 /* Line */: {
          const x0 = cx;
          const y0 = cy;
          cx = params[pi++];
          cy = params[pi++];
          best = lineDistanceSquared(x, y, x0, y0, cx, cy, best);
          break;
        }
        case 2 /* Curve */: {
          const cp0x = cx;
          const cp0y = cy;
          const cp1x = params[pi++];
          const cp1y = params[pi++];
          const cp2x = params[pi++];
          const cp2y = params[pi++];
          cx = params[pi++];
          cy = params[pi++];
          best = bezier2DDistance(cp0x, cp0y, cp1x, cp1y, cp2x, cp2y, cx, cy, x, y) ** 2;
          break;
        }
        case 3 /* ClosePath */:
          best = lineDistanceSquared(x, y, cx, cy, sx, sy, best);
          break;
      }
    }
    return best;
  }
  // https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/d
  toSVG(transform = (x, y) => ({ x, y })) {
    const buffer = [];
    const { commands, params } = this;
    const addCommand = (command, count) => {
      buffer.push(command);
      for (let i = 0; i < count; i += 2) {
        const { x, y } = transform(params[pi++], params[pi++]);
        buffer.push(x, y);
      }
    };
    let pi = 0;
    for (let ci = 0; ci < this.commandsLength; ci++) {
      const command = commands[ci];
      switch (command) {
        case 0 /* Move */:
          addCommand("M", 2);
          break;
        case 1 /* Line */:
          addCommand("L", 2);
          break;
        case 2 /* Curve */:
          addCommand("C", 6);
          break;
        case 3 /* ClosePath */:
          addCommand("Z", 0);
          break;
      }
    }
    return buffer.join(" ");
  }
  computeBBox() {
    const { commands, params } = this;
    let [top, left, right, bot] = [Infinity, Infinity, -Infinity, -Infinity];
    let [cx, cy] = [Number.NaN, Number.NaN];
    let [sx, sy] = [Number.NaN, Number.NaN];
    const joinPoint = (x, y) => {
      top = Math.min(y, top);
      left = Math.min(x, left);
      right = Math.max(x, right);
      bot = Math.max(y, bot);
      cx = x;
      cy = y;
    };
    let pi = 0;
    for (let ci = 0; ci < this.commandsLength; ci++) {
      const command = commands[ci];
      switch (command) {
        case 0 /* Move */:
          joinPoint(params[pi++], params[pi++]);
          sx = cx;
          sy = cy;
          break;
        case 1 /* Line */:
          joinPoint(params[pi++], params[pi++]);
          break;
        case 2 /* Curve */: {
          const cp0x = cx;
          const cp0y = cy;
          const cp1x = params[pi++];
          const cp1y = params[pi++];
          const cp2x = params[pi++];
          const cp2y = params[pi++];
          const cp3x = params[pi++];
          const cp3y = params[pi++];
          const ts = bezier2DExtrema(cp0x, cp0y, cp1x, cp1y, cp2x, cp2y, cp3x, cp3y);
          for (const t of ts) {
            const px = evaluateBezier(cp0x, cp1x, cp2x, cp3x, t);
            const py = evaluateBezier(cp0y, cp1y, cp2y, cp3y, t);
            joinPoint(px, py);
          }
          joinPoint(cp3x, cp3y);
          break;
        }
        case 3 /* ClosePath */:
          joinPoint(sx, sy);
          sx = Number.NaN;
          sy = Number.NaN;
          break;
      }
    }
    return new BBox(left, top, right - left, bot - top);
  }
};

// packages/ag-charts-community/src/scene/util/pixel.ts
function align(pixelRatio, start2, length2) {
  const alignedStart = Math.round(start2 * pixelRatio) / pixelRatio;
  if (length2 == null) {
    return alignedStart;
  } else if (length2 === 0) {
    return 0;
  } else if (length2 < 1) {
    return Math.ceil(length2 * pixelRatio) / pixelRatio;
  }
  return Math.round((length2 + start2) * pixelRatio) / pixelRatio - alignedStart;
}
function alignBefore(pixelRatio, start2) {
  return Math.floor(start2 * pixelRatio) / pixelRatio;
}

// packages/ag-charts-community/src/scene/pattern/patterns.ts
function drawPatternUnitPolygon(path, params, moves) {
  const { width: width2, height: height2, padding: padding2, strokeWidth } = params;
  const x0 = width2 / 2;
  const y0 = height2 / 2;
  const w = Math.max(1, width2 - padding2 - strokeWidth / 2);
  const h = Math.max(1, height2 - padding2 - strokeWidth / 2);
  let didMove = false;
  for (const [dx2, dy2] of moves) {
    const x = x0 + (dx2 - 0.5) * w;
    const y = y0 + (dy2 - 0.5) * h;
    if (didMove) {
      path.lineTo(x, y);
    } else {
      path.moveTo(x, y);
    }
    didMove = true;
  }
  path.closePath();
}
var PATTERNS = {
  circles(path, { width: width2, strokeWidth, padding: padding2 }) {
    const c = width2 / 2;
    const r = Math.max(1, c - padding2 - strokeWidth / 2);
    path.arc(c, c, r, 0, Math.PI * 2);
  },
  squares(path, { width: width2, height: height2, pixelRatio, padding: padding2, strokeWidth }) {
    const offset = padding2 + strokeWidth / 2;
    path.moveTo(align(pixelRatio, offset), align(pixelRatio, offset));
    path.lineTo(align(pixelRatio, width2 - offset), align(pixelRatio, offset));
    path.lineTo(align(pixelRatio, width2 - offset), align(pixelRatio, height2 - offset));
    path.lineTo(align(pixelRatio, offset), align(pixelRatio, height2 - offset));
    path.closePath();
  },
  triangles(path, params) {
    drawPatternUnitPolygon(path, params, [
      [0.5, 0],
      [1, 1],
      [0, 1]
    ]);
  },
  diamonds(path, params) {
    drawPatternUnitPolygon(path, params, [
      [0.5, 0],
      [1, 0.5],
      [0.5, 1],
      [0, 0.5]
    ]);
  },
  stars(path, { width: width2, height: height2, padding: padding2 }) {
    const spikes = 5;
    const outerRadius = Math.max(1, (width2 - padding2) / 2);
    const innerRadius = outerRadius / 2;
    const rotation = Math.PI / 2;
    for (let i = 0; i < spikes * 2; i++) {
      const radius = i % 2 === 0 ? outerRadius : innerRadius;
      const angle2 = i * Math.PI / spikes - rotation;
      const xCoordinate = width2 / 2 + Math.cos(angle2) * radius;
      const yCoordinate = height2 / 2 + Math.sin(angle2) * radius;
      path.lineTo(xCoordinate, yCoordinate);
    }
    path.closePath();
  },
  hearts(path, { width: width2, height: height2, padding: padding2 }) {
    const r = Math.max(1, width2 / 4 - padding2 / 2);
    const x = width2 / 2;
    const y = height2 / 2 + r / 2;
    path.arc(x - r, y - r, r, toRadians(130), toRadians(330));
    path.arc(x + r, y - r, r, toRadians(220), toRadians(50));
    path.lineTo(x, y + r);
    path.closePath();
  },
  crosses(path, params) {
    drawPatternUnitPolygon(path, params, [
      [0.25, 0],
      [0.5, 0.25],
      [0.75, 0],
      [1, 0.25],
      [0.75, 0.5],
      [1, 0.75],
      [0.75, 1],
      [0.5, 0.75],
      [0.25, 1],
      [0, 0.75],
      [0.25, 0.5],
      [0, 0.25]
    ]);
  },
  "vertical-lines"(path, { width: width2, height: height2, pixelRatio, strokeWidth }) {
    const x = align(pixelRatio, width2 / 2) - strokeWidth % 2 / 2;
    path.moveTo(x, 0);
    path.lineTo(x, height2);
  },
  "horizontal-lines"(path, { width: width2, height: height2, pixelRatio, strokeWidth }) {
    const y = align(pixelRatio, height2 / 2) - strokeWidth % 2 / 2;
    path.moveTo(0, y);
    path.lineTo(width2, y);
  },
  "forward-slanted-lines"(path, { width: width2, height: height2, strokeWidth }) {
    const angle2 = Math.atan2(height2, width2);
    const insetX = strokeWidth * Math.cos(angle2);
    const insetY = strokeWidth * Math.sin(angle2);
    path.moveTo(-insetX, insetY);
    path.lineTo(insetX, -insetY);
    path.moveTo(-insetX, height2 + insetY);
    path.lineTo(width2 + insetX, -insetY);
    path.moveTo(width2 - insetX, height2 + insetY);
    path.lineTo(width2 + insetX, height2 - insetY);
  },
  "backward-slanted-lines"(path, { width: width2, height: height2, strokeWidth }) {
    const angle2 = Math.atan2(height2, width2);
    const insetX = strokeWidth * Math.cos(angle2);
    const insetY = strokeWidth * Math.sin(angle2);
    path.moveTo(width2 - insetX, -insetY);
    path.lineTo(width2 + insetX, insetY);
    path.moveTo(-insetX, -insetY);
    path.lineTo(width2 + insetX, height2 + insetY);
    path.moveTo(-insetX, height2 - insetY);
    path.lineTo(insetX, height2 + insetY);
  }
};

// packages/ag-charts-community/src/scene/pattern/pattern.ts
var Pattern = class {
  constructor(patternOptions) {
    this._cache = void 0;
    this.width = Math.max(patternOptions?.width ?? 10, 1);
    this.height = Math.max(patternOptions?.height ?? 10, 1);
    this.fill = patternOptions.fill ?? "none";
    this.fillOpacity = patternOptions.fillOpacity ?? 1;
    this.backgroundFill = patternOptions.backgroundFill ?? "none";
    this.backgroundFillOpacity = patternOptions.backgroundFillOpacity ?? 1;
    this.stroke = patternOptions.stroke ?? "black";
    this.strokeOpacity = patternOptions.strokeOpacity ?? 1;
    this.strokeWidth = patternOptions.strokeWidth ?? 1;
    this.padding = patternOptions.padding ?? 1;
    this.pattern = patternOptions.pattern ?? "forward-slanted-lines";
    this.rotation = patternOptions.rotation ?? 0;
    this.scale = patternOptions.scale ?? 1;
    this.path = patternOptions.path;
  }
  getPath(pixelRatio) {
    const { pattern, width: width2, height: height2, padding: padding2, strokeWidth, path: svgPath } = this;
    const path = new ExtendedPath2D();
    let renderPattern = PATTERNS[pattern] != null;
    if (svgPath) {
      renderPattern && (renderPattern = !path.appendSvg(svgPath));
    }
    if (renderPattern) {
      PATTERNS[pattern](path, { width: width2, height: height2, pixelRatio, strokeWidth, padding: padding2 });
    }
    return path;
  }
  renderStroke(path2d, ctx) {
    const { stroke: stroke3, strokeWidth, strokeOpacity } = this;
    if (!strokeWidth)
      return;
    ctx.strokeStyle = stroke3;
    ctx.lineWidth = strokeWidth;
    ctx.globalAlpha = strokeOpacity;
    ctx.stroke(path2d);
  }
  renderFill(path2d, ctx) {
    const { fill, fillOpacity } = this;
    if (fill === "none") {
      return;
    }
    ctx.fillStyle = fill;
    ctx.globalAlpha = fillOpacity;
    ctx.fill(path2d);
  }
  createCanvasPattern(ctx, pixelRatio) {
    const { width: width2, height: height2, scale: scale2, backgroundFill, backgroundFillOpacity } = this;
    if (width2 * scale2 < 1 || height2 * scale2 < 1) {
      logger_exports.warnOnce("Pattern fill is too small to render, ignoring.");
      return null;
    }
    const offscreenPattern = new HdpiOffscreenCanvas({ width: width2, height: height2, pixelRatio: pixelRatio * scale2 });
    const offscreenPatternCtx = offscreenPattern.context;
    if (backgroundFill !== "none") {
      offscreenPatternCtx.fillStyle = backgroundFill;
      offscreenPatternCtx.globalAlpha = backgroundFillOpacity;
      offscreenPatternCtx.fillRect(0, 0, width2, height2);
    }
    const path2d = this.getPath(pixelRatio).getPath2D();
    this.renderFill(path2d, offscreenPatternCtx);
    this.renderStroke(path2d, offscreenPatternCtx);
    const pattern = ctx.createPattern(offscreenPattern.canvas, "repeat");
    this.setPatternTransform(pattern, pixelRatio);
    offscreenPattern.destroy();
    return pattern;
  }
  setPatternTransform(pattern, pixelRatio, tx = 0, ty = 0) {
    if (pattern == null)
      return;
    const angle2 = normalizeAngle360FromDegrees(this.rotation);
    const scale2 = 1 / pixelRatio;
    const cos = Math.cos(angle2) * scale2;
    const sin = Math.sin(angle2) * scale2;
    const DOMMatrixCtor = getDOMMatrix();
    pattern.setTransform(new DOMMatrixCtor([cos, sin, -sin, cos, tx, ty]));
  }
  createPattern(ctx, pixelRatio) {
    if (this._cache?.ctx === ctx && this._cache.pixelRatio === pixelRatio) {
      return this._cache.pattern;
    }
    const pattern = this.createCanvasPattern(ctx, pixelRatio);
    if (pattern == null)
      return;
    this._cache = { ctx, pattern, pixelRatio };
    return pattern;
  }
  toSvg() {
    const {
      width: width2,
      height: height2,
      fill,
      fillOpacity,
      backgroundFill,
      backgroundFillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      rotation,
      scale: scale2
    } = this;
    const pattern = createSvgElement("pattern");
    pattern.setAttribute("viewBox", `0 0 ${width2} ${height2}`);
    pattern.setAttribute("width", String(width2));
    pattern.setAttribute("height", String(height2));
    pattern.setAttribute("patternUnits", "userSpaceOnUse");
    const rect2 = createSvgElement("rect");
    rect2.setAttribute("x", "0");
    rect2.setAttribute("y", "0");
    rect2.setAttribute("width", String(width2));
    rect2.setAttribute("height", String(height2));
    rect2.setAttribute("fill", backgroundFill);
    rect2.setAttribute("fill-opacity", String(backgroundFillOpacity));
    pattern.appendChild(rect2);
    const path = createSvgElement("path");
    path.setAttribute("fill", fill);
    path.setAttribute("fill-opacity", String(fillOpacity));
    path.setAttribute("stroke-opacity", String(strokeOpacity));
    path.setAttribute("stroke", stroke3);
    path.setAttribute("stroke-width", String(strokeWidth));
    path.setAttribute("transform", `rotate(${rotation}) scale(${scale2})`);
    path.setAttribute("d", this.getPath(1).toSVG());
    pattern.appendChild(path);
    return pattern;
  }
};

// packages/ag-charts-community/src/scene/shape/svgUtils.ts
function setSvgFontAttributes(element2, options) {
  const { fontStyle, fontWeight: fontWeight2, fontSize, fontFamily } = options;
  if (fontStyle)
    element2.setAttribute("font-style", fontStyle);
  if (fontWeight2)
    element2.setAttribute("font-weight", String(fontWeight2));
  if (fontSize != null)
    element2.setAttribute("font-size", String(fontSize));
  if (fontFamily)
    element2.setAttribute("font-family", fontFamily);
}
function setSvgStrokeAttributes(element2, options) {
  const { stroke: stroke3, strokeWidth, strokeOpacity } = options;
  if (stroke3)
    element2.setAttribute("stroke", stroke3);
  if (strokeWidth != null)
    element2.setAttribute("stroke-width", String(strokeWidth));
  if (strokeOpacity != null)
    element2.setAttribute("stroke-opacity", String(strokeOpacity));
}
function setSvgLineDashAttributes(element2, options) {
  const { lineDash, lineDashOffset } = options;
  if (lineDash?.some((d) => d !== 0)) {
    const lineDashArray = lineDash.length % 2 === 1 ? [...lineDash, ...lineDash] : lineDash;
    element2.setAttribute("stroke-dasharray", lineDashArray.join(" "));
    if (lineDashOffset != null)
      element2.setAttribute("stroke-dashoffset", String(lineDashOffset));
  }
}

// packages/ag-charts-community/src/scene/shape/shape.ts
var _Shape = class _Shape extends Node2 {
  constructor() {
    super(...arguments);
    this.drawingMode = "overlay";
    this.fillOpacity = 1;
    this.strokeOpacity = 1;
    this.fill = "black";
    this.strokeWidth = 0;
    this.lineDashOffset = 0;
    this.opacity = 1;
  }
  // optimised field accessor
  getGradient(fill) {
    if (isGradientFill(fill))
      return this.createGradient(fill);
  }
  createGradient(fill) {
    const { colorSpace = "rgb", gradient: gradient2 = "linear", colorStops, rotation = 0, reverse = false } = fill;
    if (colorStops == null)
      return;
    let stops = getColorStops(colorStops, ["black"], [0, 1]);
    if (reverse) {
      stops = stops.map((s) => ({ color: s.color, stop: 1 - s.stop })).reverse();
    }
    switch (gradient2) {
      case "linear":
        return new LinearGradient(colorSpace, stops, rotation);
      case "radial":
        return new RadialGradient(colorSpace, stops);
      case "conic":
        return new ConicGradient(colorSpace, stops, rotation);
    }
  }
  getPattern(fill) {
    if (isPatternFill(fill))
      return this.createPattern(fill);
  }
  createPattern(fill) {
    return new Pattern(fill);
  }
  getImage(fill) {
    if (isImageFill(fill))
      return this.createImage(fill);
  }
  createImage(fill) {
    return new Image(this.imageLoader, fill);
  }
  onFillChange() {
    if (typeof this.fill === "object") {
      if (objectsEqual(this._cachedFill ?? {}, this.fill)) {
        return;
      }
    }
    this.fillGradient = this.getGradient(this.fill);
    this.fillPattern = this.getPattern(this.fill);
    this.fillImage = this.getImage(this.fill);
    this._cachedFill = this.fill;
  }
  // optimised field accessor
  onStrokeChange() {
    this.strokeGradient = this.getGradient(this.stroke);
  }
  // optimised field accessor
  /**
   * Returns a device-pixel aligned coordinate (or length if length is supplied).
   *
   * NOTE: Not suitable for strokes, since the stroke needs to be offset to the middle
   * of a device pixel.
   */
  align(start2, length2) {
    return align(this.layerManager?.canvas?.pixelRatio ?? 1, start2, length2);
  }
  markDirty(property) {
    super.markDirty(property);
    this.cachedDefaultGradientFillBBox = void 0;
  }
  fillStroke(ctx, path) {
    if (this.__drawingMode === "cutout") {
      ctx.globalCompositeOperation = "destination-out";
      this.executeFill(ctx, path);
      ctx.globalCompositeOperation = "source-over";
    }
    this.renderFill(ctx, path);
    this.renderStroke(ctx, path);
  }
  renderFill(ctx, path) {
    const { __fill: fill, __fillOpacity: fillOpacity = 1, fillImage } = this;
    if (fill != null && fill !== "none" && fillOpacity > 0) {
      const globalAlpha = ctx.globalAlpha;
      if (fillImage) {
        ctx.globalAlpha = fillImage.backgroundFillOpacity;
        ctx.fillStyle = fillImage.backgroundFill;
        this.executeFill(ctx, path);
        ctx.globalAlpha = globalAlpha;
      }
      this.applyFillAndAlpha(ctx);
      this.applyShadow(ctx);
      this.executeFill(ctx, path);
      ctx.globalAlpha = globalAlpha;
      if (this.fillShadow?.enabled) {
        ctx.shadowColor = "rgba(0, 0, 0, 0)";
      }
    }
  }
  executeFill(ctx, path) {
    if (path) {
      ctx.fill(path);
    } else {
      ctx.fill();
    }
  }
  applyFillAndAlpha(ctx) {
    const {
      __fill: fill,
      fillGradient,
      fillPattern,
      fillImage,
      __fillOpacity: fillOpacity = 1,
      __opacity: opacity = 1
    } = this;
    const combinedOpacity = opacity * fillOpacity;
    if (combinedOpacity !== 1) {
      ctx.globalAlpha *= combinedOpacity;
    }
    if (fillGradient) {
      const { fillBBox = this.getDefaultGradientFillBBox() ?? this.getBBox(), fillParams } = this;
      ctx.fillStyle = fillGradient.createGradient(ctx, fillBBox, fillParams) ?? "black";
    } else if (fillPattern) {
      const { x, y } = this.getBBox();
      const pixelRatio = this.layerManager?.canvas?.pixelRatio ?? 1;
      const pattern = fillPattern.createPattern(ctx, pixelRatio);
      fillPattern.setPatternTransform(pattern, pixelRatio, x, y);
      if (pattern) {
        ctx.fillStyle = pattern;
      } else {
        ctx.fillStyle = fillPattern.fill;
        ctx.globalAlpha *= fillPattern.fillOpacity;
      }
    } else if (fillImage) {
      const bbox = this.getBBox();
      const image = fillImage.createPattern(ctx, bbox.width, bbox.height, this);
      fillImage.setImageTransform(image, bbox);
      ctx.fillStyle = image ?? "transparent";
    } else {
      ctx.fillStyle = typeof fill === "string" ? fill : "black";
    }
  }
  applyStrokeAndAlpha(ctx) {
    const { __stroke: stroke3, __strokeOpacity: strokeOpacity = 1, strokeGradient, __opacity: opacity = 1 } = this;
    ctx.strokeStyle = strokeGradient?.createGradient(ctx, this.getBBox()) ?? (typeof stroke3 === "string" ? stroke3 : void 0) ?? "black";
    const combinedOpacity = opacity * strokeOpacity;
    if (combinedOpacity !== 1) {
      ctx.globalAlpha *= combinedOpacity;
    }
  }
  applyShadow(ctx) {
    const pixelRatio = this.layerManager?.canvas.pixelRatio ?? 1;
    const { __fillShadow: fillShadow } = this;
    if (fillShadow?.enabled) {
      ctx.shadowColor = fillShadow.color;
      ctx.shadowOffsetX = fillShadow.xOffset * pixelRatio;
      ctx.shadowOffsetY = fillShadow.yOffset * pixelRatio;
      ctx.shadowBlur = fillShadow.blur * pixelRatio;
    }
  }
  renderStroke(ctx, path) {
    const {
      __stroke: stroke3,
      __strokeWidth: strokeWidth = 0,
      __strokeOpacity: strokeOpacity = 1,
      __lineDash: lineDash,
      __lineDashOffset: lineDashOffset,
      __lineCap: lineCap,
      __lineJoin: lineJoin,
      __miterLimit: miterLimit
    } = this;
    if (stroke3 != null && stroke3 !== "none" && strokeWidth > 0 && strokeOpacity > 0) {
      const { globalAlpha } = ctx;
      this.applyStrokeAndAlpha(ctx);
      ctx.lineWidth = strokeWidth;
      if (lineDash) {
        ctx.setLineDash(lineDash);
      }
      if (lineDashOffset) {
        ctx.lineDashOffset = lineDashOffset;
      }
      if (lineCap) {
        ctx.lineCap = lineCap;
      }
      if (lineJoin) {
        ctx.lineJoin = lineJoin;
      }
      if (miterLimit != null) {
        ctx.miterLimit = miterLimit;
      }
      this.executeStroke(ctx, path);
      ctx.globalAlpha = globalAlpha;
    }
  }
  executeStroke(ctx, path) {
    if (path) {
      ctx.stroke(path);
    } else {
      ctx.stroke();
    }
  }
  getDefaultGradientFillBBox() {
    this.cachedDefaultGradientFillBBox ?? (this.cachedDefaultGradientFillBBox = Object.freeze(this.computeDefaultGradientFillBBox()));
    return this.cachedDefaultGradientFillBBox;
  }
  computeDefaultGradientFillBBox() {
    return;
  }
  containsPoint(x, y) {
    return this.isPointInPath(x, y);
  }
  applySvgFillAttributes(element2, defs) {
    const { fill, fillOpacity } = this;
    if (typeof fill === "string") {
      element2.setAttribute("fill", fill);
    } else if (isGradientFill(fill) && this.fillGradient) {
      defs ?? (defs = []);
      const gradient2 = this.fillGradient.toSvg(this.fillBBox ?? this.getBBox());
      const id = generateUUID();
      gradient2.setAttribute("id", id);
      defs.push(gradient2);
      element2.setAttribute("fill", `url(#${id})`);
    } else if (isPatternFill(fill) && this.fillPattern) {
      defs ?? (defs = []);
      const pattern = this.fillPattern.toSvg();
      const id = generateUUID();
      pattern.setAttribute("id", id);
      defs.push(pattern);
      element2.setAttribute("fill", `url(#${id})`);
    } else if (isImageFill(fill) && this.fillImage) {
      defs ?? (defs = []);
      const pixelRatio = this.layerManager?.canvas?.pixelRatio ?? 1;
      const pattern = this.fillImage.toSvg(this.getBBox(), pixelRatio);
      const id = generateUUID();
      pattern.setAttribute("id", id);
      defs.push(pattern);
      element2.setAttribute("fill", `url(#${id})`);
    } else {
      element2.setAttribute("fill", "none");
    }
    element2.setAttribute("fill-opacity", String(fillOpacity));
    return defs;
  }
  applySvgStrokeAttributes(element2) {
    const { stroke: stroke3, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this;
    setSvgStrokeAttributes(element2, { stroke: isString(stroke3) ? stroke3 : void 0, strokeOpacity, strokeWidth });
    setSvgLineDashAttributes(element2, { lineDash, lineDashOffset });
  }
  static handleFillChange(shape) {
    shape.onFillChange();
  }
  static handleStrokeChange(shape) {
    shape.onStrokeChange();
  }
  /**
   * Sets style properties on the shape, optimizing by writing directly to __ prefix fields
   * where possible to avoid setter overhead.
   */
  setStyleProperties(style2, fillBBox, fillParams) {
    const opacity = style2?.opacity ?? 1;
    const fill = style2?.fill;
    const computedFillOpacity = (style2?.fillOpacity ?? 1) * opacity;
    const computedStrokeOpacity = (style2?.strokeOpacity ?? 1) * opacity;
    const computedStrokeWidth = style2?.strokeWidth ?? 0;
    const computedLineDashOffset = style2?.lineDashOffset ?? 0;
    let hasDirectChanges = false;
    if (this.__fillOpacity !== computedFillOpacity) {
      this.__fillOpacity = computedFillOpacity;
      hasDirectChanges = true;
    }
    if (this.__strokeOpacity !== computedStrokeOpacity) {
      this.__strokeOpacity = computedStrokeOpacity;
      hasDirectChanges = true;
    }
    if (this.__strokeWidth !== computedStrokeWidth) {
      this.__strokeWidth = computedStrokeWidth;
      hasDirectChanges = true;
    }
    if (this.__lineDashOffset !== computedLineDashOffset) {
      this.__lineDashOffset = computedLineDashOffset;
      hasDirectChanges = true;
    }
    if (this.__lineDash !== style2?.lineDash) {
      this.__lineDash = style2?.lineDash;
      hasDirectChanges = true;
    }
    this.setFillProperties(fill, fillBBox, fillParams);
    if (fill !== this.fill) {
      this.fill = fill;
    }
    if (style2?.stroke !== this.stroke) {
      this.stroke = style2?.stroke;
    }
    if (hasDirectChanges) {
      this.markDirty();
    }
  }
  /**
   * Sets fill-related properties (fillBBox and fillParams) on the shape.
   * Used for gradient fills that need bounding box information.
   */
  setFillProperties(fill, fillBBox, fillParams) {
    const computedFillBBox = fillBBox == null || !isGradientFill(fill) || fill.bounds == null || fill.bounds === "item" ? void 0 : fillBBox[fill.bounds];
    let hasDirectChanges = false;
    if (this.__fillBBox !== computedFillBBox) {
      this.__fillBBox = computedFillBBox;
      hasDirectChanges = true;
    }
    if (this.__fillParams !== fillParams) {
      this.__fillParams = fillParams;
      hasDirectChanges = true;
    }
    if (hasDirectChanges) {
      this.onFillChange();
      this.markDirty();
    }
  }
};
__decorateClass([
  DeclaredSceneChangeDetection()
], _Shape.prototype, "drawingMode", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], _Shape.prototype, "fillOpacity", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], _Shape.prototype, "strokeOpacity", 2);
__decorateClass([
  DeclaredSceneObjectChangeDetection({
    equals: objectsEqual,
    changeCb: _Shape.handleFillChange
  })
], _Shape.prototype, "fill", 2);
__decorateClass([
  SceneObjectChangeDetection({ equals: objectsEqual, changeCb: _Shape.handleStrokeChange })
], _Shape.prototype, "stroke", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], _Shape.prototype, "strokeWidth", 2);
__decorateClass([
  SceneArrayChangeDetection()
], _Shape.prototype, "lineDash", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], _Shape.prototype, "lineDashOffset", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], _Shape.prototype, "lineCap", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], _Shape.prototype, "lineJoin", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], _Shape.prototype, "miterLimit", 2);
__decorateClass([
  DeclaredSceneChangeDetection({ convertor: (v) => clamp(0, v ?? 1, 1) })
], _Shape.prototype, "opacity", 2);
__decorateClass([
  SceneObjectChangeDetection({ equals: TRIPLE_EQ, checkDirtyOnAssignment: true })
], _Shape.prototype, "fillShadow", 2);
__decorateClass([
  DeclaredSceneObjectChangeDetection({ equals: boxesEqual, changeCb: (s) => s.onFillChange() })
], _Shape.prototype, "fillBBox", 2);
__decorateClass([
  DeclaredSceneObjectChangeDetection({ equals: objectsEqual, changeCb: (s) => s.onFillChange() })
], _Shape.prototype, "fillParams", 2);
var Shape = _Shape;

// packages/ag-charts-community/src/scene/matrix.ts
var IDENTITY_MATRIX_ELEMENTS = [1, 0, 0, 1, 0, 0];
var Matrix = class _Matrix {
  get e() {
    return [...this.elements];
  }
  constructor(elements = IDENTITY_MATRIX_ELEMENTS) {
    this.elements = [...elements];
  }
  setElements(elements) {
    const e = this.elements;
    e[0] = elements[0];
    e[1] = elements[1];
    e[2] = elements[2];
    e[3] = elements[3];
    e[4] = elements[4];
    e[5] = elements[5];
    return this;
  }
  get identity() {
    const e = this.elements;
    return isNumberEqual(e[0], 1) && isNumberEqual(e[1], 0) && isNumberEqual(e[2], 0) && isNumberEqual(e[3], 1) && isNumberEqual(e[4], 0) && isNumberEqual(e[5], 0);
  }
  /**
   * Performs the AxB matrix multiplication and saves the result
   * to `C`, if given, or to `A` otherwise.
   */
  AxB(A, B, C2) {
    const a = A[0] * B[0] + A[2] * B[1], b = A[1] * B[0] + A[3] * B[1], c = A[0] * B[2] + A[2] * B[3], d = A[1] * B[2] + A[3] * B[3], e = A[0] * B[4] + A[2] * B[5] + A[4], f = A[1] * B[4] + A[3] * B[5] + A[5];
    C2 = C2 ?? A;
    C2[0] = a;
    C2[1] = b;
    C2[2] = c;
    C2[3] = d;
    C2[4] = e;
    C2[5] = f;
  }
  /**
   * The `other` matrix gets post-multiplied to the current matrix.
   * Returns the current matrix.
   * @param other
   */
  multiplySelf(other) {
    this.AxB(this.elements, other.elements);
    return this;
  }
  /**
   * The `other` matrix gets post-multiplied to the current matrix.
   * Returns a new matrix.
   * @param other
   */
  multiply(other) {
    const elements = [Number.NaN, Number.NaN, Number.NaN, Number.NaN, Number.NaN, Number.NaN];
    if (other instanceof _Matrix) {
      this.AxB(this.elements, other.elements, elements);
    } else {
      this.AxB(this.elements, [other.a, other.b, other.c, other.d, other.e, other.f], elements);
    }
    return new _Matrix(elements);
  }
  preMultiplySelf(other) {
    this.AxB(other.elements, this.elements, this.elements);
    return this;
  }
  /**
   * Returns the inverse of this matrix as a new matrix.
   */
  inverse() {
    const el = this.elements;
    let a = el[0], b = el[1], c = el[2], d = el[3];
    const e = el[4], f = el[5];
    const rD = 1 / (a * d - b * c);
    a *= rD;
    b *= rD;
    c *= rD;
    d *= rD;
    return new _Matrix([d, -b, -c, a, c * f - d * e, b * e - a * f]);
  }
  invertSelf() {
    const el = this.elements;
    let a = el[0], b = el[1], c = el[2], d = el[3];
    const e = el[4], f = el[5];
    const rD = 1 / (a * d - b * c);
    a *= rD;
    b *= rD;
    c *= rD;
    d *= rD;
    el[0] = d;
    el[1] = -b;
    el[2] = -c;
    el[3] = a;
    el[4] = c * f - d * e;
    el[5] = b * e - a * f;
    return this;
  }
  transformPoint(x, y) {
    const e = this.elements;
    return {
      x: x * e[0] + y * e[2] + e[4],
      y: x * e[1] + y * e[3] + e[5]
    };
  }
  transformBBox(bbox, target) {
    const el = this.elements;
    const xx = el[0];
    const xy = el[1];
    const yx = el[2];
    const yy = el[3];
    const h_w = bbox.width * 0.5;
    const h_h = bbox.height * 0.5;
    const cx = bbox.x + h_w;
    const cy = bbox.y + h_h;
    const w = Math.abs(h_w * xx) + Math.abs(h_h * yx);
    const h = Math.abs(h_w * xy) + Math.abs(h_h * yy);
    target ?? (target = new BBox(0, 0, 0, 0));
    target.x = cx * xx + cy * yx + el[4] - w;
    target.y = cx * xy + cy * yy + el[5] - h;
    target.width = w + w;
    target.height = h + h;
    return target;
  }
  toContext(ctx) {
    if (this.identity) {
      return;
    }
    const e = this.elements;
    ctx.transform(e[0], e[1], e[2], e[3], e[4], e[5]);
  }
  static updateTransformMatrix(matrix, scalingX, scalingY, rotation, translationX, translationY, opts) {
    const sx = scalingX;
    const sy = scalingY;
    let scx;
    let scy;
    if (sx === 1 && sy === 1) {
      scx = 0;
      scy = 0;
    } else {
      scx = opts?.scalingCenterX ?? 0;
      scy = opts?.scalingCenterY ?? 0;
    }
    const r = rotation;
    const cos = Math.cos(r);
    const sin = Math.sin(r);
    let rcx;
    let rcy;
    if (r === 0) {
      rcx = 0;
      rcy = 0;
    } else {
      rcx = opts?.rotationCenterX ?? 0;
      rcy = opts?.rotationCenterY ?? 0;
    }
    const tx = translationX;
    const ty = translationY;
    const tx4 = scx * (1 - sx) - rcx;
    const ty4 = scy * (1 - sy) - rcy;
    matrix.setElements([
      cos * sx,
      sin * sx,
      -sin * sy,
      cos * sy,
      cos * tx4 - sin * ty4 + rcx + tx,
      sin * tx4 + cos * ty4 + rcy + ty
    ]);
    return matrix;
  }
};

// packages/ag-charts-community/src/scene/transformable.ts
function isMatrixTransform(node) {
  return isMatrixTransformType(node.constructor);
}
var MATRIX_TRANSFORM_TYPE = Symbol("isMatrixTransform");
function isMatrixTransformType(cstr) {
  return cstr[MATRIX_TRANSFORM_TYPE] === true;
}
function MatrixTransform(Parent) {
  var _a, _b;
  const ParentNode = Parent;
  if (isMatrixTransformType(Parent)) {
    return Parent;
  }
  const TRANSFORM_MATRIX = Symbol("matrix_combined_transform");
  class MatrixTransformInternal extends ParentNode {
    constructor() {
      super(...arguments);
      this[_b] = new Matrix();
      this._dirtyTransform = true;
    }
    onChangeDetection(property) {
      super.onChangeDetection(property);
      this._dirtyTransform = true;
      if (this.batchLevel > 0) {
        return;
      }
      this.markDirty("transform");
    }
    updateMatrix(_matrix) {
    }
    computeTransformMatrix() {
      if (!this._dirtyTransform)
        return;
      this[TRANSFORM_MATRIX].setElements(IDENTITY_MATRIX_ELEMENTS);
      this.updateMatrix(this[TRANSFORM_MATRIX]);
      this._dirtyTransform = false;
    }
    toParent(bbox) {
      this.computeTransformMatrix();
      if (this[TRANSFORM_MATRIX].identity)
        return bbox.clone();
      return this[TRANSFORM_MATRIX].transformBBox(bbox);
    }
    toParentPoint(x, y) {
      this.computeTransformMatrix();
      if (this[TRANSFORM_MATRIX].identity)
        return { x, y };
      return this[TRANSFORM_MATRIX].transformPoint(x, y);
    }
    fromParent(bbox) {
      this.computeTransformMatrix();
      if (this[TRANSFORM_MATRIX].identity)
        return bbox.clone();
      return this[TRANSFORM_MATRIX].inverse().transformBBox(bbox);
    }
    fromParentPoint(x, y) {
      this.computeTransformMatrix();
      if (this[TRANSFORM_MATRIX].identity)
        return { x, y };
      return this[TRANSFORM_MATRIX].inverse().transformPoint(x, y);
    }
    computeBBox() {
      const bbox = super.computeBBox();
      if (!bbox)
        return bbox;
      return this.toParent(bbox);
    }
    computeBBoxWithoutTransforms() {
      return super.computeBBox();
    }
    pickNode(x, y) {
      ({ x, y } = this.fromParentPoint(x, y));
      return super.pickNode(x, y);
    }
    pickNodes(x, y, into) {
      ({ x, y } = this.fromParentPoint(x, y));
      return super.pickNodes(x, y, into);
    }
    render(renderCtx) {
      this.computeTransformMatrix();
      const { ctx } = renderCtx;
      const matrix = this[TRANSFORM_MATRIX];
      let performRestore = false;
      try {
        if (!matrix.identity) {
          ctx.save();
          performRestore = true;
          matrix.toContext(ctx);
        }
        super.render(renderCtx);
      } finally {
        if (performRestore) {
          ctx.restore();
        }
      }
    }
    toSVG() {
      this.computeTransformMatrix();
      const svg = super.toSVG();
      const matrix = this[TRANSFORM_MATRIX];
      if (matrix.identity || svg == null)
        return svg;
      const g = createSvgElement("g");
      g.append(...svg.elements);
      const [a, b, c, d, e, f] = matrix.e;
      g.setAttribute("transform", `matrix(${a} ${b} ${c} ${d} ${e} ${f})`);
      return {
        elements: [g],
        defs: svg.defs
      };
    }
  }
  _a = MATRIX_TRANSFORM_TYPE, _b = TRANSFORM_MATRIX;
  MatrixTransformInternal[_a] = true;
  return MatrixTransformInternal;
}
function Rotatable(Parent) {
  var _a;
  const ParentNode = Parent;
  const ROTATABLE_MATRIX = Symbol("matrix_rotation");
  class RotatableInternal extends MatrixTransform(ParentNode) {
    constructor() {
      super(...arguments);
      this[_a] = new Matrix();
      this.rotationCenterX = 0;
      this.rotationCenterY = 0;
      this.rotation = 0;
    }
    updateMatrix(matrix) {
      super.updateMatrix(matrix);
      const { rotation, rotationCenterX, rotationCenterY } = this;
      if (rotation === 0)
        return;
      Matrix.updateTransformMatrix(this[ROTATABLE_MATRIX], 1, 1, rotation, 0, 0, {
        rotationCenterX,
        rotationCenterY
      });
      matrix.multiplySelf(this[ROTATABLE_MATRIX]);
    }
  }
  _a = ROTATABLE_MATRIX;
  __decorateClass([
    SceneChangeDetection()
  ], RotatableInternal.prototype, "rotationCenterX", 2);
  __decorateClass([
    SceneChangeDetection()
  ], RotatableInternal.prototype, "rotationCenterY", 2);
  __decorateClass([
    SceneChangeDetection()
  ], RotatableInternal.prototype, "rotation", 2);
  return RotatableInternal;
}
function isScalable(node) {
  return "scalingX" in node && "scalingY" in node && "scalingCenterX" in node && "scalingCenterY" in node;
}
function Scalable(Parent) {
  var _a;
  const ParentNode = Parent;
  const SCALABLE_MATRIX = Symbol("matrix_scale");
  class ScalableInternal extends MatrixTransform(ParentNode) {
    constructor() {
      super(...arguments);
      this[_a] = new Matrix();
      this.scalingX = 1;
      this.scalingY = 1;
      this.scalingCenterX = 0;
      this.scalingCenterY = 0;
    }
    // optimised field accessor
    updateMatrix(matrix) {
      super.updateMatrix(matrix);
      const { scalingX, scalingY, scalingCenterX, scalingCenterY } = this;
      if (scalingX === 1 && scalingY === 1)
        return;
      Matrix.updateTransformMatrix(this[SCALABLE_MATRIX], scalingX, scalingY, 0, 0, 0, {
        scalingCenterX,
        scalingCenterY
      });
      matrix.multiplySelf(this[SCALABLE_MATRIX]);
    }
    /**
     * Optimised reset for animation hot paths.
     * Bypasses SceneChangeDetection decorators by writing directly to backing fields.
     */
    resetScalingProperties(scalingX, scalingY, scalingCenterX, scalingCenterY) {
      this.__scalingX = scalingX;
      this.__scalingY = scalingY;
      this.__scalingCenterX = scalingCenterX;
      this.__scalingCenterY = scalingCenterY;
      this.onChangeDetection("scaling");
    }
  }
  _a = SCALABLE_MATRIX;
  __decorateClass([
    SceneChangeDetection()
  ], ScalableInternal.prototype, "scalingX", 2);
  __decorateClass([
    SceneChangeDetection()
  ], ScalableInternal.prototype, "scalingY", 2);
  __decorateClass([
    SceneChangeDetection()
  ], ScalableInternal.prototype, "scalingCenterX", 2);
  __decorateClass([
    SceneChangeDetection()
  ], ScalableInternal.prototype, "scalingCenterY", 2);
  return ScalableInternal;
}
function Translatable(Parent) {
  var _a;
  const ParentNode = Parent;
  const TRANSLATABLE_MATRIX = Symbol("matrix_translation");
  class TranslatableInternal extends MatrixTransform(ParentNode) {
    constructor() {
      super(...arguments);
      this[_a] = new Matrix();
      this.translationX = 0;
      this.translationY = 0;
    }
    updateMatrix(matrix) {
      super.updateMatrix(matrix);
      const { translationX, translationY } = this;
      if (translationX === 0 && translationY === 0)
        return;
      Matrix.updateTransformMatrix(this[TRANSLATABLE_MATRIX], 1, 1, 0, translationX, translationY);
      matrix.multiplySelf(this[TRANSLATABLE_MATRIX]);
    }
  }
  _a = TRANSLATABLE_MATRIX;
  __decorateClass([
    SceneChangeDetection()
  ], TranslatableInternal.prototype, "translationX", 2);
  __decorateClass([
    SceneChangeDetection()
  ], TranslatableInternal.prototype, "translationY", 2);
  return TranslatableInternal;
}
var Transformable = class {
  /**
   * Converts a BBox from canvas coordinate space into the coordinate space of the given Node.
   */
  static fromCanvas(node, bbox) {
    const parents = [];
    for (const parent of node.traverseUp()) {
      if (isMatrixTransform(parent)) {
        parents.unshift(parent);
      }
    }
    for (const parent of parents) {
      bbox = parent.fromParent(bbox);
    }
    if (isMatrixTransform(node)) {
      bbox = node.fromParent(bbox);
    }
    return bbox;
  }
  /**
   * Converts a Nodes BBox (or an arbitrary BBox if supplied) from local Node coordinate space
   * into the Canvas coordinate space.
   */
  static toCanvas(node, bbox) {
    if (bbox == null) {
      bbox = node.getBBox();
    } else if (isMatrixTransform(node)) {
      bbox = node.toParent(bbox);
    }
    for (const parent of node.traverseUp()) {
      if (isMatrixTransform(parent)) {
        bbox = parent.toParent(bbox);
      }
    }
    return bbox;
  }
  /**
   * Converts a point from canvas coordinate space into the coordinate space of the given Node.
   */
  static fromCanvasPoint(node, x, y) {
    const parents = [];
    for (const parent of node.traverseUp()) {
      if (isMatrixTransform(parent)) {
        parents.unshift(parent);
      }
    }
    for (const parent of parents) {
      ({ x, y } = parent.fromParentPoint(x, y));
    }
    if (isMatrixTransform(node)) {
      ({ x, y } = node.fromParentPoint(x, y));
    }
    return { x, y };
  }
  /**
   * Converts a point from a Nodes local coordinate space into the Canvas coordinate space.
   */
  static toCanvasPoint(node, x, y) {
    if (isMatrixTransform(node)) {
      ({ x, y } = node.toParentPoint(x, y));
    }
    for (const parent of node.traverseUp()) {
      if (isMatrixTransform(parent)) {
        ({ x, y } = parent.toParentPoint(x, y));
      }
    }
    return { x, y };
  }
};

// packages/ag-charts-community/src/scene/group.ts
var sharedOffscreenCanvas;
var _Group = class _Group extends Node2 {
  // optimizeForInfrequentRedraws: true
  constructor(opts) {
    super(opts);
    this.childNodes = /* @__PURE__ */ new Set();
    this.dirty = false;
    this.dirtyZIndex = false;
    this.clipRect = void 0;
    this.opacity = 1;
    // Used when renderToOffscreenCanvas: true
    this.layer = void 0;
    // optimizeForInfrequentRedraws: false
    this.image = void 0;
    this._lastWidth = Number.NaN;
    this._lastHeight = Number.NaN;
    this._lastDevicePixelRatio = Number.NaN;
    this.isContainerNode = true;
    this.renderToOffscreenCanvas = opts?.renderToOffscreenCanvas === true;
    this.optimizeForInfrequentRedraws = opts?.optimizeForInfrequentRedraws === true;
  }
  static is(value) {
    return value instanceof _Group;
  }
  static computeChildrenBBox(nodes, skipInvisible = true) {
    return BBox.merge(Node2.extractBBoxes(nodes, skipInvisible));
  }
  static compareChildren(a, b) {
    return compareZIndex(a.__zIndex, b.__zIndex) || a.serialNumber - b.serialNumber;
  }
  // We consider a group to be boundless, thus any point belongs to it.
  containsPoint(_x, _y) {
    return true;
  }
  computeBBox() {
    return _Group.computeChildrenBBox(this.children());
  }
  computeSafeClippingBBox(pixelRatio) {
    const bbox = this.computeBBox();
    if (bbox?.isFinite() !== true)
      return;
    let strokeWidth = 0;
    const strokeMiterAmount = 4;
    for (const child of this.descendants()) {
      if (child instanceof Shape) {
        strokeWidth = Math.max(strokeWidth, child.strokeWidth);
      }
    }
    const padding2 = Math.max(
      // Account for anti-aliasing artefacts
      1,
      // Account for strokes (incl. miters) - this may not be the best place to include this
      strokeWidth / 2 * strokeMiterAmount
    );
    const { x: originX, y: originY } = Transformable.toCanvasPoint(this, 0, 0);
    const x = alignBefore(pixelRatio, originX + bbox.x - padding2) - originX;
    const y = alignBefore(pixelRatio, originY + bbox.y - padding2) - originY;
    const width2 = Math.ceil(bbox.x + bbox.width - x + padding2);
    const height2 = Math.ceil(bbox.y + bbox.height - y + padding2);
    return new BBox(x, y, width2, height2);
  }
  prepareSharedCanvas(width2, height2, pixelRatio) {
    if (sharedOffscreenCanvas?.pixelRatio === pixelRatio) {
      sharedOffscreenCanvas.resize(width2, height2, pixelRatio);
    } else {
      sharedOffscreenCanvas = new HdpiOffscreenCanvas({ width: width2, height: height2, pixelRatio });
    }
    return sharedOffscreenCanvas;
  }
  setScene(scene) {
    const previousScene = this.scene;
    super.setScene(scene);
    if (this.layer && previousScene && previousScene !== scene) {
      previousScene.layersManager.removeLayer(this.layer);
      this.layer = void 0;
    }
    for (const child of this.children()) {
      child.setScene(scene);
    }
  }
  markDirty(property) {
    this.dirty = true;
    super.markDirty(property);
  }
  markDirtyChildrenOrder() {
    super.markDirtyChildrenOrder();
    this.dirtyZIndex = true;
    this.markDirty();
  }
  /**
   * Appends one or more new node instances to this parent.
   * If one needs to:
   * - move a child to the end of the list of children
   * - move a child from one parent to another (including parents in other scenes)
   * one should use the {@link insertBefore} method instead.
   * @param nodes A node or nodes to append.
   */
  append(nodes) {
    for (const node of toIterable(nodes)) {
      node.remove();
      this.childNodes.add(node);
      node.parentNode = this;
      node.setScene(this.scene);
    }
    this.markDirtyChildrenOrder();
    this.markDirty();
  }
  appendChild(node) {
    this.append(node);
    return node;
  }
  removeChild(node) {
    if (!this.childNodes?.delete(node)) {
      throw new Error(
        `AG Charts - internal error, unknown child node ${node.name ?? node.id} in $${this.name ?? this.id}`
      );
    }
    node.parentNode = void 0;
    node.setScene();
    this.markDirtyChildrenOrder();
    this.markDirty();
  }
  clear() {
    for (const child of this.children()) {
      delete child.parentNode;
      child.setScene();
    }
    this.childNodes?.clear();
    this.markDirty();
  }
  /**
   * Hit testing method.
   * Recursively checks if the given point is inside this node or any of its children.
   * Returns the first matching node or `undefined`.
   * Nodes that render later (show on top) are hit tested first.
   */
  pickNode(x, y) {
    if (!this.visible || this.pointerEvents === 1 /* None */ || !this.containsPoint(x, y)) {
      return;
    }
    if (this.childNodes != null && this.childNodes.size !== 0) {
      const children = [...this.children()];
      for (let i = children.length - 1; i >= 0; i--) {
        const child = children[i];
        const hit = child.pickNode(x, y);
        if (hit != null) {
          return hit;
        }
      }
    } else if (!this.isContainerNode) {
      return this;
    }
  }
  pickNodes(x, y, into = []) {
    if (!this.visible || this.pointerEvents === 1 /* None */ || !this.containsPoint(x, y)) {
      return into;
    }
    if (!this.isContainerNode) {
      into.push(this);
    }
    for (const child of this.children()) {
      child.pickNodes(x, y, into);
    }
    return into;
  }
  isDirty(renderCtx) {
    const { width: width2, height: height2, devicePixelRatio } = renderCtx;
    const { dirty, layer } = this;
    const layerResized = layer != null && (this._lastWidth !== width2 || this._lastHeight !== height2);
    const pixelRatioChanged = this._lastDevicePixelRatio !== devicePixelRatio;
    this._lastWidth = width2;
    this._lastHeight = height2;
    this._lastDevicePixelRatio = devicePixelRatio;
    return dirty || layerResized || pixelRatioChanged;
  }
  preRender(renderCtx) {
    let counts;
    if (this.dirty) {
      counts = super.preRender(renderCtx, 0);
      for (const child of this.children()) {
        const childCounts = child.preRender(renderCtx);
        counts.groups += childCounts.groups;
        counts.nonGroups += childCounts.nonGroups;
        counts.complexity += childCounts.complexity;
      }
      counts.groups += 1;
      counts.nonGroups -= 1;
    } else {
      counts = this.childNodeCounts;
    }
    if (this.renderToOffscreenCanvas && !this.optimizeForInfrequentRedraws && counts.nonGroups > 0 && this.getVisibility()) {
      this.layer ?? (this.layer = this.layerManager?.addLayer({ name: this.name }));
    } else if (this.layer != null) {
      this.layerManager?.removeLayer(this.layer);
      this.layer = void 0;
    }
    return counts;
  }
  render(renderCtx) {
    const { layer, renderToOffscreenCanvas } = this;
    const childRenderCtx = { ...renderCtx };
    const dirty = this.isDirty(renderCtx);
    this.dirty = false;
    if (!renderToOffscreenCanvas) {
      this.renderInContext(childRenderCtx);
      super.render(childRenderCtx);
      return;
    }
    const { ctx, stats, devicePixelRatio: pixelRatio } = renderCtx;
    let { image } = this;
    if (dirty) {
      image?.bitmap.close();
      image = void 0;
      const bbox = layer ? void 0 : this.computeSafeClippingBBox(pixelRatio);
      const renderOffscreen = (offscreenCanvas, ...transform) => {
        const offscreenCtx = offscreenCanvas.context;
        childRenderCtx.ctx = offscreenCtx;
        offscreenCanvas.clear();
        offscreenCtx.save();
        try {
          offscreenCtx.setTransform(...transform);
          offscreenCtx.globalAlpha = 1;
          this.renderInContext(childRenderCtx);
        } finally {
          offscreenCtx.restore();
          offscreenCtx.verifyDepthZero?.();
        }
      };
      if (layer) {
        renderOffscreen(layer, ctx.getTransform());
      } else if (bbox) {
        const { x, y, width: width2, height: height2 } = bbox;
        const scaledWidth = Math.floor(width2 * pixelRatio);
        const scaledHeight = Math.floor(height2 * pixelRatio);
        if (scaledWidth > 0 && scaledHeight > 0) {
          const canvas = this.prepareSharedCanvas(width2, height2, pixelRatio);
          renderOffscreen(canvas, pixelRatio, 0, 0, pixelRatio, -x * pixelRatio, -y * pixelRatio);
          image = { bitmap: canvas.transferToImageBitmap(), x, y, width: width2, height: height2 };
        }
      }
      this.image = image;
      if (stats)
        stats.layersRendered++;
    } else if (stats) {
      stats.layersSkipped++;
    }
    const { globalAlpha } = ctx;
    ctx.globalAlpha = globalAlpha * this.opacity;
    if (layer) {
      ctx.save();
      try {
        ctx.resetTransform();
        layer.drawImage(ctx);
      } finally {
        ctx.restore();
      }
    } else if (image) {
      const { bitmap, x, y, width: width2, height: height2 } = image;
      ctx.drawImage(bitmap, 0, 0, width2 * pixelRatio, height2 * pixelRatio, x, y, width2, height2);
    }
    ctx.globalAlpha = globalAlpha;
    super.render(childRenderCtx);
  }
  applyClip(ctx, clipRect) {
    const { x, y, width: width2, height: height2 } = clipRect;
    ctx.beginPath();
    ctx.rect(x, y, width2, height2);
    ctx.clip();
  }
  renderInContext(childRenderCtx) {
    const { ctx, stats } = childRenderCtx;
    if (this.dirtyZIndex) {
      this.sortChildren(_Group.compareChildren);
      this.dirtyZIndex = false;
    }
    ctx.save();
    try {
      ctx.globalAlpha *= this.opacity;
      if (this.clipRect != null) {
        this.applyClip(ctx, this.clipRect);
        childRenderCtx.clipBBox = Transformable.toCanvas(this, this.clipRect);
      }
      for (const child of this.children()) {
        if (!child.visible) {
          if (stats) {
            stats.nodesSkipped += child.childNodeCounts.nonGroups + child.childNodeCounts.groups;
            stats.opsSkipped += child.childNodeCounts.complexity;
          }
          continue;
        }
        child.isolatedRender(childRenderCtx);
      }
    } finally {
      ctx.restore();
    }
  }
  sortChildren(compareFn) {
    if (!this.childNodes)
      return;
    const sortedChildren = [...this.childNodes].sort(compareFn);
    this.childNodes.clear();
    for (const child of sortedChildren) {
      this.childNodes.add(child);
    }
  }
  *children() {
    yield* this.childNodes;
  }
  *excludeChildren(exclude) {
    for (const child of this.children()) {
      if (exclude.instance && !(child instanceof exclude.instance) || exclude.name && child.name !== exclude.name) {
        yield child;
      }
    }
  }
  *descendants() {
    for (const child of this.children()) {
      yield child;
      if (child instanceof _Group) {
        yield* child.descendants();
      }
    }
  }
  /**
   * Transforms bbox given in the canvas coordinate space to bbox in this group's coordinate space and
   * sets this group's clipRect to the transformed bbox.
   * @param bbox clipRect bbox in the canvas coordinate space.
   */
  setClipRect(bbox) {
    this.clipRect = bbox ? Transformable.fromCanvas(this, bbox) : void 0;
  }
  /**
   * Set the clip rect within the canvas coordinate space.
   * @param bbox clipRect bbox in the canvas coordinate space.
   */
  setClipRectCanvasSpace(bbox) {
    this.clipRect = bbox;
  }
  getVisibility() {
    for (const node of this.traverseUp(true)) {
      if (!node.visible) {
        return false;
      }
    }
    return true;
  }
  toSVG() {
    if (!this.visible)
      return;
    const defs = [];
    const elements = [];
    for (const child of this.children()) {
      const svg = child.toSVG();
      if (svg != null) {
        elements.push(...svg.elements);
        if (svg.defs != null) {
          defs.push(...svg.defs);
        }
      }
    }
    return { elements, defs };
  }
};
_Group.className = "Group";
__decorateClass([
  SceneChangeDetection({ convertor: (v) => clamp(0, v, 1) })
], _Group.prototype, "opacity", 2);
var Group = _Group;
var ScalableGroup = class extends Scalable(Group) {
};
var RotatableGroup = class extends Rotatable(Group) {
};
var TranslatableGroup = class extends Translatable(Group) {
};
var TransformableGroup = class extends Rotatable(Translatable(Group)) {
};

// packages/ag-charts-community/src/util/mutex.ts
var Mutex = class {
  constructor() {
    this.available = true;
    this.acquireQueue = [];
  }
  acquire(cb) {
    return new Promise((resolve, reject) => {
      this.acquireQueue.push([cb, resolve, reject]);
      if (this.available) {
        this.dispatchNext().catch(reject);
      }
    });
  }
  async acquireImmediately(cb) {
    if (!this.available) {
      return false;
    }
    await this.acquire(cb);
    return true;
  }
  async waitForClearAcquireQueue() {
    return this.acquire(() => Promise.resolve(void 0));
  }
  async dispatchNext() {
    this.available = false;
    let [next, done, reject] = this.acquireQueue.shift() ?? [];
    while (next) {
      try {
        await next();
        done?.();
      } catch (error2) {
        reject?.(error2);
      }
      [next, done, reject] = this.acquireQueue.shift() ?? [];
    }
    this.available = true;
  }
};

// packages/ag-charts-community/src/util/observable.ts
var Observable = class {
  constructor() {
    this.eventListeners = /* @__PURE__ */ new Map();
  }
  addEventListener(eventType, listener) {
    if (typeof listener !== "function") {
      throw new TypeError("AG Charts - listener must be a Function");
    }
    const eventTypeListeners = this.eventListeners.get(eventType);
    if (eventTypeListeners) {
      eventTypeListeners.add(listener);
    } else {
      this.eventListeners.set(eventType, /* @__PURE__ */ new Set([listener]));
    }
  }
  removeEventListener(type, listener) {
    const listeners = this.eventListeners.get(type);
    if (listeners == null)
      return;
    listeners.delete(listener);
    if (listeners.size === 0) {
      this.eventListeners.delete(type);
    }
  }
  hasEventListener(type) {
    return this.eventListeners.has(type);
  }
  clearEventListeners() {
    this.eventListeners.clear();
  }
  fireEvent(event) {
    const listeners = this.eventListeners.get(event.type);
    if (listeners) {
      for (const listener of listeners) {
        listener(event);
      }
    }
  }
};

// packages/ag-charts-community/src/util/render.ts
function debouncedAnimationFrame(cb) {
  const window = getWindow();
  function scheduleWithAnimationFrame(innerCb, _delayMs) {
    return window.requestAnimationFrame(innerCb);
  }
  function cancelWithAnimationFrame(id) {
    window.cancelAnimationFrame(id);
  }
  return buildScheduler(scheduleWithAnimationFrame, cb, cancelWithAnimationFrame);
}
function debouncedCallback(cb) {
  function scheduleWithDelay(innerCb, delayMs = 0) {
    if (delayMs === 0) {
      queueMicrotask(innerCb);
      return void 0;
    }
    return setTimeout(innerCb, delayMs);
  }
  function cancelWithTimeout(id) {
    clearTimeout(id);
  }
  return buildScheduler(scheduleWithDelay, cb, cancelWithTimeout);
}
function buildScheduler(scheduleFn, cb, cancelFn) {
  let scheduleCount = 0;
  let promiseRunning = false;
  let awaitingPromise;
  let awaitingDone;
  let scheduledId;
  function busy() {
    return promiseRunning;
  }
  function done() {
    promiseRunning = false;
    scheduledId = void 0;
    awaitingDone?.();
    awaitingDone = void 0;
    awaitingPromise = void 0;
    if (scheduleCount > 0) {
      scheduledId = scheduleFn(scheduleCallback);
    }
  }
  function scheduleCallback() {
    const count = scheduleCount;
    scheduleCount = 0;
    promiseRunning = true;
    const maybePromise = cb({ count });
    if (!maybePromise) {
      done();
      return;
    }
    maybePromise.then(done, done);
  }
  function schedule(delayMs) {
    if (scheduleCount === 0 && !busy()) {
      scheduledId = scheduleFn(scheduleCallback, delayMs);
    }
    scheduleCount++;
  }
  function cancel() {
    if (scheduledId != null && cancelFn) {
      cancelFn(scheduledId);
      scheduledId = void 0;
      scheduleCount = 0;
    }
  }
  async function waitForCompletion() {
    if (!busy()) {
      return;
    }
    awaitingPromise ?? (awaitingPromise = new Promise(resolveAwaitingPromise));
    while (busy()) {
      await awaitingPromise;
    }
  }
  function resolveAwaitingPromise(resolve) {
    awaitingDone = resolve;
  }
  return {
    schedule,
    cancel,
    waitForCompletion
  };
}

// packages/ag-charts-community/src/widget/widgetEvents.ts
var WIDGET_HTML_EVENTS = [
  "blur",
  "change",
  "contextmenu",
  "focus",
  "keydown",
  "keyup",
  "click",
  "dblclick",
  "mouseenter",
  "mousemove",
  "mouseleave",
  "wheel",
  "touchstart",
  "touchmove",
  "touchend",
  "touchcancel"
];
function allocMouseEvent(type, sourceEvent, current) {
  const { offsetX, offsetY, clientX, clientY } = sourceEvent;
  const { currentX, currentY } = WidgetEventUtil.calcCurrentXY(current, sourceEvent);
  return { type, device: "mouse", offsetX, offsetY, clientX, clientY, currentX, currentY, sourceEvent };
}
function allocTouchEvent(type, sourceEvent, _current) {
  return { type, sourceEvent };
}
var WidgetAllocators = {
  blur: (sourceEvent) => {
    return { type: "blur", sourceEvent };
  },
  change: (sourceEvent) => {
    return { type: "change", sourceEvent };
  },
  contextmenu: (sourceEvent, current) => {
    return allocMouseEvent("contextmenu", sourceEvent, current);
  },
  focus: (sourceEvent) => {
    return { type: "focus", sourceEvent };
  },
  keydown: (sourceEvent) => {
    return { type: "keydown", sourceEvent };
  },
  keyup: (sourceEvent) => {
    return { type: "keyup", sourceEvent };
  },
  click: (sourceEvent, current) => {
    return allocMouseEvent("click", sourceEvent, current);
  },
  dblclick: (sourceEvent, current) => {
    return allocMouseEvent("dblclick", sourceEvent, current);
  },
  mouseenter: (sourceEvent, current) => {
    return allocMouseEvent("mouseenter", sourceEvent, current);
  },
  mousemove: (sourceEvent, current) => {
    return allocMouseEvent("mousemove", sourceEvent, current);
  },
  mouseleave: (sourceEvent, current) => {
    return allocMouseEvent("mouseleave", sourceEvent, current);
  },
  wheel: (sourceEvent) => {
    const { offsetX, offsetY, clientX, clientY } = sourceEvent;
    const factor = sourceEvent.deltaMode === 0 ? 0.01 : 1;
    const deltaX = sourceEvent.deltaX * factor;
    const deltaY = sourceEvent.deltaY * factor;
    return { type: "wheel", offsetX, offsetY, clientX, clientY, deltaX, deltaY, sourceEvent };
  },
  touchstart: (sourceEvent, current) => {
    return allocTouchEvent("touchstart", sourceEvent, current);
  },
  touchmove: (sourceEvent, current) => {
    return allocTouchEvent("touchmove", sourceEvent, current);
  },
  touchend: (sourceEvent, current) => {
    return allocTouchEvent("touchend", sourceEvent, current);
  },
  touchcancel: (sourceEvent, current) => {
    return allocTouchEvent("touchcancel", sourceEvent, current);
  }
};
var WidgetEventUtil = class {
  static alloc(type, sourceEvent, current) {
    return WidgetAllocators[type](sourceEvent, current);
  }
  static isHTMLEvent(type) {
    const htmlTypes = WIDGET_HTML_EVENTS;
    return htmlTypes.includes(type);
  }
  static calcCurrentXY(current, event) {
    const currentRect = current.getBoundingClientRect();
    return { currentX: event.clientX - currentRect.x, currentY: event.clientY - currentRect.y };
  }
};

// packages/ag-charts-community/src/widget/widgetListenerHTML.ts
var WidgetListenerHTML = class {
  constructor() {
    this.widgetListeners = {};
    this.sourceListeners = {};
  }
  initSourceHandler(type, handler) {
    this.sourceListeners ?? (this.sourceListeners = {});
    this.sourceListeners[type] = handler;
  }
  lazyGetWidgetListeners(type, target) {
    var _a;
    if (!(type in (this.sourceListeners ?? {}))) {
      const sourceHandler = (sourceEvent) => {
        const widgetEvent = WidgetEventUtil.alloc(type, sourceEvent, target.getElement());
        this.dispatch(type, target, widgetEvent);
      };
      const opts = {};
      if (type.startsWith("touch") || type === "wheel") {
        opts.passive = false;
      }
      this.initSourceHandler(type, sourceHandler);
      target.getElement().addEventListener(type, sourceHandler, opts);
    }
    this.widgetListeners ?? (this.widgetListeners = {});
    (_a = this.widgetListeners)[type] ?? (_a[type] = []);
    return this.widgetListeners[type];
  }
  add(type, target, handler) {
    const listeners = this.lazyGetWidgetListeners(type, target);
    listeners.push(handler);
  }
  remove(type, target, handler) {
    const listeners = this.lazyGetWidgetListeners(type, target);
    const index = listeners.indexOf(handler);
    if (index > -1)
      listeners.splice(index, 1);
  }
  destroy(target) {
    this.widgetListeners = void 0;
    if (this.sourceListeners) {
      for (const [key, sourceHandler] of entries(this.sourceListeners)) {
        target.getElement().removeEventListener(key, sourceHandler);
      }
      this.sourceListeners = void 0;
    }
  }
  dispatch(type, target, event) {
    for (const widgetListener of this.widgetListeners?.[type] ?? []) {
      widgetListener(event, target);
    }
  }
};

// packages/ag-charts-community/src/widget/mouseDragger.ts
var MouseDragger = class {
  constructor(glob, self, myCallbacks, downEvent) {
    this.glob = glob;
    this.self = self;
    this.window = getWindow();
    this.cleanup = new CleanupRegistry();
    this.mousegeneral = (generalEvent) => {
      generalEvent.stopPropagation();
      generalEvent.stopImmediatePropagation();
    };
    this.mousemove = (moveEvent) => {
      moveEvent.stopPropagation();
      moveEvent.stopImmediatePropagation();
      this.glob.globalMouseDragCallbacks?.mousemove(moveEvent);
    };
    this.mouseup = (upEvent) => {
      if (upEvent.button === 0) {
        upEvent.stopPropagation();
        upEvent.stopImmediatePropagation();
        this.glob.globalMouseDragCallbacks?.mouseup(upEvent);
        this.destroy();
      }
    };
    const { window, mousegeneral, mousemove, mouseup } = this;
    this.cleanup.register(
      attachListener(window, "mousedown", mousegeneral, { capture: true }),
      attachListener(window, "mouseenter", mousegeneral, { capture: true }),
      attachListener(window, "mouseleave", mousegeneral, { capture: true }),
      attachListener(window, "mouseout", mousegeneral, { capture: true }),
      attachListener(window, "mouseover", mousegeneral, { capture: true }),
      attachListener(window, "mousemove", mousemove, { capture: true }),
      attachListener(window, "mouseup", mouseup, { capture: true })
    );
    self.mouseDragger = this;
    glob.globalMouseDragCallbacks = myCallbacks;
    glob.globalMouseDragCallbacks.mousedown(downEvent);
    downEvent.stopPropagation();
    downEvent.stopImmediatePropagation();
  }
  destroy() {
    this.cleanup.flush();
    this.glob.globalMouseDragCallbacks = void 0;
    this.self.mouseDragger = void 0;
  }
};
function startMouseDrag(glob, self, myCallbacks, downEvent) {
  if (glob.globalMouseDragCallbacks != null)
    return void 0;
  return new MouseDragger(glob, self, myCallbacks, downEvent);
}

// packages/ag-charts-community/src/widget/touchDragger.ts
var LONG_TAP_DURATION_MS = 500;
var LONG_TAP_INTERRUPT_MIN_TOUCHMOVE_PXPX = 100;
function deltaClientSquared(a, b) {
  const dx2 = a.clientX - b.clientX;
  const dy2 = a.clientY - b.clientY;
  return dx2 * dx2 + dy2 * dy2;
}
var gIsInLongTap = false;
var TouchDragger = class {
  constructor(glob, self, myCallbacks, initialTouch, target) {
    this.glob = glob;
    this.self = self;
    this.initialTouch = initialTouch;
    this.target = target;
    this.cleanup = new CleanupRegistry();
    this.longTapInterrupted = false;
    this.longtap = () => {
      const { target, initialTouch } = this;
      if (!this.longTapInterrupted) {
        const cleanup = new CleanupRegistry();
        target.dispatchEvent(new TouchEvent("touchcancel", { touches: [initialTouch], bubbles: true }));
        gIsInLongTap = true;
        const longTapMove = (e) => e.preventDefault();
        const longTapEnd = (e) => {
          gIsInLongTap = false;
          e.preventDefault();
          cleanup.flush();
        };
        cleanup.register(
          attachListener(target, "touchmove", longTapMove, { passive: false }),
          attachListener(target, "touchend", longTapEnd, { passive: false }),
          attachListener(target, "touchcancel", longTapEnd, { passive: false })
        );
        const { clientX, clientY } = initialTouch;
        const contextMenuEvent = new PointerEvent("contextmenu", {
          bubbles: true,
          cancelable: true,
          view: getWindow(),
          clientX,
          clientY,
          pointerType: "touch"
        });
        target.dispatchEvent(contextMenuEvent);
      }
    };
    this.touchmove = (moveEvent) => {
      const { glob, self, initialTouch } = this;
      const touch = this.findInitialFinger(moveEvent.targetTouches);
      if (touch != null) {
        this.longTapInterrupted = this.longTapInterrupted || deltaClientSquared(initialTouch, touch) > LONG_TAP_INTERRUPT_MIN_TOUCHMOVE_PXPX;
        if (self.dragTouchEnabled) {
          glob.globalTouchDragCallbacks?.touchmove(moveEvent, touch);
        }
      }
    };
    this.touchend = (endEvent) => {
      this.longTapInterrupted = true;
      const touch = this.findInitialFinger(endEvent.changedTouches, endEvent.touches);
      if (touch != null) {
        this.glob.globalTouchDragCallbacks?.touchend(endEvent, touch);
      }
      this.destroy();
    };
    this.longtapTimer = setTimeout(this.longtap, LONG_TAP_DURATION_MS);
    const { touchmove, touchend } = this;
    this.cleanup.register(
      attachListener(target, "touchmove", touchmove, { passive: false }),
      attachListener(target, "touchstart", touchend, { passive: false }),
      attachListener(target, "touchend", touchend, { passive: false }),
      attachListener(target, "touchcancel", touchend, { passive: false })
    );
    self.touchDragger = this;
    glob.globalTouchDragCallbacks = myCallbacks;
  }
  destroy() {
    clearTimeout(this.longtapTimer);
    this.cleanup.flush();
    this.glob.globalTouchDragCallbacks = void 0;
    this.self.touchDragger = void 0;
  }
  findInitialFinger(...touchLists) {
    const touches = touchLists.flatMap((touchList) => Array.from(touchList));
    return Array.from(touches).find((v) => v.identifier === this.initialTouch.identifier);
  }
};
function startOneFingerTouch(glob, self, myCallbacks, initialTouch, target) {
  if (glob.globalTouchDragCallbacks != null || gIsInLongTap)
    return void 0;
  return new TouchDragger(glob, self, myCallbacks, initialTouch, target);
}

// packages/ag-charts-community/src/widget/widgetListenerInternal.ts
function makeMouseDrag(current, type, origin3, sourceEvent) {
  const { currentX, currentY } = WidgetEventUtil.calcCurrentXY(current.getElement(), sourceEvent);
  const originDeltaX = sourceEvent.pageX - origin3.pageX;
  const originDeltaY = sourceEvent.pageY - origin3.pageY;
  return {
    type,
    device: "mouse",
    offsetX: origin3.offsetX + originDeltaX,
    offsetY: origin3.offsetY + originDeltaY,
    clientX: sourceEvent.clientX,
    clientY: sourceEvent.clientY,
    currentX,
    currentY,
    originDeltaX,
    originDeltaY,
    sourceEvent
  };
}
function getTouchOffsets(current, { pageX, pageY }) {
  const { x, y } = current.getElement().getBoundingClientRect();
  return { offsetX: pageX - x, offsetY: pageY - y };
}
function makeTouchDrag(current, type, origin3, sourceEvent, touch) {
  const { currentX, currentY } = WidgetEventUtil.calcCurrentXY(current.getElement(), touch);
  const originDeltaX = touch.pageX - origin3.pageX;
  const originDeltaY = touch.pageY - origin3.pageY;
  return {
    type,
    device: "touch",
    offsetX: origin3.offsetX + originDeltaX,
    offsetY: origin3.offsetY + originDeltaY,
    clientX: touch.clientX,
    clientY: touch.clientY,
    currentX,
    currentY,
    originDeltaX,
    originDeltaY,
    sourceEvent
  };
}
var GlobalCallbacks = {};
var WidgetListenerInternal = class {
  constructor(dispatchCallback) {
    this.dispatchCallback = dispatchCallback;
    this.dragTouchEnabled = true;
  }
  destroy() {
    this.dragTriggerRemover?.();
    this.dragTriggerRemover = void 0;
    this.listeners?.clear();
    this.mouseDragger?.destroy();
    this.touchDragger?.destroy();
  }
  getListenerSet(type) {
    this.listeners ?? (this.listeners = /* @__PURE__ */ new Map());
    let result = this.listeners.get(type);
    if (result === void 0) {
      result = /* @__PURE__ */ new Set();
      this.listeners.set(type, result);
    }
    return result;
  }
  add(type, target, handler) {
    this.getListenerSet(type).add(handler);
    switch (type) {
      case "drag-start":
      case "drag-move":
      case "drag-end": {
        this.registerDragTrigger(target);
        break;
      }
    }
  }
  remove(type, _target, handler) {
    this.getListenerSet(type).delete(handler);
  }
  registerDragTrigger(target) {
    if (this.dragTriggerRemover == null) {
      const element2 = target.getElement();
      const cleanup = new CleanupRegistry();
      cleanup.register(
        attachListener(element2, "mousedown", (event) => this.triggerMouseDrag(target, event)),
        attachListener(element2, "touchstart", (event) => this.triggerTouchDrag(target, event), {
          passive: false
        })
      );
      this.dragTriggerRemover = () => cleanup.flush();
    }
  }
  triggerMouseDrag(current, downEvent) {
    if (downEvent.button === 0) {
      this.startMouseDrag(current, downEvent);
    }
  }
  startMouseDrag(current, initialDownEvent) {
    const origin3 = { pageX: Number.NaN, pageY: Number.NaN, offsetX: Number.NaN, offsetY: Number.NaN };
    partialAssign(["pageX", "pageY", "offsetX", "offsetY"], origin3, initialDownEvent);
    const dragCallbacks = {
      mousedown: (downEvent) => {
        const dragStartEvent = makeMouseDrag(current, "drag-start", origin3, downEvent);
        this.dispatch("drag-start", current, dragStartEvent);
      },
      mousemove: (moveEvent) => {
        const dragMoveEvent = makeMouseDrag(current, "drag-move", origin3, moveEvent);
        this.dispatch("drag-move", current, dragMoveEvent);
      },
      mouseup: (upEvent) => {
        const dragEndEvent = makeMouseDrag(current, "drag-end", origin3, upEvent);
        this.dispatch("drag-end", current, dragEndEvent);
        this.endDrag(current, dragEndEvent);
      }
    };
    this.mouseDragger = startMouseDrag(GlobalCallbacks, this, dragCallbacks, initialDownEvent);
  }
  endDrag(target, { sourceEvent, clientX, clientY }) {
    const elem = target.getElement();
    const rect2 = elem.getBoundingClientRect();
    if (!boxContains(rect2, clientX, clientY)) {
      elem.dispatchEvent(new MouseEvent("mouseleave", sourceEvent));
      sourceEvent.target?.dispatchEvent(new MouseEvent("mouseenter", sourceEvent));
    }
  }
  triggerTouchDrag(current, startEvent) {
    const touch = startEvent.targetTouches[0];
    if (startEvent.targetTouches.length === 1 && touch != null) {
      this.startOneFingerTouch(current, startEvent, touch);
    }
  }
  startOneFingerTouch(current, initialEvent, initialTouch) {
    const origin3 = { pageX: Number.NaN, pageY: Number.NaN, ...getTouchOffsets(current, initialTouch) };
    partialAssign(["pageX", "pageY"], origin3, initialTouch);
    const dragCallbacks = {
      touchmove: (moveEvent, touch) => {
        const dragMoveEvent = makeTouchDrag(current, "drag-move", origin3, moveEvent, touch);
        this.dispatch("drag-move", current, dragMoveEvent);
      },
      touchend: (cancelEvent, touch) => {
        const dragMoveEvent = makeTouchDrag(current, "drag-end", origin3, cancelEvent, touch);
        this.dispatch("drag-end", current, dragMoveEvent);
      }
    };
    const target = current.getElement();
    this.touchDragger = startOneFingerTouch(GlobalCallbacks, this, dragCallbacks, initialTouch, target);
    const dragStartEvent = makeTouchDrag(current, "drag-start", origin3, initialEvent, initialTouch);
    this.dispatch("drag-start", current, dragStartEvent);
  }
  dispatch(type, current, event) {
    for (const handler of this.getListenerSet(type)) {
      handler(event, current);
    }
    this.dispatchCallback(type, event);
  }
};

// packages/ag-charts-community/src/widget/widget.ts
var WidgetBounds = class {
  constructor(elem) {
    this.elem = elem;
  }
  setBounds(bounds) {
    setElementBBox(this.elemContainer ?? this.elem, bounds);
  }
  getBounds() {
    return getElementBBox(this.elemContainer ?? this.elem);
  }
  static setElementContainer(widget, elemContainer) {
    const currentBounds = widget.getBounds();
    setElementBBox(elemContainer, currentBounds);
    setElementStyles(widget.elem, { width: "100%", height: "100%" });
    widget.elem.remove();
    widget.elemContainer = elemContainer;
    widget.elemContainer.replaceChildren(widget.elem);
  }
};
var Widget = class extends WidgetBounds {
  constructor() {
    super(...arguments);
    this.index = Number.NaN;
    this.children = [];
  }
  set id(elementId) {
    setAttribute(this.elem, "id", elementId);
  }
  get id() {
    return getAttribute(this.elem, "id");
  }
  getElement() {
    return this.elem;
  }
  getBoundingClientRect() {
    return this.elem.getBoundingClientRect();
  }
  get clientWidth() {
    return this.elem.clientWidth;
  }
  get clientHeight() {
    return this.elem.clientHeight;
  }
  destroy() {
    this.destroyListener?.();
    this.destroyListener = void 0;
    this.remove();
    for (const child of this.children) {
      child.parent = void 0;
      child.destroy();
    }
    this.children.length = 0;
    this.destructor();
    this.remove();
    this.internalListener?.destroy();
    this.htmlListener?.destroy(this);
  }
  remove() {
    this.elem.remove();
    this.elemContainer?.remove();
  }
  setHidden(hidden) {
    setElementStyle(this.elem, "display", hidden ? "none" : void 0);
  }
  isHidden() {
    return getWindow()?.getComputedStyle?.(this.elem).display === "none";
  }
  setCursor(cursor) {
    setElementStyle(this.elem, "cursor", cursor);
  }
  setTextContent(textContent) {
    this.elem.textContent = textContent ?? null;
  }
  setAriaDescribedBy(ariaDescribedBy) {
    setAttribute(this.elem, "aria-describedby", ariaDescribedBy);
  }
  setAriaHidden(ariaHidden) {
    setAttribute(this.elem, "aria-hidden", ariaHidden);
  }
  setAriaLabel(ariaLabel) {
    setAttribute(this.elem, "aria-label", ariaLabel);
  }
  setAriaExpanded(ariaExpanded) {
    setAttribute(this.elem, "aria-expanded", ariaExpanded);
  }
  setAriaControls(ariaControls) {
    setAttribute(this.elem, "aria-controls", ariaControls);
  }
  setAriaHasPopup(ariaHasPopup) {
    setAttribute(this.elem, "aria-haspopup", ariaHasPopup);
  }
  setInnerHTML(html) {
    this.elem.innerHTML = html;
  }
  setPointerEvents(pointerEvents) {
    setElementStyle(this.elem, "pointer-events", pointerEvents);
  }
  setCSSVariable(key, value) {
    this.elem.style.setProperty(key, value);
  }
  isDisabled() {
    return getAttribute(this.elem, "aria-disabled", false);
  }
  hasPopup() {
    const ariaHasPopup = getAttribute(this.elem, "aria-haspopup");
    return ariaHasPopup !== void 0 && ariaHasPopup !== "false";
  }
  parseFloat(s) {
    return s === "" ? 0 : Number.parseFloat(s);
  }
  cssLeft() {
    return this.parseFloat(this.elem.style.left);
  }
  cssTop() {
    return this.parseFloat(this.elem.style.top);
  }
  cssWidth() {
    return this.parseFloat(this.elem.style.width);
  }
  cssHeight() {
    return this.parseFloat(this.elem.style.height);
  }
  focus(opts) {
    this.elem.focus(opts);
  }
  setFocusOverride(focus) {
    setAttribute(this.elem, "data-focus-override", focus);
  }
  setPreventsDefault(preventDefault) {
    setAttribute(this.elem, "data-preventdefault", preventDefault);
  }
  setTabIndex(tabIndex) {
    setAttribute(this.elem, "tabindex", tabIndex);
  }
  addChild(child) {
    this.addChildToDOM(child, this.getBefore(child));
    this.children.push(child);
    child.index = this.children.length - 1;
    child.parent = this;
    this.onChildAdded(child);
  }
  removeChild(child) {
    const i = this.children.indexOf(child);
    this.children.splice(i, 1);
    this.removeChildFromDOM(child);
    this.onChildRemoved(child);
  }
  moveChild(child, domIndex) {
    if (child.domIndex === domIndex)
      return;
    child.domIndex = domIndex;
    this.removeChildFromDOM(child);
    this.addChildToDOM(child, this.getBefore(child));
  }
  addClass(...tokens) {
    this.elem.classList.add(...tokens);
  }
  removeClass(...tokens) {
    this.elem.classList.remove(...tokens);
  }
  toggleClass(token, force) {
    this.elem.classList.toggle(token, force);
  }
  appendOrInsert(child, before) {
    if (before) {
      before.getElement().insertAdjacentElement("beforebegin", child);
    } else {
      this.elem.appendChild(child);
    }
  }
  addChildToDOM(child, before) {
    this.appendOrInsert(child.getElement(), before);
  }
  removeChildFromDOM(child) {
    child.getElement().remove();
  }
  onChildAdded(_child) {
  }
  onChildRemoved(_child) {
  }
  getBefore({ domIndex }) {
    if (domIndex === void 0)
      return void 0;
    return this.children.filter((child) => child.domIndex !== void 0 && child.domIndex > domIndex).reduce((prev, curr) => !prev || curr.domIndex < prev.domIndex ? curr : prev, void 0);
  }
  addListener(type, listener) {
    if (WidgetEventUtil.isHTMLEvent(type)) {
      this.htmlListener ?? (this.htmlListener = new WidgetListenerHTML());
      this.htmlListener.add(type, this, listener);
    } else {
      this.internalListener ?? (this.internalListener = new WidgetListenerInternal(this.onDispatch.bind(this)));
      this.internalListener.add(type, this, listener);
    }
    return () => this.removeListener(type, listener);
  }
  removeListener(type, listener) {
    if (WidgetEventUtil.isHTMLEvent(type)) {
      this.htmlListener?.remove(type, this, listener);
    } else if (this.htmlListener != null) {
      this.internalListener?.remove(type, this, listener);
    }
  }
  setDragTouchEnabled(dragTouchEnabled) {
    this.internalListener ?? (this.internalListener = new WidgetListenerInternal(this.onDispatch.bind(this)));
    this.internalListener.dragTouchEnabled = dragTouchEnabled;
  }
  onDispatch(type, event) {
    if (!event.sourceEvent?.bubbles)
      return;
    let { parent } = this;
    while (parent != null) {
      const { internalListener } = parent;
      if (internalListener != null) {
        const parentEvent = { ...event, ...WidgetEventUtil.calcCurrentXY(parent.getElement(), event) };
        internalListener.dispatch(type, parent, parentEvent);
      }
      parent = parent.parent;
    }
  }
  static addWindowEvent(_type, listener) {
    const pagehideHandler = (event) => {
      if (event.persisted) {
        return;
      }
      listener();
    };
    return attachListener(getWindow(), "pagehide", pagehideHandler);
  }
};

// packages/ag-charts-community/src/scene/util/corner.ts
var drawCorner = (path, { x0, y0, x1, y1, cx, cy }, cornerRadius, move) => {
  if (move) {
    path.moveTo(x0, y0);
  }
  if (x0 !== x1 || y0 !== y1) {
    const r0 = Math.atan2(y0 - cy, x0 - cx);
    const r1 = Math.atan2(y1 - cy, x1 - cx);
    path.arc(cx, cy, cornerRadius, r0, r1);
  } else {
    path.lineTo(x0, y0);
  }
};

// packages/ag-charts-community/src/scene/shape/path.ts
var Path = class extends Shape {
  constructor() {
    super(...arguments);
    /**
     * Declare a path to retain for later rendering and hit testing
     * using custom Path2D class. Think of it as a TypeScript version
     * of the native Path2D (with some differences) that works in all browsers.
     */
    this.path = new ExtendedPath2D();
    this._clipX = Number.NaN;
    this._clipY = Number.NaN;
    this.clip = false;
    /**
     * The path only has to be updated when certain attributes change.
     * For example, if transform attributes (such as `translationX`)
     * are changed, we don't have to update the path. The `dirtyPath` flag
     * is how we keep track if the path has to be updated or not.
     */
    this._dirtyPath = true;
    this.lastPixelRatio = Number.NaN;
  }
  set clipX(value) {
    this._clipX = value;
    this.dirtyPath = true;
  }
  set clipY(value) {
    this._clipY = value;
    this.dirtyPath = true;
  }
  set dirtyPath(value) {
    if (this._dirtyPath !== value) {
      this._dirtyPath = value;
      if (value) {
        this.markDirty("path");
      }
    }
  }
  get dirtyPath() {
    return this._dirtyPath;
  }
  checkPathDirty() {
    if (this._dirtyPath) {
      return;
    }
    this.dirtyPath = this.path.isDirty() || (this.fillShadow?.isDirty() ?? false) || (this._clipPath?.isDirty() ?? false);
  }
  resetPathDirty() {
    this.path.clear(true);
    this._dirtyPath = false;
  }
  isPathDirty() {
    return this.path.isDirty();
  }
  onChangeDetection(property) {
    if (!this._dirtyPath) {
      this._dirtyPath = true;
      super.onChangeDetection(property);
    }
  }
  computeBBox() {
    this.updatePathIfDirty();
    return this.path.computeBBox();
  }
  isPointInPath(x, y) {
    this.updatePathIfDirty();
    return this.path.closedPath && this.path.isPointInPath(x, y);
  }
  distanceSquared(x, y) {
    return this.distanceSquaredTransformedPoint(x, y);
  }
  svgPathData(transform) {
    this.updatePathIfDirty();
    return this.path.toSVG(transform);
  }
  distanceSquaredTransformedPoint(x, y) {
    this.updatePathIfDirty();
    if (this.path.closedPath && this.path.isPointInPath(x, y)) {
      return 0;
    }
    return this.path.distanceSquared(x, y);
  }
  isDirtyPath() {
    return false;
  }
  updatePath() {
  }
  updatePathIfDirty() {
    if (this.dirtyPath || this.isDirtyPath()) {
      this.updatePath();
      this.dirtyPath = false;
    }
  }
  preRender(renderCtx) {
    if (renderCtx.devicePixelRatio !== this.lastPixelRatio) {
      this.dirtyPath = true;
    }
    this.lastPixelRatio = renderCtx.devicePixelRatio;
    this.updatePathIfDirty();
    return super.preRender(renderCtx, this.path.commands.length);
  }
  render(renderCtx) {
    const { ctx } = renderCtx;
    if (this.clip && !Number.isNaN(this._clipX) && !Number.isNaN(this._clipY)) {
      ctx.save();
      try {
        const margin = this.strokeWidth / 2;
        this._clipPath ?? (this._clipPath = new ExtendedPath2D());
        this._clipPath.clear();
        this._clipPath.rect(-margin, -margin, this._clipX + margin, this._clipY + margin + margin);
        ctx.clip(this._clipPath?.getPath2D());
        if (this._clipX > 0 && this._clipY > 0) {
          this.drawPath(ctx);
        }
      } finally {
        ctx.restore();
      }
    } else {
      this._clipPath = void 0;
      this.drawPath(ctx);
    }
    this.fillShadow?.markClean();
    super.render(renderCtx);
  }
  drawPath(ctx) {
    this.fillStroke(ctx, this.path.getPath2D());
  }
  toSVG() {
    if (!this.visible)
      return;
    const element2 = createSvgElement("path");
    element2.setAttribute("d", this.svgPathData());
    const defs = this.applySvgFillAttributes(element2, []);
    this.applySvgStrokeAttributes(element2);
    return {
      elements: [element2],
      defs
    };
  }
};
Path.className = "Path";
__decorateClass([
  SceneChangeDetection()
], Path.prototype, "clip", 2);
__decorateClass([
  SceneChangeDetection()
], Path.prototype, "clipX", 1);
__decorateClass([
  SceneChangeDetection()
], Path.prototype, "clipY", 1);

// packages/ag-charts-community/src/scene/shape/rect.ts
function cornerEdges(leadingEdge, trailingEdge, leadingInset, trailingInset, cornerRadius) {
  let leadingClipped = false;
  let trailingClipped = false;
  let leading0 = trailingInset - Math.sqrt(Math.max(cornerRadius ** 2 - leadingInset ** 2, 0));
  let leading1 = 0;
  let trailing0 = 0;
  let trailing1 = leadingInset - Math.sqrt(Math.max(cornerRadius ** 2 - trailingInset ** 2, 0));
  if (leading0 > leadingEdge) {
    leadingClipped = true;
    leading0 = leadingEdge;
    leading1 = leadingInset - Math.sqrt(Math.max(cornerRadius ** 2 - (trailingInset - leadingEdge) ** 2));
  } else if (isNumberEqual(leading0, 0)) {
    leading0 = 0;
  }
  if (trailing1 > trailingEdge) {
    trailingClipped = true;
    trailing0 = trailingInset - Math.sqrt(Math.max(cornerRadius ** 2 - (leadingInset - trailingEdge) ** 2));
    trailing1 = trailingEdge;
  } else if (isNumberEqual(trailing1, 0)) {
    trailing1 = 0;
  }
  return { leading0, leading1, trailing0, trailing1, leadingClipped, trailingClipped };
}
function clippedRoundRect(path, x, y, width2, height2, cornerRadii, clipBBox) {
  let {
    topLeft: topLeftCornerRadius,
    topRight: topRightCornerRadius,
    bottomRight: bottomRightCornerRadius,
    bottomLeft: bottomLeftCornerRadius
  } = cornerRadii;
  const maxVerticalCornerRadius = Math.max(
    topLeftCornerRadius + bottomLeftCornerRadius,
    topRightCornerRadius + bottomRightCornerRadius
  );
  const maxHorizontalCornerRadius = Math.max(
    topLeftCornerRadius + topRightCornerRadius,
    bottomLeftCornerRadius + bottomRightCornerRadius
  );
  if (maxVerticalCornerRadius <= 0 && maxHorizontalCornerRadius <= 0) {
    if (clipBBox == null) {
      path.rect(x, y, width2, height2);
    } else {
      const x0 = Math.max(x, clipBBox.x);
      const x1 = Math.min(x + width2, clipBBox.x + clipBBox.width);
      const y0 = Math.max(y, clipBBox.y);
      const y1 = Math.min(y + height2, clipBBox.y + clipBBox.height);
      path.rect(x0, y0, x1 - x0, y1 - y0);
    }
    return;
  } else if (clipBBox == null && topLeftCornerRadius === topRightCornerRadius && topLeftCornerRadius === bottomRightCornerRadius && topLeftCornerRadius === bottomLeftCornerRadius) {
    path.roundRect(x, y, width2, height2, topLeftCornerRadius);
    return;
  }
  if (width2 < 0) {
    x += width2;
    width2 = Math.abs(width2);
  }
  if (height2 < 0) {
    y += height2;
    height2 = Math.abs(height2);
  }
  if (width2 <= 0 || height2 <= 0)
    return;
  if (clipBBox == null) {
    clipBBox = new BBox(x, y, width2, height2);
  } else {
    const x0 = Math.max(x, clipBBox.x);
    const x1 = Math.min(x + width2, clipBBox.x + clipBBox.width);
    const y0 = Math.max(y, clipBBox.y);
    const y1 = Math.min(y + height2, clipBBox.y + clipBBox.height);
    clipBBox = new BBox(x0, y0, x1 - x0, y1 - y0);
  }
  const borderScale = Math.max(maxVerticalCornerRadius / height2, maxHorizontalCornerRadius / width2, 1);
  if (borderScale > 1) {
    topLeftCornerRadius /= borderScale;
    topRightCornerRadius /= borderScale;
    bottomRightCornerRadius /= borderScale;
    bottomLeftCornerRadius /= borderScale;
  }
  let drawTopLeftCorner = true;
  let drawTopRightCorner = true;
  let drawBottomRightCorner = true;
  let drawBottomLeftCorner = true;
  let topLeftCorner;
  let topRightCorner;
  let bottomRightCorner;
  let bottomLeftCorner;
  if (drawTopLeftCorner) {
    const nodes = cornerEdges(
      clipBBox.height,
      clipBBox.width,
      Math.max(x + topLeftCornerRadius - clipBBox.x, 0),
      Math.max(y + topLeftCornerRadius - clipBBox.y, 0),
      topLeftCornerRadius
    );
    if (nodes.leadingClipped)
      drawBottomLeftCorner = false;
    if (nodes.trailingClipped)
      drawTopRightCorner = false;
    const x0 = Math.max(clipBBox.x + nodes.leading1, clipBBox.x);
    const y0 = Math.max(clipBBox.y + nodes.leading0, clipBBox.y);
    const x1 = Math.max(clipBBox.x + nodes.trailing1, clipBBox.x);
    const y1 = Math.max(clipBBox.y + nodes.trailing0, clipBBox.y);
    const cx = x + topLeftCornerRadius;
    const cy = y + topLeftCornerRadius;
    topLeftCorner = { x0, y0, x1, y1, cx, cy };
  }
  if (drawTopRightCorner) {
    const nodes = cornerEdges(
      clipBBox.width,
      clipBBox.height,
      Math.max(y + topRightCornerRadius - clipBBox.y, 0),
      Math.max(clipBBox.x + clipBBox.width - (x + width2 - topRightCornerRadius), 0),
      topRightCornerRadius
    );
    if (nodes.leadingClipped)
      drawTopLeftCorner = false;
    if (nodes.trailingClipped)
      drawBottomRightCorner = false;
    const x0 = Math.min(clipBBox.x + clipBBox.width - nodes.leading0, clipBBox.x + clipBBox.width);
    const y0 = Math.max(clipBBox.y + nodes.leading1, clipBBox.y);
    const x1 = Math.min(clipBBox.x + clipBBox.width - nodes.trailing0, clipBBox.x + clipBBox.width);
    const y1 = Math.max(clipBBox.y + nodes.trailing1, clipBBox.y);
    const cx = x + width2 - topRightCornerRadius;
    const cy = y + topRightCornerRadius;
    topRightCorner = { x0, y0, x1, y1, cx, cy };
  }
  if (drawBottomRightCorner) {
    const nodes = cornerEdges(
      clipBBox.height,
      clipBBox.width,
      Math.max(clipBBox.x + clipBBox.width - (x + width2 - bottomRightCornerRadius), 0),
      Math.max(clipBBox.y + clipBBox.height - (y + height2 - bottomRightCornerRadius), 0),
      bottomRightCornerRadius
    );
    if (nodes.leadingClipped)
      drawTopRightCorner = false;
    if (nodes.trailingClipped)
      drawBottomLeftCorner = false;
    const x0 = Math.min(clipBBox.x + clipBBox.width - nodes.leading1, clipBBox.x + clipBBox.width);
    const y0 = Math.min(clipBBox.y + clipBBox.height - nodes.leading0, clipBBox.y + clipBBox.height);
    const x1 = Math.min(clipBBox.x + clipBBox.width - nodes.trailing1, clipBBox.x + clipBBox.width);
    const y1 = Math.min(clipBBox.y + clipBBox.height - nodes.trailing0, clipBBox.y + clipBBox.height);
    const cx = x + width2 - bottomRightCornerRadius;
    const cy = y + height2 - bottomRightCornerRadius;
    bottomRightCorner = { x0, y0, x1, y1, cx, cy };
  }
  if (drawBottomLeftCorner) {
    const nodes = cornerEdges(
      clipBBox.width,
      clipBBox.height,
      Math.max(clipBBox.y + clipBBox.height - (y + height2 - bottomLeftCornerRadius), 0),
      Math.max(x + bottomLeftCornerRadius - clipBBox.x, 0),
      bottomLeftCornerRadius
    );
    if (nodes.leadingClipped)
      drawBottomRightCorner = false;
    if (nodes.trailingClipped)
      drawTopLeftCorner = false;
    const x0 = Math.max(clipBBox.x + nodes.leading0, clipBBox.x);
    const y0 = Math.min(clipBBox.y + clipBBox.height - nodes.leading1, clipBBox.y + clipBBox.height);
    const x1 = Math.max(clipBBox.x + nodes.trailing0, clipBBox.x);
    const y1 = Math.min(clipBBox.y + clipBBox.height - nodes.trailing1, clipBBox.y + clipBBox.height);
    const cx = x + bottomLeftCornerRadius;
    const cy = y + height2 - bottomLeftCornerRadius;
    bottomLeftCorner = { x0, y0, x1, y1, cx, cy };
  }
  let didMove = false;
  if (drawTopLeftCorner && topLeftCorner != null) {
    drawCorner(path, topLeftCorner, topLeftCornerRadius, !didMove);
    didMove || (didMove = true);
  }
  if (drawTopRightCorner && topRightCorner != null) {
    drawCorner(path, topRightCorner, topRightCornerRadius, !didMove);
    didMove || (didMove = true);
  }
  if (drawBottomRightCorner && bottomRightCorner != null) {
    drawCorner(path, bottomRightCorner, bottomRightCornerRadius, !didMove);
    didMove || (didMove = true);
  }
  if (drawBottomLeftCorner && bottomLeftCorner != null) {
    drawCorner(path, bottomLeftCorner, bottomLeftCornerRadius, !didMove);
  }
  path.closePath();
}
var Rect = class extends Path {
  constructor() {
    super(...arguments);
    this.borderPath = new ExtendedPath2D();
    this.x = 0;
    this.y = 0;
    this.width = 10;
    this.height = 10;
    this.topLeftCornerRadius = 0;
    this.topRightCornerRadius = 0;
    this.bottomRightCornerRadius = 0;
    this.bottomLeftCornerRadius = 0;
    this.clipBBox = void 0;
    this.crisp = false;
    this.lastUpdatePathStrokeWidth = this.__strokeWidth;
    this.effectiveStrokeWidth = this.__strokeWidth;
    this.hittester = super.isPointInPath.bind(this);
    this.distanceCalculator = super.distanceSquaredTransformedPoint.bind(this);
    /**
     * When the rectangle's width or height is less than a pixel
     * and crisp mode is on, the rectangle will still fit into the pixel,
     * but will be less opaque to make an effect of holding less space.
     */
    this.microPixelEffectOpacity = 1;
  }
  // optimised field accessor
  set cornerRadius(cornerRadius) {
    this.topLeftCornerRadius = cornerRadius;
    this.topRightCornerRadius = cornerRadius;
    this.bottomRightCornerRadius = cornerRadius;
    this.bottomLeftCornerRadius = cornerRadius;
  }
  isDirtyPath() {
    return this.lastUpdatePathStrokeWidth !== this.__strokeWidth || Boolean(this.path.isDirty() || this.borderPath.isDirty());
  }
  updatePath() {
    const {
      path,
      borderPath,
      __crisp: crisp,
      __topLeftCornerRadius: topLeft,
      __topRightCornerRadius: topRight,
      __bottomRightCornerRadius: bottomRight,
      __bottomLeftCornerRadius: bottomLeft
    } = this;
    let { __x: x, __y: y, __width: w, __height: h, __strokeWidth: strokeWidth, __clipBBox: clipBBox } = this;
    const pixelRatio = this.layerManager?.canvas.pixelRatio ?? 1;
    const pixelSize = 1 / pixelRatio;
    let microPixelEffectOpacity = 1;
    path.clear();
    borderPath.clear();
    if (w === 0 || h === 0) {
      this.effectiveStrokeWidth = 0;
      this.lastUpdatePathStrokeWidth = 0;
      this.microPixelEffectOpacity = 0;
      return;
    }
    if (crisp) {
      if (w <= pixelSize) {
        microPixelEffectOpacity *= w / pixelSize;
      }
      if (h <= pixelSize) {
        microPixelEffectOpacity *= h / pixelSize;
      }
      w = this.align(x, w);
      h = this.align(y, h);
      x = this.align(x);
      y = this.align(y);
      clipBBox = clipBBox == null ? void 0 : new BBox(
        this.align(clipBBox.x),
        this.align(clipBBox.y),
        this.align(clipBBox.x, clipBBox.width),
        this.align(clipBBox.y, clipBBox.height)
      );
    }
    if (strokeWidth) {
      if (w < pixelSize) {
        const lx = x + pixelSize / 2;
        borderPath.moveTo(lx, y);
        borderPath.lineTo(lx, y + h);
        strokeWidth = pixelSize;
        this.borderClipPath = void 0;
      } else if (h < pixelSize) {
        const ly = y + pixelSize / 2;
        borderPath.moveTo(x, ly);
        borderPath.lineTo(x + w, ly);
        strokeWidth = pixelSize;
        this.borderClipPath = void 0;
      } else if (strokeWidth < w && strokeWidth < h) {
        const halfStrokeWidth = strokeWidth / 2;
        x += halfStrokeWidth;
        y += halfStrokeWidth;
        w -= strokeWidth;
        h -= strokeWidth;
        const adjustedClipBBox = clipBBox?.clone().shrink(halfStrokeWidth);
        const cornerRadii = {
          topLeft: topLeft > 0 ? topLeft - strokeWidth : 0,
          topRight: topRight > 0 ? topRight - strokeWidth : 0,
          bottomRight: bottomRight > 0 ? bottomRight - strokeWidth : 0,
          bottomLeft: bottomLeft > 0 ? bottomLeft - strokeWidth : 0
        };
        this.borderClipPath = void 0;
        if (w > 0 && h > 0 && (adjustedClipBBox == null || adjustedClipBBox?.width > 0 && adjustedClipBBox?.height > 0)) {
          clippedRoundRect(path, x, y, w, h, cornerRadii, adjustedClipBBox);
          clippedRoundRect(borderPath, x, y, w, h, cornerRadii, adjustedClipBBox);
        }
      } else {
        this.borderClipPath = this.borderClipPath ?? new ExtendedPath2D();
        this.borderClipPath.clear();
        this.borderClipPath.rect(x, y, w, h);
        borderPath.rect(x, y, w, h);
      }
    } else {
      const cornerRadii = { topLeft, topRight, bottomRight, bottomLeft };
      this.borderClipPath = void 0;
      clippedRoundRect(path, x, y, w, h, cornerRadii, clipBBox);
    }
    if ([topLeft, topRight, bottomRight, bottomLeft].every(areCornersZero)) {
      let distanceSquaredFromRect2 = function(hitX, hitY) {
        return rectInstance.getBBox().distanceSquared(hitX, hitY);
      };
      var distanceSquaredFromRect = distanceSquaredFromRect2;
      const bbox = this.getBBox();
      this.hittester = bbox.containsPoint.bind(bbox);
      const rectInstance = this;
      this.distanceSquared = distanceSquaredFromRect2;
    } else {
      this.hittester = super.isPointInPath;
      this.distanceCalculator = super.distanceSquaredTransformedPoint;
    }
    this.effectiveStrokeWidth = strokeWidth;
    this.lastUpdatePathStrokeWidth = strokeWidth;
    this.microPixelEffectOpacity = microPixelEffectOpacity;
  }
  computeBBox() {
    const { __x: x, __y: y, __width: width2, __height: height2, __clipBBox: clipBBox } = this;
    return clipBBox?.clone() ?? new BBox(x, y, width2, height2);
  }
  isPointInPath(x, y) {
    return this.hittester(x, y);
  }
  get midPoint() {
    return { x: this.__x + this.__width / 2, y: this.__y + this.__height / 2 };
  }
  /**
   * High-performance static property setter that bypasses the decorator system entirely.
   * Writes directly to backing fields (__propertyName) to avoid:
   * - Decorator setter chains and equality checks
   * - Multiple onChangeDetection calls per property
   * - Object.keys() iteration in assignIfNotStrictlyEqual
   * - Object allocation overhead
   *
   * A single markDirty() call at the end ensures the scene graph is properly invalidated.
   * WARNING: Only use for hot paths where performance is critical and properties don't need
   * individual change detection (e.g., when updating many nodes in a loop).
   */
  setStaticProperties(drawingMode, topLeftCornerRadius, topRightCornerRadius, bottomRightCornerRadius, bottomLeftCornerRadius, visible, crisp, fillShadow) {
    this.__drawingMode = drawingMode;
    this.__topLeftCornerRadius = topLeftCornerRadius;
    this.__topRightCornerRadius = topRightCornerRadius;
    this.__bottomRightCornerRadius = bottomRightCornerRadius;
    this.__bottomLeftCornerRadius = bottomLeftCornerRadius;
    this.__visible = visible;
    this.__crisp = crisp;
    this.__fillShadow = fillShadow;
    this.dirtyPath = true;
    this.markDirty();
  }
  /**
   * High-performance animation reset that bypasses the decorator system entirely.
   * Writes directly to backing fields (__x, __y, etc.) to avoid:
   * - Decorator setter chains and equality checks
   * - Multiple onChangeDetection calls
   * - Object.keys() iteration
   *
   * A single markDirty() call at the end ensures the scene graph is properly invalidated.
   * WARNING: Only use for animation hot paths where performance is critical.
   */
  resetAnimationProperties(x, y, width2, height2, opacity, clipBBox) {
    this.__x = x;
    this.__y = y;
    this.__width = width2;
    this.__height = height2;
    this.__opacity = opacity;
    this.__clipBBox = clipBBox;
    this.dirtyPath = true;
    this.markDirty();
  }
  distanceSquared(x, y) {
    return this.distanceCalculator(x, y);
  }
  applyFillAndAlpha(ctx) {
    super.applyFillAndAlpha(ctx);
    ctx.globalAlpha *= this.microPixelEffectOpacity;
  }
  applyStrokeAndAlpha(ctx) {
    super.applyStrokeAndAlpha(ctx);
    ctx.globalAlpha *= this.microPixelEffectOpacity;
  }
  renderStroke(ctx) {
    const { stroke: stroke3, effectiveStrokeWidth } = this;
    if (stroke3 && effectiveStrokeWidth) {
      const { globalAlpha } = ctx;
      const { lineDash, lineDashOffset, lineCap, lineJoin, borderPath, borderClipPath } = this;
      if (borderClipPath) {
        ctx.clip(borderClipPath.getPath2D());
      }
      this.applyStrokeAndAlpha(ctx);
      ctx.lineWidth = effectiveStrokeWidth;
      if (lineDash) {
        ctx.setLineDash(lineDash);
      }
      if (lineDashOffset) {
        ctx.lineDashOffset = lineDashOffset;
      }
      if (lineCap) {
        ctx.lineCap = lineCap;
      }
      if (lineJoin) {
        ctx.lineJoin = lineJoin;
      }
      ctx.stroke(borderPath.getPath2D());
      ctx.globalAlpha = globalAlpha;
    }
  }
};
Rect.className = "Rect";
__decorateClass([
  DeclaredSceneChangeDetection()
], Rect.prototype, "x", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], Rect.prototype, "y", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], Rect.prototype, "width", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], Rect.prototype, "height", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], Rect.prototype, "topLeftCornerRadius", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], Rect.prototype, "topRightCornerRadius", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], Rect.prototype, "bottomRightCornerRadius", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], Rect.prototype, "bottomLeftCornerRadius", 2);
__decorateClass([
  DeclaredSceneChangeDetection({ equals: boxesEqual })
], Rect.prototype, "clipBBox", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], Rect.prototype, "crisp", 2);
function areCornersZero(cornerRadius) {
  return cornerRadius === 0;
}

// packages/ag-charts-community/src/scene/sceneDebug.ts
var StatsAccumulator = class {
  // Log every 10 seconds
  constructor() {
    this.stats = /* @__PURE__ */ new Map();
    this.lastLogTime = Date.now();
    this.LOG_INTERVAL_MS = 1e4;
    this.startPeriodicLogging();
  }
  startPeriodicLogging() {
    if (!debugLogger_exports.check("scene:stats" /* SCENE_STATS */, "scene:stats:verbose" /* SCENE_STATS_VERBOSE */)) {
      return;
    }
    this.stopPeriodicLogging();
    this.intervalId = setInterval(() => {
      this.logAccumulatedStats();
    }, this.LOG_INTERVAL_MS);
  }
  stopPeriodicLogging() {
    if (this.intervalId) {
      clearInterval(this.intervalId);
      this.intervalId = void 0;
    }
  }
  recordTiming(category, duration) {
    const existing = this.stats.get(category);
    if (existing) {
      existing.min = Math.min(existing.min, duration);
      existing.max = Math.max(existing.max, duration);
      existing.sum += duration;
      existing.count += 1;
    } else {
      this.stats.set(category, {
        min: duration,
        max: duration,
        sum: duration,
        count: 1
      });
    }
  }
  recordTimings(durations) {
    for (const [category, duration] of Object.entries(durations)) {
      if (category !== "start" && typeof duration === "number") {
        this.recordTiming(category, duration);
      }
    }
  }
  logAccumulatedStats() {
    if (this.stats.size === 0)
      return;
    const timeSinceLastLog = (Date.now() - this.lastLogTime) / 1e3;
    const categories = Array.from(this.stats.keys()).sort((a, b) => {
      if (a === "\u23F1\uFE0F")
        return -1;
      if (b === "\u23F1\uFE0F")
        return 1;
      return a.localeCompare(b);
    });
    const parts = [];
    for (const category of categories) {
      const stats = this.stats.get(category);
      const avg = stats.sum / stats.count;
      parts.push(`${category}[${stats.min.toFixed(1)}/${avg.toFixed(1)}/${stats.max.toFixed(1)}]ms`);
    }
    const totalStats = this.stats.get("\u23F1\uFE0F");
    const count = totalStats?.count ?? 0;
    logger_exports.log(`\u{1F4CA} Stats (${timeSinceLastLog.toFixed(0)}s, ${count} renders): ${parts.join(" ")}`);
    this.stats.clear();
    this.lastLogTime = Date.now();
  }
  destroy() {
    this.stopPeriodicLogging();
    this.stats.clear();
  }
};
var globalStatsAccumulator;
var statsAccumulatorConsumers = 0;
function getStatsAccumulator() {
  globalStatsAccumulator ?? (globalStatsAccumulator = new StatsAccumulator());
  return globalStatsAccumulator;
}
function registerDebugStatsConsumer() {
  statsAccumulatorConsumers++;
  let released = false;
  return () => {
    if (released || statsAccumulatorConsumers === 0)
      return;
    released = true;
    statsAccumulatorConsumers--;
    if (statsAccumulatorConsumers === 0) {
      cleanupDebugStats();
    }
  };
}
function formatBytes(value) {
  for (const unit of ["B", "KB", "MB", "GB"]) {
    if (value < 1536) {
      return `${value.toFixed(1)}${unit}`;
    }
    value /= 1024;
  }
  return `${value.toFixed(1)}TB}`;
}
function memoryUsage() {
  if (!("memory" in performance))
    return;
  const { totalJSHeapSize, usedJSHeapSize, jsHeapSizeLimit } = performance.memory;
  const result = [];
  for (const amount of [usedJSHeapSize, totalJSHeapSize, jsHeapSizeLimit]) {
    if (typeof amount !== "number")
      continue;
    result.push(formatBytes(amount));
  }
  return `Heap ${result.join(" / ")}`;
}
function debugStats(layersManager, debugSplitTimes, ctx, renderCtxStats, extraDebugStats = {}, seriesRect = BBox.zero, colors) {
  if (!debugLogger_exports.check("scene:stats" /* SCENE_STATS */, "scene:stats:verbose" /* SCENE_STATS_VERBOSE */))
    return;
  const {
    layersRendered = 0,
    layersSkipped = 0,
    nodesRendered = 0,
    nodesSkipped = 0,
    opsPerformed = 0,
    opsSkipped = 0
  } = renderCtxStats ?? {};
  const end3 = performance.now();
  const { start: start2, ...durations } = debugSplitTimes;
  const totalTime = end3 - start2;
  const statsAccumulator = getStatsAccumulator();
  statsAccumulator.recordTimings(durations);
  statsAccumulator.recordTiming("\u23F1\uFE0F", totalTime);
  const splits = Object.entries(durations).map(([n, t]) => time2(n, t)).filter((v) => v != null).join(" + ");
  const extras = Object.entries(extraDebugStats).map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(" ; ");
  const detailedStats = debugLogger_exports.check("scene:stats:verbose" /* SCENE_STATS_VERBOSE */);
  const memUsage = detailedStats ? memoryUsage() : null;
  const metrics2 = detailedStats ? debugMetrics_exports.flush() : {};
  const metricsEntries = Object.entries(metrics2);
  const aggregationMetrics = [];
  const nodeDataMetrics = [];
  for (const [k, v] of metricsEntries) {
    if (k.endsWith(":aggregation") && Array.isArray(v)) {
      aggregationMetrics.push(`${k.replace(":aggregation", "")}(${v.join(",")})`);
    } else if (k.endsWith(":nodeData") && typeof v === "number") {
      nodeDataMetrics.push(`${k.replace(":nodeData", "")}(${v})`);
    }
  }
  const aggregationText = aggregationMetrics.length > 0 ? `Aggregation: ${aggregationMetrics.join(", ")}` : null;
  const nodeDataText = nodeDataMetrics.length > 0 ? `NodeData: ${nodeDataMetrics.join(", ")}` : null;
  const stats = [
    `${time2("\u23F1\uFE0F", start2, end3)} (${splits})`,
    `${extras}`,
    aggregationText,
    nodeDataText,
    `Layers: ${detailedStats ? pct(layersRendered, layersSkipped) : layersManager.size}`,
    detailedStats ? `Nodes: ${pct(nodesRendered, nodesSkipped)}` : null,
    detailedStats ? `Ops: ${pct(opsPerformed, opsSkipped)}` : null,
    memUsage
  ].filter(isString);
  const measurer3 = new TextMeasurer(ctx);
  const statsSize = new Map(stats.map((t) => [t, measurer3.measureText(t)]));
  const width2 = Math.max(...Array.from(statsSize.values(), (s) => s.width));
  const height2 = accumulate(statsSize.values(), (s) => s.height);
  const x = 2 + seriesRect.x;
  ctx.save();
  try {
    ctx.fillStyle = colors?.background ?? "white";
    ctx.fillRect(x, 0, width2, height2);
    ctx.fillStyle = colors?.foreground ?? "black";
    let y = 0;
    for (const [stat, size] of statsSize.entries()) {
      y += size.height;
      ctx.fillText(stat, x, y);
    }
  } catch (e) {
    logger_exports.warnOnce("Error during debug stats rendering", e);
  } finally {
    ctx.restore();
  }
}
function prepareSceneNodeHighlight(ctx) {
  const config = toArray(getWindow("agChartsSceneDebug"));
  const result = [];
  for (const name of config) {
    if (name === "layout") {
      result.push("seriesRoot", "legend", "root", /.*Axis-\d+-axis.*/);
    } else {
      result.push(name);
    }
  }
  ctx.debugNodeSearch = result;
}
function debugSceneNodeHighlight(ctx, debugNodes) {
  ctx.save();
  try {
    for (const [name, node] of Object.entries(debugNodes)) {
      const bbox = Transformable.toCanvas(node);
      if (!bbox) {
        logger_exports.log(`Scene.render() - no bbox for debugged node [${name}].`);
        continue;
      }
      ctx.globalAlpha = 0.8;
      ctx.strokeStyle = "red";
      ctx.lineWidth = 1;
      ctx.strokeRect(bbox.x, bbox.y, bbox.width, bbox.height);
      ctx.fillStyle = "red";
      ctx.strokeStyle = "white";
      ctx.font = "16px sans-serif";
      ctx.textBaseline = "top";
      ctx.textAlign = "left";
      ctx.lineWidth = 2;
      ctx.strokeText(name, bbox.x, bbox.y, bbox.width);
      ctx.fillText(name, bbox.x, bbox.y, bbox.width);
    }
  } catch (e) {
    logger_exports.warnOnce("Error during debug rendering", e);
  } finally {
    ctx.restore();
  }
}
var skippedProperties = /* @__PURE__ */ new Set();
var allowedProperties = /* @__PURE__ */ new Set([
  "gradient",
  // '_datum',
  "zIndex",
  "clipRect",
  "cachedBBox",
  "childNodeCounts",
  "path",
  "__zIndex",
  "name",
  "__scalingCenterX",
  "__scalingCenterY",
  "__rotationCenterX",
  "__rotationCenterY",
  "_previousDatum",
  "__fill",
  "__lineDash",
  "borderPath",
  "borderClipPath",
  "_clipPath"
]);
function nodeProps(node) {
  const { ...allProps } = node;
  for (const prop of Object.keys(allProps)) {
    if (allowedProperties.has(prop))
      continue;
    if (typeof allProps[prop] === "number")
      continue;
    if (typeof allProps[prop] === "string")
      continue;
    if (typeof allProps[prop] === "boolean")
      continue;
    skippedProperties.add(prop);
    delete allProps[prop];
  }
  return allProps;
}
function buildTree(node, mode) {
  if (!debugLogger_exports.check(true, "scene" /* SCENE */)) {
    return {};
  }
  let order = 0;
  return {
    node: mode === "json" ? nodeProps(node) : node,
    name: node.name ?? node.id,
    dirty: node instanceof Group ? node.dirty : void 0,
    ...Array.from(node instanceof Group ? node.children() : [], (c) => buildTree(c, mode)).reduce((result, childTree) => {
      let { name: treeNodeName } = childTree;
      const {
        node: { visible, opacity, zIndex, translationX, translationY, rotation, scalingX, scalingY },
        node: childNode
      } = childTree;
      if (!visible || opacity <= 0) {
        treeNodeName = `(${treeNodeName})`;
      }
      if (Group.is(childNode) && childNode.renderToOffscreenCanvas) {
        treeNodeName = `*${treeNodeName}*`;
      }
      const zIndexString = Array.isArray(zIndex) ? `(${zIndex.join(", ")})` : zIndex;
      const key = [
        `${(order++).toString().padStart(3, "0")}|`,
        `${treeNodeName ?? "<unknown>"}`,
        `z: ${zIndexString}`,
        translationX && `x: ${translationX}`,
        translationY && `y: ${translationY}`,
        rotation && `r: ${rotation}`,
        scalingX != null && scalingX !== 1 && `sx: ${scalingX}`,
        scalingY != null && scalingY !== 1 && `sy: ${scalingY}`
      ].filter((v) => !!v).join(" ");
      let selectedKey = key;
      let index = 1;
      while (result[selectedKey] != null && index < 100) {
        selectedKey = `${key} (${index++})`;
      }
      result[selectedKey] = childTree;
      return result;
    }, {})
  };
}
function buildDirtyTree(node) {
  const nodeDirty = node instanceof Group ? node.dirty : void 0;
  if (!nodeDirty) {
    return { dirtyTree: {}, paths: [] };
  }
  const childrenDirtyTree = Array.from(node instanceof Group ? node.children() : [], (c) => buildDirtyTree(c)).filter(
    (c) => c.paths.length > 0
  );
  const name = Group.is(node) ? node.name ?? node.id : node.id;
  const paths = childrenDirtyTree.length ? childrenDirtyTree.flatMap((c) => c.paths).map((p) => `${name}.${p}`) : [name];
  return {
    dirtyTree: {
      name,
      node,
      dirty: nodeDirty,
      ...childrenDirtyTree.map((c) => c.dirtyTree).filter((t) => t.dirty != null).reduce((result, childTree) => {
        result[childTree.name ?? "<unknown>"] = childTree;
        return result;
      }, {})
    },
    paths
  };
}
function pct(rendered, skipped) {
  const total = rendered + skipped;
  return `${rendered} / ${total} (${Math.round(100 * rendered / total)}%)`;
}
function time2(name, start2, end3) {
  const duration = end3 == null ? start2 : end3 - start2;
  return `${name}: ${Math.round(duration * 100) / 100}ms`;
}
function accumulate(iterator, mapper) {
  let sum = 0;
  for (const item of iterator) {
    sum += mapper(item);
  }
  return sum;
}
function cleanupDebugStats(force = false) {
  if (!globalStatsAccumulator) {
    if (force) {
      statsAccumulatorConsumers = 0;
    }
    return;
  }
  if (!force && statsAccumulatorConsumers > 0) {
    return;
  }
  globalStatsAccumulator.destroy();
  globalStatsAccumulator = void 0;
  if (force) {
    statsAccumulatorConsumers = 0;
  }
}

// packages/ag-charts-community/src/scene/shape/text.ts
var _Text = class _Text extends Shape {
  constructor(options) {
    super(options);
    this.x = 0;
    this.y = 0;
    this.lines = [];
    this.text = void 0;
    this.fontCache = void 0;
    this.fontSize = _Text.defaultFontSize;
    this.fontFamily = "sans-serif";
    this.textAlign = "start";
    this.textBaseline = "alphabetic";
    this.boxPadding = 0;
    this.trimText = options?.trimText ?? true;
  }
  onTextChange() {
    this.richText?.clear();
    this.textMap?.clear();
    if (isArray(this.text)) {
      this.lines = [];
      this.richText ?? (this.richText = new Group());
      this.richText.setScene(this.scene);
      this.richText.append(
        this.text.flatMap((s) => toTextString(s.text).split(LineSplitter)).filter(Boolean).map(() => new _Text({ trimText: false }))
      );
    } else {
      const lines = toTextString(this.text).split(LineSplitter);
      this.lines = this.trimText ? lines.map((line) => line.trim()) : lines;
    }
  }
  get font() {
    this.fontCache ?? (this.fontCache = toFontString(this));
    return this.fontCache;
  }
  static measureBBox(text2, x, y, options) {
    if (isArray(text2)) {
      const { font: font3, lineHeight, textAlign, textBaseline } = options;
      const { width: width2, height: height2, lineMetrics } = measureTextSegments(text2, font3);
      const totalHeight = lineHeight ? lineHeight * lineMetrics.length : height2;
      const offsetTop = _Text.calcTopOffset(totalHeight, lineMetrics[0], textBaseline);
      const offsetLeft = _Text.calcLeftOffset(width2, textAlign);
      return new BBox(x - offsetLeft, y - offsetTop, width2, totalHeight);
    } else {
      return _Text.computeBBox(toTextString(text2).split(LineSplitter), x, y, options);
    }
  }
  static computeBBox(lines, x, y, opts) {
    const { font: font3, lineHeight, textAlign, textBaseline } = opts;
    const { width: width2, height: height2, lineMetrics } = cachedTextMeasurer(font3).measureLines(lines);
    const totalHeight = lineHeight ? lineHeight * lineMetrics.length : height2;
    const offsetTop = _Text.calcTopOffset(totalHeight, lineMetrics[0], textBaseline);
    const offsetLeft = _Text.calcLeftOffset(width2, textAlign);
    return new BBox(x - offsetLeft, y - offsetTop, width2, totalHeight);
  }
  static calcTopOffset(height2, textMetrics, textBaseline) {
    switch (textBaseline) {
      case "alphabetic":
        return textMetrics?.ascent ?? 0;
      case "middle":
        return height2 / 2;
      case "bottom":
        return height2;
      default:
        return 0;
    }
  }
  static calcSegmentedTopOffset(height2, lineMetrics, textBaseline) {
    switch (textBaseline) {
      case "alphabetic":
        return lineMetrics[0]?.ascent ?? 0;
      case "middle":
        return lineMetrics.length === 1 ? lineMetrics[0].ascent + lineMetrics[0].segments.reduce(
          (offsetY, segment) => Math.min(offsetY, cachedTextMeasurer(segment).baselineDistance("middle")),
          0
        ) : height2 / 2;
      case "bottom":
        return height2;
      default:
        return 0;
    }
  }
  static calcLeftOffset(width2, textAlign) {
    let offset = 0;
    switch (textAlign) {
      case "center":
        offset = 0.5;
        break;
      case "right":
      case "end":
        offset = 1;
    }
    return width2 * offset;
  }
  getBBox() {
    const bbox = super.getBBox();
    if (!this.textMap?.size || !isArray(this.text))
      return bbox;
    const { height: height2, lineMetrics } = measureTextSegments(this.text, this);
    const offsetTop = _Text.calcSegmentedTopOffset(height2, lineMetrics, this.textBaseline);
    const y = this.y - offsetTop;
    if (bbox.y === y)
      return bbox;
    return new BBox(bbox.x, y, bbox.width, bbox.height);
  }
  computeBBox() {
    this.generateTextMap();
    if (this.textMap?.size) {
      const bbox = BBox.merge(this.textMap.values());
      bbox.x = this.x - _Text.calcLeftOffset(bbox.width, this.textAlign);
      bbox.y = this.y;
      return bbox;
    }
    const { x, y, lines, textBaseline, textAlign } = this;
    const measuredTextBounds = _Text.computeBBox(lines, x, y, { font: this, textBaseline, textAlign });
    if (this.boxing != null)
      measuredTextBounds.grow(this.boxPadding);
    return measuredTextBounds;
  }
  getTextMeasureBBox() {
    return this.computeBBox();
  }
  getPlainText() {
    return toPlainText(this.text);
  }
  isPointInPath(x, y) {
    return this.getBBox()?.containsPoint(x, y) ?? false;
  }
  setScene(scene) {
    this.richText?.setScene(scene);
    super.setScene(scene);
  }
  generateTextMap() {
    if (!isArray(this.text) || this.textMap?.size)
      return;
    this.textMap ?? (this.textMap = /* @__PURE__ */ new Map());
    let offsetY = 0;
    const textNodes = this.richText.children();
    for (const { width: width2, height: height2, ascent, segments } of measureTextSegments(this.text, this).lineMetrics) {
      let offsetX = 0;
      for (const { color: color2, textMetrics, ...segment } of segments) {
        const textNode = textNodes.next().value;
        textNode.x = this.x - width2 / 2 + offsetX;
        textNode.y = ascent + offsetY;
        textNode.setProperties({ ...segment, fill: color2 ?? this.fill });
        const textBBox = textNode.getBBox();
        this.textMap.set(textNode, textBBox);
        offsetX += textMetrics.width;
      }
      offsetY += height2;
    }
  }
  render(renderCtx) {
    const { ctx, stats } = renderCtx;
    if (!this.layerManager || !this.hasRenderableText()) {
      if (stats)
        stats.nodesSkipped += 1;
      return super.render(renderCtx);
    }
    if (isArray(this.text) && this.richText) {
      this.generateTextMap();
      const richTextBBox = this.richText.getBBox();
      const { width: width2, height: height2, lineMetrics } = measureTextSegments(this.text, this);
      let translateX = 0;
      switch (this.textAlign) {
        case "left":
        case "start":
          translateX = width2 / 2;
          break;
        case "right":
        case "end":
          translateX = width2 / -2;
      }
      const translateY = this.y - _Text.calcSegmentedTopOffset(height2, lineMetrics, this.textBaseline);
      this.renderBoxing(renderCtx, richTextBBox.clone().translate(translateX, translateY));
      ctx.save();
      ctx.translate(translateX, translateY);
      this.richText.opacity = this.opacity;
      this.richText.render(renderCtx);
      ctx.restore();
    } else {
      this.renderText(renderCtx);
    }
    if (_Text.debug.check()) {
      const bbox = this.getBBox();
      ctx.lineWidth = this.textMap?.size ? 2 : 1;
      ctx.strokeStyle = this.textMap?.size ? "blue" : "red";
      ctx.strokeRect(bbox.x, bbox.y, bbox.width, bbox.height);
    }
    super.render(renderCtx);
  }
  markDirty(property) {
    this.textMap?.clear();
    return super.markDirty(property);
  }
  renderText(renderCtx) {
    const { fill, stroke: stroke3, strokeWidth, font: font3, textAlign } = this;
    if (!fill && !(stroke3 && strokeWidth) || !this.layerManager) {
      return super.render(renderCtx);
    }
    const { ctx } = renderCtx;
    if (ctx.font !== font3) {
      ctx.font = font3;
    }
    ctx.textAlign = textAlign;
    this.renderBoxing(renderCtx);
    this.fillStroke(ctx);
  }
  renderBoxing(renderCtx, bbox) {
    if (!this.boxing)
      return;
    const textBBox = bbox ?? _Text.computeBBox(this.lines, this.x, this.y, this);
    if (textBBox.width === 0 || textBBox.height === 0)
      return;
    const { x, y, width: width2, height: height2 } = textBBox.grow(this.boxPadding);
    this.boxing.opacity = this.opacity;
    this.boxing.x = x;
    this.boxing.y = y;
    this.boxing.width = width2;
    this.boxing.height = height2;
    this.boxing.preRender(renderCtx);
    this.boxing.render(renderCtx);
  }
  executeFill(ctx) {
    this.renderLines((line, x, y) => ctx.fillText(line, x, y));
  }
  executeStroke(ctx) {
    this.renderLines((line, x, y) => ctx.strokeText(line, x, y));
  }
  renderLines(renderCallback) {
    const { x, y, lines } = this;
    if (!Number.isFinite(x) || !Number.isFinite(y))
      return;
    const measurer3 = cachedTextMeasurer(this);
    const { lineMetrics } = measurer3.measureLines(lines);
    const { textBaseline, lineHeight = measurer3.lineHeight() } = this;
    let offsetY = 0;
    if (textBaseline === "top") {
      offsetY = lineMetrics[0].ascent;
    } else if (textBaseline === "middle" || textBaseline === "bottom") {
      offsetY = lineHeight * (1 - lines.length);
      if (textBaseline === "middle") {
        offsetY /= 2;
        offsetY -= measurer3.baselineDistance(textBaseline);
      } else {
        offsetY -= lineMetrics[0].descent;
      }
    }
    for (const line of lineMetrics) {
      renderCallback(line.text, x, y + offsetY);
      offsetY += lineHeight;
    }
  }
  setFont(props) {
    this.fontFamily = props.fontFamily;
    this.fontSize = props.fontSize;
    this.fontStyle = props.fontStyle;
    this.fontWeight = props.fontWeight;
  }
  setAlign(props) {
    this.textAlign = props.textAlign;
    this.textBaseline = props.textBaseline;
  }
  setBoxing(props) {
    const stroke3 = props.border?.enabled ? props.border?.stroke : void 0;
    if (props.fill != null || stroke3 != null) {
      this.boxing ?? (this.boxing = new Rect({ scene: this.scene }));
      this.boxing.fill = props.fill;
      this.boxing.fillOpacity = props.fillOpacity ?? 1;
      this.boxing.cornerRadius = props.cornerRadius ?? 0;
      this.boxing.stroke = stroke3;
      this.boxing.strokeWidth = props.border?.strokeWidth ?? 0;
      this.boxing.strokeOpacity = props.border?.strokeOpacity ?? 1;
      this.boxPadding = props.padding ?? 0;
    } else if (this.boxing) {
      this.boxing.destroy();
      this.boxing = void 0;
    }
  }
  getBoxingProperties() {
    const { fill, fillOpacity, cornerRadius, stroke: stroke3, strokeWidth, strokeOpacity } = this.boxing ?? {};
    return {
      border: { enabled: stroke3 != null, stroke: stroke3, strokeWidth, strokeOpacity },
      cornerRadius,
      fill,
      fillOpacity,
      padding: this.boxPadding
    };
  }
  toSVG() {
    if (!this.visible || !this.hasRenderableText())
      return;
    const text2 = this.text;
    if (text2 == null)
      return;
    const element2 = createSvgElement("text");
    if (isArray(text2)) {
      for (const segment of text2) {
        const segmentElement = createSvgElement("tspan");
        setSvgFontAttributes(segmentElement, {
          fontSize: segment.fontSize ?? this.fontSize,
          fontFamily: segment.fontFamily ?? this.fontFamily,
          fontWeight: segment.fontWeight ?? this.fontWeight,
          fontStyle: segment.fontStyle ?? this.fontStyle
        });
        this.applySvgFillAttributes(segmentElement);
        segmentElement.textContent = toTextString(segment.text);
        element2.append(segmentElement);
      }
    } else {
      this.applySvgFillAttributes(element2);
      setSvgFontAttributes(element2, this);
      element2.setAttribute(
        "text-anchor",
        {
          center: "middle",
          left: "start",
          right: "end",
          start: "start",
          end: "end"
        }[this.textAlign ?? "start"]
      );
      element2.setAttribute("alignment-baseline", this.textBaseline);
      element2.setAttribute("x", String(this.x));
      element2.setAttribute("y", String(this.y));
      element2.textContent = toTextString(text2);
    }
    return { elements: [element2] };
  }
  hasRenderableText() {
    const { text: text2 } = this;
    if (text2 == null) {
      return false;
    }
    return isArray(text2) ? true : toTextString(text2) !== "";
  }
};
_Text.className = "Text";
_Text.debug = debugLogger_exports.create(true, "scene:text" /* SCENE_TEXT */);
_Text.defaultFontSize = 10;
__decorateClass([
  SceneChangeDetection()
], _Text.prototype, "x", 2);
__decorateClass([
  SceneChangeDetection()
], _Text.prototype, "y", 2);
__decorateClass([
  SceneRefChangeDetection({
    changeCb: (o) => o.onTextChange()
  })
], _Text.prototype, "text", 2);
__decorateClass([
  SceneChangeDetection({
    changeCb: (o) => {
      o.fontCache = void 0;
    }
  })
], _Text.prototype, "fontStyle", 2);
__decorateClass([
  SceneChangeDetection({
    changeCb: (o) => {
      o.fontCache = void 0;
    }
  })
], _Text.prototype, "fontWeight", 2);
__decorateClass([
  SceneChangeDetection({
    changeCb: (o) => {
      o.fontCache = void 0;
    }
  })
], _Text.prototype, "fontSize", 2);
__decorateClass([
  SceneChangeDetection({
    changeCb: (o) => {
      o.fontCache = void 0;
    }
  })
], _Text.prototype, "fontFamily", 2);
__decorateClass([
  SceneChangeDetection()
], _Text.prototype, "textAlign", 2);
__decorateClass([
  SceneChangeDetection()
], _Text.prototype, "textBaseline", 2);
__decorateClass([
  SceneChangeDetection()
], _Text.prototype, "lineHeight", 2);
var Text = _Text;
var RotatableText = class extends Rotatable(Text) {
};
var TransformableText = class extends Rotatable(Translatable(Text)) {
};

// packages/ag-charts-community/src/chart/background/background.ts
var Background = class extends AbstractModuleInstance {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.rectNode = new Rect();
    this.textNode = new Text();
    this.fill = "white";
    this.node = this.createNode();
    this.node.append([this.rectNode, this.textNode]);
    this.visible = true;
    this.cleanup.register(
      ctx.scene.attachNode(this.node),
      ctx.eventsHub.on("layout:complete", (e) => this.onLayoutComplete(e))
    );
  }
  createNode() {
    return new Group({ name: "background", zIndex: 0 /* CHART_BACKGROUND */ });
  }
  onLayoutComplete(e) {
    const { width: width2, height: height2 } = e.chart;
    this.rectNode.width = width2;
    this.rectNode.height = height2;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty,
  ProxyPropertyOnWrite("node", "visible")
], Background.prototype, "visible", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ProxyPropertyOnWrite("rectNode", "fill")
], Background.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Background.prototype, "image", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ProxyPropertyOnWrite("textNode")
], Background.prototype, "text", 2);

// packages/ag-charts-community/src/chart/caption.ts
var Caption = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.id = createId(this);
    this.node = new RotatableText({ zIndex: 1 }).setProperties({
      textAlign: "center",
      pointerEvents: 1 /* None */
    });
    this.enabled = false;
    this.textAlign = "center";
    this.fontSize = 10 /* SMALLER */;
    this.fontFamily = "sans-serif";
    this.wrapping = "always";
    this.padding = 0;
    this.layoutStyle = "block";
    this.truncated = false;
  }
  registerInteraction(moduleCtx, where) {
    return moduleCtx.eventsHub.on("layout:complete", () => this.updateA11yText(moduleCtx, where));
  }
  computeTextWrap(containerWidth, containerHeight) {
    const { text: text2, padding: padding2, wrapping } = this;
    const maxWidth = Math.min(this.maxWidth ?? Infinity, containerWidth) - padding2 * 2;
    const maxHeight = this.maxHeight ?? containerHeight - padding2 * 2;
    const options = { maxWidth, maxHeight, font: this, textWrap: wrapping };
    if (!Number.isFinite(maxWidth) && !Number.isFinite(maxHeight)) {
      this.node.text = text2;
      return;
    }
    let wrappedText;
    if (isArray(text2)) {
      wrappedText = wrapTextSegments(text2, options);
      this.truncated = wrappedText.some(isSegmentTruncated);
    } else {
      wrappedText = wrapText(toTextString(text2), options);
      this.truncated = isTextTruncated(wrappedText);
    }
    this.node.text = wrappedText;
  }
  updateA11yText(moduleCtx, where) {
    const { proxyInteractionService } = moduleCtx;
    if (!this.enabled || !this.text) {
      this.destroyProxyText();
      return;
    }
    const bbox = Transformable.toCanvas(this.node);
    if (!bbox)
      return;
    const { id: domManagerId } = this;
    if (this.proxyText == null) {
      this.proxyText = proxyInteractionService.createProxyElement({ type: "text", domManagerId, where });
      this.proxyTextListeners = [
        this.proxyText.addListener("mousemove", (ev) => this.handleMouseMove(moduleCtx, ev)),
        this.proxyText.addListener("mouseleave", (ev) => this.handleMouseLeave(moduleCtx, ev))
      ];
    }
    const textContent = toPlainText(this.text);
    if (textContent !== this.lastProxyTextContent) {
      this.proxyText.textContent = textContent;
      this.lastProxyTextContent = textContent;
    }
    const { lastProxyBBox } = this;
    if (lastProxyBBox == null || bbox.x !== lastProxyBBox.x || bbox.y !== lastProxyBBox.y || bbox.width !== lastProxyBBox.width || bbox.height !== lastProxyBBox.height) {
      this.proxyText.setBounds(bbox);
      this.lastProxyBBox = { x: bbox.x, y: bbox.y, width: bbox.width, height: bbox.height };
    }
  }
  handleMouseMove(moduleCtx, event) {
    if (event != null && this.enabled && this.truncated) {
      const { x, y } = Transformable.toCanvas(this.node);
      const canvasX = event.sourceEvent.offsetX + x;
      const canvasY = event.sourceEvent.offsetY + y;
      moduleCtx.tooltipManager.updateTooltip(this.id, { canvasX, canvasY, showArrow: false }, [
        { type: "structured", title: toPlainText(this.text) }
      ]);
    }
  }
  handleMouseLeave(moduleCtx, _event) {
    moduleCtx.tooltipManager.removeTooltip(this.id, void 0, true);
  }
  destroy() {
    this.destroyProxyText();
  }
  destroyProxyText() {
    if (this.proxyText == null)
      return;
    for (const cleanup of this.proxyTextListeners ?? []) {
      cleanup();
    }
    this.proxyTextListeners = void 0;
    this.proxyText.destroy();
    this.proxyText = void 0;
    this.lastProxyTextContent = void 0;
    this.lastProxyBBox = void 0;
  }
};
Caption.className = "Caption";
Caption.SMALL_PADDING = 10;
__decorateClass([
  addFakeTransformToInstanceProperty,
  ProxyPropertyOnWrite("node", "visible")
], Caption.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ProxyPropertyOnWrite("node")
], Caption.prototype, "text", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ProxyPropertyOnWrite("node")
], Caption.prototype, "textAlign", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ProxyPropertyOnWrite("node")
], Caption.prototype, "fontStyle", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ProxyPropertyOnWrite("node")
], Caption.prototype, "fontWeight", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ProxyPropertyOnWrite("node")
], Caption.prototype, "fontSize", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ProxyPropertyOnWrite("node")
], Caption.prototype, "fontFamily", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ProxyPropertyOnWrite("node", "fill")
], Caption.prototype, "color", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Caption.prototype, "spacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Caption.prototype, "maxWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Caption.prototype, "maxHeight", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Caption.prototype, "wrapping", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Caption.prototype, "padding", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Caption.prototype, "layoutStyle", 2);

// packages/ag-charts-community/src/chart/chartAxes.ts
var ChartAxes = class extends Array {
  destroy() {
    for (const axis of this) {
      axis.destroy();
    }
    this.length = 0;
  }
  findById(id) {
    return this.find((a) => a.id === id);
  }
  matches(comparison) {
    return this.length === Object.keys(comparison).length && every(
      comparison,
      (id, object2) => isObject(object2) && "type" in object2 && this.findById(id)?.type === object2.type
    );
  }
  getById(id) {
    const axis = this.findById(id);
    if (!axis)
      throw new Error(`Could not find axis by id [${id}].`);
    return axis;
  }
};
var CartesianChartAxes = class extends ChartAxes {
  get ["x" /* X */]() {
    return this.getById("x" /* X */);
  }
  get ["y" /* Y */]() {
    return this.getById("y" /* Y */);
  }
  perpendicular(to) {
    const direction = to.direction === "x" /* X */ ? "y" /* Y */ : "x" /* X */;
    return this[direction];
  }
};
var PolarChartAxes = class extends ChartAxes {
  get ["angle" /* Angle */]() {
    return this.getById("angle" /* Angle */);
  }
  get ["radius" /* Radius */]() {
    return this.getById("radius" /* Radius */);
  }
};

// packages/ag-charts-community/src/chart/chartCaptions.ts
var ChartCaptions = class {
  constructor() {
    this.title = new Caption();
    this.subtitle = new Caption();
    this.footnote = new Caption();
  }
  positionCaptions({ layoutBox }) {
    const { title, subtitle, footnote } = this;
    const maxHeight = layoutBox.height / 10;
    if (title.enabled) {
      this.positionCaption("top", title, layoutBox, maxHeight);
      this.shrinkLayoutByCaption("top", title, layoutBox);
    }
    if (subtitle.enabled) {
      this.positionCaption("top", subtitle, layoutBox, maxHeight);
      this.shrinkLayoutByCaption("top", subtitle, layoutBox);
    }
    if (footnote.enabled) {
      this.positionCaption("bottom", footnote, layoutBox, maxHeight);
      this.shrinkLayoutByCaption("bottom", footnote, layoutBox);
    }
  }
  positionAbsoluteCaptions(ctx) {
    const { title, subtitle, footnote } = this;
    const { rect: rect2 } = ctx.series;
    for (const caption of [title, subtitle, footnote]) {
      if (caption.layoutStyle !== "overlay")
        continue;
      if (caption.textAlign === "left") {
        caption.node.x = rect2.x + caption.padding;
      } else if (caption.textAlign === "right") {
        const bbox = caption.node.getBBox();
        caption.node.x = rect2.x + rect2.width - bbox.width - caption.padding;
      }
    }
  }
  computeX(align2, layoutBox) {
    if (align2 === "left") {
      return layoutBox.x;
    } else if (align2 === "right") {
      return layoutBox.x + layoutBox.width;
    }
    return layoutBox.x + layoutBox.width / 2;
  }
  positionCaption(vAlign, caption, layoutBox, maxHeight) {
    if (!caption.text)
      return;
    const { lineMetrics } = isArray(caption.text) ? measureTextSegments(caption.text, caption) : cachedTextMeasurer(caption).measureLines(toTextString(caption.text));
    const containerHeight = Math.max(lineMetrics[0].height, maxHeight);
    caption.node.x = this.computeX(caption.textAlign, layoutBox) + caption.padding;
    caption.node.y = layoutBox.y + (vAlign === "top" ? 0 : layoutBox.height) + caption.padding;
    caption.node.textBaseline = vAlign;
    caption.computeTextWrap(layoutBox.width, containerHeight);
  }
  shrinkLayoutByCaption(vAlign, caption, layoutBox) {
    if (caption.layoutStyle === "block") {
      const bbox = caption.node.getBBox().clone();
      const { spacing = 0 } = caption;
      if (vAlign === "bottom" && isArray(caption.text)) {
        bbox.y -= bbox.height;
      }
      layoutBox.shrink(
        vAlign === "top" ? Math.ceil(bbox.y - layoutBox.y + bbox.height + spacing) : Math.ceil(layoutBox.y + layoutBox.height - bbox.y + spacing),
        vAlign
      );
    }
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ChartCaptions.prototype, "title", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChartCaptions.prototype, "subtitle", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChartCaptions.prototype, "footnote", 2);

// packages/ag-charts-community/src/api/preset/chartTypeOriginator.ts
var chartTypes = [
  "candlestick",
  "hollow-candlestick",
  "ohlc",
  "line",
  "step-line",
  "hlc",
  "high-low"
];
var ChartTypeOriginator = class {
  constructor(chartService) {
    this.chartService = chartService;
    this.mementoOriginatorKey = "chartType";
  }
  createMemento() {
    let chartType = this.chartService.publicApi?.getOptions()?.chartType;
    chartType ?? (chartType = "candlestick");
    return chartType;
  }
  guardMemento(blob) {
    return blob == null || chartTypes.includes(blob);
  }
  restoreMemento(_version, _mementoVersion, memento) {
    if (memento == null)
      return;
    const options = { chartType: memento };
    this.chartService.publicApi?.updateDelta(options).catch((e) => logger_exports.error("error restoring state", e));
  }
};

// packages/ag-charts-community/src/version.ts
var VERSION = "13.1.0";

// packages/ag-charts-community/src/api/state/historyManager.ts
var NOT_FOUND = Symbol("previous-memento-not-found");
var HistoryManager = class {
  constructor(eventsHub) {
    this.history = [];
    this.historyIndex = -1;
    this.originators = /* @__PURE__ */ new Map();
    this.clearState = /* @__PURE__ */ new Map();
    this.maxHistoryLength = 100;
    this.debug = debugLogger_exports.create(true, "history");
    this.cleanup = new CleanupRegistry();
    this.cleanup.register(
      eventsHub.on("series:undo", this.undo.bind(this)),
      eventsHub.on("series:redo", this.redo.bind(this))
    );
  }
  destroy() {
    this.cleanup.flush();
  }
  addMementoOriginator(originator) {
    this.originators.set(originator.mementoOriginatorKey, originator);
    this.clearState.set(originator.mementoOriginatorKey, originator.createMemento());
    this.debugEvent("History add originator:", originator.mementoOriginatorKey);
  }
  clear() {
    this.debug(`History clear:`, Object.keys(this.originators));
    this.history = [];
    this.historyIndex = -1;
    for (const [mementoOriginatorKey, originator] of this.originators.entries()) {
      this.clearState.set(mementoOriginatorKey, originator.createMemento());
    }
  }
  record(label, ...originators) {
    if (this.historyIndex < this.history.length - 1) {
      this.history = this.history.slice(0, this.historyIndex + 1);
    }
    if (this.history.length > this.maxHistoryLength) {
      this.history = this.history.slice(-this.maxHistoryLength);
    }
    const mementos = /* @__PURE__ */ new Map();
    for (const originator of originators) {
      if (!this.originators.has(originator.mementoOriginatorKey)) {
        throw new Error(
          `Originator [${originator.mementoOriginatorKey}] has not been added to the HistoryManager.`
        );
      }
      mementos.set(originator.mementoOriginatorKey, originator.createMemento());
    }
    this.history.push({ label, mementos });
    this.historyIndex = this.history.length - 1;
    this.debugEvent(`History record: [${label}]`);
  }
  undo() {
    const undoAction = this.history[this.historyIndex];
    if (!undoAction)
      return;
    for (const mementoOriginatorKey of undoAction.mementos.keys()) {
      const previousMemento = this.findPreviousMemento(mementoOriginatorKey);
      if (previousMemento === NOT_FOUND) {
        throw new Error(`Could not find previous memento for [${mementoOriginatorKey}].`);
      }
      this.restoreMemento(mementoOriginatorKey, previousMemento);
    }
    this.historyIndex -= 1;
    this.debugEvent(`History undo: [${undoAction.label}]`);
  }
  redo() {
    const redoAction = this.history[this.historyIndex + 1];
    if (!redoAction)
      return;
    for (const [mementoOriginatorKey, memento] of redoAction.mementos.entries()) {
      this.restoreMemento(mementoOriginatorKey, memento);
    }
    this.historyIndex += 1;
    this.debugEvent(`History redo: [${redoAction.label}]`);
  }
  findPreviousMemento(mementoOriginatorKey) {
    for (let i = this.historyIndex - 1; i >= 0; i--) {
      if (this.history[i].mementos.has(mementoOriginatorKey)) {
        return this.history[i].mementos.get(mementoOriginatorKey);
      }
    }
    if (this.clearState.has(mementoOriginatorKey)) {
      return this.clearState.get(mementoOriginatorKey);
    }
    return NOT_FOUND;
  }
  restoreMemento(mementoOriginatorKey, memento) {
    this.originators.get(mementoOriginatorKey)?.restoreMemento(VERSION, VERSION, memento);
  }
  debugEvent(...logContent) {
    this.debug(
      ...logContent,
      this.history.map((action, index) => index === this.historyIndex ? `** ${action.label} **` : action.label)
    );
  }
};

// packages/ag-charts-community/src/api/state/stateManager.ts
var StateManager = class {
  constructor() {
    this.caretaker = new MementoCaretaker(VERSION);
    this.state = /* @__PURE__ */ new Map();
  }
  setState(originator, value) {
    if (objectsEqual(this.state.get(originator.mementoOriginatorKey), value)) {
      return;
    }
    this.setStateAndRestore(originator, value);
  }
  setStateAndRestore(originator, value) {
    this.state.set(originator.mementoOriginatorKey, value);
    this.restoreState(originator);
  }
  restoreState(originator) {
    const { caretaker, state } = this;
    if (!state.has(originator.mementoOriginatorKey))
      return;
    const value = state.get(originator.mementoOriginatorKey);
    caretaker.restore({ version: caretaker.version, [originator.mementoOriginatorKey]: value }, originator);
  }
};

// packages/ag-charts-community/src/styles.css
var styles_default = '.ag-charts-wrapper,.ag-charts-wrapper:after,.ag-charts-wrapper:before,.ag-charts-wrapper *,.ag-charts-wrapper *:after,.ag-charts-wrapper *:before{box-sizing:border-box}.ag-charts-wrapper{--align-items: center;--justify-content: center;position:relative;user-select:none;-webkit-user-select:none;-webkit-tap-highlight-color:rgba(0,0,0,0)}.ag-charts-wrapper--safe-horizontal{--justify-content: flex-start}.ag-charts-wrapper--safe-vertical{--align-items: flex-start}.ag-charts-tab-guard{width:0%;height:0%;position:absolute;pointer-events:none}.ag-charts-canvas-background{position:absolute}.ag-charts-canvas-center{width:100%;height:100%;position:absolute;touch-action:auto;pointer-events:auto;display:flex;align-items:var(--align-items);justify-content:var(--justify-content)}.ag-charts-canvas-container,.ag-charts-canvas{position:relative;user-select:none;-webkit-user-select:none}.ag-charts-canvas-container>*,.ag-charts-canvas>*{pointer-events:none}.ag-charts-canvas canvas{display:block}.ag-charts-series-area{outline:none;pointer-events:auto;position:absolute}.ag-charts-swapchain{top:0;left:0;outline:none;opacity:0;pointer-events:none;position:absolute;width:100%;height:100%}.ag-charts-swapchain:focus-visible{opacity:1}.ag-charts-canvas-proxy,.ag-charts-canvas-overlay{inset:0;pointer-events:none;position:absolute;user-select:none;-webkit-user-select:none}.ag-charts-canvas-overlay>*{position:absolute;pointer-events:auto}.ag-charts-theme-default,.ag-charts-theme-default-dark{--ag-charts-accent-color: #2196f3;--ag-charts-background-color: #fff;--ag-charts-border-color: #dddddd;--ag-charts-border-radius: 4px;--ag-charts-chart-background-color: #fff;--ag-charts-chart-padding: 20px;--ag-charts-focus-shadow: 0 0 0 3px #2196f3;--ag-charts-foreground-color: #181d1f;--ag-charts-font-family: Verdana, sans-serif;--ag-charts-font-size: 12px;--ag-charts-font-weight: 400;--ag-charts-popup-shadow: 0 0 16px rgba(0, 0, 0, .15);--ag-charts-subtle-text-color: #8c8c8c;--ag-charts-text-color: #181d1f;--ag-charts-chrome-background-color: #fafafa;--ag-charts-chrome-font-family: Verdana, sans-serif;--ag-charts-chrome-font-size: 12px;--ag-charts-chrome-font-weight: 400;--ag-charts-chrome-subtle-text-color: #8c8c8c;--ag-charts-chrome-text-color: #181d1f;--ag-charts-button-background-color: #fff;--ag-charts-button-border: 1px solid #dddddd;--ag-charts-button-font-weight: normal;--ag-charts-button-text-color: inherit;--ag-charts-input-background-color: #fff;--ag-charts-input-border: 1px solid #dddddd;--ag-charts-input-text-color: #181d1f;--ag-charts-menu-background-color: #fafafa;--ag-charts-menu-border: 1px solid #dddddd;--ag-charts-menu-text-color: #181d1f;--ag-charts-panel-background-color: #fafafa;--ag-charts-panel-text-color: #181d1f;--ag-charts-tooltip-background-color: #fafafa;--ag-charts-tooltip-border: 1px solid #dddddd;--ag-charts-tooltip-text-color: #181d1f;--ag-charts-tooltip-subtle-text-color: #8c8c8c;--ag-charts-crosshair-label-background-color: #fafafa;--ag-charts-crosshair-label-text-color: #181d1f;--ag-charts-spacing: 4px;--ag-charts-icon-size: 16px;--ag-charts-focus-color: color-mix(in srgb, var(--ag-charts-background-color), var(--ag-charts-accent-color) 12%);--ag-charts-input-border-radius: var(--ag-charts-border-radius);--ag-charts-input-focus-border-color: var(--ag-charts-accent-color);--ag-charts-input-focus-text-color: var(--ag-charts-accent-color);--ag-charts-input-disabled-background-color: color-mix( in srgb, var(--ag-charts-chrome-background-color), var(--ag-charts-foreground-color) 6% );--ag-charts-input-disabled-border-color: var(--ag-charts-border-color);--ag-charts-input-disabled-text-color: color-mix( in srgb, var(--ag-charts-chrome-background-color), var(--ag-charts-input-text-color) 50% );--ag-charts-input-placeholder-text-color: color-mix( in srgb, var(--ag-charts-input-background-color), var(--ag-charts-input-text-color) 60% );--ag-charts-button-border-radius: var(--ag-charts-border-radius);--ag-charts-button-focus-background-color: color-mix( in srgb, var(--ag-charts-button-background-color), var(--ag-charts-accent-color) 12% );--ag-charts-button-focus-border-color: var(--ag-charts-accent-color);--ag-charts-button-focus-text-color: var(--ag-charts-accent-color);--ag-charts-button-disabled-background-color: color-mix( in srgb, var(--ag-charts-chrome-background-color), var(--ag-charts-foreground-color) 6% );--ag-charts-button-disabled-border-color: var(--ag-charts-border-color);--ag-charts-button-disabled-text-color: color-mix( in srgb, var(--ag-charts-chrome-background-color), var(--ag-charts-chrome-text-color) 50% );--ag-charts-checkbox-background-color: color-mix( in srgb, var(--ag-charts-background-color), var(--ag-charts-foreground-color) 35% );--ag-charts-checkbox-checked-background-color: var(--ag-charts-accent-color);--ag-charts-tooltip-border-radius: var(--ag-charts-border-radius);--ag-charts-menu-border-radius: var(--ag-charts-border-radius);--ag-charts-chrome-font-size-small: var(--ag-charts-chrome-font-size);--ag-charts-chrome-font-size-medium: calc(var(--ag-charts-chrome-font-size) * (13 / 12));--ag-charts-chrome-font-size-large: calc(var(--ag-charts-chrome-font-size) * (14 / 12));--ag-charts-border: 1px solid var(--ag-charts-border-color);--ag-charts-focus-border: 1px solid var(--ag-charts-accent-color);--ag-charts-focus-border-shadow: 0 0 0 3px color-mix(in srgb, transparent, var(--ag-charts-accent-color) 20%);--ag-charts-layer-menu: 6;--ag-charts-layer-ui-overlay: 5;--ag-charts-layer-tooltip: 4;--ag-charts-layer-toolbar: 3;--ag-charts-layer-crosshair: 2;--ag-charts-layer-annotations: 1}.ag-charts-theme-default-dark{--ag-charts-focus-color: color-mix(in srgb, var(--ag-charts-background-color), var(--ag-charts-accent-color) 22%)}.ag-chart-canvas-wrapper .ag-charts-theme-default{--ag-charts-border-radius: var(--ag-border-radius, 4px);--ag-charts-border: var(--ag-borders-critical, solid 1px) var(--ag-charts-border-color);--ag-charts-focus-shadow: var(--ag-focus-shadow, 0 0 0 3px var(--ag-charts-accent-color));--ag-charts-focus-border-shadow: var( --ag-focus-shadow, 0 0 0 3px color-mix(in srgb, transparent, var(--ag-charts-accent-color) 20%) )}.ag-charts-icon{display:block;width:20px;height:20px;speak:none;speak:never;mask:var(--icon) center / contain no-repeat;background-color:currentColor;transition:background-color .25s ease-in-out}.ag-charts-icon-align-center{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBkPSJNNyAxMGg2djFIN3pNNCA3aDEydjFINHptMSA2aDEwdjFINXoiLz48L3N2Zz4=)}.ag-charts-icon-align-left{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBkPSJNNCAxMGg2djFINHptMC0zaDEydjFINHptMCA2aDEwdjFINHoiLz48L3N2Zz4=)}.ag-charts-icon-align-right{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBkPSJNMTAgMTBoNnYxaC02ek00IDdoMTJ2MUg0em0yIDZoMTB2MUg2eiIvPjwvc3ZnPg==)}.ag-charts-icon-arrow-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0iTTE1LjI5MyA0LjVIMTIuNXYtMUgxN3Y0aC0xVjUuMjA3bC05LjY0NiA5LjY0Ny0uNzA4LS43MDh6IiBmaWxsPSIjMDAwIi8+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03IDE2YTIuNSAyLjUgMCAxIDEtNSAwIDIuNSAyLjUgMCAwIDEgNSAwbS0yLjUgMS41YTEuNSAxLjUgMCAxIDAgMC0zIDEuNSAxLjUgMCAwIDAgMCAzIiBmaWxsPSIjMDAwIi8+PC9zdmc+)}.ag-charts-icon-arrow-down-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik02IDhMMS41IDhMMTAgMThMMTguNSA4TDE0IDhMMTQgM0w2IDNMNiA4Wk03IDRMNyA5SDMuNjYyNDRMMTAgMTYuNDU2TDE2LjMzNzYgOUwxMyA5TDEzIDRMNyA0WiIgZmlsbD0iYmxhY2siLz4KPC9zdmc+Cg==)}.ag-charts-icon-arrow-up-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xNCAxMkgxOC41TDEwIDJMMS41IDEySDZMNi4wMDAwMiAxN0gxNFYxMlpNMTMgMTZWMTFIMTYuMzM3NkwxMCAzLjU0NDA1TDMuNjYyNDQgMTFIN0w3LjAwMDAyIDE2SDEzWiIgZmlsbD0iYmxhY2siLz4KPC9zdmc+Cg==)}.ag-charts-icon-callout-annotation{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMyA0LjVBMS41IDEuNSAwIDAgMSA0LjUgM2gxMUExLjUgMS41IDAgMCAxIDE3IDQuNXY4YTEuNSAxLjUgMCAwIDEtMS41IDEuNWgtNC41MTRhMjYgMjYgMCAwIDAtMi4wMTcgMS41NGwtLjMxNC4yNmMtLjU1LjQ1Ny0xLjExNS45MjYtMS43NiAxLjQtLjY2OS40OTEtMS41NjItLjAxMi0xLjU2Mi0uOFYxNEg0LjVBMS41IDEuNSAwIDAgMSAzIDEyLjV6TTQuNSA0YS41LjUgMCAwIDAtLjUuNXY4YS41LjUgMCAwIDAgLjUuNWgxLjgzM3YzLjM3MmEzNiAzNiAwIDAgMCAxLjY3OC0xLjMzOGwuMzItLjI2NWEyNiAyNiAwIDAgMSAyLjIyNS0xLjY4NWwuMTI2LS4wODRIMTUuNWEuNS41IDAgMCAwIC41LS41di04YS41LjUgMCAwIDAtLjUtLjV6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=)}.ag-charts-icon-candlestick-series{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNyAxdjNoMnYxMkg3djNINnYtM0g0VjRoMlYxek01IDVoM3YxMEg1ek0xMSAxNFY2aDJWMy4yNWgxVjZoMnY4aC0ydjIuNzVoLTFWMTR6bTEtN2gzdjZoLTN6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=)}.ag-charts-icon-close{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJtNSA1IDEwIDEwTTUgMTUgMTUgNSIgc3Ryb2tlPSIjMDAwIi8+PC9zdmc+)}.ag-charts-icon-comment-annotation{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNy41MTMgMy45OTVhNi41IDYuNSAwIDAgMSA2LjA5OCAxMS40MWMtLjU4OC4zOTMtMS4yMTcuNTM2LTEuODI5LjU4NWExMyAxMyAwIDAgMS0xLjI3LjAxN0EyNyAyNyAwIDAgMCAxMCAxNkg0LjVhLjUuNSAwIDAgMS0uNS0uNVYxMHEwLS4yNDctLjAwNy0uNTEzYy0uMDA4LS40MTYtLjAxNi0uODU3LjAxNy0xLjI2OS4wNS0uNjEyLjE5Mi0xLjI0LjU4NS0xLjgzYTYuNSA2LjUgMCAwIDEgMi45MTgtMi4zOTNtMy41Ni42MWE1LjUgNS41IDAgMCAwLTUuNjQ2IDIuMzRjLS4yNjYuMzk3LS4zNzkuODQyLS40MiAxLjM1NC0uMDMuMzYtLjAyMi43MTgtLjAxNSAxLjEwOFE1IDkuNjg5IDUgMTB2NWg1cS4zMTEuMDAxLjU5My4wMDhjLjM5LjAwNy43NDcuMDE1IDEuMTA4LS4wMTUuNTEyLS4wNDEuOTU3LS4xNTQgMS4zNTUtLjQyYTUuNSA1LjUgMCAwIDAtMS45ODMtOS45NjciIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-crosshair-add-line{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZD0iTTEwIDUuNWEuNS41IDAgMCAxIC41LjV2My41aDMuODc1YS41LjUgMCAwIDEgMCAxSDEwLjV2NC4yNWEuNS41IDAgMSAxLTEgMFYxMC41SDUuNjI1YS41LjUgMCAxIDEgMC0xSDkuNVY2YS41LjUgMCAwIDEgLjUtLjUiLz48L3N2Zz4=)}.ag-charts-icon-date-range-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMiAyaDF2MTZIMnptMTUgMGgxdjE2aC0xeiIgZmlsbD0iIzE4MUQxRiIvPjxwYXRoIGQ9Ik0xMy4xNTcgMTFINXYtMWg3Ljc5M0wxMSA4LjIwN2wuNzA3LS43MDcgMy4xODIgMy4xODItMy4xODIgMy4xODItLjcwNy0uNzA3eiIgZmlsbD0iIzAwMCIvPjwvc3ZnPg==)}.ag-charts-icon-date-price-range-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMyAySDJ2MTZoMXptMy41MDcgNC44OUw4LjUgNC44OTVWMTBINXYxaDMuNXY3aDF2LTdoNS4wODhsLTEuOTU3IDEuOTU3LjcwNy43MDcgMy4xODItMy4xODJMMTMuMzM4IDcuM2wtLjcwNy43MDdMMTQuNjI0IDEwSDkuNVY0LjkzMmwxLjk1NyAxLjk1Ny43MDctLjcwN0w4Ljk4MiAzIDUuOCA2LjE4MnoiIGZpbGw9IiMxODFEMUYiLz48L3N2Zz4=)}.ag-charts-icon-delete{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZD0iTTguNDk2IDguOTk2QS41LjUgMCAwIDEgOSA5LjQ5MnY0YS41LjUgMCAxIDEtMSAuMDA4di00YS41LjUgMCAwIDEgLjQ5Ni0uNTA0TTEyIDkuNWEuNS41IDAgMCAwLTEgMHY0YS41LjUgMCAwIDAgMSAweiIvPjxwYXRoIGZpbGw9IiMxMzE3MjIiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTYgNVYzLjVBMi41IDIuNSAwIDAgMSA4LjUgMWgzQTIuNSAyLjUgMCAwIDEgMTQgMy41VjVoMi44MzNhLjUuNSAwIDAgMSAwIDFIMTV2MTAuMjVjMCAuNDE1LS4wNjYuODYzLS4zIDEuMjIxLS4yNTcuMzk0LS42NzIuNjEyLTEuMi42MTJoLTdjLS41MjggMC0uOTQzLS4yMTgtMS4yLS42MTItLjIzNC0uMzU4LS4zLS44MDYtLjMtMS4yMjFWNkgzLjMzM2EuNS41IDAgMCAxIDAtMXptMS0xLjVBMS41IDEuNSAwIDAgMSA4LjUgMmgzQTEuNSAxLjUgMCAwIDEgMTMgMy41VjVIN3pNNiAxNi4yNVY2aDh2MTAuMjVjMCAuMzM1LS4wNTkuNTU0LS4xMzguNjc1LS4wNTUuMDg1LS4xNC4xNTgtLjM2Mi4xNThoLTdjLS4yMjIgMC0uMzA3LS4wNzMtLjM2Mi0uMTU4LS4wOC0uMTIxLS4xMzgtLjM0LS4xMzgtLjY3NSIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+)}.ag-charts-icon-disjoint-channel,.ag-charts-icon-disjoint-channel-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTkuMDI4IDE3LjQ2YTIuMjUgMi4yNSAwIDAgMC00LjA5Mi0xLjg1bC05LjUxMS0yLjM3OGEyLjI1IDIuMjUgMCAxIDAtLjIyNS45NzRsOS40NzUgMi4zNjlhMi4yNTEgMi4yNTEgMCAwIDAgNC4zNTMuODg2bS0xLjY2Mi0xLjk2NWExLjI1IDEuMjUgMCAxIDEtLjg4NSAyLjMzOCAxLjI1IDEuMjUgMCAwIDEgLjg4NS0yLjMzOE00LjM0MyAxMy42NjlhMS4yNSAxLjI1IDAgMSAwLTIuMzM4LS44ODUgMS4yNSAxLjI1IDAgMCAwIDIuMzM4Ljg4NU0zLjk3IDguNzY5YTIuMjUgMi4yNSAwIDAgMCAxLjQ1NS0yLjExbDkuNTExLTIuMzc4YTIuMjUgMi4yNSAwIDEgMC0uMjYtLjk2NUw1LjIgNS42ODVhMi4yNSAyLjI1IDAgMSAwLTEuMjMgMy4wODRtLjM3My0yLjU0N2ExLjI1IDEuMjUgMCAxIDEtMi4zMzguODg1IDEuMjUgMS4yNSAwIDAgMSAyLjMzOC0uODg1bTEzLjc1LTMuNDM4YTEuMjUgMS4yNSAwIDEgMS0yLjMzOC44ODUgMS4yNSAxLjI1IDAgMCAxIDIuMzM4LS44ODUiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-drag-handle{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSI1Ljc1IiBjeT0iNy43NSIgcj0iLjc1IiBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii41Ii8+PGNpcmNsZSBjeD0iOS43NSIgY3k9IjcuNzUiIHI9Ii43NSIgZmlsbD0iIzAwMCIgZmlsbC1vcGFjaXR5PSIuNSIvPjxjaXJjbGUgY3g9IjEzLjc1IiBjeT0iNy43NSIgcj0iLjc1IiBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii41Ii8+PGNpcmNsZSBjeD0iMTMuNzUiIGN5PSIxMS43NSIgcj0iLjc1IiBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii41Ii8+PGNpcmNsZSBjeD0iOS43NSIgY3k9IjExLjc1IiByPSIuNzUiIGZpbGw9IiMwMDAiIGZpbGwtb3BhY2l0eT0iLjUiLz48Y2lyY2xlIGN4PSI1Ljc1IiBjeT0iMTEuNzUiIHI9Ii43NSIgZmlsbD0iIzAwMCIgZmlsbC1vcGFjaXR5PSIuNSIvPjwvc3ZnPg==)}.ag-charts-icon-fibonacci-retracement-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBkPSJNMiA1aDEydjFIMnoiLz48Y2lyY2xlIGN4PSIxNS43NSIgY3k9IjUuNSIgcj0iMS43NSIgc3Ryb2tlPSIjMDAwIi8+PGNpcmNsZSBjeD0iNC4yNSIgY3k9IjE0LjUiIHI9IjEuNzUiIHN0cm9rZT0iIzAwMCIvPjxwYXRoIGZpbGw9IiMwMDAiIGQ9Ik0xOCAxNUg2di0xaDEyem0wLTQuNUgydi0xaDE2eiIvPjwvc3ZnPg==)}.ag-charts-icon-fibonacci-retracement-trend-based-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBkPSJtNC45OTYgMTIuNjc0IDMuMjkxLTUuNzQzLjg2OC40OTctMy4yOTEgNS43NDN6Ii8+PGNpcmNsZSBjeD0iOS43NSIgY3k9IjUuNSIgcj0iMS43NSIgc3Ryb2tlPSIjMDAwIi8+PGNpcmNsZSBjeD0iNC4zNTEiIGN5PSIxNC41IiByPSIxLjc1IiBzdHJva2U9IiMwMDAiLz48cGF0aCBmaWxsPSIjMDAwIiBkPSJNMTggNmgtN1Y1aDd6bTAgNC41aC03di0xaDd6bTAgNC41SDZ2LTFoMTJ6Ii8+PC9zdmc+)}.ag-charts-icon-fill-color{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJtOC4wNzEgNC4wNi0uOTI0LS45MjQuNzA3LS43MDcgNy4yODggNy4yODgtNC45NSA0Ljk1YTMuNSAzLjUgMCAwIDEtNC45NSAwbC0xLjQxNC0xLjQxNGEzLjUgMy41IDAgMCAxIDAtNC45NXptLjcwNy43MDhMNC41MzYgOS4wMWEyLjUgMi41IDAgMCAwIDAgMy41MzZMNS45NSAxMy45NmEyLjUgMi41IDAgMCAwIDMuNTM1IDBsNC4yNDMtNC4yNDN6bTYuOSA3LjIwMi0uMzQ1LjM2My0uMzQ0LS4zNjNhLjUuNSAwIDAgMSAuNjg4IDBtLS4zNDUgMS4wOGE4IDggMCAwIDAtLjI4LjMyMyA0LjMgNC4zIDAgMCAwLS40MDkuNTgyYy0uMTEzLjIwMS0uMTQ0LjMyNi0uMTQ0LjM3OGEuODMzLjgzMyAwIDAgMCAxLjY2NyAwYzAtLjA1Mi0uMDMxLS4xNzctLjE0NC0uMzc4YTQuMyA0LjMgMCAwIDAtLjQxLS41ODIgOCA4IDAgMCAwLS4yOC0uMzIybS0uMzQ0LTEuMDguMzQ0LjM2My4zNDQtLjM2My4wMDIuMDAyLjAwNC4wMDQuMDEzLjAxMmE2IDYgMCAwIDEgLjIwNi4yMDhjLjEzMS4xMzYuMzA4LjMyNy40ODUuNTQ1LjE3Ni4yMTUuMzYzLjQ2Ny41MDcuNzI0LjEzNy4yNDMuMjczLjU1My4yNzMuODY4YTEuODMzIDEuODMzIDAgMSAxLTMuNjY3IDBjMC0uMzE1LjEzNi0uNjI1LjI3My0uODY4LjE0NC0uMjU3LjMzLS41MDkuNTA3LS43MjRhOSA5IDAgMCAxIC42NDUtLjcwOGwuMDQ2LS4wNDUuMDEzLS4wMTIuMDA0LS4wMDR6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=)}.ag-charts-icon-hollow-candlestick-series{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1vcGFjaXR5PSIuMTUiIGQ9Ik01IDVoM3YxMEg1eiIvPjxwYXRoIGZpbGw9IiMxMzE3MjIiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTcgMXYzaDJ2MTJIN3YzSDZ2LTNINFY0aDJWMXpNNSA1aDN2MTBINXptNyAyaDN2NmgtM3ptLTEgN1Y2aDJWMy4yNWgxVjZoMnY4aC0ydjIuNzVoLTFWMTR6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=)}.ag-charts-icon-horizontal-line,.ag-charts-icon-horizontal-line-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNLjUgOS41aDcuMzA2YTIuMjUgMi4yNSAwIDAgMSA0LjM4OCAwSDE5LjV2MWgtNy4zMDZhMi4yNSAyLjI1IDAgMCAxLTQuMzg4IDBILjV6bTkuNSAxLjc1YTEuMjUgMS4yNSAwIDEgMCAwLTIuNSAxLjI1IDEuMjUgMCAwIDAgMCAyLjUiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-line-color{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTQuMjQyIDIuNzIyYy0uNjEyIDAtMS4yLjI0My0xLjYzMi42NzVsLTEuMzQzIDEuMzQ0YS41LjUgMCAwIDAtLjExMi4xMTJMNC4wNSAxMS45NTljLS4yMDcuMjA3LS4zNi40Ni0uNDQ2Ljc0di4wMDFsLS42OSAyLjc2N3YuMDAyYS44Mi44MiAwIDAgMCAxLjAyMiAxLjAyMWguMDAybDIuNjM0LS44MjJjLjI4LS4wODUuNTM0LS4yMzcuNzQtLjQ0M2w3LjEwNy03LjEwOGEuNS41IDAgMCAwIC4xMTItLjExMmwxLjM0My0xLjM0M2EyLjMwOCAyLjMwOCAwIDAgMC0xLjYzMi0zLjk0TTE0LjEyMiA3bDEuMDQ0LTEuMDQ1YTEuMzA4IDEuMzA4IDAgMSAwLTEuODQ5LTEuODVMMTIuMjcxIDUuMTV6bS0yLjU1OC0xLjE0Mi02LjgwNyA2LjgwOWEuOC44IDAgMCAwLS4xOTYuMzI1bC0uNzUgMi40NjggMi40Ny0uNzQ5YS44LjggMCAwIDAgLjMyNS0uMTk0bDYuODA4LTYuODF6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=)}.ag-charts-icon-line-series{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJtMTcuMzYyIDQuODczLTQuNTk0IDYuNjU0LTQuODUtMy4zMTctNC4yNTEgNi45NzctLjg1NC0uNTJMNy42MTIgNi43OWw0Ljg5OSAzLjM1IDQuMDI4LTUuODM2eiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+)}.ag-charts-icon-line-style-dashed{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBkPSJNMiA5aDR2MUgyem0xMiAwaDR2MWgtNHpNOCA5aDR2MUg4eiIvPjwvc3ZnPg==)}.ag-charts-icon-line-style-dotted{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIyLjUiIGN5PSI5LjUiIHI9Ii41IiBmaWxsPSIjMDAwIi8+PGNpcmNsZSBjeD0iNC41IiBjeT0iOS41IiByPSIuNSIgZmlsbD0iIzAwMCIvPjxjaXJjbGUgY3g9IjYuNSIgY3k9IjkuNSIgcj0iLjUiIGZpbGw9IiMwMDAiLz48Y2lyY2xlIGN4PSI4LjUiIGN5PSI5LjUiIHI9Ii41IiBmaWxsPSIjMDAwIi8+PGNpcmNsZSBjeD0iMTAuNSIgY3k9IjkuNSIgcj0iLjUiIGZpbGw9IiMwMDAiLz48Y2lyY2xlIGN4PSIxMi41IiBjeT0iOS41IiByPSIuNSIgZmlsbD0iIzAwMCIvPjxjaXJjbGUgY3g9IjE0LjUiIGN5PSI5LjUiIHI9Ii41IiBmaWxsPSIjMDAwIi8+PGNpcmNsZSBjeD0iMTYuNSIgY3k9IjkuNSIgcj0iLjUiIGZpbGw9IiMwMDAiLz48L3N2Zz4=)}.ag-charts-icon-line-style-solid{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBkPSJNMiA5aDE2djFIMnoiLz48L3N2Zz4=)}.ag-charts-icon-line-with-markers-series{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJtMTguMTk4IDQuODg4LTMuNTU2IDQuOTE4YTIuMjUgMi4yNSAwIDEgMS0zLjg2Ni43NWwtMS40MzItLjlhMi4yNCAyLjI0IDAgMCAxLTIuMDA5LjQzNWwtMy44MjggNi40MjgtLjg2LS41MTJMNi40NSA5LjYyM2EyLjI1IDIuMjUgMCAxIDEgMy41MS0uNzYxbDEuMzI5LjgzNWEyLjI0IDIuMjQgMCAwIDEgMi41NTctLjQ5N2wzLjU0Mi00Ljg5OHptLTQuOTYgNS4xNTNhMS4yNSAxLjI1IDAgMSAwLS42NCAyLjQxOSAxLjI1IDEuMjUgMCAwIDAgLjY0LTIuNDE5TTkuMSA4LjMyMXEuMDY2LS4xOTIuMDY3LS40MDRhMS4yNSAxLjI1IDAgMSAwLS4wNjcuNDA0IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=)}.ag-charts-icon-lock,.ag-charts-icon-locked{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTAuMjA3IDMuNzY0YTIuODk0IDIuODk0IDAgMCAwLTIuODk1IDIuODk0VjloNS43ODlWNi42NThhMi44OTQgMi44OTQgMCAwIDAtMi44OTUtMi44OTRNMTQuMSA5VjYuNjU4YTMuODk0IDMuODk0IDAgMSAwLTcuNzg5IDB2Mi4zNDlBMi41IDIuNSAwIDAgMCA0IDExLjV2M0EyLjUgMi41IDAgMCAwIDYuNSAxN2g4YTIuNSAyLjUgMCAwIDAgMi41LTIuNXYtM0EyLjUgMi41IDAgMCAwIDE0LjUgOXpNNi41IDEwQTEuNSAxLjUgMCAwIDAgNSAxMS41djNBMS41IDEuNSAwIDAgMCA2LjUgMTZoOGExLjUgMS41IDAgMCAwIDEuNS0xLjV2LTNhMS41IDEuNSAwIDAgMC0xLjUtMS41eiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+)}.ag-charts-icon-measurer-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsLXJ1bGU9ImV2ZW5vZGQiIGNsaXAtcnVsZT0iZXZlbm9kZCIgZD0ibTQuNDYxIDEyLjcxIDEuNTMyLTEuNTMxIDEuNDE0IDEuNDE0LjcwNy0uNzA3TDYuNyAxMC40NzJsMS41MzItMS41MzMgMiAyIC43MDctLjcwNy0yLTIgNi4wMS02LjAxIDIuODMgMi44MjhMNS4wNSAxNy43NzggMi4yMjIgMTQuOTVsMS41MzItMS41MzIgMS40MTQgMS40MTQuNzA3LS43MDd6TS44MDggMTQuOTVsLjcwNy0uNzA3TDE0LjI0MyAxLjUxNWwuNzA3LS43MDcuNzA3LjcwNyAyLjgyOCAyLjgyOC43MDcuNzA3LS43MDcuNzA3TDUuNzU3IDE4LjQ4NWwtLjcwNy43MDctLjcwNy0uNzA3LTIuODI4LTIuODI4em0xMS4wNzgtNi44MzVMMTAuNDcgNi43bC43MDctLjcwNyAxLjQxNSAxLjQxNHptLjgyNC0zLjY1NCAxIDEgLjcwOC0uNzA3LTEtMXoiIGZpbGw9IiMxODFEMUYiLz48L3N2Zz4=)}.ag-charts-icon-note-annotation{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMyA0LjVBMS41IDEuNSAwIDAgMSA0LjUgM2gxMUExLjUgMS41IDAgMCAxIDE3IDQuNXY4YTEuNSAxLjUgMCAwIDEtMS41IDEuNWgtMy4yMWwtMS40NjkgMi41N2ExIDEgMCAwIDEtMS42ODIuMDg1TDcuMjQzIDE0SDQuNUExLjUgMS41IDAgMCAxIDMgMTIuNXpNNC41IDRhLjUuNSAwIDAgMC0uNS41djhhLjUuNSAwIDAgMCAuNS41aDMuMjU3bDIuMTk2IDMuMDc0TDExLjcxIDEzaDMuNzlhLjUuNSAwIDAgMCAuNS0uNXYtOGEuNS41IDAgMCAwLS41LS41eiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNi41IDYuNUEuNS41IDAgMCAxIDcgNmg2YS41LjUgMCAwIDEgMCAxSDdhLjUuNSAwIDAgMS0uNS0uNU02LjUgOS41QS41LjUgMCAwIDEgNyA5aDZhLjUuNSAwIDAgMSAwIDFIN2EuNS41IDAgMCAxLS41LS41IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=)}.ag-charts-icon-ohlc-series{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZD0iTTEzIDExaC0zdi0xaDNWM2gxdjJoNHYxaC00djExaC0xek02IDE3di0yaDN2LTFINlY0SDV2MUgydjFoM3YxMXoiLz48L3N2Zz4=)}.ag-charts-icon-pan-end{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZD0ibTYuNjQ2IDEzLjgxMy0uMzUzLjM1NC43MDcuNzA3LjM1NC0uMzU0ek0xMS4xNjYgMTBsLjM1NC4zNTQuMzU0LS4zNTQtLjM1NC0uMzU0ek03LjM1NSA1LjQ4IDcgNS4xMjZsLS43MDcuNzA3LjM1My4zNTR6bTAgOS4wNCA0LjE2Ni00LjE2Ni0uNzA3LS43MDgtNC4xNjcgNC4xNjd6bTQuMTY2LTQuODc0TDcuMzU0IDUuNDhsLS43MDguNzA3IDQuMTY3IDQuMTY3ek0xMy4wODMgNXYxMGgxVjV6Ii8+PC9zdmc+)}.ag-charts-icon-pan-left{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTIuNzkgNS44MzMgOC42MjUgMTBsNC4xNjYgNC4xNjctLjcwNy43MDdMNy4yMSAxMGw0Ljg3My00Ljg3NHoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-pan-right{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNy4yMSAxNC4xNjcgMTEuMzc2IDEwIDcuMjEgNS44MzNsLjcwNy0uNzA3TDEyLjc5IDEwbC00Ljg3MyA0Ljg3NHoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-pan-start{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZD0iTTYgNXYxMGgxVjV6TTkuNjI0IDEwbDQuMTY2LTQuMTY3LS43MDctLjcwN0w4LjIxIDEwbDQuODc0IDQuODc0LjcwNy0uNzA3eiIvPjwvc3ZnPg==)}.ag-charts-icon-parallel-channel,.ag-charts-icon-parallel-channel-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTcuNzIgNS4zMzFBMi4yNSAyLjI1IDAgMSAwIDE0LjcwNSAzLjZsLTkuNDkgNC41NjJhMi4yNSAyLjI1IDAgMSAwIC4yMDkgMS4wMWw5LjY2Mi00LjY0NmEyLjI1IDIuMjUgMCAwIDAgMi42MzQuODA1bS4zNzMtMi41NDdhMS4yNSAxLjI1IDAgMSAxLTIuMzM4Ljg4NSAxLjI1IDEuMjUgMCAwIDEgMi4zMzgtLjg4NU00LjM0MyA4LjY3YTEuMjUgMS4yNSAwIDEgMS0yLjMzOC44ODUgMS4yNSAxLjI1IDAgMCAxIDIuMzM4LS44ODVNNS4zMDcgMTYuNzI4YTIuMjUgMi4yNSAwIDEgMS0uNTI1LS44NThsOS45MjMtNC43N2EyLjI1IDIuMjUgMCAxIDEgLjM4MS45MjZ6bS0uOTY0LjI3NGExLjI1IDEuMjUgMCAxIDEtMi4zMzguODg1IDEuMjUgMS4yNSAwIDAgMSAyLjMzOC0uODg1bTEzLjAyMy01LjEwNmExLjI1IDEuMjUgMCAxIDAtLjg4NS0yLjMzOSAxLjI1IDEuMjUgMCAwIDAgLjg4NSAyLjMzOSIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+)}.ag-charts-icon-position-bottom{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii4yNSIgZD0iTTMgMTBoMTR2MUgzem0zLTNoOHYxSDZ6Ii8+PHBhdGggZmlsbD0iIzAwMCIgZD0iTTYgMTNoOHYxSDZ6Ii8+PC9zdmc+)}.ag-charts-icon-position-center{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBkPSJNMyAxMGgxNHYxSDN6Ii8+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1vcGFjaXR5PSIuMjUiIGQ9Ik02IDdoOHYxSDZ6bTAgNmg4djFINnoiLz48L3N2Zz4=)}.ag-charts-icon-position-top{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBmaWxsPSIjMDAwIiBmaWxsLW9wYWNpdHk9Ii4yNSIgZD0iTTMgMTBoMTR2MUgzeiIvPjxwYXRoIGZpbGw9IiMwMDAiIGQ9Ik02IDdoOHYxSDZ6Ii8+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1vcGFjaXR5PSIuMjUiIGQ9Ik02IDEzaDh2MUg2eiIvPjwvc3ZnPg==)}.ag-charts-icon-price-label-annotation{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNC41IDNBMS41IDEuNSAwIDAgMCAzIDQuNVYxM2ExLjUgMS41IDAgMCAwIDEuNSAxLjVoLjgzM3YuMDU3Yy4yNDItLjI5OS41OTctLjUwMyAxLS41NDhWMTMuNUg0LjVBLjUuNSAwIDAgMSA0IDEzVjQuNWEuNS41IDAgMCAxIC41LS41aDExYS41LjUgMCAwIDEgLjUuNXY4YS41LjUgMCAwIDEtLjUuNWgtNC44MThsLS4xMjYuMDg0YTI2IDI2IDAgMCAwLTIuMjI1IDEuNjg1bC0uMzIuMjY1LS4wNjguMDU2YTEuNSAxLjUgMCAwIDEtMi42MDkgMS4zNTRjLjAzMy43NjMuOTA1IDEuMjM4IDEuNTYuNzU2LjY0Ni0uNDc0IDEuMjEtLjk0MyAxLjc2MS0xLjRsLjMxMy0uMjZBMjYgMjYgMCAwIDEgMTAuOTg2IDE0SDE1LjVhMS41IDEuNSAwIDAgMCAxLjUtMS41di04QTEuNSAxLjUgMCAwIDAgMTUuNSAzeiIgY2xpcC1ydWxlPSJldmVub2RkIi8+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNOC43MTYgMTQuODE1YTIuMjUgMi4yNSAwIDEgMS00LjIxIDEuNTkzIDIuMjUgMi4yNSAwIDAgMSA0LjIxLTEuNTkzbS0xLjY2MiAxLjk2NmExLjI1IDEuMjUgMCAxIDAtLjg4NS0yLjMzOSAxLjI1IDEuMjUgMCAwIDAgLjg4NSAyLjMzOSIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+)}.ag-charts-icon-price-range-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNOS4wNDYgMTVWNS44NzdoLjk0MlYxNXoiIGZpbGw9IiMxODFEMUYiLz48cGF0aCBkPSJNOS4wNDYgMTVWNS44NzdoLjk0MlYxNXoiIGZpbGw9IiMxODFEMUYiLz48cGF0aCBkPSJNOS41IDYuMjI4IDcuMTY3IDguMzc2IDYuNSA3Ljc2MiA5LjUgNWwzIDIuNzYyLS42NjcuNjE0eiIgZmlsbD0iIzAwMCIvPjxwYXRoIGQ9Ik0yIDE4di0xaDE2djF6TTIgM1YyaDE2djF6IiBmaWxsPSIjMTgxRDFGIi8+PC9zdmc+)}.ag-charts-icon-reset{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTIuMDQgNC40NDVhNS44MSA1LjgxIDAgMCAwLTcuMjU3IDIuNDUzLjUuNSAwIDAgMS0uODY1LS41MDJBNi44MSA2LjgxIDAgMSAxIDMgOS44MTNhLjUuNSAwIDAgMSAxIDAgNS44MSA1LjgxIDAgMSAwIDguMDQtNS4zNjgiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjxwYXRoIGZpbGw9IiMwMDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTQuMjg5IDMuMDAyYS41LjUgMCAwIDEgLjUuNXYyLjY1NWgyLjY1NWEuNS41IDAgMCAxIDAgMUg0LjI5YS41LjUgMCAwIDEtLjUtLjVWMy41MDJhLjUuNSAwIDAgMSAuNS0uNSIgY2xpcC1ydWxlPSJldmVub2RkIi8+PC9zdmc+)}.ag-charts-icon-settings{--icon: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjAgMjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgc3R5bGU9ImZpbGwtcnVsZTpldmVub2RkIj48cGF0aCBkPSJNMTAgMTNhMyAzIDAgMSAwIDAtNiAzIDMgMCAwIDAgMCA2bTAtMWEyIDIgMCAxIDEtLjAwMS0zLjk5OUEyIDIgMCAwIDEgMTAgMTIiLz48cGF0aCBkPSJNMi4zMSAxNC4zNDVjLS44MTctMS40OTEuMDI3LTIuNDk5LjQ3NC0yLjg2NS41MzEtLjQzNC45NjktLjM2NS45NzItMS40OC0uMDAzLTEuMTE1LS40NDEtMS4wNDYtLjk3Mi0xLjQ4MS0uNDU0LS4zNzEtMS4zMTctMS40MDUtLjQzNC0yLjkzNmwuMDA1LS4wMDljLjg4NC0xLjUyIDIuMjA3LTEuMjkgMi43NTUtMS4wODMuNjQxLjI0My44MDEuNjU2IDEuNzY4LjEwMS45NjQtLjU2LjY4Ni0uOTA0Ljc5Ni0xLjU4Mi4wOTQtLjU3OC41NTktMS44NDMgMi4zMjYtMS44NDNoLjAxYzEuNzU5LjAwNSAyLjIyMiAxLjI2NiAyLjMxNiAxLjg0My4xMS42NzgtLjE2OCAxLjAyMi43OTYgMS41ODIuOTY3LjU1NSAxLjEyNy4xNDIgMS43NjgtLjEwMS41NDktLjIwOCAxLjg3Ni0uNDM4IDIuNzYgMS4wOTJzLjAyIDIuNTY1LS40MzQgMi45MzZjLS41MzEuNDM1LS45NjkuMzY2LS45NzIgMS40ODEuMDAzIDEuMTE1LjQ0MSAxLjA0Ni45NzIgMS40OC40NTQuMzcyIDEuMzE3IDEuNDA2LjQzNCAyLjkzN2wtLjAwNS4wMDljLS44ODQgMS41Mi0yLjIwNyAxLjI5LTIuNzU1IDEuMDgzLS42NDEtLjI0My0uODAxLS42NTYtMS43NjgtLjEwMS0uOTY0LjU2LS42ODYuOTA0LS43OTYgMS41ODEtLjA5NC41NzktLjU1OSAxLjg0NC0yLjMyNiAxLjg0NGgtLjAxYy0xLjc1OS0uMDA1LTIuMjIyLTEuMjY2LTIuMzE2LTEuODQ0LS4xMS0uNjc3LjE2OC0xLjAyMS0uNzk2LTEuNTgxLS45NjctLjU1NS0xLjEyNy0uMTQyLTEuNzY4LjEwMS0uNTQ5LjIwOC0xLjg3Ni40MzgtMi43Ni0xLjA5MmwtLjAyLS4wMzZ6TTkuOTg0IDIuMTYySDEwYzEuMzU1IDAgMS4zNDIgMS4wMzkgMS4zNTMgMS40MjUuMDA4LjMxMi4wNCAxLjE2IDEuMjU5IDEuODcybC4wMTUuMDA4YzEuMjI1LjcgMS45NzYuMzA0IDIuMjUxLjE1NS4zMzctLjE4MyAxLjIyNi0uNzExIDEuOTAyLjQ0NWwuMDA4LjAxNGMuNjc4IDEuMTczLS4yMjkgMS42ODItLjU1OCAxLjg4NC0uMjY2LjE2My0uOTg0LjYxNS0uOTkxIDIuMDI3di4wMTZjLjAwNyAxLjQxMi43MjUgMS44NjQuOTkxIDIuMDI3LjMyOC4yMDEgMS4yMjkuNzA3LjU2NiAxLjg3bC0uMDA4LjAxNGMtLjY3NyAxLjE3NC0xLjU3MS42NDMtMS45MS40NTktLjI3NS0uMTQ5LTEuMDI2LS41NDUtMi4yNTEuMTU0bC0uMDE1LjAwOWMtMS4yMTkuNzEyLTEuMjUxIDEuNTYtMS4yNTkgMS44NzItLjAxMS4zODYuMDAyIDEuNDI1LTEuMzUzIDEuNDI1cy0xLjM0Mi0xLjAzOS0xLjM1My0xLjQyNWMtLjAwOC0uMzEyLS4wNC0xLjE2LTEuMjU5LTEuODcybC0uMDE1LS4wMDljLTEuMjI1LS42OTktMS45NzYtLjMwMy0yLjI1MS0uMTU0LS4zMzYuMTgzLTEuMjE5LjcwNi0xLjg5NC0uNDMybC0uMDE2LS4wMjdjLS42NzgtMS4xNzQuMjI5LTEuNjgyLjU1OC0xLjg4NC4yNjYtLjE2My45ODQtLjYxNS45OTEtMi4wMjd2LS4wMTZjLS4wMDctMS40MTItLjcyNS0xLjg2NC0uOTkxLTIuMDI3LS4zMjgtLjIwMS0xLjIyOS0uNzA3LS41NjYtMS44N2wuMDA4LS4wMTRjLjY3Ny0xLjE3NCAxLjU3MS0uNjQzIDEuOTEtLjQ1OS4yNzUuMTQ5IDEuMDI2LjU0NSAyLjI1MS0uMTU1bC4wMTUtLjAwOGMxLjIxOS0uNzEyIDEuMjUxLTEuNTYgMS4yNTktMS44NzIuMDEtLjM4NC0uMDAyLTEuNDE3IDEuMzM3LTEuNDI1Ii8+PC9zdmc+)}.ag-charts-icon-step-line-series{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzE4MUQxRiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNiA0aDV2OGgzVjhoNXYxaC00djRoLTVWNUg3djEwSDJ2LTFoNHoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-text-annotation{--icon: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMCAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik00IDRIMTZWN0gxNVY1SDEwLjVWMTVIMTRWMTZINlYxNUg5LjVWNUg1VjdINFY0WiIgZmlsbD0iYmxhY2siLz4KPC9zdmc+Cg==)}.ag-charts-icon-trend-line,.ag-charts-icon-trend-line-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNS4zMTQgMTAuOTM4YTIuMjUgMi4yNSAwIDEgMSAuMDEtMWg5LjM1MmEyLjI1IDIuMjUgMCAxIDEgLjAxIDF6bS0yLjE4OS43MjlhMS4yNSAxLjI1IDAgMSAwIDAtMi41IDEuMjUgMS4yNSAwIDAgMCAwIDIuNW0xMy43NSAwYTEuMjUgMS4yNSAwIDEgMCAwLTIuNSAxLjI1IDEuMjUgMCAwIDAgMCAyLjUiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-unlock,.ag-charts-icon-unlocked{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTAuNjUxIDMuNWEyLjg5NCAyLjg5NCAwIDAgMC0yLjg5NCAyLjg5NFY5SDE0LjVhMi41IDIuNSAwIDAgMSAyLjUgMi41djNhMi41IDIuNSAwIDAgMS0yLjUgMi41aC04QTIuNSAyLjUgMCAwIDEgNCAxNC41di0zQTIuNSAyLjUgMCAwIDEgNi41IDloLjI1N1Y2LjM5NGEzLjg5NCAzLjg5NCAwIDEgMSA3Ljc4OSAwIC41LjUgMCAwIDEtMSAwQTIuODk0IDIuODk0IDAgMCAwIDEwLjY1IDMuNU02LjUgMTBBMS41IDEuNSAwIDAgMCA1IDExLjV2M0ExLjUgMS41IDAgMCAwIDYuNSAxNmg4YTEuNSAxLjUgMCAwIDAgMS41LTEuNXYtM2ExLjUgMS41IDAgMCAwLTEuNS0xLjV6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=)}.ag-charts-icon-vertical-line,.ag-charts-icon-vertical-line-drawing{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTAuNSA3LjgwNmEyLjI1IDIuMjUgMCAwIDEgMCA0LjM4OFYxOS41aC0xdi03LjMwNmEyLjI1IDIuMjUgMCAwIDEgMC00LjM4OFYuNWgxem0tLjUuOTQ0YTEuMjUgMS4yNSAwIDEgMSAwIDIuNSAxLjI1IDEuMjUgMCAwIDEgMC0yLjUiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-zoom-in{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZD0iTTEwIDUuNWEuNS41IDAgMCAxIC41LjV2My41aDMuODc1YS41LjUgMCAwIDEgMCAxSDEwLjV2NC4yNWEuNS41IDAgMSAxLTEgMFYxMC41SDUuNjI1YS41LjUgMCAxIDEgMC0xSDkuNVY2YS41LjUgMCAwIDEgLjUtLjUiLz48L3N2Zz4=)}.ag-charts-icon-zoom-out{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzAwMCIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNS41IDEwYS41LjUgMCAwIDEgLjUtLjVoOGEuNS41IDAgMCAxIDAgMUg2YS41LjUgMCAwIDEtLjUtLjUiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-high-low-series{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNNyA0aDJ2MTJINFY0aDNNNSA1aDN2MTBINXpNMTEgMTRWNmg1djhoLTVtMS03aDN2NmgtM3oiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==)}.ag-charts-icon-hlc-series{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyMCIgaGVpZ2h0PSIyMCIgZmlsbD0ibm9uZSI+PHBhdGggZmlsbD0iIzEzMTcyMiIgZmlsbC1ydWxlPSJldmVub2RkIiBkPSJtMTguMTYzIDEuODM3LTUuMzM0IDExLjYyMUw2Ljk1NyA4LjEybC00LjE5OSA5LjYyMi0uOTE2LS40IDQuNzU2LTEwLjlMMTIuNDkgMTEuOCAxNy4yNTQgMS40MnoiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjxwYXRoIGZpbGw9IiMwMDAiIGZpbGwtb3BhY2l0eT0iLjQiIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTUuODI1IDIuNzA0LjU1IDEzLjc4NWwuOTAyLjQzIDQuNzI0LTkuOTE5IDYuMDM0IDUuMDI5IDMuMjU1LTguMTQtLjkyOC0uMzctMi43NDUgNi44NnptNy44NTIgMTQuNjM2IDUuNzgtMTMuMTM5LS45MTUtLjQwMi01LjIxOSAxMS44Ni02LjAwNS01LjUwNC0zLjI3OCA3LjY0OC45Mi4zOTQgMi43MjItNi4zNTJ6IiBjbGlwLXJ1bGU9ImV2ZW5vZGQiLz48L3N2Zz4=)}.ag-charts-icon-chevron-right{--icon: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjAgMjAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik03LjQ3IDUuNDdhLjc1Ljc1IDAgMCAxIDEuMDYgMGw0IDRhLjc1Ljc1IDAgMCAxIDAgMS4wNmwtNCA0YS43NS43NSAwIDAgMS0xLjA2LTEuMDZMMTAuOTQgMTAgNy40NyA2LjUzYS43NS43NSAwIDAgMSAwLTEuMDYiIGZpbGw9IiMwMDAiLz48L3N2Zz4=)}.ag-charts-icon-zoom-in-alt{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLXpvb20taW4iPjxjaXJjbGUgY3g9IjExIiBjeT0iMTEiIHI9IjgiLz48bGluZSB4MT0iMjEiIHgyPSIxNi42NSIgeTE9IjIxIiB5Mj0iMTYuNjUiLz48bGluZSB4MT0iMTEiIHgyPSIxMSIgeTE9IjgiIHkyPSIxNCIvPjxsaW5lIHgxPSI4IiB4Mj0iMTQiIHkxPSIxMSIgeTI9IjExIi8+PC9zdmc+)}.ag-charts-icon-zoom-out-alt{--icon: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9ImN1cnJlbnRDb2xvciIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2UtbGluZWNhcD0icm91bmQiIHN0cm9rZS1saW5lam9pbj0icm91bmQiIGNsYXNzPSJsdWNpZGUgbHVjaWRlLXpvb20tb3V0Ij48Y2lyY2xlIGN4PSIxMSIgY3k9IjExIiByPSI4Ii8+PGxpbmUgeDE9IjIxIiB4Mj0iMTYuNjUiIHkxPSIyMSIgeTI9IjE2LjY1Ii8+PGxpbmUgeDE9IjgiIHgyPSIxNCIgeTE9IjExIiB5Mj0iMTEiLz48L3N2Zz4=)}.ag-charts-input{--input-layer-active: 1;--input-layer-focus: 2;--input-padding: calc(var(--ag-charts-spacing) * 2);--input-padding-large: calc(var(--ag-charts-spacing) * 2.5);color:var(--ag-charts-input-text-color);font-family:var(--ag-charts-chrome-font-family);font-size:var(--ag-charts-chrome-font-size-large);transition-duration:.25s;transition-property:none;transition-timing-function:ease-out}.ag-charts-input:focus-visible{outline:var(--ag-charts-focus-border);box-shadow:var(--ag-charts-focus-border-shadow);z-index:var(--input-layer-focus)}.ag-charts-button{background:var(--ag-charts-button-background-color);border:var(--ag-charts-button-border);border-radius:var(--ag-charts-button-border-radius);color:var(--ag-charts-button-text-color);cursor:pointer;padding:var(--input-padding);transition-property:background,border-color}.ag-charts-button:hover{background:var(--ag-charts-focus-color)}.ag-charts-button:has(.ag-charts-icon){padding:2px}.ag-charts-checkbox{--checkbox-transition-duration: .1s;appearance:none;background:var(--ag-charts-checkbox-background-color);border-radius:calc(var(--ag-charts-border-radius) * 9);cursor:pointer;height:18px;margin:0;transition-duration:var(--checkbox-transition-duration);transition-property:margin;width:29px}.ag-charts-checkbox:before{display:block;background:var(--ag-charts-input-background-color);border-radius:calc(var(--ag-charts-border-radius) * 7);content:" ";height:14px;margin:2px;transition-duration:var(--checkbox-transition-duration);transition-property:margin;transition-timing-function:var(--ag-charts-input-transition-easing);width:14px}.ag-charts-checkbox:checked{background:var(--ag-charts-checkbox-checked-background-color)}.ag-charts-checkbox:checked:before{margin-left:13px}.ag-charts-select{background:var(--ag-charts-input-background-color);border:var(--ag-charts-input-border);border-radius:var(--ag-charts-input-border-radius);padding:3px 2px 4px;font-size:inherit}.ag-charts-textarea{--textarea-line-height: 1.38;background:var(--ag-charts-input-background-color);border:var(--ag-charts-input-border);border-radius:var(--ag-charts-input-border-radius);line-height:var(--textarea-line-height);font-family:var(--ag-charts-chrome-font-family);font-size:var(--ag-charts-chrome-font-size-large);padding:var(--input-padding-large) var(--input-padding)}.ag-charts-textarea::placeholder{color:var(--ag-charts-input-placeholder-text-color)}.ag-charts-proxy-container{pointer-events:none;position:absolute}.ag-charts-proxy-legend-toolbar{pointer-events:auto}.ag-charts-proxy-legend-toolbar>div[role=listitem]{pointer-events:none}.ag-charts-proxy-elem{-webkit-appearance:none;appearance:none;background:none;border:none;color:#0000;overflow:hidden;pointer-events:auto;position:absolute}.ag-charts-proxy-elem::-moz-range-thumb,.ag-charts-proxy-elem::-moz-range-track{opacity:0}.ag-charts-proxy-elem::-webkit-slider-runnable-track,.ag-charts-proxy-elem::-webkit-slider-thumb{opacity:0}.ag-charts-proxy-elem:focus-visible{outline:var(--ag-charts-focus-border);box-shadow:var(--ag-charts-focus-border-shadow)}.ag-charts-proxy-elem svg{display:block}.ag-charts-proxy-scrollbar-slider:focus-visible{outline:none;box-shadow:none}.ag-charts-proxy-scrollbar-thumb-focus{border:var(--ag-charts-focus-border);box-shadow:var(--ag-charts-focus-border-shadow);box-sizing:border-box;opacity:0;pointer-events:none}.ag-charts-proxy-scrollbar-slider:focus-visible~.ag-charts-proxy-scrollbar-thumb-focus{opacity:1}.ag-charts-focus-indicator{position:absolute;display:block;pointer-events:none;user-select:none;-webkit-user-select:none;width:100%;height:100%}.ag-charts-focus-indicator>div{position:absolute;outline:solid 1px var(--ag-charts-chrome-background-color);box-shadow:var(--ag-charts-focus-shadow)}.ag-charts-focus-indicator>svg{width:100%;height:100%;fill:none;overflow:visible}.ag-charts-focus-svg-outer-path{stroke:var(--ag-charts-chrome-background-color);stroke-width:4px}.ag-charts-focus-svg-inner-path{stroke:var(--ag-charts-accent-color);stroke-width:2px}.ag-charts-overlay{color:#181d1f;pointer-events:none}.ag-charts-overlay.ag-charts-dark-overlay{color:#fff}.ag-charts-overlay--loading{color:#8c8c8c}.ag-charts-overlay__loading-background{background:#fff;pointer-events:none}.ag-charts-overlay.ag-charts-dark-overlay .ag-charts-overlay__loading-background{background:#192232}.ag-charts-tooltip{--tooltip-arrow-size: 8px;--tooltip-row-spacing: 8px;--tooltip-column-spacing: 16px;position:fixed;inset:unset;margin:0;padding:0;overflow:visible;top:var(--top, 0px);left:var(--left, 0px);width:max-content;max-width:100%;font-family:var(--ag-charts-chrome-font-family);font-size:var(--ag-charts-chrome-font-size);font-weight:var(--ag-charts-chrome-font-weight);color:var(--ag-charts-tooltip-text-color);background:var(--ag-charts-tooltip-background-color);border:var(--ag-charts-tooltip-border);border-radius:var(--ag-charts-tooltip-border-radius);box-shadow:var(--ag-charts-popup-shadow)}.ag-charts-tooltip--compact .ag-charts-tooltip-content{--tooltip-row-spacing: 2px;--tooltip-column-spacing: 8px;padding:3px 6px}.ag-charts-tooltip--arrow-top:before,.ag-charts-tooltip--arrow-right:before,.ag-charts-tooltip--arrow-bottom:before,.ag-charts-tooltip--arrow-left:before{content:"";position:absolute;display:block;width:var(--tooltip-arrow-size);height:var(--tooltip-arrow-size);border:inherit;border-bottom-color:transparent;border-right-color:transparent;background:inherit;clip-path:polygon(0 0,100% 0,100% 1px,1px 100%,0 100%)}.ag-charts-tooltip--arrow-top:before{bottom:100%;left:50%;transform:translate(-50%) translateY(calc(var(--tooltip-arrow-size) * .5)) rotate(45deg)}.ag-charts-tooltip--arrow-bottom:before{top:100%;left:50%;transform:translate(-50%) translateY(calc(var(--tooltip-arrow-size) * -.5)) rotate(225deg)}.ag-charts-tooltip--arrow-left:before{right:100%;top:50%;transform:translateY(-50%) translate(calc(var(--tooltip-arrow-size) * .5)) rotate(315deg)}.ag-charts-tooltip--arrow-right:before{left:100%;top:50%;transform:translateY(-50%) translate(calc(var(--tooltip-arrow-size) * -.5)) rotate(135deg)}.ag-charts-tooltip--no-interaction{pointer-events:none;user-select:none;-webkit-user-select:none}.ag-charts-tooltip--wrap-always{overflow-wrap:break-word;word-break:break-word;hyphens:none}.ag-charts-tooltip--wrap-hyphenate{overflow-wrap:break-word;word-break:break-word;hyphens:auto}.ag-charts-tooltip--wrap-on-space{overflow-wrap:normal;word-break:normal}.ag-charts-tooltip--wrap-never{white-space:nowrap}.ag-charts-tooltip-heading,.ag-charts-tooltip-title,.ag-charts-tooltip-label,.ag-charts-tooltip-value{overflow:hidden;text-overflow:ellipsis}.ag-charts-tooltip-content{display:grid;grid:auto-flow minmax(1em,auto) / 1fr;padding:8px 12px;gap:var(--tooltip-row-spacing)}.ag-charts-tooltip-content:has(.ag-charts-tooltip-symbol){grid:auto-flow minmax(1em,auto) / auto 1fr}.ag-charts-tooltip-heading{grid-column:1 / -1}.ag-charts-tooltip-symbol{grid-column:1 / 2;place-self:center}.ag-charts-tooltip-symbol svg{display:block}.ag-charts-tooltip-title{grid-column:-2 / -1}.ag-charts-tooltip-row{grid-column:1 / -1;display:flex;gap:var(--tooltip-column-spacing);align-items:baseline;justify-content:space-between;overflow:hidden}.ag-charts-tooltip-row--inline{grid-column:-2 / -1}.ag-charts-tooltip-label{flex:1;min-width:0}.ag-charts-tooltip-value{min-width:0}.ag-charts-tooltip-footer{grid-column:1 / -1;color:var(--ag-charts-tooltip-subtle-text-color);text-align:center}.ag-charts-popover{position:absolute;border:var(--ag-charts-border);border-radius:var(--ag-charts-border-radius);background:var(--ag-charts-panel-background-color);color:var(--ag-charts-chrome-text-color);font-family:var(--ag-charts-chrome-font-family);font-size:var(--ag-charts-chrome-font-size);font-weight:var(--ag-charts-chrome-font-weight);box-shadow:var(--ag-charts-popup-shadow);z-index:var(--ag-charts-layer-ui-overlay)}.ag-charts-menu{--item-padding: 6px 12px;--icon-color: var(--ag-charts-menu-text-color);display:grid;grid:auto-flow auto / 1fr;column-gap:12px;font-size:var(--ag-charts-chrome-font-size)}.ag-charts-menu:has(.ag-charts-menu__icon,.ag-charts-menu__row--stroke-width-visible){grid:auto-flow auto / auto 1fr}.ag-charts-menu__row--stroke-width-visible:before{content:"";height:var(--strokeWidth);width:12px;background:var(--icon-color)}.ag-charts-menu__row--stroke-width-visible[aria-disabled=true]:before{filter:grayscale(1);opacity:.5}.ag-charts-menu__row{display:grid;grid-column:1 / -1;grid-template-columns:subgrid;align-items:center;padding:var(--item-padding)}.ag-charts-menu__row:not(.ag-charts-menu__row--active){cursor:pointer}.ag-charts-menu__row:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.ag-charts-menu__row:last-child{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.ag-charts-menu__row:focus{background:var(--ag-charts-focus-color)}.ag-charts-menu__row:focus-visible{outline:var(--ag-charts-focus-border);box-shadow:var(--ag-charts-focus-border-shadow);z-index:var(--ag-charts-layer-menu)}.ag-charts-menu__row--active{--icon-color: var(--ag-charts-accent-color);background:var(--ag-charts-focus-color);color:var(--ag-charts-accent-color)}.ag-charts-menu__label{grid-column:-1 / span 1}.ag-charts-toolbar{--toolbar-gap: calc(var(--ag-charts-spacing) * 2);--toolbar-size: 34px;--toolbar-button-padding: 6px;align-items:center;display:flex;flex-wrap:nowrap;position:absolute}.ag-charts-toolbar__button{align-items:center;background:var(--ag-charts-chrome-background-color);border:var(--ag-charts-button-border);color:var(--ag-charts-button-text-color);cursor:pointer;display:flex;font-family:var(--ag-charts-chrome-font-family);font-size:var(--ag-charts-chrome-font-size-medium);font-weight:var(--ag-charts-chrome-font-weight);justify-content:center;min-height:var(--toolbar-size);min-width:var(--toolbar-size);padding:var(--toolbar-button-padding);position:relative;transition:background-color .25s ease-in-out,border-color .25s ease-in-out,color .25s ease-in-out;white-space:nowrap}.ag-charts-toolbar__button:hover{background:var(--ag-charts-focus-color);z-index:1}.ag-charts-toolbar__button:focus-visible{outline:var(--ag-charts-focus-border);box-shadow:var(--ag-charts-focus-border-shadow);z-index:calc(var(--ag-charts-layer-ui-overlay) + 1)}.ag-charts-toolbar__button--active{background:var(--ag-charts-focus-color);border-color:var(--ag-charts-accent-color);color:var(--ag-charts-accent-color);z-index:2;+.ag-charts-toolbar__button{border-left-color:var(--ag-charts-accent-color)}}.ag-charts-toolbar__button[aria-disabled=true]{background:var(--ag-charts-button-disabled-background-color);color:var(--ag-charts-button-disabled-text-color);cursor:default}.ag-charts-toolbar--horizontal{flex-direction:row;.ag-charts-toolbar__button{border-right-width:0}.ag-charts-toolbar__button--first{border-bottom-left-radius:var(--ag-charts-border-radius);border-top-left-radius:var(--ag-charts-border-radius);margin:0}.ag-charts-toolbar__button--last{border-bottom-right-radius:var(--ag-charts-border-radius);border-top-right-radius:var(--ag-charts-border-radius);border-right-width:1px}}.ag-charts-toolbar--vertical{flex-direction:column;.ag-charts-toolbar__button{margin:-1px 0 0;max-width:100%}.ag-charts-toolbar__button--first{border-top-left-radius:var(--ag-charts-border-radius);border-top-right-radius:var(--ag-charts-border-radius);margin:0}.ag-charts-toolbar__button--last{border-bottom-left-radius:var(--ag-charts-border-radius);border-bottom-right-radius:var(--ag-charts-border-radius)}}.ag-charts-toolbar__icon+.ag-charts-toolbar__label{margin-left:var(--toolbar-gap)}.ag-charts-toolbar__icon,.ag-charts-toolbar__label{pointer-events:none}.ag-charts-floating-toolbar{border:none;display:flex;.ag-charts-toolbar{align-items:unset;position:unset}}.ag-charts-floating-toolbar__drag-handle{align-items:center;background:var(--ag-charts-chrome-background-color);border:var(--ag-charts-border);border-bottom-left-radius:var(--ag-charts-border-radius);border-top-left-radius:var(--ag-charts-border-radius);border-right-width:0;cursor:grab;display:flex;justify-content:center;min-width:24px;padding-left:0;padding-right:0}.ag-charts-floating-toolbar__drag-handle--dragging{cursor:grabbing}\n';

// packages/ag-charts-community/src/util/baseManager.ts
var BaseManager = class {
  constructor() {
    this.cleanup = new CleanupRegistry();
    this.destroyed = false;
  }
  destroy() {
    this.cleanup.flush();
    this.destroyed = true;
  }
};

// packages/ag-charts-community/src/util/guardedElement.ts
var GuardedElement = class _GuardedElement {
  constructor(element2, topTabGuard, bottomTabGuard) {
    this.element = element2;
    this.topTabGuard = topTabGuard;
    this.bottomTabGuard = bottomTabGuard;
    this.cleanup = new CleanupRegistry();
    this.guardTabIndex = 0;
    this.hasFocus = false;
    this.initTabGuard(this.topTabGuard, false);
    this.initTabGuard(this.bottomTabGuard, true);
    this.element.addEventListener("focus", () => this.onFocus(), { capture: true });
    this.element.addEventListener("blur", (ev) => this.onBlur(ev), { capture: true });
  }
  set tabIndex(index) {
    this.guardTabIndex = index;
    if (this.guardTabIndex === 0) {
      this.setGuardIndices(void 0);
    } else if (!this.hasFocus) {
      this.setGuardIndices(this.guardTabIndex);
    }
  }
  destroy() {
    this.cleanup.flush();
  }
  initTabGuard(guard, reverse) {
    this.cleanup.register(attachListener(guard, "focus", () => this.onTab(guard, reverse)));
  }
  setGuardIndices(index) {
    const tabindex = index;
    setAttribute(this.topTabGuard, "tabindex", tabindex);
    setAttribute(this.bottomTabGuard, "tabindex", tabindex);
  }
  onFocus() {
    this.hasFocus = true;
    if (this.guardTabIndex !== 0) {
      this.setGuardIndices(0);
    }
  }
  onBlur({ relatedTarget }) {
    const { topTabGuard: top, bottomTabGuard: bot } = this;
    this.hasFocus = false;
    if (this.guardTabIndex !== 0 && relatedTarget !== top && relatedTarget !== bot) {
      this.setGuardIndices(this.guardTabIndex);
    }
  }
  onTab(guard, reverse) {
    if (this.guardTabIndex !== 0) {
      let focusTarget;
      if (guard.tabIndex === 0) {
        focusTarget = this.findExitTarget(!reverse);
        this.setGuardIndices(this.guardTabIndex);
      } else {
        focusTarget = this.findEnterTarget(reverse);
      }
      focusTarget?.focus();
    }
  }
  static queryFocusable(element2, selectors) {
    const myWindow = getWindow();
    return Array.from(element2.querySelectorAll(selectors)).filter((e) => {
      if (isHTMLElement(e)) {
        const style2 = myWindow.getComputedStyle(e);
        return style2.display !== "none" && style2.visibility !== "none";
      }
      return false;
    });
  }
  findEnterTarget(reverse) {
    const focusables = _GuardedElement.queryFocusable(this.element, '[tabindex="0"]');
    const index = reverse ? focusables.length - 1 : 0;
    return focusables[index];
  }
  findExitTarget(reverse) {
    const focusables = _GuardedElement.queryFocusable(getDocument(), "[tabindex]").filter((e) => e.tabIndex > 0).sort((a, b) => a.tabIndex - b.tabIndex);
    const { before, after } = _GuardedElement.findBeforeAndAfter(focusables, this.guardTabIndex);
    return reverse ? before : after;
  }
  static findBeforeAndAfter(elements, targetTabIndex) {
    let left = 0;
    let right = elements.length - 1;
    let before = void 0;
    let after = void 0;
    while (left <= right) {
      const mid = Math.floor((left + right) / 2);
      const currentTabIndex = elements[mid].tabIndex;
      if (currentTabIndex === targetTabIndex) {
        before = elements[mid - 1] || void 0;
        after = elements[mid + 1] || void 0;
        break;
      } else if (currentTabIndex < targetTabIndex) {
        before = elements[mid];
        left = mid + 1;
      } else {
        after = elements[mid];
        right = mid - 1;
      }
    }
    return { before, after };
  }
};

// packages/ag-charts-community/src/util/pixelRatioObserver.ts
var PixelRatioObserver = class {
  constructor(callback2) {
    this.callback = callback2;
    this.devicePixelRatio = getWindow("devicePixelRatio") ?? 1;
    this.devicePixelRatioMediaQuery = void 0;
    this.devicePixelRatioListener = (e) => {
      if (e.matches)
        return;
      this.devicePixelRatio = getWindow("devicePixelRatio") ?? 1;
      this.unregisterDevicePixelRatioListener();
      this.registerDevicePixelRatioListener();
      this.callback(this.pixelRatio);
    };
  }
  get pixelRatio() {
    return this.devicePixelRatio;
  }
  observe() {
    this.registerDevicePixelRatioListener();
  }
  disconnect() {
    this.unregisterDevicePixelRatioListener();
  }
  unregisterDevicePixelRatioListener() {
    this.devicePixelRatioMediaQuery?.removeEventListener("change", this.devicePixelRatioListener);
    this.devicePixelRatioMediaQuery = void 0;
  }
  registerDevicePixelRatioListener() {
    const devicePixelRatioMediaQuery = getWindow("matchMedia")?.(`(resolution: ${this.pixelRatio}dppx)`);
    devicePixelRatioMediaQuery?.addEventListener("change", this.devicePixelRatioListener);
    this.devicePixelRatioMediaQuery = devicePixelRatioMediaQuery;
  }
};

// packages/ag-charts-community/src/util/sizeMonitor.ts
var SizeMonitor = class {
  constructor() {
    this.elements = /* @__PURE__ */ new Map();
    this.documentReady = false;
    this.queuedObserveRequests = [];
    this.onLoad = () => {
      this.documentReady = true;
      for (const [el, cb] of this.queuedObserveRequests) {
        this.observe(el, cb);
      }
      this.queuedObserveRequests = [];
      this.observeWindow();
    };
    const ResizeObserverCtor = getResizeObserver();
    if (ResizeObserverCtor !== void 0) {
      this.resizeObserver = new ResizeObserverCtor((entries2) => {
        for (const {
          target,
          contentRect: { width: width2, height: height2 }
        } of entries2) {
          const entry = this.elements.get(target);
          this.checkSize(entry, target, width2, height2);
        }
      });
    }
    let animationFrame;
    this.pixelRatioObserver = new PixelRatioObserver(() => {
      clearTimeout(animationFrame);
      animationFrame = setTimeout(() => this.checkPixelRatio(), 0);
    });
    this.documentReady = getDocument("readyState") === "complete";
    if (this.documentReady) {
      this.observeWindow();
    } else {
      getWindow()?.addEventListener("load", this.onLoad);
    }
  }
  destroy() {
    getWindow()?.removeEventListener("load", this.onLoad);
    this.resizeObserver?.disconnect();
    this.resizeObserver = void 0;
    this.pixelRatioObserver?.disconnect();
    this.pixelRatioObserver = void 0;
  }
  observeWindow() {
    this.pixelRatioObserver?.observe();
  }
  checkPixelRatio() {
    const pixelRatio = this.pixelRatioObserver?.pixelRatio ?? 1;
    for (const [element2, entry] of this.elements) {
      if (entry.size != null && entry.size.pixelRatio !== pixelRatio) {
        const { width: width2, height: height2 } = entry.size;
        entry.size = { width: width2, height: height2, pixelRatio };
        entry.cb(entry.size, element2);
      }
    }
  }
  checkSize(entry, element2, width2, height2) {
    if (!entry)
      return;
    if (width2 !== entry.size?.width || height2 !== entry.size?.height) {
      const pixelRatio = this.pixelRatioObserver?.pixelRatio ?? 1;
      entry.size = { width: width2, height: height2, pixelRatio };
      entry.cb(entry.size, element2);
    }
  }
  // Only a single callback is supported.
  observe(element2, cb) {
    if (!this.documentReady) {
      this.queuedObserveRequests.push([element2, cb]);
      return;
    }
    if (this.elements.has(element2)) {
      this.removeFromQueue(element2);
    } else {
      this.resizeObserver?.observe(element2);
    }
    const entry = { cb };
    this.elements.set(element2, entry);
  }
  unobserve(element2) {
    this.resizeObserver?.unobserve(element2);
    this.elements.delete(element2);
    this.removeFromQueue(element2);
    if (!this.elements.size) {
      this.destroy();
    }
  }
  removeFromQueue(element2) {
    this.queuedObserveRequests = this.queuedObserveRequests.filter(([el]) => el !== element2);
  }
};

// packages/ag-charts-community/src/util/stateTracker.ts
var StateTracker = class extends Map {
  constructor(defaultValue, defaultState) {
    super();
    this.defaultValue = defaultValue;
    this.defaultState = defaultState;
  }
  set(key, value) {
    this.delete(key);
    if (value !== void 0) {
      super.set(key, value);
    }
    delete this.cachedState;
    delete this.cachedValue;
    return this;
  }
  delete(key) {
    delete this.cachedState;
    delete this.cachedValue;
    return super.delete(key);
  }
  stateId() {
    this.cachedState ?? (this.cachedState = Array.from(this.keys()).pop() ?? this.defaultState);
    return this.cachedState;
  }
  stateValue() {
    this.cachedValue ?? (this.cachedValue = Array.from(this.values()).pop() ?? this.defaultValue);
    return this.cachedValue;
  }
};

// packages/ag-charts-community/src/dom/domLayout.html
var domLayout_default = '<div role="presentation" class="ag-charts-wrapper ag-charts-styles" data-ag-charts><div role="presentation" class="ag-charts-canvas-center"><div role="presentation" class="ag-charts-canvas-container"><div role="presentation" class="ag-charts-canvas-background" aria-hidden="true"></div><div role="presentation" class="ag-charts-canvas" aria-hidden="true"></div><div role="figure" class="ag-charts-canvas-proxy"><div role="presentation" class="ag-charts-series-area"></div></div><div role="presentation" class="ag-charts-canvas-overlay ag-charts-tooltip-container"></div></div></div></div>';

// packages/ag-charts-community/src/dom/domManager.ts
var DOM_ELEMENT_CLASSES = [
  "styles",
  "canvas",
  "canvas-background",
  "canvas-center",
  "canvas-container",
  "canvas-overlay",
  "canvas-proxy",
  "series-area",
  "tooltip-container"
];
var MINIMAL_DOM_ELEMENT_ROLES = /* @__PURE__ */ new Set(["styles", "canvas-container", "canvas", "tooltip-container"]);
var CONTAINER_MODIFIERS = {
  safeHorizontal: "ag-charts-wrapper--safe-horizontal",
  safeVertical: "ag-charts-wrapper--safe-vertical"
};
var domElementConfig = /* @__PURE__ */ new Map([
  ["styles", { childElementType: "style" }],
  ["canvas", { childElementType: "canvas" }],
  ["canvas-proxy", { childElementType: "div" }],
  ["canvas-overlay", { childElementType: "div" }],
  ["canvas-center", { childElementType: "div" }],
  ["series-area", { childElementType: "div" }],
  ["tooltip-container", { childElementType: "div" }]
]);
function setupObserver(element2, cb) {
  if (typeof IntersectionObserver === "undefined")
    return;
  const observer = new IntersectionObserver(
    (observedEntries) => {
      for (const entry of observedEntries) {
        if (entry.target === element2) {
          cb(entry.intersectionRatio);
        }
      }
    },
    { root: element2 }
  );
  observer.observe(element2);
  return observer;
}
var NULL_DOMRECT = {
  x: 0,
  y: 0,
  width: 0,
  height: 0,
  top: 0,
  bottom: 0,
  left: 0,
  right: 0,
  toJSON() {
    return NULL_DOMRECT;
  }
};
function createTabGuardElement(guardedElem, where) {
  const div = createElement("div");
  div.className = "ag-charts-tab-guard";
  guardedElem.insertAdjacentElement(where, div);
  return div;
}
var _DOMManager = class _DOMManager extends BaseManager {
  constructor(eventsHub, chart, initialContainer, styleContainer, skipCss, mode = "normal") {
    super();
    this.eventsHub = eventsHub;
    this.chart = chart;
    this.styleContainer = styleContainer;
    this.skipCss = skipCss;
    this.mode = mode;
    this.anchorName = `--${createId(this)}`;
    this.styles = /* @__PURE__ */ new Map();
    this.pendingContainer = void 0;
    this.container = void 0;
    this.documentRoot = void 0;
    this.initiallyConnected = void 0;
    this.containerSize = void 0;
    this.sizeMonitor = new SizeMonitor();
    this.cursorState = new StateTracker("default");
    this.minWidth = 0;
    this.minHeight = 0;
    this.element = this.initDOM();
    this.rootElements = this.initRootElements();
    this.rootElements["canvas"].element.style.setProperty("anchor-name", this.anchorName);
    let hidden = false;
    this.observer = setupObserver(this.element, (intersectionRatio) => {
      if (intersectionRatio === 0 && !hidden) {
        this.eventsHub.emit("dom:hidden", null);
      }
      hidden = intersectionRatio === 0;
    });
    this.setSizeOptions();
    this.updateContainerSize();
    this.addStyles("ag-charts-community", styles_default);
    this.setContainer(initialContainer);
    this.cleanup.register(stopPageScrolling(this.element));
    if (this.mode === "normal") {
      const guardedElement = this.rootElements["canvas-center"].element;
      if (guardedElement == null)
        throw new Error("Error initializing tab guards");
      const topGuard = createTabGuardElement(guardedElement, "beforebegin");
      const botGuard = createTabGuardElement(guardedElement, "afterend");
      this.tabGuards = new GuardedElement(guardedElement, topGuard, botGuard);
    }
  }
  initDOM() {
    if (this.mode === "normal") {
      const templateEl = createElement("div");
      templateEl.innerHTML = domLayout_default;
      return templateEl.firstChild;
    }
    const element2 = createElement("div");
    element2.role = "presentation";
    element2.dataset.agCharts = "";
    element2.classList.add("ag-charts-wrapper");
    const seriesArea = createElement("div");
    element2.appendChild(seriesArea);
    seriesArea.role = "presentation";
    seriesArea.classList.add("ag-charts-series-area");
    return element2;
  }
  initRootElements() {
    const { mode, element: element2 } = this;
    const rootElements = {};
    for (const domElement of DOM_ELEMENT_CLASSES) {
      const className = `ag-charts-${domElement}`;
      let el;
      if (mode === "normal") {
        el = element2.classList.contains(className) ? element2 : element2.getElementsByClassName(className)[0];
      } else if (MINIMAL_DOM_ELEMENT_ROLES.has(domElement)) {
        el = element2;
      } else {
        el = element2.getElementsByClassName(className)[0] ?? createElement("div");
      }
      if (el == null) {
        throw new Error(`AG Charts - unable to find DOM element ${className}`);
      }
      rootElements[domElement] = {
        element: el,
        children: /* @__PURE__ */ new Map(),
        listeners: []
      };
    }
    return rootElements;
  }
  destroy() {
    super.destroy();
    this.observer?.unobserve(this.element);
    if (this.container) {
      this.sizeMonitor.unobserve(this.container);
    }
    this.pendingContainer = void 0;
    for (const el of Object.values(this.rootElements)) {
      for (const c of el.children.values()) {
        c.remove();
      }
      el.element.remove();
    }
    this.element.remove();
  }
  postRenderUpdate() {
    this.updateStylesLocation();
    if (this.mode === "minimal")
      return;
    if (this.pendingContainer == null || this.pendingContainer === this.container)
      return;
    if (_DOMManager.batchedUpdateContainer.length === 0) {
      getWindow().setTimeout(this.applyBatchedUpdateContainer.bind(this), 0);
    }
    _DOMManager.batchedUpdateContainer.push(this);
  }
  applyBatchedUpdateContainer() {
    for (const manager of _DOMManager.batchedUpdateContainer) {
      if (!manager.destroyed) {
        manager.updateContainer();
      }
    }
    _DOMManager.batchedUpdateContainer.splice(0);
  }
  updateStylesLocation() {
    if (this.initiallyConnected === true || this.container?.isConnected === false)
      return;
    this.documentRoot = this.getShadowDocumentRoot(this.container);
    this.initiallyConnected = true;
    for (const id of this.rootElements["styles"].children.keys()) {
      this.removeChild("styles", id);
    }
    for (const [id, styles] of this.styles) {
      this.addStyles(id, styles);
    }
  }
  setSizeOptions(minWidth = 300, minHeight = 300, optionsWidth, optionsHeight) {
    const { style: style2 } = this.element;
    style2.width = `${optionsWidth ?? minWidth}px`;
    style2.height = `${optionsHeight ?? minHeight}px`;
    this.minWidth = optionsWidth ?? minWidth;
    this.minHeight = optionsHeight ?? minHeight;
    this.updateContainerClassName();
  }
  updateContainerSize() {
    const { style: centerStyle } = this.rootElements["canvas-center"].element;
    centerStyle.visibility = this.containerSize == null ? "hidden" : "";
    if (this.containerSize) {
      centerStyle.width = `${this.containerSize.width ?? 0}px`;
      centerStyle.height = `${this.containerSize.height ?? 0}px`;
    } else {
      centerStyle.width = "";
      centerStyle.height = "";
    }
    this.updateContainerClassName();
  }
  setTabGuardIndex(tabIndex) {
    if (!this.tabGuards)
      return;
    this.tabGuards.tabIndex = tabIndex;
  }
  setContainer(newContainer) {
    if (newContainer === this.container)
      return;
    this.pendingContainer = newContainer;
    if (this.mode === "minimal" || this.container == null) {
      this.updateContainer();
    }
  }
  updateContainer() {
    const { pendingContainer } = this;
    if (pendingContainer == null || pendingContainer === this.container)
      return;
    if (this.container) {
      this.element.remove();
      this.sizeMonitor.unobserve(this.container);
    }
    if (this.documentRoot != null) {
      for (const id of this.rootElements["styles"].children.keys()) {
        this.removeChild("styles", id);
      }
    }
    this.container = pendingContainer;
    this.pendingContainer = void 0;
    this.documentRoot = this.getShadowDocumentRoot(pendingContainer);
    this.initiallyConnected = pendingContainer.isConnected;
    for (const [id, styles] of this.styles) {
      this.addStyles(id, styles);
    }
    pendingContainer.appendChild(this.element);
    this.sizeMonitor.observe(pendingContainer, (size) => {
      this.containerSize = size;
      this.updateContainerSize();
      this.eventsHub.emit("dom:resize", null);
    });
    this.eventsHub.emit("dom:container-change", null);
  }
  setThemeClass(themeClassName) {
    const themeClassNamePrefix = "ag-charts-theme-";
    for (const className of Array.from(this.element.classList)) {
      if (className.startsWith(themeClassNamePrefix) && className !== themeClassName) {
        this.element.classList.remove(className);
      }
    }
    this.element.classList.add(themeClassName);
  }
  setThemeParameters(params) {
    for (const [key, value] of entries(params)) {
      let formattedValue = `${value}`;
      if (key.endsWith("Size") || key.endsWith("Radius")) {
        formattedValue = `${value}px`;
      } else if (key.endsWith("Border") && typeof value === "boolean") {
        formattedValue = value ? "var(--ag-charts-border)" : "none";
      }
      this.element.style.setProperty(`--ag-charts-${kebabCase(key)}`, formattedValue);
    }
  }
  updateCanvasLabel(ariaLabel) {
    setAttribute(this.rootElements["canvas-proxy"].element, "aria-label", ariaLabel);
  }
  getEventElement(defaultElem, eventType) {
    const events = ["focus", "blur", "keydown", "keyup"];
    return events.includes(eventType) ? this.rootElements["series-area"].element : defaultElem;
  }
  addEventListener(type, listener, options) {
    const element2 = this.getEventElement(this.element, type);
    return attachListener(element2, type, listener, options);
  }
  removeEventListener(type, listener, options) {
    this.getEventElement(this.element, type).removeEventListener(type, listener, options);
  }
  /** Get the main chart area client bound rect. */
  getBoundingClientRect() {
    return this.rootElements["canvas"].element.getBoundingClientRect();
  }
  /**
   * Get the client bounding rect for overlay elements that might float outside the bounds of the
   * main chart area.
   */
  getOverlayClientRect() {
    const window = getWindow();
    const windowBBox = new BBox(0, 0, window.innerWidth, window.innerHeight);
    const containerBBox = this.getRawOverlayClientRect();
    return windowBBox.intersection(containerBBox)?.toDOMRect() ?? NULL_DOMRECT;
  }
  getRawOverlayClientRect() {
    let element2 = this.element;
    const fullScreenElement = this.element.getRootNode()?.fullscreenElement;
    while (element2 != null) {
      let isContainer;
      if (fullScreenElement != null && element2 === fullScreenElement) {
        isContainer = true;
      } else {
        const styleMap = element2.computedStyleMap?.();
        const overflowY = styleMap?.get("overflow-y")?.toString();
        isContainer = overflowY === "auto" || overflowY === "scroll";
      }
      if (isContainer) {
        return BBox.fromObject(element2.getBoundingClientRect());
      }
      element2 = element2.parentElement;
    }
    if (this.documentRoot != null)
      return BBox.fromObject(this.documentRoot.getBoundingClientRect());
    const { innerWidth, innerHeight } = getWindow();
    return new BBox(0, 0, innerWidth, innerHeight);
  }
  getShadowDocumentRoot(current = this.container) {
    const docRoot = current?.ownerDocument?.body ?? getDocument("body");
    while (current != null) {
      if (current === docRoot) {
        return void 0;
      }
      if (isDocumentFragment(current.parentNode)) {
        return current;
      }
      current = current.parentNode;
    }
  }
  getParent(domElementClass) {
    return this.rootElements[domElementClass].element;
  }
  getChildBoundingClientRect(type) {
    const { children } = this.rootElements[type];
    const childRects = [];
    for (const child of children.values()) {
      childRects.push(BBox.fromObject(child.getBoundingClientRect()));
    }
    return BBox.merge(childRects);
  }
  isManagedChildDOMElement(el, domElementClass, id) {
    const { children } = this.rootElements[domElementClass];
    const search = children?.get(id);
    return search != null && el.contains(search);
  }
  contains(element2, domElementClass) {
    if (domElementClass == null)
      return this.element.contains(element2);
    return this.rootElements[domElementClass].element.contains(element2);
  }
  addStyles(id, styles) {
    const dataAttribute = "data-ag-charts";
    this.styles.set(id, styles);
    if (this.container == null)
      return;
    if (this.skipCss)
      return;
    const checkId = (el) => {
      return el.getAttribute(dataAttribute) === id;
    };
    const addStyleElement = (el) => {
      const metaElements = /* @__PURE__ */ new Set(["TITLE", "META"]);
      let skippingMetaElements = true;
      let insertAfterEl;
      for (const child of el.children) {
        if (skippingMetaElements && metaElements.has(child.tagName)) {
          insertAfterEl = child;
          continue;
        }
        skippingMetaElements = false;
        if (checkId(child))
          return;
        if (child.hasAttribute(dataAttribute)) {
          insertAfterEl = child;
        }
      }
      const styleEl = createElement("style");
      if (this.chart.styleNonce != null) {
        styleEl.nonce = this.chart.styleNonce;
      }
      if (insertAfterEl == null) {
        el.prepend(styleEl);
      } else {
        el.insertBefore(styleEl, insertAfterEl.nextSibling);
      }
      return styleEl;
    };
    let styleElement;
    if (this.styleContainer) {
      styleElement = addStyleElement(this.styleContainer);
    } else if (this.initiallyConnected === false) {
      styleElement = this.addChild("styles", id);
    } else if (this.documentRoot == null && !_DOMManager.headStyles.has(id)) {
      styleElement = addStyleElement(getDocument("head"));
      _DOMManager.headStyles.add(id);
    } else if (this.documentRoot != null) {
      styleElement = this.addChild("styles", id);
    }
    if (styleElement == null || checkId(styleElement))
      return;
    styleElement.setAttribute(dataAttribute, id);
    styleElement.innerHTML = styles;
  }
  removeStyles(id) {
    this.removeChild("styles", id);
  }
  updateCursor(callerId, style2) {
    this.cursorState.set(callerId, style2);
    this.element.style.cursor = this.cursorState.stateValue();
  }
  getCursor() {
    return this.element.style.cursor;
  }
  addChild(domElementClass, id, child, insert) {
    const { element: element2, children, listeners } = this.rootElements[domElementClass];
    if (!children) {
      throw new Error("AG Charts - unable to create DOM elements after destroy()");
    }
    if (children.has(id)) {
      return children.get(id);
    }
    const { childElementType = "div" } = domElementConfig.get(domElementClass) ?? {};
    if (child && child.tagName.toLowerCase() !== childElementType.toLowerCase()) {
      throw new Error("AG Charts - mismatching DOM element type");
    }
    const newChild = child ?? createElement(childElementType);
    for (const [type, fn, opts] of listeners) {
      newChild.addEventListener(type, fn, opts);
    }
    children.set(id, newChild);
    if (childElementType === "style" && this.chart.styleNonce != null) {
      newChild.nonce = this.chart.styleNonce;
    }
    if (insert) {
      const queryResult = element2.querySelector(insert.query);
      if (queryResult == null) {
        throw new Error(`AG Charts - addChild query failed ${insert.query}`);
      }
      queryResult.insertAdjacentElement(insert.where, newChild);
    } else {
      element2?.appendChild(newChild);
    }
    return newChild;
  }
  removeChild(domElementClass, id) {
    const { children } = this.rootElements[domElementClass];
    if (!children)
      return;
    children.get(id)?.remove();
    children.delete(id);
  }
  incrementDataCounter(name) {
    const { dataset } = this.element;
    dataset[name] ?? (dataset[name] = "0");
    dataset[name] = String(Number(dataset[name]) + 1);
  }
  setDataBoolean(name, value) {
    this.element.dataset[name] = String(value);
  }
  setDataNumber(name, value) {
    this.element.dataset[name] = String(value);
  }
  updateContainerClassName() {
    const { element: element2, containerSize, minWidth, minHeight } = this;
    element2.classList.toggle(CONTAINER_MODIFIERS.safeHorizontal, minWidth >= (containerSize?.width ?? Infinity));
    element2.classList.toggle(CONTAINER_MODIFIERS.safeVertical, minHeight >= (containerSize?.height ?? Infinity));
  }
};
_DOMManager.className = "DOMManager";
_DOMManager.batchedUpdateContainer = [];
_DOMManager.headStyles = /* @__PURE__ */ new Set();
var DOMManager = _DOMManager;

// packages/ag-charts-community/src/widget/boundedTextWidget.ts
var BoundedTextWidget = class extends Widget {
  constructor() {
    super(createElement("div"));
    this.textElement = createSvgElement("text");
    this.textElement.role = "presentation";
    this.svgElement = createSvgElement("svg");
    this.svgElement.appendChild(this.textElement);
    this.svgElement.style.width = "100%";
    this.svgElement.style.opacity = "0";
    this.svgElement.role = "presentation";
    this.elem.appendChild(this.svgElement);
    this.elem.role = "presentation";
  }
  set textContent(text2) {
    this.textElement.textContent = text2;
    const bboxCalculator = this.textElement;
    const bbox = bboxCalculator.getBBox?.();
    if (bbox) {
      this.svgElement.setAttribute("viewBox", `${bbox.x} ${bbox.y} ${bbox.width} ${bbox.height}`);
    }
  }
  get textContent() {
    return this.textElement.textContent;
  }
  destructor() {
  }
};

// packages/ag-charts-community/src/widget/expansionControllerImpl.ts
var ExpansionControllerImpl = class {
  constructor(controller, getDispatcher) {
    this.getDispatcher = getDispatcher;
    this.onExpanded = () => {
      this.controller.setAriaExpanded(true);
      const dispatcher = this.getDispatcher();
      if (dispatcher && this.controls) {
        const event = {
          type: "expand-controlled-widget",
          controlled: this.controls
        };
        dispatcher.dispatch("expand-controlled-widget", this.controller, event);
      }
    };
    this.onCollapsed = (e) => {
      this.controller.setAriaExpanded(false);
      if (e.mode === "0" /* CLOSE */) {
        this.controller.focus();
      }
    };
    controller.setAriaExpanded(false);
    this.controller = controller;
  }
  destroy() {
    this.controls?.collapse({ mode: "2" /* DESTROY */ });
    this.setControlled(void 0);
  }
  setControlled(controls) {
    if (this.controls) {
      this.controls.removeListener("expand-widget", this.onExpanded);
      this.controls.removeListener("collapse-widget", this.onCollapsed);
    }
    this.controls = controls;
    if (this.controls) {
      this.controller.setAriaControls(this.controls.id);
      this.controls.addListener("expand-widget", this.onExpanded);
      this.controls.addListener("collapse-widget", this.onCollapsed);
    }
  }
  getControlled() {
    return this.controls;
  }
  expandControlled(opts) {
    if (!this.controller.isDisabled()) {
      this.controls?.expand({
        controller: this.controller,
        sourceEvent: void 0,
        overrideFocusVisible: opts?.overrideFocusVisible
      });
    }
  }
};

// packages/ag-charts-community/src/widget/abstractButtonWidget.ts
var AbstractButtonWidget = class extends Widget {
  constructor(element2, role) {
    super(element2);
    setAttribute(this.elem, "role", role);
    this.setEnabled(true);
    this.addListener("keydown", ({ sourceEvent }) => {
      if (isButtonClickEvent(sourceEvent)) {
        sourceEvent.preventDefault();
        this.htmlListener?.dispatch("click", this, { type: "click", device: "keyboard", sourceEvent });
      }
    });
  }
  lazyControllerImpl() {
    this.controllerImpl ?? (this.controllerImpl = new ExpansionControllerImpl(this, () => this.internalListener));
    return this.controllerImpl;
  }
  destructor() {
    this.controllerImpl?.destroy();
  }
  setEnabled(enabled) {
    setAttribute(this.elem, "aria-disabled", !enabled);
  }
  setControlled(controls) {
    return this.lazyControllerImpl().setControlled(controls);
  }
  getControlled() {
    return this.lazyControllerImpl().getControlled();
  }
  expandControlled(opts) {
    return this.lazyControllerImpl().expandControlled(opts);
  }
  addListener(type, listener) {
    return super.addListener(type, (ev, current) => {
      if ((type === "click" || type === "dblclick") && this.isDisabled())
        return;
      listener(ev, current);
    });
  }
};

// packages/ag-charts-community/src/widget/buttonWidget.ts
var ButtonWidget = class extends AbstractButtonWidget {
  constructor() {
    super(createElement("button"));
  }
};

// packages/ag-charts-community/src/widget/groupWidget.ts
var GroupWidget = class extends Widget {
  constructor() {
    super(createElement("div"));
    setAttribute(this.elem, "role", "group");
  }
  destructor() {
  }
};

// packages/ag-charts-community/src/widget/rovingTabContainerWidget.ts
var RovingTabContainerWidget = class extends Widget {
  constructor(initialOrientation, role) {
    super(createElement("div"));
    this.focusedChildIndex = 0;
    this.onChildFocus = (_event, child) => {
      const oldFocus = this.children[this.focusedChildIndex];
      this.focusedChildIndex = child.index;
      oldFocus?.setTabIndex(-1);
      child.setTabIndex(0);
    };
    this.onChildKeyDown = (event, child) => {
      const rovingOrientation = this.orientation;
      const [primaryKeys, secondaryKeys] = rovingOrientation === "both" ? [PREV_NEXT_KEYS["horizontal"], PREV_NEXT_KEYS["vertical"]] : [PREV_NEXT_KEYS[rovingOrientation], void 0];
      let targetIndex = -1;
      if (hasNoModifiers(event.sourceEvent)) {
        const key = event.sourceEvent.key;
        if (key === primaryKeys.nextKey || key === secondaryKeys?.nextKey) {
          targetIndex = child.index + 1;
        } else if (key === primaryKeys.prevKey || key === secondaryKeys?.prevKey) {
          targetIndex = child.index - 1;
        }
      }
      this.children[targetIndex]?.focus();
    };
    setAttribute(this.elem, "role", role);
    this.orientation = initialOrientation;
  }
  get orientation() {
    return getAttribute(this.elem, "aria-orientation") ?? "both";
  }
  set orientation(orientation) {
    setAttribute(this.elem, "aria-orientation", orientation === "both" ? void 0 : orientation);
  }
  focus() {
    this.children[this.focusedChildIndex]?.focus();
  }
  clear() {
    this.focusedChildIndex = 0;
    for (const child of this.children) {
      this.removeChildListeners(child);
      child.parent = void 0;
    }
    this.elem.textContent = "";
    this.children.length = 0;
  }
  addChildListeners(child) {
    child.addListener("focus", this.onChildFocus);
    child.addListener("keydown", this.onChildKeyDown);
  }
  removeChildListeners(child) {
    child.removeListener("focus", this.onChildFocus);
    child.removeListener("keydown", this.onChildKeyDown);
  }
  onChildAdded(child) {
    this.addChildListeners(child);
    child.setTabIndex(this.children.length === 1 ? 0 : -1);
  }
  onChildRemoved(removedChild) {
    this.removeChildListeners(removedChild);
    const { focusedChildIndex, children } = this;
    const removedFocusedChild = focusedChildIndex === removedChild.index;
    for (let i = 0; i < children.length; i++) {
      const child = children[i];
      if (child.index === focusedChildIndex) {
        this.focusedChildIndex = i;
      }
      child.index = i;
    }
    if (removedFocusedChild) {
      const newFocusChild = children[focusedChildIndex] ?? children[focusedChildIndex - 1];
      if (newFocusChild) {
        this.focusedChildIndex = newFocusChild.index;
        newFocusChild.setTabIndex(0);
      } else {
        this.focusedChildIndex = 0;
      }
    }
  }
};

// packages/ag-charts-community/src/widget/listWidget.ts
var ListWidget = class extends RovingTabContainerWidget {
  constructor() {
    super("both", "list");
    this.setHidden(true);
  }
  destructor() {
    for (const c of this.children) {
      c.getElement().parentElement.remove();
    }
  }
  addChildToDOM(child, before) {
    const listItem = createElement("div");
    setAttribute(listItem, "role", "listitem");
    setElementStyle(listItem, "position", "absolute");
    Widget.setElementContainer(child, listItem);
    this.appendOrInsert(listItem, before);
    this.setHidden(false);
  }
  removeChildFromDOM(child) {
    child.getElement().parentElement.remove();
    this.setHidden(this.children.length === 0);
  }
  setHidden(hidden) {
    if (this.children.length === 0) {
      hidden = true;
    }
    super.setHidden(hidden);
  }
};

// packages/ag-charts-community/src/widget/nativeWidget.ts
var NativeWidget = class extends Widget {
  constructor(elem) {
    super(elem);
  }
  destructor() {
  }
};

// packages/ag-charts-community/src/widget/sliderWidget.ts
var _SliderWidget = class _SliderWidget extends Widget {
  constructor() {
    super(createElement("input"));
    this._step = _SliderWidget.STEP_ONE;
    this.orientation = "both";
  }
  get step() {
    return this._step;
  }
  set step(step) {
    this._step = step;
    this.getElement().step = step.attributeValue;
  }
  get keyboardStep() {
    return this._keyboardStep?.step ?? this._step;
  }
  set keyboardStep(step) {
    if (step === this._keyboardStep?.step)
      return;
    if (this._keyboardStep !== void 0) {
      this.removeListener("keydown", this._keyboardStep.onKeyDown);
      this.removeListener("keyup", this._keyboardStep.onKeyUp);
      this.removeListener("blur", this._keyboardStep.onBlur);
      this._keyboardStep = void 0;
    }
    if (step !== void 0) {
      const onKeyDown = () => this.getElement().step = step.attributeValue;
      const resetStep = () => this.getElement().step = this._step.attributeValue;
      this._keyboardStep = { step, onKeyDown, onKeyUp: resetStep, onBlur: resetStep };
      this.addListener("keydown", this._keyboardStep.onKeyDown);
      this.addListener("keyup", this._keyboardStep.onKeyUp);
      this.addListener("blur", this._keyboardStep.onBlur);
    }
  }
  get orientation() {
    return getAttribute(this.elem, "aria-orientation") ?? "both";
  }
  set orientation(orientation) {
    setAttribute(this.elem, "aria-orientation", orientation === "both" ? void 0 : orientation);
    _SliderWidget.registerDefaultPreventers(this, orientation);
  }
  destructor() {
  }
  clampValueRatio(clampMin, clampMax) {
    const ratio2 = this.getValueRatio();
    const clampedRatio = clamp(clampMin, ratio2, clampMax);
    if (clampedRatio !== ratio2) {
      this.setValueRatio(clampedRatio);
    }
    return clampedRatio;
  }
  setValueRatio(ratio2, opts) {
    const { divider } = this.step;
    const value = Math.round(ratio2 * 1e4) / divider;
    const { ariaValueText = formatPercent(value / divider) } = opts ?? {};
    const elem = this.getElement();
    elem.value = `${value}`;
    elem.ariaValueText = ariaValueText;
    elem.ariaValueNow = `${value}`;
  }
  getValueRatio() {
    return this.getElement().valueAsNumber / this.step.divider;
  }
  static registerDefaultPreventers(target, orientation) {
    if (orientation === "both") {
      target.removeListener("keydown", _SliderWidget.onKeyDown);
    } else {
      target.addListener("keydown", _SliderWidget.onKeyDown);
    }
  }
  static onKeyDown(ev, current) {
    let ignoredKeys = [];
    const { orientation } = current;
    if (orientation === "horizontal") {
      ignoredKeys = ["ArrowUp", "ArrowDown"];
    } else if (orientation === "vertical") {
      ignoredKeys = ["ArrowLeft", "ArrowRight"];
    }
    if (ignoredKeys.includes(ev.sourceEvent.code)) {
      ev.sourceEvent.preventDefault();
    }
  }
};
_SliderWidget.STEP_ONE = { attributeValue: "1", divider: 1 };
_SliderWidget.STEP_HUNDRETH = { attributeValue: "0.01", divider: 100 };
var SliderWidget = _SliderWidget;

// packages/ag-charts-community/src/widget/switchWidget.ts
var SwitchWidget = class extends ButtonWidget {
  constructor() {
    super();
    setAttribute(this.elem, "role", "switch");
    this.setChecked(false);
  }
  setChecked(checked) {
    setAttribute(this.elem, "aria-checked", checked);
  }
};

// packages/ag-charts-community/src/widget/toolbarWidget.ts
var ToolbarWidget = class extends RovingTabContainerWidget {
  constructor(orientation = "horizontal") {
    super(orientation, "toolbar");
  }
  destructor() {
  }
};

// packages/ag-charts-community/src/dom/proxyInteractionService.ts
function checkType(type, meta) {
  return meta.params?.type === type;
}
function allocateResult(type) {
  if ("button" === type) {
    return new ButtonWidget();
  } else if ("slider" === type) {
    return new SliderWidget();
  } else if ("toolbar" === type) {
    return new ToolbarWidget();
  } else if ("group" === type) {
    return new GroupWidget();
  } else if ("list" === type) {
    return new ListWidget();
  } else if ("region" === type) {
    return new NativeWidget(createElement("div"));
  } else if ("text" === type) {
    return new BoundedTextWidget();
  } else if ("listswitch" === type) {
    return new SwitchWidget();
  } else {
    throw new Error("AG Charts - error allocating meta");
  }
}
function allocateMeta(params) {
  const meta = { params, result: void 0 };
  meta.result = allocateResult(meta.params.type);
  return meta;
}
var ProxyInteractionService = class {
  constructor(eventsHub, localeManager, domManager) {
    this.eventsHub = eventsHub;
    this.localeManager = localeManager;
    this.domManager = domManager;
    this.cleanup = new CleanupRegistry();
  }
  destroy() {
    this.cleanup.flush();
  }
  addLocalisation(fn) {
    fn();
    this.cleanup.register(this.eventsHub.on("locale:change", fn));
  }
  createProxyContainer(args) {
    const meta = allocateMeta(args);
    const { params, result } = meta;
    const div = result.getElement();
    this.domManager.addChild("canvas-proxy", params.domManagerId, div);
    div.classList.add(...params.classList, "ag-charts-proxy-container");
    div.role = params.role ?? params.type;
    if (checkType("toolbar", meta)) {
      meta.result.orientation = meta.params.orientation;
    }
    const { ariaLabel } = params;
    if (ariaLabel) {
      this.addLocalisation(() => {
        div.ariaLabel = this.localeManager.t(ariaLabel.id, ariaLabel.params);
      });
    }
    return result;
  }
  createProxyElement(args) {
    const meta = allocateMeta(args);
    if (checkType("button", meta)) {
      const { params, result } = meta;
      const button = result.getElement();
      this.initInteract(params, result);
      if (typeof params.textContent === "string") {
        button.textContent = params.textContent;
      } else {
        const { textContent } = params;
        this.addLocalisation(() => {
          button.textContent = this.localeManager.t(textContent.id, textContent.params);
        });
      }
      this.setParent(meta.params, meta.result);
    }
    if (checkType("slider", meta)) {
      const { params, result } = meta;
      const slider = result.getElement();
      this.initInteract(params, result);
      slider.type = "range";
      slider.role = params.role ?? "presentation";
      slider.style.margin = "0px";
      this.addLocalisation(() => {
        slider.ariaLabel = this.localeManager.t(params.ariaLabel.id, params.ariaLabel.params);
      });
      this.setParent(meta.params, meta.result);
    }
    if (checkType("text", meta)) {
      const { params, result } = meta;
      this.initElement(params, result);
      this.setParent(meta.params, meta.result);
    }
    if (checkType("listswitch", meta)) {
      const { params, result: button } = meta;
      this.initInteract(params, button);
      button.setTextContent(params.textContent);
      button.setChecked(params.ariaChecked);
      button.setAriaDescribedBy(params.ariaDescribedBy);
      this.setParent(meta.params, meta.result);
    }
    if (checkType("region", meta)) {
      const { params, result } = meta;
      const region = result.getElement();
      this.initInteract(params, result);
      region.role = params.role ?? "region";
      this.setParent(meta.params, meta.result);
    }
    return meta.result;
  }
  initElement(params, widget) {
    const element2 = widget.getElement();
    setElementStyle(element2, "cursor", params.cursor);
    element2.classList.toggle("ag-charts-proxy-elem", true);
    if (params.classList?.length) {
      element2.classList.add(...params.classList);
    }
    return element2;
  }
  initInteract(params, widget) {
    const { tabIndex, domIndex } = params;
    const element2 = this.initElement(params, widget);
    if (tabIndex !== void 0) {
      element2.tabIndex = tabIndex;
    }
    if (domIndex !== void 0) {
      widget.domIndex = domIndex;
    }
  }
  setParent(params, element2) {
    if ("parent" in params) {
      params.parent?.addChild(element2);
    } else {
      const insert = { where: params.where, query: ".ag-charts-series-area" };
      this.domManager.addChild("canvas-proxy", params.domManagerId, element2.getElement(), insert);
      element2.destroyListener = () => {
        this.domManager.removeChild("canvas-proxy", params.domManagerId);
      };
    }
  }
};

// packages/ag-charts-community/src/locale/defaultMessageFormatter.ts
var messageRegExp = /\$\{(\w+)}(?:\[(\w+)])?/gi;
var formatters = {
  number: new Intl.NumberFormat("en-US"),
  percent: new Intl.NumberFormat("en-US", { style: "percent", minimumFractionDigits: 2, maximumFractionDigits: 2 }),
  percent0to2dp: new Intl.NumberFormat("en-US", {
    style: "percent",
    minimumFractionDigits: 0,
    maximumFractionDigits: 2
  }),
  date: new Intl.DateTimeFormat("en-US", { dateStyle: "full" }),
  time: new Intl.DateTimeFormat("en-US", { timeStyle: "full" }),
  datetime: new Intl.DateTimeFormat("en-US", { dateStyle: "full", timeStyle: "full" })
};
var defaultMessageFormatter = ({ defaultValue, variables }) => {
  return defaultValue?.replaceAll(messageRegExp, (_, match, format) => {
    const value = variables[match];
    const formatter2 = format == null ? null : formatters[format];
    if (format != null && formatter2 == null) {
      logger_exports.warnOnce(`Format style [${format}] is not supported`);
    }
    if (formatter2 != null) {
      return formatter2.format(value);
    } else if (typeof value === "number") {
      return formatters.number.format(value);
    } else if (value instanceof Date) {
      return formatters.datetime.format(value);
    }
    return String(value);
  });
};

// packages/ag-charts-community/src/locale/localeManager.ts
var LocaleManager = class {
  constructor(eventsHub) {
    this.eventsHub = eventsHub;
    this.localeText = void 0;
    this.getLocaleText = void 0;
  }
  setLocaleText(localeText) {
    if (this.localeText !== localeText) {
      this.localeText = localeText;
      this.eventsHub.emit("locale:change", null);
    }
  }
  setLocaleTextFormatter(getLocaleText) {
    this.getLocaleText = getLocaleText;
    if (this.getLocaleText !== getLocaleText) {
      this.getLocaleText = getLocaleText;
      this.eventsHub.emit("locale:change", null);
    }
  }
  t(key, variables = {}) {
    const { localeText = AG_CHARTS_LOCALE_EN_US, getLocaleText } = this;
    const defaultValue = localeText[key];
    return String(
      getLocaleText?.({ key, defaultValue, variables }) ?? defaultMessageFormatter({ key, defaultValue, variables }) ?? key
    );
  }
};

// packages/ag-charts-community/src/scene/canvas/hdpiCanvas.ts
var HdpiCanvas = class {
  constructor(options) {
    this.enabled = true;
    this.width = 600;
    this.height = 300;
    const { width: width2, height: height2, canvasElement, willReadFrequently = false } = options;
    this.pixelRatio = options.pixelRatio ?? getWindow("devicePixelRatio") ?? 1;
    this.element = canvasElement ?? createElement("canvas");
    this.element.style.display = "block";
    this.element.style.width = (width2 ?? this.width) + "px";
    this.element.style.height = (height2 ?? this.height) + "px";
    this.element.width = Math.round((width2 ?? this.width) * this.pixelRatio);
    this.element.height = Math.round((height2 ?? this.height) * this.pixelRatio);
    this.context = this.element.getContext("2d", { willReadFrequently });
    this.onEnabledChange();
    this.resize(width2 ?? 0, height2 ?? 0, this.pixelRatio);
    debugContext(this.context);
  }
  // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents -- OffscreenCanvasRenderingContext2D is intentionally `any` for Angular 13+ compatibility (AG-6969)
  drawImage(context, dx2 = 0, dy2 = 0) {
    return context.drawImage(this.context.canvas, dx2, dy2);
  }
  toDataURL(type) {
    return this.element.toDataURL(type);
  }
  resize(width2, height2, pixelRatio) {
    if (!(width2 > 0 && height2 > 0))
      return;
    const { element: element2, context } = this;
    element2.width = Math.round(width2 * pixelRatio);
    element2.height = Math.round(height2 * pixelRatio);
    context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
    element2.style.width = width2 + "px";
    element2.style.height = height2 + "px";
    this.width = width2;
    this.height = height2;
    this.pixelRatio = pixelRatio;
  }
  clear() {
    clearContext(this);
  }
  destroy() {
    this.element.remove();
    this.element.width = 0;
    this.element.height = 0;
    this.context.clearRect(0, 0, 0, 0);
    Object.freeze(this);
  }
  reset() {
    this.context.reset();
    this.context.verifyDepthZero?.();
  }
  onEnabledChange() {
    if (this.element) {
      this.element.style.display = this.enabled ? "" : "none";
    }
  }
};
__decorateClass([
  ObserveChanges((target) => target.onEnabledChange())
], HdpiCanvas.prototype, "enabled", 2);

// packages/ag-charts-community/src/scene/image/imageLoader.ts
var ImageLoader = class extends EventEmitter {
  constructor() {
    super(...arguments);
    this.cache = /* @__PURE__ */ new Map();
    this.imageLoadingCount = 0;
  }
  loadImage(uri, affectedNode) {
    const entry = this.cache.get(uri);
    if (entry?.image) {
      return entry.image;
    } else if (entry != null && affectedNode) {
      entry.nodes.add(affectedNode);
      return;
    }
    if (!affectedNode) {
      return;
    }
    const nextEntry = { image: void 0, nodes: /* @__PURE__ */ new Set([affectedNode]) };
    const ImageCtor = getImage();
    const image = new ImageCtor();
    this.imageLoadingCount++;
    image.onload = () => {
      nextEntry.image = image;
      for (const node of nextEntry.nodes) {
        node.markDirty();
      }
      nextEntry.nodes.clear();
      this.imageLoadingCount--;
      this.emit("image-loaded", { uri });
    };
    image.onerror = () => {
      this.imageLoadingCount--;
      nextEntry.nodes.clear();
      this.emit("image-error", { uri });
    };
    image.src = uri;
    this.cache.set(uri, nextEntry);
    return nextEntry.image;
  }
  waitingToLoad() {
    return this.imageLoadingCount > 0;
  }
  destroy() {
    for (const entry of this.cache.values()) {
      entry.nodes.clear();
    }
    this.cache.clear();
  }
};

// packages/ag-charts-community/src/scene/layersManager.ts
var LayersManager = class {
  constructor(canvas) {
    this.canvas = canvas;
    this.debug = debugLogger_exports.create(true, "scene");
    this.layersMap = /* @__PURE__ */ new Map();
    this.nextLayerId = 0;
  }
  get size() {
    return this.layersMap.size;
  }
  resize(width2, height2, pixelRatio) {
    this.canvas.resize(width2, height2, pixelRatio);
    for (const { canvas } of this.layersMap.values()) {
      canvas.resize(width2, height2, pixelRatio);
    }
  }
  addLayer(opts) {
    const { width: width2, height: height2, pixelRatio } = this.canvas;
    const { name } = opts;
    const canvas = new HdpiOffscreenCanvas({ width: width2, height: height2, pixelRatio });
    this.layersMap.set(canvas, {
      id: this.nextLayerId++,
      name,
      canvas
    });
    this.debug("Scene.addLayer() - layers", this.layersMap);
    return canvas;
  }
  removeLayer(canvas) {
    if (this.layersMap.has(canvas)) {
      this.layersMap.delete(canvas);
      canvas.destroy();
      this.debug("Scene.removeLayer() -  layers", this.layersMap);
    }
  }
  clear() {
    for (const layer of this.layersMap.values()) {
      layer.canvas.destroy();
    }
    this.layersMap.clear();
  }
};

// packages/ag-charts-community/src/scene/scene.ts
var Scene = class extends EventEmitter {
  constructor(canvasOptions) {
    super();
    this.debug = debugLogger_exports.create(true, "scene" /* SCENE */);
    this.id = createId(this);
    this.imageLoader = new ImageLoader();
    this.root = null;
    this.pendingSize = null;
    this.isDirty = false;
    this.cleanup = new CleanupRegistry();
    this.updateDebugFlags();
    this.canvas = new HdpiCanvas(canvasOptions);
    this.layersManager = new LayersManager(this.canvas);
    this.cleanup.register(
      this.imageLoader.on("image-loaded", () => {
        this.emit("scene-changed", {});
      }),
      this.imageLoader.on("image-error", ({ uri }) => {
        logger_exports.warnOnce(`Unable to load image ${uri}`);
      })
    );
  }
  waitingForUpdate() {
    return this.imageLoader?.waitingToLoad() ?? false;
  }
  get width() {
    return this.pendingSize?.[0] ?? this.canvas.width;
  }
  get height() {
    return this.pendingSize?.[1] ?? this.canvas.height;
  }
  get pixelRatio() {
    return this.pendingSize?.[2] ?? this.canvas.pixelRatio;
  }
  /**
   * @deprecated v10.2.0 Only used by AG Grid Sparklines + Mini Charts
   *
   * DO NOT REMOVE WITHOUT FIXING THE GRID DEPENDENCIES.
   */
  setContainer(value) {
    const { element: element2 } = this.canvas;
    element2.remove();
    value.appendChild(element2);
    return this;
  }
  setRoot(node) {
    if (this.root === node) {
      return this;
    }
    this.isDirty = true;
    this.root?.setScene();
    this.root = node;
    if (node) {
      node.visible = true;
      node.setScene(this);
    }
    return this;
  }
  updateDebugFlags() {
    debugLogger_exports.inDevelopmentMode(() => Node2._debugEnabled = true);
  }
  clearCanvas() {
    this.canvas.clear();
  }
  attachNode(node) {
    this.appendChild(node);
    return () => node.remove();
  }
  appendChild(node) {
    this.root?.appendChild(node);
    return this;
  }
  removeChild(node) {
    node.remove();
    return this;
  }
  download(fileName, fileFormat) {
    downloadUrl(this.canvas.toDataURL(fileFormat), fileName?.trim() ?? "image");
  }
  /** NOTE: Integrated Charts undocumented image download method. */
  getDataURL(fileFormat) {
    return this.canvas.toDataURL(fileFormat);
  }
  resize(width2, height2, pixelRatio) {
    width2 = Math.round(width2);
    height2 = Math.round(height2);
    pixelRatio ?? (pixelRatio = this.pixelRatio);
    if (width2 > 0 && height2 > 0 && (width2 !== this.width || height2 !== this.height || pixelRatio !== this.pixelRatio)) {
      this.pendingSize = [width2, height2, pixelRatio];
      this.isDirty = true;
      return true;
    }
    return false;
  }
  applyPendingResize() {
    if (this.pendingSize) {
      this.layersManager.resize(...this.pendingSize);
      this.pendingSize = null;
      return true;
    }
    return false;
  }
  render(opts) {
    const { debugSplitTimes = { start: performance.now() }, extraDebugStats, seriesRect, debugColors } = opts ?? {};
    const { canvas, canvas: { context: ctx } = {}, root, width: width2, height: height2, pixelRatio: devicePixelRatio } = this;
    if (!ctx) {
      return;
    }
    const statsEnabled = debugLogger_exports.check("scene:stats" /* SCENE_STATS */, "scene:stats:verbose" /* SCENE_STATS_VERBOSE */);
    if (statsEnabled) {
      this.ensureDebugStatsRegistration();
    }
    const renderStartTime = performance.now();
    const resized = this.applyPendingResize();
    if (root && !root.visible) {
      this.isDirty = false;
      return;
    }
    let rootDirty;
    if (root instanceof Group) {
      rootDirty = root.dirty;
    }
    if (root != null && rootDirty === false && !this.isDirty) {
      if (this.debug.check()) {
        this.debug("Scene.render() - no-op", {
          tree: buildTree(root, "console")
        });
      }
      if (statsEnabled) {
        debugStats(
          this.layersManager,
          debugSplitTimes,
          ctx,
          void 0,
          extraDebugStats,
          seriesRect,
          debugColors
        );
      }
      return;
    }
    const renderCtx = {
      ctx,
      width: width2,
      height: height2,
      devicePixelRatio,
      debugNodes: {}
    };
    if (debugLogger_exports.check("scene:stats:verbose" /* SCENE_STATS_VERBOSE */)) {
      renderCtx.stats = {
        layersRendered: 0,
        layersSkipped: 0,
        nodesRendered: 0,
        nodesSkipped: 0,
        opsPerformed: 0,
        opsSkipped: 0
      };
    }
    prepareSceneNodeHighlight(renderCtx);
    let canvasCleared = false;
    if (rootDirty !== false || resized) {
      canvasCleared = true;
      canvas.clear();
    }
    if (root && debugLogger_exports.check("scene:dirtyTree" /* SCENE_DIRTY_TREE */)) {
      const { dirtyTree, paths } = buildDirtyTree(root);
      debugLogger_exports.create("scene:dirtyTree" /* SCENE_DIRTY_TREE */)("Scene.render() - dirtyTree", { dirtyTree, paths });
    }
    if (root && canvasCleared) {
      if (root.visible) {
        root.preRender(renderCtx);
      }
      if (this.debug.check()) {
        const tree = buildTree(root, "console");
        this.debug("Scene.render() - before", {
          canvasCleared,
          tree
        });
      }
      if (root.visible) {
        try {
          ctx.save();
          root.render(renderCtx);
          ctx.restore();
        } catch (e) {
          this.canvas.reset();
          throw e;
        }
      }
    }
    debugSplitTimes["\u270D\uFE0F"] = performance.now() - renderStartTime;
    ctx.verifyDepthZero?.();
    this.isDirty = false;
    if (statsEnabled) {
      debugStats(
        this.layersManager,
        debugSplitTimes,
        ctx,
        renderCtx.stats,
        extraDebugStats,
        seriesRect,
        debugColors
      );
    }
    debugSceneNodeHighlight(ctx, renderCtx.debugNodes);
    if (root && this.debug.check()) {
      this.debug("Scene.render() - after", {
        tree: buildTree(root, "console"),
        canvasCleared
      });
    }
  }
  ensureDebugStatsRegistration() {
    if (this.releaseDebugStats)
      return;
    const release = registerDebugStatsConsumer();
    const cleanup = () => {
      release();
      this.releaseDebugStats = void 0;
    };
    this.releaseDebugStats = cleanup;
    this.cleanup.register(cleanup);
  }
  toSVG() {
    const { root, width: width2, height: height2 } = this;
    if (root == null)
      return;
    return Node2.toSVG(root, width2, height2);
  }
  /** Alternative to destroy() that preserves re-usable resources. */
  strip() {
    const { context, pixelRatio } = this.canvas;
    context.setTransform(pixelRatio, 0, 0, pixelRatio, 0, 0);
    this.layersManager.clear();
    this.setRoot(null);
    this.isDirty = false;
    this.clear();
  }
  destroy() {
    this.strip();
    this.canvas.destroy();
    this.imageLoader.destroy();
    this.cleanup.flush();
    cleanupDebugStats();
    Object.assign(this, { canvas: void 0 });
  }
};
Scene.className = "Scene";

// packages/ag-charts-community/src/chart/annotation/annotationManager.ts
var AnnotationManager = class {
  constructor(eventsHub, annotationRoot, fireChartEvent) {
    this.eventsHub = eventsHub;
    this.annotationRoot = annotationRoot;
    this.fireChartEvent = fireChartEvent;
    this.mementoOriginatorKey = "annotations";
    this.annotations = [];
  }
  createMemento() {
    return this.annotations;
  }
  guardMemento(blob) {
    return blob == null || isArray(blob);
  }
  restoreMemento(_version, _mementoVersion, memento) {
    this.annotations = this.cleanData(memento ?? []).map((annotation) => {
      const annotationTheme = this.getAnnotationTypeStyles(annotation.type);
      return mergeDefaults(annotation, annotationTheme);
    });
    this.eventsHub.emit("annotations:restore", { annotations: this.annotations });
  }
  updateData(annotations) {
    this.annotations = this.cleanData(annotations ?? []);
  }
  fireChangedEvent() {
    this.fireChartEvent({ type: "annotations", annotations: deepClone([...this.annotations]) });
  }
  attachNode(node) {
    this.annotationRoot.append(node);
    return () => {
      node.remove();
      return this;
    };
  }
  setAnnotationStyles(styles) {
    this.styles = styles;
  }
  getAnnotationTypeStyles(type) {
    return this.styles?.[type];
  }
  cleanData(annotations) {
    for (const annotation of annotations) {
      if ("textAlign" in annotation)
        delete annotation.textAlign;
    }
    return annotations;
  }
};

// packages/ag-charts-community/src/chart/axis/axisManager.ts
var AxisManager = class {
  constructor(eventsHub, sceneRoot) {
    this.eventsHub = eventsHub;
    this.sceneRoot = sceneRoot;
    this.axes = /* @__PURE__ */ new Map();
    this.axisGridGroup = new Group({ name: "Axes-Grids", zIndex: 2 /* AXIS_GRID */ });
    this.axisGroup = new Group({ name: "Axes", zIndex: 3 /* AXIS */ });
    this.axisLabelGroup = new Group({ name: "Axes-Labels", zIndex: 15 /* SERIES_LABEL */ });
    this.axisCrosslineRangeGroup = new Group({
      name: "Axes-Crosslines-Range",
      zIndex: 6 /* SERIES_CROSSLINE_RANGE */
    });
    this.axisCrosslineLineGroup = new Group({
      name: "Axes-Crosslines-Line",
      zIndex: 10 /* SERIES_CROSSLINE_LINE */
    });
    this.axisCrosslineLabelGroup = new Group({
      name: "Axes-Crosslines-Label",
      zIndex: 15 /* SERIES_LABEL */
    });
    this.sceneRoot.appendChild(this.axisGroup);
    this.sceneRoot.appendChild(this.axisGridGroup);
    this.sceneRoot.appendChild(this.axisLabelGroup);
    this.sceneRoot.appendChild(this.axisCrosslineRangeGroup);
    this.sceneRoot.appendChild(this.axisCrosslineLineGroup);
    this.sceneRoot.appendChild(this.axisCrosslineLabelGroup);
  }
  updateAxes(oldAxes, newAxes) {
    const axisNodes = {
      axisNode: this.axisGroup,
      gridNode: this.axisGridGroup,
      labelNode: this.axisLabelGroup,
      crossLineRangeNode: this.axisCrosslineRangeGroup,
      crossLineLineNode: this.axisCrosslineLineGroup,
      crossLineLabelNode: this.axisCrosslineLabelGroup
    };
    for (const axis of oldAxes) {
      if (newAxes.includes(axis))
        continue;
      axis.detachAxis(axisNodes);
      axis.destroy();
    }
    for (const axis of newAxes) {
      if (oldAxes?.includes(axis))
        continue;
      axis.attachAxis(axisNodes);
    }
    this.axes.clear();
    for (const axis of newAxes) {
      const ctx = axis.createAxisContext();
      if (this.axes.has(ctx.direction)) {
        this.axes.get(ctx.direction)?.push(ctx);
      } else {
        this.axes.set(ctx.direction, [ctx]);
      }
    }
    this.eventsHub.emit("axis:change", null);
  }
  getAxisIdContext(id) {
    for (const [, contextsInThisDir] of this.axes) {
      for (const ctx of contextsInThisDir) {
        if (ctx.axisId === id)
          return ctx;
      }
    }
  }
  getAxisContext(direction) {
    return this.axes.get(direction) ?? [];
  }
  destroy() {
    this.axes.clear();
    this.axisGroup.remove();
    this.axisGridGroup.remove();
  }
};

// packages/ag-charts-community/src/chart/data/dataService.ts
var DataService = class {
  constructor(eventsHub, caller, animationManager) {
    this.eventsHub = eventsHub;
    this.caller = caller;
    this.animationManager = animationManager;
    this.dispatchOnlyLatest = true;
    this.dispatchThrottle = 0;
    this.requestThrottle = 300;
    this.isLoadingInitialData = false;
    this.isLoadingData = false;
    this.freshRequests = [];
    this.requestCounter = 0;
    this.pendingData = void 0;
    this.debug = debugLogger_exports.create(true, "data-model", "data-source");
    this.throttledFetch = this.createThrottledFetch(this.requestThrottle);
    this.throttledDispatch = this.createThrottledDispatch(this.dispatchThrottle);
  }
  updateCallback(dataSourceCallback) {
    if (typeof dataSourceCallback !== "function")
      return;
    this.debug("DataService - updated data source callback");
    this.dataSourceCallback = dataSourceCallback;
    this.isLoadingInitialData = true;
    this.animationManager.skip();
    this.eventsHub.emit("data:source-change", null);
  }
  clearCallback() {
    this.dataSourceCallback = void 0;
  }
  load(params) {
    const { pendingData } = this;
    if (pendingData != null && (pendingData.params.windowStart == null && pendingData.params.windowEnd == null || pendingData.params.windowStart?.valueOf() === params.windowStart?.valueOf() && pendingData.params.windowEnd?.valueOf() === params.windowEnd?.valueOf())) {
      const id = this.requestCounter++;
      this.isLoadingInitialData = false;
      this.dispatch(id, pendingData.data);
      return;
    }
    this.isLoadingData = true;
    this.throttledFetch(params);
  }
  isLazy() {
    return this.dataSourceCallback != null;
  }
  isLoading() {
    return this.isLazy() && (this.isLoadingInitialData || this.isLoadingData);
  }
  async getData() {
    const { latestRequest } = this;
    if (!latestRequest)
      return;
    const { params, fetchRequest } = latestRequest;
    const data = await fetchRequest;
    return { params, data };
  }
  restoreData(data) {
    this.pendingData = data;
  }
  createThrottledFetch(requestThrottle) {
    return throttle(
      (params) => this.fetch(params).catch((e) => logger_exports.error("callback failed", e)),
      requestThrottle,
      { leading: false, trailing: true }
    );
  }
  createThrottledDispatch(dispatchThrottle) {
    return throttle((id, data) => this.dispatch(id, data), dispatchThrottle, {
      leading: true,
      trailing: true
    });
  }
  dispatch(id, data) {
    this.debug(`DataService - dispatching 'data-load' | ${id}`);
    this.eventsHub.emit("data:load", { data });
  }
  async fetch(params) {
    if ("context" in this.caller) {
      params.context = this.caller.context;
    }
    const fetchRequest = Promise.resolve().then(async () => {
      if (!this.dataSourceCallback) {
        throw new Error("DataService - [dataSource.getData] callback not initialised");
      }
      const start2 = performance.now();
      const id = this.requestCounter++;
      this.debug(`DataService - requesting | ${id}`);
      let response;
      try {
        response = await this.dataSourceCallback(params);
        this.debug(`DataService - response | ${performance.now() - start2}ms | ${id}`);
      } catch (error2) {
        this.debug(`DataService - request failed | ${id}`);
        logger_exports.errorOnce(`DataService - request failed | [${error2}]`);
      }
      this.isLoadingInitialData = false;
      const requestIndex = this.freshRequests.indexOf(fetchRequest);
      if (requestIndex === -1 || this.dispatchOnlyLatest && requestIndex !== this.freshRequests.length - 1) {
        this.debug(`DataService - discarding stale request | ${id}`);
        return response;
      }
      this.freshRequests = this.freshRequests.slice(requestIndex + 1);
      if (this.freshRequests.length === 0) {
        this.isLoadingData = false;
      }
      if (Array.isArray(response)) {
        this.throttledDispatch(id, response);
      } else {
        this.eventsHub.emit("data:error", null);
      }
      return response;
    });
    this.latestRequest = { params, fetchRequest };
    this.freshRequests.push(fetchRequest);
    await fetchRequest;
  }
};
__decorateClass([
  ActionOnSet({
    newValue(dispatchThrottle) {
      this.throttledDispatch = this.createThrottledDispatch(dispatchThrottle);
    }
  })
], DataService.prototype, "dispatchThrottle", 2);
__decorateClass([
  ActionOnSet({
    newValue(requestThrottle) {
      this.throttledFetch = this.createThrottledFetch(requestThrottle);
    }
  })
], DataService.prototype, "requestThrottle", 2);

// packages/ag-charts-community/src/chart/fonts/fontManager.ts
var FontManager = class {
  constructor(domManager, updateService) {
    this.domManager = domManager;
    this.updateService = updateService;
    this.observers = [];
  }
  updateFonts(fonts) {
    if (!fonts || fonts.size === 0)
      return;
    this.loadFonts(fonts);
    for (const font3 of fonts) {
      this.observeFontStatus(font3);
    }
  }
  destroy() {
    for (const observer of this.observers) {
      observer.disconnect();
    }
    this.observers = [];
  }
  loadFonts(fonts) {
    const fontStrings = Array.from(fonts).map((font3) => encodeURIComponent(font3));
    const fontStyle = ":wght@100;200;300;400;500;600;700;800;900";
    const joinString = `${fontStyle}&family=`;
    const css = `@import url('https://fonts.googleapis.com/css2?family=${fontStrings.join(joinString)}${fontStyle}&display=swap');
`;
    this.domManager.addStyles(`google-font-${fontStrings.join("-")}`, css);
  }
  observeFontStatus(font3) {
    const ResizeObserverCtor = getResizeObserver();
    if (ResizeObserverCtor === void 0)
      return;
    const doc = getDocument();
    if (!doc)
      return;
    const fontCheckElement = doc.createElement("div");
    fontCheckElement.style.setProperty("position", "absolute");
    fontCheckElement.style.setProperty("top", "0");
    fontCheckElement.style.setProperty("margin", "0");
    fontCheckElement.style.setProperty("padding", "0");
    fontCheckElement.style.setProperty("overflow", "hidden");
    fontCheckElement.style.setProperty("visibility", "hidden");
    fontCheckElement.style.setProperty("width", "auto");
    fontCheckElement.style.setProperty("max-width", "none");
    fontCheckElement.style.setProperty("font-synthesis", "none");
    fontCheckElement.style.setProperty("font-family", font3);
    fontCheckElement.style.setProperty("font-size", "16px");
    fontCheckElement.style.setProperty("white-space", "nowrap");
    fontCheckElement.textContent = "UVWxyz";
    this.domManager.addChild("canvas-container", `font-check-${encodeURIComponent(font3)}`, fontCheckElement);
    const fontCheckObserver = new ResizeObserverCtor((entries2) => {
      const width2 = entries2?.at(0)?.contentBoxSize.at(0)?.inlineSize;
      if (width2 != null && width2 > 0) {
        cachedTextMeasurer.clear();
        this.updateService.update(5 /* PERFORM_LAYOUT */);
      }
    });
    fontCheckObserver.observe(fontCheckElement);
    this.observers.push(fontCheckObserver);
  }
};

// packages/ag-charts-community/src/util/listeners.ts
var Listeners = class {
  constructor() {
    this.registeredListeners = /* @__PURE__ */ new Map();
  }
  addListener(eventType, handler) {
    const record2 = { symbol: Symbol(eventType), handler };
    if (this.registeredListeners.has(eventType)) {
      this.registeredListeners.get(eventType).push(record2);
    } else {
      this.registeredListeners.set(eventType, [record2]);
    }
    return () => this.removeListener(record2.symbol);
  }
  removeListener(eventSymbol) {
    for (const [type, listeners] of this.registeredListeners.entries()) {
      const matchIndex = listeners.findIndex((listener) => listener.symbol === eventSymbol);
      if (matchIndex >= 0) {
        listeners.splice(matchIndex, 1);
        if (listeners.length === 0) {
          this.registeredListeners.delete(type);
        }
        break;
      }
    }
  }
  dispatch(eventType, ...params) {
    for (const listener of this.getListenersByType(eventType)) {
      try {
        listener.handler(...params);
      } catch (e) {
        logger_exports.errorOnce(e);
      }
    }
  }
  getListenersByType(eventType) {
    return this.registeredListeners.get(eventType) ?? [];
  }
  destroy() {
    this.registeredListeners.clear();
  }
};

// packages/ag-charts-community/src/chart/axis/timeFormatUtil.ts
var defaultTimeFormats = {
  millisecond: "%H:%M:%S.%L",
  second: "%H:%M:%S",
  minute: "%H:%M",
  hour: "%H:%M",
  day: "%e",
  month: "%b",
  year: "%Y"
};
var hardCodedTimeFormats = {
  millisecond: "%Y %b %e %H:%M:%S.%L",
  second: "%Y %b %e %H:%M:%S",
  minute: "%Y %b %e %H:%M",
  hour: "%Y %b %e %H:%M",
  day: "%Y %b %e",
  month: "%Y %b",
  year: "%Y"
};
var FORMAT_ORDERS = {
  year: 0,
  month: 1,
  day: 2,
  hour: 3,
  minute: 4,
  second: 5,
  millisecond: 6
};
var MILLISECOND_FORMAT = /%[-_0]?L/;
var SECOND_FORMAT = /%[-_0]?S/;
var MINUTE_FORMAT = /%[-_0]?M/;
var HOUR_FORMAT = /%[-_0]?[HI]/;
var DAY_FORMAT = /^%[-_0]?[de]$/;
var MONTH_FORMAT = /^%[-_0]?[Bbm]$/;
var YEAR_FORMAT = /^%[-_0]?[Yy]$/;
function deriveTimeSpecifier(format, unit, truncateDate) {
  if (typeof format === "string")
    return format;
  format ?? (format = defaultTimeFormats);
  const {
    millisecond = defaultTimeFormats.millisecond,
    second = defaultTimeFormats.second,
    minute = defaultTimeFormats.minute,
    hour = defaultTimeFormats.hour,
    day = defaultTimeFormats.day,
    month = defaultTimeFormats.month,
    year = defaultTimeFormats.year
  } = format;
  const formatOrder = FORMAT_ORDERS[unit];
  const hardcodedTimeFormat = hardCodedTimeFormats[unit];
  const truncationOrder = truncateDate ? FORMAT_ORDERS[truncateDate] : -1;
  if (truncationOrder < FORMAT_ORDERS.year && formatOrder >= FORMAT_ORDERS.year && !YEAR_FORMAT.test(year) || truncationOrder < FORMAT_ORDERS.month && formatOrder >= FORMAT_ORDERS.month && !MONTH_FORMAT.test(month) || truncationOrder < FORMAT_ORDERS.day && formatOrder >= FORMAT_ORDERS.day && !DAY_FORMAT.test(day)) {
    return hardcodedTimeFormat;
  }
  let timeFormat;
  switch (unit) {
    case "year":
      return year;
    case "month":
      return truncationOrder < FORMAT_ORDERS.year ? `${month} ${year}` : month;
    case "day":
      return truncationOrder < FORMAT_ORDERS.year ? `${month} ${day} ${year}` : `${month} ${day}`;
    case "hour":
      timeFormat = hour;
      break;
    case "minute":
      timeFormat = minute;
      break;
    case "second":
      timeFormat = second;
      break;
    case "millisecond":
      timeFormat = millisecond;
      break;
    default:
      return hardcodedTimeFormat;
  }
  if (formatOrder >= FORMAT_ORDERS.hour && !HOUR_FORMAT.test(timeFormat) || formatOrder >= FORMAT_ORDERS.minute && !MINUTE_FORMAT.test(timeFormat) || formatOrder >= FORMAT_ORDERS.second && !SECOND_FORMAT.test(timeFormat) || formatOrder >= FORMAT_ORDERS.millisecond && !MILLISECOND_FORMAT.test(timeFormat)) {
    return hardcodedTimeFormat;
  }
  let dateFormat;
  if (truncationOrder < FORMAT_ORDERS.year) {
    dateFormat = `${month} ${day} ${year}`;
  } else if (truncationOrder < FORMAT_ORDERS.month) {
    dateFormat = `${month} ${day}`;
  }
  return dateFormat ? `${timeFormat} ${dateFormat}` : timeFormat;
}

// packages/ag-charts-community/src/chart/formatter/formatManager.ts
var FormatManager = class _FormatManager extends Listeners {
  constructor() {
    super(...arguments);
    this.formats = /* @__PURE__ */ new Map();
    this.dateFormatter = simpleMemorize2(
      (propertyFormatter, specifier, unit, style2, truncateDate) => {
        const mergedFormatter = _FormatManager.mergeSpecifiers(propertyFormatter, specifier) ?? defaultTimeFormats;
        return _FormatManager.getFormatter("date", mergedFormatter, unit, style2, { truncateDate });
      }
    );
    this.formatter = void 0;
  }
  static mergeSpecifiers(...specifiers) {
    let out;
    for (const specifier of specifiers) {
      if (isPlainObject(specifier) && isPlainObject(out)) {
        out = { ...out, ...specifier };
      } else {
        out = specifier;
      }
    }
    return out;
  }
  static getFormatter(type, specifier, unit, style2 = "long", { truncateDate } = {}) {
    if (isPlainObject(specifier)) {
      if (type !== "date") {
        logger_exports.warn("Date formatter configuration is not supported for non-date types.");
        return;
      }
      unit ?? (unit = "millisecond");
      const fullFormat = style2 === "component" ? specifier?.[unit] ?? defaultTimeFormats[unit] : deriveTimeSpecifier(specifier, unit, truncateDate);
      return buildDateFormatter(fullFormat);
    }
    switch (type) {
      case "number": {
        const options = parseNumberFormat(specifier);
        if (options == null)
          return;
        return createNumberFormatter(options);
      }
      case "date":
        return buildDateFormatter(specifier);
      case "category":
        return (value) => specifier.replace("%s", String(value));
    }
  }
  setFormatter(formatter2) {
    if (this.formatter !== formatter2) {
      this.formatter = formatter2;
      this.formats.clear();
      this.dateFormatter.reset();
      this.dispatch("format-changed");
    }
  }
  format(formatInContext, params, { specifier, truncateDate, allowNull } = {}) {
    if (params.value == null && !allowNull)
      return;
    const { formatter: formatter2 } = this;
    if (formatter2 == null)
      return;
    if (typeof formatter2 === "function") {
      const value = formatInContext(formatter2, params);
      return value == null ? void 0 : String(value);
    }
    const propertyFormatter = formatter2[params.property];
    if (propertyFormatter == null)
      return;
    if (typeof propertyFormatter === "function") {
      const value = formatInContext(propertyFormatter, params);
      return value == null ? value : toTextString(value);
    } else if (params.type === "date") {
      const { unit, style: style2 } = params;
      const dateFormatter = this.dateFormatter(propertyFormatter, specifier, unit, style2, truncateDate);
      return dateFormatter?.(params.value);
    }
    const valueSpecifier = specifier ?? propertyFormatter;
    if (typeof valueSpecifier !== "string")
      return;
    let valueFormatter = this.formats.get(valueSpecifier);
    if (valueFormatter == null) {
      valueFormatter = _FormatManager.getFormatter(params.type, valueSpecifier);
      this.formats.set(valueSpecifier, valueFormatter);
    }
    return valueFormatter?.(params.value, params.type === "number" ? params.fractionDigits : void 0);
  }
  defaultFormat(params, { specifier, truncateDate } = {}) {
    const { formatter: formatter2 } = this;
    const propertyFormatter = typeof formatter2 === "function" ? void 0 : formatter2?.[params.property];
    switch (params.type) {
      case "date": {
        const { unit, style: style2 } = params;
        const propertySpecifier = propertyFormatter != null && typeof propertyFormatter !== "function" ? propertyFormatter : void 0;
        const dateFormatter = this.dateFormatter(propertySpecifier, specifier, unit, style2, truncateDate);
        return dateFormatter?.(params.value) ?? String(params.value);
      }
      case "number":
        return formatValue(params.value, params.fractionDigits);
      case "category":
        if (params.value == null) {
          return "";
        } else if (Array.isArray(params.value)) {
          return params.value.join(" - ");
        } else if (typeof params.value === "string") {
          return params.value;
        } else if (typeof params.value === "number") {
          return formatValue(params.value);
        } else {
          return String(params.value);
        }
    }
  }
};

// packages/ag-charts-community/src/chart/chartOptionsDefs.ts
var initialStatePickedOptionsDef = {
  activeItem: {
    type: required(strictUnion()("series-node", "legend")),
    seriesId: string,
    itemId: required(or(string, positiveNumber))
  }
};
initialStatePickedOptionsDef.frozen = undocumented(boolean);
var commonChartOptions = {
  mode: undocumented(union("integrated", "standalone")),
  container: htmlElement,
  context: () => true,
  theme: defined,
  series: array,
  annotations: defined,
  navigator: defined,
  scrollbar: defined,
  initialState: {
    active: initialStatePickedOptionsDef,
    chartType: string,
    annotations: defined,
    legend: arrayOfDefs(
      {
        visible: boolean,
        seriesId: string,
        itemId: string,
        legendItemName: string
      },
      "legend state array"
    ),
    zoom: defined
  }
};
var cartesianChartOptionsDefs = {
  ...commonChartOptionsDefs,
  ...commonChartOptions,
  axes: object,
  data: array
};
var polarChartOptionsDefs = {
  ...commonChartOptionsDefs,
  ...commonChartOptions,
  axes: object,
  data: array
};
var topologyChartOptionsDefs = {
  ...commonChartOptionsDefs,
  ...commonChartOptions,
  data: array,
  topology: geoJson
};
var standaloneChartOptionsDefs = {
  ...commonChartOptionsDefs,
  ...commonChartOptions,
  data: array
};

// packages/ag-charts-community/src/chart/interaction/interactionManager.ts
var InteractionState = /* @__PURE__ */ ((InteractionState8) => {
  InteractionState8[InteractionState8["Default"] = 64] = "Default";
  InteractionState8[InteractionState8["ZoomDrag"] = 32] = "ZoomDrag";
  InteractionState8[InteractionState8["Annotations"] = 16] = "Annotations";
  InteractionState8[InteractionState8["ContextMenu"] = 8] = "ContextMenu";
  InteractionState8[InteractionState8["Animation"] = 4] = "Animation";
  InteractionState8[InteractionState8["AnnotationsSelected"] = 2] = "AnnotationsSelected";
  InteractionState8[InteractionState8["Frozen"] = 1] = "Frozen";
  InteractionState8[InteractionState8["Clickable"] = 82] = "Clickable";
  InteractionState8[InteractionState8["Focusable"] = 68] = "Focusable";
  InteractionState8[InteractionState8["Keyable"] = 86] = "Keyable";
  InteractionState8[InteractionState8["ContextMenuable"] = 72] = "ContextMenuable";
  InteractionState8[InteractionState8["AnnotationsMoveable"] = 18] = "AnnotationsMoveable";
  InteractionState8[InteractionState8["AnnotationsDraggable"] = 114] = "AnnotationsDraggable";
  InteractionState8[InteractionState8["ZoomDraggable"] = 100] = "ZoomDraggable";
  InteractionState8[InteractionState8["ZoomClickable"] = 68] = "ZoomClickable";
  InteractionState8[InteractionState8["ZoomWheelable"] = 118] = "ZoomWheelable";
  InteractionState8[InteractionState8["All"] = 126] = "All";
  return InteractionState8;
})(InteractionState || {});
var InteractionManager = class {
  constructor() {
    this.stateQueue = 64 /* Default */ | 4 /* Animation */;
  }
  pushState(state) {
    this.stateQueue |= state;
  }
  popState(state) {
    this.stateQueue &= ~state;
  }
  isState(allowedStates) {
    return !!(this.stateQueue & -this.stateQueue & allowedStates);
  }
};

// packages/ag-charts-community/src/chart/interaction/activeManager.ts
var ActiveManager = class {
  constructor(chartService, eventsHub, updateService, interactionManager, fireEvent) {
    this.chartService = chartService;
    this.eventsHub = eventsHub;
    this.interactionManager = interactionManager;
    this.fireEvent = fireEvent;
    this.mementoOriginatorKey = "active";
    this.updateable = true;
    // FIXME: same pattern as `ZoomManager`. Perhaps an architectural rewrite is warranted.
    this.didLayout = false;
    this.pendingMemento = void 0;
    const removeListener = updateService.addListener("pre-scene-render", () => {
      this.didLayout = true;
      const { pendingMemento } = this;
      if (pendingMemento) {
        this.restoreMemento(pendingMemento.version, pendingMemento.mementoVersion, pendingMemento.memento);
        this.pendingMemento = void 0;
      }
      removeListener();
    });
  }
  isFrozen() {
    return this.interactionManager.isState(1 /* Frozen */);
  }
  clear() {
    this.update(void 0, void 0);
  }
  update(newItemState, nodeDatum) {
    this.performUpdate("user-interaction", newItemState, nodeDatum, false);
  }
  performUpdate(source, newItemState, nodeDatum, frozenChanged) {
    if (!this.updateable)
      return;
    const oldItemState = this.currentItem;
    this.currentItem = newItemState;
    this.eventsHub.emit("active:update", newItemState);
    if (frozenChanged || !objectsEqual(oldItemState, newItemState)) {
      const { activeItem } = this.createMemento();
      const { datum } = nodeDatum ?? {};
      this.fireEvent({ type: "activeChange", source, activeItem, datum });
    }
  }
  createMemento() {
    switch (this.currentItem?.type) {
      case "series-node":
      case "legend": {
        const { type, seriesId, itemId } = this.currentItem;
        return { activeItem: { type, seriesId, itemId } };
      }
      default:
        this.currentItem?.type;
        return {};
    }
  }
  guardMemento(blob, messages) {
    if (blob == void 0)
      return true;
    const validationResult = validate(blob, commonChartOptions.initialState.active);
    messages.push(...validationResult.invalid.map((err) => err.toString()));
    return validationResult.invalid.length === 0;
  }
  restoreMemento(version, mementoVersion, memento) {
    if (!this.didLayout) {
      this.pendingMemento = { version, mementoVersion, memento };
      return;
    }
    this.updateable = false;
    const [activeItem, nodeDatum] = this.performRestoration(memento?.activeItem);
    this.updateable = true;
    const oldFrozen = this.isFrozen();
    const newFrozen = memento?.frozen;
    const frozenChanged = newFrozen === void 0 ? false : oldFrozen !== newFrozen;
    if (newFrozen === true) {
      this.interactionManager.pushState(1 /* Frozen */);
    } else if (newFrozen === false) {
      this.interactionManager.popState(1 /* Frozen */);
    } else {
      newFrozen;
    }
    this.performUpdate("state-change", activeItem, nodeDatum, frozenChanged);
  }
  performRestoration(activeItem) {
    let rejection = false;
    const reject = () => rejection = true;
    let nodeDatum = void 0;
    const setDatum = (d) => nodeDatum = d;
    const initialState = this.pendingMemento !== void 0;
    const chartId = this.chartService.id;
    this.eventsHub.emit("active:load-memento", { initialState, chartId, activeItem, reject, setDatum });
    return rejection ? [void 0, void 0] : [activeItem, nodeDatum];
  }
};

// packages/ag-charts-community/src/util/interpolate.ts
function interpolateNumber(a, b) {
  return (d) => Number(a) * (1 - d) + Number(b) * d;
}
function interpolateColor(a, b) {
  if (typeof a === "string") {
    try {
      a = Color.fromString(a);
    } catch {
      a = Color.fromArray([0, 0, 0]);
    }
  }
  if (typeof b === "string") {
    try {
      b = Color.fromString(b);
    } catch {
      b = Color.fromArray([0, 0, 0]);
    }
  }
  return (d) => Color.mix(a, b, d).toRgbaString();
}

// packages/ag-charts-community/src/motion/animation.ts
var QUICK_TRANSITION = 0.2;
var PHASE_ORDER = ["initial", "remove", "update", "add", "trailing", "end", "none"];
var PHASE_METADATA = {
  initial: {
    animationDuration: 1,
    animationDelay: 0
  },
  add: {
    animationDuration: 0.25,
    animationDelay: 0.75
  },
  remove: {
    animationDuration: 0.25,
    animationDelay: 0
  },
  update: {
    animationDuration: 0.5,
    animationDelay: 0.25
  },
  trailing: {
    animationDuration: QUICK_TRANSITION,
    animationDelay: 1,
    skipIfNoEarlierAnimations: true
  },
  end: {
    animationDelay: 1 + QUICK_TRANSITION,
    animationDuration: 0,
    skipIfNoEarlierAnimations: true
  },
  none: {
    animationDuration: 0,
    animationDelay: 0
  }
};
function isNodeArray(array2) {
  return array2.every((n) => n instanceof Node2);
}
function deconstructSelectionsOrNodes(selectionsOrNodes) {
  return isNodeArray(selectionsOrNodes) ? { nodes: selectionsOrNodes, selections: [] } : { nodes: [], selections: selectionsOrNodes };
}
function animationValuesEqual(a, b) {
  if (a === b) {
    return true;
  } else if (Array.isArray(a) && Array.isArray(b)) {
    return a.length === b.length && a.every((v, i) => animationValuesEqual(v, b[i]));
  } else if (isInterpolating(a) && isInterpolating(b)) {
    return a.equals(b);
  } else if (isPlainObject(a) && isPlainObject(b)) {
    return objectsEqualWith(a, b, animationValuesEqual);
  }
  return false;
}
var Animation = class {
  constructor(opts) {
    this.isComplete = false;
    this.elapsed = 0;
    this.iteration = 0;
    this.isPlaying = false;
    this.isReverse = false;
    this.id = opts.id;
    this.groupId = opts.groupId;
    this.autoplay = opts.autoplay ?? true;
    this.ease = opts.ease ?? linear;
    this.phase = opts.phase;
    const durationProportion = opts.duration ?? PHASE_METADATA[this.phase].animationDuration;
    this.duration = durationProportion * opts.defaultDuration;
    this.delay = (opts.delay ?? 0) * opts.defaultDuration;
    this.onComplete = opts.onComplete;
    this.onPlay = opts.onPlay;
    this.onStop = opts.onStop;
    this.onUpdate = opts.onUpdate;
    this.interpolate = this.createInterpolator(opts.from, opts.to);
    this.from = opts.from;
    if (opts.skip === true) {
      this.onUpdate?.(opts.to, false, this);
      this.onStop?.(this);
      this.onComplete?.(this);
      this.isComplete = true;
    }
    if (opts.collapsable !== false) {
      this.duration = this.checkCollapse(opts, this.duration);
    }
  }
  checkCollapse(opts, calculatedDuration) {
    return animationValuesEqual(opts.from, opts.to) ? 0 : calculatedDuration;
  }
  play(initialUpdate = false) {
    if (this.isPlaying || this.isComplete)
      return;
    this.isPlaying = true;
    this.onPlay?.(this);
    if (!this.autoplay)
      return;
    this.autoplay = false;
    if (!initialUpdate)
      return;
    this.onUpdate?.(this.from, true, this);
  }
  stop() {
    this.isPlaying = false;
    if (!this.isComplete) {
      this.isComplete = true;
      this.onStop?.(this);
    }
  }
  update(time3) {
    if (this.isComplete)
      return time3;
    if (!this.isPlaying && this.autoplay) {
      this.play(true);
    }
    const previousElapsed = this.elapsed;
    this.elapsed += time3;
    if (this.delay > this.elapsed)
      return 0;
    const value = this.interpolate(this.isReverse ? 1 - this.delta : this.delta);
    this.onUpdate?.(value, false, this);
    const totalDuration = this.delay + this.duration;
    if (this.elapsed >= totalDuration) {
      this.stop();
      this.isComplete = true;
      this.onComplete?.(this);
      return time3 - (totalDuration - previousElapsed);
    }
    return 0;
  }
  get delta() {
    return this.ease(clamp(0, (this.elapsed - this.delay) / this.duration, 1));
  }
  createInterpolator(from3, to) {
    if (typeof to !== "object" || isInterpolating(to)) {
      return this.interpolateValue(from3, to);
    } else if (Array.isArray(to)) {
      const interpolatorValues = [];
      for (let i = 0; i < to.length; i++) {
        const interpolator = this.createInterpolator(from3[i], to[i]);
        if (interpolator != null) {
          interpolatorValues.push(interpolator);
        }
      }
      return (d) => {
        const out = [];
        for (const interpolator of interpolatorValues) {
          out.push(interpolator(d));
        }
        return out;
      };
    }
    const interpolatorEntries = [];
    for (const key of Object.keys(to)) {
      const interpolator = this.createInterpolator(from3[key], to[key]);
      if (interpolator != null) {
        interpolatorEntries.push([key, interpolator]);
      }
    }
    return (d) => {
      const result = {};
      for (const [key, interpolator] of interpolatorEntries) {
        result[key] = interpolator(d);
      }
      return result;
    };
  }
  interpolateValue(a, b) {
    if (a == null || b == null) {
      return;
    } else if (isInterpolating(a)) {
      return (d) => a[interpolate](b, d);
    }
    try {
      switch (typeof a) {
        case "number":
          return interpolateNumber(a, b);
        case "string":
          return interpolateColor(a, b);
        case "boolean":
          if (a === b) {
            return () => a;
          }
          break;
        case "object":
          return () => a;
        default:
          throw new Error(`Unable to interpolate values: ${a}, ${b}`);
      }
    } catch {
    }
    throw new Error(`Unable to interpolate values: ${a}, ${b}`);
  }
};

// packages/ag-charts-community/src/chart/data/data-model/utils/bandedStructure.ts
function adjustBandForInsertion(band, insertIndex, insertCount, isLastBand) {
  if (insertIndex < band.startIndex) {
    band.startIndex += insertCount;
    band.endIndex += insertCount;
    return false;
  } else if (insertIndex < band.endIndex || insertIndex === band.endIndex && isLastBand) {
    band.endIndex += insertCount;
    return true;
  }
  return false;
}
function adjustBandForRemoval(band, removeIndex, removeCount) {
  const removeEnd = removeIndex + removeCount;
  if (removeEnd <= band.startIndex) {
    band.startIndex = Math.max(0, band.startIndex - removeCount);
    band.endIndex = Math.max(band.startIndex, band.endIndex - removeCount);
    return false;
  } else if (removeIndex >= band.endIndex) {
    return false;
  } else {
    if (removeIndex <= band.startIndex && removeEnd >= band.endIndex) {
      band.startIndex = removeIndex;
      band.endIndex = removeIndex;
    } else if (removeIndex <= band.startIndex) {
      const deletedFromBand = removeEnd - band.startIndex;
      const oldBandSize = band.endIndex - band.startIndex;
      band.startIndex = removeIndex;
      band.endIndex = band.startIndex + Math.max(0, oldBandSize - deletedFromBand);
    } else if (removeEnd >= band.endIndex) {
      band.endIndex = Math.max(band.startIndex, removeIndex);
    } else {
      band.endIndex = Math.max(band.startIndex, band.endIndex - removeCount);
    }
    return true;
  }
}
function calculateTargetBandCount(dataSize, minBandCount) {
  const derivedCount = Math.ceil(dataSize / 1e3);
  return Math.max(minBandCount, derivedCount);
}
function calculateIdealBandSize(dataSize, targetBandCount) {
  return Math.max(1, Math.ceil(dataSize / targetBandCount));
}
function filterEmptyBands(bands) {
  return bands.filter((band) => band.endIndex > band.startIndex);
}
function initializeBandArray(dataSize, config, bandFactory) {
  if (!config.enableBanding || dataSize < config.minDataSizeForBanding) {
    return [bandFactory(0, dataSize)];
  }
  const targetBandCount = calculateTargetBandCount(dataSize, config.targetBandCount);
  const bandSize = calculateIdealBandSize(dataSize, targetBandCount);
  const bands = [];
  for (let startIndex = 0; startIndex < dataSize; startIndex += bandSize) {
    const endIndex = Math.min(startIndex + bandSize, dataSize);
    bands.push(bandFactory(startIndex, endIndex));
  }
  return bands;
}
function applySpliceOperations(bandHandler, spliceOps) {
  for (const op of spliceOps) {
    if (op.insertCount > 0) {
      bandHandler.handleInsertion(op.index, op.insertCount);
    }
    if (op.deleteCount > 0) {
      bandHandler.handleRemoval(op.index, op.deleteCount);
    }
  }
}
function markUpdatedIndices(bandHandler, updatedIndices) {
  for (const index of updatedIndices) {
    bandHandler.handleInsertion(index, 0);
  }
}
function applyIndexMapToBandHandler(bandHandler, indexMap) {
  applySpliceOperations(bandHandler, indexMap.spliceOps);
  if (indexMap.updatedIndices.size > 0) {
    markUpdatedIndices(bandHandler, indexMap.updatedIndices);
  }
}
var DEFAULT_MIN_DATA_SIZE_FOR_BANDING = 1e3;
var DEFAULT_TARGET_BAND_COUNT = 10;
var BandedStructure = class {
  constructor(config = {}) {
    this.bands = [];
    this.dataSize = 0;
    this.config = {
      minDataSizeForBanding: config.minDataSizeForBanding ?? DEFAULT_MIN_DATA_SIZE_FOR_BANDING,
      targetBandCount: config.targetBandCount ?? DEFAULT_TARGET_BAND_COUNT,
      maxBandSize: config.maxBandSize ?? Infinity,
      enableBanding: config.enableBanding ?? true
    };
  }
  applyIndexMap(indexMap) {
    applyIndexMapToBandHandler(this, indexMap);
  }
  /**
   * Initializes or rebalances bands based on current data size.
   */
  initializeBands(dataSize) {
    this.dataSize = Math.max(0, dataSize);
    this.bands = initializeBandArray(
      this.dataSize,
      this.config,
      (startIndex, endIndex) => this.createBand(startIndex, endIndex)
    );
  }
  /**
   * Returns the number of bands currently in this structure.
   * Useful for checking if bands need initialization.
   */
  getBandCount() {
    return this.bands.length;
  }
  /**
   * Handles insertion of new data by adjusting band indices.
   * Uses proactive band splitting to maintain optimal band sizes.
   */
  handleInsertion(insertIndex, insertCount) {
    this.dataSize += insertCount;
    if (this.bands.length === 0) {
      this.initializeBands(this.dataSize);
      return;
    }
    const targetBandCount = calculateTargetBandCount(this.dataSize, this.config.targetBandCount);
    const idealBandSize = calculateIdealBandSize(this.dataSize, targetBandCount);
    const maxBandSize = Math.ceil(idealBandSize * 1.1);
    for (let i = 0; i < this.bands.length; i++) {
      const band = this.bands[i];
      const isLastBand = i === this.bands.length - 1;
      if (insertIndex === band.endIndex && isLastBand && insertCount > 0) {
        const currentBandSize = band.endIndex - band.startIndex;
        if (currentBandSize >= idealBandSize) {
          this.bands.push(this.createBand(insertIndex, insertIndex + insertCount));
        } else {
          band.endIndex += insertCount;
          band.isDirty = true;
        }
        break;
      }
      const wasDirty = adjustBandForInsertion(band, insertIndex, insertCount, isLastBand);
      if (wasDirty) {
        band.isDirty = true;
        if (insertCount > 0 && insertIndex < band.endIndex) {
          const bandSize = band.endIndex - band.startIndex;
          if (bandSize > maxBandSize) {
            this.splitBand(i, idealBandSize);
          }
        }
      }
    }
  }
  /**
   * Handles removal of data by adjusting band indices.
   * Uses shared utilities for consistent band manipulation.
   */
  handleRemoval(removeIndex, removeCount) {
    if (removeCount <= 0 || this.bands.length === 0)
      return;
    const effectiveRemoveCount = Math.min(removeCount, Math.max(0, this.dataSize - removeIndex));
    if (effectiveRemoveCount <= 0)
      return;
    this.dataSize = Math.max(0, this.dataSize - effectiveRemoveCount);
    for (const band of this.bands) {
      const wasDirty = adjustBandForRemoval(band, removeIndex, effectiveRemoveCount);
      if (wasDirty) {
        band.isDirty = true;
      }
    }
    this.bands = filterEmptyBands(this.bands);
  }
  /**
   * Split an oversized band into two smaller bands.
   * Called when a band exceeds maxBandSize during insertion.
   *
   * Strategy:
   * - Split the band as evenly as possible
   * - Both halves marked as dirty (need recalculation)
   * - No cache preservation (splitting indicates data changed)
   */
  splitBand(bandIndex, idealSize) {
    const band = this.bands[bandIndex];
    const bandSize = band.endIndex - band.startIndex;
    const firstHalfSize = Math.min(idealSize, Math.floor(bandSize / 2));
    const splitPoint = band.startIndex + firstHalfSize;
    const band1 = this.createBand(band.startIndex, splitPoint);
    const band2 = this.createBand(splitPoint, band.endIndex);
    this.bands.splice(bandIndex, 1, band1, band2);
  }
  /**
   * Returns statistics about the banded structure for debugging.
   * Subclasses can override to add domain-specific stats.
   */
  getStats() {
    const dirtyBands = this.bands.filter((band) => band.isDirty);
    return {
      totalBands: this.bands.length,
      dirtyBands: dirtyBands.length,
      dataSize: this.dataSize
    };
  }
  markRangeDirty(startIndex, endIndex) {
    for (const band of this.bands) {
      if (startIndex < band.endIndex && endIndex > band.startIndex) {
        band.isDirty = true;
      }
    }
  }
};

// packages/ag-charts-community/src/chart/data/dataDomain.ts
var DiscreteDomain = class _DiscreteDomain {
  constructor() {
    // Set-based storage (default mode)
    this.domain = /* @__PURE__ */ new Set();
    this.dateTimestamps = /* @__PURE__ */ new Set();
    this.hasDateValues = false;
    // Sorted array storage (optimized mode for sorted unique data)
    this.sortedValues = null;
    this.sortOrder = void 0;
    this.isSortedUnique = false;
  }
  static is(value) {
    return value instanceof _DiscreteDomain;
  }
  /**
   * Configure domain for sorted unique mode.
   * When enabled, uses a single array for O(1) append.
   * Call this before extending with data.
   */
  setSortedUniqueMode(sortOrder, isUnique) {
    if (isUnique) {
      this.isSortedUnique = true;
      this.sortOrder = sortOrder;
      this.sortedValues = [];
    }
  }
  extend(val) {
    if (this.isSortedUnique && this.sortedValues) {
      this.sortedValues.push(val);
      if (val instanceof Date) {
        this.hasDateValues = true;
      }
    } else if (val instanceof Date) {
      this.hasDateValues = true;
      this.dateTimestamps.add(val.valueOf());
    } else {
      this.domain.add(val);
    }
  }
  getDomain() {
    if (this.isSortedUnique && this.sortedValues) {
      let hasSeenInvalid = false;
      return this.sortedValues.filter((v) => {
        if (v == null) {
          if (hasSeenInvalid)
            return false;
          hasSeenInvalid = true;
          return true;
        }
        if (v instanceof Date && Number.isNaN(v.valueOf())) {
          if (hasSeenInvalid)
            return false;
          hasSeenInvalid = true;
        }
        return true;
      });
    }
    if (this.hasDateValues) {
      const dates = Array.from(this.dateTimestamps, (ts) => new Date(ts));
      if (this.domain.size > 0) {
        return [...dates, ...Array.from(this.domain)];
      }
      return dates;
    }
    return Array.from(this.domain);
  }
  /** Returns true if this domain contains Date values stored as timestamps */
  isDateDomain() {
    return this.hasDateValues;
  }
  /** Returns true if this domain is in sorted unique mode */
  isSortedUniqueMode() {
    return this.isSortedUnique;
  }
  /** Returns the sort order if in sorted mode, undefined otherwise */
  getSortOrder() {
    return this.sortOrder;
  }
  /** Merges another DiscreteDomain's values into this one */
  mergeFrom(other) {
    if (this.isSortedUnique && other.isSortedUnique && this.sortOrder === other.sortOrder && this.sortOrder !== void 0 && other.sortedValues) {
      if (other.hasDateValues) {
        this.hasDateValues = true;
      }
      this.sortedValues ?? (this.sortedValues = []);
      this.sortedValues.push(...other.sortedValues);
      return;
    }
    this.convertToSetMode();
    if (other.hasDateValues) {
      this.hasDateValues = true;
    }
    if (other.isSortedUnique && other.sortedValues) {
      for (const val of other.sortedValues) {
        if (val instanceof Date) {
          this.dateTimestamps.add(val.valueOf());
        } else {
          this.domain.add(val);
        }
      }
    } else {
      for (const ts of other.dateTimestamps) {
        this.dateTimestamps.add(ts);
      }
      for (const val of other.domain) {
        this.domain.add(val);
      }
    }
  }
  /** Converts from sorted array mode to Set mode (one-way transition) */
  convertToSetMode() {
    if (!this.isSortedUnique)
      return;
    if (this.sortedValues) {
      for (const val of this.sortedValues) {
        if (val instanceof Date) {
          this.dateTimestamps.add(val.valueOf());
        } else {
          this.domain.add(val);
        }
      }
      this.sortedValues = null;
    }
    this.isSortedUnique = false;
    this.sortOrder = void 0;
  }
};
var ContinuousDomain = class _ContinuousDomain {
  constructor() {
    this.domain = [Infinity, -Infinity];
  }
  static is(value) {
    return value instanceof _ContinuousDomain;
  }
  static extendDomain(values, domain = [Infinity, -Infinity]) {
    for (const value of values) {
      if (typeof value !== "number") {
        continue;
      }
      if (domain[0] > value) {
        domain[0] = value;
      }
      if (domain[1] < value) {
        domain[1] = value;
      }
    }
    return domain;
  }
  extend(value) {
    if (typeof value !== "number" && !(value instanceof Date)) {
      return;
    }
    if (this.domain[0] > value) {
      this.domain[0] = value;
    }
    if (this.domain[1] < value) {
      this.domain[1] = value;
    }
  }
  getDomain() {
    return [...this.domain];
  }
};
var BandedDomain = class extends BandedStructure {
  constructor(domainFactory, config = {}, isDiscrete = false) {
    super(config);
    this.fullDomainCache = null;
    // Sort order metadata for optimization (set from KEY_SORT_ORDERS)
    this.sortOrder = void 0;
    this.isUnique = false;
    this.domainFactory = domainFactory;
    this.isDiscrete = isDiscrete;
  }
  /**
   * Set sort order metadata from KEY_SORT_ORDERS.
   * When data is sorted and unique, enables fast array concatenation in getDomain().
   */
  setSortOrderMetadata(sortOrder, isUnique) {
    this.sortOrder = sortOrder;
    this.isUnique = isUnique;
  }
  /**
   * Creates a new domain band with its own sub-domain instance.
   * Configures sub-domain for sorted mode if applicable.
   */
  createBand(startIndex, endIndex) {
    const subDomain = this.domainFactory();
    if (this.isDiscrete && this.sortOrder !== void 0 && this.isUnique) {
      if (DiscreteDomain.is(subDomain)) {
        subDomain.setSortedUniqueMode(this.sortOrder, this.isUnique);
      }
    }
    return {
      startIndex,
      endIndex,
      subDomain,
      isDirty: true
    };
  }
  /**
   * Initializes bands and clears the full domain cache.
   */
  initializeBands(dataSize) {
    super.initializeBands(dataSize);
    this.fullDomainCache = null;
  }
  /**
   * Handles insertion and clears the full domain cache.
   */
  handleInsertion(insertIndex, insertCount) {
    super.handleInsertion(insertIndex, insertCount);
    this.fullDomainCache = null;
  }
  /**
   * Handles removal and clears the full domain cache.
   */
  handleRemoval(removeIndex, removeCount) {
    super.handleRemoval(removeIndex, removeCount);
    this.fullDomainCache = null;
  }
  /**
   * Split an oversized band into two smaller bands.
   * Override to handle band splitting for large datasets where banding is beneficial.
   */
  splitBand(bandIndex, idealSize) {
    if (this.bands.length > 1) {
      super.splitBand(bandIndex, idealSize);
    }
  }
  /**
   * Marks bands as dirty that need rescanning.
   */
  markBandsDirty(startIndex, endIndex) {
    this.markRangeDirty(startIndex, endIndex);
    this.fullDomainCache = null;
  }
  /**
   * Marks all bands as dirty, forcing a full rescan.
   */
  markAllBandsDirty() {
    for (const band of this.bands) {
      band.isDirty = true;
    }
    this.fullDomainCache = null;
  }
  /**
   * Extends the domain with values from specified bands.
   * This is called after dirty bands have been rescanned.
   */
  extendBandsFromData(data, invalidData) {
    const dataLength = data.length;
    for (const band of this.bands) {
      if (!band.isDirty)
        continue;
      const subDomain = this.domainFactory();
      if (this.isDiscrete && this.sortOrder !== void 0 && this.isUnique) {
        if (DiscreteDomain.is(subDomain)) {
          subDomain.setSortedUniqueMode(this.sortOrder, this.isUnique);
        }
      }
      band.subDomain = subDomain;
      const { startIndex, endIndex } = band;
      for (let i = startIndex; i < endIndex && i < dataLength; i++) {
        if (invalidData?.[i])
          continue;
        band.subDomain.extend(data[i]);
      }
      band.isDirty = false;
    }
    this.fullDomainCache = null;
  }
  /**
   * Gets the bands that need rescanning.
   */
  getDirtyBands() {
    return this.bands.filter((band) => band.isDirty);
  }
  /**
   * Standard IDataDomain interface - extends domain with a single value.
   * Note: This is less efficient than batch operations with bands.
   */
  extend(_value) {
    this.markAllBandsDirty();
    this.fullDomainCache = null;
  }
  /**
   * Check if all sub-domains support fast sorted concatenation.
   */
  canUseSortedConcatenation() {
    if (!this.sortOrder || !this.isUnique || !this.isDiscrete)
      return false;
    for (const band of this.bands) {
      if (!DiscreteDomain.is(band.subDomain))
        return false;
      if (!band.subDomain.isSortedUniqueMode())
        return false;
      if (band.subDomain.getSortOrder() !== this.sortOrder)
        return false;
    }
    return true;
  }
  /**
   * Concatenate sorted domains efficiently.
   * Only valid when canUseSortedConcatenation() returns true.
   */
  concatenateSortedDomains() {
    const combined = new DiscreteDomain();
    combined.setSortedUniqueMode(this.sortOrder, this.isUnique);
    for (const band of this.bands) {
      if (DiscreteDomain.is(band.subDomain)) {
        combined.mergeFrom(band.subDomain);
      }
    }
    return combined.getDomain();
  }
  /**
   * Deduplicate nulls and Invalid Dates in a domain result array.
   * These represent invalid data and may appear from multiple bands.
   */
  deduplicateNulls(result) {
    let hasSeenInvalid = false;
    return result.filter((v) => {
      if (v == null) {
        if (hasSeenInvalid)
          return false;
        hasSeenInvalid = true;
        return true;
      }
      if (v instanceof Date && Number.isNaN(v.valueOf())) {
        if (hasSeenInvalid)
          return false;
        hasSeenInvalid = true;
      }
      return true;
    });
  }
  /**
   * Combines all band sub-domains to get the overall domain.
   */
  getDomain() {
    if (this.fullDomainCache !== null) {
      return this.fullDomainCache;
    }
    if (this.bands.length === 0) {
      this.fullDomainCache = [];
      return [];
    }
    if (this.bands.length === 1) {
      const result = this.bands[0].subDomain.getDomain();
      this.fullDomainCache = this.isDiscrete ? this.deduplicateNulls(result) : result;
      return this.fullDomainCache;
    }
    if (this.isDiscrete) {
      const firstBand = this.bands[0].subDomain;
      if (DiscreteDomain.is(firstBand)) {
        if (this.canUseSortedConcatenation()) {
          this.fullDomainCache = this.deduplicateNulls(this.concatenateSortedDomains());
        } else {
          const combined = new DiscreteDomain();
          for (const band of this.bands) {
            if (DiscreteDomain.is(band.subDomain)) {
              combined.mergeFrom(band.subDomain);
            }
          }
          this.fullDomainCache = this.deduplicateNulls(combined.getDomain());
        }
      } else {
        const combined = /* @__PURE__ */ new Set();
        for (const band of this.bands) {
          for (const value of band.subDomain.getDomain()) {
            combined.add(value);
          }
        }
        this.fullDomainCache = Array.from(combined);
      }
    } else {
      let min;
      let max;
      for (const band of this.bands) {
        const bandDomain = band.subDomain.getDomain();
        if (bandDomain.length === 2) {
          const [bandMin, bandMax] = bandDomain;
          if (min === void 0 || bandMin != null && min != null && bandMin < min) {
            min = bandMin;
          }
          if (max === void 0 || bandMax != null && max != null && bandMax > max) {
            max = bandMax;
          }
        }
      }
      if (min !== void 0 && max !== void 0) {
        this.fullDomainCache = [min, max];
      } else {
        this.fullDomainCache = [];
      }
    }
    return this.fullDomainCache;
  }
  /**
   * Returns statistics about the banded domain for debugging.
   */
  getStats() {
    const dirtyCount = this.bands.filter((b) => b.isDirty).length;
    const totalSize = this.bands.reduce((sum, b) => sum + (b.endIndex - b.startIndex), 0);
    return {
      bandCount: this.bands.length,
      dirtyBandCount: dirtyCount,
      averageBandSize: this.bands.length > 0 ? totalSize / this.bands.length : 0,
      dataSize: this.dataSize
    };
  }
};

// packages/ag-charts-community/src/chart/data/aggregateFunctions.ts
function sumValues(values, accumulator = [0, 0]) {
  for (const value of values) {
    if (typeof value !== "number") {
      continue;
    }
    if (value < 0) {
      accumulator[0] += value;
    }
    if (value > 0) {
      accumulator[1] += value;
    }
  }
  return accumulator;
}
function groupSum(id, opts) {
  const visible = opts?.visible ?? true;
  return {
    id,
    type: "aggregate",
    matchGroupIds: opts?.matchGroupId ? [opts?.matchGroupId] : void 0,
    aggregateFunction: (values) => sumValues(values),
    groupAggregateFunction: (next, acc = [0, 0]) => {
      if (visible) {
        acc[0] += next?.[0] ?? 0;
        acc[1] += next?.[1] ?? 0;
      }
      return acc;
    }
  };
}
function range2(id, matchGroupId) {
  const result = {
    id,
    matchGroupIds: [matchGroupId],
    type: "aggregate",
    aggregateFunction: (values) => ContinuousDomain.extendDomain(values)
  };
  return result;
}
function groupCount(id, opts) {
  const visible = opts?.visible ?? true;
  return {
    id,
    type: "aggregate",
    aggregateFunction: () => [0, 1],
    groupAggregateFunction: (next, acc = [0, 0]) => {
      if (visible) {
        acc[0] += next?.[0] ?? 0;
        acc[1] += next?.[1] ?? 0;
      }
      return acc;
    }
  };
}
function groupAverage(id, opts) {
  const visible = opts?.visible ?? true;
  const def = {
    id,
    matchGroupIds: opts?.matchGroupId ? [opts?.matchGroupId] : void 0,
    type: "aggregate",
    aggregateFunction: (values) => sumValues(values),
    groupAggregateFunction: (next, acc = [0, 0, -1]) => {
      if (visible) {
        acc[0] += next?.[0] ?? 0;
        acc[2]++;
        acc[1] += next?.[1] ?? 0;
      }
      return acc;
    },
    finalFunction: (acc = [0, 0, 0]) => {
      const result = acc[0] + acc[1];
      if (result >= 0) {
        return [0, result / acc[2]];
      }
      return [result / acc[2], 0];
    }
  };
  return def;
}
function area(id, aggFn, matchGroupId) {
  const result = {
    id,
    matchGroupIds: matchGroupId ? [matchGroupId] : void 0,
    type: "aggregate",
    aggregateFunction: (values, keyRange = []) => {
      const keyWidth = keyRange[1] - keyRange[0];
      return aggFn.aggregateFunction(values).map((v) => v / keyWidth);
    }
  };
  if (aggFn.groupAggregateFunction) {
    result.groupAggregateFunction = aggFn.groupAggregateFunction;
  }
  return result;
}
function accumulatedValue(onlyPositive) {
  return () => {
    let value = 0;
    return (datum) => {
      if (!isFiniteNumber(datum)) {
        return datum;
      }
      value += onlyPositive ? Math.max(0, datum) : datum;
      return value;
    };
  };
}
function trailingAccumulatedValue() {
  return () => {
    let value = 0;
    return (datum) => {
      if (!isFiniteNumber(datum)) {
        return datum;
      }
      const trailingValue = value;
      value += datum;
      return trailingValue;
    };
  };
}

// packages/ag-charts-community/src/chart/data/data-model/utils/helpers.ts
var NULL_KEY_STRING = "\0__AG_NULL__\0";
var UNDEFINED_KEY_STRING = "\0__AG_UNDEFINED__\0";
function keyToString(key) {
  if (key === null)
    return NULL_KEY_STRING;
  if (key === void 0)
    return UNDEFINED_KEY_STRING;
  if (Array.isArray(key)) {
    return "[" + key.map(keyToString).join(",") + "]";
  }
  return isObject(key) ? JSON.stringify(key) : String(key);
}
function toKeyString(keys) {
  return keys.map(keyToString).join("-");
}
function fixNumericExtent(extent2) {
  const numberExtent = extent2?.map(Number);
  return numberExtent?.every(Number.isFinite) ? numberExtent : [];
}
function getMissCount(scopeProvider, missMap) {
  return missMap?.get(scopeProvider.id) ?? 0;
}
function isScoped(obj) {
  return "scopes" in obj && Array.isArray(obj.scopes);
}
function createArray(length2, value) {
  const out = [];
  for (let i = 0; i < length2; i += 1) {
    out[i] = value;
  }
  return out;
}
function uniqueChangeDescriptions(scopeChanges) {
  const deduped = /* @__PURE__ */ new Set();
  for (const changeDesc of scopeChanges.values()) {
    if (changeDesc) {
      deduped.add(changeDesc);
    }
  }
  return deduped;
}
function datumKeys(keys, datumIndex, allowNull = false) {
  const out = [];
  for (const k of keys) {
    const key = k?.[datumIndex];
    if (key == null && !allowNull)
      return;
    out.push(key);
  }
  return out;
}
function getPathComponents(path) {
  const components = [];
  let matchIndex = 0;
  let matchGroup;
  const regExp = /((?:(?:^|\.)\s*\w+|\[\s*(?:'(?:[^']|(?<!\\)\\')*'|"(?:[^"]|(?<!\\)\\")*"|-?\d+)\s*\])\s*)/g;
  while (matchGroup = regExp.exec(path)) {
    if (matchGroup.index !== matchIndex) {
      return;
    }
    matchIndex = matchGroup.index + matchGroup[0].length;
    const match = matchGroup[1].trim();
    if (match.startsWith(".")) {
      components.push(match.slice(1).trim());
    } else if (match.startsWith("[")) {
      const accessor = match.slice(1, -1).trim();
      if (accessor.startsWith(`'`)) {
        components.push(accessor.slice(1, -1).replaceAll(/(?<!\\)\\'/g, `'`));
      } else if (accessor.startsWith(`"`)) {
        components.push(accessor.slice(1, -1).replaceAll(/(?<!\\)\\"/g, `"`));
      } else {
        components.push(accessor);
      }
    } else {
      components.push(match);
    }
  }
  if (matchIndex !== path.length)
    return;
  return components;
}
function createPathAccessor(components) {
  return (datum) => {
    let current = datum;
    for (const component of components) {
      current = current[component];
    }
    return current;
  };
}

// packages/ag-charts-community/src/chart/data/data-model/aggregation/aggregator.ts
var Aggregator = class {
  constructor(ctx, scopeCacheManager, resolvers) {
    this.ctx = ctx;
    this.scopeCacheManager = scopeCacheManager;
    this.resolvers = resolvers;
  }
  /**
   * Aggregates data for ungrouped datasets.
   * Each datum gets its own aggregation result.
   */
  aggregateUngroupedData(processedData) {
    const domainAggValues = this.ctx.aggregates.map(() => [Infinity, -Infinity]);
    processedData.domain.aggValues = domainAggValues;
    const { columns, dataSources } = processedData;
    const onlyScope = first(dataSources.keys());
    const keys = processedData.keys.map((k) => k.get(onlyScope));
    const rawData = dataSources.get(onlyScope)?.data ?? [];
    const allowNull = this.ctx.keys.some((keyDef) => keyDef.allowNullKey === true);
    processedData.aggregation = rawData?.map((_, datumIndex) => {
      const aggregation = [];
      for (const [index, def] of this.ctx.aggregates.entries()) {
        const indices = this.valueGroupIdxLookup(def);
        let groupAggValues = def.groupAggregateFunction?.() ?? [Infinity, -Infinity];
        const valuesToAgg = indices.map((columnIndex) => columns[columnIndex][datumIndex]);
        const k = datumKeys(keys, datumIndex, allowNull);
        const valuesAgg = k == null ? void 0 : def.aggregateFunction(valuesToAgg, k);
        if (valuesAgg) {
          groupAggValues = def.groupAggregateFunction?.(valuesAgg, groupAggValues) ?? ContinuousDomain.extendDomain(valuesAgg, groupAggValues);
        }
        const finalValues = def.finalFunction?.(groupAggValues) ?? groupAggValues;
        aggregation[index] = finalValues;
        ContinuousDomain.extendDomain(finalValues, domainAggValues[index]);
      }
      return aggregation;
    });
  }
  /**
   * Aggregates data for grouped datasets.
   * Multiple datums in a group share aggregation results.
   */
  aggregateGroupedData(processedData) {
    const domainAggValues = this.ctx.aggregates.map(() => [Infinity, -Infinity]);
    processedData.domain.aggValues = domainAggValues;
    const { columns } = processedData;
    for (const [index, def] of this.ctx.aggregates.entries()) {
      const indices = this.valueGroupIdxLookup(def);
      for (let groupIndex = 0; groupIndex < processedData.groups.length; groupIndex++) {
        const group = processedData.groups[groupIndex];
        group.aggregation ?? (group.aggregation = []);
        const groupKeys = group.keys;
        let groupAggValues = def.groupAggregateFunction?.() ?? [Infinity, -Infinity];
        const maxDatumIndex = Math.max(
          ...indices.map((columnIndex) => group.datumIndices[columnIndex]?.length ?? 0)
        );
        for (let datumIndex = 0; datumIndex < maxDatumIndex; datumIndex++) {
          const valuesToAgg = indices.map((columnIndex) => {
            const relativeDatumIndex = group.datumIndices[columnIndex]?.[datumIndex];
            if (relativeDatumIndex == null) {
              return void 0;
            }
            const absoluteDatumIndex = this.resolvers.resolveAbsoluteIndex(groupIndex, relativeDatumIndex);
            return columns[columnIndex][absoluteDatumIndex];
          });
          const valuesAgg = def.aggregateFunction(valuesToAgg, groupKeys);
          if (valuesAgg) {
            groupAggValues = def.groupAggregateFunction?.(valuesAgg, groupAggValues) ?? ContinuousDomain.extendDomain(valuesAgg, groupAggValues);
          }
        }
        const finalValues = def.finalFunction?.(groupAggValues) ?? groupAggValues;
        group.aggregation[index] = finalValues;
        ContinuousDomain.extendDomain(finalValues, domainAggValues[index]);
      }
    }
  }
  /**
   * Post-processes groups after grouping is complete.
   * Applies group value processors to adjust group values and recompute domains.
   */
  postProcessGroups(processedData) {
    const { groupProcessors } = this.ctx;
    const { columnScopes, columns, invalidData } = processedData;
    for (const processor of groupProcessors) {
      const valueIndexes = this.valueGroupIdxLookup(processor);
      const adjustFn = processor.adjust()();
      for (let groupIndex = 0; groupIndex < processedData.groups.length; groupIndex++) {
        const dataGroup = processedData.groups[groupIndex];
        adjustFn(columns, valueIndexes, dataGroup, groupIndex);
      }
      for (const valueIndex of valueIndexes) {
        const valueDef = this.ctx.values[valueIndex];
        const isDiscrete = valueDef.valueType === "category";
        const column = columns[valueIndex];
        const columnScope = first(columnScopes[valueIndex]);
        const invalidDatums = invalidData?.get(columnScope);
        const domain = isDiscrete ? new DiscreteDomain() : new ContinuousDomain();
        for (let datumIndex = 0; datumIndex < column.length; datumIndex += 1) {
          if (invalidDatums?.[datumIndex] === true)
            continue;
          domain.extend(column[datumIndex]);
        }
        processedData.domain.values[valueIndex] = domain.getDomain();
      }
    }
  }
  valueGroupIdxLookup(selector) {
    return this.scopeCacheManager.valueGroupIdxLookup(selector);
  }
};

// packages/ag-charts-community/src/chart/data/data-model/domain/domainInitializer.ts
var DomainInitializer = class {
  constructor(ctx) {
    this.ctx = ctx;
  }
  /**
   * Sets up the appropriate domain type for a property definition.
   * Returns a BandedDomain wrapping DiscreteDomain for category values,
   * or a BandedDomain wrapping ContinuousDomain for continuous values.
   * Falls back to non-banded domains when banding is disabled.
   *
   * @param sortOrderEntry Optional sort order metadata from KEY_SORT_ORDERS.
   * When data is sorted and unique, enables fast array concatenation optimization.
   */
  setupDomainForDefinition(def, bandedDomains, sortOrderEntry) {
    const isDiscrete = def.valueType === "category";
    let domain = bandedDomains.get(def);
    if (!domain && this.ctx.bandingConfig?.enableBanding !== false) {
      domain = new BandedDomain(
        isDiscrete ? () => new DiscreteDomain() : () => new ContinuousDomain(),
        this.ctx.bandingConfig,
        isDiscrete
      );
      bandedDomains.set(def, domain);
    }
    if (domain && isDiscrete) {
      domain.setSortOrderMetadata(
        sortOrderEntry?.sortOrder,
        sortOrderEntry?.isUnique ?? false
      );
    }
    if (domain) {
      return domain;
    }
    return isDiscrete ? new DiscreteDomain() : new ContinuousDomain();
  }
  /**
   * Extends a domain from data array, using banded optimization if available.
   * Note: For BandedDomain, bands should already be initialized before calling this method.
   */
  extendDomainFromData(domain, data, invalidData) {
    if (domain instanceof BandedDomain) {
      domain.extendBandsFromData(data, invalidData);
    } else {
      for (let i = 0; i < data.length; i++) {
        if (invalidData?.[i] === true)
          continue;
        domain.extend(data[i]);
      }
    }
  }
  /**
   * Initializes a banded domain if needed based on data size and state.
   * This is a memory optimization that divides large datasets into bands.
   */
  initializeBandedDomain(domain, dataSize, propertyName) {
    if (!(domain instanceof BandedDomain))
      return;
    const stats = domain.getStats();
    const shouldReinit = stats.bandCount === 0 || stats.dataSize !== dataSize;
    if (this.ctx.debug.check() && shouldReinit && propertyName) {
      this.ctx.debug(
        `Reinitializing bands for ${propertyName}: bandCount=${stats.bandCount}, dataSize=${stats.dataSize}, dataLength=${dataSize}`
      );
    }
    if (shouldReinit) {
      domain.initializeBands(dataSize);
    }
  }
};

// packages/ag-charts-community/src/chart/data/dataModelTypes.ts
var KEY_SORT_ORDERS = Symbol("key-sort-orders");
var COLUMN_SORT_ORDERS = Symbol("column-sort-orders");
var DOMAIN_RANGES = Symbol("domain-ranges");
var DOMAIN_BANDS = Symbol("domain-bands");
var REDUCER_BANDS = Symbol("reducer-bands");
var SHARED_ZERO_INDICES = Object.freeze([0]);

// packages/ag-charts-community/src/chart/data/data-model/domain/processValueFactory.ts
function trackMissingValue(missing, valueScopes) {
  if (typeof valueScopes === "string") {
    missing.set(valueScopes, (missing.get(valueScopes) ?? 0) + 1);
  } else {
    for (const scope of valueScopes) {
      missing.set(scope, (missing.get(scope) ?? 0) + 1);
    }
  }
}
function handleInvalidValue(meta, value) {
  meta.reusableResult.valid = false;
  if (meta.hasInvalidValue) {
    meta.reusableResult.value = meta.invalidValue;
    meta.domain.extend(meta.invalidValue);
    return;
  }
  if (meta.mode !== "integrated") {
    logger_exports.warnOnce(
      `invalid value of type [${typeof value}] for [${meta.def.scopes} / ${meta.def.id}] ignored:`,
      `[${value}]`
    );
  }
  meta.reusableResult.value = void 0;
}
function processValidationCheck(validation, valueInDatum, value, datum, idx, meta) {
  if (validation && valueInDatum && validation(value, datum, idx) === false) {
    meta.reusableResult.missing = false;
    handleInvalidValue(meta, value);
    return meta.reusableResult;
  }
  return null;
}
function handleMissingTracking(valueInDatum, hasMissingValue, missing, valueScopes, reusableResult) {
  reusableResult.missing = !valueInDatum;
  if (!valueInDatum && !hasMissingValue) {
    trackMissingValue(missing, valueScopes);
  }
}
function setValidResult(value, reusableResult, domain) {
  reusableResult.valid = true;
  reusableResult.value = value;
  domain.extend(value);
  return reusableResult;
}
var ProcessValueFactory = class {
  constructor(ctx) {
    this.ctx = ctx;
  }
  createProcessValueFn(def, accessor, domain, reusableResult, processorFns, domainMode) {
    const context = {
      def,
      accessor,
      domain,
      reusableResult,
      processorFns,
      mode: this.ctx.mode
    };
    const specializedFn = domainMode === "extend" ? this.createSpecializedProcessValue(context, def.validation) : null;
    return specializedFn ?? this.createGenericProcessValue(context, domainMode);
  }
  createSpecializedProcessValue(context, validation) {
    if (context.def.forceValue != null) {
      return this.createSpecializedProcessValueForceValue(context);
    }
    if (context.def.processor) {
      return this.createSpecializedProcessValueProcessor(context, validation);
    }
    if (validation) {
      return context.def.type === "key" ? this.createSpecializedProcessValueKeyValidation(context, validation) : this.createSpecializedProcessValueValueValidation(context, validation);
    }
    return null;
  }
  createValidationMeta(context) {
    const { def, domain, reusableResult, mode } = context;
    return {
      reusableResult,
      hasInvalidValue: "invalidValue" in def,
      invalidValue: def.invalidValue,
      domain,
      def,
      mode
    };
  }
  /**
   * Creates a specialized processValue function optimized for key properties with validation.
   * Eliminates all branching for the most common key property case (~30% of calls).
   */
  createSpecializedProcessValueKeyValidation(context, validation) {
    const { def, accessor, domain, reusableResult } = context;
    const property = def.property;
    const hasMissingValue = "missingValue" in def;
    const missingValue = def.missingValue;
    const missing = def.missing;
    const allowNullKey = def.allowNullKey ?? false;
    const validationMeta = this.createValidationMeta(context);
    if (accessor) {
      const accessorFn = accessor;
      return function processValueKeyValidationAccessor(datum, idx, valueScopes) {
        let value;
        try {
          value = accessorFn(datum);
        } catch {
        }
        const valueInDatum = value != null || allowNullKey && value == null;
        const nullInvalid = !allowNullKey && value == null;
        if (!valueInDatum || nullInvalid || validation(value, datum, idx) === false) {
          reusableResult.missing = !valueInDatum;
          if (!valueInDatum && !hasMissingValue) {
            trackMissingValue(missing, valueScopes);
          }
          handleInvalidValue(validationMeta, value);
          return reusableResult;
        }
        reusableResult.missing = false;
        reusableResult.valid = true;
        reusableResult.value = value;
        domain.extend(value);
        return reusableResult;
      };
    }
    return function processValueKeyValidationDirect(datum, idx, valueScopes) {
      const valueInDatum = property in datum;
      const value = valueInDatum ? datum[property] : missingValue;
      const nullInvalid = !allowNullKey && value == null;
      if (!valueInDatum || nullInvalid || validation(value, datum, idx) === false) {
        reusableResult.missing = !valueInDatum;
        if (!valueInDatum && !hasMissingValue) {
          trackMissingValue(missing, valueScopes);
        }
        handleInvalidValue(validationMeta, value);
        return reusableResult;
      }
      reusableResult.missing = false;
      reusableResult.valid = true;
      reusableResult.value = value;
      domain.extend(value);
      return reusableResult;
    };
  }
  /**
   * Creates a specialized processValue function optimized for value properties with validation.
   * Eliminates branching for the most common value property case (~50% of calls).
   */
  createSpecializedProcessValueValueValidation(context, validation) {
    const { def, accessor, domain, reusableResult } = context;
    const property = def.property;
    const hasMissingValue = "missingValue" in def;
    const missingValue = def.missingValue;
    const missing = def.missing;
    const validationMeta = this.createValidationMeta(context);
    if (accessor) {
      const accessorFn = accessor;
      return function processValueValueValidationAccessor(datum, idx, valueScopes) {
        let value;
        try {
          value = accessorFn(datum);
        } catch {
        }
        const valueInDatum = value != null;
        const validationFailed = processValidationCheck(
          validation,
          valueInDatum,
          value,
          datum,
          idx,
          validationMeta
        );
        if (validationFailed !== null)
          return validationFailed;
        handleMissingTracking(valueInDatum, hasMissingValue, missing, valueScopes, reusableResult);
        return setValidResult(value, reusableResult, domain);
      };
    }
    return function processValueValueValidationDirect(datum, idx, valueScopes) {
      const valueInDatum = property in datum;
      const value = valueInDatum ? datum[property] : missingValue;
      const validationFailed = processValidationCheck(
        validation,
        valueInDatum,
        value,
        datum,
        idx,
        validationMeta
      );
      if (validationFailed !== null)
        return validationFailed;
      handleMissingTracking(valueInDatum, hasMissingValue, missing, valueScopes, reusableResult);
      return setValidResult(value, reusableResult, domain);
    };
  }
  /**
   * Creates a specialized processValue function for properties with forceValue.
   * Optimized for invisible series (~5-10% of calls).
   */
  createSpecializedProcessValueForceValue(context) {
    const { def, accessor, domain, reusableResult } = context;
    const property = def.property;
    const forceValue = def.forceValue;
    if (accessor) {
      const accessorFn = accessor;
      return function processValueForceValueAccessor(datum, _idx, _valueScopes) {
        let value;
        try {
          value = accessorFn(datum);
        } catch {
        }
        const valueInDatum = value != null;
        const valueNegative = valueInDatum && isNegative(value);
        const forcedValue = valueNegative ? -1 * forceValue : forceValue;
        reusableResult.missing = false;
        reusableResult.valid = true;
        reusableResult.value = forcedValue;
        domain.extend(forcedValue);
        return reusableResult;
      };
    }
    return function processValueForceValueDirect(datum, _idx, _valueScopes) {
      const valueInDatum = property in datum;
      const value = valueInDatum ? datum[property] : void 0;
      const valueNegative = valueInDatum && isNegative(value);
      const forcedValue = valueNegative ? -1 * forceValue : forceValue;
      reusableResult.missing = false;
      reusableResult.valid = true;
      reusableResult.value = forcedValue;
      domain.extend(forcedValue);
      return reusableResult;
    };
  }
  /**
   * Creates a specialized processValue function for properties with processors.
   * Optimized for data transformations (~5-10% of calls).
   */
  createSpecializedProcessValueProcessor(context, validation) {
    const { def, accessor, domain, reusableResult, processorFns } = context;
    const property = def.property;
    const hasMissingValue = "missingValue" in def;
    const missingValue = def.missingValue;
    const missing = def.missing;
    const processor = def.processor;
    const validationMeta = this.createValidationMeta(context);
    if (accessor) {
      const accessorFn = accessor;
      return function processValueProcessorAccessor(datum, idx, valueScopes) {
        let value;
        try {
          value = accessorFn(datum);
        } catch {
        }
        const valueInDatum = value != null;
        const validationFailed = processValidationCheck(
          validation,
          valueInDatum,
          value,
          datum,
          idx,
          validationMeta
        );
        if (validationFailed !== null)
          return validationFailed;
        handleMissingTracking(valueInDatum, hasMissingValue, missing, valueScopes, reusableResult);
        let processorFn = processorFns.get(def);
        if (processorFn == null) {
          processorFn = processor();
          processorFns.set(def, processorFn);
        }
        value = processorFn(value, idx);
        return setValidResult(value, reusableResult, domain);
      };
    }
    return function processValueProcessorDirect(datum, idx, valueScopes) {
      const valueInDatum = property in datum;
      let value = valueInDatum ? datum[property] : missingValue;
      const validationFailed = processValidationCheck(
        validation,
        valueInDatum,
        value,
        datum,
        idx,
        validationMeta
      );
      if (validationFailed !== null)
        return validationFailed;
      handleMissingTracking(valueInDatum, hasMissingValue, missing, valueScopes, reusableResult);
      let processorFn = processorFns.get(def);
      if (processorFn == null) {
        processorFn = processor();
        processorFns.set(def, processorFn);
      }
      value = processorFn(value, idx);
      return setValidResult(value, reusableResult, domain);
    };
  }
  /**
   * Creates the generic fallback processValue implementation used for edge cases
   * and for skip mode (no domain extension). Generates a per-definition function
   * so callers can resolve it once and reuse it without additional branching.
   */
  createGenericProcessValue(context, domainMode) {
    const { def, accessor, domain, processorFns } = context;
    const property = def.property;
    const hasMissingValue = "missingValue" in def;
    const missingValue = def.missingValue;
    const missing = def.missing;
    const shouldExtendDomain = domainMode === "extend";
    const reusableResult = context.reusableResult;
    const validationMeta = this.createValidationMeta(context);
    return function processValueGeneric(datum, idx, valueScopes) {
      let value;
      let valueInDatum;
      if (accessor) {
        try {
          value = accessor(datum);
        } catch {
        }
        valueInDatum = value != null;
      } else {
        valueInDatum = property in datum;
        value = valueInDatum ? datum[property] : missingValue;
      }
      if (def.forceValue != null) {
        const valueNegative = valueInDatum && isNegative(value);
        value = valueNegative ? -1 * def.forceValue : def.forceValue;
        valueInDatum = true;
      }
      handleMissingTracking(valueInDatum, hasMissingValue, missing, valueScopes, reusableResult);
      const allowNullKey = def.allowNullKey ?? false;
      const isKeyWithNullValue = def.type === "key" && value == null && !allowNullKey;
      if (isKeyWithNullValue) {
        handleInvalidValue(validationMeta, value);
        return reusableResult;
      }
      const validationFailed = processValidationCheck(
        def.validation,
        valueInDatum,
        value,
        datum,
        idx,
        validationMeta
      );
      if (validationFailed !== null)
        return validationFailed;
      reusableResult.valid = true;
      if (def.processor) {
        let processor = processorFns.get(def);
        if (processor == null) {
          processor = def.processor();
          processorFns.set(def, processor);
        }
        value = processor(value, idx);
      }
      if (shouldExtendDomain) {
        domain.extend(value);
      }
      reusableResult.value = value;
      return reusableResult;
    };
  }
};

// packages/ag-charts-community/src/chart/data/data-model/domain/domainManager.ts
function scopesOverlap(scopes1, scopes2) {
  if (!scopes1 || !scopes2 || scopes1.length === 0 || scopes2.length === 0) {
    return true;
  }
  return scopes1.some((s) => scopes2.includes(s));
}
function findMatchingKeyDef(valueDef, keyDefs) {
  if (valueDef.valueType !== "category")
    return void 0;
  for (const keyDef of keyDefs) {
    if (keyDef.property !== valueDef.property)
      continue;
    if (keyDef.valueType !== valueDef.valueType)
      continue;
    if (!scopesOverlap(keyDef.scopes, valueDef.scopes))
      continue;
    if (keyDef.validation !== valueDef.validation)
      continue;
    return keyDef;
  }
  return void 0;
}
var DomainManager = class {
  constructor(ctx, initializer, scopeCacheManager) {
    this.ctx = ctx;
    this.initializer = initializer;
    this.scopeCacheManager = scopeCacheManager;
    this.processValueFactory = new ProcessValueFactory(ctx);
  }
  /**
   * Recomputes all domains from processed data.
   * Uses BandedDomain optimization for continuous domains to avoid full rescans.
   * Shares domains between keys and values when they reference the same property.
   */
  recomputeDomains(processedData) {
    const startTime = this.ctx.debug.check() ? performance.now() : 0;
    const bandedDomains = processedData[DOMAIN_BANDS];
    let bandStats;
    const keySortOrders = processedData[KEY_SORT_ORDERS];
    const keyDomains = this.setupDefinitionDomains(this.ctx.keys, bandedDomains, keySortOrders);
    const valueToKeyDef = /* @__PURE__ */ new Map();
    for (const valueDef of this.ctx.values) {
      const matchingKeyDef = findMatchingKeyDef(valueDef, this.ctx.keys);
      if (matchingKeyDef) {
        valueToKeyDef.set(valueDef, matchingKeyDef);
      }
    }
    const valueDomains = this.setupValueDomainsWithSharing(
      this.ctx.values,
      bandedDomains,
      keyDomains,
      valueToKeyDef
    );
    const sharedDomains = /* @__PURE__ */ new Set();
    for (const [, keyDef] of valueToKeyDef) {
      const sharedDomain = keyDomains.get(keyDef);
      if (sharedDomain) {
        sharedDomains.add(sharedDomain);
      }
    }
    this.initializeDomainBands(
      this.ctx.keys,
      keyDomains,
      (defIndex) => {
        const keysMap = processedData.keys[defIndex];
        return Math.max(...Array.from(keysMap.values()).map((keys) => keys.length));
      },
      (def) => String(def.property)
    );
    this.initializeDomainBands(
      this.ctx.values,
      valueDomains,
      (defIndex) => processedData.columns[defIndex].length,
      (def) => String(def.property)
    );
    const preScanDomainStats = /* @__PURE__ */ new Map();
    if (bandedDomains.size > 0) {
      bandStats = {
        totalBands: 0,
        dirtyBands: 0,
        totalData: 0
      };
      for (const domain of bandedDomains.values()) {
        if (domain instanceof BandedDomain) {
          const stats = domain.getStats();
          preScanDomainStats.set(domain, stats);
          bandStats.totalBands += stats.bandCount;
          bandStats.dirtyBands += stats.dirtyBandCount;
          bandStats.totalData = Math.max(bandStats.totalData, stats.dataSize);
        }
      }
    }
    this.extendDomainsFromData(
      this.ctx.keys,
      keyDomains,
      (defIndex, scope) => processedData.keys[defIndex]?.get(scope),
      (def) => def.scopes ?? [],
      (scope) => processedData.invalidKeys?.get(scope)
    );
    this.extendDomainsFromData(
      this.ctx.values,
      valueDomains,
      (defIndex, _scope) => processedData.columns[defIndex],
      (def) => [first(def.scopes)],
      (scope) => processedData.invalidKeys?.get(scope),
      sharedDomains
    );
    processedData.domain.keys = this.ctx.keys.map(function mapDomainKeys(keyDef) {
      const domain = keyDomains.get(keyDef);
      const result = domain.getDomain();
      if (ContinuousDomain.is(domain) && result[0] > result[1]) {
        return [];
      }
      return result;
    });
    processedData.domain.values = this.ctx.values.map(function mapDomainValues(valueDef) {
      const domain = valueDomains.get(valueDef);
      const result = domain.getDomain();
      if (ContinuousDomain.is(domain) && result[0] > result[1]) {
        return [];
      }
      return result;
    });
    if (processedData.type === "grouped") {
      processedData.domain.groups = processedData.groups.map((group) => group.keys);
    }
    this.collectDomainBandingMetadata(processedData, keyDomains, valueDomains, bandedDomains, preScanDomainStats);
    if (this.ctx.debug.check() && startTime > 0) {
      const endTime = performance.now();
      const duration = endTime - startTime;
      if (bandStats && bandStats.totalBands > 0) {
        const scanRatio = bandStats.dirtyBands / bandStats.totalBands;
        const dataScanned = Math.round(scanRatio * bandStats.totalData);
        this.ctx.debug(
          `recomputeDomains with banding: ${duration.toFixed(2)}ms, bands: ${bandStats.dirtyBands}/${bandStats.totalBands} dirty, data scanned: ~${dataScanned}/${bandStats.totalData} (${(scanRatio * 100).toFixed(1)}%)`
        );
      } else {
        this.ctx.debug(`recomputeDomains: ${duration.toFixed(2)}ms (no banding)`);
      }
    }
  }
  /**
   * Creates domain instances for the given definitions, reusing banded domains when available.
   * For key definitions, passes KEY_SORT_ORDERS metadata to enable fast array concatenation.
   */
  setupDefinitionDomains(defs, bandedDomains, keySortOrders) {
    const domains = /* @__PURE__ */ new Map();
    for (const [defIndex, def] of defs.entries()) {
      const sortOrderEntry = keySortOrders?.get(defIndex);
      domains.set(def, this.initializer.setupDomainForDefinition(def, bandedDomains, sortOrderEntry));
    }
    return domains;
  }
  /**
   * Initializes banded domains for each definition using the provided data length accessor.
   */
  initializeDomainBands(defs, domains, getDataLength, getPropertyName) {
    for (const [defIndex, def] of defs.entries()) {
      const domain = domains.get(def);
      if (!domain)
        continue;
      const dataLength = getDataLength(defIndex);
      this.initializer.initializeBandedDomain(domain, dataLength, getPropertyName(def));
    }
  }
  /**
   * Extends domains from data sources using a shared traversal.
   * @param skipDomains Optional set of domains to skip (already extended via shared key processing)
   */
  extendDomainsFromData(defs, domains, getData, getScopes, getInvalid, skipDomains) {
    for (const [defIndex, def] of defs.entries()) {
      const domain = domains.get(def);
      if (!domain)
        continue;
      if (skipDomains?.has(domain))
        continue;
      for (const scope of getScopes(def)) {
        if (!scope)
          continue;
        const data = getData(defIndex, scope);
        if (!data)
          continue;
        const invalid = getInvalid(scope);
        this.initializer.extendDomainFromData(domain, data, invalid);
      }
    }
  }
  /**
   * Sets up value domains, reusing key domains where properties match.
   * This avoids duplicate domain computation for properties that appear as both key and value.
   */
  setupValueDomainsWithSharing(defs, bandedDomains, keyDomains, valueToKeyDef) {
    const domains = /* @__PURE__ */ new Map();
    for (const def of defs) {
      const matchingKeyDef = valueToKeyDef.get(def);
      if (matchingKeyDef) {
        const keyDomain = keyDomains.get(matchingKeyDef);
        if (keyDomain) {
          domains.set(def, keyDomain);
          continue;
        }
      }
      domains.set(def, this.initializer.setupDomainForDefinition(def, bandedDomains));
    }
    return domains;
  }
  /**
   * Initializes domain processor for value processing during data transformation.
   * Returns domain maps and processing functions used during data extraction.
   * Uses specialized functions per property definition to eliminate branching in hot paths.
   * Shares domains between keys and values when they reference the same property.
   */
  initDataDomainProcessor(domainMode) {
    const { keys: keyDefs, values: valueDefs } = this.ctx;
    const scopes = /* @__PURE__ */ new Set();
    for (const valueDef of valueDefs) {
      if (!valueDef.scopes)
        continue;
      for (const scope of valueDef.scopes) {
        scopes.add(scope);
      }
    }
    const dataDomain = /* @__PURE__ */ new Map();
    const processorFns = /* @__PURE__ */ new Map();
    let allScopesHaveSameDefs = true;
    const initDataDomain = () => {
      for (const def of keyDefs) {
        if (def.valueType === "category") {
          dataDomain.set(def, new DiscreteDomain());
        } else {
          dataDomain.set(def, new ContinuousDomain());
        }
      }
      for (const def of valueDefs) {
        const matchingKeyDef = findMatchingKeyDef(def, keyDefs);
        if (matchingKeyDef) {
          const keyDomain = dataDomain.get(matchingKeyDef);
          if (keyDomain) {
            dataDomain.set(def, keyDomain);
            allScopesHaveSameDefs && (allScopesHaveSameDefs = (def.scopes?.length ?? 0) === scopes.size);
            continue;
          }
        }
        if (def.valueType === "category") {
          dataDomain.set(def, new DiscreteDomain());
        } else {
          dataDomain.set(def, new ContinuousDomain());
          allScopesHaveSameDefs && (allScopesHaveSameDefs = (def.scopes?.length ?? 0) === scopes.size);
        }
      }
    };
    initDataDomain();
    const accessors = this.scopeCacheManager.buildAccessors(iterate(keyDefs, valueDefs));
    const processValueFns = /* @__PURE__ */ new WeakMap();
    for (const def of iterate(keyDefs, valueDefs)) {
      const accessor = accessors.get(def.property);
      const domain = dataDomain.get(def);
      const reusableResult = {
        value: void 0,
        missing: false,
        valid: false
      };
      const processFn = this.processValueFactory.createProcessValueFn(
        def,
        accessor,
        domain,
        reusableResult,
        processorFns,
        domainMode
      );
      processValueFns.set(def, processFn);
    }
    function getProcessValue(def) {
      const processFn = processValueFns.get(def);
      if (!processFn) {
        throw new Error("AG Charts - missing processValue function for definition");
      }
      return processFn;
    }
    function processValue(def, datum, idx, valueScopes) {
      return getProcessValue(def)(datum, idx, valueScopes);
    }
    return { dataDomain, processValue, getProcessValue, initDataDomain, scopes, allScopesHaveSameDefs };
  }
  /**
   * Collects metadata about banded domain optimization for debugging and testing.
   * Stores statistics about domain banding per key and value definition.
   */
  collectDomainBandingMetadata(processedData, keyDomains, valueDomains, bandedDomains, preScanDomainStats) {
    processedData.optimizations ?? (processedData.optimizations = {});
    const collectDefs = (defs, domains) => {
      return defs.map((def) => {
        const domain = domains.get(def);
        const bandedDomain = bandedDomains.get(def);
        const isBanded = domain instanceof BandedDomain;
        let reason;
        if (!isBanded) {
          reason = def.valueType === "category" ? "discrete domain" : "not configured";
        }
        let stats;
        if (isBanded && bandedDomain) {
          const domainStats = preScanDomainStats.get(bandedDomain) ?? bandedDomain.getStats();
          const scanRatio = domainStats.bandCount > 0 ? domainStats.dirtyBandCount / domainStats.bandCount : 0;
          stats = {
            totalBands: domainStats.bandCount,
            dirtyBands: domainStats.dirtyBandCount,
            dataSize: domainStats.dataSize,
            scanRatio
          };
        }
        return {
          property: String(def.property),
          applied: isBanded,
          reason,
          stats
        };
      });
    };
    const keyDefs = collectDefs(this.ctx.keys, keyDomains);
    const valueDefs = collectDefs(this.ctx.values, valueDomains);
    processedData.optimizations.domainBanding = {
      keyDefs,
      valueDefs
    };
  }
};

// packages/ag-charts-community/src/chart/data/data-model/extraction/dataExtractor.ts
function createKeyTracker() {
  return { lastValue: void 0, sortOrder: 0, isUnique: true, isOrdered: true };
}
function updateKeyTracker(tracker, value) {
  const numericValue = typeof value === "number" ? value : value?.valueOf?.();
  if (typeof numericValue !== "number" || !Number.isFinite(numericValue))
    return;
  if (tracker.lastValue === void 0) {
    tracker.lastValue = numericValue;
    return;
  }
  const diff9 = numericValue - tracker.lastValue;
  if (diff9 === 0) {
    tracker.isUnique = false;
  } else if (tracker.isOrdered) {
    const direction = diff9 > 0 ? 1 : -1;
    if (tracker.sortOrder === 0) {
      tracker.sortOrder = direction;
    } else if (tracker.sortOrder !== direction) {
      tracker.isOrdered = false;
    }
  }
  tracker.lastValue = numericValue;
}
function trackerToSortOrderEntry(tracker) {
  return {
    sortOrder: tracker.isOrdered && tracker.sortOrder !== 0 ? tracker.sortOrder : void 0,
    isUnique: tracker.isUnique,
    isDirty: false
  };
}
var DataExtractor = class {
  constructor(ctx, domainManager) {
    this.ctx = ctx;
    this.domainManager = domainManager;
    this.markScopeDatumInvalid = function(scopes, data, datumIndex, invalidData, invalidDataCount) {
      for (const scope of scopes) {
        if (!invalidData.has(scope)) {
          invalidData.set(scope, createArray(data.length, false));
          invalidDataCount.set(scope, 0);
        }
        const scopeInvalidData = invalidData.get(scope);
        if (!scopeInvalidData[datumIndex]) {
          scopeInvalidData[datumIndex] = true;
          invalidDataCount.set(scope, invalidDataCount.get(scope) + 1);
        }
      }
    };
  }
  extractData(sources) {
    const { dataDomain, getProcessValue, allScopesHaveSameDefs } = this.domainManager.initDataDomainProcessor("extend");
    const { keys: keyDefs, values: valueDefs } = this.ctx;
    const { invalidData, invalidKeys, invalidKeyCount, invalidDataCount, allKeyMappings, keySortOrders } = this.extractKeys(keyDefs, sources, getProcessValue);
    const { columns, columnScopes, columnNeedValueOf, partialValidDataCount, maxDataLength } = this.extractValues(
      invalidData,
      invalidDataCount,
      valueDefs,
      sources,
      invalidKeys,
      getProcessValue
    );
    const propertyDomain = (def) => {
      const defDomain = dataDomain.get(def);
      const result = defDomain.getDomain();
      if (ContinuousDomain.is(defDomain) && result[0] > result[1]) {
        return [];
      }
      return result;
    };
    return {
      type: "ungrouped",
      input: { count: maxDataLength },
      scopes: new Set(sources.keys()),
      dataSources: sources,
      aggregation: void 0,
      keys: [...allKeyMappings.values()],
      columns,
      columnScopes,
      columnNeedValueOf,
      invalidKeys,
      invalidKeyCount,
      invalidData,
      invalidDataCount,
      domain: {
        keys: keyDefs.map(propertyDomain),
        values: valueDefs.map(propertyDomain)
      },
      defs: {
        allScopesHaveSameDefs,
        keys: keyDefs,
        values: valueDefs
      },
      partialValidDataCount,
      time: 0,
      version: 0,
      [DOMAIN_RANGES]: /* @__PURE__ */ new Map(),
      [KEY_SORT_ORDERS]: keySortOrders,
      [COLUMN_SORT_ORDERS]: /* @__PURE__ */ new Map(),
      [DOMAIN_BANDS]: /* @__PURE__ */ new Map(),
      [REDUCER_BANDS]: /* @__PURE__ */ new Map()
    };
  }
  extractKeys(keyDefs, sources, getProcessValue) {
    const invalidKeys = /* @__PURE__ */ new Map();
    const invalidData = /* @__PURE__ */ new Map();
    const invalidKeyCount = /* @__PURE__ */ new Map();
    const invalidDataCount = /* @__PURE__ */ new Map();
    const allKeys = /* @__PURE__ */ new Map();
    const keySortOrders = /* @__PURE__ */ new Map();
    let keyDefKeys;
    let scopeDataProcessed;
    const keyProcessors = keyDefs.map((def) => getProcessValue(def));
    const cloneScope = (source, target) => {
      const sourceScope = scopeDataProcessed.get(source);
      keyDefKeys.set(target, keyDefKeys.get(sourceScope));
      if (invalidKeys.has(sourceScope)) {
        invalidKeys.set(target, invalidKeys.get(sourceScope));
        invalidData.set(target, invalidData.get(sourceScope));
        invalidDataCount.set(target, invalidDataCount.get(sourceScope));
      }
    };
    for (const [keyDefIndex, keyDef] of keyDefs.entries()) {
      const { invalidValue, scopes: keyScopes } = keyDef;
      const processKeyValue = keyProcessors[keyDefIndex];
      keyDefKeys = /* @__PURE__ */ new Map();
      scopeDataProcessed = /* @__PURE__ */ new Map();
      allKeys.set(keyDef, keyDefKeys);
      const tracker = createKeyTracker();
      for (const scope of keyScopes ?? []) {
        const data = sources.get(scope)?.data ?? [];
        if (scopeDataProcessed.has(data)) {
          cloneScope(data, scope);
          continue;
        }
        const keys = [];
        keyDefKeys.set(scope, keys);
        scopeDataProcessed.set(data, scope);
        let invalidScopeKeys;
        let invalidScopeData;
        let missingKeys = 0;
        for (let datumIndex = 0; datumIndex < data.length; datumIndex++) {
          if (data[datumIndex] == null || typeof data[datumIndex] !== "object") {
            invalidScopeKeys ?? (invalidScopeKeys = createArray(data.length, false));
            invalidScopeData ?? (invalidScopeData = createArray(data.length, false));
            missingKeys += 1;
            invalidScopeKeys[datumIndex] = true;
            invalidScopeData[datumIndex] = true;
            keys.push(invalidValue);
            continue;
          }
          const result = processKeyValue(data[datumIndex], datumIndex, scope);
          if (result.valid) {
            keys.push(result.value);
            updateKeyTracker(tracker, result.value);
            continue;
          }
          keys.push(invalidValue);
          invalidScopeKeys ?? (invalidScopeKeys = createArray(data.length, false));
          invalidScopeData ?? (invalidScopeData = createArray(data.length, false));
          missingKeys += 1;
          invalidScopeKeys[datumIndex] = true;
          invalidScopeData[datumIndex] = true;
        }
        if (invalidScopeKeys && invalidScopeData) {
          invalidKeys.set(scope, invalidScopeKeys);
          invalidData.set(scope, invalidScopeData);
          invalidKeyCount.set(scope, missingKeys);
          invalidDataCount.set(scope, missingKeys);
        }
      }
      keySortOrders.set(keyDefIndex, trackerToSortOrderEntry(tracker));
    }
    return { invalidData, invalidKeys, invalidKeyCount, invalidDataCount, allKeyMappings: allKeys, keySortOrders };
  }
  extractValues(invalidData, invalidDataCount, valueDefs, sources, scopeInvalidKeys, getProcessValue) {
    let partialValidDataCount = 0;
    const columns = [];
    const allColumnScopes = [];
    const columnNeedValueOf = [];
    let maxDataLength = 0;
    const valueProcessors = valueDefs.map((def) => getProcessValue(def));
    for (const [valueDefIndex, def] of valueDefs.entries()) {
      const { invalidValue } = def;
      const processValueForDef = valueProcessors[valueDefIndex];
      const valueSources = new Set(def.scopes.map((s) => sources.get(s)));
      if (valueSources.size > 1) {
        throw new Error(`AG Charts - more than one data source for: ${JSON.stringify(def)}`);
      }
      const columnScopes = new Set(def.scopes);
      const columnScope = first(def.scopes);
      const columnSource = sources.get(columnScope)?.data ?? [];
      const column = new Array();
      const invalidKeys = scopeInvalidKeys.get(columnScope);
      let needsValueOf = false;
      for (let datumIndex = 0; datumIndex < columnSource.length; datumIndex++) {
        if (columnSource[datumIndex] == null || typeof columnSource[datumIndex] !== "object") {
          this.markScopeDatumInvalid(def.scopes, columnSource, datumIndex, invalidData, invalidDataCount);
          column[datumIndex] = invalidValue;
          continue;
        }
        const valueDatum = columnSource[datumIndex];
        const invalidKey = invalidKeys == null ? false : invalidKeys[datumIndex];
        const result = processValueForDef(valueDatum, datumIndex, def.scopes);
        let value = result.value;
        if (invalidKey || !result.valid) {
          this.markScopeDatumInvalid(def.scopes, columnSource, datumIndex, invalidData, invalidDataCount);
        }
        if (invalidKey) {
          value = invalidValue;
        } else if (!result.valid) {
          partialValidDataCount += 1;
          value = invalidValue;
        }
        if (!needsValueOf && value != null && typeof value === "object") {
          needsValueOf = true;
        }
        column[datumIndex] = value;
      }
      columns.push(column);
      allColumnScopes.push(columnScopes);
      columnNeedValueOf.push(needsValueOf);
      maxDataLength = Math.max(maxDataLength, column.length);
    }
    return { columns, columnScopes: allColumnScopes, columnNeedValueOf, partialValidDataCount, maxDataLength };
  }
  warnDataMissingProperties(sources) {
    if (sources.size === 0)
      return;
    for (const def of iterate(this.ctx.keys, this.ctx.values)) {
      for (const [scope, missCount] of def.missing) {
        if (missCount < (sources.get(scope)?.data.length ?? Infinity))
          continue;
        const scopeHint = scope == null ? "" : ` for ${scope}`;
        logger_exports.warnOnce(`the key '${def.property}' was not found in any data element${scopeHint}.`);
      }
    }
  }
};

// packages/ag-charts-community/src/chart/data/data-model/grouping/dataGrouper.ts
var DataGrouper = class {
  constructor(ctx) {
    this.ctx = ctx;
  }
  /**
   * Groups data by keys or custom grouping function.
   *
   * GROUPED DATA STRUCTURE AND INVARIANTS:
   *
   * When groupsUnique=true (each datum has distinct keys):
   * - groups.length === columns[i].length for all columns
   * - groups[i] corresponds to datum at columns[j][i]
   * - All datumIndices arrays contain [0] (shared memory optimization)
   * - Relative indexing: datumIndices contains offsets from group start
   * - Absolute indexing: groupIndex + relativeDatumIndex gives column position
   *
   * When groupsUnique=false (data is aggregated):
   * - groups.length <= columns[i].length
   * - Multiple datums may map to same group
   * - datumIndices contain actual relative offsets
   *
   * This design optimizes memory usage for high-frequency data updates
   * where each datum typically has unique keys (e.g., time series data).
   */
  groupData(data, customGroupingFn) {
    var _a;
    const { keys: dataKeys, columns: allColumns, columnScopes, invalidKeys, invalidData } = data;
    const allScopes = data.scopes;
    const resultGroups = [];
    const resultData = [];
    const groups = allScopes.size !== 1 || customGroupingFn != null ? /* @__PURE__ */ new Map() : void 0;
    let groupsUnique = true;
    let groupIndex = 0;
    const rawBatchCount = allScopes.size;
    const columnBatches = this.groupBatches(
      allScopes,
      allColumns,
      columnScopes,
      dataKeys,
      invalidData,
      invalidKeys
    );
    const mergedBatchCount = columnBatches.length;
    if (this.ctx.debug?.check() && !data.optimizations) {
      data.optimizations = {};
    }
    if (this.ctx.debug?.check()) {
      const mergeRatio = rawBatchCount > 0 ? 1 - mergedBatchCount / rawBatchCount : 0;
      data.optimizations.batchMerging = {
        originalBatchCount: rawBatchCount,
        mergedBatchCount,
        mergeRatio
      };
    }
    const singleBatch = columnBatches.length === 1;
    const allZeroDatumIndices = Object.freeze(createArray(columnBatches[0][1].length, SHARED_ZERO_INDICES));
    for (const [
      scopes,
      scopeColumnIndexes,
      scopeKeys,
      siblingScopes,
      scopeInvalidData,
      scopeInvalidKeys
    ] of columnBatches) {
      const firstColumn = allColumns[first(scopeColumnIndexes)];
      for (let datumIndex = 0; datumIndex < firstColumn.length; datumIndex++) {
        if (scopeInvalidKeys?.[datumIndex] === true)
          continue;
        const keys = scopeKeys.map((k) => k[datumIndex]);
        if (keys == null || keys.length === 0) {
          throw new Error("AG Charts - no keys found for scope(s): " + scopes.join(", "));
        }
        const group = customGroupingFn?.(keys) ?? keys;
        const groupStr = groups == null ? void 0 : toKeyString(group);
        let outputGroup = groups?.get(groupStr);
        let currentGroup;
        let currentGroupIndex;
        let isNewGroup = false;
        if (outputGroup == null) {
          currentGroup = {
            keys: group,
            datumIndices: [],
            aggregation: [],
            validScopes: allScopes
          };
          currentGroupIndex = groupIndex++;
          outputGroup = [currentGroupIndex, currentGroup];
          isNewGroup = true;
          groups?.set(groupStr, outputGroup);
          resultGroups.push(currentGroup.keys);
          resultData.push(currentGroup);
        } else {
          [currentGroupIndex, currentGroup] = outputGroup;
          groupsUnique = false;
        }
        if (scopeInvalidData?.[datumIndex] === true) {
          if (currentGroup.validScopes === allScopes) {
            currentGroup.validScopes = new Set(allScopes.values());
          }
          for (const invalidScope of siblingScopes) {
            currentGroup.validScopes.delete(invalidScope);
          }
        }
        if (isNewGroup && datumIndex === currentGroupIndex && singleBatch) {
          currentGroup.datumIndices = allZeroDatumIndices;
        } else {
          if (!isNewGroup && currentGroup.datumIndices === allZeroDatumIndices) {
            currentGroup.datumIndices = allZeroDatumIndices.map((arr) => [...arr]);
          }
          for (const columnIdx of scopeColumnIndexes) {
            (_a = currentGroup.datumIndices)[columnIdx] ?? (_a[columnIdx] = []);
            currentGroup.datumIndices[columnIdx].push(datumIndex - currentGroupIndex);
          }
        }
      }
    }
    return {
      ...data,
      type: "grouped",
      domain: {
        ...data.domain,
        groups: resultGroups
      },
      groups: resultData,
      groupsUnique,
      optimizations: data.optimizations,
      [DOMAIN_BANDS]: data[DOMAIN_BANDS],
      [REDUCER_BANDS]: data[REDUCER_BANDS]
    };
  }
  /**
   * Groups and merges column batches for efficient processing.
   *
   * BATCH MERGING OPTIMIZATION:
   * - Identifies columns that share the same data characteristics
   * - Merges compatible batches to reduce iteration overhead
   * - Can reduce processing iterations by 30-50% for multi-scope datasets
   *
   * Compatibility criteria:
   * - Same keys arrays (by reference)
   * - Same invalidity arrays (by reference)
   * - Scopes can be safely processed together
   */
  groupBatches(allScopes, allColumns, columnScopes, dataKeys, invalidData, invalidKeys) {
    const columnBatches = [];
    const processedColumnIndexes = /* @__PURE__ */ new Set();
    for (const scope of allScopes) {
      const scopeColumnIndexes = allColumns.map((_, idx) => idx).filter((idx) => !processedColumnIndexes.has(idx) && columnScopes[idx].has(scope));
      if (scopeColumnIndexes.length === 0)
        continue;
      for (const idx of scopeColumnIndexes) {
        processedColumnIndexes.add(idx);
      }
      const siblingScopes = /* @__PURE__ */ new Set();
      for (const columnIdx of scopeColumnIndexes) {
        for (const columnScope of columnScopes[columnIdx]) {
          siblingScopes.add(columnScope);
        }
      }
      const scopeKeys = dataKeys.map((k) => k.get(scope)).filter((k) => k != null);
      const scopeInvalidData = invalidData?.get(scope);
      const scopeInvalidKeys = invalidKeys?.get(scope);
      columnBatches.push([
        scope,
        scopeColumnIndexes,
        scopeKeys,
        siblingScopes,
        scopeInvalidData,
        scopeInvalidKeys
      ]);
    }
    return this.mergeCompatibleBatches(columnBatches);
  }
  /**
   * Checks if two column batches can be merged based on shared data characteristics.
   */
  areBatchesCompatible(batch1, batch2) {
    const [, , keys1, , invalidData1, invalidKeys1] = batch1;
    const [, , keys2, , invalidData2, invalidKeys2] = batch2;
    return keys1.every((k, i) => k === keys2[i]) && invalidKeys1 === invalidKeys2 && invalidData1 === invalidData2;
  }
  mergeCompatibleBatches(columnBatches) {
    const merged = [];
    const processed = /* @__PURE__ */ new Set();
    for (let i = 0; i < columnBatches.length; i++) {
      if (processed.has(i))
        continue;
      const [scope, columnIndexes, keys, siblingScopes, invalidData, invalidKeys] = columnBatches[i];
      const mergedBatch = [
        [scope],
        [...columnIndexes],
        keys,
        new Set(siblingScopes),
        invalidData,
        invalidKeys
      ];
      this.findAndMergeCompatibleBatches(columnBatches, i, mergedBatch, processed);
      merged.push(mergedBatch);
      processed.add(i);
    }
    return merged;
  }
  findAndMergeCompatibleBatches(columnBatches, startIndex, mergedBatch, processed) {
    const firstBatch = columnBatches[startIndex];
    for (let j = startIndex + 1; j < columnBatches.length; j++) {
      if (processed.has(j))
        continue;
      const otherBatch = columnBatches[j];
      const [scope, otherColumnIndexes, , otherSiblingScopes] = otherBatch;
      if (!this.areBatchesCompatible(firstBatch, otherBatch))
        continue;
      mergedBatch[0].push(scope);
      mergedBatch[1].push(...otherColumnIndexes);
      for (const siblingScope of otherSiblingScopes) {
        mergedBatch[3].add(siblingScope);
      }
      processed.add(j);
    }
  }
};

// packages/ag-charts-community/src/chart/data/dataChangeDescription.ts
function isAppendOnly(indexMap) {
  return indexMap.removedIndices.size === 0 && indexMap.totalPrependCount === 0 && indexMap.totalAppendCount > 0;
}
function isPrependOnly(indexMap) {
  return indexMap.removedIndices.size === 0 && indexMap.totalAppendCount === 0 && indexMap.totalPrependCount > 0;
}
function hasNoRemovals(indexMap) {
  return indexMap.removedIndices.size === 0;
}
function isUpdateOnly(indexMap) {
  return indexMap.removedIndices.size === 0 && indexMap.totalPrependCount === 0 && indexMap.totalAppendCount === 0 && indexMap.spliceOps.every((op) => op.insertCount === 0 && op.deleteCount === 0);
}
function hasOnlyRemovals(indexMap) {
  return indexMap.removedIndices.size > 0 && indexMap.totalPrependCount === 0 && indexMap.totalAppendCount === 0 && indexMap.spliceOps.every((op) => op.insertCount === 0);
}
function hasContiguousRemovalsAtStart(indexMap) {
  const { removedIndices } = indexMap;
  if (removedIndices.size === 0)
    return false;
  const sorted = Array.from(removedIndices).sort((a, b) => a - b);
  if (sorted[0] !== 0)
    return false;
  for (let i = 0; i < sorted.length; i++) {
    if (sorted[i] !== i)
      return false;
  }
  return true;
}
function isRollingWindow(indexMap) {
  return hasContiguousRemovalsAtStart(indexMap) && indexMap.totalAppendCount > 0 && indexMap.totalPrependCount === 0;
}
var DataChangeDescription = class {
  constructor(indexMap, insertions) {
    this.indexMap = indexMap;
    this.prependValues = insertions.prependValues;
    this.appendValues = insertions.appendValues;
    this.insertionValues = insertions.insertionValues;
  }
  /**
   * Get all indices that were removed from the original array, sorted ascending.
   *
   * @returns Array of removed indices (e.g., [2, 5, 8])
   *
   * @example
   * ```typescript
   * const removed = changeDesc.getRemovedIndices();
   * console.log(`Removed ${removed.length} items at indices: ${removed}`);
   * ```
   */
  getRemovedIndices() {
    return Array.from(this.indexMap.removedIndices).sort((a, b) => a - b);
  }
  /**
   * Get all indices that were updated in the final array, sorted ascending.
   *
   * @returns Array of updated indices (e.g., [1, 3, 7])
   *
   * @example
   * ```typescript
   * const updated = changeDesc.getUpdatedIndices();
   * console.log(`Updated ${updated.length} items at indices: ${updated}`);
   * ```
   */
  getUpdatedIndices() {
    return Array.from(this.indexMap.updatedIndices).sort((a, b) => a - b);
  }
  /**
   * Iterate over preserved elements, mapping source index to destination index.
   * Only calls callback for elements that were NOT removed.
   *
   * **Use this for:**
   * - Tracking which elements moved (when sourceIndex !== destIndex)
   * - Generating diff metadata (added/removed/moved items)
   * - Understanding index shifts caused by prepends/removes
   *
   * @param callback - Called for each preserved element with (sourceIndex, destIndex)
   *
   * @example Detecting moved items
   * ```typescript
   * const movedItems = new Set<number>();
   * changeDesc.forEachPreservedIndex((srcIdx, destIdx) => {
   *     if (srcIdx !== destIdx) {
   *         movedItems.add(destIdx);
   *     }
   * });
   * ```
   */
  forEachPreservedIndex(callback2) {
    const { originalLength, removedIndices, totalPrependCount } = this.indexMap;
    let removalsBeforeCount = 0;
    const sortedRemovals = Array.from(removedIndices).sort((a, b) => a - b);
    let removalIdx = 0;
    for (let srcIdx = 0; srcIdx < originalLength; srcIdx++) {
      while (removalIdx < sortedRemovals.length && sortedRemovals[removalIdx] < srcIdx) {
        removalsBeforeCount++;
        removalIdx++;
      }
      if (!removedIndices.has(srcIdx)) {
        const destIdx = srcIdx + totalPrependCount - removalsBeforeCount;
        callback2(srcIdx, destIdx);
      }
    }
  }
  /**
   * Get the values that were prepended to the beginning of the array.
   *
   * These values are stored during change description construction and can be used
   * to avoid reprocessing prepended data.
   *
   * @returns Array of prepended values in order
   *
   * @example Processing prepended data
   * ```typescript
   * const prependedData = changeDesc.getPrependedValues<DataRow>();
   * for (const row of prependedData) {
   *     processRow(row);
   * }
   * ```
   */
  getPrependedValues() {
    return this.prependValues;
  }
  /**
   * Get the values that were appended to the end of the array.
   *
   * These values are stored during change description construction and can be used
   * to avoid reprocessing appended data.
   *
   * @returns Array of appended values in order
   *
   * @example Processing appended data
   * ```typescript
   * const appendedData = changeDesc.getAppendedValues<DataRow>();
   * for (const row of appendedData) {
   *     processRow(row);
   * }
   * ```
   */
  getAppendedValues() {
    return this.appendValues;
  }
  /**
   * Get the values that were inserted at arbitrary indices.
   *
   * These values are stored during change description construction and can be used
   * to avoid reprocessing inserted data.
   *
   * @returns Array of insertion values in the order they appear in splice operations
   *
   * @example Processing inserted data
   * ```typescript
   * const insertedData = changeDesc.getInsertionValues<DataRow>();
   * for (const row of insertedData) {
   *     processRow(row);
   * }
   * ```
   */
  getInsertionValues() {
    return this.insertionValues;
  }
  /**
   * Applies the transformation to an array in-place using native Array operations.
   * This is a zero-copy operation that mutates the array directly.
   *
   * **Use this for:**
   * - Transforming processed data arrays (keys, columns, invalidity)
   * - Applying prepends, removals, and appends in a single pass
   * - Maintaining synchronization between data and processed arrays
   *
   * **How it works:**
   * 1. Applies splice operations in order (prepends, removals, appends)
   * 2. Calls processInsertion callback for each inserted element
   * 3. Mutates the array in-place for zero-copy efficiency
   *
   * @param array - The array to transform in-place (will be mutated)
   * @param processInsertion - Callback to generate values for inserted indices
   *
   * @example Transforming a column array
   * ```typescript
   * // Transform processed column to match new data layout
   * const insertionCache = new Map(); // Pre-computed processed values
   * changeDesc.applyToArray(columnArray, (destIndex) => {
   *     return insertionCache.get(destIndex) ?? defaultValue;
   * });
   * ```
   *
   * @example Transforming an invalidity array
   * ```typescript
   * // Transform invalidity flags to match new data
   * changeDesc.applyToArray(invalidityArray, (destIndex) => {
   *     const cached = insertionCache.get(destIndex);
   *     return cached?.hasInvalidKey ?? false;
   * });
   * ```
   */
  applyToArray(array2, processInsertion, onRemove) {
    const { spliceOps, finalLength, originalLength } = this.indexMap;
    if (originalLength === finalLength && spliceOps.length === 0) {
      return;
    }
    for (const op of spliceOps) {
      const insertElements = op.insertCount > 0 ? Array.from({ length: op.insertCount }, function processOpInsertion(_, j) {
        return processInsertion(op.index + j);
      }) : [];
      const removed = array2.splice(op.index, op.deleteCount, ...insertElements);
      if (onRemove && removed.length > 0) {
        onRemove(removed, op);
      }
    }
    if (array2.length !== finalLength) {
      array2.length = finalLength;
    }
  }
};

// packages/ag-charts-community/src/chart/data/data-model/reducers/bandedReducer.ts
var BandedReducer = class extends BandedStructure {
  constructor(config = {}) {
    super(config);
    this.lastDirtyBandCount = 0;
    this.lastScanRatio = 0;
    this.statsCaptured = false;
  }
  /**
   * Creates a new reducer band with undefined cached result.
   */
  createBand(startIndex, endIndex) {
    return {
      startIndex,
      endIndex,
      cachedResult: void 0,
      isDirty: true
    };
  }
  /**
   * Initializes bands and resets stats capture flag.
   */
  initializeBands(dataSize) {
    super.initializeBands(dataSize);
    this.statsCaptured = false;
  }
  /**
   * Gets the array of bands for direct access.
   * For production code, prefer using evaluateFromData() and getResult() for symmetry with BandedDomain.
   * This method is primarily for testing and debugging band structure.
   */
  getBands() {
    return this.bands;
  }
  /**
   * Evaluates a reducer across all bands, reusing cached results for clean bands.
   * Symmetrical to BandedDomain.extendBandsFromData().
   *
   * @param def Reducer definition with reducer function, initial value, and overlap settings
   * @param context Reducer context containing raw data and key columns
   * @param reuseCleanBands Whether to reuse cached results for clean bands (default: false)
   */
  evaluateFromData(def, context, reuseCleanBands = false) {
    const reducerFn = def.reducer();
    for (const band of this.bands) {
      if (reuseCleanBands && !band.isDirty) {
        continue;
      }
      const startIndex = def.needsOverlap && band.startIndex > 0 ? Math.max(0, band.startIndex - 1) : band.startIndex;
      const result = this.evaluateRange(def, reducerFn, context, startIndex, band.endIndex);
      band.cachedResult = result;
      band.isDirty = false;
    }
  }
  /**
   * Combines all band results to get the final aggregated value.
   * Symmetrical to BandedDomain.getDomain().
   *
   * @param def Reducer definition with combineResults function
   * @returns Combined result from all bands
   */
  getResult(def) {
    const bandResults = this.bands.map((band) => band.cachedResult);
    return def.combineResults(bandResults);
  }
  /**
   * Evaluates a reducer over a specific range of data indices.
   * Symmetrical to BandedDomain's band scanning loop in extendBandsFromData().
   *
   * @param def Reducer definition with initial value
   * @param reducer Reducer function to apply
   * @param context Reducer context with data and keys
   * @param startIndex Starting index (inclusive)
   * @param endIndex Ending index (exclusive)
   * @returns Accumulated reducer result for the range
   */
  evaluateRange(def, reducer, context, startIndex, endIndex) {
    let accValue = def.initialValue;
    const { keyColumns, keysParam, rawData } = context;
    const clampedEnd = Math.min(endIndex, rawData.length);
    for (let datumIndex = startIndex; datumIndex < clampedEnd; datumIndex += 1) {
      for (let keyIdx = 0; keyIdx < keysParam.length; keyIdx++) {
        keysParam[keyIdx] = keyColumns[keyIdx]?.[datumIndex];
      }
      accValue = reducer(accValue, keysParam);
    }
    return accValue;
  }
  /**
   * Capture the current dirty state before processing.
   * Call this before marking bands as clean to preserve stats for reporting.
   */
  captureStatsBeforeProcessing() {
    const dirtyBands = this.bands.filter((band) => band.isDirty);
    const dirtySpan = dirtyBands.reduce((sum, band) => sum + (band.endIndex - band.startIndex), 0);
    this.lastDirtyBandCount = dirtyBands.length;
    this.lastScanRatio = this.dataSize > 0 ? dirtySpan / this.dataSize : 0;
    this.statsCaptured = true;
  }
  /**
   * Returns reducer-specific statistics including cache hits and scan ratio.
   */
  getStats() {
    const cleanBands = this.bands.filter((band) => !band.isDirty && band.cachedResult !== void 0);
    let dirtyBands;
    let scanRatio;
    if (this.statsCaptured) {
      dirtyBands = this.lastDirtyBandCount;
      scanRatio = this.lastScanRatio;
    } else {
      const currentDirtyBands = this.bands.filter((band) => band.isDirty);
      const dirtySpan = currentDirtyBands.reduce((sum, band) => sum + (band.endIndex - band.startIndex), 0);
      dirtyBands = currentDirtyBands.length;
      scanRatio = this.dataSize > 0 ? dirtySpan / this.dataSize : 0;
    }
    return {
      totalBands: this.bands.length,
      dirtyBands,
      dataSize: this.dataSize,
      scanRatio,
      cacheHits: cleanBands.length
    };
  }
};

// packages/ag-charts-community/src/chart/data/data-model/reducers/reducerManager.ts
var ReducerManager = class {
  constructor(bandingConfig = {}) {
    this.bandingConfig = bandingConfig;
  }
  /**
   * Evaluates a reducer over a specific range of data indices.
   * Used for non-banded reducer evaluation (fallback path).
   *
   * This is a static utility method for cases where banding is not applicable
   * (e.g., grouped data, small datasets, reducers that don't support banding).
   *
   * @param def Reducer definition with initial value
   * @param reducer Reducer function to apply
   * @param context Reducer context with data and keys
   * @param startIndex Starting index (inclusive)
   * @param endIndex Ending index (exclusive)
   * @returns Accumulated reducer result for the range
   */
  static evaluateRange(def, reducer, context, startIndex, endIndex) {
    let accValue = def.initialValue;
    const { keyColumns, keysParam, rawData } = context;
    const clampedEnd = Math.min(endIndex, rawData.length);
    for (let datumIndex = startIndex; datumIndex < clampedEnd; datumIndex += 1) {
      for (let keyIdx = 0; keyIdx < keysParam.length; keyIdx++) {
        keysParam[keyIdx] = keyColumns[keyIdx]?.[datumIndex];
      }
      accValue = reducer(accValue, keysParam);
    }
    return accValue;
  }
  /**
   * Evaluates a banded reducer and returns the aggregated result.
   * Symmetrical to DomainManager.recomputeDomains().
   *
   * @param def Reducer definition
   * @param processedData Processed data containing raw data and keys
   * @param options Evaluation options including band reuse settings
   * @returns Aggregated reducer result
   */
  evaluate(def, processedData, options = {}) {
    var _a;
    const context = this.createContext(def, processedData);
    if (!context) {
      return void 0;
    }
    processedData[_a = REDUCER_BANDS] ?? (processedData[_a] = /* @__PURE__ */ new Map());
    const reducerBands = processedData[REDUCER_BANDS];
    const property = def.property;
    let bandManager = reducerBands.get(property);
    if (!bandManager) {
      bandManager = new BandedReducer(this.bandingConfig);
      reducerBands.set(property, bandManager);
    }
    if (bandManager.getBandCount() === 0) {
      bandManager.initializeBands(context.rawData.length);
    }
    options.beforeEvaluate?.(bandManager, context);
    bandManager.captureStatsBeforeProcessing();
    bandManager.evaluateFromData(def, context, options.reuseCleanBands ?? false);
    return bandManager.getResult(def);
  }
  /**
   * Applies index map transformations to all reducer bands.
   * Symmetrical to DomainManager's band update logic.
   *
   * @param processedData Processed data containing reducer bands
   * @param indexMap Index map with splice operations and updated indices
   */
  applyIndexMap(processedData, indexMap) {
    const reducerBands = processedData[REDUCER_BANDS];
    if (!reducerBands)
      return;
    for (const bandManager of reducerBands.values()) {
      bandManager.applyIndexMap(indexMap);
    }
  }
  /**
   * Creates a reducer context from processed data.
   * Extracts raw data and key columns for the appropriate scope.
   * Symmetrical to domain context creation in DomainManager.
   *
   * @param def Reducer definition
   * @param processedData Processed data
   * @returns Reducer context with scope information, or undefined if not applicable
   */
  createContext(def, processedData) {
    if (processedData.type !== "ungrouped") {
      return void 0;
    }
    const scopeId = isScoped(def) ? def.scopes[0] : first(processedData.dataSources.keys());
    if (scopeId == null) {
      return void 0;
    }
    const rawData = processedData.dataSources.get(scopeId)?.data ?? [];
    const keyColumns = processedData.keys.map((column) => column.get(scopeId)).filter((column) => column != null);
    const keysParam = keyColumns.map(() => void 0);
    return { scopeId, rawData, keyColumns, keysParam };
  }
};

// packages/ag-charts-community/src/chart/data/data-model/incremental/incrementalProcessor.ts
var IncrementalProcessor = class {
  constructor(ctx, reducerManager) {
    this.ctx = ctx;
    this.reducerManager = reducerManager;
  }
  /**
   * Checks if incremental reprocessing is supported for the given data configuration.
   */
  isReprocessingSupported(processedData) {
    if (processedData.type === "grouped") {
      if (!processedData.groupsUnique)
        return false;
      const uniqueDataSets = this.getUniqueDataSets(processedData);
      if (uniqueDataSets.size !== 1)
        return false;
      const scope = first(processedData.scopes);
      const invalidKeys = processedData.invalidKeys?.get(scope);
      if (invalidKeys?.some((invalid) => invalid))
        return false;
    }
    if (this.ctx.aggregates.length > 0)
      return false;
    const hasUnsupportedReducers = this.ctx.reducers.some(
      (reducer) => reducer.supportsBanding !== true || typeof reducer.combineResults !== "function"
    );
    if (hasUnsupportedReducers)
      return false;
    const hasUnsupportedProcessors = this.ctx.processors.some(
      (processor) => processor.incrementalCalculate === void 0
    );
    if (hasUnsupportedProcessors)
      return false;
    if (this.ctx.propertyProcessors.length > 0)
      return false;
    return this.ctx.groupProcessors.every((p) => p.supportsReprocessing ?? false);
  }
  /**
   * Performs incremental reprocessing of data based on change descriptions.
   */
  reprocessData(processedData, dataSets, getProcessValue, reprocessGroupProcessorsFn, recomputeDomainsFn, collectOptimizationMetadataFn) {
    const start2 = performance.now();
    const scopeChanges = this.collectScopeChanges(processedData, dataSets);
    if (scopeChanges.size === 0) {
      return processedData;
    }
    this.commitPendingTransactions(processedData);
    const keyProcessors = this.buildDefinitionProcessors(this.ctx.keys, getProcessValue);
    const valueProcessors = this.buildDefinitionProcessors(this.ctx.values, getProcessValue);
    const insertionCaches = this.processAllInsertions(processedData, scopeChanges, keyProcessors, valueProcessors);
    this.processAllUpdates(processedData, scopeChanges, keyProcessors, valueProcessors, insertionCaches);
    this.updateBandsForChanges(processedData, scopeChanges);
    const removedKeys = this.transformKeysArrays(processedData, scopeChanges, insertionCaches);
    this.transformColumnsArrays(processedData, scopeChanges, insertionCaches);
    this.transformInvalidityArrays(processedData, scopeChanges, insertionCaches);
    this.reprocessBandedReducers(processedData, scopeChanges);
    if (processedData.type === "grouped") {
      this.transformGroupsArray(processedData, scopeChanges, insertionCaches);
      if (this.ctx.groupProcessors.length > 0) {
        reprocessGroupProcessorsFn(processedData, scopeChanges);
      }
    }
    this.invalidateSortOrdersForChanges(processedData, scopeChanges);
    recomputeDomainsFn(processedData);
    this.reprocessProcessors(processedData);
    if (processedData.reduced?.diff != null && scopeChanges.size > 0) {
      this.generateDiffMetadata(processedData, scopeChanges, removedKeys);
    }
    this.updateProcessedDataMetadata(processedData);
    const end3 = performance.now();
    processedData.time = end3 - start2;
    processedData.version += 1;
    collectOptimizationMetadataFn(processedData, "reprocess");
    const uniqueChanges = uniqueChangeDescriptions(scopeChanges);
    processedData.changeDescription = uniqueChanges.size === 1 ? uniqueChanges.values().next().value : void 0;
    return processedData;
  }
  /**
   * Updates banded domains based on pending changes.
   *
   * BANDING OPTIMIZATION:
   * - Divides large datasets into bands (default ~100 bands)
   * - Tracks which bands are "dirty" and need recalculation
   * - During updates, only dirty bands are reprocessed
   * - Significantly reduces domain calculation overhead for large datasets
   *
   * Example: 1M data points → 100 bands of 10K points each
   * Adding 1000 points only dirties 1-2 bands instead of scanning all 1M points
   *
   * This optimizes domain recalculation by only marking affected bands as dirty.
   * Deduplicates change descriptions to avoid processing the same changes multiple times
   * when multiple scopes share the same DataSet.
   */
  updateBandsForChanges(processedData, scopeChanges) {
    const bandedDomains = processedData[DOMAIN_BANDS];
    if (bandedDomains.size === 0)
      return;
    const processedChangeDescs = uniqueChangeDescriptions(scopeChanges);
    for (const changeDesc of processedChangeDescs) {
      const { indexMap } = changeDesc;
      for (const domain of bandedDomains.values()) {
        domain.applyIndexMap(indexMap);
      }
    }
  }
  reprocessBandedReducers(processedData, scopeChanges) {
    if (processedData.type !== "ungrouped")
      return;
    const bandedReducers = this.ctx.reducers.filter(
      (reducer) => reducer.supportsBanding && typeof reducer.combineResults === "function"
    );
    if (bandedReducers.length === 0)
      return;
    processedData.reduced ?? (processedData.reduced = {});
    for (const def of bandedReducers) {
      const result = this.reducerManager.evaluate(def, processedData, {
        reuseCleanBands: true,
        beforeEvaluate: (bandManager, context) => {
          if (!context.scopeId)
            return;
          const changeDesc = scopeChanges.get(context.scopeId);
          if (changeDesc) {
            bandManager.applyIndexMap(changeDesc.indexMap);
          }
        }
      });
      if (result !== void 0) {
        processedData.reduced[def.property] = result;
      }
    }
  }
  /**
   * Collects change descriptions from all DataSets before committing.
   */
  collectScopeChanges(processedData, dataSets) {
    const scopeChanges = /* @__PURE__ */ new Map();
    for (const [scopeId, dataSet] of processedData.dataSources) {
      const changeDesc = dataSets?.get(dataSet) ?? dataSet.getChangeDescription();
      if (changeDesc) {
        scopeChanges.set(scopeId, changeDesc);
      }
    }
    return scopeChanges;
  }
  /**
   * Commits all pending transactions to the data arrays.
   * Deduplicates DataSets to avoid committing the same DataSet multiple times
   * when multiple scopes share the same DataSet.
   */
  commitPendingTransactions(processedData) {
    const uniqueDataSets = this.getUniqueDataSets(processedData);
    for (const dataSet of uniqueDataSets) {
      dataSet.commitPendingTransactions();
    }
  }
  buildDefinitionProcessors(defs, getProcessValue) {
    return defs.map((def, index) => ({
      def,
      index,
      processValue: getProcessValue(def)
    }));
  }
  /**
   * Pre-processes all insertions once per scope to avoid redundant computation.
   */
  processAllInsertions(processedData, scopeChanges, keyProcessors, valueProcessors) {
    const insertionCaches = /* @__PURE__ */ new Map();
    for (const [scope, changeDesc] of scopeChanges) {
      const dataSet = processedData.dataSources.get(scope);
      if (!dataSet)
        continue;
      const cache = this.processInsertionsOnce(scope, changeDesc, dataSet, keyProcessors, valueProcessors);
      insertionCaches.set(scope, cache);
    }
    return insertionCaches;
  }
  /**
   * Processes all updated items once per scope, adding them to the insertion cache.
   * This ensures updated values are available when transforming columns/keys arrays.
   */
  processAllUpdates(processedData, scopeChanges, keyProcessors, valueProcessors, insertionCaches) {
    for (const [scope, changeDesc] of scopeChanges) {
      const dataSet = processedData.dataSources.get(scope);
      if (!dataSet)
        continue;
      const updatedIndices = changeDesc.getUpdatedIndices();
      if (updatedIndices.length === 0)
        continue;
      let cache = insertionCaches.get(scope);
      if (!cache) {
        cache = /* @__PURE__ */ new Map();
        insertionCaches.set(scope, cache);
      }
      for (const destIndex of updatedIndices) {
        if (destIndex < 0 || destIndex >= dataSet.data.length) {
          continue;
        }
        const processed = this.processDatum(dataSet, destIndex, scope, keyProcessors, valueProcessors);
        if (processed) {
          cache.set(destIndex, processed);
        }
      }
    }
  }
  /**
   * Processes all insertions for a given scope once, caching the results.
   * Returns a map from ADJUSTED destIndex to processed values for all keys and values.
   * The adjusted destIndex accounts for out-of-bounds insertions that need to be shifted.
   */
  processInsertionsOnce(scope, changeDesc, dataSet, keyProcessors, valueProcessors) {
    const cache = /* @__PURE__ */ new Map();
    const { finalLength } = changeDesc.indexMap;
    for (const op of changeDesc.indexMap.spliceOps) {
      if (op.insertCount <= 0)
        continue;
      for (let i = 0; i < op.insertCount; i++) {
        const destIndex = op.index + i;
        if (destIndex < 0 || destIndex >= finalLength) {
          continue;
        }
        const processed = this.processDatum(dataSet, destIndex, scope, keyProcessors, valueProcessors);
        if (processed) {
          cache.set(destIndex, processed);
        }
      }
    }
    return cache;
  }
  /**
   * Processes a single datum for the given scope, returning cached key/value results.
   * Shared between insert and update paths to keep behaviour consistent.
   */
  processDatum(dataSet, destIndex, scope, keyProcessors, valueProcessors) {
    const datum = dataSet.data[destIndex];
    const keys = /* @__PURE__ */ new Map();
    const values = /* @__PURE__ */ new Map();
    let hasInvalidKey = false;
    let hasInvalidValue = false;
    if (datum == null || typeof datum !== "object") {
      hasInvalidKey = true;
      hasInvalidValue = true;
    } else {
      for (const { index: keyDefIndex, def: keyDef, processValue: processKeyValue } of keyProcessors) {
        if (!keyDef.scopes?.includes(scope))
          continue;
        const result = processKeyValue(datum, destIndex, scope);
        keys.set(keyDefIndex, { value: result.value, valid: result.valid });
        if (!result.valid) {
          hasInvalidKey = true;
        }
      }
      for (const { index: valueDefIndex, def: valueDef, processValue: processValueForDef } of valueProcessors) {
        if (!valueDef.scopes?.includes(scope))
          continue;
        const result = processValueForDef(datum, destIndex, valueDef.scopes);
        values.set(valueDefIndex, { value: result.value, valid: result.valid });
        if (!result.valid) {
          hasInvalidValue = true;
        }
      }
    }
    return { keys, values, hasInvalidKey, hasInvalidValue };
  }
  /**
   * Generic utility to transform arrays using cached insertion results.
   * This reduces duplication across transformKeysArrays, transformColumnsArrays, and transformInvalidityArrays.
   */
  transformArraysWithCache(definitions, scopeChanges, insertionCaches, getArray, getScopes, extractValue) {
    for (const [defIndex, def] of definitions.entries()) {
      for (const scope of getScopes(def)) {
        const changeDesc = scopeChanges.get(scope);
        if (!changeDesc)
          continue;
        const array2 = getArray(defIndex, scope);
        if (!array2)
          continue;
        const insertionCache = insertionCaches.get(scope);
        this.applyChangeDescWithCache(
          changeDesc,
          array2,
          insertionCache,
          (cached, _destIndex) => extractValue(cached, def, defIndex)
        );
      }
    }
  }
  /**
   * Transforms keys arrays using cached insertion results.
   */
  transformKeysArrays(processedData, scopeChanges, insertionCaches) {
    const removedByScope = /* @__PURE__ */ new Map();
    const ensureRemovedMetadata = (scope) => {
      let metadata = removedByScope.get(scope);
      if (!metadata) {
        metadata = { tuples: [] };
        removedByScope.set(scope, metadata);
      }
      return metadata;
    };
    const processedArrays = /* @__PURE__ */ new WeakSet();
    for (const [defIndex, def] of this.ctx.keys.entries()) {
      for (const scope of def.scopes ?? []) {
        const changeDesc = scopeChanges.get(scope);
        if (!changeDesc)
          continue;
        const keysArray = processedData.keys[defIndex]?.get(scope);
        if (!keysArray)
          continue;
        if (processedArrays.has(keysArray)) {
          const sourceScope = Array.from(processedData.keys[defIndex].entries()).find(
            ([_, arr]) => arr === keysArray
          )?.[0];
          if (sourceScope && sourceScope !== scope && removedByScope.has(sourceScope)) {
            removedByScope.set(scope, removedByScope.get(sourceScope));
          }
          continue;
        }
        processedArrays.add(keysArray);
        const insertionCache = insertionCaches.get(scope);
        const removedMetadata = ensureRemovedMetadata(scope);
        let removalCursor = 0;
        this.applyChangeDescWithCache(
          changeDesc,
          keysArray,
          insertionCache,
          (cached) => {
            const keyResult = cached?.keys.get(defIndex);
            return keyResult?.valid ? keyResult.value : def.invalidValue;
          },
          (removedValues) => {
            for (const value of removedValues) {
              if (!removedMetadata.tuples[removalCursor]) {
                removedMetadata.tuples[removalCursor] = new Array(this.ctx.keys.length);
              }
              removedMetadata.tuples[removalCursor][defIndex] = value;
              removalCursor += 1;
            }
          }
        );
      }
    }
    const removedKeyStrings = /* @__PURE__ */ new Map();
    for (const [scope, { tuples }] of removedByScope) {
      if (tuples.length === 0)
        continue;
      const scopeSet = /* @__PURE__ */ new Set();
      for (const tuple of tuples) {
        const keyValues = [];
        for (const [defIndex, value] of tuple.entries()) {
          const keyDef = this.ctx.keys[defIndex];
          if (!keyDef.scopes?.includes(scope))
            continue;
          keyValues.push(value);
        }
        if (keyValues.length > 0) {
          scopeSet.add(toKeyString(keyValues));
        }
      }
      removedKeyStrings.set(scope, scopeSet);
    }
    return removedKeyStrings;
  }
  /**
   * Transforms columns arrays using cached insertion results.
   */
  transformColumnsArrays(processedData, scopeChanges, insertionCaches) {
    this.transformArraysWithCache(
      this.ctx.values,
      scopeChanges,
      insertionCaches,
      (defIndex) => processedData.columns[defIndex],
      (def) => [first(def.scopes)],
      (cached, def, defIndex) => {
        if (cached) {
          if (cached.hasInvalidKey) {
            return def.invalidValue;
          }
          const valueResult = cached.values.get(defIndex);
          return valueResult?.valid ? valueResult.value : def.invalidValue;
        }
        return def.invalidValue;
      }
    );
  }
  /**
   * Helper to transform a scope-based invalidity map.
   */
  transformInvalidityMap(invalidityMap, scopeChanges, insertionCaches, extractValue) {
    const processedArrays = /* @__PURE__ */ new Set();
    for (const [scope, changeDesc] of scopeChanges) {
      let array2 = invalidityMap.get(scope);
      if (!array2) {
        const insertionCache2 = insertionCaches.get(scope);
        const hasAnyInvalid = insertionCache2 && Array.from(insertionCache2.values()).some(extractValue);
        if (hasAnyInvalid) {
          array2 = createArray(changeDesc.indexMap.originalLength, false);
          invalidityMap.set(scope, array2);
        } else {
          continue;
        }
      }
      if (processedArrays.has(array2))
        continue;
      processedArrays.add(array2);
      const insertionCache = insertionCaches.get(scope);
      this.applyChangeDescWithCache(
        changeDesc,
        array2,
        insertionCache,
        (cached, _destIndex) => extractValue(cached)
      );
    }
  }
  /**
   * Transforms invalidity arrays using cached insertion results.
   */
  transformInvalidityArrays(processedData, scopeChanges, insertionCaches) {
    if (processedData.invalidKeys) {
      this.transformInvalidityMap(
        processedData.invalidKeys,
        scopeChanges,
        insertionCaches,
        (cached) => cached?.hasInvalidKey ?? false
      );
    }
    if (processedData.invalidData) {
      this.transformInvalidityMap(
        processedData.invalidData,
        scopeChanges,
        insertionCaches,
        (cached) => cached ? cached.hasInvalidKey || cached.hasInvalidValue : false
      );
    }
  }
  /**
   * Applies a change description to an array using the provided cache-aware extractor.
   * Shared by array transformation helpers to keep update logic consistent.
   */
  applyChangeDescWithCache(changeDesc, target, insertionCache, extractValue, onRemove) {
    changeDesc.applyToArray(
      target,
      (destIndex) => {
        const cached = insertionCache?.get(destIndex);
        return extractValue(cached, destIndex);
      },
      onRemove
    );
    const updatedIndices = changeDesc.getUpdatedIndices();
    if (updatedIndices.length === 0)
      return;
    for (const destIndex of updatedIndices) {
      if (destIndex < 0 || destIndex >= target.length) {
        continue;
      }
      const cached = insertionCache?.get(destIndex);
      target[destIndex] = extractValue(cached, destIndex);
    }
  }
  /**
   * Transforms the groups array for grouped data during reprocessing.
   * Only called when groupsUnique=true and no invalid keys exist.
   *
   * This maintains the invariant: groups[i] corresponds to datum at columns[i].
   */
  transformGroupsArray(processedData, scopeChanges, insertionCaches) {
    const scope = first(processedData.scopes);
    const changeDesc = scopeChanges.get(scope);
    if (!changeDesc)
      return;
    const insertionCache = insertionCaches.get(scope);
    for (const [, cached] of insertionCache ?? []) {
      if (cached.hasInvalidKey) {
        throw new Error(
          "AG Charts - reprocessing grouped data with invalid keys not supported. This typically indicates a data quality issue that requires full reprocessing."
        );
      }
    }
    changeDesc.applyToArray(processedData.groups, (destIndex) => {
      return this.createDataGroupForInsertion(destIndex, processedData, scope, insertionCache);
    });
    const updatedIndices = changeDesc.getUpdatedIndices();
    if (updatedIndices.length > 0) {
      for (const destIndex of updatedIndices) {
        if (destIndex < 0 || destIndex >= processedData.groups.length) {
          continue;
        }
        processedData.groups[destIndex] = this.createDataGroupForInsertion(
          destIndex,
          processedData,
          scope,
          insertionCache
        );
      }
    }
  }
  /**
   * Creates a new DataGroup for an inserted datum during reprocessing.
   *
   * When groupsUnique=true and no invalid keys exist, each datum has:
   * - A unique set of keys
   * - datumIndices[columnIdx] = [0] (relative offset is always 0)
   * - All scopes are valid initially (unless invalid value detected)
   */
  createDataGroupForInsertion(datumIndex, processedData, scope, insertionCache) {
    const keys = [];
    for (const keysMap of processedData.keys) {
      const scopeKeys = keysMap.get(scope);
      if (scopeKeys) {
        keys.push(scopeKeys[datumIndex]);
      }
    }
    const firstGroup = processedData.groups[0];
    const allZeroDatumIndices = () => Object.freeze(createArray(processedData.columnScopes.length, SHARED_ZERO_INDICES));
    const datumIndices = firstGroup?.datumIndices ?? allZeroDatumIndices();
    const cached = insertionCache?.get(datumIndex);
    const hasInvalidValue = cached?.hasInvalidValue ?? false;
    let validScopes;
    if (hasInvalidValue) {
      validScopes = new Set(processedData.scopes);
      validScopes.delete(scope);
    } else {
      validScopes = processedData.scopes;
    }
    return {
      keys,
      datumIndices,
      aggregation: [],
      // Empty - we don't support aggregates in reprocessing yet
      validScopes
    };
  }
  /**
   * Generates diff metadata for animations and incremental rendering.
   * This is an opt-in feature - only runs if diff tracking is already initialized.
   */
  generateDiffMetadata(processedData, scopeChanges, removedKeys) {
    const getKeyString = (scope, datumIndex) => {
      const keys = [];
      for (const keysMap of processedData.keys) {
        const scopeKeys = keysMap.get(scope);
        if (!scopeKeys)
          return void 0;
        keys.push(scopeKeys[datumIndex]);
      }
      return keys.length > 0 ? toKeyString(keys) : void 0;
    };
    for (const [scope, changeDesc] of scopeChanges) {
      const diff9 = {
        changed: true,
        added: /* @__PURE__ */ new Set(),
        removed: removedKeys.get(scope) ?? /* @__PURE__ */ new Set(),
        updated: /* @__PURE__ */ new Set(),
        moved: /* @__PURE__ */ new Set()
      };
      for (const op of changeDesc.indexMap.spliceOps) {
        if (op.insertCount > 0) {
          for (let i = 0; i < op.insertCount; i++) {
            const datumIndex = op.index + i;
            const keyStr = getKeyString(scope, datumIndex);
            if (keyStr) {
              diff9.added.add(keyStr);
            }
          }
        }
      }
      const { originalLength, totalPrependCount } = changeDesc.indexMap;
      if (isAppendOnly(changeDesc.indexMap)) {
      } else if (isPrependOnly(changeDesc.indexMap) && originalLength > 0) {
        for (let destIndex = totalPrependCount; destIndex < totalPrependCount + originalLength; destIndex++) {
          const keyStr = getKeyString(scope, destIndex);
          if (keyStr)
            diff9.moved.add(keyStr);
        }
      } else if (hasNoRemovals(changeDesc.indexMap) && totalPrependCount > 0) {
        for (let sourceIndex = 0; sourceIndex < originalLength; sourceIndex++) {
          const destIndex = sourceIndex + totalPrependCount;
          const keyStr = getKeyString(scope, destIndex);
          if (keyStr)
            diff9.moved.add(keyStr);
        }
      } else {
        changeDesc.forEachPreservedIndex((sourceIndex, destIndex) => {
          if (sourceIndex !== destIndex) {
            const keyStr = getKeyString(scope, destIndex);
            if (keyStr)
              diff9.moved.add(keyStr);
          }
        });
      }
      processedData.reduced.diff[scope] = diff9;
    }
  }
  /**
   * Updates metadata after array transformations.
   * Uses intelligent cache management based on change patterns.
   */
  updateProcessedDataMetadata(processedData) {
    let maxDataLength = 0;
    for (const dataSet of processedData.dataSources.values()) {
      maxDataLength = Math.max(maxDataLength, dataSet.data.length);
    }
    processedData.input.count = maxDataLength;
    let partialValidDataCount = 0;
    for (const [scope, invalidData] of processedData.invalidData ?? /* @__PURE__ */ new Map()) {
      const invalidKeys = processedData.invalidKeys?.get(scope);
      for (let i = 0; i < invalidData.length; i++) {
        if (invalidData[i] && !invalidKeys?.[i]) {
          partialValidDataCount += 1;
        }
      }
    }
    processedData.partialValidDataCount = partialValidDataCount;
    this.recountInvalid(processedData.invalidKeys, processedData.invalidKeyCount);
    this.recountInvalid(processedData.invalidData, processedData.invalidDataCount);
    this.invalidateCachesForChanges(processedData);
  }
  /**
   * Updates sort order entry incrementally for appended values.
   * Checks if new values maintain the existing ordering/uniqueness.
   */
  updateSortOrderForAppend(entry, lastExistingValue, appendedValues) {
    if (appendedValues.length === 0)
      return;
    const toNumeric = (v) => {
      if (typeof v === "number")
        return v;
      if (v instanceof Date)
        return v.valueOf();
      return void 0;
    };
    let lastValue = toNumeric(lastExistingValue);
    const existingSortOrder = entry.sortOrder;
    for (const value of appendedValues) {
      const numericValue = toNumeric(value);
      if (numericValue === void 0)
        continue;
      if (lastValue === void 0) {
        lastValue = numericValue;
        continue;
      }
      const diff9 = numericValue - lastValue;
      if (diff9 === 0) {
        entry.isUnique = false;
      }
      if (entry.sortOrder !== void 0) {
        let direction = 0;
        if (diff9 > 0) {
          direction = 1;
        } else if (diff9 < 0) {
          direction = -1;
        }
        if (direction !== 0 && direction !== existingSortOrder) {
          entry.sortOrder = void 0;
        }
      }
      lastValue = numericValue;
    }
  }
  /**
   * Updates KEY_SORT_ORDERS incrementally after an append operation.
   */
  updateKeySortOrdersForAppend(processedData, originalLength) {
    for (const [keyDefIndex, keysMap] of processedData.keys.entries()) {
      const sortOrderEntry = processedData[KEY_SORT_ORDERS].get(keyDefIndex);
      if (!sortOrderEntry)
        continue;
      const keysArray = first(keysMap.values());
      if (!keysArray || keysArray.length <= originalLength)
        continue;
      const lastExistingValue = originalLength > 0 ? keysArray[originalLength - 1] : void 0;
      const appendedValues = keysArray.slice(originalLength);
      this.updateSortOrderForAppend(sortOrderEntry, lastExistingValue, appendedValues);
    }
  }
  /**
   * Invalidates sort order metadata BEFORE domain recomputation.
   *
   * This must be called BEFORE recomputeDomains() so that BandedDomain.setSortOrderMetadata()
   * receives the correct (possibly cleared) metadata. Without this, rolling window operations
   * would see stale sort order data and incorrectly configure sub-domains for sorted mode.
   *
   * @param anyKeyChanged - Whether any key values changed during update processing
   */
  invalidateSortOrdersForChanges(processedData, scopeChanges) {
    const changeDescs = uniqueChangeDescriptions(scopeChanges);
    let preserveSortOrders = true;
    let hasAppendOnly = false;
    let hasRollingWindow = false;
    let appendOriginalLength;
    let rollingWindowInfo;
    for (const changeDesc of changeDescs) {
      const { indexMap } = changeDesc;
      if (isUpdateOnly(indexMap)) {
      } else if (isAppendOnly(indexMap)) {
        hasAppendOnly = true;
        appendOriginalLength = indexMap.originalLength;
      } else if (hasOnlyRemovals(indexMap)) {
      } else if (isRollingWindow(indexMap)) {
        hasRollingWindow = true;
        rollingWindowInfo = {
          originalLength: indexMap.originalLength,
          removedCount: indexMap.removedIndices.size
        };
      } else {
        preserveSortOrders = false;
      }
    }
    if (!preserveSortOrders) {
      processedData[KEY_SORT_ORDERS].clear();
      processedData[COLUMN_SORT_ORDERS].clear();
    } else if (hasAppendOnly && appendOriginalLength !== void 0) {
      this.updateKeySortOrdersForAppend(processedData, appendOriginalLength);
    } else if (hasRollingWindow && rollingWindowInfo) {
      this.updateKeySortOrdersForRollingWindow(processedData, rollingWindowInfo);
    }
  }
  /**
   * Updates KEY_SORT_ORDERS incrementally after a rolling window operation.
   * Rolling window = contiguous removals at start + appends at end.
   */
  updateKeySortOrdersForRollingWindow(processedData, info) {
    const { originalLength, removedCount } = info;
    for (const [keyDefIndex, keysMap] of processedData.keys.entries()) {
      const sortOrderEntry = processedData[KEY_SORT_ORDERS].get(keyDefIndex);
      if (!sortOrderEntry)
        continue;
      const keysArray = first(keysMap.values());
      if (!keysArray || keysArray.length === 0)
        continue;
      const appendStartIndex = originalLength - removedCount;
      const lastRemainingValue = appendStartIndex > 0 ? keysArray[appendStartIndex - 1] : void 0;
      const appendedValues = keysArray.slice(appendStartIndex);
      this.updateSortOrderForAppend(sortOrderEntry, lastRemainingValue, appendedValues);
    }
  }
  /**
   * Invalidates domain range caches after domain recomputation.
   *
   * Called AFTER recomputeDomains() to mark domain ranges as dirty for lazy rebuild.
   * Sort order invalidation is handled separately by invalidateSortOrdersForChanges().
   */
  invalidateCachesForChanges(processedData) {
    this.markDomainRangesDirty(processedData[DOMAIN_RANGES]);
  }
  /**
   * Marks all RangeLookup entries as dirty for lazy rebuild.
   */
  markDomainRangesDirty(domainRanges) {
    for (const rangeLookup of domainRanges.values()) {
      rangeLookup.isDirty = true;
    }
  }
  /**
   * Recounts invalid entries for the given map into the provided counts map.
   */
  recountInvalid(invalidMap, counts) {
    if (!invalidMap || !counts)
      return;
    for (const [scope, invalidArray] of invalidMap) {
      const invalidCount = invalidArray.filter(Boolean).length;
      if (invalidCount === 0) {
        invalidMap.delete(scope);
        counts.delete(scope);
      } else {
        counts.set(scope, invalidCount);
      }
    }
  }
  /**
   * Recomputes processor outputs using their incrementalCalculate hook when available.
   * Falls back to calculate to avoid stale reducer outputs if a processor lacks the hook.
   */
  reprocessProcessors(processedData) {
    if (this.ctx.processors.length === 0)
      return;
    processedData.reduced ?? (processedData.reduced = {});
    for (const def of this.ctx.processors) {
      const previousValue = processedData.reduced[def.property];
      const nextValue = def.incrementalCalculate?.(processedData, previousValue) ?? def.calculate(processedData, previousValue);
      processedData.reduced[def.property] = nextValue;
    }
  }
  /**
   * Helper to get unique DataSets from processed data.
   */
  getUniqueDataSets(processedData) {
    return new Set(processedData.dataSources.values());
  }
};

// packages/ag-charts-community/src/chart/data/rangeLookup.ts
var MIN = 0;
var MAX = 1;
var SPAN = 2;
var RangeLookup = class _RangeLookup {
  constructor(allValues) {
    /** When true, the lookup needs to be rebuilt before use */
    this.isDirty = false;
    const dataLength = allValues.reduce((acc, v) => Math.max(acc, v.length), 0);
    const { maxLevelSize, buffer } = _RangeLookup.createBuffer(dataLength);
    this.maxLevelSize = maxLevelSize;
    this.buffer = buffer;
    this.dataLength = dataLength;
    this.populateBuffer(allValues);
  }
  static computeMaxLevelSize(dataLength) {
    const sizePower = 32 - Math.clz32(dataLength);
    let maxLevelSize = 1 << sizePower;
    if (dataLength === maxLevelSize / 2) {
      maxLevelSize = maxLevelSize >>> 1;
    }
    return maxLevelSize;
  }
  static createBuffer(dataLength) {
    const maxLevelSize = _RangeLookup.computeMaxLevelSize(dataLength);
    const buffer = new Float64Array((maxLevelSize * 2 - 1) * 2).fill(Number.NaN);
    return { maxLevelSize, buffer };
  }
  populateBuffer(allValues) {
    const { maxLevelSize, buffer } = this;
    const leafOffset = maxLevelSize - 1;
    for (const values of allValues) {
      const valuesLength = values.length;
      for (let i = 0; i < valuesLength; i += 1) {
        const value = Number(values[i]);
        if (value !== value)
          continue;
        const bufferOffset = leafOffset + i << 1;
        const prevMin = buffer[bufferOffset];
        const prevMax = buffer[bufferOffset + 1];
        if (prevMin !== prevMin || value < prevMin) {
          buffer[bufferOffset] = value;
        }
        if (prevMax !== prevMax || value > prevMax) {
          buffer[bufferOffset + 1] = value;
        }
      }
    }
    for (let size = maxLevelSize >>> 1; size >= 1; size >>>= 1) {
      const start2 = size - 1;
      const childStart = start2 + size << 1;
      let nodeOffset = start2 << 1;
      let leftOffset = childStart;
      for (let i = 0; i < size; i += 1) {
        const rightOffset = leftOffset + 2;
        const aMin = buffer[leftOffset];
        const bMin = buffer[rightOffset];
        buffer[nodeOffset] = bMin !== bMin || aMin < bMin ? aMin : bMin;
        const aMax = buffer[leftOffset + 1];
        const bMax = buffer[rightOffset + 1];
        buffer[nodeOffset + 1] = bMax !== bMax || aMax > bMax ? aMax : bMax;
        nodeOffset += 2;
        leftOffset += 4;
      }
    }
  }
  /**
   * Rebuild the segment tree with new values, reusing the buffer if possible.
   * Only allocates a new buffer if the data length requires a different maxLevelSize.
   */
  rebuild(allValues) {
    const dataLength = allValues.reduce((acc, v) => Math.max(acc, v.length), 0);
    const requiredMaxLevelSize = _RangeLookup.computeMaxLevelSize(dataLength);
    if (requiredMaxLevelSize === this.maxLevelSize) {
      this.buffer.fill(Number.NaN);
    } else {
      const { maxLevelSize, buffer } = _RangeLookup.createBuffer(dataLength);
      this.maxLevelSize = maxLevelSize;
      this.buffer = buffer;
    }
    this.dataLength = dataLength;
    this.populateBuffer(allValues);
  }
  /**
   * Update values at a specific data index - O(k log n) where k is number of columns.
   * After updating the leaf, propagates changes up to the root.
   *
   * @param dataIndex - Index in the data array (0-based)
   * @param newValues - New values for this index from all columns
   */
  updateValue(dataIndex, newValues) {
    const { maxLevelSize, buffer } = this;
    const bufferIndex = maxLevelSize + dataIndex - 1;
    const bufferMinIndex = Math.trunc(bufferIndex * SPAN) + MIN;
    const bufferMaxIndex = Math.trunc(bufferIndex * SPAN) + MAX;
    buffer[bufferMinIndex] = Number.NaN;
    buffer[bufferMaxIndex] = Number.NaN;
    for (const value of newValues) {
      const numValue = Number(value);
      const prevMin = buffer[bufferMinIndex];
      const prevMax = buffer[bufferMaxIndex];
      if (!Number.isFinite(prevMin) || numValue < prevMin) {
        buffer[bufferMinIndex] = numValue;
      }
      if (!Number.isFinite(prevMax) || numValue > prevMax) {
        buffer[bufferMaxIndex] = numValue;
      }
    }
    this.propagateUp(bufferIndex);
  }
  /**
   * Batch update multiple values - O(k log n) per update.
   * More efficient than individual updateValue calls when tracking dirty nodes.
   *
   * @param updates - Array of {index, values} pairs to update
   */
  updateValues(updates) {
    for (const { index, values } of updates) {
      this.updateValue(index, values);
    }
  }
  /**
   * Propagate min/max changes from a leaf up to the root.
   * Each level recalculates its min/max from its children.
   */
  propagateUp(bufferIndex) {
    const { buffer } = this;
    while (bufferIndex > 0) {
      const parentIndex = Math.trunc((bufferIndex - 1) / 2);
      const leftChild = 2 * parentIndex + 1;
      const rightChild = 2 * parentIndex + 2;
      const leftMin = buffer[Math.trunc(leftChild * SPAN) + MIN];
      const leftMax = buffer[Math.trunc(leftChild * SPAN) + MAX];
      const rightMin = buffer[Math.trunc(rightChild * SPAN) + MIN];
      const rightMax = buffer[Math.trunc(rightChild * SPAN) + MAX];
      buffer[Math.trunc(parentIndex * SPAN) + MIN] = !Number.isFinite(rightMin) || leftMin < rightMin ? leftMin : rightMin;
      buffer[Math.trunc(parentIndex * SPAN) + MAX] = !Number.isFinite(rightMax) || leftMax > rightMax ? leftMax : rightMax;
      bufferIndex = parentIndex;
    }
  }
  computeRangeInto(buffer, start2, end3, bufferIndex, currentStart, step, into) {
    const currentEnd = currentStart + step - 1;
    if (currentEnd < start2 || currentStart >= end3)
      return into;
    if (currentStart >= start2 && currentEnd < end3) {
      const min = buffer[Math.trunc(bufferIndex * SPAN) + MIN];
      const max = buffer[Math.trunc(bufferIndex * SPAN) + MAX];
      if (Number.isFinite(min))
        into[0] = Math.min(into[0], min);
      if (Number.isFinite(max))
        into[1] = Math.max(into[1], max);
    } else if (step > 1) {
      bufferIndex = Math.trunc(bufferIndex * 2);
      step = Math.trunc(step / 2);
      this.computeRangeInto(buffer, start2, end3, Math.trunc(bufferIndex + 1), currentStart, step, into);
      this.computeRangeInto(buffer, start2, end3, Math.trunc(bufferIndex + 2), currentStart + step, step, into);
    }
    return into;
  }
  rangeBetween(start2, end3, into) {
    const result = into ?? [0, 0];
    if (start2 > end3) {
      result[0] = Number.NaN;
      result[1] = Number.NaN;
      return result;
    }
    const { maxLevelSize, buffer } = this;
    result[0] = Infinity;
    result[1] = -Infinity;
    this.computeRangeInto(buffer, start2, end3, 0, 0, maxLevelSize, result);
    return result;
  }
  getRange(into) {
    const { buffer } = this;
    const result = into ?? [0, 0];
    result[0] = buffer[MIN];
    result[1] = buffer[MAX];
    return result;
  }
  get range() {
    const { buffer } = this;
    return [buffer[MIN], buffer[MAX]];
  }
  /** The number of data elements in the segment tree */
  get length() {
    return this.dataLength;
  }
};

// packages/ag-charts-community/src/chart/data/sortOrder.ts
function valuesSortOrder(values, needsValueOf) {
  const valuesLength = values.length;
  if (values.length <= 1)
    return 1;
  let order = 0;
  let v0 = values[0];
  for (let i = 1; i < valuesLength; i++) {
    const v1 = values[i];
    if (v1 == null)
      continue;
    const primitive = needsValueOf ? v1.valueOf() : v1;
    if (typeof primitive !== "number")
      return;
    const diff9 = Math.sign(v1 - v0);
    if (diff9 !== 0) {
      if (order !== 0 && order !== diff9)
        return;
      order = diff9;
    }
    v0 = v1;
  }
  return order === 0 ? 1 : order;
}

// packages/ag-charts-community/src/chart/data/data-model/utils/resolvers.ts
var DataModelResolvers = class {
  constructor(ctx) {
    this.ctx = ctx;
    this.rangeBetweenBuffer = [0, 0];
  }
  resolveMissingDataCount(scope) {
    let missingDataCount = 0;
    for (const value of this.ctx.values) {
      missingDataCount = Math.max(missingDataCount, value.missing.get(scope.id) ?? 0);
    }
    return missingDataCount;
  }
  resolveProcessedDataDefById(scope, searchId) {
    const def = this.ctx.scopeCache.get(scope.id)?.get(searchId);
    if (!def) {
      throw new Error(`AG Charts - didn't find property definition for [${searchId}, ${scope.id}]`);
    }
    return { index: def.index, def };
  }
  resolveProcessedDataIndexById(scope, searchId) {
    return this.resolveProcessedDataDefById(scope, searchId).index;
  }
  resolveKeysById(scope, searchId, processedData) {
    const index = this.resolveProcessedDataIndexById(scope, searchId);
    const keys = processedData.keys[index];
    if (keys == null) {
      throw new Error(`AG Charts - didn't find keys for [${searchId}, ${scope.id}]`);
    }
    return keys.get(scope.id);
  }
  hasColumnById(scope, searchId) {
    return this.ctx.scopeCache.get(scope.id)?.get(searchId) != null;
  }
  resolveColumnById(scope, searchId, processedData) {
    const index = this.resolveProcessedDataIndexById(scope, searchId);
    const column = processedData.columns?.[index];
    if (column == null) {
      throw new Error(`AG Charts - didn't find column for [${searchId}, ${scope.id}]`);
    }
    return column;
  }
  resolveColumnNeedsValueOf(scope, searchId, processedData) {
    const index = this.resolveProcessedDataIndexById(scope, searchId);
    return processedData.columnNeedValueOf?.[index] ?? true;
  }
  /**
   * Converts a relative datum index to an absolute column index.
   *
   * INDEXING STRATEGY:
   * - Relative index: Offset from the start of a group (stored in datumIndices)
   * - Absolute index: Position in the full column array
   * - Conversion: absoluteIndex = groupIndex + relativeIndex
   *
   * When groupsUnique=true, relativeIndex is always 0, making this a simple
   * identity mapping. This optimization reduces memory usage significantly
   * for large datasets with unique keys.
   *
   * @param groupIndex index of the group in ProcessedData.groups
   * @param relativeDatumIndex relative index stored in group.datumIndices
   * @returns absolute index for accessing columns
   */
  resolveAbsoluteIndex(groupIndex, relativeDatumIndex) {
    return groupIndex + relativeDatumIndex;
  }
  getDomain(scope, searchId, type, processedData) {
    const domains = this.getDomainsByType(type ?? "value", processedData);
    return domains?.[this.resolveProcessedDataIndexById(scope, searchId)] ?? [];
  }
  getDomainBetweenRange(scope, searchIds, [i0, i1], processedData) {
    const columnIndices = searchIds.map((searchId) => this.resolveProcessedDataIndexById(scope, searchId));
    const dataLength = processedData.input.count;
    if (i0 <= 0 && i1 >= dataLength) {
      const domains = processedData.domain.values;
      let min = Infinity;
      let max = -Infinity;
      for (const columnIndex of columnIndices) {
        const domain = domains[columnIndex];
        if (domain != null) {
          if (domain[0] < min)
            min = domain[0];
          if (domain[1] > max)
            max = domain[1];
        }
      }
      this.rangeBetweenBuffer[0] = min;
      this.rangeBetweenBuffer[1] = max;
      return this.rangeBetweenBuffer;
    }
    const cacheKey = columnIndices.join(":");
    const domainRanges = processedData[DOMAIN_RANGES];
    const values = columnIndices.map((columnIndex) => processedData.columns[columnIndex]);
    let rangeLookup = domainRanges.get(cacheKey);
    if (rangeLookup == null) {
      rangeLookup = new RangeLookup(values);
      domainRanges.set(cacheKey, rangeLookup);
    } else if (rangeLookup.isDirty) {
      rangeLookup.rebuild(values);
      rangeLookup.isDirty = false;
    }
    return rangeLookup.rangeBetween(i0, i1, this.rangeBetweenBuffer);
  }
  getSortOrder(values, index, sortOrders, needsValueOf) {
    const entry = sortOrders.get(index);
    if (entry == null || entry.isDirty) {
      const newEntry = { sortOrder: valuesSortOrder(values, needsValueOf) };
      sortOrders.set(index, newEntry);
      return newEntry.sortOrder;
    }
    return entry.sortOrder;
  }
  getKeySortOrder(scope, searchId, processedData) {
    const columnIndex = this.resolveProcessedDataIndexById(scope, searchId);
    const keys = processedData.keys[columnIndex]?.get(scope.id);
    return keys ? this.getSortOrder(keys, columnIndex, processedData[KEY_SORT_ORDERS], true) : void 0;
  }
  getKeySortEntry(scope, searchId, processedData) {
    const columnIndex = this.resolveProcessedDataIndexById(scope, searchId);
    const entry = processedData[KEY_SORT_ORDERS].get(columnIndex);
    return entry?.isDirty ? void 0 : entry;
  }
  getColumnSortOrder(scope, searchId, processedData) {
    const columnIndex = this.resolveProcessedDataIndexById(scope, searchId);
    const needsValueOf = processedData.columnNeedValueOf?.[columnIndex] ?? true;
    return this.getSortOrder(
      processedData.columns[columnIndex],
      columnIndex,
      processedData[COLUMN_SORT_ORDERS],
      needsValueOf
    );
  }
  getDomainsByType(type, processedData) {
    switch (type) {
      case "key":
        return processedData.domain.keys;
      case "value":
        return processedData.domain.values;
      case "aggregate":
        return processedData.domain.aggValues;
      case "group-value-processor":
        return processedData.domain.groups;
      default:
        return null;
    }
  }
};

// packages/ag-charts-community/src/chart/data/data-model/utils/scopeCache.ts
var ScopeCacheManager = class {
  constructor(ctx) {
    this.ctx = ctx;
  }
  processScopeCache() {
    this.ctx.scopeCache.clear();
    for (const def of iterate(this.ctx.keys, this.ctx.values, this.ctx.aggregates)) {
      if (!def.idsMap)
        continue;
      for (const [scope, ids] of def.idsMap) {
        for (const id of ids) {
          if (!this.ctx.scopeCache.has(scope)) {
            this.ctx.scopeCache.set(scope, /* @__PURE__ */ new Map([[id, def]]));
          } else if (this.ctx.scopeCache.get(scope)?.has(id)) {
            throw new Error("duplicate definition ids on the same scope are not allowed.");
          } else {
            this.ctx.scopeCache.get(scope).set(id, def);
          }
        }
      }
    }
  }
  valueGroupIdxLookup({ matchGroupIds }) {
    const result = [];
    for (const [index, def] of this.ctx.values.entries()) {
      if (!matchGroupIds || def.groupId && matchGroupIds.includes(def.groupId)) {
        result.push(index);
      }
    }
    return result;
  }
  valueIdxLookup(scopes, prop) {
    const noScopesToMatch = scopes == null || scopes.length === 0;
    const propId = typeof prop === "string" ? prop : prop.id;
    const hasMatchingScopeId = (def) => {
      if (def.idsMap) {
        for (const [scope, ids] of def.idsMap) {
          if (scopes?.includes(scope) && ids.has(propId)) {
            return true;
          }
        }
      }
      return false;
    };
    const result = this.ctx.values.reduce((res, def, index) => {
      const validDefScopes = def.scopes == null || noScopesToMatch && !def.scopes.length || def.scopes.some((s) => scopes?.includes(s));
      if (validDefScopes && (def.property === propId || def.id === propId || hasMatchingScopeId(def))) {
        res.push(index);
      }
      return res;
    }, []);
    if (result.length === 0) {
      throw new Error(
        `AG Charts - configuration error, unknown property ${JSON.stringify(prop)} in scope(s) ${JSON.stringify(
          scopes
        )}`
      );
    }
    return result;
  }
  buildAccessors(defs) {
    const result = /* @__PURE__ */ new Map();
    if (this.ctx.suppressFieldDotNotation) {
      return result;
    }
    for (const def of defs) {
      const isPath = def.property.includes(".") || def.property.includes("[");
      if (!isPath)
        continue;
      const components = getPathComponents(def.property);
      if (components == null) {
        logger_exports.warnOnce("Invalid property path [%s]", def.property);
        continue;
      }
      const accessor = createPathAccessor(components);
      result.set(def.property, accessor);
    }
    return result;
  }
};

// packages/ag-charts-community/src/chart/data/dataModel.ts
var DataModel = class {
  constructor(opts, mode = "standalone", suppressFieldDotNotation = false, eventsHub) {
    this.opts = opts;
    this.mode = mode;
    this.suppressFieldDotNotation = suppressFieldDotNotation;
    this.eventsHub = eventsHub;
    this.debug = debugLogger_exports.create(true, "data-model");
    this.scopeCache = /* @__PURE__ */ new Map();
    this.keys = [];
    this.values = [];
    this.aggregates = [];
    this.groupProcessors = [];
    this.propertyProcessors = [];
    this.reducers = [];
    this.processors = [];
    let keys = true;
    for (const next of opts.props) {
      if (next.type === "key" && !keys) {
        throw new Error("AG Charts - internal config error: keys must come before values.");
      }
      if (next.type === "value" && keys) {
        keys = false;
      }
    }
    const verifyMatchGroupId = ({ matchGroupIds = [] }) => {
      for (const matchGroupId of matchGroupIds) {
        if (this.values.every((def) => def.groupId !== matchGroupId)) {
          throw new Error(
            `AG Charts - internal config error: matchGroupIds properties must match defined groups (${matchGroupId}).`
          );
        }
      }
    };
    const keyScopes = /* @__PURE__ */ new Set();
    const valueScopes = /* @__PURE__ */ new Set();
    for (const def of opts.props) {
      const scopes = def.type === "key" ? keyScopes : valueScopes;
      if (isScoped(def)) {
        if (def.scopes) {
          for (const s of def.scopes) {
            scopes.add(s);
          }
        }
      }
      switch (def.type) {
        case "key":
          this.keys.push({ ...def, index: this.keys.length, missing: /* @__PURE__ */ new Map() });
          break;
        case "value":
          if (def.property == null) {
            throw new Error(
              `AG Charts - internal config error: no properties specified for value definitions: ${JSON.stringify(
                def
              )}`
            );
          }
          this.values.push({ ...def, index: this.values.length, missing: /* @__PURE__ */ new Map() });
          break;
        case "aggregate":
          verifyMatchGroupId(def);
          this.aggregates.push({ ...def, index: this.aggregates.length });
          break;
        case "group-value-processor":
          verifyMatchGroupId(def);
          this.groupProcessors.push({ ...def, index: this.groupProcessors.length });
          break;
        case "property-value-processor":
          this.propertyProcessors.push({ ...def, index: this.propertyProcessors.length });
          break;
        case "reducer":
          this.reducers.push({ ...def, index: this.reducers.length });
          break;
        case "processor":
          this.processors.push({ ...def, index: this.processors.length });
          break;
      }
    }
    if (!!this.opts.groupByKeys || this.opts.groupByFn != null) {
      const ungroupedScopes = new Set(valueScopes.values());
      for (const s of keyScopes) {
        ungroupedScopes.delete(s);
      }
      if (ungroupedScopes.size > 0) {
        throw new Error(
          `AG Charts - scopes missing key for grouping, illegal configuration: ${[...ungroupedScopes.values()]}`
        );
      }
    }
    const ctx = {
      keys: this.keys,
      values: this.values,
      aggregates: this.aggregates,
      groupProcessors: this.groupProcessors,
      propertyProcessors: this.propertyProcessors,
      reducers: this.reducers,
      processors: this.processors,
      debug: this.debug,
      mode: this.mode,
      bandingConfig: this.opts.domainBandingConfig,
      suppressFieldDotNotation: this.suppressFieldDotNotation,
      scopeCache: this.scopeCache
    };
    this.resolvers = new DataModelResolvers(ctx);
    this.scopeCacheManager = new ScopeCacheManager(ctx);
    this.domainInitializer = new DomainInitializer(ctx);
    this.domainManager = new DomainManager(ctx, this.domainInitializer, this.scopeCacheManager);
    this.reducerManager = new ReducerManager(this.opts.domainBandingConfig);
    this.dataExtractor = new DataExtractor(ctx, this.domainManager);
    this.dataGrouper = new DataGrouper(ctx);
    this.aggregator = new Aggregator(ctx, this.scopeCacheManager, this.resolvers);
    this.incrementalProcessor = new IncrementalProcessor(ctx, this.reducerManager);
  }
  resolveProcessedDataDefById(scope, searchId) {
    return this.resolvers.resolveProcessedDataDefById(scope, searchId);
  }
  resolveProcessedDataIndexById(scope, searchId) {
    return this.resolvers.resolveProcessedDataIndexById(scope, searchId);
  }
  resolveKeysById(scope, searchId, processedData) {
    return this.resolvers.resolveKeysById(scope, searchId, processedData);
  }
  hasColumnById(scope, searchId) {
    return this.resolvers.hasColumnById(scope, searchId);
  }
  resolveColumnById(scope, searchId, processedData) {
    return this.resolvers.resolveColumnById(scope, searchId, processedData);
  }
  resolveColumnNeedsValueOf(scope, searchId, processedData) {
    return this.resolvers.resolveColumnNeedsValueOf(scope, searchId, processedData);
  }
  resolveMissingDataCount(scope) {
    return this.resolvers.resolveMissingDataCount(scope);
  }
  /**
   * Provides a convenience iterator to iterate over all of the extract datum values in a
   * specific DataGroup.
   *
   * @param scope to which datums should belong
   * @param group containing the datums
   * @param processedData containing the group
   * @param groupIndex index of the group in processedData.groups
   */
  *forEachDatum(scope, processedData, group, groupIndex) {
    const columnIndex = processedData.columnScopes.findIndex((s) => s.has(scope.id));
    for (const relativeDatumIndex of group.datumIndices[columnIndex] ?? []) {
      const absoluteDatumIndex = this.resolvers.resolveAbsoluteIndex(groupIndex, relativeDatumIndex);
      yield processedData.columns[columnIndex][absoluteDatumIndex];
    }
  }
  getUniqueDataSets(processedData) {
    return new Set(processedData.dataSources.values());
  }
  /**
   * Provides a convenience iterator to iterate over all of the extracted datum values in a
   * GroupedData.
   *
   * @param scope to which datums should belong
   * @param processedData to iterate through
   */
  *forEachGroupDatum(scope, processedData) {
    const columnIndex = processedData.columnScopes.findIndex((s) => s.has(scope.id));
    const output = {
      groupIndex: 0,
      columnIndex
    };
    const empty = [];
    for (const group of processedData.groups) {
      output.group = group;
      for (const relativeDatumIndex of group.datumIndices[columnIndex] ?? empty) {
        output.datumIndex = this.resolvers.resolveAbsoluteIndex(output.groupIndex, relativeDatumIndex);
        yield output;
      }
      output.groupIndex++;
    }
  }
  getDomain(scope, searchId, type, processedData) {
    const domain = this.resolvers.getDomain(scope, searchId, type, processedData);
    if (type === "key" && domain.length > 0) {
      const sortMetadata = this.getKeySortMetadata(scope, searchId, processedData);
      return { domain, sortMetadata };
    }
    return { domain };
  }
  getDomainBetweenRange(scope, searchIds, [i0, i1], processedData) {
    return this.resolvers.getDomainBetweenRange(scope, searchIds, [i0, i1], processedData);
  }
  getKeySortOrder(scope, searchId, processedData) {
    return this.resolvers.getKeySortOrder(scope, searchId, processedData);
  }
  getColumnSortOrder(scope, searchId, processedData) {
    return this.resolvers.getColumnSortOrder(scope, searchId, processedData);
  }
  /**
   * Get sort metadata for a key column if available.
   * Returns undefined if metadata is not available, is dirty, or data is unsorted.
   */
  getKeySortMetadata(scope, searchId, processedData) {
    const entry = this.resolvers.getKeySortEntry(scope, searchId, processedData);
    if (entry?.sortOrder != null) {
      return { sortOrder: entry.sortOrder, isUnique: entry.isUnique };
    }
    return void 0;
  }
  processData(sources) {
    const {
      opts: { groupByKeys, groupByFn },
      aggregates,
      groupProcessors,
      reducers,
      processors,
      propertyProcessors
    } = this;
    const start2 = performance.now();
    if (groupByKeys && this.keys.length === 0) {
      return;
    }
    let processedData = this.extractData(sources);
    if (groupByKeys) {
      processedData = this.dataGrouper.groupData(processedData);
    } else if (groupByFn) {
      processedData = this.dataGrouper.groupData(processedData, groupByFn(processedData));
    }
    if (groupProcessors.length > 0 && processedData.type === "grouped") {
      this.aggregator.postProcessGroups(processedData);
    }
    if (aggregates.length > 0 && processedData.type === "ungrouped") {
      this.aggregator.aggregateUngroupedData(processedData);
    } else if (aggregates.length > 0 && processedData.type === "grouped") {
      this.aggregator.aggregateGroupedData(processedData);
    }
    if (propertyProcessors.length > 0) {
      this.postProcessProperties(processedData);
    }
    if (reducers.length > 0) {
      this.reduceData(processedData);
    }
    if (processors.length > 0) {
      this.postProcessData(processedData);
    }
    this.warnDataMissingProperties(sources);
    const end3 = performance.now();
    processedData.time = end3 - start2;
    processedData.version += 1;
    this.collectOptimizationMetadata(processedData, "full-process");
    if (this.debug.check()) {
      logProcessedData(processedData);
    }
    this.processScopeCache();
    return processedData;
  }
  /**
   * Determines if incremental reprocessing is supported for the given data.
   *
   * Reprocessing is supported when:
   * - For ungrouped data: No aggregates, reducers, processors, or property processors
   * - For grouped data: Additionally requires:
   *   - groupsUnique=true (each datum has unique keys)
   *   - Single data source (all scopes share same DataSet)
   *   - No invalid keys (to maintain groups.length === columns.length invariant)
   *   - All group processors support reprocessing
   *
   * When unsupported, falls back to full reprocessing automatically.
   *
   * @returns true if incremental reprocessing can be used, false otherwise
   */
  isReprocessingSupported(processedData) {
    return this.incrementalProcessor.isReprocessingSupported(processedData);
  }
  reprocessData(processedData, dataSets) {
    if (!this.isReprocessingSupported(processedData)) {
      if (this.debug.check()) {
        this.debug("Falling back to full reprocessing - incremental not supported for current configuration");
      }
      const uniqueDataSets = this.getUniqueDataSets(processedData);
      for (const dataSet of uniqueDataSets) {
        dataSet.commitPendingTransactions();
      }
      return this.processData(processedData.dataSources);
    }
    const { getProcessValue } = this.initDataDomainProcessor("skip");
    return this.incrementalProcessor.reprocessData(
      processedData,
      dataSets,
      getProcessValue,
      this.reprocessGroupProcessors.bind(this),
      this.recomputeDomains.bind(this),
      this.collectOptimizationMetadata.bind(this)
    );
  }
  /**
   * Recomputes domains from transformed arrays.
   * Uses BandedDomain optimization for continuous domains to avoid full rescans.
   */
  recomputeDomains(processedData) {
    this.domainManager.recomputeDomains(processedData);
  }
  warnDataMissingProperties(sources) {
    this.dataExtractor.warnDataMissingProperties(sources);
  }
  processScopeCache() {
    this.scopeCacheManager.processScopeCache();
  }
  valueGroupIdxLookup(selector) {
    return this.scopeCacheManager.valueGroupIdxLookup(selector);
  }
  valueIdxLookup(scopes, prop) {
    return this.scopeCacheManager.valueIdxLookup(scopes, prop);
  }
  extractData(sources) {
    return this.dataExtractor.extractData(sources);
  }
  /**
   * Reprocesses group processors for incremental updates.
   * Only processes newly inserted groups to avoid double-processing.
   * This is safe only when all group processors support reprocessing.
   * Deduplicates change descriptions to avoid processing the same groups multiple times
   * when multiple scopes share the same DataSet.
   */
  reprocessGroupProcessors(processedData, scopeChanges) {
    const { groupProcessors } = this;
    const { columns } = processedData;
    for (const processor of groupProcessors) {
      if (!processor.supportsReprocessing) {
        throw new Error(
          "AG Charts - attempted to reprocess group processor that does not support reprocessing. This is an internal error that should not occur."
        );
      }
    }
    const processedChangeDescs = uniqueChangeDescriptions(scopeChanges);
    for (const processor of groupProcessors) {
      const valueIndexes = this.valueGroupIdxLookup(processor);
      const adjustFn = processor.adjust()();
      for (const changeDesc of processedChangeDescs) {
        const { indexMap } = changeDesc;
        for (const op of indexMap.spliceOps) {
          if (op.insertCount > 0) {
            for (let i = 0; i < op.insertCount; i++) {
              const groupIndex = op.index + i;
              const dataGroup = processedData.groups[groupIndex];
              adjustFn(columns, valueIndexes, dataGroup, groupIndex);
            }
          }
        }
      }
    }
  }
  postProcessProperties(processedData) {
    for (const { adjust, property, scopes } of this.propertyProcessors) {
      for (const idx of this.valueIdxLookup(scopes, property)) {
        adjust()(processedData, idx);
      }
    }
  }
  reduceData(processedData) {
    processedData.reduced ?? (processedData.reduced = {});
    for (const def of this.reducers) {
      if (this.shouldUseReducerBanding(def, processedData)) {
        processedData.reduced[def.property] = this.reduceWithBands(
          def,
          processedData
        );
      } else {
        processedData.reduced[def.property] = this.reduceStandard(
          def,
          processedData
        );
      }
    }
  }
  shouldUseReducerBanding(def, processedData) {
    return processedData.type === "ungrouped" && def.supportsBanding === true && typeof def.combineResults === "function";
  }
  reduceWithBands(def, processedData) {
    const result = this.reducerManager.evaluate(def, processedData, {
      reuseCleanBands: false
    });
    if (result === void 0) {
      return this.reduceStandard(def, processedData);
    }
    return result;
  }
  reduceStandard(def, processedData) {
    const reducer = def.reducer();
    if (processedData.type === "grouped") {
      let accValue = def.initialValue;
      for (const group of processedData.groups) {
        accValue = reducer(accValue, group.keys);
      }
      return accValue;
    }
    const scopeId = isScoped(def) ? def.scopes[0] : first(processedData.scopes);
    if (scopeId == null) {
      return def.initialValue;
    }
    const rawData = processedData.dataSources.get(scopeId)?.data ?? [];
    const keyColumns = processedData.keys.map((column) => column.get(scopeId)).filter((column) => column != null);
    const keysParam = keyColumns.map(() => void 0);
    return ReducerManager.evaluateRange(def, reducer, { rawData, keyColumns, keysParam }, 0, rawData.length);
  }
  postProcessData(processedData) {
    processedData.reduced ?? (processedData.reduced = {});
    for (const def of this.processors) {
      processedData.reduced[def.property] = def.calculate(
        processedData,
        processedData.reduced[def.property]
      );
    }
    const { diff: diff9 } = processedData.reduced;
    if (diff9) {
      this.eventsHub?.emit("datamodel:diff", { diff: diff9 });
    }
  }
  initDataDomainProcessor(domainMode) {
    return this.domainManager.initDataDomainProcessor(domainMode);
  }
  /**
   * Collects optimization metadata for debugging purposes.
   * Only called when debug mode is enabled.
   */
  collectOptimizationMetadata(processedData, pathTaken) {
    const existingDomainBanding = processedData.optimizations?.domainBanding;
    const reducerBands = processedData[REDUCER_BANDS];
    if (this.reducers.length > 0 && reducerBands) {
      this.collectReducerBandingMetadata(processedData, reducerBands);
    }
    const reducerBanding = processedData.optimizations?.reducerBanding;
    processedData.optimizations = {
      performance: {
        processingTime: processedData.time,
        pathTaken
      },
      ...existingDomainBanding && { domainBanding: existingDomainBanding },
      ...reducerBanding && { reducerBanding }
    };
    const reprocessingSupported = this.isReprocessingSupported(processedData);
    const reprocessingApplied = pathTaken === "reprocess";
    let reprocessingReason;
    if (!reprocessingSupported) {
      const reasons = [];
      if (processedData.type === "grouped") {
        if (!processedData.groupsUnique) {
          reasons.push("groupsUnique=false");
        }
        const uniqueDataSets = this.getUniqueDataSets(processedData);
        if (uniqueDataSets.size !== 1) {
          reasons.push("multiple data sources");
        }
        const scope = first(processedData.scopes);
        const invalidKeys = processedData.invalidKeys?.get(scope);
        if (invalidKeys?.some((invalid) => invalid)) {
          reasons.push("has invalid keys");
        }
      }
      if (this.aggregates.length > 0) {
        reasons.push("has aggregates");
      }
      if (this.reducers.filter((r) => !r.supportsBanding).length > 0) {
        reasons.push("has reducers");
      }
      if (this.processors.filter((p) => p.incrementalCalculate === void 0).length > 0) {
        reasons.push("has processors");
      }
      if (this.propertyProcessors.length > 0) {
        reasons.push("has property processors");
      }
      reprocessingReason = reasons.length > 0 ? reasons.join(", ") : void 0;
    }
    processedData.optimizations.reprocessing = {
      applied: reprocessingApplied,
      reason: reprocessingReason
    };
    if (processedData.type === "grouped") {
      let sharedGroupCount = 0;
      const firstGroup = processedData.groups[0];
      if (firstGroup) {
        const sharedDatumIndices = firstGroup.datumIndices;
        for (const group of processedData.groups) {
          if (group.datumIndices === sharedDatumIndices) {
            sharedGroupCount++;
          }
        }
      }
      processedData.optimizations.sharedDatumIndices = {
        applied: sharedGroupCount > 0,
        sharedGroupCount,
        totalGroupCount: processedData.groups.length
      };
    }
  }
  /**
   * Collects reducer banding metadata for debugging purposes.
   * Tracks which reducers used banding and their performance stats.
   */
  collectReducerBandingMetadata(processedData, reducerBands) {
    if (this.reducers.length === 0)
      return;
    processedData.optimizations ?? (processedData.optimizations = {});
    const reducerMetadata = [];
    for (const def of this.reducers) {
      const bandManager = reducerBands.get(def.property);
      const isBanded = this.shouldUseReducerBanding(def, processedData) && bandManager != null;
      let reason;
      if (!isBanded) {
        if (def.supportsBanding !== true) {
          reason = "reducer does not support banding";
        } else if (processedData.type !== "ungrouped") {
          reason = "grouped data not supported";
        } else if (def.combineResults === void 0) {
          reason = "missing combineResults function";
        } else {
          reason = "banding not applied";
        }
      }
      let stats;
      if (isBanded && bandManager) {
        stats = bandManager.getStats();
      }
      reducerMetadata.push({
        property: String(def.property),
        applied: isBanded,
        reason,
        stats
      });
    }
    processedData.optimizations.reducerBanding = {
      reducers: reducerMetadata
    };
  }
  buildAccessors(defs) {
    return this.scopeCacheManager.buildAccessors(defs);
  }
};
function logProcessedData(processedData) {
  const logValues = (name, data) => {
    if (data.length > 0) {
      logger_exports.log(`DataModel.processData() - ${name}`);
      logger_exports.table(data);
    }
  };
  logger_exports.log("DataModel.processData() - processedData", processedData);
  logValues("Key Domains", processedData.domain.keys);
  logValues("Value Domains", processedData.domain.values);
  logValues("Aggregate Domains", processedData.domain.aggValues ?? []);
  if (processedData.optimizations) {
    logger_exports.log("DataModel.processData() - Optimization Summary");
    const opt = processedData.optimizations;
    if (opt.performance) {
      logger_exports.log(`  Performance: ${opt.performance.processingTime.toFixed(2)}ms (${opt.performance.pathTaken})`);
    }
    if (opt.reprocessing) {
      const symbol = opt.reprocessing.applied ? "\u2713" : "\u2717";
      const reason = opt.reprocessing.reason ? ` (${opt.reprocessing.reason})` : "";
      logger_exports.log(`  Reprocessing: ${symbol}${reason}`);
    }
    if (opt.domainBanding) {
      const keyStats = opt.domainBanding.keyDefs.filter((d) => d.applied);
      const valueStats = opt.domainBanding.valueDefs.filter((d) => d.applied);
      const totalApplied = keyStats.length + valueStats.length;
      const totalDefs = opt.domainBanding.keyDefs.length + opt.domainBanding.valueDefs.length;
      if (totalApplied > 0) {
        logger_exports.log(`  Domain Banding: \u2713 (${totalApplied}/${totalDefs} definitions)`);
        for (const def of [...keyStats, ...valueStats]) {
          if (def.stats) {
            const pct2 = (def.stats.scanRatio * 100).toFixed(1);
            logger_exports.log(
              `    ${def.property}: scanned ${def.stats.dirtyBands}/${def.stats.totalBands} bands (${pct2}%)`
            );
          }
        }
      } else {
        const reasons = [
          ...opt.domainBanding.keyDefs.filter((d) => !d.applied).map((d) => d.reason),
          ...opt.domainBanding.valueDefs.filter((d) => !d.applied).map((d) => d.reason)
        ];
        const uniqueReasons = [...new Set(reasons)].join(", ");
        logger_exports.log(`  Domain Banding: \u2717 (${uniqueReasons})`);
      }
    }
    if (opt.sharedDatumIndices) {
      const symbol = opt.sharedDatumIndices.applied ? "\u2713" : "\u2717";
      const ratio2 = `${opt.sharedDatumIndices.sharedGroupCount}/${opt.sharedDatumIndices.totalGroupCount}`;
      logger_exports.log(`  Shared DatumIndices: ${symbol} (${ratio2} groups)`);
    }
    if (opt.batchMerging) {
      const pct2 = (opt.batchMerging.mergeRatio * 100).toFixed(0);
      const reduction = `${opt.batchMerging.originalBatchCount} \u2192 ${opt.batchMerging.mergedBatchCount}`;
      logger_exports.log(`  Batch Merging: ${reduction} (${pct2}% reduction)`);
    }
  }
}

// packages/ag-charts-community/src/chart/data/processors.ts
var MAX_ANIMATABLE_NODES = 1e3;
function combineIntervalBandResults(bandResults, fallback, combiner) {
  const validResults = bandResults.filter(
    (result) => typeof result === "number" && Number.isFinite(result)
  );
  return validResults.length > 0 ? combiner(validResults) : fallback;
}
function processedDataIsAnimatable(processedData) {
  return processedData.input.count <= MAX_ANIMATABLE_NODES;
}
function basicContinuousCheckDatumValidation(value) {
  return value != null && isContinuous(value);
}
function basicDiscreteCheckDatumValidation(value) {
  return value != null;
}
function basicDiscreteCheckDatumValidationAllowNull(_value) {
  return true;
}
function getValidationFn(scaleType, allowNullKey) {
  switch (scaleType) {
    case "number":
    case "log":
    case "time":
    case "unit-time":
    case "ordinal-time":
    case "color":
      return basicContinuousCheckDatumValidation;
    default:
      return allowNullKey ? basicDiscreteCheckDatumValidationAllowNull : basicDiscreteCheckDatumValidation;
  }
}
function getValueType(scaleType) {
  switch (scaleType) {
    case "number":
    case "log":
    case "time":
    case "color":
      return "range";
    default:
      return "category";
  }
}
function keyProperty(propName, scaleType, opts = {}) {
  const allowNullKey = opts.allowNullKey ?? false;
  const result = {
    property: propName,
    type: "key",
    valueType: getValueType(scaleType),
    validation: opts.validation ?? getValidationFn(scaleType, allowNullKey),
    ...opts
  };
  return result;
}
function valueProperty(propName, scaleType, opts = {}) {
  const allowNullKey = opts.allowNullKey ?? false;
  const result = {
    property: propName,
    type: "value",
    valueType: getValueType(scaleType),
    validation: opts.validation ?? getValidationFn(scaleType, allowNullKey),
    ...opts
  };
  return result;
}
function rowCountProperty(propName, opts = {}) {
  const result = {
    property: propName,
    type: "value",
    valueType: "range",
    missingValue: 1,
    processor: function rowCountResetFn() {
      return function rowCountGroupResetFn() {
        return 1;
      };
    },
    ...opts
  };
  return result;
}
var noopProcessor = function(v) {
  return v;
};
function processorChain(...chain) {
  const filteredChain = chain.filter((fn) => fn != null);
  if (filteredChain.length === 0) {
    return () => noopProcessor;
  }
  if (filteredChain.length === 1) {
    return filteredChain[0];
  }
  return function processorChainFn() {
    const processorInstances = filteredChain.map((fn) => fn());
    return function processorChainResultFn(value, index) {
      return processorInstances.reduce((r, p) => p(r, index), value);
    };
  };
}
function rangedValueProperty(propName, opts = {}) {
  const { min = -Infinity, max = Infinity, processor, ...defOpts } = opts;
  return {
    type: "value",
    property: propName,
    valueType: "range",
    validation: basicContinuousCheckDatumValidation,
    processor: processorChain(processor, function clampFnBuilder() {
      return function clampFn(datum) {
        return isFiniteNumber(datum) ? clamp(min, datum, max) : datum;
      };
    }),
    ...defOpts
  };
}
function accumulativeValueProperty(propName, scaleType, opts = {}) {
  const { onlyPositive, processor, ...defOpts } = opts;
  const result = {
    ...valueProperty(propName, scaleType, defOpts),
    processor: processorChain(processor, accumulatedValue(onlyPositive))
  };
  return result;
}
function trailingAccumulatedValueProperty(propName, scaleType, opts = {}) {
  const result = {
    ...valueProperty(propName, scaleType, opts),
    processor: trailingAccumulatedValue()
  };
  return result;
}
function groupAccumulativeValueProperty(propName, mode, opts, scaleType) {
  return [
    valueProperty(propName, scaleType, opts),
    accumulateGroup(opts.groupId, mode, opts.separateNegative),
    ...opts.rangeId == null ? [] : [range2(opts.rangeId, opts.groupId)]
  ];
}
var SMALLEST_KEY_INTERVAL = {
  type: "reducer",
  property: "smallestKeyInterval",
  initialValue: Infinity,
  reducer() {
    let prevX = Number.NaN;
    return function smallestKeyIntervalReducerFn(smallestSoFar, keys) {
      const key = keys[0];
      const nextX = typeof key === "number" ? key : Number(key);
      if (!Number.isFinite(nextX))
        return smallestSoFar;
      const prevX2 = prevX;
      prevX = nextX;
      if (!Number.isFinite(prevX))
        return smallestSoFar;
      const interval = Math.abs(nextX - prevX2);
      const currentSmallest = smallestSoFar ?? Infinity;
      if (interval > 0 && interval < currentSmallest) {
        return interval;
      }
      return currentSmallest;
    };
  },
  supportsBanding: true,
  combineResults(bandResults) {
    return combineIntervalBandResults(bandResults, Infinity, (values) => Math.min(...values));
  },
  needsOverlap: true
};
var LARGEST_KEY_INTERVAL = {
  type: "reducer",
  property: "largestKeyInterval",
  initialValue: -Infinity,
  reducer() {
    let prevX = Number.NaN;
    return function largestKeyIntervalReducerFn(largestSoFar, keys) {
      const key = keys[0];
      const nextX = typeof key === "number" ? key : Number(key);
      if (!Number.isFinite(nextX))
        return largestSoFar;
      const prevX2 = prevX;
      prevX = nextX;
      if (!Number.isFinite(prevX))
        return largestSoFar;
      const interval = Math.abs(nextX - prevX2);
      const currentLargest = largestSoFar ?? -Infinity;
      if (interval > 0 && interval > currentLargest) {
        return interval;
      }
      return currentLargest;
    };
  },
  supportsBanding: true,
  combineResults(bandResults) {
    return combineIntervalBandResults(bandResults, -Infinity, (values) => Math.max(...values));
  },
  needsOverlap: true
};
var SORT_DOMAIN_GROUPS = {
  type: "processor",
  property: "sortedGroupDomain",
  calculate: function sortedGroupDomainFn({ domain: { groups } }) {
    return groups?.slice().sort((a, b) => {
      for (let i = 0; i < a.length; i++) {
        const result = a[i] - b[i];
        if (result !== 0) {
          return result;
        }
      }
      return 0;
    });
  }
};
function normaliseFnBuilder({ normaliseTo }) {
  const normalise2 = (val, extent2) => {
    if (extent2 === 0)
      return 0;
    const result = (val ?? 0) * normaliseTo / extent2;
    if (result >= 0) {
      return Math.min(normaliseTo, result);
    }
    return Math.max(-normaliseTo, result);
  };
  return () => () => (columns, valueIndexes, dataGroup, groupIndex) => {
    const extent2 = normaliseFindExtent(columns, valueIndexes, dataGroup, groupIndex);
    for (const valueIdx of valueIndexes) {
      const datumIndices = dataGroup.datumIndices[valueIdx];
      if (datumIndices == null)
        continue;
      for (const relativeDatumIndex of datumIndices) {
        const datumIndex = groupIndex + relativeDatumIndex;
        const column = columns[valueIdx];
        const value = column[datumIndex];
        if (value == null) {
          column[datumIndex] = void 0;
          continue;
        }
        column[datumIndex] = normalise2(value, extent2);
      }
    }
  };
}
function normaliseFindExtent(columns, valueIndexes, dataGroup, groupIndex) {
  const valuesExtent = [0, 0];
  for (const valueIdx of valueIndexes) {
    const column = columns[valueIdx];
    const datumIndices = dataGroup.datumIndices[valueIdx];
    if (datumIndices == null)
      continue;
    for (const relativeDatumIndex of datumIndices) {
      const datumIndex = groupIndex + relativeDatumIndex;
      const value = column[datumIndex];
      if (value == null)
        continue;
      const valueExtent = typeof value === "number" ? value : Math.max(...value.map((v) => v ?? 0));
      const valIdx = valueExtent < 0 ? 0 : 1;
      if (valIdx === 0) {
        valuesExtent[valIdx] = Math.min(valuesExtent[valIdx], valueExtent);
      } else {
        valuesExtent[valIdx] = Math.max(valuesExtent[valIdx], valueExtent);
      }
    }
  }
  return Math.max(Math.abs(valuesExtent[0]), valuesExtent[1]);
}
function normaliseGroupTo(matchGroupIds, normaliseTo) {
  return {
    type: "group-value-processor",
    matchGroupIds,
    adjust: memo({ normaliseTo }, normaliseFnBuilder)
  };
}
function normalisePropertyFnBuilder({
  normaliseTo,
  zeroDomain,
  rangeMin,
  rangeMax
}) {
  const normaliseSpan = normaliseTo[1] - normaliseTo[0];
  const normalise2 = function normaliseFn(val, start2, span) {
    const result = normaliseTo[0] + (val - start2) / span * normaliseSpan;
    if (span === 0) {
      return zeroDomain;
    } else if (result >= normaliseTo[1]) {
      return normaliseTo[1];
    } else if (result < normaliseTo[0]) {
      return normaliseTo[0];
    }
    return result;
  };
  return function normalisePropertyResetFn() {
    return function normalisePropertyResultFn(pData, pIdx) {
      let [start2, end3] = pData.domain.values[pIdx];
      if (rangeMin != null)
        start2 = rangeMin;
      if (rangeMax != null)
        end3 = rangeMax;
      const span = end3 - start2;
      pData.domain.values[pIdx] = [normaliseTo[0], normaliseTo[1]];
      const column = pData.columns[pIdx];
      for (let datumIndex = 0; datumIndex < column.length; datumIndex += 1) {
        column[datumIndex] = normalise2(column[datumIndex], start2, span);
      }
    };
  };
}
function normalisePropertyTo(property, normaliseTo, zeroDomain, rangeMin, rangeMax) {
  return {
    type: "property-value-processor",
    property,
    adjust: memo({ normaliseTo, rangeMin, rangeMax, zeroDomain }, normalisePropertyFnBuilder)
  };
}
var ANIMATION_VALIDATION_UNIQUE_KEYS = 1;
var ANIMATION_VALIDATION_ORDERED_KEYS = 2;
function animationValidationProcessValue(def, domainValues, column) {
  let validation = ANIMATION_VALIDATION_UNIQUE_KEYS | ANIMATION_VALIDATION_ORDERED_KEYS;
  if (def.valueType === "category") {
    if (domainValues.length < column.length)
      validation &= ~ANIMATION_VALIDATION_UNIQUE_KEYS;
    return validation;
  }
  let lastValue = column[0]?.valueOf();
  for (let d = 1; validation !== 0 && d < column.length; d++) {
    const keyValue = column[d]?.valueOf();
    if (!Number.isFinite(keyValue) || lastValue > keyValue)
      validation &= ~ANIMATION_VALIDATION_ORDERED_KEYS;
    if (Number.isFinite(keyValue) && lastValue === keyValue)
      validation &= ~ANIMATION_VALIDATION_UNIQUE_KEYS;
    lastValue = keyValue;
  }
  return validation;
}
function buildAnimationValidationFn(valueKeyIds) {
  return function calculate(result, _previousValue) {
    if (!processedDataIsAnimatable(result))
      return;
    const { keys: keysDefs, values: valuesDef } = result.defs;
    const {
      input,
      domain: { values: domainValues },
      columns
    } = result;
    let uniqueKeys = true;
    let orderedKeys = true;
    if (input.count !== 0) {
      const keySortOrders = result[KEY_SORT_ORDERS];
      for (let i = 0; (uniqueKeys || orderedKeys) && i < keysDefs.length; i++) {
        const def = keysDefs[i];
        const entry = keySortOrders.get(i);
        if (def.valueType === "category") {
          const domainSize = result.domain.keys[i]?.length ?? 0;
          const dataSize = result.keys[i]?.values().next().value?.length ?? 0;
          if (domainSize < dataSize)
            uniqueKeys = false;
        } else if (entry) {
          if (entry.isUnique === false)
            uniqueKeys = false;
          if (entry.sortOrder !== 1)
            orderedKeys = false;
        }
      }
      if (valueKeyIds && valueKeyIds.length > 0) {
        let validation = ANIMATION_VALIDATION_UNIQUE_KEYS | ANIMATION_VALIDATION_ORDERED_KEYS;
        for (let i = 0; validation !== 0 && i < valuesDef.length; i++) {
          const value = valuesDef[i];
          if (!valueKeyIds.includes(value.id))
            continue;
          validation &= animationValidationProcessValue(value, domainValues[i], columns[i]);
        }
        if ((validation & ANIMATION_VALIDATION_UNIQUE_KEYS) === 0)
          uniqueKeys = false;
        if ((validation & ANIMATION_VALIDATION_ORDERED_KEYS) === 0)
          orderedKeys = false;
      }
    }
    return { uniqueKeys, orderedKeys };
  };
}
function incrementalCalculateAnimationValidation() {
  return {
    uniqueKeys: true,
    orderedKeys: false
  };
}
function animationValidation(valueKeyIds) {
  const calculate = memo(valueKeyIds, buildAnimationValidationFn);
  return {
    type: "processor",
    property: "animationValidation",
    calculate,
    incrementalCalculate: incrementalCalculateAnimationValidation
  };
}
function buildGroupAccFn({ mode, separateNegative }) {
  return function buildGroupAccFnResetFn() {
    return function buildGroupAccFnGroupResetFn() {
      return function buildGroupAccFnResultFn(columns, valueIndexes, dataGroup, groupIndex) {
        const acc = [0, 0];
        for (const valueIdx of valueIndexes) {
          const datumIndices = dataGroup.datumIndices[valueIdx];
          if (datumIndices == null)
            continue;
          const stackNegative = acc[0];
          const stackPositive = acc[1];
          const column = columns[valueIdx];
          let didAccumulate = false;
          for (const relativeDatumIndex of datumIndices) {
            const datumIndex = groupIndex + relativeDatumIndex;
            const currentVal = column[datumIndex];
            if (!isFiniteNumber(currentVal))
              continue;
            const useNegative = separateNegative && isNegative(currentVal);
            const accValue = useNegative ? stackNegative : stackPositive;
            if (mode === "normal") {
              column[datumIndex] = accValue + currentVal;
            } else {
              column[datumIndex] = accValue;
            }
            if (!didAccumulate) {
              const accIndex = useNegative ? 0 : 1;
              acc[accIndex] = accValue + currentVal;
              didAccumulate = true;
            }
          }
        }
      };
    };
  };
}
function accumulateGroup(matchGroupId, mode, separateNegative = false) {
  const adjust = memo({ mode, separateNegative }, buildGroupAccFn);
  return {
    type: "group-value-processor",
    matchGroupIds: [matchGroupId],
    adjust,
    supportsReprocessing: true
  };
}
function valueIdentifier(value) {
  return value.id ?? value.property;
}
function valueIndices(id, previousData, processedData) {
  const properties = /* @__PURE__ */ new Map();
  const previousValues = previousData.defs.values;
  for (let previousIndex = 0; previousIndex < previousValues.length; previousIndex += 1) {
    const previousValue = previousValues[previousIndex];
    if (previousValue.scopes?.includes(id) === false)
      continue;
    const valueId = valueIdentifier(previousValue);
    if (properties.has(valueId))
      return;
    properties.set(valueId, previousIndex);
  }
  const indices = [];
  const nextValues = processedData.defs.values;
  for (let nextIndex = 0; nextIndex < nextValues.length; nextIndex += 1) {
    const nextValue = nextValues[nextIndex];
    if (nextValue.scopes?.includes(id) === false)
      continue;
    const valueId = valueIdentifier(nextValue);
    const previousIndex = properties.get(valueId);
    if (previousIndex == null)
      return;
    properties.delete(valueId);
    indices.push({ previousIndex, nextIndex });
  }
  if (properties.size !== 0)
    return;
  return indices;
}
function columnsEqual(previousColumns, nextColumns, indices, previousDatumIndex, nextDatumIndex) {
  for (const { previousIndex, nextIndex } of indices) {
    const previousColumn = previousColumns[previousIndex];
    const nextColumn = nextColumns[nextIndex];
    const previousValue = previousColumn[previousDatumIndex];
    const nextValue = nextColumn[nextDatumIndex];
    if (previousValue !== nextValue) {
      return false;
    }
  }
  return true;
}
function diff(id, previousData, updateMovedData = true) {
  return {
    type: "processor",
    property: "diff",
    calculate(processedData, previousValue) {
      if (!processedDataIsAnimatable(processedData))
        return;
      const moved = /* @__PURE__ */ new Map();
      const added = /* @__PURE__ */ new Map();
      const updated = /* @__PURE__ */ new Map();
      const removed = /* @__PURE__ */ new Map();
      const previousKeys = previousData.keys.map((keyMap) => keyMap.get(id));
      const keys = processedData.keys.map((keyMap) => keyMap.get(id));
      const previousColumns = previousData.columns;
      const columns = processedData.columns;
      const indices = valueIndices(id, previousData, processedData);
      if (indices == null)
        return previousValue;
      const length2 = Math.max(previousData.input.count, processedData.input.count);
      const allowNull = processedData.defs.keys.some((def) => def.allowNullKey === true);
      for (let i = 0; i < length2; i++) {
        const hasPreviousDatum = i < previousData.input.count;
        const hasDatum = i < processedData.input.count;
        const prevKeys = hasPreviousDatum ? datumKeys(previousKeys, i, allowNull) : void 0;
        const prevId = prevKeys == null ? "" : createDatumId(...prevKeys);
        const dKeys = hasDatum ? datumKeys(keys, i, allowNull) : void 0;
        const datumId = dKeys == null ? "" : createDatumId(...dKeys);
        if (hasDatum && hasPreviousDatum && prevId === datumId) {
          if (!columnsEqual(previousColumns, columns, indices, i, i)) {
            updated.set(datumId, i);
          }
          continue;
        }
        const removedIndex = removed.get(datumId);
        if (removedIndex != null) {
          if (updateMovedData || !columnsEqual(previousColumns, columns, indices, removedIndex, i)) {
            updated.set(datumId, i);
            moved.set(datumId, i);
          }
          removed.delete(datumId);
        } else if (hasDatum) {
          added.set(datumId, i);
        }
        const addedIndex = added.get(prevId);
        if (addedIndex != null) {
          if (updateMovedData || !columnsEqual(previousColumns, columns, indices, addedIndex, i)) {
            updated.set(prevId, i);
            moved.set(prevId, i);
          }
          added.delete(prevId);
        } else if (hasPreviousDatum) {
          updated.delete(prevId);
          removed.set(prevId, i);
        }
      }
      const changed = added.size > 0 || updated.size > 0 || removed.size > 0;
      const value = {
        changed,
        added: new Set(added.keys()),
        updated: new Set(updated.keys()),
        removed: new Set(removed.keys()),
        moved: new Set(moved.keys())
      };
      return {
        ...previousValue,
        [id]: value
      };
    }
  };
}
function createDatumId(...keys) {
  if (keys.length === 1) {
    const key = transformIntegratedCategoryValue(keys[0]);
    if (key === null)
      return NULL_KEY_STRING;
    if (key === void 0)
      return UNDEFINED_KEY_STRING;
    const isPrimitive = typeof key === "boolean" || typeof key === "number" || typeof key === "string";
    if (isPrimitive)
      return key;
  }
  return keys.map((key) => {
    const transformed = transformIntegratedCategoryValue(key);
    if (transformed === null)
      return NULL_KEY_STRING;
    if (transformed === void 0)
      return UNDEFINED_KEY_STRING;
    return transformed;
  }).join("___");
}

// packages/ag-charts-community/src/chart/interaction/animationBatch.ts
var AnimationBatch = class {
  constructor(maxAnimationTime) {
    this.maxAnimationTime = maxAnimationTime;
    this.debug = debugLogger_exports.create(true, "animation");
    this.controllers = /* @__PURE__ */ new Map();
    this.stoppedCbs = /* @__PURE__ */ new Set();
    this.currentPhase = 0;
    this.phases = new Map(PHASE_ORDER.map((p) => [p, []]));
    this.skipAnimations = false;
    this.animationTimeConsumed = 0;
    /** Guard against premature animation execution. */
    this.isReady = false;
  }
  get size() {
    return this.controllers.size;
  }
  get consumedTimeMs() {
    return this.animationTimeConsumed;
  }
  isActive() {
    return this.controllers.size > 0;
  }
  getActiveControllers() {
    return this.phases.get(PHASE_ORDER[this.currentPhase]) ?? [];
  }
  checkOverlappingId(id) {
    if (id != null && this.controllers.has(id)) {
      this.controllers.get(id).stop();
      this.debug(`Skipping animation batch due to update of existing animation: ${id}`);
      this.skip();
    }
  }
  addAnimation(animation) {
    if (animation.isComplete)
      return;
    const animationPhaseIdx = PHASE_ORDER.indexOf(animation.phase);
    if (animationPhaseIdx < this.currentPhase) {
      this.debug(`Skipping animation due to being for an earlier phase`, animation.id);
      animation.stop();
      return;
    }
    this.controllers.set(animation.id, animation);
    this.phases.get(animation.phase)?.push(animation);
  }
  removeAnimation(animation) {
    this.controllers.delete(animation.id);
    const phase = this.phases.get(animation.phase);
    const index = phase?.indexOf(animation);
    if (index != null && index >= 0) {
      phase?.splice(index, 1);
    }
  }
  progress(deltaTime) {
    if (!this.isReady)
      return;
    let unusedTime = deltaTime === 0 ? 0.01 : deltaTime;
    const refresh = () => {
      const phase2 = PHASE_ORDER[this.currentPhase];
      return {
        phaseControllers: [...this.getActiveControllers()],
        phase: phase2,
        phaseMeta: PHASE_METADATA[phase2]
      };
    };
    let { phase, phaseControllers, phaseMeta } = refresh();
    const arePhasesComplete = () => PHASE_ORDER[this.currentPhase] == null;
    const progressPhase = () => {
      ({ phase, phaseControllers, phaseMeta } = refresh());
      while (!arePhasesComplete() && phaseControllers.length === 0) {
        this.currentPhase++;
        ({ phase, phaseControllers, phaseMeta } = refresh());
        this.debug(`AnimationBatch - phase changing to ${phase}`, { unusedTime }, phaseControllers);
      }
    };
    const total = this.controllers.size;
    this.debug(`AnimationBatch - ${deltaTime}ms; phase ${phase} with ${phaseControllers?.length} of ${total}`);
    do {
      const phaseDeltaTime = unusedTime;
      const skipPhase = phaseMeta.skipIfNoEarlierAnimations && this.animationTimeConsumed === 0;
      let completeCount = 0;
      for (const controller of phaseControllers) {
        if (skipPhase) {
          controller.stop();
        } else {
          unusedTime = Math.min(controller.update(phaseDeltaTime), unusedTime);
        }
        if (controller.isComplete) {
          completeCount++;
          this.removeAnimation(controller);
        }
      }
      this.animationTimeConsumed += phaseDeltaTime - unusedTime;
      this.debug(
        `AnimationBatch - updated ${phaseControllers.length} controllers; ${completeCount} completed`,
        phaseControllers
      );
      this.debug(`AnimationBatch - animationTimeConsumed: ${this.animationTimeConsumed}`);
      progressPhase();
    } while (unusedTime > 0 && !arePhasesComplete());
    if (this.animationTimeConsumed > this.maxAnimationTime) {
      this.debug(`Animation batch exceeded max animation time, skipping`, [...this.controllers]);
      this.stop();
    }
  }
  ready() {
    if (this.isReady)
      return;
    this.isReady = true;
    this.debug(`AnimationBatch - ready; skipped: ${this.skipAnimations}`, [...this.controllers]);
    let skipAll = true;
    for (const [, controller] of this.controllers) {
      if (controller.duration > 0 && PHASE_METADATA[controller.phase].skipIfNoEarlierAnimations !== true) {
        skipAll = false;
        break;
      }
    }
    if (!skipAll) {
      for (const [, controller] of this.controllers) {
        if (controller.autoplay) {
          controller.play(true);
        }
      }
    }
  }
  skip(skip = true) {
    if (this.skipAnimations === false && skip === true) {
      for (const controller of this.controllers.values()) {
        controller.stop();
      }
      this.controllers.clear();
    }
    this.skipAnimations = skip;
  }
  play() {
    for (const controller of this.controllers.values()) {
      controller.play();
    }
  }
  stop() {
    for (const controller of this.controllers.values()) {
      try {
        controller.stop();
        this.removeAnimation(controller);
      } catch (error2) {
        logger_exports.error("Error during animation stop", error2);
      }
    }
    this.dispatchStopped();
  }
  stopByAnimationId(id) {
    if (id != null && this.controllers.has(id)) {
      const controller = this.controllers.get(id);
      if (controller) {
        controller.stop();
        this.removeAnimation(controller);
      }
    }
  }
  stopByAnimationGroupId(id) {
    for (const controller of this.controllers.values()) {
      if (controller.groupId === id) {
        this.stopByAnimationId(controller.id);
      }
    }
  }
  dispatchStopped() {
    for (const cb of this.stoppedCbs) {
      cb();
    }
    this.stoppedCbs.clear();
  }
  isSkipped() {
    return this.skipAnimations;
  }
  getRemainingTime(restrictPhase) {
    if (!this.isActive())
      return 0;
    let total = 0;
    for (const [phase, controllers] of this.phases) {
      if (controllers.length === 0)
        continue;
      if (restrictPhase != null && restrictPhase !== phase)
        continue;
      total += Math.max(...controllers.map((c) => c.isComplete ? 0 : c.delay + c.duration - (c.elapsed ?? 0)));
    }
    return total;
  }
  destroy() {
    this.stop();
    this.controllers.clear();
  }
};

// packages/ag-charts-community/src/chart/interaction/animationManager.ts
function validAnimationDuration(testee) {
  if (testee == null)
    return true;
  return !Number.isNaN(testee) && testee >= 0 && testee <= 2;
}
var AnimationManager = class {
  constructor(interactionManager, chartUpdateMutex) {
    this.interactionManager = interactionManager;
    this.chartUpdateMutex = chartUpdateMutex;
    this.defaultDuration = 1e3;
    this.maxAnimatableItems = MAX_ANIMATABLE_NODES;
    this.batch = new AnimationBatch(this.defaultDuration * 1.5);
    this.debug = debugLogger_exports.create(true, "animation");
    this.events = new EventEmitter();
    this.rafAvailable = typeof requestAnimationFrame !== "undefined";
    this.isPlaying = true;
    this.requestId = null;
    this.skipAnimations = true;
    this.currentAnonymousAnimationId = 0;
    this.cumulativeAnimationTime = 0;
  }
  addListener(eventName, listener) {
    return this.events.on(eventName, listener);
  }
  /**
   * Create an animation to tween a value between the `from` and `to` properties. If an animation already exists
   * with the same `id`, immediately stop it.
   */
  animate(opts) {
    const batch = this.batch;
    try {
      batch.checkOverlappingId(opts.id);
    } catch (error2) {
      this.failsafeOnError(error2);
      return;
    }
    let { id } = opts;
    if (id == null) {
      id = `__${this.currentAnonymousAnimationId}`;
      this.currentAnonymousAnimationId += 1;
    }
    const skip = this.isSkipped() || opts.phase === "none";
    if (skip) {
      this.debug("AnimationManager - skipping animation");
    }
    const { delay, duration } = opts;
    if (!validAnimationDuration(delay)) {
      throw new Error(`Animation delay of ${delay} is unsupported (${id})`);
    }
    if (!validAnimationDuration(duration)) {
      throw new Error(`Animation duration of ${duration} is unsupported (${id})`);
    }
    const animation = new Animation({
      ...opts,
      id,
      skip,
      autoplay: this.isPlaying ? opts.autoplay : false,
      phase: opts.phase,
      defaultDuration: this.defaultDuration
    });
    if (this.forceTimeJump(animation, this.defaultDuration)) {
      return;
    }
    this.batch.addAnimation(animation);
    return animation;
  }
  play() {
    if (this.isPlaying) {
      return;
    }
    this.isPlaying = true;
    this.debug("AnimationManager.play()");
    try {
      this.batch.play();
    } catch (error2) {
      this.failsafeOnError(error2);
    }
    this.requestAnimation();
  }
  stop() {
    this.isPlaying = false;
    this.cancelAnimation();
    this.debug("AnimationManager.stop()");
    this.batch.stop();
  }
  stopByAnimationId(id) {
    try {
      this.batch.stopByAnimationId(id);
    } catch (error2) {
      this.failsafeOnError(error2);
    }
  }
  stopByAnimationGroupId(id) {
    try {
      this.batch.stopByAnimationGroupId(id);
    } catch (error2) {
      this.failsafeOnError(error2);
    }
  }
  reset() {
    if (this.isPlaying) {
      this.stop();
      this.play();
    } else {
      this.stop();
    }
  }
  skip(skip = true) {
    this.skipAnimations = skip;
  }
  isSkipped() {
    return !this.rafAvailable || this.skipAnimations || this.batch.isSkipped();
  }
  isActive() {
    return this.isPlaying && this.batch.isActive();
  }
  getRemainingTime(phase) {
    return this.batch.getRemainingTime(phase);
  }
  getCumulativeAnimationTime() {
    return this.cumulativeAnimationTime;
  }
  skipCurrentBatch() {
    if (this.debug.check()) {
      this.debug(`AnimationManager - skipCurrentBatch()`, {
        stack: new Error("Stack trace for animation skip tracking").stack
      });
    }
    this.batch.skip();
  }
  /** Mocking point for tests to guarantee that animation updates happen. */
  isSkippingFrames() {
    return true;
  }
  /** Mocking point for tests to capture requestAnimationFrame callbacks. */
  scheduleAnimationFrame(cb) {
    this.requestId = getWindow().requestAnimationFrame((t) => {
      cb(t).catch((e) => logger_exports.error(e));
    });
  }
  /** Mocking point for tests to skip animations to a specific point in time. */
  forceTimeJump(_animation, _defaultDuration) {
    return false;
  }
  requestAnimation() {
    if (!this.rafAvailable)
      return;
    if (!this.batch.isActive() || this.requestId !== null)
      return;
    let prevTime;
    const onAnimationFrame = async (time3) => {
      await this.debug.group("AnimationManager.onAnimationFrame()", async () => {
        const executeAnimationFrame = () => {
          const deltaTime = time3 - (prevTime ?? time3);
          prevTime = time3;
          this.debug("AnimationManager", {
            controllersCount: this.batch.size,
            deltaTime
          });
          this.interactionManager.pushState(4 /* Animation */);
          try {
            this.batch.progress(deltaTime);
            this.cumulativeAnimationTime += deltaTime;
          } catch (error2) {
            this.failsafeOnError(error2);
          }
          this.events.emit("animation-frame", {
            type: "animation-frame",
            deltaMs: deltaTime
          });
        };
        if (this.isSkippingFrames()) {
          await this.chartUpdateMutex.acquireImmediately(executeAnimationFrame);
        } else {
          await this.chartUpdateMutex.acquire(executeAnimationFrame);
        }
        if (this.batch.isActive()) {
          this.scheduleAnimationFrame(onAnimationFrame);
        } else {
          this.batch.stop();
          this.events.emit("animation-stop", {
            type: "animation-stop",
            deltaMs: this.batch.consumedTimeMs
          });
        }
      });
    };
    this.events.emit("animation-start", {
      type: "animation-start",
      deltaMs: 0
    });
    this.scheduleAnimationFrame(onAnimationFrame);
  }
  cancelAnimation() {
    if (this.requestId === null)
      return;
    cancelAnimationFrame(this.requestId);
    this.events.emit("animation-stop", {
      type: "animation-stop",
      deltaMs: this.batch.consumedTimeMs
    });
    this.requestId = null;
    this.startBatch();
  }
  failsafeOnError(error2, cancelAnimation = true) {
    logger_exports.error("Error during animation, skipping animations", error2);
    if (cancelAnimation) {
      this.cancelAnimation();
    }
  }
  startBatch(skipAnimations) {
    this.debug(`AnimationManager - startBatch() with skipAnimations=${skipAnimations}.`);
    this.reset();
    this.batch.destroy();
    this.batch = new AnimationBatch(this.defaultDuration * 1.5);
    if (skipAnimations === true) {
      this.batch.skip();
    }
  }
  endBatch() {
    if (this.batch.isActive()) {
      this.batch.ready();
      this.requestAnimation();
    } else {
      this.interactionManager.popState(4 /* Animation */);
      if (this.batch.isSkipped()) {
        this.batch.skip(false);
      }
    }
  }
  onBatchStop(cb) {
    this.batch.stoppedCbs.add(cb);
  }
  destroy() {
    this.stop();
    this.events.clear();
  }
};

// packages/ag-charts-community/src/chart/interaction/contextMenuTypes.ts
var ContextMenuBuiltinItems = class {
  constructor() {
    this.download = {
      type: "action",
      showOn: "always",
      label: "contextMenuDownload",
      enabled: true,
      action: void 0,
      items: void 0
    };
    this["zoom-to-cursor"] = {
      type: "action",
      showOn: "series-area",
      label: "contextMenuZoomToCursor",
      enabled: true,
      action: void 0,
      items: void 0
    };
    this["pan-to-cursor"] = {
      type: "action",
      showOn: "series-area",
      label: "contextMenuPanToCursor",
      enabled: true,
      action: void 0,
      items: void 0
    };
    this["reset-zoom"] = {
      type: "action",
      showOn: "series-area",
      label: "contextMenuResetZoom",
      enabled: true,
      action: void 0,
      items: void 0
    };
    this["toggle-series-visibility"] = {
      type: "action",
      showOn: "legend-item",
      label: "contextMenuToggleSeriesVisibility",
      enabled: true,
      action: void 0,
      items: void 0
    };
    this["toggle-other-series"] = {
      type: "action",
      showOn: "legend-item",
      label: "contextMenuToggleOtherSeries",
      enabled: true,
      action: void 0,
      items: void 0
    };
    this["separator"] = {
      type: "separator",
      showOn: "always",
      label: "separator",
      enabled: true,
      action: void 0,
      items: void 0
    };
  }
};
var ContextMenuBuiltinItemLists = class {
  constructor() {
    this.defaults = [
      "download",
      "zoom-to-cursor",
      "pan-to-cursor",
      "reset-zoom",
      "toggle-series-visibility",
      "toggle-other-series"
    ];
  }
};
var ContextMenuBuiltins = class {
  constructor() {
    this.items = new ContextMenuBuiltinItems();
    this.lists = new ContextMenuBuiltinItemLists();
  }
};

// packages/ag-charts-community/src/chart/interaction/contextMenuRegistry.ts
var ContextMenuRegistry = class {
  constructor(eventsHub) {
    this.eventsHub = eventsHub;
    this.builtins = new ContextMenuBuiltins();
    this.hiddenActions = /* @__PURE__ */ new Set();
    this.toggle("zoom-to-cursor", "hide");
    this.toggle("pan-to-cursor", "hide");
    this.toggle("reset-zoom", "hide");
  }
  static check(showOn, event) {
    return event.showOn == showOn;
  }
  static checkCallback(desiredShowOn, showOn, _callback) {
    return desiredShowOn === showOn;
  }
  dispatchContext(showOn, pointerEvent, context, position) {
    const { widgetEvent } = pointerEvent;
    if (widgetEvent.sourceEvent.defaultPrevented) {
      return;
    }
    const x = position?.x ?? pointerEvent.canvasX;
    const y = position?.y ?? pointerEvent.canvasY;
    const event = { showOn, x, y, context, widgetEvent };
    this.eventsHub.emit("context-menu:setup", event);
    this.eventsHub.emit("context-menu:complete", event);
  }
  isVisible(id) {
    return !this.hiddenActions.has(id);
  }
  toggle(id, action) {
    action ?? (action = this.isVisible(id) ? "hide" : "show");
    switch (action) {
      case "show":
        this.hiddenActions.delete(id);
        break;
      case "hide":
        this.hiddenActions.add(id);
        break;
    }
  }
};

// packages/ag-charts-community/src/chart/interaction/highlightManager.ts
var _HighlightManager = class _HighlightManager {
  constructor(eventsHub) {
    this.eventsHub = eventsHub;
    this.highlightStates = new StateTracker();
    // Track pending unhighlights per caller
    this.pendingUnhighlights = /* @__PURE__ */ new Map();
    // Configurable delay (hardcoded for POC, will be user-configurable later)
    this.unhighlightDelay = 100;
  }
  updateHighlight(callerId, highlightedDatum, delayed = false) {
    if (highlightedDatum?.series?.isHighlightEnabled() === false) {
      highlightedDatum = void 0;
    }
    const previousHighlight = this.getActiveHighlight();
    if (highlightedDatum == null && delayed && this.unhighlightDelay > 0) {
      if (!this.pendingUnhighlights.has(callerId)) {
        const scheduler = debouncedCallback(() => {
          this.applyPendingUnhighlight(callerId);
        });
        this.pendingUnhighlights.set(callerId, { scheduler });
        scheduler.schedule(this.unhighlightDelay);
      }
      return;
    }
    const pending = this.pendingUnhighlights.get(callerId);
    if (pending) {
      pending.scheduler.cancel();
      this.pendingUnhighlights.delete(callerId);
    }
    if (highlightedDatum) {
      this.highlightStates.set(callerId, highlightedDatum);
    } else {
      this.highlightStates.delete(callerId);
    }
    this.maybeEmitChange(callerId, previousHighlight);
  }
  maybeEmitChange(callerId, previousHighlight) {
    const currentHighlight = this.getActiveHighlight();
    if (!this.isEqual(currentHighlight, previousHighlight)) {
      this.eventsHub.emit(_HighlightManager.HIGHLIGHT_CHANGE_EVENT, {
        callerId,
        currentHighlight,
        previousHighlight
      });
    }
  }
  applyPendingUnhighlight(callerId) {
    if (!this.pendingUnhighlights.has(callerId)) {
      return;
    }
    this.pendingUnhighlights.delete(callerId);
    const previousHighlight = this.getActiveHighlight();
    this.highlightStates.delete(callerId);
    const currentHighlight = this.getActiveHighlight();
    if (!this.isEqual(currentHighlight, previousHighlight)) {
      this.eventsHub.emit(_HighlightManager.HIGHLIGHT_CHANGE_EVENT, {
        callerId,
        currentHighlight,
        previousHighlight
      });
    }
  }
  getActiveHighlight() {
    return this.highlightStates.stateValue();
  }
  destroy() {
    for (const { scheduler } of this.pendingUnhighlights.values()) {
      scheduler.cancel();
    }
    this.pendingUnhighlights.clear();
  }
  isEqual(a, b) {
    return a === b || a != null && b != null && a.series === b.series && this.idsMatch(a, b) && a.datum === b.datum;
  }
  idsMatch(a, b) {
    return a.itemId != null && b.itemId != null && a.itemId === b.itemId || a.datumIndex != null && b.datumIndex != null && objectsEqual(a.datumIndex, b.datumIndex);
  }
};
// milliseconds
_HighlightManager.HIGHLIGHT_CHANGE_EVENT = "highlight:change";
var HighlightManager = _HighlightManager;

// packages/ag-charts-community/src/chart/series/seriesProperties.ts
var HighlightState = /* @__PURE__ */ ((HighlightState9) => {
  HighlightState9[HighlightState9["None"] = 0] = "None";
  HighlightState9[HighlightState9["Item"] = 1] = "Item";
  HighlightState9[HighlightState9["Series"] = 2] = "Series";
  HighlightState9[HighlightState9["OtherSeries"] = 3] = "OtherSeries";
  HighlightState9[HighlightState9["OtherItem"] = 4] = "OtherItem";
  return HighlightState9;
})(HighlightState || {});
var highlightStates = [
  0 /* None */,
  1 /* Item */,
  2 /* Series */,
  3 /* OtherSeries */,
  4 /* OtherItem */
];
function getHighlightStyleOptionKeys(highlightState) {
  switch (highlightState) {
    case 1 /* Item */:
      return ["highlightedItem", "highlightedSeries"];
    case 4 /* OtherItem */:
      return ["unhighlightedItem", "highlightedSeries"];
    case 2 /* Series */:
      return ["highlightedSeries"];
    case 3 /* OtherSeries */:
      return ["unhighlightedSeries"];
    case 0 /* None */:
      return [];
  }
}
function toHighlightString(state) {
  const unreachable = (a) => a;
  switch (state) {
    case 1 /* Item */:
      return "highlighted-item";
    case 4 /* OtherItem */:
      return "unhighlighted-item";
    case 2 /* Series */:
      return "highlighted-series";
    case 3 /* OtherSeries */:
      return "unhighlighted-series";
    case 0 /* None */:
      return "none";
    default:
      return unreachable(state);
  }
}
var SeriesItemHighlightStyle = class extends BaseProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesItemHighlightStyle.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesItemHighlightStyle.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesItemHighlightStyle.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesItemHighlightStyle.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesItemHighlightStyle.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesItemHighlightStyle.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesItemHighlightStyle.prototype, "lineDashOffset", 2);
var HighlightProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = true;
    this.range = "tooltip";
    this.bringToFront = true;
    this.highlightedItem = {};
    this.unhighlightedItem = {};
    this.highlightedSeries = {};
    this.unhighlightedSeries = {};
  }
  getStyle(highlightState) {
    const keys = getHighlightStyleOptionKeys(highlightState);
    if (keys.length === 0)
      return {};
    return mergeDefaults(...keys.map((key) => this[key]));
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], HighlightProperties.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HighlightProperties.prototype, "range", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HighlightProperties.prototype, "bringToFront", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HighlightProperties.prototype, "highlightedItem", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HighlightProperties.prototype, "unhighlightedItem", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HighlightProperties.prototype, "highlightedSeries", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HighlightProperties.prototype, "unhighlightedSeries", 2);
var SegmentOptions = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.fill = "#c16068";
    this.fillOpacity = 1;
    this.stroke = "#874349";
    this.strokeWidth = 2;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], SegmentOptions.prototype, "start", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SegmentOptions.prototype, "stop", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SegmentOptions.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SegmentOptions.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SegmentOptions.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SegmentOptions.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SegmentOptions.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SegmentOptions.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SegmentOptions.prototype, "lineDashOffset", 2);
var Segmentation = class {
  constructor() {
    this.key = "x";
    this.segments = new PropertiesArray(SegmentOptions);
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], Segmentation.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Segmentation.prototype, "key", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Segmentation.prototype, "segments", 2);
var FillGradientDefaults = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.type = "gradient";
    this.colorStops = [];
    this.bounds = "item";
    this.gradient = "linear";
    this.rotation = 0;
    this.reverse = false;
    this.colorSpace = "rgb";
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], FillGradientDefaults.prototype, "type", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillGradientDefaults.prototype, "colorStops", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillGradientDefaults.prototype, "bounds", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillGradientDefaults.prototype, "gradient", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillGradientDefaults.prototype, "rotation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillGradientDefaults.prototype, "reverse", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillGradientDefaults.prototype, "colorSpace", 2);
var FillPatternDefaults = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.type = "pattern";
    this.colorStops = [];
    this.bounds = "item";
    this.gradient = "linear";
    this.rotation = 0;
    this.scale = 1;
    this.reverse = false;
    this.pattern = "forward-slanted-lines";
    this.width = 26;
    this.height = 26;
    this.padding = 6;
    this.fill = "black";
    this.fillOpacity = 1;
    this.backgroundFill = "white";
    this.backgroundFillOpacity = 1;
    this.stroke = "black";
    this.strokeOpacity = 1;
    this.strokeWidth = 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], FillPatternDefaults.prototype, "type", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillPatternDefaults.prototype, "colorStops", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillPatternDefaults.prototype, "bounds", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillPatternDefaults.prototype, "gradient", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillPatternDefaults.prototype, "rotation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillPatternDefaults.prototype, "scale", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillPatternDefaults.prototype, "reverse", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillPatternDefaults.prototype, "path", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillPatternDefaults.prototype, "pattern", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillPatternDefaults.prototype, "width", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillPatternDefaults.prototype, "height", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillPatternDefaults.prototype, "padding", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillPatternDefaults.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillPatternDefaults.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillPatternDefaults.prototype, "backgroundFill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillPatternDefaults.prototype, "backgroundFillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillPatternDefaults.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillPatternDefaults.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillPatternDefaults.prototype, "strokeWidth", 2);
var FillImageDefaults = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.type = "image";
    this.url = "";
    this.rotation = 0;
    this.scale = 1;
    this.backgroundFill = "black";
    this.backgroundFillOpacity = 1;
    this.repeat = "no-repeat";
    this.fit = "contain";
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], FillImageDefaults.prototype, "type", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillImageDefaults.prototype, "url", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillImageDefaults.prototype, "rotation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillImageDefaults.prototype, "scale", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillImageDefaults.prototype, "backgroundFill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillImageDefaults.prototype, "backgroundFillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillImageDefaults.prototype, "repeat", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FillImageDefaults.prototype, "fit", 2);
var SeriesProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.visible = true;
    this.focusPriority = Infinity;
    this.showInLegend = true;
    this.cursor = "default";
    this.nodeClickRange = "exact";
    this.highlight = new HighlightProperties();
  }
  handleUnknownProperties(unknownKeys, properties) {
    if ("context" in properties) {
      this.context = properties.context;
      unknownKeys.delete("context");
    }
    if ("allowNullKeys" in properties) {
      this.allowNullKeys = properties.allowNullKeys;
      unknownKeys.delete("allowNullKeys");
    }
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesProperties.prototype, "id", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesProperties.prototype, "visible", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesProperties.prototype, "focusPriority", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesProperties.prototype, "showInLegend", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesProperties.prototype, "cursor", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesProperties.prototype, "nodeClickRange", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesProperties.prototype, "highlight", 2);

// packages/ag-charts-community/src/chart/series/util.ts
function datumBoundaryPoints(datum, domain) {
  if (domain.length === 0) {
    return [false, false];
  }
  const d0 = domain[0];
  const d1 = domain.at(-1);
  if (typeof d0 === "string" || d0 === null || d0 === void 0) {
    return [datum === d0, datum === d1];
  }
  if (datum == null) {
    return [false, false];
  }
  const datumValue = datum.valueOf();
  if (d0 == null || d1 == null) {
    return [false, false];
  }
  let min = d0.valueOf();
  let max = d1.valueOf();
  if (min > max) {
    [min, max] = [max, min];
  }
  return [datumValue === min, datumValue === max];
}
function datumStylerProperties(xValue, yValue, xKey, yKey, xDomain, yDomain) {
  const [min, max] = datumBoundaryPoints(yValue, yDomain);
  const [first2, last] = datumBoundaryPoints(xValue, xDomain);
  return {
    xKey,
    yKey,
    xValue,
    yValue,
    first: first2,
    last,
    min,
    max
  };
}
function visibleRangeIndices(sortOrder, length2, [range0, range1], xRange) {
  let xMinIndex = findMinIndex(0, length2 - 1, (i) => {
    const index = sortOrder === 1 ? i : length2 - i;
    const x1 = xRange(index)?.[1] ?? Number.NaN;
    return !Number.isFinite(x1) || x1 >= range0;
  }) ?? 0;
  let xMaxIndex = findMaxIndex(0, length2 - 1, (i) => {
    const index = sortOrder === 1 ? i : length2 - i;
    const x0 = xRange(index)?.[0] ?? Number.NaN;
    return !Number.isFinite(x0) || x0 <= range1;
  }) ?? length2 - 1;
  if (sortOrder === -1) {
    [xMinIndex, xMaxIndex] = [length2 - xMaxIndex, length2 - xMinIndex];
  }
  xMinIndex = Math.max(xMinIndex, 0);
  xMaxIndex = Math.min(xMaxIndex + 1, length2);
  return [xMinIndex, xMaxIndex];
}
function getDatumRefPoint(series, datum, movedBounds) {
  if (movedBounds) {
    const { x, y, width: width2, height: height2 } = movedBounds;
    return { canvasX: x + width2 / 2, canvasY: y + height2 / 2 };
  }
  const refPoint = datum.yBar?.upperPoint ?? datum.midPoint ?? series.datumMidPoint?.(datum);
  if (refPoint) {
    const { x, y } = Transformable.toCanvasPoint(series.contentGroup, refPoint.x, refPoint.y);
    return { canvasX: Math.round(x), canvasY: Math.round(y) };
  }
}
function countExpandingSearch(min, max, start2, countUntil, iteratee) {
  let i = -1;
  let count = 0;
  let shift = 0;
  let reachedAnEnd = false;
  while (count < countUntil && i <= max - min) {
    i += 1;
    const index = start2 + shift;
    if (!reachedAnEnd)
      shift *= -1;
    if (shift >= 0)
      shift += 1;
    if (reachedAnEnd && shift < 0)
      shift -= 1;
    if (index < min || index > max) {
      reachedAnEnd = true;
      continue;
    }
    if (iteratee(index))
      count += 1;
  }
  return count;
}
function getItemStyles(getItemStyle2) {
  const result = {};
  for (const state of highlightStates) {
    result[state] = getItemStyle2(void 0, false, state);
  }
  return result;
}
function getItemStylesPerItemId(getItemStyle2, ...itemIds) {
  const result = {};
  for (const itemId of itemIds ?? ["default"]) {
    for (const state of highlightStates) {
      const states = result[itemId] ?? (result[itemId] = {});
      states[state] = getItemStyle2(void 0, false, state, itemId);
    }
  }
  return result;
}
function hasDimmedOpacity(style2) {
  return (style2?.opacity ?? 1) < 1 || (style2?.fillOpacity ?? 1) < 1 || (style2?.strokeOpacity ?? 1) < 1;
}
var opaqueMarkerFillCache = /* @__PURE__ */ new Map();
function isOpaqueMarkerFillStyle(style2) {
  if (style2 == null)
    return false;
  const fill = style2.fill;
  if (!isString(fill))
    return false;
  const fillString = fill.trim();
  const fillLower = fillString.toLowerCase();
  if (fillLower === "transparent" || fillLower === "none")
    return false;
  let cached = opaqueMarkerFillCache.get(fillString);
  if (cached == null) {
    try {
      cached = Color.fromString(fillString).a === 1;
    } catch {
      cached = false;
    }
    opaqueMarkerFillCache.set(fillString, cached);
  }
  return cached;
}
function resolveMarkerDrawingMode(baseDrawingMode, style2) {
  if (baseDrawingMode !== "cutout")
    return baseDrawingMode;
  return isOpaqueMarkerFillStyle(style2) ? "cutout" : "overlay";
}
function findNodeDatumInArray(itemIdOrIndex, nodeData) {
  for (const node of nodeData ?? []) {
    switch (typeof itemIdOrIndex) {
      case "string":
        if (node.itemId === itemIdOrIndex) {
          return node;
        }
        break;
      case "number":
        if (node.datumIndex === itemIdOrIndex) {
          return node;
        }
        break;
      default:
        return itemIdOrIndex;
    }
  }
  return void 0;
}

// packages/ag-charts-community/src/chart/interaction/tooltipManager.ts
var TooltipManager = class {
  constructor(eventsHub, localeManager, domManager, tooltip) {
    this.domManager = domManager;
    this.tooltip = tooltip;
    this.stateTracker = new StateTracker();
    this.suppressState = new StateTracker(false);
    this.appliedState = null;
    // Track pending removals per caller
    this.pendingRemovals = /* @__PURE__ */ new Map();
    // Configurable delay (match highlights at 100ms)
    this.removeDelay = 100;
    // milliseconds
    this.cleanup = new CleanupRegistry();
    this.cleanup.register(
      tooltip.setup(localeManager, domManager),
      eventsHub.on("dom:hidden", () => this.tooltip.hide())
    );
  }
  destroy() {
    for (const { scheduler } of this.pendingRemovals.values()) {
      scheduler.cancel();
    }
    this.pendingRemovals.clear();
    this.cleanup.flush();
  }
  updateTooltip(callerId, meta, content, pagination) {
    const pending = this.pendingRemovals.get(callerId);
    if (pending) {
      pending.scheduler.cancel();
      this.pendingRemovals.delete(callerId);
    }
    content ?? (content = this.stateTracker.get(callerId)?.content);
    this.stateTracker.set(callerId, { meta, content, pagination });
    this.applyStates();
  }
  removeTooltip(callerId, meta, delayed = false) {
    if (delayed && this.removeDelay > 0) {
      const existingPending = this.pendingRemovals.get(callerId);
      if (existingPending) {
        if (meta) {
          existingPending.lastMeta = meta;
        }
        return;
      }
      const scheduler = debouncedCallback(() => {
        this.applyPendingRemoval(callerId);
      });
      this.pendingRemovals.set(callerId, { scheduler, lastMeta: meta });
      scheduler.schedule(this.removeDelay);
      return;
    }
    const pending = this.pendingRemovals.get(callerId);
    if (pending) {
      pending.scheduler.cancel();
      this.pendingRemovals.delete(callerId);
    }
    this.stateTracker.delete(callerId);
    this.applyStates();
  }
  suppressTooltip(callerId) {
    this.suppressState.set(callerId, true);
  }
  unsuppressTooltip(callerId) {
    this.suppressState.delete(callerId);
  }
  applyPendingRemoval(callerId) {
    if (!this.pendingRemovals.has(callerId)) {
      return;
    }
    this.pendingRemovals.delete(callerId);
    this.stateTracker.delete(callerId);
    this.applyStates();
  }
  applyStates() {
    const id = this.stateTracker.stateId();
    const state = id ? this.stateTracker.get(id) : void 0;
    if (this.suppressState.stateValue() || state?.meta == null || state?.content == null) {
      this.appliedState = null;
      this.tooltip.hide();
      return;
    }
    const canvasRect = this.domManager.getBoundingClientRect();
    const boundingRect = this.tooltip.bounds === "extended" ? this.domManager.getOverlayClientRect() : canvasRect;
    if (objectsEqual(this.appliedState?.content, state?.content) && objectsEqual(this.appliedState?.pagination, state?.pagination)) {
      const renderInstantly = this.tooltip.isVisible();
      this.tooltip.show(boundingRect, canvasRect, state?.meta, null, void 0, renderInstantly);
    } else {
      this.tooltip.show(boundingRect, canvasRect, state?.meta, state?.content, state?.pagination);
    }
    this.appliedState = state;
  }
  static makeTooltipMeta(event, series, datum, movedBounds) {
    const { canvasX, canvasY } = event;
    const tooltip = series.properties.tooltip;
    const { placement, anchorTo, xOffset, yOffset } = tooltip.position;
    const refPoint = getDatumRefPoint(series, datum, movedBounds);
    const meta = {
      canvasX,
      canvasY,
      nodeCanvasX: refPoint?.canvasX ?? canvasX,
      nodeCanvasY: refPoint?.canvasY ?? canvasY,
      enableInteraction: tooltip.interaction?.enabled ?? false,
      showArrow: tooltip.showArrow,
      position: {
        placement,
        anchorTo,
        xOffset,
        yOffset
      }
    };
    return meta;
  }
};

// packages/ag-charts-community/src/chart/interaction/dragInterpreter.ts
var DRAG_THRESHOLD_PX = 3;
var DOUBLE_TAP_TIMER_MS = 505;
var DOUBLE_TAP_THRESHOLD_PX = 30;
function makeSynthetic(type, event) {
  const { device, offsetX, offsetY, clientX, clientY, currentX, currentY, sourceEvent } = event;
  return { type, device, offsetX, offsetY, clientX, clientY, currentX, currentY, sourceEvent };
}
function checkDragDistance(dx2, dy2) {
  const distanceSquared2 = dx2 * dx2 + dy2 * dy2;
  const thresholdSquared = DRAG_THRESHOLD_PX * DRAG_THRESHOLD_PX;
  return distanceSquared2 >= thresholdSquared;
}
function checkDoubleTapDistance(t1, t2) {
  const dx2 = t1.clientX - t2.clientX;
  const dy2 = t1.clientY - t2.clientY;
  const distanceSquared2 = dx2 * dx2 + dy2 * dy2;
  const thresholdSquared = DOUBLE_TAP_THRESHOLD_PX * DOUBLE_TAP_THRESHOLD_PX;
  return distanceSquared2 < thresholdSquared;
}
var DragInterpreter = class {
  constructor(widget) {
    this.cleanup = new CleanupRegistry();
    this.events = new EventEmitter();
    this.isDragging = false;
    this.touch = { distanceTravelledX: 0, distanceTravelledY: 0, clientX: 0, clientY: 0 };
    this.cleanup.register(
      widget.addListener("touchstart", this.onTouchStart.bind(this)),
      widget.addListener("touchmove", this.onTouchMove.bind(this)),
      widget.addListener("touchend", this.onTouchEnd.bind(this)),
      widget.addListener("mousemove", this.onMouseMove.bind(this)),
      widget.addListener("dblclick", this.onDblClick.bind(this)),
      widget.addListener("drag-start", this.onDragStart.bind(this)),
      widget.addListener("drag-move", this.onDragMove.bind(this)),
      widget.addListener("drag-end", this.onDragEnd.bind(this))
    );
  }
  destroy() {
    this.cleanup.flush();
  }
  onTouchStart(e) {
    const { clientX, clientY } = e.sourceEvent.targetTouches[0] ?? { clientX: Infinity, clientY: Infinity };
    this.touch.distanceTravelledX = 0;
    this.touch.distanceTravelledY = 0;
    this.touch.clientX = clientX;
    this.touch.clientY = clientY;
  }
  onTouchMove(e) {
    const { clientX, clientY } = e.sourceEvent.targetTouches[0] ?? { clientX: Infinity, clientY: Infinity };
    this.touch.distanceTravelledX += Math.abs(this.touch.clientX - clientX);
    this.touch.distanceTravelledY += Math.abs(this.touch.clientY - clientY);
    this.touch.clientX = clientX;
    this.touch.clientY = clientY;
  }
  onTouchEnd(event) {
    event.sourceEvent.preventDefault();
  }
  onMouseMove(event) {
    this.events.emit("mousemove", event);
  }
  onDblClick(event) {
    this.events.emit("dblclick", event);
  }
  onDragStart(event) {
    this.dragStartEvent = event;
  }
  onDragMove(event) {
    if (this.dragStartEvent != null) {
      if (checkDragDistance(event.originDeltaX, event.originDeltaY)) {
        this.events.emit("drag-start", this.dragStartEvent);
        this.events.emit("drag-move", { ...this.dragStartEvent, type: "drag-move" });
        this.dragStartEvent = void 0;
        this.isDragging = true;
      }
    }
    if (this.isDragging) {
      this.events.emit("drag-move", event);
    }
  }
  onDragEnd(event) {
    if (this.isDragging) {
      this.events.emit("drag-end", event);
      this.isDragging = false;
      return;
    }
    if (event.device === "mouse") {
      const click = makeSynthetic("click", event);
      this.events.emit("click", click);
    } else if (event.sourceEvent.type === "touchend") {
      if (checkDragDistance(this.touch.distanceTravelledX, this.touch.distanceTravelledY)) {
        return;
      }
      const click = makeSynthetic("click", event);
      this.events.emit("click", click);
      const now = Date.now();
      if (this.lastClick !== void 0 && now - this.lastClick.time <= DOUBLE_TAP_TIMER_MS && checkDoubleTapDistance(this.lastClick, event)) {
        const dblClick = makeSynthetic("dblclick", event);
        this.events.emit("dblclick", dblClick);
        this.lastClick = void 0;
      } else {
        this.lastClick = { time: now, clientX: event.clientX, clientY: event.clientY };
      }
    }
  }
};

// packages/ag-charts-community/src/chart/interaction/widgetSet.ts
var DOMManagerWidget = class extends NativeWidget {
  constructor(elem) {
    super(elem);
  }
  addChildToDOM() {
  }
  removeChildFromDOM() {
  }
};
var WidgetSet = class {
  constructor(domManager, opts) {
    this.seriesWidget = new DOMManagerWidget(domManager.getParent("series-area"));
    this.chartWidget = new DOMManagerWidget(domManager.getParent("canvas-proxy"));
    this.containerWidget = new DOMManagerWidget(domManager.getParent("canvas-container"));
    this.containerWidget.addChild(this.chartWidget);
    this.chartWidget.addChild(this.seriesWidget);
    if (opts.withDragInterpretation) {
      this.seriesDragInterpreter = new DragInterpreter(this.seriesWidget);
    }
  }
  destroy() {
    this.seriesDragInterpreter?.destroy();
    this.seriesWidget.destroy();
    this.chartWidget.destroy();
    this.containerWidget.destroy();
  }
};

// packages/ag-charts-community/src/scale/continuousScale.ts
var _ContinuousScale = class _ContinuousScale extends AbstractScale {
  constructor(domain = [], range3 = []) {
    super();
    this.range = range3;
    this.defaultTickCount = _ContinuousScale.defaultTickCount;
    this.defaultClamp = false;
    // Domain caching to avoid repeated valueOf() calls in hot paths
    this._domain = [];
    this.domainNeedsValueOf = true;
    // Safe default
    this.d0Cache = Number.NaN;
    this.d1Cache = Number.NaN;
    this.domain = domain;
  }
  static is(value) {
    return value instanceof _ContinuousScale;
  }
  get domain() {
    return this._domain;
  }
  set domain(values) {
    this._domain = values;
    if (values && values.length >= 2) {
      const sample = values[0];
      this.domainNeedsValueOf = sample != null && typeof sample === "object";
      if (this.domainNeedsValueOf) {
        this.d0Cache = values[0].valueOf();
        this.d1Cache = values[1].valueOf();
      } else {
        this.d0Cache = values[0];
        this.d1Cache = values[1];
      }
    } else {
      this.d0Cache = Number.NaN;
      this.d1Cache = Number.NaN;
    }
  }
  normalizeDomains(...domains) {
    return normalizeContinuousDomains(...domains);
  }
  calcBandwidth(smallestInterval = 1, minWidth = 1) {
    const { domain } = this;
    const rangeDistance = this.getPixelRange();
    if (domain.length === 0)
      return rangeDistance;
    const intervals = Math.abs(this.d1Cache - this.d0Cache) / smallestInterval + 1;
    let bands = intervals;
    if (minWidth !== 0) {
      const maxBands = Math.floor(rangeDistance);
      bands = Math.min(bands, maxBands);
    }
    return rangeDistance / Math.max(1, bands);
  }
  convert(value, options) {
    const { domain } = this;
    if (!domain || domain.length < 2 || value == null) {
      return Number.NaN;
    }
    const { range: range3 } = this;
    const clamp2 = options?.clamp ?? this.defaultClamp;
    let d0 = this.d0Cache;
    let d1 = this.d1Cache;
    let x = typeof value === "number" ? value : value.valueOf();
    if (this.transform) {
      d0 = this.transform(d0);
      d1 = this.transform(d1);
      x = this.transform(x);
    }
    if (clamp2) {
      const [start2, stop] = findMinMax([d0, d1]);
      if (x < start2) {
        return range3[0];
      } else if (x > stop) {
        return range3[1];
      }
    }
    if (d0 === d1) {
      return (range3[0] + range3[1]) / 2;
    } else if (x === d0) {
      return range3[0];
    } else if (x === d1) {
      return range3[1];
    }
    const r0 = range3[0];
    return r0 + (x - d0) / (d1 - d0) * (range3[1] - r0);
  }
  invert(x, _nearest) {
    const { domain } = this;
    if (domain.length < 2)
      return;
    let d0 = this.d0Cache;
    let d1 = this.d1Cache;
    if (this.transform) {
      d0 = this.transform(d0);
      d1 = this.transform(d1);
    }
    const { range: range3 } = this;
    const [r0, r1] = range3;
    let d;
    if (r0 === r1) {
      d = this.toDomain((d0 + d1) / 2);
    } else {
      d = this.toDomain(d0 + (x - r0) / (r1 - r0) * (d1 - d0));
    }
    return this.transformInvert ? this.transformInvert(d) : d;
  }
  getDomainMinMax() {
    return unpackDomainMinMax(this.domain);
  }
  getPixelRange() {
    const [a, b] = this.range;
    return Math.abs(b - a);
  }
};
_ContinuousScale.defaultTickCount = 5;
var ContinuousScale = _ContinuousScale;
function normalizeContinuousDomains(...domains) {
  let min;
  let minValue = Infinity;
  let max;
  let maxValue = -Infinity;
  for (const input of domains) {
    const domain = input.domain;
    for (const d of domain) {
      const value = d.valueOf();
      if (value < minValue) {
        minValue = value;
        min = d;
      }
      if (value > maxValue) {
        maxValue = value;
        max = d;
      }
    }
  }
  if (min != null && max != null) {
    const domain = [min, max];
    return { domain, animatable: true };
  } else {
    return { domain: [], animatable: false };
  }
}

// packages/ag-charts-community/src/scale/bandScale.ts
var _BandScale = class _BandScale extends AbstractScale {
  constructor() {
    super(...arguments);
    this.invalid = true;
    this.range = [0, 1];
    this.round = false;
    this._bandwidth = 1;
    this._step = 1;
    this._inset = 1;
    this._rawBandwidth = 1;
    /**
     * The ratio of the range that is reserved for space between bands.
     */
    this._paddingInner = 0;
    /**
     * The ratio of the range that is reserved for space before the first
     * and after the last band.
     */
    this._paddingOuter = 0;
  }
  static is(value) {
    return value instanceof _BandScale;
  }
  get bandwidth() {
    this.refresh();
    return this._bandwidth;
  }
  get step() {
    this.refresh();
    return this._step;
  }
  get inset() {
    this.refresh();
    return this._inset;
  }
  get rawBandwidth() {
    this.refresh();
    return this._rawBandwidth;
  }
  set padding(value) {
    value = clamp(0, value, 1);
    this._paddingInner = value;
    this._paddingOuter = value;
  }
  get padding() {
    return this._paddingInner;
  }
  set paddingInner(value) {
    this.invalid = true;
    this._paddingInner = clamp(0, value, 1);
  }
  get paddingInner() {
    return this._paddingInner;
  }
  set paddingOuter(value) {
    this.invalid = true;
    this._paddingOuter = clamp(0, value, 1);
  }
  get paddingOuter() {
    return this._paddingOuter;
  }
  /** Override in subclass to provide band count without triggering full band materialization */
  getBandCountForUpdate() {
    return this.bands.length;
  }
  refresh() {
    if (!this.invalid)
      return;
    this.invalid = false;
    this.update();
    if (this.invalid) {
      logger_exports.warnOnce("Expected update to not invalidate scale");
    }
  }
  convert(d, options) {
    this.refresh();
    const i = this.findIndex(d, options?.alignment);
    if (i == null || i < 0 || i >= this.getBandCountForUpdate()) {
      return Number.NaN;
    }
    return this.ordinalRange(i);
  }
  getDomainMinMax() {
    return unpackDomainMinMax(this.domain);
  }
  invertNearestIndex(position) {
    this.refresh();
    const bandCount = this.getBandCountForUpdate();
    if (bandCount === 0)
      return -1;
    let low = 0;
    let high = bandCount - 1;
    let closestDistance = Infinity;
    let closestIndex = 0;
    while (low <= high) {
      const mid = Math.trunc((high + low) / 2);
      const p = this.ordinalRange(mid);
      const distance2 = Math.abs(p - position);
      if (distance2 === 0)
        return mid;
      if (distance2 < closestDistance) {
        closestDistance = distance2;
        closestIndex = mid;
      }
      if (p < position) {
        low = mid + 1;
      } else {
        high = mid - 1;
      }
    }
    return closestIndex;
  }
  update() {
    const [r0, r1] = this.range;
    let { _paddingInner: paddingInner } = this;
    const { _paddingOuter: paddingOuter } = this;
    const bandCount = this.getBandCountForUpdate();
    if (bandCount === 0)
      return;
    const rangeDistance = r1 - r0;
    let rawStep;
    if (bandCount === 1) {
      paddingInner = 0;
      rawStep = rangeDistance * (1 - paddingOuter * 2);
    } else {
      rawStep = rangeDistance / Math.max(1, bandCount - paddingInner + paddingOuter * 2);
    }
    const round4 = this.round && Math.floor(rawStep) > 0;
    const step = round4 ? Math.floor(rawStep) : rawStep;
    let inset = r0 + (rangeDistance - step * (bandCount - paddingInner)) / 2;
    let bandwidth = step * (1 - paddingInner);
    if (round4) {
      inset = Math.round(inset);
      bandwidth = Math.round(bandwidth);
    }
    this._step = step;
    this._inset = inset;
    this._bandwidth = bandwidth;
    this._rawBandwidth = rawStep * (1 - paddingInner);
  }
  ordinalRange(i) {
    const { _inset: inset, _step: step, range: range3 } = this;
    const min = Math.min(range3[0], range3[1]);
    const max = Math.max(range3[0], range3[1]);
    return clamp(min, inset + step * i, max);
  }
};
__decorateClass([
  Invalidating
], _BandScale.prototype, "range", 2);
__decorateClass([
  Invalidating
], _BandScale.prototype, "round", 2);
var BandScale = _BandScale;

// packages/ag-charts-community/src/scale/discreteTimeScale.ts
var APPROXIMATE_THRESHOLD = 1e3;
var SAMPLE_POINTS = 20;
function checkUniformityBySampling(bands, startIdx = 0, endIdx = bands.length - 1) {
  const n = endIdx - startIdx + 1;
  if (n < 2)
    return { isUniform: false };
  const indices = Array.from(
    { length: SAMPLE_POINTS },
    (_, i) => startIdx + Math.floor(i * (n - 1) / (SAMPLE_POINTS - 1))
  );
  const samples = indices.map((i) => bands[i].valueOf());
  const expectedInterval = (samples.at(-1) - samples[0]) / (n - 1);
  if (!Number.isFinite(expectedInterval) || expectedInterval === 0) {
    return { isUniform: false };
  }
  const tolerance = Math.abs(expectedInterval * 0.01);
  for (let i = 1; i < samples.length; i++) {
    const indexGap = indices[i] - indices[i - 1];
    const actualInterval = (samples[i] - samples[i - 1]) / indexGap;
    if (Math.abs(actualInterval - expectedInterval) > tolerance) {
      return { isUniform: false };
    }
  }
  return { isUniform: true, interval: expectedInterval };
}
var DiscreteTimeScale = class _DiscreteTimeScale extends BandScale {
  static is(value) {
    return value instanceof _DiscreteTimeScale;
  }
  toDomain(value) {
    return new Date(value);
  }
  get reversed() {
    const { domain } = this;
    return domain.length > 0 && domain[0].valueOf() > domain.at(-1).valueOf();
  }
  /** Cached numeric band values for efficient binary search. Subclasses should override with a cached version. */
  get numericBands() {
    return this.bands.map((d) => d.valueOf());
  }
  convert(value, options) {
    this.refresh();
    if (!(value instanceof Date))
      value = new Date(value);
    const { domain, reversed } = this;
    const numericBands = this.numericBands;
    const bandCount = numericBands.length;
    if (domain.length <= 0)
      return Number.NaN;
    const r0 = this.ordinalRange(0);
    const r1 = this.ordinalRange(bandCount - 1);
    if (bandCount === 0)
      return r0;
    if (options?.clamp === true) {
      const { range: range3 } = this;
      if (value.valueOf() < numericBands[0])
        return range3[0];
      if (value.valueOf() > numericBands.at(-1))
        return range3[1];
    }
    const alignment = options?.alignment ?? 0 /* Leading */;
    if (alignment !== 2 /* Interpolate */) {
      const r2 = super.convert(value, options);
      return reversed ? r1 - (r2 - r0) : r2;
    }
    const v = value.valueOf();
    let bandIndex = this.findIndex(value) ?? 0;
    let dIndex;
    if (reversed) {
      bandIndex = Math.min(Math.max(bandIndex, 1), bandCount - 1);
      dIndex = -1;
    } else {
      bandIndex = Math.min(Math.max(bandIndex, 0), bandCount - 2);
      dIndex = 1;
    }
    const v0 = numericBands[bandIndex];
    const v1 = numericBands[bandIndex + dIndex];
    const vr0 = this.ordinalRange(bandIndex);
    const vr1 = this.ordinalRange(bandIndex + dIndex);
    const ratio2 = (v - v0) / (v1 - v0);
    const r = ratio2 * (vr1 - vr0) + vr0;
    return reversed ? r1 - (r - r0) : r;
  }
  invert(position, nearest = false) {
    this.refresh();
    const { domain } = this;
    if (domain.length <= 0)
      return;
    const bands = this.bands;
    const bandCount = this.getBandCountForUpdate();
    const reversed = domain[0].valueOf() > domain.at(-1).valueOf();
    let index;
    if (nearest) {
      index = this.invertNearestIndex(position - this.bandwidth / 2);
    } else {
      const closestIndex = findMinIndex(0, bandCount - 1, (i) => {
        const p = this.ordinalRange(i);
        return p >= position;
      });
      index = closestIndex ?? bandCount - 1;
    }
    return bands[reversed ? bandCount - 1 - index : index];
  }
  /** Override in subclass to provide cached uniformity check result */
  getUniformityCache(_visibleRange) {
    return void 0;
  }
  findIndex(value, alignment = 0 /* Leading */) {
    if (value == null)
      return void 0;
    const numericBands = this.numericBands;
    const n = numericBands.length;
    if (n === 0)
      return void 0;
    if (n === 1)
      return 0;
    const target = value.valueOf();
    if (alignment === 1 /* Trailing */) {
      return findMinIndex(0, n - 1, (index) => numericBands[index] >= target);
    }
    return findMaxIndex(0, n - 1, (index) => numericBands[index] <= target);
  }
};

// packages/ag-charts-community/src/util/panToBBox.ts
function normalize(screenMin, min, screenMax, max, target) {
  return min + (max - min) * ((target - screenMin) / (screenMax - screenMin));
}
function unnormalize(screenMin, min, screenMax, max, ratio2) {
  return screenMin + (ratio2 - min) * ((screenMax - screenMin) / (max - min));
}
function calcWorldAxis(viewportMin, viewportMax, ratio2) {
  return [
    unnormalize(viewportMin, ratio2.min, viewportMax, ratio2.max, 0),
    unnormalize(viewportMin, ratio2.min, viewportMax, ratio2.max, 1)
  ];
}
function calcWorldVec4(viewport, ratioX, ratioY) {
  const [x1, x2] = calcWorldAxis(viewport.x1, viewport.x2, ratioX);
  const [y1, y2] = calcWorldAxis(viewport.y1, viewport.y2, ratioY);
  return { x1, x2, y1, y2 };
}
function panAxesUnnormalized(worldMin, worldMax, viewportMin, viewportMax, targetMin, targetMax) {
  if (viewportMin <= targetMin && targetMax <= viewportMax)
    return viewportMin;
  const minDiff = targetMin - viewportMin;
  const maxDiff = targetMax - viewportMax;
  const diff9 = Math.abs(minDiff) < Math.abs(maxDiff) ? minDiff : maxDiff;
  return clamp(worldMin, viewportMin + diff9, worldMax);
}
function calcPanToBBoxRatios(viewportBBox, ratios, targetBBox) {
  const { x: ratioX = { min: 0, max: 1 }, y: ratioY = { min: 0, max: 1 } } = ratios;
  const target = vector4_exports.from(targetBBox);
  const viewport = vector4_exports.from(viewportBBox);
  const world = calcWorldVec4(viewport, ratioX, ratioY);
  const x = panAxesUnnormalized(world.x1, world.x2, viewport.x1, viewport.x2, target.x1, target.x2);
  const y = panAxesUnnormalized(world.y1, world.y2, viewport.y1, viewport.y2, target.y1, target.y2);
  const result = {
    x: {
      min: normalize(viewport.x1, ratioX.min, viewport.x2, ratioX.max, x),
      max: normalize(viewport.x1, ratioX.min, viewport.x2, ratioX.max, x + viewportBBox.width)
    },
    y: {
      min: normalize(viewport.y1, ratioY.min, viewport.y2, ratioY.max, y),
      max: normalize(viewport.y1, ratioY.min, viewport.y2, ratioY.max, y + viewportBBox.height)
    }
  };
  const diffX = result.x.max - result.x.min;
  const diffY = result.y.max - result.y.min;
  result.x.min = clamp(0, result.x.min, 1 - diffX);
  result.x.max = result.x.min + diffX;
  result.y.min = clamp(0, result.y.min, 1 - diffY);
  result.y.max = result.y.min + diffY;
  return result;
}

// packages/ag-charts-community/src/chart/rangeAlignment.ts
function rangeAlignment(start2, end3) {
  const startValue = start2?.valueOf();
  const endValue = end3?.valueOf();
  if (typeof startValue !== "number" || typeof endValue !== "number")
    return [void 0, void 0];
  return startValue < endValue ? [0 /* Leading */, 1 /* Trailing */] : [1 /* Trailing */, 0 /* Leading */];
}

// packages/ag-charts-community/src/chart/interaction/zoomManager.ts
var rangeValidator2 = (axis) => attachDescription((value, { options }) => {
  if (!ContinuousScale.is(axis?.scale) && !DiscreteTimeScale.is(axis?.scale))
    return true;
  if (value == null || options.end == null)
    return true;
  return value < options.end;
}, `to be less than end`);
function validateChanges(changes) {
  for (const axisId of strictObjectKeys(changes)) {
    const zoom = changes[axisId];
    if (!zoom)
      continue;
    const { min, max } = zoom;
    if (min < 0 || max > 1) {
      logger_exports.warnOnce(
        `Attempted to update axis (${axisId}) zoom to an invalid ratio of [{ min: ${min}, max: ${max} }], expecting a ratio of 0 to 1. Ignoring.`
      );
      delete changes[axisId];
    }
  }
}
function refreshCoreState(nextAxes, state) {
  const result = {};
  for (const { id, direction } of nextAxes) {
    const { min, max } = state[id] ?? { min: 0, max: 1 };
    result[id] = { min, max, direction };
  }
  return result;
}
function areEqualCoreZooms(p, q) {
  const pKeys = strictObjectKeys(p);
  const qKeys = strictObjectKeys(q);
  if (pKeys.length !== qKeys.length)
    return false;
  for (const k of pKeys)
    if (!qKeys.includes(k))
      return false;
  for (const k of pKeys) {
    const pVal = p[k];
    const qVal = q[k];
    if (pVal === qVal) {
      continue;
    } else if (pVal == void 0 || qVal == void 0 || pVal.direction !== qVal.direction || pVal.min !== qVal.min || pVal.max !== qVal.max) {
      return false;
    }
  }
  return true;
}
function userInteraction(sourceDetail) {
  return { source: "user-interaction", sourceDetail };
}
var ZoomManager = class extends BaseManager {
  constructor(eventsHub, updateService, fireChartEvent) {
    super();
    this.eventsHub = eventsHub;
    this.fireChartEvent = fireChartEvent;
    this.mementoOriginatorKey = "zoom";
    this.state = {};
    this.axes = [];
    this.didLayoutAxes = false;
    this.lastRestoredState = {};
    this.independentAxes = false;
    this.navigatorModule = false;
    this.zoomModule = false;
    // The initial state memento can not be restored until the chart has performed its first layout. Instead save it as
    // pending and restore then delete it on the first layout.
    this.pendingMemento = void 0;
    this.cleanup.register(
      eventsHub.on("zoom:change-request", (event) => {
        this.constrainZoomToRequiredWidth(event);
      }),
      updateService.addListener("pre-series-update", ({ requiredRangeRatio, requiredRangeDirection }) => {
        this.didLayoutAxes = true;
        const { pendingMemento } = this;
        if (pendingMemento) {
          this.restoreMemento(pendingMemento.version, pendingMemento.mementoVersion, pendingMemento.memento);
        } else {
          this.restoreRequiredRange(requiredRangeRatio, requiredRangeDirection);
        }
        this.updateZoom({
          source: "chart-update",
          // FIXME(AG-16412): this is "probably" what caused, but we don't really know
          sourceDetail: "unspecified"
        });
      }),
      updateService.addListener("update-complete", ({ wasShortcut }) => {
        if (wasShortcut)
          return;
        if (this.pendingZoomEventSource) {
          const source = this.pendingZoomEventSource;
          this.fireChartEvent({ type: "zoom", source, ...this.getMementoRanges() });
          this.pendingZoomEventSource = void 0;
        }
      })
    );
  }
  // FIXME: should be private
  toCoreZoomState(axisZoom) {
    const result = {};
    let ids;
    const { state } = this;
    if (this.independentAxes) {
      const xId = this.getPrimaryAxisId("x" /* X */);
      const yId = this.getPrimaryAxisId("y" /* Y */);
      ids = [];
      if (xId)
        ids.push(xId);
      if (yId)
        ids.push(yId);
    } else {
      ids = strictObjectKeys(state);
    }
    for (const id of ids) {
      const { direction } = state[id] ?? {};
      if (direction != void 0) {
        const zoom = axisZoom[direction];
        if (zoom) {
          const { min, max } = zoom;
          result[id] = { min, max, direction };
        }
      }
    }
    return result;
  }
  // FIXME: should be private
  toZoomState(coreZoom) {
    let x;
    let y;
    for (const id of strictObjectKeys(coreZoom)) {
      const { min, max, direction } = coreZoom[id];
      if (direction === "x" /* X */) {
        x ?? (x = { min, max });
      } else if (direction === "y" /* Y */) {
        y ?? (y = { min, max });
      }
    }
    if (x || y) {
      return { x, y };
    }
  }
  createMemento() {
    return this.getMementoRanges();
  }
  guardMemento(blob, messages) {
    if (blob == null)
      return true;
    if (!isObject(blob))
      return false;
    const primaryX = this.getPrimaryAxis("x" /* X */);
    const primaryY = this.getPrimaryAxis("y" /* Y */);
    const zoomMementoDefs = {
      rangeX: { start: rangeValidator2(primaryX), end: defined },
      rangeY: { start: rangeValidator2(primaryY), end: defined },
      ratioX: { start: defined, end: defined },
      ratioY: { start: defined, end: defined },
      autoScaledAxes: defined
    };
    const { invalid } = validate(blob, zoomMementoDefs);
    if (invalid.length > 0) {
      messages.push(...invalid.map(String));
      return false;
    }
    return true;
  }
  restoreMemento(version, mementoVersion, memento) {
    if (!this.axes || !this.didLayoutAxes) {
      this.pendingMemento = { version, mementoVersion, memento };
      return;
    }
    this.pendingMemento = void 0;
    const zoom = definedZoomState(this.getZoom());
    if (memento?.rangeX) {
      zoom.x = this.rangeToRatioDirection("x" /* X */, memento.rangeX) ?? { min: 0, max: 1 };
    } else if (memento?.ratioX) {
      zoom.x = {
        min: memento.ratioX.start ?? 0,
        max: memento.ratioX.end ?? 1
      };
    } else {
      zoom.x = { min: 0, max: 1 };
    }
    const { navigatorModule, zoomModule } = this;
    this.eventsHub.emit("zoom:load-memento", { zoom, memento, navigatorModule, zoomModule });
    const changes = this.toCoreZoomState(zoom);
    this.lastRestoredState = deepFreeze(deepClone(changes));
    this.updateChanges({
      source: "state-change",
      sourceDetail: "internal-restoreMemento",
      changes,
      isReset: false
    });
  }
  findAxis(axisId) {
    for (const a of this.axes) {
      if (a.id === axisId)
        return a;
    }
  }
  getAxes() {
    return this.axes;
  }
  setAxes(nextAxes) {
    const { axes } = this;
    axes.length = 0;
    for (const axis of nextAxes) {
      if ("range" in axis) {
        axes.push(axis);
      }
    }
    const oldState = this.state;
    const changes = refreshCoreState(nextAxes, oldState);
    this.state = changes;
    this.lastRestoredState = refreshCoreState(nextAxes, this.lastRestoredState);
    this.updateChanges({ source: "chart-update", sourceDetail: "internal-setAxes", changes, isReset: false });
  }
  setIndependentAxes(independent = true) {
    this.independentAxes = independent;
  }
  setNavigatorEnabled(enabled = true) {
    this.navigatorModule = enabled;
  }
  setZoomModuleEnabled(enabled = true) {
    this.zoomModule = enabled;
  }
  isNavigatorEnabled() {
    return this.navigatorModule;
  }
  isZoomEnabled() {
    return this.zoomModule;
  }
  updateZoom({ source, sourceDetail }, newZoom) {
    const changes = this.toCoreZoomState(newZoom ?? {});
    return this.updateChanges({ source, sourceDetail, changes, isReset: false });
  }
  computeChangedAxesIds(newState) {
    const result = [];
    const oldState = this.state;
    for (const id of strictObjectKeys(newState)) {
      const newAxisState = newState[id] ?? { min: 0, max: 1 };
      const oldAxisState = oldState[id];
      if (oldAxisState == void 0 || oldAxisState.min !== newAxisState.min || oldAxisState.max !== newAxisState.max) {
        result.push(id);
      }
    }
    return result;
  }
  updateChanges(params) {
    const { source, sourceDetail, isReset, changes } = params;
    validateChanges(changes);
    const changedAxes = this.computeChangedAxesIds(changes);
    const oldState = deepClone(this.state);
    const newState = deepClone(this.state);
    for (const id of changedAxes) {
      const axis = newState[id];
      if (axis != void 0) {
        axis.min = changes[id]?.min ?? 0;
        axis.max = changes[id]?.max ?? 1;
      }
    }
    this.state = newState;
    return this.dispatch(source, sourceDetail, changedAxes, isReset, oldState);
  }
  resetZoom({ source, sourceDetail }) {
    this.updateChanges({ source, sourceDetail, changes: this.getRestoredZoom(), isReset: true });
  }
  resetAxisZoom({ source, sourceDetail }, axisId) {
    this.updateChanges({
      source,
      sourceDetail,
      changes: { [axisId]: this.getRestoredZoom()[axisId] },
      isReset: true
    });
  }
  panToBBox(seriesRect, target) {
    if (!this.isZoomEnabled() && !this.isNavigatorEnabled())
      return false;
    const zoom = this.getZoom();
    if (zoom === void 0 || !zoom.x && !zoom.y)
      return false;
    const panIsPossible = seriesRect.width > 0 && seriesRect.height > 0 && Math.abs(target.width) <= Math.abs(seriesRect.width) && Math.abs(target.height) <= Math.abs(seriesRect.height);
    if (!panIsPossible) {
      logger_exports.warnOnce(`cannot pan to target BBox - chart too small?`);
      return false;
    }
    const newZoom = calcPanToBBoxRatios(seriesRect, zoom, target);
    const changes = this.toCoreZoomState(newZoom);
    return this.updateChanges({
      source: "user-interaction",
      sourceDetail: "internal-panToBBox",
      changes,
      isReset: false
    });
  }
  // Fire this event to signal to listeners that the view is changing through a zoom and/or pan change.
  fireZoomPanStartEvent(callerId) {
    this.eventsHub.emit("zoom:pan-start", { callerId });
  }
  extendToEnd(sourcing, direction, extent2) {
    return this.extendWith(sourcing, direction, (end3) => Number(end3) - extent2);
  }
  extendWith({ source, sourceDetail }, direction, fn) {
    const axis = this.getPrimaryAxis(direction);
    if (!axis)
      return;
    const extents = this.getDomainExtents(axis);
    if (!extents)
      return;
    const [, end3] = extents;
    const start2 = fn(end3);
    const ratio2 = this.rangeToRatioAxis(axis, { start: start2 });
    if (!ratio2)
      return;
    this.updateChanges({ source, sourceDetail, changes: { [direction]: ratio2 }, isReset: false });
  }
  updateWith({ source, sourceDetail }, direction, fn) {
    const axis = this.getPrimaryAxis(direction);
    if (!axis)
      return;
    const extents = this.getDomainExtents(axis);
    if (!extents)
      return;
    let [start2, end3] = extents;
    [start2, end3] = fn(start2, end3);
    const ratio2 = this.rangeToRatioAxis(axis, { start: start2, end: end3 });
    if (!ratio2)
      return;
    this.updateChanges({ source, sourceDetail, changes: { [direction]: ratio2 }, isReset: false });
  }
  getZoom() {
    return this.toZoomState(this.state);
  }
  getAxisZoom(axisId) {
    return this.state[axisId] ?? { min: 0, max: 1 };
  }
  getAxisZooms() {
    return this.state;
  }
  getCoreZoom() {
    return this.state;
  }
  getRestoredZoom() {
    return this.lastRestoredState;
  }
  getPrimaryAxisId(direction) {
    return this.getPrimaryAxis(direction)?.id;
  }
  getBoundSeries() {
    const xAxis = this.getPrimaryAxis("x" /* X */);
    const yAxis = this.getPrimaryAxis("y" /* Y */);
    let boundSeries;
    if (this.independentAxes) {
      const xBoundSeries = new Set(xAxis?.boundSeries ?? []);
      const yBoundSeries = new Set(yAxis?.boundSeries ?? []);
      boundSeries = /* @__PURE__ */ new Set();
      for (const series of xBoundSeries) {
        if (yBoundSeries.has(series)) {
          boundSeries.add(series);
        }
      }
    } else {
      boundSeries = /* @__PURE__ */ new Set([...xAxis?.boundSeries ?? [], ...yAxis?.boundSeries ?? []]);
    }
    return boundSeries;
  }
  constrainZoomToItemCount(zoom, minVisibleItems, shouldAutoscale) {
    let xVisibleRange = [zoom.x.min, zoom.x.max];
    let yVisibleRange = shouldAutoscale ? void 0 : [zoom.y.min, zoom.y.max];
    for (const series of this.getBoundSeries()) {
      const nextZoom = series.getZoomRangeFittingItems(xVisibleRange, yVisibleRange, minVisibleItems);
      if (nextZoom == null)
        continue;
      xVisibleRange = nextZoom.x;
      yVisibleRange = nextZoom.y;
    }
    const x = { min: xVisibleRange[0], max: xVisibleRange[1] };
    const y = yVisibleRange ? { min: yVisibleRange[0], max: yVisibleRange[1] } : void 0;
    return definedZoomState({ x, y });
  }
  isVisibleItemsCountAtLeast(zoom, minVisibleItems, opts) {
    const boundSeries = this.getBoundSeries();
    const xVisibleRange = [zoom.x.min, zoom.x.max];
    const yVisibleRange = !opts.includeYVisibleRange && opts.autoScaleYAxis ? void 0 : [zoom.y.min, zoom.y.max];
    let visibleItemsCount = 0;
    for (const series of boundSeries) {
      const remainingItems = minVisibleItems - (visibleItemsCount ?? 0);
      const seriesVisibleItems = series.getVisibleItems(xVisibleRange, yVisibleRange, remainingItems);
      visibleItemsCount += seriesVisibleItems;
      if (visibleItemsCount >= minVisibleItems)
        return true;
    }
    return boundSeries.size === 0;
  }
  getMementoRanges() {
    const zoom = definedZoomState(this.getZoom());
    const memento = {
      rangeX: this.getRangeDirection("x" /* X */, zoom.x),
      rangeY: this.getRangeDirection("y" /* Y */, zoom.y),
      ratioX: { start: zoom.x.min, end: zoom.x.max },
      ratioY: { start: zoom.y.min, end: zoom.y.max },
      autoScaledAxes: void 0
    };
    this.eventsHub.emit("zoom:save-memento", { memento });
    return memento;
  }
  restoreRequiredRange(requiredRangeRatio, requiredRangeDirection) {
    const { lastRestoredRequiredRange, lastRestoredRequiredRangeDirection } = this;
    const directionInvalid = requiredRangeDirection !== "x" /* X */ && requiredRangeDirection !== "y" /* Y */;
    const requiredRangeUnchanged = lastRestoredRequiredRangeDirection === requiredRangeDirection && lastRestoredRequiredRange === requiredRangeRatio;
    const requiredRangeUnset = requiredRangeRatio === 0 && (lastRestoredRequiredRange == null || lastRestoredRequiredRange === 0);
    if (directionInvalid || requiredRangeUnchanged || requiredRangeUnset)
      return;
    const crossAxisId = this.getPrimaryAxisId(requiredRangeDirection);
    if (!crossAxisId)
      return;
    const crossAxisZoom = this.getAxisZoom(crossAxisId);
    const requiredZoom = Math.min(1, 1 / requiredRangeRatio);
    let min = 0;
    let max = 1;
    if (requiredRangeDirection === "x" /* X */) {
      min = clamp(0, 1 - requiredZoom, crossAxisZoom.min);
      max = clamp(0, min + requiredZoom, 1);
    } else {
      max = Math.min(1, crossAxisZoom.max);
      min = max - requiredZoom;
      if (min < 0) {
        max -= min;
        min = 0;
      }
      min = clamp(0, min, 1);
      max = clamp(0, max, 1);
    }
    this.lastRestoredRequiredRange = requiredRangeRatio;
    this.lastRestoredRequiredRangeDirection = requiredRangeDirection;
    const zoom = { [requiredRangeDirection]: { min, max } };
    const changes = this.toCoreZoomState(zoom);
    this.lastRestoredState = deepFreeze(deepClone(changes));
    this.updateChanges({
      source: "state-change",
      sourceDetail: "internal-requiredWidth",
      changes,
      isReset: false
    });
  }
  constrainZoomToRequiredWidth(event) {
    if (this.lastRestoredRequiredRange == null || this.lastRestoredRequiredRangeDirection == null)
      return;
    const axis = this.lastRestoredRequiredRangeDirection;
    const crossAxisId = this.getPrimaryAxisId(this.lastRestoredRequiredRangeDirection);
    if (!crossAxisId)
      return;
    const zoom = event.stateAsDefinedZoom();
    const oldState = event.oldState[crossAxisId];
    const delta5 = zoom[axis].max - zoom[axis].min;
    const minDelta = 1 / this.lastRestoredRequiredRange;
    if (delta5 <= minDelta)
      return;
    event.constrainZoom({
      ...zoom,
      [axis]: { min: oldState.min, max: oldState.min + minDelta }
    });
  }
  dispatch(source, sourceDetail, changedAxes, isReset, oldState) {
    const { x, y } = this.getZoom() ?? {};
    const state = this.state;
    let constrainedState;
    const zoomManager = this;
    const event = {
      source,
      sourceDetail,
      isReset,
      changedAxes,
      state,
      oldState,
      x,
      y,
      stateAsDefinedZoom() {
        return definedZoomState(zoomManager.toZoomState(event.state));
      },
      constrainZoom(restrictions) {
        this.constrainChanges(zoomManager.toCoreZoomState(restrictions));
      },
      constrainChanges(restrictions) {
        constrainedState ?? (constrainedState = deepClone(state));
        for (const id of strictObjectKeys(restrictions)) {
          const src = restrictions[id];
          const dst = constrainedState[id];
          if (src && dst) {
            dst.min = src.min;
            dst.max = src.max;
          }
        }
        event.state = constrainedState;
      }
    };
    this.eventsHub.emit("zoom:change-request", event);
    let wasChangeConstrained = false;
    if (constrainedState && !areEqualCoreZooms(state, constrainedState)) {
      wasChangeConstrained = true;
      this.state = constrainedState;
    }
    const changeAccepted = changedAxes.length > 0 || wasChangeConstrained;
    if (changeAccepted) {
      const acceptedZoom = this.getZoom() ?? {};
      this.eventsHub.emit("zoom:change-complete", { source, sourceDetail, x: acceptedZoom.x });
      this.pendingZoomEventSource = source;
    }
    return changeAccepted;
  }
  getRange(axisId, ratio2) {
    return this.getRangeAxis(this.findAxis(axisId), ratio2);
  }
  getRangeDirection(direction, ratio2) {
    return this.getRangeAxis(this.getPrimaryAxis(direction), ratio2);
  }
  getRangeAxis(axis, ratio2) {
    if (!axis || !ratio2 || !ContinuousScale.is(axis.scale) && !DiscreteTimeScale.is(axis.scale))
      return;
    const extents = this.getDomainPixelExtents(axis);
    if (!extents)
      return;
    const [d0, d1] = extents;
    let start2;
    let end3;
    if (d0 <= d1) {
      start2 = axis.scale.invert(0);
      end3 = axis.scale.invert(d0 + (d1 - d0) * ratio2.max);
    } else {
      start2 = axis.scale.invert(d0 - (d0 - d1) * ratio2.min);
      end3 = axis.scale.invert(0);
    }
    return { start: start2, end: end3 };
  }
  rangeToRatio(axisId, range3) {
    return this.rangeToRatioAxis(this.findAxis(axisId), range3);
  }
  rangeToRatioDirection(direction, range3) {
    return this.rangeToRatioAxis(this.getPrimaryAxis(direction), range3);
  }
  rangeToRatioAxis(axis, range3) {
    if (!axis)
      return;
    const extents = this.getDomainPixelExtents(axis);
    if (!extents)
      return;
    const [d0, d1] = extents;
    const { scale: scale2 } = axis;
    const { start: start2, end: end3 } = range3;
    const [startAlignment = 0 /* Leading */, endAlignment = 1 /* Trailing */] = rangeAlignment(
      start2,
      end3
    );
    const r0 = start2 == null ? d0 : scale2.convert(start2, { alignment: startAlignment });
    const r1 = end3 == null ? d1 : scale2.convert(end3, { alignment: endAlignment }) + (scale2.bandwidth ?? 0);
    if (!isFiniteNumber(r0) || !isFiniteNumber(r1))
      return;
    const [dMin, dMax] = [Math.min(d0, d1), Math.max(d0, d1)];
    if (r0 < dMin || r0 > dMax) {
      logger_exports.warnOnce(
        `Invalid range start [${start2}], expecting a value between [${scale2.invert(d0)}] and [${scale2.invert(d1)}], ignoring.`
      );
      return;
    }
    if (r1 < dMin || r1 > dMax) {
      logger_exports.warnOnce(
        `Invalid range end [${end3}], expecting a value between [${scale2.invert(d0)}] and [${scale2.invert(d1)}], ignoring.`
      );
      return;
    }
    const diff9 = d1 - d0;
    if (diff9 === 0)
      return;
    const min = Math.abs((r0 - d0) / diff9);
    const max = Math.abs((r1 - d0) / diff9);
    if (min >= max)
      return;
    return { min, max };
  }
  getPrimaryAxis(direction) {
    return this.axes?.find((a) => a.direction === direction);
  }
  getDomainExtents(axis) {
    const { domain } = axis.scale;
    const d0 = domain.at(0);
    const d1 = domain.at(-1);
    if (d0 == null || d1 == null)
      return;
    return [d0, d1];
  }
  getDomainPixelExtents(axis) {
    const [d0, d1] = axis.scale.range;
    if (!isFiniteNumber(d0) || !isFiniteNumber(d1))
      return;
    return [d0, d1];
  }
};

// packages/ag-charts-community/src/chart/layout/layoutManager.ts
var LayoutElement = /* @__PURE__ */ ((LayoutElement8) => {
  LayoutElement8[LayoutElement8["Caption"] = 0] = "Caption";
  LayoutElement8[LayoutElement8["Legend"] = 1] = "Legend";
  LayoutElement8[LayoutElement8["ToolbarLeft"] = 2] = "ToolbarLeft";
  LayoutElement8[LayoutElement8["ToolbarBottom"] = 3] = "ToolbarBottom";
  LayoutElement8[LayoutElement8["Scrollbar"] = 4] = "Scrollbar";
  LayoutElement8[LayoutElement8["Navigator"] = 5] = "Navigator";
  LayoutElement8[LayoutElement8["Overlay"] = 6] = "Overlay";
  return LayoutElement8;
})(LayoutElement || {});
var LayoutManager = class {
  constructor(eventsHub) {
    this.eventsHub = eventsHub;
    this.elements = /* @__PURE__ */ new Map();
  }
  registerElement(element2, listener) {
    if (this.elements.has(element2)) {
      this.elements.get(element2).add(listener);
    } else {
      this.elements.set(element2, /* @__PURE__ */ new Set([listener]));
    }
    return () => this.elements.get(element2)?.delete(listener);
  }
  createContext(width2, height2) {
    const context = { width: width2, height: height2, layoutBox: new BBox(0, 0, width2, height2), scrollbars: {} };
    for (const element2 of Object.values(LayoutElement)) {
      if (typeof element2 !== "number")
        continue;
      const listeners = this.elements.get(element2);
      if (listeners) {
        for (const listener of listeners) {
          listener(context);
        }
      }
    }
    return context;
  }
  emitLayoutComplete({ width: width2, height: height2 }, options) {
    this.eventsHub.emit("layout:complete", {
      axes: options.axes ?? {},
      chart: { width: width2, height: height2 },
      clipSeries: options.clipSeries ?? false,
      series: options.series
    });
  }
};

// packages/ag-charts-community/src/chart/layout/seriesLabelLayoutManager.ts
var SeriesLabelLayoutManager = class {
  constructor() {
    this.labelData = /* @__PURE__ */ new Map();
  }
  updateLabels(placedLabelSeries, padding2, seriesRect = BBox.zero) {
    const bounds = {
      x: -padding2.left,
      y: -padding2.top,
      width: seriesRect.width + padding2.left + padding2.right,
      height: seriesRect.height + padding2.top + padding2.bottom
    };
    const expectedSeriesId = new Set(placedLabelSeries.map((s) => s.id));
    for (const seriesId of this.labelData.keys()) {
      if (!expectedSeriesId.has(seriesId)) {
        this.labelData.delete(seriesId);
      }
    }
    for (const series of placedLabelSeries) {
      const labelData = series.getLabelData();
      if (labelData.every(isPointLabelDatum)) {
        this.labelData.set(series.id, labelData);
      }
    }
    const placedLabels = placeLabels(this.labelData, bounds, 5);
    for (const series of placedLabelSeries) {
      series.updatePlacedLabelData?.(placedLabels.get(series.id) ?? []);
    }
  }
};

// packages/ag-charts-community/src/chart/legend/legendManager.ts
var LegendManager = class {
  constructor(eventsHub) {
    this.eventsHub = eventsHub;
    this.mementoOriginatorKey = "legend";
    this.legendDataMap = /* @__PURE__ */ new Map();
  }
  createMemento() {
    return this.getData().filter(({ hideInLegend, isFixed }) => !hideInLegend && !isFixed).map(({ enabled, seriesId, itemId, legendItemName }) => ({
      visible: enabled,
      seriesId,
      itemId,
      legendItemName
    }));
  }
  guardMemento(blob) {
    return blob == null || isArray(blob);
  }
  restoreMemento(_version, _mementoVersion, memento) {
    if (memento) {
      for (const datum of memento) {
        const { seriesId, data } = this.getRestoredData(datum) ?? {};
        if (!seriesId || !data) {
          continue;
        }
        this.updateData(seriesId, data);
      }
    }
    this.update();
  }
  getRestoredData(datum) {
    const { seriesId, itemId, legendItemName, visible } = datum;
    if (seriesId) {
      const legendData = this.legendDataMap.get(seriesId) ?? [];
      const data = legendData.map((d) => {
        const match = d.seriesId === seriesId && (!itemId || d.itemId === itemId);
        if (match && d.isFixed) {
          this.warnFixed(d.seriesId, d.itemId);
        }
        return !d.isFixed && match ? { ...d, enabled: visible } : d;
      });
      return { seriesId, data };
    }
    if (itemId == null && legendItemName == null) {
      return;
    }
    for (const legendDatum of this.getData()) {
      if (itemId != null && legendDatum.itemId !== itemId || legendItemName != null && legendDatum.legendItemName !== legendItemName) {
        continue;
      }
      if (legendDatum.isFixed) {
        this.warnFixed(legendDatum.seriesId, itemId);
        return;
      }
      const seriesLegendData = (this.legendDataMap.get(legendDatum.seriesId) ?? []).map(
        (d) => d.itemId === itemId || d.legendItemName === legendItemName ? { ...d, enabled: visible } : d
      );
      return {
        seriesId: legendDatum.seriesId,
        data: seriesLegendData
      };
    }
  }
  warnFixed(seriesId, itemId) {
    logger_exports.warnOnce(
      `The legend item with seriesId [${seriesId}] and itemId [${itemId}] is not configurable, this series item cannot be toggled through the legend.`
    );
  }
  update(data) {
    this.eventsHub.emit("legend:change", {
      legendData: data ?? this.getData()
    });
  }
  updateData(seriesId, data = []) {
    this.eventsHub.emit("legend:change-partial", { seriesId, legendData: data });
    this.legendDataMap.set(seriesId, data);
  }
  clearData() {
    this.legendDataMap.clear();
  }
  toggleItem(enabled, seriesId, itemId, legendItemName) {
    if (legendItemName) {
      for (const datum of this.getData()) {
        const newData = (this.legendDataMap.get(datum.seriesId) ?? []).map(
          (d) => d.legendItemName === legendItemName ? { ...d, enabled } : d
        );
        this.updateData(datum.seriesId, newData);
      }
      return;
    }
    const seriesLegendData = this.getData(seriesId);
    const singleLegendItem = seriesLegendData.length === 1;
    const data = seriesLegendData.map(
      (datum) => itemId == null && singleLegendItem || datum.itemId === itemId ? { ...datum, enabled } : datum
    );
    this.updateData(seriesId, data);
  }
  getData(seriesId) {
    if (seriesId) {
      return this.legendDataMap.get(seriesId) ?? [];
    }
    return [...this.legendDataMap].reduce(
      (data, [_, legendData]) => data.concat(legendData),
      []
    );
  }
  getDatum({ seriesId, itemId } = {}) {
    return this.getData(seriesId).find((datum) => datum.itemId === itemId);
  }
  getSeriesEnabled(seriesId) {
    const data = this.getData(seriesId);
    if (data.length > 0) {
      return data.some((d) => d.enabled);
    }
  }
  getItemEnabled({ seriesId, itemId } = {}) {
    return this.getDatum({ seriesId, itemId })?.enabled ?? true;
  }
};

// packages/ag-charts-community/src/chart/optionsGraphService.ts
var OptionsGraphService = class {
  updateCallback(resolvePartialCallback) {
    this.resolvePartialCallback = resolvePartialCallback;
  }
  resolvePartial(path, partialOptions, resolveOptions) {
    return this.resolvePartialCallback?.(path, partialOptions, resolveOptions);
  }
};

// packages/ag-charts-community/src/scale/irregularBandScale.ts
var IrregularBandScale = class extends BandScale {
  constructor() {
    super(...arguments);
    this.type = "category";
    // TODO: 'irregular-band'?
    this.defaultTickCount = 0;
    this._hasFixedWidth = false;
    this._paddingInnerWidth = 0;
    this._domain = [];
    this._bandRanges = /* @__PURE__ */ new Map();
  }
  set domain(values) {
    if (this._domain === values)
      return;
    if (values.length === 0) {
      this._bandRanges.clear();
      this._hasFixedWidth = false;
    }
    this.invalid = true;
    this._domain = values;
  }
  get domain() {
    return this._domain;
  }
  get bands() {
    return this.domain;
  }
  addBand(groupIndex, stackIndex, value) {
    this._domain.push(this.getDomainValue(groupIndex, stackIndex));
    if (!this._bandRanges.has(groupIndex)) {
      this._bandRanges.set(groupIndex, /* @__PURE__ */ new Map());
    }
    this._bandRanges.get(groupIndex).set(stackIndex, value);
    this._hasFixedWidth || (this._hasFixedWidth = value != null);
    this.invalid = true;
  }
  getDomainValue(groupIndex, stackIndex) {
    return `${groupIndex}-${stackIndex}`;
  }
  findIndex(value) {
    let index = 0;
    for (const key of this._bandRanges.keys()) {
      if (key === value)
        return index;
      index++;
    }
  }
  convert(domainValue) {
    const { _bandwidth, _bandRanges, _inset, _paddingInnerWidth } = this;
    let value = _inset;
    const valueDs = domainValue.split("-");
    const valueGroupIndex = Number(valueDs[0]);
    if (!this._hasFixedWidth) {
      return super.convert(valueGroupIndex);
    }
    for (let i = 0; i < valueGroupIndex; i++) {
      const stacks = _bandRanges.get(i);
      if (!stacks) {
        value += _paddingInnerWidth;
        continue;
      }
      let maxStackWidth = 0;
      for (const width2 of stacks.values()) {
        maxStackWidth = Math.max(maxStackWidth, width2 == null ? _bandwidth : width2);
      }
      value += maxStackWidth + _paddingInnerWidth;
    }
    return value;
  }
  invert(_value, _nearest) {
    return;
  }
  getBandCountForUpdate() {
    return this._bandRanges.size;
  }
  update() {
    if (!this._hasFixedWidth) {
      return super.update();
    }
    const [r0, r1] = this.range;
    let { paddingInner } = this;
    const bandCount = this.getBandCountForUpdate();
    if (bandCount === 0)
      return;
    let totalBandRange = 0;
    let bandCountWithUnfixedWidths = bandCount;
    let bandCountWithOnlyFixedWidths = bandCount;
    for (const stacks of this._bandRanges.values()) {
      let maxStackWidth = 0;
      let hasUnfixed = false;
      for (const width2 of stacks.values()) {
        if (width2 == null) {
          hasUnfixed = true;
          continue;
        }
        maxStackWidth = Math.max(maxStackWidth, width2);
      }
      if (hasUnfixed) {
        bandCountWithOnlyFixedWidths -= 1;
      } else {
        bandCountWithUnfixedWidths -= 1;
        totalBandRange += maxStackWidth;
      }
    }
    if (bandCount === 1) {
      paddingInner = 0;
    }
    const targetRangeDistance = r1 - r0;
    const paddingInnerWidth = targetRangeDistance / bandCount * paddingInner;
    const actualRangeDistance = totalBandRange + paddingInnerWidth * (bandCount - 1);
    const rangeDiff = targetRangeDistance - actualRangeDistance;
    let inset = r0;
    let rawBandwidth = bandCountWithUnfixedWidths > 0 && rangeDiff >= 0 ? rangeDiff / bandCountWithUnfixedWidths : targetRangeDistance / bandCount;
    let bandwidth = rawBandwidth;
    if (bandCountWithOnlyFixedWidths === bandCount && rangeDiff > 0) {
      inset += rangeDiff / 2;
    }
    const round4 = this.round && Math.floor(bandwidth) > 0;
    if (round4) {
      inset = Math.round(inset);
      bandwidth = Math.round(bandwidth);
    }
    if (rangeDiff < 0) {
      rawBandwidth = 0;
      bandwidth = 0;
    }
    this._inset = inset;
    this._bandwidth = bandwidth;
    this._rawBandwidth = rawBandwidth;
    this._paddingInnerWidth = paddingInnerWidth;
  }
  normalizeDomains(..._domains) {
    return { domain: [], animatable: false };
  }
  toDomain(_value) {
    return void 0;
  }
};

// packages/ag-charts-community/src/chart/series/seriesStateManager.ts
var SeriesStateManager = class {
  constructor() {
    this.groups = /* @__PURE__ */ new Map();
    this.groupScales = /* @__PURE__ */ new Map();
  }
  registerSeries({ internalId, seriesGrouping, visible, width: width2, type }) {
    if (!seriesGrouping)
      return;
    let group = this.groups.get(type);
    if (group == null) {
      group = /* @__PURE__ */ new Map();
      this.groups.set(type, group);
    }
    group.set(internalId, { grouping: seriesGrouping, visible, width: width2 });
  }
  updateSeries({ internalId, seriesGrouping, visible, width: width2, type }) {
    if (!seriesGrouping)
      return;
    const entry = this.groups.get(type)?.get(internalId);
    if (entry) {
      entry.grouping = seriesGrouping;
      entry.width = width2;
      entry.visible = visible;
    }
  }
  deregisterSeries({ internalId, type }) {
    const group = this.groups.get(type);
    if (group == null)
      return;
    group.delete(internalId);
    if (group.size === 0) {
      this.groups.delete(type);
    }
  }
  getVisiblePeerGroupIndex({ type, seriesGrouping, visible }) {
    if (!seriesGrouping) {
      return { visibleGroupCount: visible ? 1 : 0, visibleSameStackCount: visible ? 1 : 0, index: 0 };
    }
    const visibleGroupsSet = /* @__PURE__ */ new Set();
    const visibleSameStackSet = /* @__PURE__ */ new Set();
    const group = this.groups.get(type);
    for (const entry of group?.values() ?? []) {
      if (!entry.visible)
        continue;
      visibleGroupsSet.add(entry.grouping.groupIndex);
      if (entry.grouping.groupIndex === seriesGrouping.groupIndex) {
        visibleSameStackSet.add(entry.grouping.stackIndex);
      }
    }
    const visibleGroups = Array.from(visibleGroupsSet);
    visibleGroups.sort((a, b) => a - b);
    return {
      visibleGroupCount: visibleGroups.length,
      visibleSameStackCount: visibleSameStackSet.size,
      index: visibleGroups.indexOf(seriesGrouping.groupIndex)
    };
  }
  updateGroupScale({ type }, bandwidth, axis) {
    const groupScale = this.groupScales.get(type) ?? new IrregularBandScale();
    this.groupScales.set(type, groupScale);
    groupScale.domain = [];
    const group = this.groups.get(type);
    for (const entry of group?.values() ?? []) {
      if (!entry.visible)
        continue;
      groupScale.addBand(entry.grouping.groupIndex, entry.grouping.stackIndex, entry.width);
    }
    if (groupScale.domain.length === 0) {
      groupScale.addBand(0, 0, void 0);
    }
    groupScale.range = [0, bandwidth];
    if (axis.type === "grouped-category") {
      groupScale.paddingInner = axis.groupPaddingInner;
    } else if (axis.type === "category" || axis.type === "unit-time") {
      groupScale.paddingInner = axis.groupPaddingInner;
      groupScale.round = groupScale.padding !== 0;
    } else {
      groupScale.padding = 0;
    }
    groupScale.update();
  }
  getGroupScale({ type }) {
    return this.groupScales.get(type);
  }
  getGroupOffset(series) {
    const { seriesGrouping } = series;
    if (!seriesGrouping)
      return 0;
    const groupScale = this.getGroupScale(series);
    if (!groupScale)
      return 0;
    const domainValue = groupScale.getDomainValue(seriesGrouping.groupIndex, seriesGrouping.stackIndex);
    return groupScale.convert(domainValue);
  }
  getStackOffset(series, barWidth) {
    const { seriesGrouping } = series;
    if (!seriesGrouping)
      return 0;
    const group = this.groups.get(series.type);
    if (!group)
      return 0;
    const scale2 = this.getGroupScale(series);
    if (!scale2)
      return 0;
    const stackCount = seriesGrouping.stackCount ?? 0;
    if (stackCount < 1)
      return 0;
    let maxStackWidth = 0;
    for (const entry of group.values()) {
      if (!entry.visible)
        continue;
      if (entry.grouping.groupIndex !== seriesGrouping.groupIndex)
        continue;
      maxStackWidth = Math.max(maxStackWidth, entry.width ?? scale2.bandwidth);
    }
    if (maxStackWidth === 0)
      return 0;
    return maxStackWidth / 2 - barWidth / 2;
  }
};

// packages/ag-charts-community/src/chart/updateService.ts
var UpdateService = class {
  constructor(updateCallback) {
    this.updateCallback = updateCallback;
    this.events = new EventEmitter();
  }
  addListener(eventName, listener) {
    return this.events.on(eventName, listener);
  }
  destroy() {
    this.events.clear();
  }
  update(type = 0 /* FULL */, options) {
    this.updateCallback(type, options);
  }
  dispatchUpdateComplete(apiUpdate, wasShortcut) {
    this.events.emit("update-complete", { type: "update-complete", apiUpdate, wasShortcut });
  }
  dispatchPreDomUpdate() {
    this.events.emit("pre-dom-update", { type: "pre-dom-update" });
  }
  dispatchPreSeriesUpdate(requiredRangeRatio, requiredRangeDirection) {
    this.events.emit("pre-series-update", {
      type: "pre-series-update",
      requiredRangeRatio,
      requiredRangeDirection
    });
  }
  dispatchPreSceneRender() {
    this.events.emit("pre-scene-render", { type: "pre-scene-render" });
  }
  dispatchProcessData({ series }) {
    this.events.emit("process-data", { type: "process-data", series });
  }
};

// packages/ag-charts-community/src/chart/chartContext.ts
var ChartContext = class {
  constructor(chart, vars) {
    this.eventsHub = new EventEmitter();
    this.callbackCache = new CallbackCache();
    this.highlightManager = new HighlightManager(this.eventsHub);
    this.formatManager = new FormatManager();
    this.layoutManager = new LayoutManager(this.eventsHub);
    this.localeManager = new LocaleManager(this.eventsHub);
    this.seriesStateManager = new SeriesStateManager();
    this.stateManager = new StateManager();
    this.seriesLabelLayoutManager = new SeriesLabelLayoutManager();
    this.cleanup = new CleanupRegistry();
    const {
      scene,
      root,
      syncManager,
      container,
      fireEvent,
      updateCallback,
      updateMutex,
      styleContainer,
      skipCss,
      chartType,
      domMode,
      withDragInterpretation
    } = vars;
    this.chartService = chart;
    this.syncManager = syncManager;
    this.domManager = new DOMManager(
      this.eventsHub,
      this.chartService,
      container,
      styleContainer,
      skipCss,
      domMode
    );
    this.widgets = new WidgetSet(this.domManager, { withDragInterpretation });
    const canvasElement = this.domManager.addChild(
      "canvas",
      "scene-canvas",
      scene?.canvas.element
    );
    this.scene = scene ?? new Scene({ canvasElement });
    this.scene.setRoot(root);
    this.cleanup.register(
      this.scene.on("scene-changed", () => {
        this.updateService.update(9 /* SCENE_RENDER */);
      })
    );
    this.axisManager = new AxisManager(this.eventsHub, root);
    this.legendManager = new LegendManager(this.eventsHub);
    this.annotationManager = new AnnotationManager(this.eventsHub, chart.annotationRoot, fireEvent);
    this.chartTypeOriginator = new ChartTypeOriginator(chart);
    this.interactionManager = new InteractionManager();
    this.contextMenuRegistry = new ContextMenuRegistry(this.eventsHub);
    this.optionsGraphService = new OptionsGraphService();
    this.updateService = new UpdateService(updateCallback);
    this.activeManager = new ActiveManager(
      this.chartService,
      this.eventsHub,
      this.updateService,
      this.interactionManager,
      fireEvent
    );
    this.proxyInteractionService = new ProxyInteractionService(this.eventsHub, this.localeManager, this.domManager);
    this.fontManager = new FontManager(this.domManager, this.updateService);
    this.historyManager = new HistoryManager(this.eventsHub);
    this.animationManager = new AnimationManager(this.interactionManager, updateMutex);
    this.dataService = new DataService(this.eventsHub, chart, this.animationManager);
    this.tooltipManager = new TooltipManager(this.eventsHub, this.localeManager, this.domManager, chart.tooltip);
    this.zoomManager = new ZoomManager(this.eventsHub, this.updateService, fireEvent);
    for (const module2 of moduleRegistry_exports.listModulesByType("plugin" /* Plugin */)) {
      if (!module2.chartType || module2.chartType === chartType) {
        module2.patchContext?.(this);
      }
    }
  }
  destroy() {
    this.animationManager.destroy();
    this.axisManager.destroy();
    this.callbackCache.invalidateCache();
    this.domManager.destroy();
    this.fontManager.destroy();
    this.proxyInteractionService.destroy();
    this.tooltipManager.destroy();
    this.zoomManager.destroy();
    this.widgets.destroy();
    this.cleanup.flush();
  }
};

// packages/ag-charts-community/src/chart/chartHighlight.ts
var ChartHighlight = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.range = "tooltip";
    this.drawingMode = "cutout";
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ChartHighlight.prototype, "range", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChartHighlight.prototype, "drawingMode", 2);

// packages/ag-charts-community/src/chart/data/caching.ts
function setsEqual(a, b) {
  if (a.size !== b.size)
    return false;
  for (const value of a) {
    if (!b.has(value))
      return false;
  }
  return true;
}
function idsMapEqual(a, b) {
  if (a == null || b == null)
    return a === b;
  if (a.size !== b.size)
    return false;
  for (const [key, aValue] of a) {
    const bValue = b.get(key);
    if (bValue == null)
      return false;
    if (!setsEqual(aValue, bValue))
      return false;
  }
  return true;
}
function propsEqual(a, b) {
  if (a.length !== b.length)
    return false;
  for (let i = 0; i < a.length; i += 1) {
    const { type: typeA, idsMap: idsMapA, scopes: scopesA, data: dataA, ...propA } = a[i];
    const { type: typeB, idsMap: idsMapB, scopes: scopesB, data: dataB, ...propB } = b[i];
    if (typeA !== typeB)
      return false;
    if (scopesA && scopesB && !arraysEqual(scopesA, scopesB))
      return false;
    if (dataA && dataB && dataA !== dataB)
      return false;
    if (!objectsEqual(propA, propB) || !idsMapEqual(idsMapA, idsMapB))
      return false;
  }
  return true;
}
function optsEqual(a, b) {
  const { props: propsA, ...restA } = a;
  const { props: propsB, ...restB } = b;
  return objectsEqual(restA, restB) && propsEqual(propsA, propsB);
}
function canReuseCachedData(cachedDataItem, dataSet, ids, opts) {
  if (dataSet !== cachedDataItem.dataSet) {
    return false;
  }
  return arraysEqual(ids, cachedDataItem.ids) && optsEqual(opts, cachedDataItem.opts);
}

// packages/ag-charts-community/src/chart/data/dataController.ts
function getPropertyKeys(props) {
  return props.filter((p) => p.type === "key").map((p) => p.property).join(";");
}
var _DataController = class _DataController {
  constructor(mode, suppressFieldDotNotation, eventsHub) {
    this.mode = mode;
    this.suppressFieldDotNotation = suppressFieldDotNotation;
    this.eventsHub = eventsHub;
    this.debug = debugLogger_exports.create(true, "data-model");
    this.requested = [];
    this.status = "setup";
  }
  async request(id, dataSet, opts) {
    if (this.status !== "setup") {
      throw new Error(`AG Charts - data request after data setup phase.`);
    }
    return new Promise((resolve, reject) => {
      this.requested.push({ id, opts, dataSet, resolve, reject });
    });
  }
  execute(cachedData) {
    if (this.status !== "setup") {
      throw new Error(`AG Charts - data request after data setup phase.`);
    }
    this.status = "executed";
    const dataSets = /* @__PURE__ */ new Map();
    for (const request of this.requested) {
      if (request.dataSet.hasPendingTransactions()) {
        dataSets.set(request.dataSet, request.dataSet.getChangeDescription());
      }
      request.dataSet.commitPendingTransactions();
    }
    this.debug("DataController.execute() - requested", this.requested);
    const valid = this.validateRequests(this.requested);
    this.debug("DataController.execute() - validated", valid);
    const merged = this.mergeRequested(valid);
    this.debug("DataController.execute() - merged", merged);
    if (this.debug.check()) {
      getWindow().processedData = [];
    }
    const nextCachedData = [];
    for (const { dataSet, ids, opts, resolves, rejects } of merged) {
      let cachePredicateFn2 = function(cacheItem) {
        return canReuseCachedData(cacheItem, dataSet, ids, opts);
      };
      var cachePredicateFn = cachePredicateFn2;
      const reusableCache = cachedData?.find(cachePredicateFn2);
      const resolveResult = (dataModel2, processedData2) => {
        if (this.debug.check()) {
          getWindow("processedData").push(processedData2);
        }
        if (processedData2 == null) {
          for (const cb of rejects) {
            cb(new Error(`AG Charts - no processed data generated`));
          }
          return;
        }
        nextCachedData.push({ opts, dataSet, dataLength: dataSet.data.length, ids, dataModel: dataModel2, processedData: processedData2 });
        for (const resolve of resolves) {
          resolve({ dataModel: dataModel2, processedData: processedData2 });
        }
      };
      const fullReprocess = () => {
        try {
          const dataModel2 = new DataModel(
            opts,
            this.mode,
            this.suppressFieldDotNotation,
            this.eventsHub
          );
          const sources = new Map(valid.map((v) => [v.id, v.dataSet]));
          const processedData2 = dataModel2.processData(sources);
          resolveResult(dataModel2, processedData2);
          return dataModel2;
        } catch (error2) {
          for (const cb of rejects) {
            cb(error2);
          }
        }
      };
      if (reusableCache == null) {
        fullReprocess();
        continue;
      }
      const { dataModel, processedData } = reusableCache;
      const changeDescription = dataSets.get(dataSet);
      if (processedData && changeDescription && dataModel.isReprocessingSupported(processedData)) {
        this.debug("DataController.execute() - reprocessing data", processedData, dataSet);
        dataModel.reprocessData(processedData, dataSets);
        if (debugLogger_exports.check("data-model:reprocess-diff")) {
          const baselineModel = new DataModel(
            opts,
            this.mode,
            this.suppressFieldDotNotation,
            this.eventsHub
          );
          const sources = new Map(valid.map((v) => [v.id, v.dataSet]));
          const baselineData = baselineModel.processData(sources);
          const reprocessedJson = JSON.parse(JSON.stringify(processedData, _DataController.jsonReplacer));
          const baselineJson = JSON.parse(JSON.stringify(baselineData, _DataController.jsonReplacer));
          delete reprocessedJson.time;
          delete reprocessedJson.optimizations;
          delete baselineJson.time;
          delete baselineJson.optimizations;
          const diff9 = jsonDiff(baselineJson, reprocessedJson);
          if (diff9) {
            logger_exports.log("\u26A0\uFE0F DATA-MODEL REPROCESS DIFF DETECTED \u26A0\uFE0F");
            logger_exports.log("Difference between incremental update and full reprocess:");
            logger_exports.log("");
            logger_exports.log("BASELINE (full reprocess):");
            logger_exports.log(JSON.stringify(baselineJson, null, 2));
            logger_exports.log("");
            logger_exports.log("REPROCESSED (incremental update):");
            logger_exports.log(JSON.stringify(reprocessedJson, null, 2));
            logger_exports.log("");
            logger_exports.log("DIFF (what changed):");
            logger_exports.log(JSON.stringify(diff9, null, 2));
          } else {
            logger_exports.log("\u2705 Data-model reprocess matches baseline (no diff)");
          }
        }
        resolveResult(dataModel, processedData);
        continue;
      }
      fullReprocess();
    }
    return nextCachedData;
  }
  validateRequests(requested) {
    const valid = [];
    for (const [index, request] of requested.entries()) {
      if (index > 0 && request.dataSet.data.length !== requested[0].dataSet.data.length && request.opts.groupByData === false && request.opts.groupByKeys === false) {
        request.reject(
          new Error("all series[].data arrays must be of the same length and have matching keys.")
        );
      } else {
        valid.push(request);
      }
    }
    return valid;
  }
  mergeRequested(requested) {
    const grouped = [];
    for (const request of requested) {
      const match = grouped.find(_DataController.groupMatch(request));
      if (match) {
        match.push(request);
      } else {
        grouped.push([request]);
      }
    }
    return grouped.map(_DataController.mergeRequests);
  }
  static groupMatch({ dataSet, opts }) {
    const { groupByData, groupByKeys = false, groupByFn, props } = opts;
    const propsKeys = getPropertyKeys(props);
    return ([group]) => (groupByData === false || group.dataSet === dataSet) && (group.opts.groupByKeys ?? false) === groupByKeys && group.opts.groupByFn === groupByFn && getPropertyKeys(group.opts.props) === propsKeys;
  }
  static mergeRequests(requests) {
    const result = {
      ids: [],
      rejects: [],
      resolves: [],
      dataSet: requests[0].dataSet,
      opts: { ...requests[0].opts, props: [] }
    };
    const optsByTypeAndDataId = /* @__PURE__ */ new Map();
    const dataIds = /* @__PURE__ */ new Map();
    let nextDataId = 0;
    for (const request of requests) {
      const {
        id,
        dataSet,
        resolve,
        reject,
        opts: { props, ...opts }
      } = request;
      result.ids.push(id);
      result.rejects.push(reject);
      result.resolves.push(resolve);
      result.dataSet ?? (result.dataSet = dataSet);
      result.opts ?? (result.opts = { ...opts, props: [] });
      for (const prop of props) {
        const clone2 = { ...prop, scopes: [id], data: dataSet.data };
        _DataController.createIdsMap(id, clone2);
        let dataId;
        if (_DataController.crossScopeMergableTypes.has(clone2.type)) {
          dataId = -1;
        } else if (dataIds.has(dataSet.data)) {
          dataId = dataIds.get(dataSet.data);
        } else {
          dataId = nextDataId++;
          dataIds.set(dataSet.data, dataId);
        }
        const matchKey = `${clone2.type}-${dataId}-${clone2.groupId}`;
        const matches = optsByTypeAndDataId.get(matchKey);
        const match = matches?.find((existing) => _DataController.deepEqual(existing, clone2));
        if (matches == null) {
          result.opts.props.push(clone2);
          optsByTypeAndDataId.set(matchKey, [clone2]);
          continue;
        } else if (match == null) {
          result.opts.props.push(clone2);
          matches.push(clone2);
          continue;
        }
        if (clone2.scopes != null) {
          match.scopes ?? (match.scopes = []);
          match.scopes.push(...clone2.scopes);
        }
        if ((match.type === "key" || match.type === "value") && clone2.idsMap?.size) {
          match.idsMap ?? (match.idsMap = /* @__PURE__ */ new Map());
          _DataController.mergeIdsMap(clone2.idsMap, match.idsMap);
        }
      }
    }
    return result;
  }
  static mergeIdsMap(fromMap, toMap) {
    for (const [scope, ids] of fromMap) {
      const toMapValue = toMap.get(scope);
      if (toMapValue == null) {
        toMap.set(scope, new Set(ids));
      } else {
        for (const id of ids) {
          toMapValue.add(id);
        }
      }
    }
  }
  static createIdsMap(scope, prop) {
    if (prop.id == null)
      return;
    prop.idsMap ?? (prop.idsMap = /* @__PURE__ */ new Map());
    if (prop.idsMap.has(scope)) {
      prop.idsMap.get(scope).add(prop.id);
    } else {
      prop.idsMap.set(scope, /* @__PURE__ */ new Set([prop.id]));
    }
  }
  static deepEqual(a, b) {
    if (a === b) {
      return true;
    }
    if (a && b && typeof a == "object" && typeof b == "object") {
      if (a.constructor !== b.constructor) {
        return false;
      }
      let i, length2;
      if (Array.isArray(a)) {
        length2 = a.length;
        if (length2 !== b.length) {
          return false;
        }
        for (i = length2 - 1; i >= 0; i--) {
          if (!_DataController.deepEqual(a[i], b[i])) {
            return false;
          }
        }
        return true;
      }
      const keys = Object.keys(a);
      length2 = keys.length;
      if (length2 !== Object.keys(b).length) {
        return false;
      }
      for (i = length2 - 1; i >= 0; i--) {
        const key = keys[i];
        if (!_DataController.skipKeys.has(key) && (!Object.hasOwn(b, key) || !_DataController.deepEqual(a[key], b[key]))) {
          return false;
        }
      }
      return true;
    }
    return false;
  }
  /** JSON replacer for serializing non-JSON-serializable objects like Map and Set */
  static jsonReplacer(_key, value) {
    if (value instanceof Map) {
      return { __type: "Map", value: Array.from(value.entries()) };
    }
    if (value instanceof Set) {
      return { __type: "Set", value: Array.from(value) };
    }
    return value;
  }
};
_DataController.crossScopeMergableTypes = /* @__PURE__ */ new Set(["key", "group-value-processor"]);
// optimized version of deep equality for `mergeRequests` which can potentially loop over 1M times
_DataController.skipKeys = /* @__PURE__ */ new Set(["id", "idsMap", "type", "scopes", "data"]);
var DataController = _DataController;

// packages/ag-charts-community/src/chart/data/dataSet.ts
var DataSet = class _DataSet {
  constructor(data) {
    this.data = data;
    this.pendingTransactions = [];
  }
  /**
   * Creates an empty DataSet.
   */
  static empty() {
    return new _DataSet([]);
  }
  /**
   * Wraps existing data in a DataSet.
   */
  static wrap(data) {
    return new _DataSet(data);
  }
  netSize() {
    if (!this.hasPendingTransactions()) {
      return this.data.length;
    }
    const changeDesc = this.getChangeDescription();
    return changeDesc ? changeDesc.indexMap.finalLength : this.data.length;
  }
  /**
   * Queues a transaction (applied on commit).
   * Normalizes AG Grid-compatible format (add/addIndex) to internal format (prepend/append).
   */
  addTransaction(transaction) {
    const normalized2 = this.normalizeTransaction(transaction);
    this.pendingTransactions.push(normalized2);
    this.cachedChangeDescription = void 0;
  }
  /**
   * @returns A deep clone of the DataSet.
   */
  deepClone() {
    return new _DataSet([...this.data]);
  }
  /**
   * Converts AG Grid-compatible transaction format to internal format.
   * Maps `add` + `addIndex` to prepend, append, or arbitrary insertion based on the index.
   */
  normalizeTransaction(transaction) {
    const { add: add2, addIndex, prepend, append, remove, update } = transaction;
    if (add2 === void 0) {
      return transaction;
    }
    const result = { remove, update };
    if (prepend)
      result.prepend = prepend;
    if (append)
      result.append = append;
    if (add2 && add2.length > 0) {
      const currentSize = this.netSize();
      if (addIndex === void 0 || addIndex >= currentSize) {
        result.append = append ? [...append, ...add2] : add2;
      } else if (addIndex === 0) {
        result.prepend = prepend ? [...add2, ...prepend] : add2;
      } else {
        result.insertions = [{ index: addIndex, items: add2 }];
      }
    }
    return result;
  }
  hasPendingTransactions() {
    return this.pendingTransactions.length > 0;
  }
  getPendingTransactionCount() {
    return this.pendingTransactions.length;
  }
  /** Applies all pending transactions to the data array. */
  commitPendingTransactions() {
    if (!this.hasPendingTransactions()) {
      return false;
    }
    const changeDescription = this.getChangeDescription();
    if (!changeDescription) {
      return false;
    }
    const prependedValues = changeDescription.getPrependedValues();
    const insertionValues = changeDescription.getInsertionValues();
    const appendedValues = changeDescription.getAppendedValues();
    const allInsertionValues = [...prependedValues, ...insertionValues, ...appendedValues];
    let insertionValueIndex = 0;
    changeDescription.applyToArray(this.data, function applyToArrayResultFn(destIndex) {
      if (insertionValueIndex >= allInsertionValues.length) {
        throw new Error(`AG Charts - Internal error: No insertion value found for index ${destIndex}`);
      }
      return allInsertionValues[insertionValueIndex++];
    });
    this.pendingTransactions = [];
    this.cachedChangeDescription = void 0;
    this.updateItemToIndexCache(changeDescription, appendedValues, prependedValues, insertionValues);
    return true;
  }
  /** Updates item→index cache incrementally, or invalidates for complex changes. */
  updateItemToIndexCache(changeDescription, appendedValues, prependedValues, insertionValues) {
    if (!this.itemToIndexCache)
      return;
    const { indexMap } = changeDescription;
    const { totalPrependCount, totalAppendCount, removedIndices } = indexMap;
    const hasRemovals = removedIndices.size > 0;
    const hasArbitraryInsertions = insertionValues.length > 0;
    if (!hasRemovals && totalPrependCount === 0 && totalAppendCount === 0 && !hasArbitraryInsertions) {
      return;
    }
    if (hasArbitraryInsertions) {
      this.itemToIndexCache = void 0;
      return;
    }
    let removalsAreContiguousAtStart = false;
    let contiguousRemovalCount = 0;
    if (hasRemovals) {
      const sortedRemovals = Array.from(removedIndices).sort((a, b) => a - b);
      removalsAreContiguousAtStart = sortedRemovals[0] === 0;
      if (removalsAreContiguousAtStart) {
        for (let i = 0; i < sortedRemovals.length; i++) {
          if (sortedRemovals[i] !== i) {
            removalsAreContiguousAtStart = false;
            break;
          }
        }
        if (removalsAreContiguousAtStart) {
          contiguousRemovalCount = sortedRemovals.length;
        }
      }
    }
    if (hasRemovals && !removalsAreContiguousAtStart) {
      this.itemToIndexCache = void 0;
      return;
    }
    const cache = this.itemToIndexCache;
    const indexShift = totalPrependCount - contiguousRemovalCount;
    if (indexShift !== 0) {
      for (const [item, oldIndex] of cache) {
        if (removedIndices.has(oldIndex)) {
          cache.delete(item);
        } else {
          cache.set(item, oldIndex + indexShift);
        }
      }
    } else if (hasRemovals) {
      for (const [item, oldIndex] of cache) {
        if (removedIndices.has(oldIndex)) {
          cache.delete(item);
        }
      }
    }
    for (let i = 0; i < prependedValues.length; i++) {
      const item = prependedValues[i];
      if (!cache.has(item)) {
        cache.set(item, i);
      }
    }
    const appendStartIndex = indexMap.finalLength - totalAppendCount;
    for (let i = 0; i < appendedValues.length; i++) {
      const item = appendedValues[i];
      if (!cache.has(item)) {
        cache.set(item, appendStartIndex + i);
      }
    }
  }
  clearPendingTransactions() {
    const count = this.pendingTransactions.length;
    this.pendingTransactions = [];
    this.cachedChangeDescription = void 0;
    return count;
  }
  getPendingTransactions() {
    return [...this.pendingTransactions];
  }
  /** Custom JSON serialization (avoids snapshot bloat). */
  toJSON() {
    return this.data;
  }
  /** Builds a DataChangeDescription from pending transactions (does not modify data). */
  getChangeDescription() {
    if (!this.hasPendingTransactions()) {
      return void 0;
    }
    if (this.cachedChangeDescription) {
      return this.cachedChangeDescription;
    }
    const { indexMap, prependValues, appendValues, insertionValues } = this.buildIndexMap();
    const changeDescription = new DataChangeDescription(indexMap, {
      prependValues,
      appendValues,
      insertionValues
    });
    this.cachedChangeDescription = changeDescription;
    return changeDescription;
  }
  /**
   * Helper method to remove items from a list of groups.
   * Mutates the groups in-place and removes found items from toRemove set.
   * @param groups List of groups to search and remove from
   * @param toRemove Set of items to remove (modified in-place)
   */
  removeFromGroups(groups, toRemove) {
    for (const group of groups) {
      let i = 0;
      while (i < group.length && toRemove.size > 0) {
        if (toRemove.has(group[i])) {
          toRemove.delete(group[i]);
          group.splice(i, 1);
        } else {
          i++;
        }
      }
      if (toRemove.size === 0)
        break;
    }
  }
  /**
   * Builds the index transformation map by sequentially applying all pending transactions.
   * Optimized to:
   * - Track operation boundaries instead of individual items
   * - Only scan for values that are actually being removed
   * - Stop scanning early when all removed values are found
   * - Support arbitrary insertions at any index
   * - Track updated items by referential equality
   */
  buildIndexMap() {
    const originalLength = this.data.length;
    const effects = this.collectTransactionEffects();
    const survivingPrepends = effects.prependsList.flat();
    const survivingAppends = effects.appendsList.flat();
    const survivingInsertions = effects.insertionsList.flat();
    const totalPrependCount = survivingPrepends.length;
    const totalAppendCount = survivingAppends.length;
    const totalInsertionCount = survivingInsertions.length;
    const survivingOriginalCount = originalLength - effects.removedOriginalIndices.size;
    const finalLength = totalPrependCount + survivingOriginalCount + totalInsertionCount + totalAppendCount;
    const sortedRemoved = effects.removedOriginalIndices.size > 0 ? this.getSortedRemovedIndices(effects.removedOriginalIndices) : void 0;
    const spliceOps = this.buildSpliceOperations(
      totalPrependCount,
      totalInsertionCount,
      totalAppendCount,
      survivingOriginalCount,
      effects.trackedInsertions,
      sortedRemoved?.desc,
      sortedRemoved?.asc
    );
    const updatedFinalIndices = this.resolveUpdatedIndices(
      totalPrependCount,
      totalInsertionCount,
      survivingOriginalCount,
      effects.updateTracking,
      sortedRemoved?.asc,
      effects.updatedOriginalIndices,
      effects.trackedInsertions
    );
    const indexMap = {
      originalLength,
      finalLength,
      spliceOps,
      removedIndices: effects.removedOriginalIndices,
      updatedIndices: updatedFinalIndices,
      totalPrependCount,
      totalAppendCount
    };
    return {
      indexMap,
      prependValues: survivingPrepends,
      appendValues: survivingAppends,
      insertionValues: survivingInsertions
    };
  }
  getSortedRemovedIndices(removedOriginalIndices) {
    const asc = Array.from(removedOriginalIndices).sort((a, b) => a - b);
    return { asc, desc: [...asc].reverse() };
  }
  collectTransactionEffects() {
    const state = {
      prependsList: [],
      appendsList: [],
      insertionsList: [],
      trackedInsertions: [],
      removedOriginalIndices: /* @__PURE__ */ new Set(),
      updatedOriginalIndices: /* @__PURE__ */ new Set(),
      virtualLength: this.data.length
    };
    for (const transaction of this.pendingTransactions) {
      const { prepend, append, insertions, remove, update } = transaction;
      this.applyPrepends(prepend, state);
      this.applyInsertions(insertions, state);
      this.applyAppends(append, state);
      this.applyRemovals(remove, state);
      this.applyUpdates(update, state);
    }
    return {
      prependsList: state.prependsList,
      appendsList: state.appendsList,
      insertionsList: state.insertionsList,
      trackedInsertions: state.trackedInsertions,
      removedOriginalIndices: state.removedOriginalIndices,
      updatedOriginalIndices: state.updatedOriginalIndices,
      updateTracking: state.updateTracking
    };
  }
  applyPrepends(prepend, state) {
    if (!Array.isArray(prepend) || prepend.length === 0) {
      return;
    }
    state.prependsList.unshift([...prepend]);
    state.virtualLength += prepend.length;
  }
  applyInsertions(insertions, state) {
    if (!Array.isArray(insertions)) {
      return;
    }
    for (const { index, items } of insertions) {
      if (index >= 0 && index <= state.virtualLength && items.length > 0) {
        state.trackedInsertions.push({
          virtualIndex: index,
          items: [...items]
        });
        state.insertionsList.push([...items]);
        state.virtualLength += items.length;
      }
    }
  }
  applyAppends(append, state) {
    if (!Array.isArray(append) || append.length === 0) {
      return;
    }
    state.appendsList.push([...append]);
    state.virtualLength += append.length;
  }
  applyRemovals(remove, state) {
    if (!Array.isArray(remove) || remove.length === 0) {
      return;
    }
    const toRemove = new Set(remove);
    this.removeFromGroups(state.prependsList, toRemove);
    if (toRemove.size > 0) {
      this.removeFromGroups(state.insertionsList, toRemove);
    }
    if (state.trackedInsertions.length > 0) {
      this.removeFromTrackedInsertions(remove, state);
    }
    if (toRemove.size > 0) {
      this.removeFromGroups(state.appendsList, toRemove);
    }
    if (toRemove.size > 0) {
      for (let i = 0; i < this.data.length && toRemove.size > 0; i++) {
        const value = this.data[i];
        if (toRemove.has(value)) {
          state.removedOriginalIndices.add(i);
          toRemove.delete(value);
          state.virtualLength--;
        }
      }
    }
    if (toRemove.size > 0) {
      logger_exports.warnOnce(
        "applyTransaction() remove includes items not present in current data; ignoring missing items."
      );
    }
  }
  applyUpdates(update, state) {
    if (!Array.isArray(update) || update.length === 0) {
      return;
    }
    const toUpdate = new Set(update);
    const updatedPrependsIndices = this.collectUpdatedIndicesFromGroups(state.prependsList, toUpdate);
    const updatedInsertionsIndices = toUpdate.size > 0 ? this.collectUpdatedIndicesFromGroups(state.insertionsList, toUpdate) : [];
    const updatedAppendsIndices = toUpdate.size > 0 ? this.collectUpdatedIndicesFromGroups(state.appendsList, toUpdate) : [];
    if (toUpdate.size > 0) {
      this.collectUpdatedOriginalIndices(toUpdate, state);
    }
    state.updateTracking = {
      updatedPrependsIndices,
      updatedAppendsIndices,
      updatedInsertionsIndices
    };
    if (toUpdate.size > 0) {
      logger_exports.warnOnce(
        "applyTransaction() update includes items not present in current data; ignoring missing items."
      );
    }
  }
  // Flattens grouped inserts to find updated item offsets while consuming the lookup set.
  collectUpdatedIndicesFromGroups(groups, toUpdate) {
    if (toUpdate.size === 0 || groups.length === 0) {
      return [];
    }
    const updatedIndices = [];
    let flatIndex = 0;
    for (const group of groups) {
      for (const item of group) {
        if (toUpdate.has(item)) {
          updatedIndices.push(flatIndex);
          toUpdate.delete(item);
        }
        flatIndex++;
      }
      if (toUpdate.size === 0) {
        break;
      }
    }
    return updatedIndices;
  }
  /** Lazy item→index map for O(1) lookups. */
  getItemToIndexMap() {
    if (this.itemToIndexCache === void 0) {
      this.itemToIndexCache = /* @__PURE__ */ new Map();
      for (let i = 0; i < this.data.length; i++) {
        if (!this.itemToIndexCache.has(this.data[i])) {
          this.itemToIndexCache.set(this.data[i], i);
        }
      }
    }
    return this.itemToIndexCache;
  }
  collectUpdatedOriginalIndices(toUpdate, state) {
    const indexMap = this.getItemToIndexMap();
    for (const item of [...toUpdate]) {
      const idx = indexMap.get(item);
      if (idx !== void 0 && !state.removedOriginalIndices.has(idx)) {
        state.updatedOriginalIndices.add(idx);
        toUpdate.delete(item);
      }
    }
  }
  removeFromTrackedInsertions(removeValues, state) {
    for (let trackedIdx = 0; trackedIdx < state.trackedInsertions.length; trackedIdx++) {
      const tracked = state.trackedInsertions[trackedIdx];
      const previousLength = tracked.items.length;
      const removedOffsets = [];
      let itemIndex = 0;
      while (itemIndex < tracked.items.length) {
        if (removeValues.includes(tracked.items[itemIndex])) {
          removedOffsets.push(itemIndex + removedOffsets.length);
          tracked.items.splice(itemIndex, 1);
          state.virtualLength--;
        } else {
          itemIndex++;
        }
      }
      if (removedOffsets.length > 0) {
        this.adjustLaterInsertionsAfterRemoval(
          state.trackedInsertions,
          trackedIdx,
          tracked,
          previousLength,
          removedOffsets
        );
      }
    }
  }
  adjustLaterInsertionsAfterRemoval(trackedInsertions, trackedIdx, tracked, previousLength, removedOffsets) {
    const removedCount = removedOffsets.length;
    for (let j = trackedIdx + 1; j < trackedInsertions.length; j++) {
      const later = trackedInsertions[j];
      if (later.virtualIndex <= tracked.virtualIndex) {
        continue;
      }
      const relativeInsertionPosition = Math.min(
        Math.max(later.virtualIndex - tracked.virtualIndex, 0),
        previousLength
      );
      let removedBeforeInsertion = 0;
      for (const offset of removedOffsets) {
        if (offset < relativeInsertionPosition) {
          removedBeforeInsertion++;
        } else {
          break;
        }
      }
      if (relativeInsertionPosition === previousLength) {
        removedBeforeInsertion = removedCount;
      }
      if (removedBeforeInsertion > 0) {
        later.virtualIndex -= removedBeforeInsertion;
      }
    }
  }
  buildSpliceOperations(totalPrependCount, totalInsertionCount, totalAppendCount, survivingOriginalCount, trackedInsertions, sortedRemovedDesc, sortedRemovedAsc) {
    const spliceOps = [];
    if (totalPrependCount > 0) {
      spliceOps.push({
        index: 0,
        deleteCount: 0,
        insertCount: totalPrependCount
      });
    }
    if (sortedRemovedDesc && sortedRemovedDesc.length > 0) {
      let currentGroupStart = sortedRemovedDesc[0];
      let currentGroupCount = 1;
      for (let i = 1; i < sortedRemovedDesc.length; i++) {
        const currentIndex = sortedRemovedDesc[i];
        const prevIndex = sortedRemovedDesc[i - 1];
        if (prevIndex - currentIndex === 1) {
          currentGroupCount++;
        } else {
          spliceOps.push({
            index: currentGroupStart - currentGroupCount + 1 + totalPrependCount,
            deleteCount: currentGroupCount,
            insertCount: 0
          });
          currentGroupStart = currentIndex;
          currentGroupCount = 1;
        }
      }
      spliceOps.push({
        index: currentGroupStart - currentGroupCount + 1 + totalPrependCount,
        deleteCount: currentGroupCount,
        insertCount: 0
      });
    }
    if (trackedInsertions.length > 0) {
      for (const insertion of trackedInsertions) {
        const removalsBeforeInsertion = this.countRemovalsBeforeIndex(
          sortedRemovedAsc,
          totalPrependCount,
          insertion.virtualIndex
        );
        const adjustedIndex = insertion.virtualIndex - removalsBeforeInsertion;
        spliceOps.push({
          index: adjustedIndex,
          deleteCount: 0,
          insertCount: insertion.items.length
        });
      }
    }
    if (totalAppendCount > 0) {
      spliceOps.push({
        index: totalPrependCount + survivingOriginalCount + totalInsertionCount,
        deleteCount: 0,
        insertCount: totalAppendCount
      });
    }
    return spliceOps;
  }
  countRemovalsBeforeIndex(sortedRemovedAsc, totalPrependCount, insertionVirtualIndex) {
    if (!sortedRemovedAsc || sortedRemovedAsc.length === 0) {
      return 0;
    }
    let removalsBeforeInsertion = 0;
    for (const removedIndex of sortedRemovedAsc) {
      const virtualIndexOfRemoval = removedIndex + totalPrependCount;
      if (virtualIndexOfRemoval < insertionVirtualIndex) {
        removalsBeforeInsertion++;
      } else {
        break;
      }
    }
    return removalsBeforeInsertion;
  }
  resolveUpdatedIndices(totalPrependCount, totalInsertionCount, survivingOriginalCount, updateTracking, sortedRemovedAsc, updatedOriginalIndices, trackedInsertions) {
    const updatedFinalIndices = /* @__PURE__ */ new Set();
    if (updateTracking) {
      for (const prependIdx of updateTracking.updatedPrependsIndices) {
        updatedFinalIndices.add(prependIdx);
      }
    }
    if (updatedOriginalIndices.size > 0) {
      const sortedUpdatedOriginals = Array.from(updatedOriginalIndices).sort((a, b) => a - b);
      let removalPtr = 0;
      for (const originalIdx of sortedUpdatedOriginals) {
        if (sortedRemovedAsc) {
          while (removalPtr < sortedRemovedAsc.length && sortedRemovedAsc[removalPtr] < originalIdx) {
            removalPtr++;
          }
        }
        const removalsBeforeCount = sortedRemovedAsc ? removalPtr : 0;
        const virtualPosOfOriginal = originalIdx + totalPrependCount;
        let insertionsBeforeCount = 0;
        for (const insertion of trackedInsertions) {
          if (insertion.virtualIndex <= virtualPosOfOriginal) {
            insertionsBeforeCount += insertion.items.length;
          }
        }
        const finalIdx = originalIdx + totalPrependCount - removalsBeforeCount + insertionsBeforeCount;
        updatedFinalIndices.add(finalIdx);
      }
    }
    if (updateTracking) {
      const appendStartIdx = totalPrependCount + survivingOriginalCount + totalInsertionCount;
      for (const appendIdx of updateTracking.updatedAppendsIndices) {
        updatedFinalIndices.add(appendStartIdx + appendIdx);
      }
      if (updateTracking.updatedInsertionsIndices.length > 0 && trackedInsertions.length > 0) {
        let flatIdx = 0;
        for (const insertion of trackedInsertions) {
          const removalsBeforeInsertion = this.countRemovalsBeforeIndex(
            sortedRemovedAsc,
            totalPrependCount,
            insertion.virtualIndex
          );
          const insertionFinalIdx = insertion.virtualIndex - removalsBeforeInsertion;
          for (let itemOffset = 0; itemOffset < insertion.items.length; itemOffset++) {
            if (updateTracking.updatedInsertionsIndices.includes(flatIdx)) {
              updatedFinalIndices.add(insertionFinalIdx + itemOffset);
            }
            flatIdx++;
          }
        }
      }
    }
    return updatedFinalIndices;
  }
};

// packages/ag-charts-community/src/chart/interaction/syncManager.ts
var _SyncManager = class _SyncManager {
  constructor(chart) {
    this.chart = chart;
  }
  subscribe(groupId = _SyncManager.DEFAULT_GROUP) {
    let syncGroup = this.get(groupId);
    if (!syncGroup) {
      syncGroup = { members: /* @__PURE__ */ new Set() };
      _SyncManager.chartsGroups.set(groupId, syncGroup);
    }
    syncGroup.members.add(this.chart);
    return this;
  }
  unsubscribe(groupId = _SyncManager.DEFAULT_GROUP) {
    const groupState = this.get(groupId);
    groupState?.members.delete(this.chart);
    delete groupState?.domains?.x?.sources?.[this.chart.id];
    delete groupState?.domains?.y?.sources?.[this.chart.id];
    return this;
  }
  getChart() {
    return this.chart;
  }
  getGroupState(groupId = _SyncManager.DEFAULT_GROUP) {
    return this.get(groupId);
  }
  getGroupMembers(groupId = _SyncManager.DEFAULT_GROUP) {
    const syncGroup = this.get(groupId);
    return syncGroup ? Array.from(syncGroup.members) : [];
  }
  getGroupSiblings(groupId = _SyncManager.DEFAULT_GROUP) {
    return this.getGroupMembers(groupId).filter((chart) => chart !== this.chart);
  }
  getGroupSyncMode(groupId = _SyncManager.DEFAULT_GROUP) {
    if (this.getGroupMembers(groupId).some((c) => c.series.length > 1)) {
      return "multi-series";
    }
    return "single-series";
  }
  get(groupId) {
    return _SyncManager.chartsGroups.get(groupId);
  }
};
_SyncManager.chartsGroups = /* @__PURE__ */ new Map();
_SyncManager.DEFAULT_GROUP = Symbol("sync-group-default");
var SyncManager = _SyncManager;

// packages/ag-charts-community/src/chart/keyboard.ts
var Keyboard = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = false;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], Keyboard.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Keyboard.prototype, "tabIndex", 2);

// packages/ag-charts-community/src/motion/fromToMotion.ts
var fromToMotion_exports = {};
__export(fromToMotion_exports, {
  NODE_UPDATE_STATE_TO_PHASE_MAPPING: () => NODE_UPDATE_STATE_TO_PHASE_MAPPING,
  fromToMotion: () => fromToMotion,
  staticFromToMotion: () => staticFromToMotion
});
var NODE_UPDATE_STATE_TO_PHASE_MAPPING = {
  added: "add",
  updated: "update",
  removed: "remove",
  unknown: "initial",
  "no-op": "none"
};
function fromToMotion(groupId, subId, animationManager, selectionsOrNodes, fns, getDatumId, diff9) {
  const { fromFn, toFn, applyFn = (node, props) => node.setProperties(props) } = fns;
  const { nodes, selections } = deconstructSelectionsOrNodes(selectionsOrNodes);
  const processNodes = (liveNodes, subNodes) => {
    let prevFromProps;
    let liveNodeIndex = 0;
    let nodeIndex = 0;
    for (const node of subNodes) {
      const isLive = liveNodes[liveNodeIndex] === node;
      const ctx = {
        last: nodeIndex >= subNodes.length - 1,
        lastLive: liveNodeIndex >= liveNodes.length - 1,
        prev: subNodes[nodeIndex - 1],
        prevFromProps,
        prevLive: liveNodes[liveNodeIndex - 1],
        next: subNodes[nodeIndex + 1],
        nextLive: liveNodes[liveNodeIndex + (isLive ? 1 : 0)]
      };
      const animationId = `${groupId}_${subId}_${node.id}`;
      animationManager.stopByAnimationId(animationId);
      let status = "unknown";
      if (!isLive) {
        status = "removed";
      } else if (getDatumId && diff9) {
        status = calculateStatus(node, node.datum, getDatumId, diff9);
      }
      node.transitionOut = status === "removed";
      const { phase, start: start2, finish, delay, duration, ...from3 } = fromFn(node, node.datum, status, ctx);
      const {
        phase: toPhase,
        start: toStart,
        finish: toFinish,
        delay: toDelay,
        duration: toDuration,
        ...to
      } = toFn(node, node.datum, status, ctx);
      const collapsable = finish == null;
      animationManager.animate({
        id: animationId,
        groupId,
        phase: phase ?? toPhase ?? "update",
        duration: duration ?? toDuration,
        delay: delay ?? toDelay,
        from: from3,
        to,
        ease: easeOut,
        collapsable,
        onPlay: () => {
          const startProps = { ...start2, ...toStart, ...from3 };
          applyFn(node, startProps, "start");
        },
        onUpdate(props) {
          applyFn(node, props, "update");
        },
        onStop: () => {
          const endProps = {
            ...start2,
            ...toStart,
            ...from3,
            ...to,
            ...finish,
            ...toFinish
          };
          applyFn(node, endProps, "end");
        }
      });
      if (isLive) {
        liveNodeIndex++;
      }
      nodeIndex++;
      prevFromProps = from3;
    }
  };
  let selectionIndex = 0;
  for (const selection of selections) {
    const selectionNodes = selection.nodes();
    const liveNodes = selectionNodes.filter((n) => !selection.isGarbage(n));
    processNodes(liveNodes, selectionNodes);
    animationManager.animate({
      id: `${groupId}_${subId}_selection_${selectionIndex}`,
      groupId,
      phase: "end",
      from: 0,
      to: 1,
      ease: easeOut,
      onStop() {
        selection.cleanup();
      }
    });
    selectionIndex++;
  }
  processNodes(nodes, nodes);
}
function staticFromToMotion(groupId, subId, animationManager, selectionsOrNodes, from3, to, extraOpts) {
  const { nodes, selections } = deconstructSelectionsOrNodes(selectionsOrNodes);
  const { start: start2, finish, phase } = extraOpts;
  animationManager.animate({
    id: `${groupId}_${subId}`,
    groupId,
    phase: phase ?? "update",
    from: from3,
    to,
    ease: easeOut,
    onPlay: () => {
      if (!start2)
        return;
      for (const node of nodes) {
        node.setProperties(start2);
      }
      for (const selection of selections) {
        const selectionNodes = selection.nodes();
        selection.batchedUpdate(function staticMotionPlay() {
          for (const node of selectionNodes) {
            node.setProperties(start2);
          }
        });
      }
    },
    onUpdate(props) {
      for (const node of nodes) {
        node.setProperties(props);
      }
      for (const selection of selections) {
        const selectionNodes = selection.nodes();
        selection.batchedUpdate(function staticMotionUpdate() {
          for (const node of selectionNodes) {
            node.setProperties(props);
          }
        });
      }
    },
    onStop: () => {
      for (const node of nodes) {
        node.setProperties({ ...to, ...finish });
      }
      for (const selection of selections) {
        const selectionNodes = selection.nodes();
        selection.batchedUpdate(function staticMotionStop() {
          for (const node of selectionNodes) {
            node.setProperties({ ...to, ...finish });
          }
          selection.cleanup();
        });
      }
    }
  });
}
function calculateStatus(node, datum, getDatumId, diff9) {
  const id = getDatumId(node, datum);
  if (diff9.added.has(id)) {
    return "added";
  }
  if (diff9.removed.has(id)) {
    return "removed";
  }
  if (node.previousDatum == null && node.datum != null) {
    return "added";
  }
  if (node.previousDatum != null && node.datum == null) {
    return "removed";
  }
  return "updated";
}

// packages/ag-charts-community/src/motion/resetMotion.ts
var resetMotion_exports = {};
__export(resetMotion_exports, {
  resetMotion: () => resetMotion
});
function resetMotion(selectionsOrNodes, propsFn) {
  const { nodes, selections } = deconstructSelectionsOrNodes(selectionsOrNodes);
  for (const selection of selections) {
    const selectionNodes = selection.nodes();
    selection.batchedUpdate(function resetMotionNodes() {
      for (const node of selectionNodes) {
        const from3 = propsFn(node, node.datum);
        node.setProperties(from3);
      }
      selection.cleanup();
    });
  }
  for (const node of nodes) {
    const from3 = propsFn(node, node.datum);
    node.setProperties(from3);
  }
}

// packages/ag-charts-community/src/scene/selection.ts
var Selection = class _Selection {
  constructor(parentNode, classOrFactory, autoCleanup = true) {
    this.parentNode = parentNode;
    this.autoCleanup = autoCleanup;
    this.garbageBin = /* @__PURE__ */ new Set();
    this._nodesMap = /* @__PURE__ */ new Map();
    this._nodes = [];
    this.data = [];
    this.debug = debugLogger_exports.create(true, "scene", "scene:selections");
    this.nodeFactory = Object.prototype.isPrototypeOf.call(Node2, classOrFactory) ? () => new classOrFactory() : classOrFactory;
  }
  static select(parent, classOrFactory, garbageCollection = true) {
    return new _Selection(parent, classOrFactory, garbageCollection);
  }
  static selectAll(parent, predicate) {
    const results = [];
    const traverse = (node) => {
      if (predicate(node)) {
        results.push(node);
      }
      if (node instanceof Group) {
        for (const child of node.children()) {
          traverse(child);
        }
      }
    };
    traverse(parent);
    return results;
  }
  static selectByClass(node, ...Classes) {
    return _Selection.selectAll(node, (n) => Classes.some((C2) => n instanceof C2));
  }
  static selectByTag(node, tag) {
    return _Selection.selectAll(node, (n) => n.tag === tag);
  }
  createNode(datum, initializer, idx) {
    const node = this.nodeFactory(datum);
    node.datum = datum;
    initializer?.(node);
    if (idx == null) {
      this._nodes.push(node);
    } else {
      this._nodes.splice(idx, 0, node);
    }
    this.parentNode.appendChild(node);
    return node;
  }
  /**
   * Update the data in a selection. If an `getDatumId()` function is provided, maintain a list of ids related to
   * the nodes. Otherwise, take the more efficient route of simply creating and destroying nodes at the end
   * of the array.
   */
  update(data, initializer, getDatumId) {
    if (this.garbageBin.size > 0) {
      this.debug(`Selection - update() called with pending garbage`, data);
    }
    if (getDatumId && this._nodesMap.size === 0 && this._nodes.length > 0) {
      for (const node of this._nodes) {
        this.garbageBin.add(node);
      }
    }
    if (!getDatumId && this._nodesMap.size > 0) {
      this._nodesMap.clear();
    }
    if (getDatumId) {
      const dataMap = /* @__PURE__ */ new Map();
      const duplicateMap = /* @__PURE__ */ new Map();
      for (let idx = 0; idx < data.length; idx++) {
        const datum = data[idx];
        let id = getDatumId(datum);
        if (dataMap.has(id)) {
          const index = (duplicateMap.get(id) ?? 0) + 1;
          duplicateMap.set(id, index);
          id = `${id}:${index}`;
        }
        dataMap.set(id, idx);
      }
      for (const [node, datumId] of this._nodesMap.entries()) {
        const idx = dataMap.get(datumId);
        if (idx == null) {
          this.garbageBin.add(node);
        } else {
          node.datum = data[idx];
          this.garbageBin.delete(node);
          dataMap.delete(datumId);
        }
      }
      for (const [datumId, idx] of dataMap.entries()) {
        const datum = data[idx];
        this._nodesMap.set(this.createNode(datum, initializer, idx), datumId);
      }
    } else {
      const maxLength = Math.max(data.length, this.data.length);
      for (let i = 0; i < maxLength; i++) {
        if (i >= data.length) {
          this.garbageBin.add(this._nodes[i]);
        } else if (i >= this._nodes.length) {
          this.createNode(data[i], initializer);
        } else {
          this._nodes[i].datum = data[i];
          this.garbageBin.delete(this._nodes[i]);
        }
      }
    }
    this.data = data.slice();
    if (this.autoCleanup) {
      this.cleanup();
    }
    return this;
  }
  cleanup() {
    if (this.garbageBin.size === 0) {
      return this;
    }
    const selection = this;
    function removeGarbage(node) {
      if (selection.garbageBin.has(node)) {
        selection._nodesMap.delete(node);
        selection.garbageBin.delete(node);
        node.destroy();
        return false;
      }
      return true;
    }
    this._nodes = this._nodes.filter(removeGarbage);
    return this;
  }
  clear() {
    this.update([]);
    for (const node of this._nodesMap.keys()) {
      this.garbageBin.add(node);
    }
    this._nodesMap.clear();
    return this;
  }
  isGarbage(node) {
    return this.garbageBin.has(node);
  }
  each(iterate2) {
    const nodes = this._nodes;
    this.parentNode.batchedUpdate(function selectionEach() {
      for (const entry of nodes.entries()) {
        iterate2(entry[1], entry[1].datum, entry[0]);
      }
    });
    return this;
  }
  *[Symbol.iterator]() {
    for (let index = 0; index < this._nodes.length; index++) {
      const node = this._nodes[index];
      yield { node, datum: node.datum, index };
    }
  }
  select(predicate) {
    return _Selection.selectAll(this.parentNode, predicate);
  }
  selectByClass(Class) {
    return _Selection.selectByClass(this.parentNode, Class);
  }
  selectByTag(tag) {
    return _Selection.selectByTag(this.parentNode, tag);
  }
  nodes() {
    return this._nodes;
  }
  at(index) {
    return this._nodes.at(index);
  }
  get length() {
    return this._nodes.length;
  }
  batchedUpdate(fn) {
    this.parentNode.batchedUpdate(fn);
  }
};

// packages/ag-charts-community/src/scene/shape/line.ts
var Line = class extends Shape {
  constructor(opts = {}) {
    super(opts);
    this.x1 = 0;
    this.y1 = 0;
    this.x2 = 0;
    this.y2 = 0;
    this.fill = void 0;
    this.strokeWidth = 1;
  }
  set x(value) {
    this.x1 = value;
    this.x2 = value;
  }
  set y(value) {
    this.y1 = value;
    this.y2 = value;
  }
  get midPoint() {
    return { x: (this.x1 + this.x2) / 2, y: (this.y1 + this.y2) / 2 };
  }
  computeBBox() {
    return new BBox(
      Math.min(this.x1, this.x2),
      Math.min(this.y1, this.y2),
      Math.abs(this.x2 - this.x1),
      Math.abs(this.y2 - this.y1)
    );
  }
  isPointInPath(x, y) {
    if (this.x1 === this.x2 || this.y1 === this.y2) {
      return this.getBBox().clone().grow(this.strokeWidth / 2).containsPoint(x, y);
    }
    return false;
  }
  distanceSquared(px, py) {
    const { x1, y1, x2, y2 } = this;
    return lineDistanceSquared(px, py, x1, y1, x2, y2, Infinity);
  }
  render(renderCtx) {
    const { ctx, devicePixelRatio } = renderCtx;
    let { x1, y1, x2, y2 } = this;
    if (x1 === x2) {
      const { strokeWidth } = this;
      const x = Math.round(x1 * devicePixelRatio) / devicePixelRatio + Math.trunc(strokeWidth * devicePixelRatio) % 2 / (devicePixelRatio * 2);
      x1 = x;
      x2 = x;
    } else if (y1 === y2) {
      const { strokeWidth } = this;
      const y = Math.round(y1 * devicePixelRatio) / devicePixelRatio + Math.trunc(strokeWidth * devicePixelRatio) % 2 / (devicePixelRatio * 2);
      y1 = y;
      y2 = y;
    }
    ctx.beginPath();
    ctx.moveTo(x1, y1);
    ctx.lineTo(x2, y2);
    this.fillStroke(ctx);
    this.fillShadow?.markClean();
    super.render(renderCtx);
  }
  toSVG() {
    if (!this.visible)
      return;
    const element2 = createSvgElement("line");
    element2.setAttribute("x1", String(this.x1));
    element2.setAttribute("y1", String(this.y1));
    element2.setAttribute("x2", String(this.x2));
    element2.setAttribute("y2", String(this.y2));
    this.applySvgStrokeAttributes(element2);
    return {
      elements: [element2]
    };
  }
};
Line.className = "Line";
__decorateClass([
  SceneChangeDetection()
], Line.prototype, "x1", 2);
__decorateClass([
  SceneChangeDetection()
], Line.prototype, "y1", 2);
__decorateClass([
  SceneChangeDetection()
], Line.prototype, "x2", 2);
__decorateClass([
  SceneChangeDetection()
], Line.prototype, "y2", 2);

// packages/ag-charts-community/src/chart/label.ts
var LabelBorder = class {
  constructor() {
    this.enabled = true;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], LabelBorder.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LabelBorder.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LabelBorder.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LabelBorder.prototype, "strokeOpacity", 2);
var LabelStyle = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.border = new LabelBorder();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], LabelStyle.prototype, "border", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LabelStyle.prototype, "color", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LabelStyle.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LabelStyle.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LabelStyle.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LabelStyle.prototype, "fontStyle", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LabelStyle.prototype, "fontWeight", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LabelStyle.prototype, "fontSize", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LabelStyle.prototype, "fontFamily", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LabelStyle.prototype, "padding", 2);
var Label = class extends LabelStyle {
  constructor() {
    super(...arguments);
    this.enabled = false;
    this._cachedFormatter = void 0;
  }
  formatValue(formatWithContext2, type, value, params) {
    const { formatter: formatter2, format } = this;
    let result;
    if (formatter2 != null) {
      result ?? (result = formatWithContext2(formatter2, params));
    }
    if (format != null) {
      let cachedFormatter = this._cachedFormatter;
      if (cachedFormatter?.type !== type || cachedFormatter?.format !== format) {
        cachedFormatter = {
          type,
          format,
          formatter: FormatManager.getFormatter(type, format)
        };
        this._cachedFormatter = cachedFormatter;
      }
      result ?? (result = cachedFormatter.formatter?.(value));
    }
    return result == null || isArray(result) ? result : String(result);
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], Label.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Label.prototype, "formatter", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Label.prototype, "format", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Label.prototype, "itemStyler", 2);
function expandLabelPadding(label) {
  const { enabled: borderEnabled = false, stroke: borderStroke } = label?.border ?? {};
  const hasBoxing = label?.fill != null || borderEnabled && borderStroke != null;
  const padding2 = hasBoxing ? label?.padding : null;
  if (padding2 == null) {
    return { bottom: 0, left: 0, right: 0, top: 0 };
  } else if (typeof padding2 === "number") {
    return { bottom: padding2, left: padding2, right: padding2, top: padding2 };
  } else {
    const { bottom = 0, left = 0, right = 0, top = 0 } = padding2;
    return { bottom, left, right, top };
  }
}

// packages/ag-charts-community/src/module/moduleMap.ts
var ModuleMap = class {
  constructor() {
    this.moduleMap = /* @__PURE__ */ new Map();
  }
  modules() {
    return this.moduleMap.values();
  }
  addModule(moduleName, moduleInstance) {
    if (this.moduleMap.has(moduleName)) {
      throw new Error(`AG Charts - module already initialised: ${moduleName}`);
    }
    this.moduleMap.set(moduleName, moduleInstance);
  }
  removeModule(moduleName) {
    this.moduleMap.get(moduleName)?.destroy?.();
    this.moduleMap.delete(moduleName);
  }
  getModule(moduleName) {
    return this.moduleMap.get(moduleName);
  }
  isEnabled(moduleName) {
    return this.moduleMap.has(moduleName);
  }
  mapModules(callback2) {
    return Array.from(this.moduleMap.values(), callback2);
  }
  destroy() {
    for (const moduleInstance of this.moduleMap.values()) {
      moduleInstance?.destroy?.();
    }
    this.moduleMap.clear();
  }
};

// packages/ag-charts-community/src/scene/shape/range.ts
var Range = class extends Shape {
  constructor(opts = {}) {
    super(opts);
    this.x1 = 0;
    this.y1 = 0;
    this.x2 = 0;
    this.y2 = 0;
    this.startLine = false;
    this.endLine = false;
    this.horizontal = false;
    this.strokeWidth = 1;
  }
  computeBBox() {
    return new BBox(this.x1, this.y1, this.x2 - this.x1, this.y2 - this.y1);
  }
  isPointInPath(_x, _y) {
    return false;
  }
  render(renderCtx) {
    const { ctx } = renderCtx;
    let { x1, y1, x2, y2 } = this;
    x1 = this.align(x1);
    y1 = this.align(y1);
    x2 = this.align(x2);
    y2 = this.align(y2);
    const { fill, horizontal } = this;
    const { globalAlpha } = ctx;
    if (fill != null) {
      this.applyFillAndAlpha(ctx);
      ctx.beginPath();
      ctx.moveTo(x1, y1);
      ctx.lineTo(x2, y1);
      ctx.lineTo(x2, y2);
      ctx.lineTo(x1, y2);
      ctx.closePath();
      ctx.fill();
      ctx.globalAlpha = globalAlpha;
    }
    const { stroke: stroke3, strokeWidth, startLine, endLine } = this;
    const strokeActive = !!((startLine || endLine) && stroke3 && strokeWidth);
    if (strokeActive) {
      const { lineDash, lineDashOffset, lineCap, lineJoin } = this;
      this.applyStrokeAndAlpha(ctx);
      ctx.lineWidth = strokeWidth;
      if (lineDash) {
        ctx.setLineDash([...lineDash]);
      }
      if (lineDashOffset) {
        ctx.lineDashOffset = lineDashOffset;
      }
      if (lineCap) {
        ctx.lineCap = lineCap;
      }
      if (lineJoin) {
        ctx.lineJoin = lineJoin;
      }
      ctx.beginPath();
      if (startLine) {
        ctx.moveTo(x1, y1);
        if (horizontal) {
          ctx.lineTo(x1, y2);
        } else {
          ctx.lineTo(x2, y1);
        }
      }
      if (endLine) {
        ctx.moveTo(x2, y2);
        if (horizontal) {
          ctx.lineTo(x2, y1);
        } else {
          ctx.lineTo(x1, y2);
        }
      }
      ctx.stroke();
      ctx.globalAlpha = globalAlpha;
    }
    this.fillShadow?.markClean();
    super.render(renderCtx);
  }
};
Range.className = "Range";
__decorateClass([
  SceneChangeDetection()
], Range.prototype, "x1", 2);
__decorateClass([
  SceneChangeDetection()
], Range.prototype, "y1", 2);
__decorateClass([
  SceneChangeDetection()
], Range.prototype, "x2", 2);
__decorateClass([
  SceneChangeDetection()
], Range.prototype, "y2", 2);
__decorateClass([
  SceneChangeDetection()
], Range.prototype, "startLine", 2);
__decorateClass([
  SceneChangeDetection()
], Range.prototype, "endLine", 2);
__decorateClass([
  SceneChangeDetection()
], Range.prototype, "horizontal", 2);

// packages/ag-charts-community/src/chart/crossline/crossLine.ts
function getCrossLineValue(crossLine) {
  switch (crossLine.type) {
    case "line":
      return crossLine.value;
    case "range":
      return crossLine.range;
  }
}
function validateCrossLineValue(crossLine, scale2) {
  const value = getCrossLineValue(crossLine);
  if (value == null) {
    return false;
  }
  const isContinuous2 = ContinuousScale.is(scale2) || DiscreteTimeScale.is(scale2);
  const validValue = (val) => checkDatum(val, isContinuous2) && !Number.isNaN(scale2.convert(val, { clamp: true }));
  if (crossLine.type === "range") {
    const [start2, end3] = value;
    return validValue(start2) && validValue(end3);
  } else {
    return validValue(value);
  }
}

// packages/ag-charts-community/src/chart/crossline/cartesianCrossLine.ts
var horizontalLineAnchors = {
  top: { rangeH: 0, rangeV: -1, labelH: 0, labelV: 1 },
  "inside-top": { rangeH: 0, rangeV: -1, labelH: 0, labelV: 1 },
  "top-left": { rangeH: -1, rangeV: -1, labelH: -1, labelV: 1 },
  "inside-top-left": { rangeH: -1, rangeV: -1, labelH: -1, labelV: 1 },
  left: { rangeH: -1, rangeV: 0, labelH: 1, labelV: 0 },
  "inside-left": { rangeH: -1, rangeV: 0, labelH: -1, labelV: 0 },
  "bottom-left": { rangeH: -1, rangeV: 1, labelH: -1, labelV: -1 },
  "inside-bottom-left": { rangeH: -1, rangeV: 1, labelH: -1, labelV: -1 },
  bottom: { rangeH: 0, rangeV: 1, labelH: 0, labelV: -1 },
  "inside-bottom": { rangeH: 0, rangeV: 1, labelH: 0, labelV: -1 },
  "bottom-right": { rangeH: 1, rangeV: 1, labelH: 1, labelV: -1 },
  "inside-bottom-right": { rangeH: 1, rangeV: 1, labelH: 1, labelV: -1 },
  right: { rangeH: 1, rangeV: 0, labelH: -1, labelV: 0 },
  "inside-right": { rangeH: 1, rangeV: 0, labelH: 1, labelV: 0 },
  "top-right": { rangeH: 1, rangeV: -1, labelH: 1, labelV: 1 },
  "inside-top-right": { rangeH: 1, rangeV: -1, labelH: 1, labelV: 1 },
  inside: { rangeH: 0, rangeV: 0, labelH: 0, labelV: 0 }
};
var verticalLineAnchors = {
  top: { rangeH: 0, rangeV: -1, labelH: 0, labelV: 1 },
  "inside-top": { rangeH: 0, rangeV: -1, labelH: 0, labelV: -1 },
  "top-left": { rangeH: -1, rangeV: -1, labelH: 1, labelV: -1 },
  "inside-top-left": { rangeH: -1, rangeV: -1, labelH: 1, labelV: -1 },
  left: { rangeH: -1, rangeV: 0, labelH: 1, labelV: 0 },
  "inside-left": { rangeH: -1, rangeV: 0, labelH: 1, labelV: 0 },
  "bottom-left": { rangeH: -1, rangeV: 1, labelH: 1, labelV: 1 },
  "inside-bottom-left": { rangeH: -1, rangeV: 1, labelH: 1, labelV: 1 },
  bottom: { rangeH: 0, rangeV: 1, labelH: 0, labelV: -1 },
  "inside-bottom": { rangeH: 0, rangeV: 1, labelH: 0, labelV: 1 },
  "bottom-right": { rangeH: 1, rangeV: 1, labelH: -1, labelV: 1 },
  "inside-bottom-right": { rangeH: 1, rangeV: 1, labelH: -1, labelV: 1 },
  right: { rangeH: 1, rangeV: 0, labelH: -1, labelV: 0 },
  "inside-right": { rangeH: 1, rangeV: 0, labelH: -1, labelV: 0 },
  "top-right": { rangeH: 1, rangeV: -1, labelH: -1, labelV: -1 },
  "inside-top-right": { rangeH: -1, rangeV: -1, labelH: -1, labelV: -1 },
  inside: { rangeH: 0, rangeV: 0, labelH: 0, labelV: 0 }
};
var horizontalRangeAnchors = {
  top: { rangeH: 0, rangeV: -1, labelH: 0, labelV: 1 },
  "inside-top": { rangeH: 0, rangeV: -1, labelH: 0, labelV: -1 },
  "top-left": { rangeH: -1, rangeV: -1, labelH: -1, labelV: 1 },
  "inside-top-left": { rangeH: -1, rangeV: -1, labelH: -1, labelV: -1 },
  left: { rangeH: -1, rangeV: 0, labelH: 1, labelV: 0 },
  "inside-left": { rangeH: -1, rangeV: 0, labelH: -1, labelV: 0 },
  "bottom-left": { rangeH: -1, rangeV: 1, labelH: -1, labelV: -1 },
  "inside-bottom-left": { rangeH: -1, rangeV: 1, labelH: -1, labelV: 1 },
  bottom: { rangeH: 0, rangeV: 1, labelH: 0, labelV: -1 },
  "inside-bottom": { rangeH: 0, rangeV: 1, labelH: 0, labelV: 1 },
  "bottom-right": { rangeH: 1, rangeV: 1, labelH: 1, labelV: -1 },
  "inside-bottom-right": { rangeH: 1, rangeV: 1, labelH: 1, labelV: 1 },
  right: { rangeH: 1, rangeV: 0, labelH: -1, labelV: 0 },
  "inside-right": { rangeH: 1, rangeV: 0, labelH: 1, labelV: 0 },
  "top-right": { rangeH: 1, rangeV: -1, labelH: 1, labelV: 1 },
  "inside-top-right": { rangeH: 1, rangeV: -1, labelH: 1, labelV: -1 },
  inside: { rangeH: 0, rangeV: 0, labelH: 0, labelV: 0 }
};
var verticalRangeAnchors = {
  top: { rangeH: 0, rangeV: -1, labelH: 0, labelV: 1 },
  "inside-top": { rangeH: 0, rangeV: -1, labelH: 0, labelV: -1 },
  "top-left": { rangeH: -1, rangeV: -1, labelH: 1, labelV: -1 },
  "inside-top-left": { rangeH: -1, rangeV: -1, labelH: -1, labelV: -1 },
  left: { rangeH: -1, rangeV: 0, labelH: 1, labelV: 0 },
  "inside-left": { rangeH: -1, rangeV: 0, labelH: -1, labelV: 0 },
  "bottom-left": { rangeH: -1, rangeV: 1, labelH: 1, labelV: 1 },
  "inside-bottom-left": { rangeH: -1, rangeV: 1, labelH: -1, labelV: 1 },
  bottom: { rangeH: 0, rangeV: 1, labelH: 0, labelV: -1 },
  "inside-bottom": { rangeH: 0, rangeV: 1, labelH: 0, labelV: 1 },
  "bottom-right": { rangeH: 1, rangeV: 1, labelH: -1, labelV: 1 },
  "inside-bottom-right": { rangeH: 1, rangeV: 1, labelH: 1, labelV: 1 },
  right: { rangeH: 1, rangeV: 0, labelH: -1, labelV: 0 },
  "inside-right": { rangeH: 1, rangeV: 0, labelH: 1, labelV: 0 },
  "top-right": { rangeH: 1, rangeV: -1, labelH: -1, labelV: -1 },
  "inside-top-right": { rangeH: 1, rangeV: -1, labelH: 1, labelV: -1 },
  inside: { rangeH: 0, rangeV: 0, labelH: 0, labelV: 0 }
};
var CartesianCrossLineLabel = class extends LabelStyle {
  constructor() {
    super(...arguments);
    this.enabled = void 0;
    this.padding = 5;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianCrossLineLabel.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianCrossLineLabel.prototype, "padding", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianCrossLineLabel.prototype, "text", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianCrossLineLabel.prototype, "position", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianCrossLineLabel.prototype, "rotation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianCrossLineLabel.prototype, "parallel", 2);
var CartesianCrossLine = class extends BaseProperties {
  constructor() {
    super();
    this.id = createId(this);
    this.defaultColorRange = [];
    this.fill = "#c16068";
    this.label = new CartesianCrossLineLabel();
    this.scale = void 0;
    this.clippedRange = [-Infinity, Infinity];
    this.gridLength = 0;
    this.position = "top";
    this.rangeGroup = new Group({ name: this.id });
    this.lineGroup = new Group({ name: this.id });
    this.labelGroup = new Group({ name: this.id });
    this.crossLineRange = this.lineGroup.appendChild(new Range());
    this.crossLineLabel = this.labelGroup.appendChild(new TransformableText());
    this.data = void 0;
    this.startLine = false;
    this.endLine = false;
    this._isRange = void 0;
    this.crossLineRange.pointerEvents = 1 /* None */;
  }
  get defaultLabelPosition() {
    return "top";
  }
  update(visible) {
    const { enabled, type, data, scale: scale2 } = this;
    if (!scale2 || !enabled || !visible || !validateCrossLineValue(this, scale2) || data == null) {
      this.rangeGroup.visible = false;
      this.lineGroup.visible = false;
      this.labelGroup.visible = false;
      return;
    }
    this.rangeGroup.visible = visible;
    this.lineGroup.visible = visible;
    this.labelGroup.visible = visible;
    this.updateNodes();
    const isRange = type === "range";
    if (isRange !== this._isRange) {
      if (isRange) {
        this.rangeGroup.appendChild(this.crossLineRange);
      } else {
        this.lineGroup.appendChild(this.crossLineRange);
      }
    }
    this._isRange = isRange;
  }
  calculateLayout(visible) {
    this.data = void 0;
    if (!visible)
      return;
    const { type, range: range3, value, scale: scale2, clippedRange, strokeWidth = 0 } = this;
    if (!scale2)
      return;
    const bandwidth = scale2.bandwidth ?? 0;
    const step = scale2.step ?? 0;
    const rangePadding = scale2 instanceof BandScale ? (step - bandwidth) / 2 : 0;
    let [clippedRange0, clippedRange1] = findMinMax(clippedRange);
    clippedRange0 -= bandwidth;
    clippedRange1 += bandwidth;
    let yStart;
    let yEnd;
    let clampedYStart;
    let clampedYEnd;
    if (type === "line") {
      const offset = bandwidth / 2;
      yStart = scale2.convert(value) + offset;
      yEnd = Number.NaN;
      clampedYStart = scale2.convert(value, { clamp: true }) + offset;
      clampedYEnd = Number.NaN;
      if (clampedYStart >= clippedRange1 || clampedYStart <= clippedRange0) {
        return;
      }
    } else if (range3) {
      const [r0, r1] = range3;
      const [startAlignment, endAlignment] = rangeAlignment(r0, r1);
      yStart = scale2.convert(r0, { alignment: startAlignment });
      yEnd = scale2.convert(r1, { alignment: endAlignment });
      clampedYStart = scale2.convert(r0, { clamp: true, alignment: startAlignment });
      clampedYEnd = scale2.convert(r1, { clamp: true, alignment: endAlignment });
      if (clampedYStart > clampedYEnd) {
        [clampedYStart, clampedYEnd] = [clampedYEnd, clampedYStart];
        [yStart, yEnd] = [yEnd, yStart];
      }
      if (clampedYStart >= clippedRange1 || clampedYEnd <= clippedRange0) {
        return;
      }
      if (Number.isFinite(yStart)) {
        clampedYStart -= rangePadding;
      }
      if (Number.isFinite(yEnd)) {
        yEnd += bandwidth;
        clampedYEnd += bandwidth + rangePadding;
      }
    } else {
      return;
    }
    clampedYStart = clampArray(clampedYStart, clippedRange);
    clampedYEnd = clampArray(clampedYEnd, clippedRange);
    if (yStart - rangePadding >= clampedYStart)
      yStart -= rangePadding;
    if (yEnd + rangePadding <= clampedYEnd)
      yEnd += rangePadding;
    this.startLine = strokeWidth > 0 && yStart >= clampedYStart && yStart <= clampedYStart + rangePadding;
    this.endLine = strokeWidth > 0 && yEnd >= clampedYEnd - bandwidth - rangePadding && yEnd <= clampedYEnd;
    this.data = [clampedYStart, clampedYEnd];
    if (this.label.enabled === false || !this.label.text)
      return;
  }
  updateNodes() {
    const { position, data: [r0, r1] = [0, 0], gridLength } = this;
    const dr = Number.isFinite(r1) ? r1 - r0 : 0;
    let bounds;
    switch (position) {
      case "top":
      case "bottom":
        bounds = new BBox(r0, position === "top" ? 0 : -gridLength, dr, gridLength);
        break;
      case "left":
      case "right":
        bounds = new BBox(position === "left" ? 0 : -gridLength, r0, gridLength, dr);
    }
    this.updateRangeNode(bounds);
    const { label } = this;
    if (label.enabled !== false && label.text) {
      this.updateLabel();
      this.positionLabel(bounds);
    }
  }
  updateRangeNode(bounds) {
    const {
      type,
      position,
      crossLineRange,
      startLine,
      endLine,
      fill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash
    } = this;
    crossLineRange.x1 = bounds.x;
    crossLineRange.x2 = bounds.x + bounds.width;
    crossLineRange.y1 = bounds.y;
    crossLineRange.y2 = bounds.y + bounds.height;
    crossLineRange.horizontal = position === "top" || position === "bottom";
    crossLineRange.startLine = startLine;
    crossLineRange.endLine = endLine;
    crossLineRange.fill = type === "range" ? fill : void 0;
    crossLineRange.fillOpacity = fillOpacity ?? 1;
    crossLineRange.stroke = stroke3;
    crossLineRange.strokeWidth = strokeWidth ?? 1;
    crossLineRange.strokeOpacity = strokeOpacity ?? 1;
    crossLineRange.lineDash = lineDash;
  }
  updateLabel() {
    const { crossLineLabel, label } = this;
    if (!label.text)
      return;
    crossLineLabel.fill = label.color;
    crossLineLabel.text = label.text;
    crossLineLabel.textAlign = "center";
    crossLineLabel.textBaseline = "middle";
    crossLineLabel.setFont(label);
    crossLineLabel.setBoxing(label);
  }
  get anchor() {
    const horizontal = this.position === "left" || this.position === "right";
    const range3 = this.type === "range";
    const { position = this.defaultLabelPosition } = this.label;
    if (range3) {
      const anchors = horizontal ? horizontalRangeAnchors : verticalRangeAnchors;
      return anchors[position];
    } else {
      const anchors = horizontal ? horizontalLineAnchors : verticalLineAnchors;
      return anchors[position];
    }
  }
  positionLabel(bounds) {
    const { crossLineLabel, label, anchor } = this;
    crossLineLabel.rotation = toRadians(label.rotation ?? 0);
    const bbox = crossLineLabel.getBBox();
    if (!bbox)
      return;
    const { width: width2, height: height2 } = bbox;
    const xOffset = label.padding + width2 / 2;
    const yOffset = label.padding + height2 / 2;
    const x = bounds.x + bounds.width * (anchor.rangeH + 1) / 2 - xOffset * anchor.labelH;
    const y = bounds.y + bounds.height * (anchor.rangeV + 1) / 2 - yOffset * anchor.labelV;
    crossLineLabel.x = x;
    crossLineLabel.y = y;
    crossLineLabel.rotationCenterX = x;
    crossLineLabel.rotationCenterY = y;
  }
  computeLabelSize() {
    const { label } = this;
    if (label.enabled === false || !label.text)
      return;
    const tempText = new TransformableText();
    tempText.fontFamily = label.fontFamily;
    tempText.fontSize = label.fontSize;
    tempText.fontStyle = label.fontStyle;
    tempText.fontWeight = label.fontWeight;
    tempText.text = label.text;
    tempText.rotation = toRadians(label.rotation ?? 0);
    tempText.textBaseline = "middle";
    tempText.textAlign = "center";
    const bbox = tempText.getBBox();
    if (!bbox)
      return;
    const { width: width2, height: height2 } = bbox;
    return { width: width2, height: height2 };
  }
  calculatePadding(into) {
    const { label, anchor } = this;
    const size = this.computeLabelSize();
    if (!size)
      return;
    const { width: width2, height: height2 } = size;
    const xOffset = label.padding + width2;
    const yOffset = label.padding + height2;
    const horizontal = this.position === "left" || this.position === "right";
    if (horizontal) {
      if (anchor.rangeH === -1 && anchor.labelH === 1) {
        into.left = Math.max(into.left ?? 0, xOffset);
      } else if (anchor.rangeH === 1 && anchor.labelH === -1) {
        into.right = Math.max(into.right ?? 0, xOffset);
      }
    }
    if (!horizontal) {
      if (anchor.rangeV === -1 && anchor.labelV === 1) {
        into.top = Math.max(into.top ?? 0, yOffset);
      } else if (anchor.rangeV === 1 && anchor.labelV === -1) {
        into.bottom = Math.max(into.bottom ?? 0, yOffset);
      }
    }
  }
};
CartesianCrossLine.className = "CrossLine";
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianCrossLine.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianCrossLine.prototype, "type", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianCrossLine.prototype, "range", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianCrossLine.prototype, "value", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianCrossLine.prototype, "defaultColorRange", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianCrossLine.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianCrossLine.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianCrossLine.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianCrossLine.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianCrossLine.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianCrossLine.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianCrossLine.prototype, "label", 2);

// packages/ag-charts-community/src/chart/axis/axisGridLine.ts
var AxisGridLine = class {
  constructor() {
    this.enabled = true;
    this.width = 1;
    this.style = [
      {
        fill: void 0,
        fillOpacity: 1,
        stroke: void 0,
        strokeWidth: void 0,
        lineDash: []
      }
    ];
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisGridLine.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisGridLine.prototype, "width", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisGridLine.prototype, "style", 2);

// packages/ag-charts-community/src/chart/axis/axisInterval.ts
var AxisInterval = class extends BaseProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisInterval.prototype, "placement", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisInterval.prototype, "step", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisInterval.prototype, "values", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisInterval.prototype, "minSpacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisInterval.prototype, "maxSpacing", 2);

// packages/ag-charts-community/src/chart/axis/axisLabel.ts
var AxisLabel = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = true;
    this.border = new LabelBorder();
    this.wrapping = "never";
    this.truncate = false;
    this.spacing = 5;
    this.color = "#575757";
    this.avoidCollisions = true;
    this.mirrored = false;
    this.parallel = false;
    this._formatters = {
      "component:year": void 0,
      "component:month": void 0,
      "component:day": void 0,
      "component:none": void 0,
      "long:year": void 0,
      "long:month": void 0,
      "long:day": void 0,
      "long:none": void 0
    };
  }
  /**
   * The side of the axis line to position the labels on.
   * -1 = left (default)
   * 1 = right
   */
  getSideFlag() {
    return this.mirrored ? 1 : -1;
  }
  formatValue(callWithContext2, params, index, options) {
    const { formatter: formatter2, format } = this;
    const { type, value, domain, boundSeries } = params;
    const fractionDigits = params.type === "number" ? params.fractionDigits : void 0;
    const unit = params.type === "date" ? params.unit : void 0;
    let result;
    if (formatter2 != null) {
      const step = params.type === "date" ? params.step : void 0;
      const visibleDomain = params.type === "number" ? params.visibleDomain : void 0;
      result = callWithContext2(formatter2, {
        value,
        index,
        domain,
        fractionDigits,
        unit,
        step,
        boundSeries,
        visibleDomain
      });
    }
    if (format != null && result == null) {
      const { specifier, dateStyle = "long", truncateDate } = options ?? {};
      const cacheKey = `${dateStyle}:${truncateDate ?? "none"}`;
      let valueFormatter = this._formatters[cacheKey];
      const mergedFormat = FormatManager.mergeSpecifiers(specifier, format);
      if (valueFormatter?.type !== type || valueFormatter?.unit !== unit || !objectsEqual(valueFormatter?.mergedFormat, mergedFormat)) {
        valueFormatter = {
          type,
          mergedFormat,
          unit,
          formatter: FormatManager.getFormatter(type, mergedFormat, unit, dateStyle, { truncateDate })
        };
        this._formatters[cacheKey] = valueFormatter;
      }
      result = valueFormatter.formatter?.(value, fractionDigits);
    }
    return result == null || isArray(result) ? result : String(result);
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "border", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "fontStyle", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "fontWeight", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "fontSize", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "fontFamily", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "wrapping", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "truncate", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "spacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "minSpacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "color", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "rotation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "avoidCollisions", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "mirrored", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "padding", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "parallel", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "itemStyler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "formatter", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabel.prototype, "format", 2);

// packages/ag-charts-community/src/chart/axis/axisLine.ts
var AxisLine = class {
  constructor() {
    this.enabled = true;
    this.width = 1;
    this.stroke = void 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLine.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLine.prototype, "width", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLine.prototype, "stroke", 2);

// packages/ag-charts-community/src/chart/axis/axisTick.ts
var AxisTick = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = true;
    this.width = 1;
    this.size = 6;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisTick.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisTick.prototype, "width", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisTick.prototype, "size", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisTick.prototype, "stroke", 2);

// packages/ag-charts-community/src/chart/axis/axisTitle.ts
var AxisTitle = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.caption = new Caption();
    this.enabled = false;
    this.spacing = Caption.SMALL_PADDING;
    this.fontSize = 10 /* SMALLER */;
    this.fontFamily = "sans-serif";
    this.wrapping = "always";
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisTitle.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisTitle.prototype, "text", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisTitle.prototype, "spacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisTitle.prototype, "fontStyle", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisTitle.prototype, "fontWeight", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisTitle.prototype, "fontSize", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisTitle.prototype, "fontFamily", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisTitle.prototype, "color", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisTitle.prototype, "wrapping", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisTitle.prototype, "formatter", 2);

// packages/ag-charts-community/src/chart/axis/axisUtil.ts
var NiceMode = /* @__PURE__ */ ((NiceMode3) => {
  NiceMode3[NiceMode3["TickAndDomain"] = 0] = "TickAndDomain";
  NiceMode3[NiceMode3["TicksOnly"] = 1] = "TicksOnly";
  NiceMode3[NiceMode3["Off"] = 2] = "Off";
  return NiceMode3;
})(NiceMode || {});
function prepareAxisAnimationContext(axis) {
  const [requestedRangeMin, requestedRangeMax] = findMinMax(axis.range);
  const min = Math.floor(requestedRangeMin);
  const max = Math.ceil(requestedRangeMax);
  return { min, max, visible: min !== max };
}
var fullCircle = Math.PI * 2;
var halfCircle = fullCircle / 2;
function normaliseEndRotation(start2, end3) {
  const directDistance = Math.abs(end3 - start2);
  if (directDistance < halfCircle) {
    return end3;
  } else if (start2 > end3) {
    return end3 + fullCircle;
  }
  return end3 - fullCircle;
}
function prepareAxisAnimationFunctions(ctx) {
  const { min, max } = ctx;
  const outOfBounds = (y) => {
    return y < min || y > max;
  };
  const tick = {
    fromFn(node, datum, status) {
      let { x1, x2, y1, y2 } = node;
      let opacity = node.opacity;
      if (status === "added" || outOfBounds(datum.offset)) {
        ({ x1, x2, y1, y2 } = datum);
        opacity = 0;
      }
      return {
        x1,
        x2,
        y1,
        y2,
        opacity,
        phase: NODE_UPDATE_STATE_TO_PHASE_MAPPING[status]
      };
    },
    toFn(_node, datum, status) {
      const { x1, x2, y1, y2 } = datum;
      let opacity = 1;
      if (status === "removed") {
        opacity = 0;
      }
      return { x1, x2, y1, y2, opacity };
    },
    applyFn(node, props) {
      node.setProperties(props);
      node.visible = !outOfBounds(node.y);
    }
  };
  const label = {
    fromFn(node, newDatum, status) {
      const datum = node.previousDatum ?? newDatum;
      let { x, y, rotationCenterX, rotationCenterY, rotation } = datum;
      let opacity = node.opacity;
      if (status === "removed" || outOfBounds(datum.y)) {
        rotation = newDatum.rotation;
      } else if (status === "added" || outOfBounds(node.datum.y)) {
        ({ x, y, rotationCenterX, rotationCenterY, rotation } = newDatum);
        opacity = 0;
      }
      return {
        x,
        y,
        rotationCenterX,
        rotationCenterY,
        rotation,
        opacity,
        phase: NODE_UPDATE_STATE_TO_PHASE_MAPPING[status]
      };
    },
    toFn(node, datum, status) {
      const { x, y, rotationCenterX, rotationCenterY } = datum;
      let rotation = 0;
      let opacity = 1;
      if (status === "added") {
        rotation = datum.rotation;
      } else if (status === "removed") {
        opacity = 0;
        rotation = datum.rotation;
      } else {
        rotation = normaliseEndRotation(node.previousDatum?.rotation ?? datum.rotation, datum.rotation);
      }
      return {
        x,
        y,
        rotationCenterX,
        rotationCenterY,
        rotation,
        opacity,
        finish: { rotation: datum.rotation }
      };
    }
  };
  const line = {
    fromFn(node, datum) {
      const { x1, x2, y1, y2 } = node.previousDatum ?? datum;
      return {
        x1,
        x2,
        y1,
        y2,
        phase: NODE_UPDATE_STATE_TO_PHASE_MAPPING["updated"]
      };
    },
    toFn(_node, datum) {
      const { x1, x2, y1, y2 } = datum;
      return { x1, x2, y1, y2 };
    }
  };
  const group = {
    fromFn(node, _datum) {
      const { translationX, translationY } = node;
      return {
        translationX,
        translationY,
        phase: NODE_UPDATE_STATE_TO_PHASE_MAPPING["updated"]
      };
    },
    toFn(_node, datum) {
      const { translationX, translationY } = datum;
      return { translationX, translationY };
    }
  };
  return { tick, line, label, group };
}
function resetAxisGroupFn() {
  return (_node, datum) => {
    return {
      translationX: datum.translationX,
      translationY: datum.translationY
    };
  };
}
function resetAxisLabelSelectionFn() {
  return (_node, datum) => {
    return {
      x: datum.x,
      y: datum.y,
      rotationCenterX: datum.rotationCenterX,
      rotationCenterY: datum.rotationCenterY,
      rotation: datum.rotation
    };
  };
}
function resetAxisLineSelectionFn() {
  return (_node, datum) => {
    const { x1, x2, y1, y2 } = datum;
    return { x1, x2, y1, y2 };
  };
}
function resetAxisFillSelectionFn() {
  return (_node, datum) => {
    const { x1, x2, y1, y2 } = datum;
    return { x: x1, y: y1, width: x2 - x1, height: y2 - y1 };
  };
}

// packages/ag-charts-community/src/chart/axis/axis.ts
var AxisGroupZIndexMap = /* @__PURE__ */ ((AxisGroupZIndexMap3) => {
  AxisGroupZIndexMap3[AxisGroupZIndexMap3["TickLines"] = 0] = "TickLines";
  AxisGroupZIndexMap3[AxisGroupZIndexMap3["AxisLine"] = 1] = "AxisLine";
  AxisGroupZIndexMap3[AxisGroupZIndexMap3["TickLabels"] = 2] = "TickLabels";
  return AxisGroupZIndexMap3;
})(AxisGroupZIndexMap || {});
function tickLayoutCacheValid(a, b) {
  return a.domain === b.domain && a.rangeExtent === b.rangeExtent && a.nice[0] === b.nice[0] && a.nice[1] === b.nice[1] && a.gridLength === b.gridLength && a.visibleRange[0] === b.visibleRange[0] && a.visibleRange[1] === b.visibleRange[1] && a.scrollbarKey === b.scrollbarKey && a.initialPrimaryTickCount?.unzoomed === b.initialPrimaryTickCount?.unzoomed && a.initialPrimaryTickCount?.zoomed === b.initialPrimaryTickCount?.zoomed;
}
function computeBand(scale2, range3, value) {
  const bandwidth = scale2.bandwidth ?? 0;
  const step = scale2.step ?? 0;
  const offset = (step - bandwidth) / 2;
  const position = scale2.convert(value);
  const start2 = position - offset;
  const end3 = position + bandwidth + offset;
  return [position, clampArray(start2, range3), clampArray(end3, range3)];
}
var _Axis = class _Axis {
  constructor(moduleCtx, scale2) {
    this.moduleCtx = moduleCtx;
    this.scale = scale2;
    this.id = "unknown";
    this._crossLines = [];
    this.nice = true;
    this.reverse = false;
    this.interval = new AxisInterval();
    this.dataDomain = { domain: [], clipped: false };
    this.allowNull = false;
    this.title = new AxisTitle();
    this.gridLength = 0;
    /**
     * The distance between the grid ticks and the axis ticks.
     */
    this.gridPadding = 0;
    /**
     * Is used to avoid collisions between axis labels and series.
     */
    this.seriesAreaPadding = 0;
    this.layoutConstraints = {
      stacked: true,
      align: "justify",
      width: 100,
      unit: "percent"
    };
    this.boundSeries = [];
    this.includeInvisibleDomains = false;
    this.interactionEnabled = true;
    this.axisGroup = new Group({ name: `${this.id}-axis` });
    // Order is important to apply the correct z-index.
    this.tickLineGroup = this.axisGroup.appendChild(
      new TransformableGroup({ name: `${this.id}-Axis-tick-lines`, zIndex: 0 /* TickLines */ })
    );
    this.tickLabelGroup = this.axisGroup.appendChild(
      new TransformableGroup({ name: `${this.id}-Axis-tick-labels`, zIndex: 2 /* TickLabels */ })
    );
    this.labelGroup = new Group({
      name: `${this.id}-Labels`,
      zIndex: 11 /* SERIES_ANNOTATION */
    });
    this.gridGroup = new TranslatableGroup({ name: `${this.id}-Axis-grid`, zIndex: 2 /* AXIS_GRID */ });
    this.gridFillGroup = this.gridGroup.appendChild(new Group({ name: `${this.id}-gridFills` }));
    this.gridLineGroup = this.gridGroup.appendChild(new Group({ name: `${this.id}-gridLines` }));
    this.crossLineRangeGroup = new TransformableGroup({
      name: `${this.id}-CrossLines-Range`,
      zIndex: 6 /* SERIES_CROSSLINE_RANGE */
    });
    this.crossLineLineGroup = new TransformableGroup({
      name: `${this.id}-CrossLines-Line`,
      zIndex: 10 /* SERIES_CROSSLINE_LINE */
    });
    this.crossLineLabelGroup = new TransformableGroup({
      name: `${this.id}-CrossLines-Label`,
      zIndex: 15 /* SERIES_LABEL */
    });
    this.tickLabelGroupSelection = Selection.select(
      this.tickLabelGroup,
      TransformableText,
      false
    );
    this.line = new AxisLine();
    this.tick = new AxisTick();
    this.gridLine = new AxisGridLine();
    this.label = this.createLabel();
    this.defaultTickMinSpacing = _Axis.defaultTickMinSpacing;
    this.translation = { x: 0, y: 0 };
    this.layout = {
      label: {
        fractionDigits: 0,
        spacing: this.label.spacing,
        format: this.label.format
      },
      labelThickness: 0
    };
    this.axisContext = void 0;
    this.cleanup = new CleanupRegistry();
    // AG-15360 Avoid calling removeTooltip() if no tooltip is shown. This avoid a laggy tooltips caused by interference
    // with SeriesAreaManager's tooltip updates.
    this.isHovering = false;
    this.range = [0, 1];
    this.visibleRange = [0, 1];
    this.animatable = true;
    this.tickLayout = void 0;
    this.formatterBoundSeries = new WeakCache(() => {
      const { direction, boundSeries } = this;
      return deepFreeze(boundSeries.flatMap((series) => series.getFormatterContext(direction)));
    });
    this.moduleMap = new ModuleMap();
    this.range = this.scale.range.slice();
    for (const crossLine of this.crossLines) {
      this.initCrossLine(crossLine);
    }
    this.cleanup.register(
      this.moduleCtx.widgets.containerWidget.addListener("mousemove", (e) => this.onMouseMove(e)),
      this.moduleCtx.widgets.containerWidget.addListener("mouseleave", () => this.endHovering())
    );
  }
  set crossLines(value) {
    const { CrossLineConstructor } = this.constructor;
    for (const crossLine of this._crossLines) {
      this.detachCrossLine(crossLine);
    }
    this._crossLines = value.map((crossLine) => {
      const instance = new CrossLineConstructor();
      instance.set(crossLine);
      return instance;
    });
    for (const crossLine of this._crossLines) {
      this.attachCrossLine(crossLine);
      this.initCrossLine(crossLine);
    }
  }
  get crossLines() {
    return this._crossLines;
  }
  get type() {
    return this.constructor.type ?? "";
  }
  get primaryLabel() {
    return void 0;
  }
  get primaryTick() {
    return void 0;
  }
  isCategoryLike() {
    return false;
  }
  resetAnimation(_phase) {
  }
  onMouseMove(event) {
    const node = this.tickLabelGroup.pickNode(event.currentX, event.currentY);
    const datum = node?.datum;
    const { textUntruncated: title = void 0 } = datum ?? {};
    if (title) {
      this.moduleCtx.tooltipManager.updateTooltip(
        this.id,
        { canvasX: event.currentX, canvasY: event.currentY, showArrow: false },
        [{ type: "structured", title }]
      );
      this.isHovering = true;
    } else {
      this.endHovering();
    }
  }
  endHovering() {
    if (this.isHovering) {
      this.moduleCtx.tooltipManager.removeTooltip(this.id, void 0, true);
      this.isHovering = false;
    }
  }
  attachCrossLine(crossLine) {
    this.crossLineRangeGroup.appendChild(crossLine.rangeGroup);
    this.crossLineLineGroup.appendChild(crossLine.lineGroup);
    this.crossLineLabelGroup.appendChild(crossLine.labelGroup);
  }
  detachCrossLine(crossLine) {
    crossLine.rangeGroup.remove();
    crossLine.lineGroup.remove();
    crossLine.labelGroup.remove();
  }
  destroy() {
    this.moduleMap.destroy();
    this.cleanup.flush();
  }
  setScaleRange(visibleRange) {
    const { range: rr, scale: scale2 } = this;
    const span = (rr[1] - rr[0]) / (visibleRange[1] - visibleRange[0]);
    const shift = span * visibleRange[0];
    const start2 = rr[0] - shift;
    scale2.range = [start2, start2 + span];
  }
  updateScale() {
    const {
      range: [r0, r1]
    } = this;
    this.setScaleRange(this.visibleRange);
    for (const crossLine of this.crossLines) {
      crossLine.clippedRange = [r0, r1];
    }
  }
  setCrossLinesVisible(visible) {
    this.crossLineRangeGroup.visible = visible;
    this.crossLineLineGroup.visible = visible;
    this.crossLineLabelGroup.visible = visible;
  }
  attachAxis(groups) {
    groups.gridNode.appendChild(this.gridGroup);
    groups.axisNode.appendChild(this.axisGroup);
    groups.labelNode.appendChild(this.labelGroup);
    groups.crossLineRangeNode.appendChild(this.crossLineRangeGroup);
    groups.crossLineLineNode.appendChild(this.crossLineLineGroup);
    groups.crossLineLabelNode.appendChild(this.crossLineLabelGroup);
  }
  detachAxis() {
    this.gridGroup.remove();
    this.axisGroup.remove();
    this.labelGroup.remove();
    this.crossLineRangeGroup.remove();
    this.crossLineLineGroup.remove();
    this.crossLineLabelGroup.remove();
  }
  attachLabel(axisLabelNode) {
    this.labelGroup.append(axisLabelNode);
  }
  /**
   * Checks if a point or an object is in range.
   * @param value A point (or object's starting point).
   * @param tolerance Expands the range on both ends by this amount.
   */
  inRange(value, tolerance = 0) {
    const [min, max] = findMinMax(this.range);
    return value >= min - tolerance && value <= max + tolerance;
  }
  /**
   * Get a point's overflow on the range, expanded to include the non-visible range.
   * @param value Point
   * @returns Overflow
   */
  getRangeOverflow(value) {
    const { range: rr, visibleRange: vr } = this;
    const size = (rr[1] - rr[0]) / (vr[1] - vr[0]);
    const [min, max] = findMinMax([rr[0] - size * vr[0], rr[0] - size * vr[0] + size]);
    if (value < min)
      return value - min;
    if (value > max)
      return value - max;
    return 0;
  }
  onGridLengthChange(value, prevValue) {
    if (prevValue ^ value) {
      this.onGridVisibilityChange();
    }
    for (const crossLine of this.crossLines) {
      this.initCrossLine(crossLine);
    }
  }
  onGridVisibilityChange() {
  }
  createLabel() {
    return new AxisLabel();
  }
  /**
   * Creates/removes/updates the scene graph nodes that constitute the axis.
   */
  update() {
    this.formatterBoundSeries.clear();
    this.updatePosition();
    this.updateSelections();
    this.gridLineGroup.visible = this.gridLine.enabled;
    this.updateLabels();
    this.updateCrossLines();
  }
  getLabelStyles(params, additionalStyles, label = this.label) {
    const defaultStyle = {
      border: label.border,
      color: label.color,
      cornerRadius: label.cornerRadius,
      fill: label.fill,
      fillOpacity: label.fillOpacity,
      fontFamily: label.fontFamily,
      fontSize: label.fontSize,
      fontStyle: label.fontStyle,
      fontWeight: label.fontWeight,
      padding: label.padding,
      spacing: label.spacing
    };
    let stylerOutput;
    if (label.itemStyler) {
      stylerOutput = this.cachedCallWithContext(label.itemStyler, {
        ...params,
        ...defaultStyle
      });
    }
    const merged = mergeDefaults(stylerOutput, additionalStyles, defaultStyle);
    return {
      border: merged.border,
      color: merged.color,
      cornerRadius: merged.cornerRadius,
      fill: merged.fill,
      fillOpacity: merged.fillOpacity,
      fontFamily: merged.fontFamily,
      fontSize: merged.fontSize,
      fontStyle: merged.fontStyle,
      fontWeight: merged.fontWeight,
      padding: merged.padding,
      spacing: merged.spacing
    };
  }
  getTickSize(tick = this.tick) {
    return tick.enabled ? tick.size : 0;
  }
  getTickSpacing(tick = this.tick) {
    if (!tick.enabled)
      return 0;
    const scrollbar = this.chartLayout?.scrollbars?.[this.id];
    if (!scrollbar?.enabled || scrollbar.placement !== "inner")
      return 0;
    return scrollbar.tickSpacing ?? 0;
  }
  processData() {
    this.invalidateLayoutCache();
    const { includeInvisibleDomains, boundSeries, direction } = this;
    const visibleSeries = includeInvisibleDomains ? boundSeries : boundSeries.filter((s) => s.isEnabled());
    const domains = visibleSeries.map((series) => series.getDomain(direction));
    this.setDomains(...domains);
  }
  getDomainExtentsNice() {
    return [this.nice, this.nice];
  }
  setDomains(...domains) {
    let normalizedDomain;
    let animatable;
    if (domains.length > 0) {
      const result = this.scale.normalizeDomains(...domains);
      normalizedDomain = { domain: result.domain, sortMetadata: { sortOrder: 1 } };
      animatable = result.animatable;
    } else {
      normalizedDomain = { domain: [] };
      animatable = true;
    }
    this.dataDomain = this.normaliseDataDomain(normalizedDomain);
    this.allowNull = this.dataDomain.domain.some(function(v) {
      return v == null;
    });
    if (this.reverse) {
      this.dataDomain.domain.reverse();
    }
    this.animatable = animatable;
  }
  calculateDomain(initialPrimaryTickCount, scrollbarKey = "none") {
    const {
      dataDomain: { domain },
      range: range3,
      scale: scale2,
      gridLength
    } = this;
    const rangeExtent = findRangeExtent(range3);
    const visibleRange = [0, 1];
    const nice = this.getDomainExtentsNice();
    this.updateScale();
    const { unzoomedTickLayoutCache } = this;
    let unzoomedTickLayout;
    if (unzoomedTickLayoutCache == null || !tickLayoutCacheValid(unzoomedTickLayoutCache, {
      domain,
      rangeExtent,
      nice,
      gridLength,
      visibleRange,
      initialPrimaryTickCount,
      scrollbarKey
    })) {
      const scaleRange = scale2.range;
      this.setScaleRange([0, 1]);
      const niceMode = nice.map((n) => n ? 0 /* TickAndDomain */ : 2 /* Off */);
      unzoomedTickLayout = this.calculateTickLayout(domain, niceMode, [0, 1], initialPrimaryTickCount);
      scale2.range = scaleRange;
      this.unzoomedTickLayoutCache = {
        domain,
        rangeExtent,
        nice,
        gridLength,
        visibleRange,
        initialPrimaryTickCount,
        scrollbarKey,
        tickLayout: unzoomedTickLayout
      };
    } else {
      unzoomedTickLayout = unzoomedTickLayoutCache.tickLayout;
    }
    this.updateScale();
    scale2.domain = unzoomedTickLayout.niceDomain;
    return { unzoomedTickLayout, domain: scale2.domain };
  }
  calculateLayout(initialPrimaryTickCount, chartLayout) {
    this.chartLayout = chartLayout;
    const scrollbarKey = this.getScrollbarLayoutCacheKey(chartLayout);
    const { visibleRange } = this;
    const unzoomed = visibleRange[0] === 0 && visibleRange[1] === 1;
    const { unzoomedTickLayout, domain } = this.calculateDomain(initialPrimaryTickCount, scrollbarKey);
    const nice = this.getDomainExtentsNice();
    let tickLayout;
    if (unzoomed) {
      tickLayout = unzoomedTickLayout;
    } else {
      const { range: range3, gridLength } = this;
      const rangeExtent = findRangeExtent(range3);
      const niceMode = nice.map((n) => n ? 1 /* TicksOnly */ : 2 /* Off */);
      const { tickLayoutCache } = this;
      if (tickLayoutCache == null || !tickLayoutCacheValid(tickLayoutCache, {
        domain,
        rangeExtent,
        nice,
        gridLength,
        visibleRange,
        initialPrimaryTickCount,
        scrollbarKey
      })) {
        tickLayout = this.calculateTickLayout(domain, niceMode, visibleRange, initialPrimaryTickCount);
        this.tickLayoutCache = {
          domain,
          rangeExtent,
          nice,
          gridLength,
          visibleRange,
          initialPrimaryTickCount,
          scrollbarKey,
          tickLayout
        };
      } else {
        tickLayout = tickLayoutCache.tickLayout;
      }
    }
    const { rawTickCount: zoomedTickCount = 0, fractionDigits, bbox } = tickLayout;
    const unzoomedTickCount = unzoomedTickLayout.rawTickCount ?? 0;
    const primaryTickCount = zoomedTickCount !== 0 && unzoomedTickCount !== 0 ? { zoomed: zoomedTickCount, unzoomed: unzoomedTickCount } : void 0;
    this.tickLayout = tickLayout.layout;
    this.layout.label = {
      fractionDigits,
      spacing: this.label.spacing,
      format: this.label.format
    };
    this.layoutCrossLines();
    return { primaryTickCount, bbox };
  }
  invalidateLayoutCache() {
    this.unzoomedTickLayoutCache = void 0;
    this.tickLayoutCache = void 0;
    this.tickLayout = void 0;
  }
  getScrollbarLayoutCacheKey(chartLayout) {
    const scrollbar = chartLayout?.scrollbars?.[this.id];
    if (!scrollbar?.enabled)
      return "none";
    return `${scrollbar.placement}:${scrollbar.spacing}:${scrollbar.thickness}:${scrollbar.tickSpacing}`;
  }
  updateCrossLines() {
    const crosslinesVisible = this.hasDefinedDomain() || this.hasVisibleSeries();
    for (const crossLine of this.crossLines) {
      crossLine.update(crosslinesVisible);
    }
  }
  updatePosition() {
    const { crossLineRangeGroup, crossLineLineGroup, crossLineLabelGroup, gridGroup, translation } = this;
    const translationX = Math.floor(translation.x);
    const translationY = Math.floor(translation.y);
    gridGroup.setProperties({ translationX, translationY });
    crossLineRangeGroup.setProperties({ translationX, translationY });
    crossLineLineGroup.setProperties({ translationX, translationY });
    crossLineLabelGroup.setProperties({ translationX, translationY });
  }
  // For formatting (nice rounded) tick values.
  tickFormatter(domain, ticks, primary, inputFractionDigits, inputTimeInterval, dateStyle = "long") {
    const { moduleCtx, label } = this;
    const { formatManager } = moduleCtx;
    const primaryLabel = primary ? this.primaryLabel : void 0;
    const tickFormatParams = this.tickFormatParams(domain, ticks, inputFractionDigits, inputTimeInterval);
    const boundSeries = this.formatterBoundSeries.get();
    let fractionDigits;
    let timeInterval3;
    let truncateDate;
    if (tickFormatParams.type === "number") {
      fractionDigits = tickFormatParams.fractionDigits;
    } else if (tickFormatParams.type === "date") {
      const { unit, step, epoch } = tickFormatParams;
      timeInterval3 = { unit, step, epoch };
      truncateDate = tickFormatParams.truncateDate;
    }
    const f = this.uncachedCallWithContext.bind(this);
    const params = {
      datum: void 0,
      seriesId: void 0,
      legendItemName: void 0,
      key: void 0,
      source: "axis-label",
      property: this.getFormatterProperty(),
      domain,
      boundSeries
    };
    const currentLabel = primaryLabel ?? label;
    const specifier = primary ? label.format : void 0;
    const { allowNull } = this;
    const options = {
      specifier: FormatManager.mergeSpecifiers(primaryLabel?.format, label.format),
      truncateDate,
      allowNull
    };
    return (value, index) => {
      const formatParams = this.datumFormatParams(value, params, fractionDigits, timeInterval3, dateStyle);
      formatParams.value = value;
      return currentLabel.formatValue(f, formatParams, index, { specifier, dateStyle, truncateDate }) ?? formatManager.format(f, formatParams, options) ?? formatManager.defaultFormat(formatParams, options);
    };
  }
  formatDatum(contextProvider, input, source, seriesId, legendItemName, datum, key, domain, label, params, allowNull) {
    if (input == null && !allowNull)
      return "";
    const { moduleCtx, dataDomain } = this;
    domain ?? (domain = dataDomain.domain);
    const { formatManager } = moduleCtx;
    const boundSeries = this.formatterBoundSeries.get();
    let inputFractionDigits;
    switch (source) {
      case "crosshair":
      case "annotation-label":
        inputFractionDigits = this.layout.label.fractionDigits + 1;
        break;
      case "series-label":
        inputFractionDigits = 2;
        break;
      case "tooltip":
        inputFractionDigits = 3;
        break;
      case "legend-label":
        inputFractionDigits = void 0;
        break;
    }
    const formatParams = this.datumFormatParams(
      input,
      {
        source,
        datum,
        seriesId,
        legendItemName,
        key,
        property: this.getFormatterProperty(),
        domain,
        boundSeries
      },
      inputFractionDigits,
      void 0,
      "long"
    );
    const { type, value } = formatParams;
    const f = this.createCallWithContext(contextProvider);
    const result = label?.formatValue(f, type, value, params ?? formatParams) ?? formatManager.format(f, formatParams, { allowNull }) ?? this.label.formatValue(f, formatParams, Number.NaN) ?? formatManager.defaultFormat(formatParams);
    return isArray(result) ? result : String(result);
  }
  getBBox() {
    return this.axisGroup.getBBox();
  }
  initCrossLine(crossLine) {
    crossLine.scale = this.scale;
    crossLine.gridLength = this.gridLength;
  }
  hasVisibleSeries() {
    return this.boundSeries.some((s) => s.isEnabled());
  }
  clipTickLines(x, y, width2, height2) {
    this.tickLineGroup.setClipRect(new BBox(x, y, width2, height2));
  }
  clipGrid(x, y, width2, height2) {
    this.gridGroup.setClipRect(new BBox(x, y, width2, height2));
  }
  getFormatterProperty() {
    const { direction, boundSeries } = this;
    let resolvedDirection = direction;
    for (const series of boundSeries) {
      const seriesResolvedDirection = series.resolveKeyDirection(direction);
      if (seriesResolvedDirection !== direction) {
        resolvedDirection = seriesResolvedDirection;
        break;
      }
    }
    return resolvedDirection;
  }
  getTitleFormatterParams(domain) {
    const { direction } = this;
    const boundSeries = this.formatterBoundSeries.get();
    return { domain, direction, boundSeries, defaultValue: this.title?.text };
  }
  normaliseDataDomain(d) {
    return { domain: [...d.domain], clipped: false };
  }
  getLayoutTranslation() {
    return this.translation;
  }
  getLayoutState() {
    return {
      id: this.id,
      rect: this.getBBox(),
      translation: this.getLayoutTranslation(),
      gridPadding: this.gridPadding,
      seriesAreaPadding: this.seriesAreaPadding,
      tickSize: this.getTickSize(),
      direction: this.direction,
      domain: this.dataDomain.domain,
      scale: this.scale,
      ...this.layout
    };
  }
  getModuleMap() {
    return this.moduleMap;
  }
  getUpdateTypeOnResize() {
    return 5 /* PERFORM_LAYOUT */;
  }
  createModuleContext() {
    this.axisContext ?? (this.axisContext = this.createAxisContext());
    return { ...this.moduleCtx, parent: this.axisContext };
  }
  createAxisContext() {
    const { scale: scale2 } = this;
    return {
      axisId: this.id,
      scale: this.scale,
      direction: this.direction,
      continuous: ContinuousScale.is(scale2) || DiscreteTimeScale.is(scale2),
      getCanvasBounds: () => {
        return Transformable.toCanvas(this.axisGroup);
      },
      seriesKeyProperties: () => this.boundSeries.reduce((keys, series) => {
        const seriesKeys = series.getKeyProperties(this.direction);
        for (const key of seriesKeys) {
          keys.add(key);
        }
        return keys;
      }, /* @__PURE__ */ new Set()),
      seriesIds: () => this.boundSeries.map((series) => series.id),
      scaleInvert: (val) => scale2.invert(val, true),
      scaleInvertNearest: (val) => scale2.invert(val, true),
      formatScaleValue: (value, source, label) => {
        const { allowNull } = this;
        return this.formatDatum(
          void 0,
          value,
          source,
          void 0,
          void 0,
          void 0,
          void 0,
          void 0,
          label,
          void 0,
          allowNull
        );
      },
      attachLabel: (node) => this.attachLabel(node),
      inRange: (value, tolerance) => this.inRange(value, tolerance),
      getRangeOverflow: (value) => this.getRangeOverflow(value),
      pickBand: (point) => this.pickBand(point),
      measureBand: (value) => this.measureBand(value)
    };
  }
  pickBand(point) {
    if (!BandScale.is(this.scale)) {
      return;
    }
    const { scale: scale2, range: range3, id } = this;
    const value = scale2.invert(this.isVertical() ? point.y : point.x, true);
    const [position, start2, end3] = computeBand(scale2, range3, value);
    return { id, value, band: [start2, end3], position };
  }
  measureBand(value) {
    if (!BandScale.is(this.scale)) {
      return;
    }
    const [, start2, end3] = computeBand(this.scale, this.range, value);
    return { band: [start2, end3] };
  }
  isVertical() {
    return this.direction === "y" /* Y */;
  }
  isReversed() {
    return this.reverse;
  }
  cachedCallWithContext(fn, params) {
    const { callbackCache, chartService } = this.moduleCtx;
    return callbackCache.call([this, chartService], fn, params);
  }
  uncachedCallWithContext(fn, params) {
    const { chartService } = this.moduleCtx;
    return callWithContext([this, chartService], fn, params);
  }
  createCallWithContext(contextProvider) {
    const { chartService } = this.moduleCtx;
    return (fn, params) => callWithContext([contextProvider, this, chartService], fn, params);
  }
};
_Axis.defaultTickMinSpacing = 50;
_Axis.CrossLineConstructor = CartesianCrossLine;
__decorateClass([
  addFakeTransformToInstanceProperty
], _Axis.prototype, "nice", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], _Axis.prototype, "reverse", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], _Axis.prototype, "interval", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], _Axis.prototype, "title", 2);
__decorateClass([
  ObserveChanges((target, value, oldValue) => target.onGridLengthChange(value, oldValue))
], _Axis.prototype, "gridLength", 2);
var Axis = _Axis;

// packages/ag-charts-community/src/chart/axis/cartesianAxisLabel.ts
var CartesianAxisLabel = class extends AxisLabel {
  constructor() {
    super(...arguments);
    this.autoRotateAngle = 335;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianAxisLabel.prototype, "autoRotate", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianAxisLabel.prototype, "autoRotateAngle", 2);

// packages/ag-charts-community/src/scale/categoryScale.ts
var CategoryScale = class _CategoryScale extends BandScale {
  constructor() {
    super(...arguments);
    this.type = "category";
    this.defaultTickCount = 0;
    /**
     * Maps datum to its index in the {@link domain} array.
     * Used to check for duplicate data (not allowed).
     */
    this.index = /* @__PURE__ */ new Map();
    this.indexInitialized = false;
    /**
     * Contains unique data only.
     */
    this._domain = [];
  }
  static is(value) {
    return value instanceof _CategoryScale;
  }
  set domain(values) {
    if (this._domain === values)
      return;
    this.invalid = true;
    this._domain = values;
    this.index.clear();
    this.indexInitialized = false;
  }
  get domain() {
    return this._domain;
  }
  get bands() {
    return this._domain;
  }
  normalizeDomains(...domains) {
    let normalizedDomain = void 0;
    const seenDomains = /* @__PURE__ */ new Set();
    let animatable = true;
    for (const input of domains) {
      const domain = input.domain;
      if (seenDomains.has(domain))
        continue;
      seenDomains.add(domain);
      if (normalizedDomain == null) {
        normalizedDomain = deduplicateCategories(domain);
      } else {
        animatable && (animatable = domainOrderedToNormalizedDomain(domain, normalizedDomain));
        normalizedDomain = deduplicateCategories([...normalizedDomain, ...domain]);
      }
    }
    normalizedDomain ?? (normalizedDomain = []);
    return { domain: normalizedDomain, animatable };
  }
  toDomain(_value) {
    return void 0;
  }
  invert(position, nearest = false) {
    this.refresh();
    const offset = nearest ? this.bandwidth / 2 : 0;
    const index = this.invertNearestIndex(Math.max(0, position - offset));
    const matches = nearest || position === this.ordinalRange(index);
    return matches ? this.domain[index] : void 0;
  }
  ticks(params, domain = this.domain, visibleRange) {
    const { bands } = this;
    let { tickCount } = params;
    if (tickCount === 0) {
      const firstTickIndex2 = bands.length > 1 ? 1 : 0;
      const ticks2 = bands[firstTickIndex2] ? [bands[firstTickIndex2]] : [];
      return { ticks: ticks2, count: void 0, firstTickIndex: firstTickIndex2 };
    }
    let step = tickCount != null && tickCount !== 0 ? Math.trunc(bands.length / tickCount) : 1;
    step = previousPowerOf2(step);
    if (step <= 1) {
      return filterVisibleTicks(domain, false, visibleRange);
    }
    tickCount = Math.trunc(bands.length / step);
    const span = step * tickCount;
    const inset = previousPowerOf2(Math.trunc((bands.length - span) / 2));
    const vt0 = clamp(0, Math.floor((visibleRange?.[0] ?? 0) * bands.length), bands.length);
    const vt1 = clamp(0, Math.ceil((visibleRange?.[1] ?? 1) * bands.length), bands.length);
    const i0 = Math.floor((vt0 - inset) / step) * step + inset;
    const i1 = Math.ceil((vt1 - inset) / step) * step + inset;
    const ticks = [];
    for (let i = i0; i < i1; i += step) {
      if (i >= 0 && i < bands.length) {
        ticks.push(bands[i]);
      }
    }
    let firstTickIndex = ticks.length > 0 ? this.findIndex(ticks[0]) : void 0;
    if (firstTickIndex != null) {
      firstTickIndex = Math.floor((firstTickIndex - inset) / step);
    }
    return { ticks, count: void 0, firstTickIndex };
  }
  findIndex(value) {
    const { index, indexInitialized } = this;
    if (!indexInitialized) {
      const { domain } = this;
      for (let i = 0; i < domain.length; i++) {
        index.set(dateToNumber(domain[i]), i);
      }
      this.indexInitialized = true;
    }
    return index.get(dateToNumber(value));
  }
};
function deduplicateCategories(d) {
  let domain;
  const uniqueValues = /* @__PURE__ */ new Set();
  for (const value of d) {
    const key = dateToNumber(value);
    const lastSize = uniqueValues.size;
    uniqueValues.add(key);
    const isUniqueValue = uniqueValues.size !== lastSize;
    if (isUniqueValue) {
      domain?.push(value);
    } else {
      domain ?? (domain = d.slice(0, uniqueValues.size));
    }
  }
  return domain ?? d;
}
function domainOrderedToNormalizedDomain(domain, normalizedDomain) {
  let normalizedIndex = -1;
  for (const value of domain) {
    const normalizedNextIndex = normalizedDomain.indexOf(value);
    if (normalizedNextIndex === -1) {
      normalizedIndex = Infinity;
    } else if (normalizedNextIndex <= normalizedIndex) {
      return false;
    } else {
      normalizedIndex = normalizedNextIndex;
    }
  }
  return true;
}

// packages/ag-charts-community/src/scale/timeScale.ts
var sunday = new Date(1970, 0, 4);
var TimeScale = class _TimeScale extends ContinuousScale {
  constructor() {
    super([], [0, 1]);
    this.type = "time";
  }
  static is(value) {
    return value instanceof _TimeScale;
  }
  toDomain(d) {
    return new Date(d);
  }
  convert(value, options) {
    return super.convert(typeof value === "number" ? value : value?.valueOf() ?? Number.NaN, options);
  }
  invert(value) {
    return new Date(super.invert(value));
  }
  niceDomain(ticks, domain = this.domain) {
    if (domain.length < 2)
      return [];
    let [d0, d1] = domain;
    const maxAttempts = 4;
    const availableRange = this.getPixelRange();
    for (let i = 0; i < maxAttempts; i++) {
      const [n0, n1] = updateNiceDomainIteration(d0, d1, ticks, availableRange);
      if (dateToNumber(d0) === dateToNumber(n0) && dateToNumber(d1) === dateToNumber(n1)) {
        break;
      }
      d0 = n0;
      d1 = n1;
    }
    return [d0, d1];
  }
  /**
   * Returns uniformly-spaced dates that represent the scale's domain.
   */
  ticks(params, domain = this.domain, visibleRange = [0, 1], { extend = false } = {}) {
    const { nice, interval, tickCount = ContinuousScale.defaultTickCount, minTickCount, maxTickCount } = params;
    if (domain.length < 2)
      return;
    const timestamps = domain.map(dateToNumber);
    const start2 = timestamps[0];
    const stop = timestamps.at(-1);
    if (interval != null) {
      const availableRange = this.getPixelRange();
      return {
        ticks: getDateTicksForInterval({ start: start2, stop, interval, availableRange, visibleRange, extend }) ?? getDefaultDateTicks({ start: start2, stop, tickCount, minTickCount, maxTickCount, visibleRange, extend }),
        count: void 0
      };
    } else if (nice.every(Boolean) && tickCount === 2) {
      return { ticks: domain, count: void 0 };
    } else if (nice.every(Boolean) && tickCount === 1) {
      return { ticks: domain.slice(0, 1), count: void 0 };
    }
    const timeInterval3 = getTickTimeInterval(start2, stop, tickCount, minTickCount, maxTickCount, {
      weekStart: sunday
    });
    if (timeInterval3 == null)
      return;
    const ticks = intervalRange(timeInterval3, new Date(start2), new Date(stop), { visibleRange, extend });
    const firstTickIndex = intervalRangeStartIndex(timeInterval3, new Date(start2), new Date(stop), {
      visibleRange,
      extend
    });
    return {
      ticks,
      count: void 0,
      firstTickIndex,
      timeInterval: timeInterval3
    };
  }
};
function getDefaultDateTicks({
  start: start2,
  stop,
  tickCount,
  minTickCount,
  maxTickCount,
  visibleRange,
  extend
}) {
  const t = getTickTimeInterval(start2, stop, tickCount, minTickCount, maxTickCount, { weekStart: sunday });
  return t ? intervalRange(t, new Date(start2), new Date(stop), { visibleRange, extend }) : [];
}
function getDateTicksForInterval({
  start: start2,
  stop,
  interval,
  availableRange,
  visibleRange,
  extend
}) {
  if (!interval) {
    return [];
  }
  if (isPlainObject(interval) || typeof interval === "string") {
    const ticks2 = intervalRange(interval, new Date(start2), new Date(stop), { visibleRange, extend });
    if (isDenseInterval(ticks2.length, availableRange)) {
      return;
    }
    return ticks2;
  }
  const absInterval = Math.abs(interval);
  if (isDenseInterval(Math.abs(stop - start2) / absInterval, availableRange))
    return;
  const tickInterval = TickIntervals.findLast((t) => absInterval % t.duration === 0);
  if (tickInterval) {
    const { timeInterval: timeInterval3, step, duration } = tickInterval;
    const alignedInterval = {
      ...timeInterval3,
      step: step * intervalStep(timeInterval3) * Math.round(absInterval / duration),
      epoch: defaultEpoch(timeInterval3, { weekStart: sunday })
    };
    return intervalRange(alignedInterval, new Date(start2), new Date(stop), { visibleRange, extend });
  }
  let date2 = new Date(Math.min(start2, stop));
  const stopDate = new Date(Math.max(start2, stop));
  const ticks = [];
  while (date2 <= stopDate) {
    ticks.push(date2);
    date2 = new Date(date2);
    date2.setMilliseconds(date2.getMilliseconds() + absInterval);
  }
  return ticks;
}
function updateNiceDomainIteration(d0, d1, ticks, availableRange) {
  const { interval } = ticks;
  const start2 = Math.min(dateToNumber(d0), dateToNumber(d1));
  const stop = Math.max(dateToNumber(d0), dateToNumber(d1));
  let i;
  if (isPlainObject(interval) || typeof interval === "string") {
    i = interval;
  } else {
    let tickCount;
    if (typeof interval === "number") {
      tickCount = (stop - start2) / Math.max(interval, 1);
      if (isDenseInterval(tickCount, availableRange)) {
        tickCount = void 0;
      }
    }
    tickCount ?? (tickCount = ticks.tickCount ?? ContinuousScale.defaultTickCount);
    i = getTickTimeInterval(start2, stop, tickCount, ticks.minTickCount, ticks.maxTickCount, { weekStart: sunday });
  }
  if (i == null)
    return [d0, d1];
  const domain = intervalRange(i, new Date(start2), new Date(stop), { extend: true });
  if (domain == null || domain.length < 2)
    return [d0, d1];
  const r0 = domain[0];
  const r1 = domain.at(-1);
  return d0 <= d1 ? [r0, r1] : [r1, r0];
}

// packages/ag-charts-community/src/scale/ordinalTimeScale.ts
var APPROXIMATE_THRESHOLD2 = 1e3;
var OrdinalTimeScale = class _OrdinalTimeScale extends DiscreteTimeScale {
  constructor() {
    super(...arguments);
    this.type = "ordinal-time";
    this.defaultTickCount = ContinuousScale.defaultTickCount;
    this._domain = [];
    this.isReversed = false;
  }
  static is(value) {
    return value instanceof _OrdinalTimeScale;
  }
  set domain(domain) {
    if (domain === this._domain)
      return;
    this.invalid = true;
    this._domain = domain;
    this._bands = void 0;
    this._numericBands = void 0;
    this._uniformityCache = void 0;
    this.isReversed = domainReversed(domain);
  }
  get domain() {
    return this._domain;
  }
  get bands() {
    this._bands ?? (this._bands = this.isReversed ? this.domain.slice().reverse() : this.domain);
    return this._bands;
  }
  get numericBands() {
    this._numericBands ?? (this._numericBands = this.bands.map((d) => d.valueOf()));
    return this._numericBands;
  }
  getUniformityCache(visibleRange) {
    const { bands } = this;
    const n = bands.length;
    if (!visibleRange || visibleRange[0] === 0 && visibleRange[1] === 1) {
      if (n > APPROXIMATE_THRESHOLD2 && this._uniformityCache === void 0) {
        this._uniformityCache = checkUniformityBySampling(bands);
      }
      return this._uniformityCache;
    }
    const startIdx = Math.floor(visibleRange[0] * n);
    const endIdx = Math.min(Math.ceil(visibleRange[1] * n), n - 1);
    return checkUniformityBySampling(bands, startIdx, endIdx);
  }
  normalizeDomains(...domains) {
    const nonEmptyDomains = domains.filter((d) => d.domain.length > 0);
    if (nonEmptyDomains.length === 0) {
      return { domain: [], animatable: false };
    }
    const firstDomain = nonEmptyDomains[0].domain;
    const allSame = nonEmptyDomains.every((d) => d.domain === firstDomain);
    if (nonEmptyDomains.length === 1 || allSame) {
      const input = nonEmptyDomains[0];
      let domain = input.domain;
      let sortOrder;
      let isUnique = false;
      if (input.sortMetadata?.sortOrder === void 0) {
        sortOrder = datesSortOrder(domain);
      } else {
        sortOrder = input.sortMetadata.sortOrder;
        isUnique = input.sortMetadata.isUnique ?? false;
      }
      if (sortOrder === -1) {
        domain = domain.slice().reverse();
      } else if (sortOrder == null) {
        domain = isUnique ? domain.slice().sort((a, b) => a.valueOf() - b.valueOf()) : sortAndUniqueDates(domain.slice());
      }
      return { domain, animatable: true };
    }
    return {
      domain: sortAndUniqueDates(nonEmptyDomains.map((d) => d.domain).flat()),
      animatable: true
    };
  }
  ticks(params, domain, visibleRange = [0, 1], { extend = false, dropInitial = false } = {}) {
    const { interval, maxTickCount, tickCount = maxTickCount } = params;
    const { bands, reversed } = this;
    if (!bands.length)
      return;
    if (reversed) {
      visibleRange = [1 - visibleRange[1], 1 - visibleRange[0]];
    }
    this.refresh();
    if (interval == null) {
      const { ticks: ticks2, tickOffset, tickEvery } = this.getDefaultTicks(domain, tickCount, visibleRange, extend);
      let firstTickIndex = ticks2.length > 0 ? this.findIndex(ticks2[0]) : void 0;
      firstTickIndex = firstTickIndex == null ? void 0 : Math.floor((firstTickIndex - tickOffset) / tickEvery);
      return { ticks: ticks2, count: void 0, firstTickIndex };
    }
    let start2;
    let stop;
    if (domain && domain.length >= 2) {
      start2 = domain[0].valueOf();
      stop = domain.at(-1).valueOf();
    } else {
      start2 = bands[0].valueOf();
      stop = bands.at(-1).valueOf();
    }
    const [r0, r1] = this.range;
    const availableRange = Math.abs(r1 - r0);
    const dateTicks = getDateTicksForInterval({ start: start2, stop, interval, availableRange, visibleRange, extend }) ?? this.getDefaultTicks(domain, tickCount, visibleRange, extend).ticks;
    const ticks = [];
    let lastIndex = -1;
    for (const dateTick of dateTicks) {
      const index = this.findIndex(dateTick, 1 /* Trailing */) ?? -1;
      const duplicated = index === lastIndex;
      lastIndex = index;
      if (!(dropInitial && index === 0) && index !== -1 && !duplicated) {
        ticks.push(bands[index]);
      }
    }
    return { ticks, count: void 0, firstTickIndex: void 0 };
  }
  stepTicks(bandStep, domain, visibleRange = [0, 1], dropLast = true) {
    const bandIndices = domain ? this.bandDomainIndices(domain) : void 0;
    const ticks = this.ticksEvery(bandIndices, visibleRange, bandStep, 0, false);
    const lastTick = ticks.at(-1);
    const lastBandIndex = dropLast && bandStep > 1 ? bandIndices?.[1] : void 0;
    const lastTickIndex = lastBandIndex != null && lastTick != null ? this.findIndex(lastTick) : void 0;
    if (lastTickIndex != null && lastBandIndex != null && lastBandIndex - lastTickIndex < bandStep) {
      ticks.pop();
    }
    return ticks;
  }
  bandCount(visibleRange = [0, 1]) {
    const { domain } = this;
    const startIndex = Math.floor(visibleRange[0] * domain.length);
    const endIndex = Math.ceil(visibleRange[1] * domain.length);
    return endIndex - startIndex;
  }
  getDefaultTicks(domain, maxTickCount, visibleRange, extend) {
    const { bands } = this;
    const tickEvery = Math.ceil(bands.length / maxTickCount);
    const tickOffset = Math.floor(tickEvery / 2);
    const bandIndices = domain ? this.bandDomainIndices(domain) : void 0;
    return {
      ticks: this.ticksEvery(bandIndices, visibleRange, tickEvery, tickOffset, extend),
      tickOffset,
      tickEvery
    };
  }
  bandDomainIndices(domain) {
    const isReversed = domainReversed(domain);
    const i0 = this.findIndex(domain[isReversed ? domain.length - 1 : 0], 1 /* Trailing */) ?? 0;
    const i1 = this.findIndex(domain[isReversed ? 0 : domain.length - 1], 1 /* Trailing */) ?? this.bands.length - 1;
    return [i0, i1];
  }
  ticksEvery([i0, i1] = [0, this.bands.length], visibleRange, tickEvery, tickOffset, extend) {
    const { bands } = this;
    const offset = i0;
    const span = i1 - i0 + 1;
    let startIndex = offset + Math.floor(visibleRange[0] * span);
    let endIndex = offset + Math.ceil(visibleRange[1] * span);
    if (extend) {
      startIndex -= tickEvery;
      endIndex += tickEvery;
    }
    startIndex = Math.max(startIndex, 0);
    endIndex = Math.min(endIndex, bands.length);
    let ticks;
    if (tickEvery <= 1) {
      ticks = bands.slice(startIndex, endIndex);
    } else {
      ticks = [];
      for (let index = startIndex; index < endIndex; index += 1) {
        if ((index - offset + tickOffset) % tickEvery === 0) {
          ticks.push(bands[index]);
        }
      }
    }
    return ticks;
  }
};
function domainReversed(domain) {
  return domain.length > 0 && domain[0] > domain.at(-1);
}

// packages/ag-charts-community/src/scale/unitTimeScale.ts
var APPROXIMATE_THRESHOLD3 = 1e3;
var MAX_BANDS = 5e7;
var UnitTimeScale = class _UnitTimeScale extends DiscreteTimeScale {
  constructor() {
    super(...arguments);
    this.type = "unit-time";
    this.defaultTickCount = 12;
    this._domain = [];
    this._bands = void 0;
  }
  static is(value) {
    return value instanceof _UnitTimeScale;
  }
  static supportsInterval(domain, interval) {
    return supportsInterval(domain, interval);
  }
  set domain(domain) {
    if (domain === this._domain)
      return;
    this._domain = domain;
    this._bands = void 0;
    this._numericBands = void 0;
    this._uniformityCache = void 0;
    this._domainBoundaries = void 0;
    this._bandRangeCache = void 0;
    this._encodedBands = void 0;
    this._encodingParams = void 0;
    this._linearParams = void 0;
  }
  get domain() {
    return this._domain;
  }
  get interval() {
    return this._interval;
  }
  set interval(interval) {
    if (this._interval === interval)
      return;
    this._interval = interval;
    this._bands = void 0;
    this._numericBands = void 0;
    this._uniformityCache = void 0;
    this._domainBoundaries = void 0;
    this._bandRangeCache = void 0;
    this._encodedBands = void 0;
    this._encodingParams = void 0;
    this._linearParams = void 0;
  }
  get bands() {
    if (this._bands === void 0) {
      this.ensureEncodedBands();
      if (this._encodedBands != null && this._encodingParams != null) {
        const params = this._encodingParams;
        this._bands = this._encodedBands.map((e) => decodeIntervalValue(e, params));
      } else {
        this._bands = [];
      }
    }
    return this._bands;
  }
  get numericBands() {
    if (this._numericBands === void 0) {
      this.ensureEncodedBands();
      if (this._encodedBands != null && this._encodingParams != null) {
        const params = this._encodingParams;
        this._numericBands = this._encodedBands.map((e) => encodedToTimestamp(e, params));
      } else {
        this._numericBands = [];
      }
    }
    return this._numericBands;
  }
  /**
   * Ensure encoded bands are computed. This is the numeric-first optimization:
   * we compute just the encoded values (cheap numbers) and defer Date creation.
   */
  ensureEncodedBands() {
    if (this._encodedBands !== void 0)
      return;
    const { domain, interval } = this;
    if (domain.length < 2 || interval == null) {
      this._encodedBands = [];
      return;
    }
    const bandRange = this.getCachedBandRange();
    if (bandRange == null) {
      this._encodedBands = [];
      return;
    }
    const [start2, stop] = bandRange;
    const rangeParams = { visibleRange: [0, 1], extend: false };
    if (intervalRangeCount(interval, start2, stop, rangeParams) > MAX_BANDS) {
      logger_exports.warnOnce(`the configured unit results in too many bands, ignoring. Supply a larger unit.`);
      this._encodedBands = [];
      return;
    }
    const { encodedValues, encodingParams } = intervalRangeNumeric(interval, start2, stop, rangeParams);
    this._encodedBands = encodedValues;
    this._encodingParams = encodingParams;
  }
  /** Override to return band count without triggering Date materialization */
  getBandCountForUpdate() {
    this.ensureEncodedBands();
    return this._encodedBands?.length ?? 0;
  }
  getUniformityCache(visibleRange) {
    const n = this.getBandCountForUpdate();
    if (!visibleRange || visibleRange[0] === 0 && visibleRange[1] === 1) {
      if (n > APPROXIMATE_THRESHOLD3 && this._uniformityCache === void 0) {
        this.ensureEncodedBands();
        if (this._encodingParams != null && this._encodedBands != null && this._encodedBands.length >= 2) {
          const t0 = encodedToTimestamp(this._encodedBands[0], this._encodingParams);
          const t1 = encodedToTimestamp(this._encodedBands[1], this._encodingParams);
          this._uniformityCache = { isUniform: true, interval: t1 - t0 };
        } else {
          this._uniformityCache = { isUniform: false };
        }
      }
      return this._uniformityCache;
    }
    this.ensureEncodedBands();
    if (this._encodingParams != null && this._encodedBands != null && this._encodedBands.length >= 2) {
      const t0 = encodedToTimestamp(this._encodedBands[0], this._encodingParams);
      const t1 = encodedToTimestamp(this._encodedBands[1], this._encodingParams);
      return { isUniform: true, interval: t1 - t0 };
    }
    return { isUniform: false };
  }
  normalizeDomains(...domains) {
    return normalizeContinuousDomains(...domains);
  }
  getCachedBandRange() {
    const { domain, interval } = this;
    if (domain.length < 2 || interval == null)
      return void 0;
    this._bandRangeCache ?? (this._bandRangeCache = {
      start: intervalFloor(interval, domain[0]),
      stop: intervalFloor(interval, domain[1])
    });
    return [this._bandRangeCache.start, this._bandRangeCache.stop];
  }
  getDomainBoundaries() {
    const { interval } = this;
    if (interval == null)
      return void 0;
    if (this._domainBoundaries === void 0) {
      const bandRange = this.getCachedBandRange();
      if (bandRange == null)
        return void 0;
      const [start2, stop] = bandRange;
      const d0 = Math.min(start2.valueOf(), stop.valueOf());
      const d1 = Math.max(start2.valueOf(), stop.valueOf());
      const dNext = intervalNext(interval, new Date(d1)).valueOf();
      this._domainBoundaries = { d0, dNext };
    }
    return this._domainBoundaries;
  }
  /** Get linear params for O(1) index calculation and scaling metadata */
  getLinearParams() {
    if (this._linearParams === void 0) {
      this.ensureEncodedBands();
      if (this._encodedBands != null && this._encodingParams != null && this._encodedBands.length >= 2) {
        const firstBandTime = encodedToTimestamp(this._encodedBands[0], this._encodingParams);
        const secondBandTime = encodedToTimestamp(this._encodedBands[1], this._encodingParams);
        this._linearParams = {
          firstBandTime,
          intervalMs: secondBandTime - firstBandTime
        };
      }
    }
    return this._linearParams;
  }
  /** Check if current encoding uses a linear unit (exact arithmetic, no DST issues) */
  isLinearUnit() {
    const unit = this._encodingParams?.unit;
    return unit === "millisecond" || unit === "second" || unit === "minute" || unit === "hour";
  }
  /**
   * O(1) findIndex for uniform bands.
   * For linear units (ms/sec/min/hour), uses pure arithmetic without verification.
   * For non-linear units (day/month/year), verifies against actual band values.
   */
  findIndex(value, alignment = 0 /* Leading */) {
    if (value == null)
      return void 0;
    const n = this.getBandCountForUpdate();
    if (n === 0)
      return void 0;
    if (n === 1)
      return 0;
    const linearParams = this.getLinearParams();
    if (linearParams == null || linearParams.intervalMs === 0) {
      return super.findIndex(value, alignment);
    }
    const { firstBandTime, intervalMs } = linearParams;
    const target = value.valueOf();
    const rawIndex = (target - firstBandTime) / intervalMs;
    let index = alignment === 1 /* Trailing */ ? Math.ceil(rawIndex) : Math.floor(rawIndex);
    index = Math.max(0, Math.min(index, n - 1));
    if (this.isLinearUnit()) {
      if (alignment === 1 /* Trailing */) {
        const bandTime = firstBandTime + index * intervalMs;
        if (bandTime < target && index === n - 1)
          return void 0;
      } else {
        const bandTime = firstBandTime + index * intervalMs;
        if (bandTime > target && index === 0)
          return void 0;
      }
      return index;
    }
    const numericBands = this.numericBands;
    if (alignment === 1 /* Trailing */) {
      while (index > 0 && numericBands[index - 1] >= target)
        index--;
      while (index < n - 1 && numericBands[index] < target)
        index++;
      if (numericBands[index] < target)
        return void 0;
    } else {
      while (index < n - 1 && numericBands[index + 1] <= target)
        index++;
      while (index > 0 && numericBands[index] > target)
        index--;
      if (numericBands[index] > target)
        return void 0;
    }
    return index;
  }
  /**
   * Optimized convert for UnitTimeScale with O(1) boundary checks.
   * Uses linear params for fast bounds checking while delegating actual
   * conversion to parent for accuracy in edge cases.
   */
  convert(value, options) {
    this.refresh();
    if (!(value instanceof Date))
      value = new Date(value);
    const { domain, interval } = this;
    if (domain.length < 2)
      return Number.NaN;
    if (options?.clamp !== true && interval != null) {
      const boundaries = this.getDomainBoundaries();
      if (boundaries != null) {
        const t = value.valueOf();
        if (t < boundaries.d0 || t >= boundaries.dNext)
          return Number.NaN;
      }
    }
    return super.convert(value, options);
  }
  calculateBands(domain, visibleRange, extend = false) {
    if (domain === this.domain && visibleRange[0] === 0 && visibleRange[1] === 1 && !extend && this._bands != null) {
      return { bands: this._bands, firstBandIndex: 0 };
    }
    if (domain.length < 2)
      return { bands: [], firstBandIndex: void 0 };
    const { interval } = this;
    if (interval == null)
      return { bands: [], firstBandIndex: void 0 };
    const rangeParams = { visibleRange, extend };
    if (!supportsInterval(domain, interval, rangeParams))
      return { bands: [], firstBandIndex: void 0 };
    const bandRange = domain === this.domain ? this.getCachedBandRange() : calculateBandRange(domain, interval);
    if (bandRange == null)
      return { bands: [], firstBandIndex: void 0 };
    const [start2, stop] = bandRange;
    if (intervalRangeCount(interval, start2, stop, rangeParams) > MAX_BANDS) {
      logger_exports.warnOnce(`the configured unit results in too many bands, ignoring. Supply a larger unit.`);
      return { bands: [], firstBandIndex: void 0 };
    }
    const bands = intervalRange(interval, start2, stop, rangeParams);
    const firstBandIndex = intervalRangeStartIndex(interval, start2, stop, rangeParams);
    return { bands, firstBandIndex };
  }
  ticks({ interval }, domain = this.domain, visibleRange = [0, 1], { extend = false } = {}) {
    if (domain.length < 2)
      return;
    let bands;
    let firstBandIndex;
    let bandsSliceIndices;
    if (domain === this.domain && !extend) {
      ({ bands } = this.calculateBands(domain, [0, 1], false));
      bandsSliceIndices = visibleTickSliceIndices(bands, false, visibleRange);
      firstBandIndex = bandsSliceIndices[0];
    } else {
      ({ bands, firstBandIndex } = this.calculateBands(domain, visibleRange, extend));
    }
    if (interval == null) {
      return { ticks: bands, count: void 0, firstTickIndex: firstBandIndex };
    }
    const milliseconds = this.interval ? intervalMilliseconds(this.interval) : Infinity;
    const d0 = Math.min(domain[0].valueOf(), domain[1].valueOf());
    const d1 = Math.max(domain[0].valueOf(), domain[1].valueOf());
    let intervalTicks;
    let intervalStartIndex;
    let intervalEndIndex;
    if (isPlainObject(interval) || typeof interval === "string") {
      intervalTicks = intervalRange(interval, domain[0], domain[1], { extend: true, visibleRange });
      intervalStartIndex = 0;
      intervalEndIndex = intervalTicks.length - 1;
    } else {
      const i0 = bandsSliceIndices ? bandsSliceIndices[0] : 0;
      const i1 = bandsSliceIndices ? bandsSliceIndices[1] : bands.length - 1;
      intervalTicks = bands;
      intervalStartIndex = findMaxIndex(i0, i1, (index) => bands[index].valueOf() <= d0) ?? i0;
      intervalEndIndex = findMaxIndex(i0, i1, (index) => bands[index].valueOf() <= d1) ?? i1;
    }
    const ticks = [];
    let lastIndex;
    for (let i = intervalStartIndex; i <= intervalEndIndex; i++) {
      const intervalTickValue = intervalTicks[i].valueOf();
      const bandIndex = findMaxIndex(0, bands.length - 1, (index) => bands[index].valueOf() <= intervalTickValue);
      const tick = bandIndex != null && bandIndex != lastIndex ? bands[bandIndex] : void 0;
      lastIndex = bandIndex;
      if (tick != null && intervalTickValue - tick.getTime() <= milliseconds)
        ticks.push(tick);
    }
    let bandStart;
    let bandEnd;
    if (this.interval) {
      const bandRange = calculateBandRange([new Date(d0), new Date(d1)], this.interval);
      bandStart = bandRange[0].valueOf();
      bandEnd = bandRange[1].valueOf();
    } else {
      bandStart = d0;
      bandEnd = d1;
    }
    let firstTickIndex = findMinIndex(0, ticks.length - 1, (i) => ticks[i].valueOf() >= bandStart) ?? 0;
    let lastTickIndex = findMaxIndex(0, ticks.length - 1, (i) => ticks[i].valueOf() <= bandEnd) ?? ticks.length - 1;
    if (extend) {
      firstTickIndex = Math.max(firstTickIndex - 1, 0);
      lastTickIndex = Math.min(lastTickIndex + 1, ticks.length - 1);
    }
    return {
      ticks: ticks.slice(firstTickIndex, lastTickIndex + 1),
      count: ticks.length,
      firstTickIndex: firstBandIndex
    };
  }
};
function supportsInterval(domain, interval, rangeParams) {
  const [start2, stop] = calculateBandRange(domain, interval);
  return intervalRangeCount(interval, start2, stop, rangeParams) <= MAX_BANDS;
}
function calculateBandRange(domain, interval) {
  const start2 = intervalFloor(interval, domain[0]);
  const stop = intervalFloor(interval, domain[1]);
  return [start2, stop];
}

// packages/ag-charts-community/src/util/secondaryAxisTicks.ts
function calculateNiceSecondaryAxis(scale2, domain, primaryTickCount, reverse, visibleRange) {
  let [d0, d1] = findMinMax(domain.map(Number));
  const unzoomedTickCount = Math.floor(primaryTickCount.unzoomed);
  if (unzoomedTickCount <= 1) {
    const [start3, stop2] = domainWithOddTickCount(d0, d1);
    const tickCount = 5 * Math.pow(2, -Math.ceil(Math.log2(visibleRange[1] - visibleRange[0])));
    const { ticks: ticks2 } = createTicks(start3, stop2, tickCount, void 0, void 0, visibleRange);
    const d2 = [scale2.toDomain(start3), scale2.toDomain(stop2)];
    if (reverse)
      d2.reverse();
    return { domain: d2, ticks: ticks2 };
  }
  if (d0 === d1) {
    const order = Math.floor(Math.log10(d0));
    const magnitude = Math.pow(10, order);
    const rangeOffsetStep = Math.min(magnitude, 1);
    const rangeOffset = unzoomedTickCount - 1;
    d0 -= rangeOffsetStep * Math.floor(rangeOffset / 2);
    d1 = d0 + rangeOffsetStep * rangeOffset;
  }
  let start2 = d0;
  let stop = d1;
  start2 = calculateNiceStart(start2, stop, unzoomedTickCount);
  const baseStep = getTickStep(start2, stop, unzoomedTickCount);
  const segments = unzoomedTickCount - 1;
  stop = start2 + segments * baseStep;
  const stepAlignedStart = Math.floor(start2 / baseStep) * baseStep;
  const stepAlignedStop = Math.floor(stop / baseStep) * baseStep;
  if (stepAlignedStart <= d0 && stepAlignedStop >= d1) {
    start2 = stepAlignedStart;
    stop = stepAlignedStop;
  }
  const d = [scale2.toDomain(start2), scale2.toDomain(stop)];
  if (reverse)
    d.reverse();
  const step = baseStep * ((primaryTickCount.unzoomed - 1) / (primaryTickCount.zoomed - 1));
  const ticks = getTicks(start2, step, Math.floor(primaryTickCount.zoomed));
  return { domain: d, ticks };
}
function domainWithOddTickCount(d0, d1) {
  let start2 = d0;
  let stop = d1;
  let iterations = 0;
  do {
    [start2, stop] = niceTicksDomain(start2, stop);
    const { ticks } = createTicks(start2, stop, 5);
    if (ticks.length % 2 === 1)
      return [start2, stop];
    start2 -= 1;
    stop += 1;
  } while (iterations++ < 10);
  return [d0, d1];
}
function calculateNiceStart(a, b, count) {
  a = Math.floor(a);
  const rawStep = Math.abs(b - a) / (count - 1);
  const order = Math.floor(Math.log10(rawStep));
  const magnitude = Math.pow(10, order);
  return Math.floor(a / magnitude) * magnitude;
}
function getTicks(start2, step, count) {
  const fractionDigits = countFractionDigits(step);
  const f = Math.pow(10, fractionDigits);
  const ticks = [];
  for (let i = 0; i < count; i++) {
    const tick = start2 + step * i;
    ticks.push(Math.round(tick * f) / f);
  }
  return ticks;
}
function getTickStep(start2, stop, count) {
  const segments = count - 1;
  const rawStep = (stop - start2) / segments;
  return calculateNextNiceStep(rawStep);
}
function calculateNextNiceStep(rawStep) {
  const order = Math.floor(Math.log10(rawStep));
  const magnitude = Math.pow(10, order);
  const step = rawStep / magnitude;
  if (step > 0 && step <= 1)
    return magnitude;
  if (step > 1 && step <= 2)
    return 2 * magnitude;
  if (step > 2 && step <= 5)
    return 5 * magnitude;
  if (step > 5 && step <= 10)
    return 10 * magnitude;
  return rawStep;
}

// packages/ag-charts-community/src/chart/axis/generateTicksUtils.ts
var DENSE_TICK_COUNT = 18;
var TICK_STEP_VALUES = [1, 2, 3, 4, 6, 8, 9, 10, 12];
function axisLabelsOverlap(data, padding2 = 0) {
  const result = [];
  for (const datum of data) {
    const { x, y, width: width2, height: height2 } = datum;
    if (result.some((l) => boxCollides(l, x, y, width2 + padding2, height2 + padding2))) {
      return true;
    }
    result.push(datum);
  }
  return false;
}
function createTimeScaleTicks(interval, domain, visibleRange, extend) {
  if (interval == null) {
    return domain;
  }
  if (typeof interval !== "number") {
    const epoch = domain[0];
    const alignedInterval = typeof interval === "string" ? { unit: interval, epoch } : { ...interval, epoch };
    return intervalRange(alignedInterval, domain[0], domain[1], { visibleRange, extend });
  }
  const ticks = [];
  const d0 = domain[0].valueOf();
  const d1 = domain[1].valueOf();
  for (let intervalTickTime = d0; intervalTickTime <= d1; intervalTickTime += interval) {
    ticks.push(new Date(intervalTickTime));
  }
  return ticks;
}
function ticksEqual(a, b) {
  if (a.length !== b.length) {
    return false;
  }
  for (let i = 0; i < a.length; i += 1) {
    if (a[i]?.valueOf() !== b[i]?.valueOf()) {
      return false;
    }
  }
  return true;
}
function ticksSpacing(ticks) {
  if (ticks.length < 2)
    return Infinity;
  let spacing = 0;
  let y0 = ticks[0].translation;
  for (let i = 1; i < ticks.length; i++) {
    const y1 = ticks[i].translation;
    const delta5 = Math.abs(y1 - y0);
    spacing = Math.max(spacing, delta5);
    y0 = y1;
  }
  return spacing;
}
function formatTicks(options, {
  niceDomain,
  rawTicks,
  rawFirstTickIndex = 0,
  generatePrimaryTicks,
  primaryTicksIndices,
  alignment,
  fractionDigits,
  timeInterval: timeInterval3
}) {
  const { scale: scale2, label, tickFormatter, inRange: inRange2, isVertical, sizeLimit = Infinity } = options;
  const isContinuous2 = TimeScale.is(scale2) || DiscreteTimeScale.is(scale2);
  const measurer3 = cachedTextMeasurer(label);
  const idGenerator = createIdsGenerator();
  const ticks = [];
  withTemporaryDomain(scale2, niceDomain, () => {
    const maxBandwidth = BandScale.is(scale2) ? scale2.bandwidth ?? Infinity : Infinity;
    const halfBandwidth = (scale2.bandwidth ?? 0) / 2;
    const axisFormatter = axisTickFormatter(
      label.enabled,
      generatePrimaryTicks,
      niceDomain,
      rawTicks,
      fractionDigits,
      timeInterval3,
      tickFormatter
    );
    let maxWidth = isVertical ? sizeLimit : maxBandwidth;
    let maxHeight = isVertical ? maxBandwidth : sizeLimit;
    if (label.rotation) {
      const innerRect = getMaxInnerRectSize(label.rotation, maxWidth, maxHeight);
      maxWidth = innerRect.width;
      maxHeight = innerRect.height;
    }
    const wrapOptions = {
      font: label,
      maxWidth,
      maxHeight,
      overflow: label.truncate ? "ellipsis" : "hide",
      textWrap: label.wrapping
    };
    for (let i = 0; i < rawTicks.length; i++) {
      const tick = rawTicks[i];
      const translation = scale2.convert(tick, { alignment }) + halfBandwidth;
      if (inRange2 && !inRange2(translation))
        continue;
      const isPrimary = primaryTicksIndices?.has(i) ?? false;
      const inputText = axisFormatter(isPrimary, tick, i);
      let wrappedLabel = null;
      if (label.avoidCollisions) {
        wrappedLabel = wrapTextOrSegments(inputText, wrapOptions) || null;
      }
      const tickLabel = wrappedLabel ?? inputText;
      const isSegmented = isArray(tickLabel);
      const isTruncated2 = tickLabel !== inputText && (isSegmented ? isSegmentTruncated(tickLabel.at(-1)) : isTextTruncated(toTextString(tickLabel)));
      let tickId;
      if (isContinuous2) {
        const tickValue = tick?.valueOf();
        if (Number.isFinite(tickValue)) {
          tickId = idGenerator(`v:${tickValue}`);
        }
      }
      tickId ?? (tickId = idGenerator(`l:${isSegmented ? toPlainText(tickLabel.flat()) : tickLabel}`));
      ticks.push({
        tick,
        tickId,
        tickLabel,
        isPrimary,
        index: i + rawFirstTickIndex,
        textUntruncated: isTruncated2 ? toPlainText(inputText) : void 0,
        textMetrics: isSegmented ? measureTextSegments(tickLabel, label) : measurer3.measureLines(toTextString(tickLabel)),
        translation: Math.floor(translation)
      });
    }
  });
  return ticks;
}
function withTemporaryDomain(scale2, temporaryDomain, callback2) {
  const originalDomain = scale2.domain;
  try {
    scale2.domain = temporaryDomain;
    callback2();
  } finally {
    scale2.domain = originalDomain;
  }
}
function axisTickFormatter(labelEnabled, generatePrimaryTicks, niceDomain, rawTicks, fractionDigits, timeInterval3, tickFormatter) {
  const dateStyle = generatePrimaryTicks ? "component" : "long";
  const parentInterval = generatePrimaryTicks && timeInterval3 ? intervalHierarchy(timeInterval3) : void 0;
  const primaryFormatter = generatePrimaryTicks ? tickFormatter(niceDomain, rawTicks, true, fractionDigits, parentInterval, dateStyle) : null;
  const defaultFormatter = labelEnabled ? tickFormatter(niceDomain, rawTicks, false, fractionDigits, timeInterval3, dateStyle) : null;
  return (isPrimary, tick, index) => {
    const formatter2 = isPrimary ? primaryFormatter : defaultFormatter;
    return formatter2?.(tick, index) ?? String(tick);
  };
}
function getTimeIntervalTicks(scale2, visibleRange, tickCount, maxTickCount, tickParams, timeInterval3, reverse, minimumTimeGranularity) {
  if (!TimeScale.is(scale2) && !DiscreteTimeScale.is(scale2))
    return;
  const parentInterval = intervalHierarchy(timeInterval3);
  if (parentInterval == null)
    return;
  if (reverse) {
    visibleRange = [1 - visibleRange[1], 1 - visibleRange[0]];
  }
  const dv0 = Math.min(scale2.domain[0].valueOf(), scale2.domain.at(-1).valueOf());
  const dv1 = Math.max(scale2.domain[0].valueOf(), scale2.domain.at(-1).valueOf());
  let [dp0, dp1] = intervalExtent(new Date(dv0), new Date(dv1), visibleRange);
  dp0 = intervalFloor(parentInterval, dp0);
  if (dp0.valueOf() >= dv0) {
    dp0 = intervalPrevious(parentInterval, dp0);
  }
  dp1 = intervalCeil(parentInterval, dp1);
  if (dp1.valueOf() <= dv1) {
    dp1 = intervalNext(parentInterval, dp1);
  }
  const primaryTicks = intervalRange(parentInterval, dp0, dp1);
  const milliseconds = intervalMilliseconds(timeInterval3);
  const skipFirstPrimaryTick = OrdinalTimeScale.is(scale2);
  const intervalTickParams = { ...tickParams, interval: timeInterval3 };
  const ticks = [];
  let primaryTicksIndices;
  let parentLevelMode;
  let alignment;
  let ordinalTickStep = 0;
  if (OrdinalTimeScale.is(scale2)) {
    const timeIntervalGranularity = intervalUnit(timeInterval3);
    parentLevelMode = minimumTimeGranularity != null && intervalMilliseconds(minimumTimeGranularity) >= intervalMilliseconds(timeIntervalGranularity) ? 2 /* OrdinalTimeStepTicks */ : 3 /* OrdinalTimeScaleTicks */;
    alignment = 1 /* Trailing */;
    const tickDensity = tickCount / maxTickCount;
    const baseTickStep = scale2.bandCount(visibleRange) / (tickDensity * DENSE_TICK_COUNT);
    ordinalTickStep = TICK_STEP_VALUES.findLast((t) => baseTickStep >= t) ?? 1;
  } else if (UnitTimeScale.is(scale2) && (scale2.interval == null || intervalMilliseconds(scale2.interval) >= milliseconds)) {
    parentLevelMode = 1 /* UnitTimeScaleTicks */;
  } else {
    parentLevelMode = 0 /* ContinuousTimeScaleTicks */;
    alignment = 2 /* Interpolate */;
  }
  for (let i = 0; i < primaryTicks.length - 1; i++) {
    const p0 = primaryTicks[i];
    const p1 = primaryTicks[i + 1];
    const first2 = i === 0;
    const last = i === primaryTicks.length - 2;
    const dp = p1.valueOf() - p0.valueOf();
    const pVisibleRange = [
      Math.max((dv0 - p0.valueOf()) / dp, 0),
      Math.min((dv1 - p0.valueOf()) / dp, 1)
    ];
    let intervalTicks;
    switch (parentLevelMode) {
      case 0 /* ContinuousTimeScaleTicks */:
        intervalTicks = createTimeScaleTicks(intervalTickParams.interval, [p0, p1], pVisibleRange, true);
        break;
      case 1 /* UnitTimeScaleTicks */:
      case 3 /* OrdinalTimeScaleTicks */: {
        const scaleTicks = scale2.ticks(intervalTickParams, [p0, p1], pVisibleRange, {
          extend: true,
          dropInitial: true
        });
        intervalTicks = scaleTicks?.ticks ?? [];
        break;
      }
      case 2 /* OrdinalTimeStepTicks */:
        intervalTicks = scale2.stepTicks(
          ordinalTickStep,
          [p0, p1],
          void 0,
          !last
        );
        break;
    }
    dropFirstWhile(intervalTicks, (firstTick2) => firstTick2.valueOf() < p0.valueOf());
    if (!last) {
      dropLastWhile(intervalTicks, (lastTick) => {
        switch (parentLevelMode) {
          case 0 /* ContinuousTimeScaleTicks */:
          case 3 /* OrdinalTimeScaleTicks */:
            return lastTick.valueOf() + milliseconds > p1.valueOf();
          case 1 /* UnitTimeScaleTicks */:
          case 2 /* OrdinalTimeStepTicks */:
            return lastTick.valueOf() >= p1.valueOf();
        }
      });
    }
    if (intervalTicks.length === 0)
      continue;
    const firstTick = intervalTicks[0];
    const firstTickDiff = compareDates(firstTick, p0);
    const firstPrimary = parentLevelMode === 0 /* ContinuousTimeScaleTicks */ ? firstTickDiff === 0 : firstTickDiff <= milliseconds;
    if (firstPrimary && (!skipFirstPrimaryTick || !first2)) {
      primaryTicksIndices ?? (primaryTicksIndices = /* @__PURE__ */ new Set());
      primaryTicksIndices.add(ticks.length);
    }
    ticks.push(...intervalTicks);
  }
  if (primaryTicksIndices?.size === 1 && primaryTicksIndices.has(0)) {
    primaryTicksIndices = void 0;
  }
  return { ticks, primaryTicksIndices, alignment };
}
function timeIntervalMaxLabelSize(label, primaryLabel, domain, timeInterval3, textMeasurer) {
  const specifier = labelSpecifier(label.format, timeInterval3);
  if (specifier == null) {
    return { width: 0, height: 0 };
  }
  const labelFormatter = buildDateFormatter(specifier);
  const hierarchy = timeInterval3 ? intervalHierarchy(timeInterval3) : void 0;
  const primarySpecifier = labelSpecifier(primaryLabel?.format, hierarchy);
  const primaryLabelFormatter = primarySpecifier ? buildDateFormatter(primarySpecifier) : labelFormatter;
  const d0 = new Date(domain[0]);
  const d1 = new Date(domain.at(-1));
  const hierarchyRange = hierarchy ? intervalRange(hierarchy, new Date(domain[0]), new Date(domain.at(-1)), { extend: true }) : void 0;
  let maxWidth = 0;
  let maxHeight = 0;
  if (labelFormatter != null) {
    const padding2 = expandLabelPadding(label);
    const xPadding = padding2.left + padding2.right;
    const yPadding = padding2.top + padding2.bottom;
    let l0;
    let l1;
    if (hierarchyRange != null && hierarchyRange.length > 1) {
      l0 = hierarchyRange[0];
      l1 = hierarchyRange[1];
    } else {
      l0 = d0;
      l1 = d1;
    }
    const labelRange = intervalRange(timeInterval3, l0, l1, { limit: 50 });
    for (const date2 of labelRange) {
      const text2 = labelFormatter(date2);
      const { width: width2, height: height2 } = textMeasurer.measureLines(text2);
      maxWidth = Math.max(maxWidth, width2 + xPadding);
      maxHeight = Math.max(maxHeight, height2 + yPadding);
    }
  }
  if (primaryLabelFormatter != null && hierarchyRange != null) {
    const padding2 = expandLabelPadding(primaryLabel);
    const xPadding = padding2.left + padding2.right;
    const yPadding = padding2.top + padding2.bottom;
    for (const date2 of hierarchyRange) {
      const text2 = primaryLabelFormatter(date2);
      const { width: width2, height: height2 } = textMeasurer.measureLines(text2);
      maxWidth = Math.max(maxWidth, width2 + xPadding);
      maxHeight = Math.max(maxHeight, height2 + yPadding);
    }
  }
  return {
    width: Math.ceil(maxWidth),
    height: Math.ceil(maxHeight)
  };
}
function getTextBaseline(parallel, labelRotation, sideFlag, parallelFlipFlag) {
  if (parallel && !labelRotation) {
    return sideFlag * parallelFlipFlag === -1 ? "top" : "bottom";
  }
  return "middle";
}
function getTextAlign(parallel, labelRotation, labelAutoRotation, sideFlag, regularFlipFlag) {
  const labelRotated = labelRotation > 0 && labelRotation <= Math.PI;
  const labelAutoRotated = labelAutoRotation > 0 && labelAutoRotation <= Math.PI;
  const alignFlag = labelRotated || labelAutoRotated ? -1 : 1;
  if (parallel) {
    if (labelRotation || labelAutoRotation) {
      if (sideFlag * alignFlag === -1) {
        return "end";
      }
    } else {
      return "center";
    }
  } else if (sideFlag * regularFlipFlag === -1) {
    return "end";
  }
  return "start";
}
function labelSpecifier(format, timeInterval3) {
  if (format == null)
    return;
  if (typeof format === "string") {
    return format;
  } else if (isPlainObject(format) && timeInterval3 != null) {
    return format[intervalUnit(timeInterval3)];
  }
}
function calculateLabelRotation(rotation, parallel, axisRotation = 0) {
  const configuredRotation = normalizeAngle360FromDegrees(rotation);
  const parallelFlipFlag = !configuredRotation && axisRotation >= 0 && axisRotation <= Math.PI ? -1 : 1;
  const regularFlipFlag = !configuredRotation && axisRotation - Math.PI / 2 >= 0 && axisRotation - Math.PI / 2 <= Math.PI ? -1 : 1;
  const defaultRotation = parallel ? parallelFlipFlag * (Math.PI / 2) : 0;
  return { configuredRotation, defaultRotation, parallelFlipFlag, regularFlipFlag };
}

// packages/ag-charts-community/src/chart/axis/generateTicks.ts
var sunday2 = new Date(1970, 0, 4);
function generateTicks(options) {
  const { label, domain, axisRotation, labelOffset, sideFlag } = options;
  const { defaultRotation, configuredRotation, parallelFlipFlag, regularFlipFlag } = calculateLabelRotation(
    label.rotation,
    label.parallel,
    axisRotation
  );
  const initialRotation = configuredRotation + defaultRotation;
  const checkLabelOverlap = (tickData2, rotation2 = 0) => {
    const labelSpacing = label.minSpacing ?? (configuredRotation === 0 && rotation2 === 0 ? 10 : 0);
    const labelRotation = initialRotation + rotation2;
    const labelPadding = expandLabelPadding(label);
    return axisLabelsOverlap(createTimeLabelData(options, tickData2, labelRotation), labelSpacing) || axisLabelsOverlap(createLabelData(tickData2.ticks, labelOffset, labelRotation, labelPadding), labelSpacing);
  };
  const { maxTickCount } = estimateScaleTickCount(options);
  const tickGenerationType = getTickGenerationType(options);
  const avoidCollisions = label.enabled && label.avoidCollisions;
  const maxIterations = Number.isFinite(maxTickCount) ? maxTickCount : 10;
  const tryAutoRotate = avoidCollisions && label.autoRotate && label.rotation == null;
  let index = 0;
  let autoRotation = 0;
  let labelOverlap = true;
  let tickData = {
    tickDomain: [],
    niceDomain: domain,
    ticks: [],
    rawTicks: [],
    rawTickCount: void 0,
    timeInterval: void 0,
    fractionDigits: 0
  };
  while (labelOverlap && index <= maxIterations) {
    ({ tickData, index } = buildTickData(options, tickGenerationType, tickData, index));
    autoRotation = tryAutoRotate && checkLabelOverlap(tickData, 0) ? normalizeAngle360FromDegrees(label.autoRotateAngle) : 0;
    labelOverlap = avoidCollisions && checkLabelOverlap(tickData, autoRotation);
  }
  const textAlign = getTextAlign(label.parallel, configuredRotation, autoRotation, sideFlag, regularFlipFlag);
  const textBaseline = getTextBaseline(label.parallel, configuredRotation, sideFlag, parallelFlipFlag);
  const rotation = configuredRotation + autoRotation;
  return { tickData, textAlign, textBaseline, rotation };
}
function getTickGenerationType(options) {
  if (options.interval?.values) {
    return 2 /* VALUES */;
  } else if (options.primaryTickCount != null) {
    return 1 /* CREATE_SECONDARY */;
  }
  return 0 /* CREATE */;
}
function estimateScaleTickCount({
  scale: scale2,
  domain,
  range: range3,
  visibleRange,
  label,
  defaultTickMinSpacing,
  interval: { minSpacing, maxSpacing }
}) {
  const { defaultTickCount } = scale2;
  const rangeExtent = findRangeExtent(range3);
  const zoomExtent = findRangeExtent(visibleRange);
  if (CategoryScale.is(scale2) || OrdinalTimeScale.is(scale2) && domain.length < 1e3) {
    const maxTickCount = CategoryScale.is(scale2) ? domain.length : Math.min(domain.length, Math.max(1, Math.floor(rangeExtent / (zoomExtent * defaultTickMinSpacing))));
    const estimatedTickCount = Math.ceil(rangeExtent / (zoomExtent * label.fontSize));
    return {
      tickCount: Math.min(estimatedTickCount, maxTickCount),
      minTickCount: 0,
      maxTickCount
    };
  }
  return estimateTickCount(rangeExtent, zoomExtent, minSpacing, maxSpacing, defaultTickCount, defaultTickMinSpacing);
}
function buildTickData(options, tickGenerationType, previousTickData, index) {
  const { step, values } = options.interval;
  const { maxTickCount, minTickCount, tickCount } = estimateScaleTickCount(options);
  const countTicks2 = (i) => Math.max(tickCount - i, minTickCount);
  const regenerateTicks = step == null && values == null && countTicks2(index) > minTickCount;
  const previousTicks = previousTickData.rawTicks;
  const maxIterations = tickCount - minTickCount;
  const countParams = { minTickCount, maxTickCount, tickCount: countTicks2(index) };
  let nextTicks = calculateRawTicks(options, tickGenerationType, countParams);
  if (regenerateTicks && ticksEqual(nextTicks.rawTicks, previousTicks)) {
    let lowerBound = index;
    let upperBound = maxIterations;
    while (lowerBound <= upperBound) {
      index = Math.trunc((lowerBound + upperBound) / 2);
      countParams.tickCount = countTicks2(index);
      const nextTicksCandidate = calculateRawTicks(options, tickGenerationType, countParams);
      if (ticksEqual(nextTicksCandidate.rawTicks, previousTicks)) {
        lowerBound = index + 1;
      } else {
        nextTicks = nextTicksCandidate;
        upperBound = index - 1;
      }
    }
  }
  const {
    tickDomain,
    niceDomain,
    rawTicks,
    rawTickCount,
    rawFirstTickIndex,
    generatePrimaryTicks,
    primaryTicksIndices,
    alignment,
    fractionDigits,
    timeInterval: timeInterval3
  } = nextTicks;
  return {
    tickData: {
      tickDomain,
      niceDomain,
      rawTicks,
      rawTickCount,
      fractionDigits,
      timeInterval: timeInterval3,
      ticks: formatTicks(options, {
        niceDomain,
        rawTicks,
        rawFirstTickIndex,
        generatePrimaryTicks,
        primaryTicksIndices,
        alignment,
        fractionDigits,
        timeInterval: timeInterval3
      })
    },
    index: index + 1
  };
}
function calculateRawTicks(options, tickGenerationType, countParams) {
  const {
    domain,
    reverse,
    visibleRange,
    scale: scale2,
    interval,
    primaryLabel,
    niceMode,
    primaryTickCount,
    minimumTimeGranularity
  } = options;
  const domainParams = {
    nice: niceMode.map((n) => n === 0 /* TickAndDomain */),
    interval: interval.step,
    ...countParams
  };
  const tickParams = {
    ...domainParams,
    nice: niceMode.map((n) => n === 0 /* TickAndDomain */ || n === 1 /* TicksOnly */)
  };
  let secondaryAxisTicks;
  if (tickGenerationType === 1 /* CREATE_SECONDARY */ && primaryTickCount != null && ContinuousScale.is(scale2)) {
    secondaryAxisTicks = calculateNiceSecondaryAxis(scale2, domain, primaryTickCount, reverse, visibleRange);
  }
  const niceDomain = niceMode.includes(0 /* TickAndDomain */) ? secondaryAxisTicks?.domain ?? scale2.niceDomain(domainParams, domain) : domain;
  let tickDomain = niceDomain;
  let rawTicks;
  let rawTickCount;
  let rawFirstTickIndex;
  let timeInterval3;
  let primaryTicksIndices;
  let alignment;
  const generatePrimaryTicks = primaryLabel?.enabled === true && tickParams.interval == null;
  withTemporaryDomain(scale2, niceDomain, () => {
    switch (tickGenerationType) {
      case 2 /* VALUES */:
        tickDomain = interval.values;
        rawTicks = interval.values;
        rawTickCount = rawTicks.length;
        if (OrdinalTimeScale.is(scale2)) {
          alignment = 1 /* Trailing */;
        } else if (UnitTimeScale.is(scale2)) {
          alignment = 2 /* Interpolate */;
        }
        if (ContinuousScale.is(scale2)) {
          const [d0, d1] = findMinMax(niceDomain.map(Number));
          rawTicks = rawTicks.filter((value) => Number(value) >= d0 && Number(value) <= d1).sort((a, b) => Number(a) - Number(b));
        }
        break;
      case 1 /* CREATE_SECONDARY */:
        if (secondaryAxisTicks) {
          rawTicks = secondaryAxisTicks.ticks;
          rawTickCount = secondaryAxisTicks.ticks.length;
        } else {
          const tickGeneration = scale2.ticks(tickParams, niceDomain, visibleRange);
          rawTicks = tickGeneration?.ticks;
          rawTickCount = tickGeneration?.count;
        }
        break;
      default: {
        const { tickCount, minTickCount, maxTickCount } = countParams;
        if (niceDomain.length > 0 && tickParams.interval == null && (UnitTimeScale.is(scale2) || generatePrimaryTicks && (TimeScale.is(scale2) || OrdinalTimeScale.is(scale2)))) {
          const dates = niceDomain;
          const start2 = Math.min(dates[0].valueOf(), dates.at(-1).valueOf());
          const end3 = Math.max(dates[0].valueOf(), dates.at(-1).valueOf());
          timeInterval3 = getTickTimeInterval(start2, end3, tickCount, minTickCount, maxTickCount, {
            weekStart: primaryLabel == null ? sunday2 : void 0,
            primaryOnly: true
          });
        }
        let minTimeInterval;
        if (OrdinalTimeScale.is(scale2)) {
          minTimeInterval = minimumTimeGranularity;
        } else if (UnitTimeScale.is(scale2)) {
          minTimeInterval = scale2.interval;
        }
        if (minTimeInterval != null && timeInterval3 != null && // Prefer UnitTimeAxis.unit over this interval, because the user may have defined an epoch
        intervalMilliseconds(minTimeInterval) >= intervalMilliseconds(timeInterval3)) {
          timeInterval3 = minTimeInterval;
        }
        const intervalTicks = timeInterval3 ? getTimeIntervalTicks(
          scale2,
          visibleRange,
          tickCount,
          maxTickCount,
          tickParams,
          timeInterval3,
          reverse,
          minimumTimeGranularity
        ) : void 0;
        if (intervalTicks) {
          ({ ticks: rawTicks, primaryTicksIndices, alignment } = intervalTicks);
        } else {
          const intervalTickParams = UnitTimeScale.is(scale2) && tickParams.interval == null && timeInterval3 != null ? { ...tickParams, interval: timeInterval3 } : tickParams;
          const tickGeneration = scale2.ticks(intervalTickParams, niceDomain, visibleRange);
          rawTicks = tickGeneration?.ticks;
          rawTickCount = tickGeneration?.count;
          rawFirstTickIndex = tickGeneration?.firstTickIndex;
          if (TimeScale.is(scale2) || DiscreteTimeScale.is(scale2)) {
            const paramsInterval = typeof tickParams.interval === "number" ? lowestGranularityForInterval(tickParams.interval) : tickParams.interval;
            timeInterval3 ?? (timeInterval3 = paramsInterval ?? tickGeneration?.timeInterval);
          }
        }
      }
    }
  });
  rawTicks ?? (rawTicks = []);
  let fractionDigits = 0;
  for (const tick of rawTicks) {
    if (typeof tick !== "number")
      continue;
    const value = countFractionDigits(tick);
    if (value > fractionDigits) {
      fractionDigits = value;
    }
  }
  if (!generatePrimaryTicks) {
    primaryTicksIndices = void 0;
  }
  return {
    tickDomain,
    niceDomain,
    rawTicks,
    rawTickCount,
    rawFirstTickIndex,
    generatePrimaryTicks,
    primaryTicksIndices,
    alignment,
    fractionDigits,
    timeInterval: timeInterval3
  };
}
function createTimeLabelData(options, tickData, labelRotation) {
  const { niceDomain, ticks, timeInterval: timeInterval3 } = tickData;
  if (timeInterval3 == null)
    return [];
  const spacing = ticksSpacing(ticks);
  const { label, labelOffset, primaryLabel, domain } = options;
  const { width: width2, height: height2 } = timeIntervalMaxLabelSize(
    label,
    primaryLabel,
    niceDomain ?? domain,
    timeInterval3,
    cachedTextMeasurer(label)
  );
  const labelData = [];
  for (const translation of [0, spacing]) {
    const { x, y } = rotatePoint(labelOffset, translation, labelRotation);
    labelData.push({ x, y, width: width2, height: height2 });
  }
  return labelData;
}
function createLabelData(tickData, labelOffset, labelRotation, labelPadding) {
  const labelData = [];
  const xPadding = labelPadding.left + labelPadding.right;
  const yPadding = labelPadding.top + labelPadding.bottom;
  for (const { tickLabel, textMetrics, translation } of tickData) {
    if (!tickLabel)
      continue;
    const { x, y } = rotatePoint(labelOffset, translation, labelRotation);
    const width2 = textMetrics.width + xPadding;
    const height2 = textMetrics.height + yPadding;
    labelData.push({ x, y, width: width2, height: height2 });
  }
  return labelData;
}

// packages/ag-charts-community/src/chart/axis/cartesianAxis.ts
var _CartesianAxis = class _CartesianAxis extends Axis {
  constructor(moduleCtx, scale2) {
    super(moduleCtx, scale2);
    this.maxThicknessRatio = 0.3;
    this.crossAxisTranslation = { x: 0, y: 0 };
    this.minimumTimeGranularity = void 0;
    this.headingLabelGroup = this.axisGroup.appendChild(
      new TranslatableGroup({ name: `${this.id}-Axis-heading` })
    );
    this.lineNodeGroup = this.axisGroup.appendChild(
      new TranslatableGroup({ name: `${this.id}-Axis-line` })
    );
    this.lineNode = this.lineNodeGroup.appendChild(new Line({ zIndex: 1 /* AxisLine */ }));
    this.tickLineGroupSelection = Selection.select(this.tickLineGroup, Line, false);
    this.gridLineGroupSelection = Selection.select(this.gridLineGroup, Line, false);
    this.gridFillGroupSelection = Selection.select(this.gridFillGroup, Rect, false);
    this.tempText = new TransformableText({ debugDirty: false });
    this.tempCaption = new Caption();
    this.animationManager = moduleCtx.animationManager;
    this.animationState = new StateMachine("empty", {
      empty: {
        update: {
          target: "ready",
          action: () => this.resetSelectionNodes()
        },
        reset: "empty"
      },
      ready: {
        update: (data) => this.animateReadyUpdate(data),
        resize: () => this.resetSelectionNodes(),
        reset: "empty"
      }
    });
    this.headingLabelGroup.appendChild(this.title.caption.node);
    let previousSize = void 0;
    this.cleanup.register(
      moduleCtx.eventsHub.on("layout:complete", (e) => {
        const size = [e.chart.width, e.chart.height];
        if (previousSize != null && !arraysEqual(size, previousSize)) {
          this.animationState.transition("resize");
        }
        previousSize = size;
      }),
      this.title.caption.registerInteraction(this.moduleCtx, "afterend")
    );
  }
  static is(value) {
    return value instanceof _CartesianAxis;
  }
  get horizontal() {
    return this.position === "top" || this.position === "bottom";
  }
  onGridVisibilityChange() {
  }
  resetAnimation(phase) {
    if (phase === "initial") {
      this.animationState.transition("reset");
    }
  }
  get direction() {
    return this.position === "top" || this.position === "bottom" ? "x" /* X */ : "y" /* Y */;
  }
  createAxisContext() {
    return { ...super.createAxisContext(), position: this.position };
  }
  createLabel() {
    return new CartesianAxisLabel();
  }
  updateDirection() {
    switch (this.position) {
      case "top":
        this.label.mirrored = true;
        this.label.parallel = true;
        break;
      case "right":
        this.label.mirrored = true;
        this.label.parallel = false;
        break;
      case "bottom":
        this.label.mirrored = false;
        this.label.parallel = true;
        break;
      case "left":
        this.label.mirrored = false;
        this.label.parallel = false;
        break;
    }
    if (this.axisContext) {
      this.axisContext.position = this.position;
      this.axisContext.direction = this.direction;
    }
  }
  calculateLayout(primaryTickCount, chartLayout) {
    this.updateDirection();
    return super.calculateLayout(primaryTickCount, chartLayout);
  }
  layoutCrossLines() {
    const crosslinesVisible = this.hasDefinedDomain() || this.hasVisibleSeries();
    for (const crossLine of this.crossLines) {
      crossLine.calculateLayout?.(crosslinesVisible);
    }
  }
  calculateTickLayout(domain, niceMode, visibleRange, initialPrimaryTickCount) {
    const sideFlag = this.label.getSideFlag();
    const labelX = sideFlag * (this.getTickSize() + this.getTickSpacing() + this.label.spacing + this.seriesAreaPadding);
    const scrollbar = this.chartLayout?.scrollbars?.[this.id];
    const scrollbarThickness = this.getScrollbarThickness(scrollbar);
    if (niceMode[0] === 2 /* Off */ && niceMode[1] === 2 /* Off */ && this.label.enabled === false && this.tick.enabled === false && this.gridLine.enabled === false) {
      const { bbox: bbox2, spacing: spacing2 } = this.measureAxisLayout(domain, [], [], scrollbar, scrollbarThickness);
      const layout2 = {
        ticks: [],
        tickLines: [],
        gridLines: [],
        gridFills: [],
        labels: [],
        spacing: spacing2
      };
      return {
        ticks: [],
        rawTickCount: 0,
        tickDomain: domain,
        niceDomain: domain,
        fractionDigits: 0,
        timeInterval: void 0,
        bbox: bbox2,
        layout: layout2
      };
    }
    const { label, primaryLabel, scale: scale2, range: range3, interval, reverse, defaultTickMinSpacing, minimumTimeGranularity } = this;
    const tickGenerationResult = generateTicks({
      label,
      scale: scale2,
      interval,
      primaryLabel,
      domain,
      range: range3,
      reverse,
      niceMode,
      visibleRange,
      defaultTickMinSpacing,
      minimumTimeGranularity,
      sideFlag,
      labelOffset: labelX,
      primaryTickCount: initialPrimaryTickCount,
      axisRotation: this.horizontal ? Math.PI / -2 : 0,
      isVertical: this.direction === "y" /* Y */,
      sizeLimit: this.chartLayout?.sizeLimit,
      inRange: (translation) => this.inRange(translation, 1e-3),
      tickFormatter: (...args) => this.tickFormatter(...args)
    });
    const { tickData } = tickGenerationResult;
    const removeOverflowLabels = this.label.avoidCollisions && this.horizontal && tickData.ticks.length > 2 && (ContinuousScale.is(this.scale) || DiscreteTimeScale.is(this.scale));
    if (removeOverflowLabels) {
      const removeOverflowThreshold = this.chartLayout?.padding.right ?? 0;
      const lastTick = tickData.ticks.at(-1);
      if (lastTick?.tickLabel != null && lastTick.translation + lastTick.textMetrics.width / 2 > range3[1] + removeOverflowThreshold) {
        lastTick.tickLabel = void 0;
        if (visibleRange[0] === 0 && visibleRange[1] === 1) {
          tickData.ticks[0].tickLabel = void 0;
        }
      }
    }
    const { ticks, tickDomain, rawTicks, rawTickCount, fractionDigits, timeInterval: timeInterval3, niceDomain } = tickData;
    const labels = ticks.map((d) => this.getTickLabelProps(d, tickGenerationResult, scrollbarThickness));
    const { position, gridPadding, gridLength } = this;
    const direction = position === "bottom" || position === "right" ? -1 : 1;
    const p1 = direction * gridPadding;
    const p2 = direction * (gridLength + gridPadding);
    const gridLines = this.calculateGridLines(ticks, p1, p2);
    const gridFills = this.calculateGridFills(ticks, p1, p2);
    const tickLines = this.calculateTickLines(ticks, direction, scrollbarThickness);
    const { bbox, spacing } = this.measureAxisLayout(tickDomain, ticks, labels, scrollbar, scrollbarThickness);
    const layout = { ticks, gridLines, gridFills, tickLines, labels, spacing };
    return { ticks: rawTicks, rawTickCount, tickDomain, niceDomain, fractionDigits, timeInterval: timeInterval3, bbox, layout };
  }
  calculateGridLines(ticks, p1, p2) {
    return ticks.map((tick, index) => this.calculateGridLine(tick, index, p1, p2, ticks));
  }
  calculateGridLine({ index: tickIndex, tickId, translation: offset }, _index, p1, p2, _ticks) {
    const { gridLine, horizontal } = this;
    const [x1, y1, x2, y2] = horizontal ? [offset, p1, offset, p2] : [p1, offset, p2, offset];
    const { style: style2 } = gridLine;
    const { stroke: stroke3, strokeWidth = 0, lineDash } = style2[tickIndex % style2.length] ?? {};
    return { tickId, offset, x1, y1, x2, y2, stroke: stroke3, strokeWidth, lineDash };
  }
  calculateGridFills(ticks, p1, p2) {
    const { horizontal, range: range3, type } = this;
    const gridFills = [];
    if (ticks.length == 0)
      return gridFills;
    let gridFillIndexOffset = 0;
    const isVerticalUnitTime = !horizontal && type === "unit-time";
    const firstFillOffCanvas = isVerticalUnitTime && ticks[0].translation < range3[0] || !isVerticalUnitTime && ticks[0].translation > range3[0];
    if (firstFillOffCanvas) {
      const injectedTick = { tickId: `before:${ticks[0].tickId}`, translation: range3[0] };
      gridFills.push(this.calculateGridFill(injectedTick, -1, ticks[0].index, p1, p2, ticks));
      gridFillIndexOffset = 1;
    }
    gridFills.push(
      ...ticks.map(
        (tick, index) => this.calculateGridFill(tick, index, tick.index + gridFillIndexOffset, p1, p2, ticks)
      )
    );
    return gridFills;
  }
  calculateGridFill({ tickId, translation }, index, gridFillIndex, p1, p2, ticks) {
    const { gridLine, horizontal, range: range3 } = this;
    const nextTick = ticks[index + 1];
    const startOffset = translation;
    const endOffset = nextTick ? nextTick.translation : range3[1];
    const [x1, y1, x2, y2] = horizontal ? [startOffset, Math.max(p1, p2), endOffset, Math.min(p1, p2)] : [Math.min(p1, p2), Math.min(startOffset, endOffset), Math.max(p1, p2), Math.max(startOffset, endOffset)];
    const { fill, fillOpacity } = gridLine.style[gridFillIndex % gridLine.style.length] ?? {};
    return { tickId, x1, y1, x2, y2, fill, fillOpacity };
  }
  calculateTickLines(ticks, direction, scrollbarThickness = 0) {
    return ticks.map((tick) => this.calculateTickLine(tick, tick.index, direction, ticks, scrollbarThickness));
  }
  calculateTickLine({ isPrimary, tickId, translation: offset }, _index, direction, _ticks, scrollbarThickness = 0) {
    const { horizontal, tick, primaryTick } = this;
    const datumTick = isPrimary && primaryTick ? primaryTick : tick;
    const tickSize = this.getTickSize(datumTick);
    const tickSpacing = this.getTickSpacing(datumTick);
    const tickOffset = -direction * (scrollbarThickness + tickSpacing);
    const h = -direction * tickSize;
    const [x1, y1, x2, y2] = horizontal ? [offset, tickOffset, offset, tickOffset + h] : [tickOffset, offset, tickOffset + h, offset];
    const { stroke: stroke3, width: strokeWidth } = datumTick;
    const lineDash = void 0;
    return { tickId, offset, x1, y1, x2, y2, stroke: stroke3, strokeWidth, lineDash };
  }
  update() {
    this.updateDirection();
    const previousTicksIds = Array.from(this.tickLabelGroupSelection.nodes(), (node) => node.datum.tickId);
    super.update();
    const { tickLayout } = this;
    this.updateTitle(this.scale.domain, tickLayout?.spacing ?? 0);
    if (!this.animatable) {
      this.moduleCtx.animationManager.skipCurrentBatch();
    }
    if (tickLayout) {
      const { ticks } = tickLayout;
      if (this.animationManager.isSkipped()) {
        this.resetSelectionNodes();
      } else {
        const tickIds = ticks.map((datum) => datum.tickId);
        const diff9 = diffArrays(previousTicksIds, tickIds);
        this.animationState.transition("update", diff9);
      }
    }
    const { enabled, stroke: stroke3, width: width2 } = this.line;
    this.lineNode.setProperties({ stroke: stroke3, strokeWidth: enabled ? width2 : 0 });
    this.updateTickLines();
    this.updateGridLines();
    this.updateGridFills();
  }
  getAxisTransform() {
    return {
      translationX: Math.floor(this.translation.x + this.crossAxisTranslation.x),
      translationY: Math.floor(this.translation.y + this.crossAxisTranslation.y)
    };
  }
  getLayoutTranslation() {
    const { translationX, translationY } = this.getAxisTransform();
    return { x: translationX, y: translationY };
  }
  getLayoutState() {
    const layout = super.getLayoutState();
    return { ...layout, position: this.position };
  }
  updatePosition() {
    super.updatePosition();
    const axisTransform = this.getAxisTransform();
    this.tickLineGroup.datum = axisTransform;
    this.tickLabelGroup.datum = axisTransform;
    this.lineNodeGroup.datum = axisTransform;
    this.headingLabelGroup.datum = axisTransform;
  }
  setAxisVisible(visible) {
    this.tickLineGroup.visible = visible && (this.tick.enabled || (this.primaryTick?.enabled ?? false));
    this.tickLabelGroup.visible = visible && (this.label.enabled || (this.primaryTick?.enabled ?? false));
    this.lineNodeGroup.visible = visible;
    this.headingLabelGroup.visible = visible;
  }
  getAxisLineCoordinates() {
    const { horizontal } = this;
    const [c1, c2] = findMinMax(this.lineRange ?? this.range);
    return horizontal ? { x1: c1, x2: c2, y1: 0, y2: 0 } : { x1: 0, x2: 0, y1: c1, y2: c2 };
  }
  getTickLineBBox(datum, scrollbarThickness) {
    const { translation } = datum;
    const { position, primaryTick } = this;
    let tickSize = this.getTickSize();
    if (primaryTick?.enabled) {
      tickSize = Math.max(tickSize, this.getTickSize(primaryTick));
    }
    const direction = position === "bottom" || position === "right" ? -1 : 1;
    const tickSpacing = this.getTickSpacing(this.tick);
    const tickOffset = -direction * (scrollbarThickness + tickSpacing);
    const start2 = tickOffset;
    const end3 = tickOffset - direction * (tickSize + tickSpacing);
    const min = Math.min(start2, end3);
    const max = Math.max(start2, end3);
    switch (position) {
      case "top":
        return new BBox(translation, min, 0, max - min);
      case "bottom":
        return new BBox(translation, min, 0, max - min);
      case "left":
        return new BBox(min, translation, max - min, 0);
      case "right":
        return new BBox(min, translation, max - min, 0);
    }
  }
  lineNodeBBox() {
    const { position, seriesAreaPadding } = this;
    const { y1, y2 } = this.getAxisLineCoordinates();
    const dy2 = y2 - y1;
    switch (position) {
      case "top":
        return new BBox(y1, -seriesAreaPadding, dy2, seriesAreaPadding);
      case "bottom":
        return new BBox(y1, 0, dy2, seriesAreaPadding);
      case "left":
        return new BBox(-seriesAreaPadding, y1, seriesAreaPadding, dy2);
      case "right":
        return new BBox(0, y1, seriesAreaPadding, dy2);
    }
  }
  titleBBox(domain, spacing) {
    const { tempCaption } = this;
    tempCaption.node.setProperties(this.titleProps(tempCaption, domain, spacing));
    return tempCaption.node.getBBox();
  }
  getScrollbarThickness(scrollbar) {
    if (!scrollbar?.enabled)
      return 0;
    return scrollbar.placement === "inner" ? scrollbar.spacing + scrollbar.thickness : 0;
  }
  resolveScrollbarLayout(scrollbar, labelThickness) {
    if (!scrollbar)
      return void 0;
    const { position } = this;
    const direction = position === "top" || position === "left" ? -1 : 1;
    if (scrollbar.placement === "inner") {
      const offset2 = direction === 1 ? scrollbar.spacing : -scrollbar.spacing - scrollbar.thickness;
      return { ...scrollbar, offset: offset2 };
    }
    const offset = direction === 1 ? labelThickness + scrollbar.spacing : -labelThickness - scrollbar.spacing - scrollbar.thickness;
    return { ...scrollbar, offset };
  }
  applyScrollbarLayout(boxes, labelThickness, scrollbar) {
    const scrollbarLayout = this.resolveScrollbarLayout(scrollbar, labelThickness);
    let spacing = labelThickness;
    if (scrollbarLayout) {
      const { offset, thickness, placement } = scrollbarLayout;
      if (placement === "outer") {
        spacing += scrollbarLayout.spacing + thickness;
      }
      if (this.horizontal) {
        boxes.push(new BBox(0, offset, 0, thickness));
      } else {
        boxes.push(new BBox(offset, 0, thickness, 0));
      }
    }
    return { spacing, scrollbarLayout };
  }
  measureAxisLayout(domain, ticks, labels, scrollbar, scrollbarThickness) {
    const { tick, primaryTick, label, primaryLabel, title, position, horizontal, seriesAreaPadding } = this;
    const boxes = [];
    boxes.push(this.lineNodeBBox());
    if (tick.enabled || primaryTick?.enabled) {
      for (const datum of ticks) {
        boxes.push(this.getTickLineBBox(datum, scrollbarThickness));
      }
    }
    const { tempText } = this;
    if (label.enabled) {
      for (const datum of labels) {
        if (!datum.visible)
          continue;
        tempText.setProperties(datum);
        const box = tempText.getBBox();
        if (box) {
          boxes.push(box);
        }
      }
    }
    if (primaryLabel?.enabled && position === "bottom") {
      const inexactMeasurementPadding = 2;
      boxes.push(
        new BBox(
          0,
          calcLineHeight(label.fontSize) + inexactMeasurementPadding,
          1,
          this.getTickSize(tick) + this.getTickSpacing(tick) + label.spacing + seriesAreaPadding
        )
      );
      if (primaryLabel.format != null) {
        const { format } = primaryLabel;
        const formats = isPlainObject(format) ? Object.values(format) : [format];
        const maxLines = formats.reduce((m, f) => Math.max(m, countLines(f)), 0);
        boxes.push(
          new BBox(
            0,
            this.getTickSize(primaryTick ?? tick) + this.getTickSpacing(primaryTick ?? tick) + primaryLabel.spacing + seriesAreaPadding,
            1,
            maxLines * calcLineHeight(primaryLabel.fontSize) + inexactMeasurementPadding
          )
        );
      }
    }
    const combined = BBox.merge(boxes);
    const labelThickness = horizontal ? combined.height : combined.width;
    const { spacing, scrollbarLayout } = this.applyScrollbarLayout(boxes, labelThickness, scrollbar);
    this.layout.labelThickness = labelThickness;
    this.layout.scrollbar = scrollbarLayout;
    if (title.enabled) {
      boxes.push(this.titleBBox(domain, spacing));
    }
    const bbox = BBox.merge(boxes);
    return { bbox, spacing };
  }
  titleProps(caption, domain, spacing) {
    const { title } = this;
    if (!title.enabled) {
      caption.enabled = false;
      return {
        visible: false,
        text: "",
        textBaseline: "bottom",
        x: 0,
        y: 0,
        rotationCenterX: 0,
        rotationCenterY: 0,
        rotation: 0
      };
    }
    caption.enabled = true;
    caption.color = title.color;
    caption.fontFamily = title.fontFamily;
    caption.fontSize = title.fontSize;
    caption.fontStyle = title.fontStyle;
    caption.fontWeight = title.fontWeight;
    caption.wrapping = title.wrapping;
    const padding2 = (title.spacing ?? 0) + spacing;
    const { range: range3 } = this;
    const midOffset = (range3[0] + range3[1]) / 2;
    let x;
    let y;
    let rotation;
    let textBaseline;
    switch (this.position) {
      case "top":
        x = midOffset;
        y = -padding2;
        rotation = 0;
        textBaseline = "bottom";
        break;
      case "bottom":
        x = midOffset;
        y = padding2;
        rotation = 0;
        textBaseline = "top";
        break;
      case "left":
        x = -padding2;
        y = midOffset;
        rotation = Math.PI / -2;
        textBaseline = "bottom";
        break;
      case "right":
        x = padding2;
        y = midOffset;
        rotation = Math.PI / 2;
        textBaseline = "bottom";
        break;
    }
    const { formatter: formatter2 = (p) => p.defaultValue } = title;
    const text2 = this.cachedCallWithContext(formatter2, this.getTitleFormatterParams(domain));
    caption.text = text2;
    return {
      visible: true,
      text: text2,
      textBaseline,
      x,
      y,
      rotationCenterX: x,
      rotationCenterY: y,
      rotation
    };
  }
  getTickLabelProps(datum, tickGenerationResult, scrollbarThickness) {
    const { horizontal, primaryLabel, primaryTick, seriesAreaPadding, scale: scale2 } = this;
    const { tickId, tickLabel: text2 = "", translation, isPrimary, textUntruncated } = datum;
    const label = isPrimary && primaryLabel?.enabled ? primaryLabel : this.label;
    const tick = isPrimary && primaryTick?.enabled ? primaryTick : this.tick;
    const { rotation, textBaseline, textAlign } = tickGenerationResult;
    const { range: range3 } = scale2;
    const sideFlag = this.label.getSideFlag();
    const borderOffset = expandLabelPadding(label)[this.position];
    let labelOffset = sideFlag * (this.getTickSize(tick) + this.getTickSpacing(tick) + label.spacing + seriesAreaPadding) - borderOffset;
    if (scrollbarThickness) {
      labelOffset += sideFlag * scrollbarThickness;
    }
    const visible = text2 !== "";
    const x = horizontal ? translation : labelOffset;
    const y = horizontal ? -labelOffset : translation;
    return {
      ...this.getLabelStyles({ value: datum.tick, formattedValue: text2 }, void 0, label),
      tickId,
      rotation,
      text: text2,
      textAlign,
      textBaseline,
      textUntruncated,
      visible,
      x,
      y,
      rotationCenterX: x,
      rotationCenterY: y,
      range: range3
    };
  }
  updateSelections() {
    if (!this.tickLayout)
      return;
    const lineData = this.getAxisLineCoordinates();
    const { tickLines, gridLines, gridFills, labels } = this.tickLayout;
    const getDatumId = (datum) => datum.tickId;
    this.lineNode.datum = lineData;
    this.gridLineGroupSelection.update(this.gridLine.enabled ? gridLines : [], void 0, getDatumId);
    this.gridFillGroupSelection.update(this.gridLine.enabled ? gridFills : [], void 0, getDatumId);
    this.tickLineGroupSelection.update(tickLines, void 0, getDatumId);
    this.tickLabelGroupSelection.update(labels, void 0, getDatumId);
  }
  updateGridLines() {
    this.gridLineGroupSelection.each((line, datum) => {
      line.stroke = datum.stroke;
      line.strokeWidth = datum.strokeWidth;
      line.lineDash = datum.lineDash;
    });
  }
  updateGridFills() {
    this.gridFillGroupSelection.each((rect2, datum) => {
      rect2.fill = datum.fill;
      rect2.fillOpacity = datum.fillOpacity ?? 1;
    });
  }
  updateTickLines() {
    this.tickLineGroupSelection.each((line, datum) => {
      line.stroke = datum.stroke;
      line.strokeWidth = datum.strokeWidth;
      line.lineDash = datum.lineDash;
    });
  }
  updateTitle(domain, spacing) {
    const { caption } = this.title;
    const titleProps = this.titleProps(caption, domain, spacing);
    caption.node.visible = titleProps.visible;
    caption.node.text = titleProps.text;
    caption.node.textBaseline = titleProps.textBaseline;
    caption.node.datum = titleProps;
  }
  updateLabels() {
    if (!this.label.enabled)
      return;
    this.tickLabelGroupSelection.each((node, datum) => {
      node.fill = datum.color;
      node.text = datum.text;
      node.textBaseline = datum.textBaseline;
      node.textAlign = datum.textAlign ?? "center";
      node.pointerEvents = datum.textUntruncated == null ? 1 /* None */ : 0 /* All */;
      node.setFont(datum);
      node.setBoxing(datum);
    });
  }
  animateReadyUpdate(diff9) {
    const { animationManager } = this.moduleCtx;
    const selectionCtx = prepareAxisAnimationContext(this);
    const fns = prepareAxisAnimationFunctions(selectionCtx);
    fromToMotion(
      this.id,
      "axis-group",
      animationManager,
      [this.lineNodeGroup, this.tickLabelGroup, this.tickLineGroup, this.headingLabelGroup],
      fns.group
    );
    fromToMotion(this.id, "line", animationManager, [this.lineNode], fns.line);
    fromToMotion(
      this.id,
      "line-paths",
      animationManager,
      [this.gridLineGroupSelection, this.tickLineGroupSelection],
      fns.tick,
      (_, d) => d.tickId,
      diff9
    );
    fromToMotion(
      this.id,
      "tick-labels",
      animationManager,
      [this.tickLabelGroupSelection],
      fns.label,
      (_, d) => d.tickId,
      diff9
    );
    fromToMotion(
      this.id,
      "title",
      animationManager,
      [this.title.caption.node],
      fns.label,
      (_, d) => d.tickId,
      diff9
    );
  }
  resetSelectionNodes() {
    resetMotion(
      [this.lineNodeGroup, this.tickLabelGroup, this.tickLineGroup, this.headingLabelGroup],
      resetAxisGroupFn()
    );
    resetMotion([this.gridLineGroupSelection, this.tickLineGroupSelection], resetAxisLineSelectionFn());
    resetMotion([this.gridFillGroupSelection], resetAxisFillSelectionFn());
    resetMotion([this.tickLabelGroupSelection], resetAxisLabelSelectionFn());
    resetMotion([this.title.caption.node], resetAxisLabelSelectionFn());
    resetMotion([this.lineNode], resetAxisLineSelectionFn());
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], _CartesianAxis.prototype, "thickness", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], _CartesianAxis.prototype, "maxThicknessRatio", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], _CartesianAxis.prototype, "position", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], _CartesianAxis.prototype, "crossAt", 2);
var CartesianAxis = _CartesianAxis;

// packages/ag-charts-community/src/chart/mapping/prepareAxis.ts
var CartesianAxisPositions = ["right", "top", "left", "bottom"];
function isAxisPosition(position) {
  return typeof position === "string" && CartesianAxisPositions.includes(position);
}
function guessInvalidPositions(axes) {
  const invalidAxes = [];
  const usedPositions = [];
  const guesses = [...CartesianAxisPositions];
  for (const axis of axes) {
    if (axis instanceof CartesianAxis) {
      if (isAxisPosition(axis.position)) {
        usedPositions.push(axis.position);
      } else {
        invalidAxes.push(axis);
      }
    }
  }
  for (const axis of invalidAxes) {
    let nextGuess;
    do {
      nextGuess = guesses.pop();
    } while (nextGuess && usedPositions.includes(nextGuess));
    if (nextGuess == null)
      break;
    axis.position = nextGuess;
  }
}

// packages/ag-charts-community/src/chart/mapping/prepareSeries.ts
var DEFAULT_MATCHING_KEYS = ["direction", "xKey", "yKey", "sizeKey", "angleKey", "radiusKey", "normalizedTo"];
function matchSeriesOptions(series, optSeries, oldOptsSeries) {
  const matchingKeysCache = /* @__PURE__ */ new Map();
  const getMatchingKeys = (type) => {
    if (type === void 0) {
      return DEFAULT_MATCHING_KEYS;
    }
    if (matchingKeysCache.has(type))
      return matchingKeysCache.get(type);
    const matchingKeys = moduleRegistry_exports.getSeriesModule(type)?.matchingKeys ?? DEFAULT_MATCHING_KEYS;
    matchingKeysCache.set(type, matchingKeys);
    return matchingKeys;
  };
  const generateKey = (type, i, opts) => {
    const matchingKeys = getMatchingKeys(type);
    const result = [type];
    for (const key of matchingKeys) {
      if (key in i && i[key] != null)
        result.push(`${key}=${i[key]}`);
    }
    if (opts?.seriesGrouping) {
      result.push(`seriesGrouping.groupId=${opts?.seriesGrouping.groupId}`);
    }
    return result.join(";");
  };
  const seriesMap = /* @__PURE__ */ new Map();
  let idx = 0;
  for (const s of series) {
    const key = generateKey(s.type, s.properties, oldOptsSeries?.[idx]);
    if (!seriesMap.has(key)) {
      seriesMap.set(key, []);
    }
    seriesMap.get(key)?.push([s, idx++]);
  }
  const optsMap = /* @__PURE__ */ new Map();
  idx = 0;
  for (const o of optSeries) {
    const key = generateKey(o.type, o, o);
    if (!optsMap.has(key)) {
      optsMap.set(key, []);
    }
    optsMap.get(key)?.push([o, idx++]);
  }
  const overlap = [...seriesMap.keys()].some((k) => optsMap.has(k));
  if (!overlap) {
    return { status: "no-overlap", oldKeys: seriesMap.keys(), newKeys: optsMap.keys() };
  }
  const changes = [];
  for (const [key, optsTuples] of optsMap.entries()) {
    for (const [opts, targetIdx] of optsTuples) {
      const seriesArray = seriesMap.get(key);
      if (seriesArray == null || seriesArray.length < 1) {
        changes.push({ opts, targetIdx, idx: targetIdx, status: "add" });
        seriesMap.delete(key);
        continue;
      }
      const [outputSeries, currentIdx] = seriesArray.shift();
      const previousOpts = oldOptsSeries?.[currentIdx] ?? {};
      const diff9 = jsonDiff(previousOpts, opts ?? {});
      const { groupIndex, stackIndex } = diff9?.seriesGrouping ?? {};
      if (groupIndex != null || stackIndex != null) {
        changes.push({
          opts,
          series: outputSeries,
          diff: diff9,
          targetIdx,
          idx: currentIdx,
          status: "series-grouping"
        });
      } else if (diff9) {
        changes.push({
          opts,
          series: outputSeries,
          diff: diff9,
          targetIdx,
          idx: currentIdx,
          status: "update"
        });
      } else {
        changes.push({ opts, series: outputSeries, targetIdx, idx: currentIdx, status: "no-op" });
      }
      if (seriesArray.length === 0) {
        seriesMap.delete(key);
      }
    }
  }
  for (const seriesArray of seriesMap.values()) {
    for (const [outputSeries, currentIdx] of seriesArray) {
      changes.push({ series: outputSeries, idx: currentIdx, targetIdx: -1, status: "remove" });
    }
  }
  return { status: "overlap", changes };
}

// packages/ag-charts-community/src/chart/factory/expectedModules.ts
var ExpectedModules = new Map(
  [
    // Chart types
    {
      type: "chart",
      name: "cartesian",
      moduleId: "CartesianChartModule"
    },
    {
      type: "chart",
      name: "standalone",
      moduleId: "StandaloneChartModule",
      enterprise: true
    },
    {
      type: "chart",
      name: "polar",
      moduleId: "PolarChartModule"
    },
    {
      type: "chart",
      name: "topology",
      moduleId: "TopologyChartModule",
      enterprise: true
    },
    // Axis types
    {
      type: "axis",
      name: "number",
      chartType: "cartesian",
      moduleId: "NumberAxisModule"
    },
    {
      type: "axis",
      name: "log",
      chartType: "cartesian",
      moduleId: "LogAxisModule"
    },
    {
      type: "axis",
      name: "time",
      chartType: "cartesian",
      moduleId: "TimeAxisModule"
    },
    {
      type: "axis",
      name: "unit-time",
      chartType: "cartesian",
      moduleId: "UnitTimeAxisModule"
    },
    {
      type: "axis",
      name: "category",
      chartType: "cartesian",
      moduleId: "CategoryAxisModule"
    },
    {
      type: "axis",
      name: "grouped-category",
      chartType: "cartesian",
      moduleId: "GroupedCategoryAxisModule"
    },
    {
      type: "axis",
      name: "ordinal-time",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "OrdinalTimeAxisModule"
    },
    {
      type: "axis",
      name: "angle-category",
      chartType: "polar",
      enterprise: true,
      moduleId: "AngleCategoryAxisModule"
    },
    {
      type: "axis",
      name: "angle-number",
      chartType: "polar",
      enterprise: true,
      moduleId: "AngleNumberAxisModule"
    },
    {
      type: "axis",
      name: "radius-category",
      chartType: "polar",
      enterprise: true,
      moduleId: "RadiusCategoryAxisModule"
    },
    {
      type: "axis",
      name: "radius-number",
      chartType: "polar",
      enterprise: true,
      moduleId: "RadiusNumberAxisModule"
    },
    // Series types
    {
      type: "series",
      name: "bar",
      chartType: "cartesian",
      moduleId: "BarSeriesModule"
    },
    {
      type: "series",
      name: "scatter",
      chartType: "cartesian",
      moduleId: "ScatterSeriesModule"
    },
    {
      type: "series",
      name: "bubble",
      chartType: "cartesian",
      moduleId: "BubbleSeriesModule"
    },
    {
      type: "series",
      name: "line",
      chartType: "cartesian",
      moduleId: "LineSeriesModule"
    },
    {
      type: "series",
      name: "area",
      chartType: "cartesian",
      moduleId: "AreaSeriesModule"
    },
    {
      type: "series",
      name: "pie",
      chartType: "polar",
      moduleId: "PieSeriesModule"
    },
    {
      type: "series",
      name: "donut",
      chartType: "polar",
      moduleId: "DonutSeriesModule"
    },
    {
      type: "series",
      name: "box-plot",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "BoxPlotSeriesModule"
    },
    {
      type: "series",
      name: "candlestick",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "CandlestickSeriesModule"
    },
    {
      type: "series",
      name: "cone-funnel",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "ConeFunnelSeriesModule"
    },
    {
      type: "series",
      name: "funnel",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "FunnelSeriesModule"
    },
    {
      type: "series",
      name: "ohlc",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "OhlcSeriesModule"
    },
    {
      type: "series",
      name: "heatmap",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "HeatmapSeriesModule"
    },
    {
      type: "series",
      name: "histogram",
      chartType: "cartesian",
      // enterprise: true,
      moduleId: "HistogramSeriesModule"
    },
    {
      type: "series",
      name: "range-area",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "RangeAreaSeriesModule"
    },
    {
      type: "series",
      name: "range-bar",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "RangeBarSeriesModule"
    },
    {
      type: "series",
      name: "waterfall",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "WaterfallSeriesModule"
    },
    {
      type: "series",
      name: "nightingale",
      chartType: "polar",
      enterprise: true,
      moduleId: "NightingaleSeriesModule"
    },
    {
      type: "series",
      name: "radar-area",
      chartType: "polar",
      enterprise: true,
      moduleId: "RadarAreaSeriesModule"
    },
    {
      type: "series",
      name: "radar-line",
      chartType: "polar",
      enterprise: true,
      moduleId: "RadarLineSeriesModule"
    },
    {
      type: "series",
      name: "radial-bar",
      chartType: "polar",
      enterprise: true,
      moduleId: "RadialBarSeriesModule"
    },
    {
      type: "series",
      name: "radial-column",
      chartType: "polar",
      enterprise: true,
      moduleId: "RadialColumnSeriesModule"
    },
    {
      type: "series",
      name: "map-shape",
      chartType: "topology",
      enterprise: true,
      moduleId: "MapShapeSeriesModule"
    },
    {
      type: "series",
      name: "map-line",
      chartType: "topology",
      enterprise: true,
      moduleId: "MapLineSeriesModule"
    },
    {
      type: "series",
      name: "map-marker",
      chartType: "topology",
      enterprise: true,
      moduleId: "MapMarkerSeriesModule"
    },
    {
      type: "series",
      name: "map-shape-background",
      chartType: "topology",
      enterprise: true,
      moduleId: "MapShapeBackgroundSeriesModule"
    },
    {
      type: "series",
      name: "map-line-background",
      chartType: "topology",
      enterprise: true,
      moduleId: "MapLineBackgroundSeriesModule"
    },
    {
      type: "series",
      name: "pyramid",
      chartType: "standalone",
      enterprise: true,
      moduleId: "PyramidSeriesModule"
    },
    {
      type: "series",
      name: "linear-gauge",
      chartType: "standalone",
      enterprise: true,
      moduleId: "LinearGaugeModule"
    },
    {
      type: "series",
      name: "radial-gauge",
      chartType: "standalone",
      enterprise: true,
      moduleId: "RadialGaugeModule"
    },
    {
      type: "series",
      name: "sunburst",
      chartType: "standalone",
      enterprise: true,
      moduleId: "SunburstSeriesModule"
    },
    {
      type: "series",
      name: "treemap",
      chartType: "standalone",
      enterprise: true,
      moduleId: "TreemapSeriesModule"
    },
    {
      type: "series",
      name: "chord",
      chartType: "standalone",
      enterprise: true,
      moduleId: "ChordSeriesModule"
    },
    {
      type: "series",
      name: "sankey",
      chartType: "standalone",
      enterprise: true,
      moduleId: "SankeySeriesModule"
    },
    // Plugins
    {
      type: "plugin",
      name: "animation",
      enterprise: true,
      moduleId: "AnimationModule"
    },
    {
      type: "plugin",
      name: "annotations",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "AnnotationsModule"
    },
    {
      type: "plugin",
      name: "legend",
      moduleId: "LegendModule"
    },
    {
      type: "plugin",
      name: "locale",
      moduleId: "LocaleModule"
    },
    {
      type: "plugin",
      name: "chartToolbar",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "ChartToolbarModule"
    },
    {
      type: "plugin",
      name: "contextMenu",
      enterprise: true,
      moduleId: "ContextMenuModule"
    },
    {
      type: "plugin",
      name: "statusBar",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "StatusBarModule"
    },
    {
      type: "plugin",
      name: "dataSource",
      enterprise: true,
      moduleId: "DataSourceModule"
    },
    {
      type: "plugin",
      name: "sync",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "SyncModule"
    },
    {
      type: "plugin",
      name: "ranges",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "RangesModule"
    },
    {
      type: "plugin",
      name: "zoom",
      enterprise: true,
      moduleId: "ZoomModule"
    },
    {
      type: "plugin",
      name: "flashOnUpdate",
      enterprise: true,
      moduleId: "FlashOnUpdateModule"
    },
    {
      type: "plugin",
      name: "gradientLegend",
      enterprise: true,
      moduleId: "GradientLegendModule"
    },
    {
      type: "plugin",
      name: "navigator",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "NavigatorModule"
    },
    {
      type: "plugin",
      name: "scrollbar",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "ScrollbarModule"
    },
    {
      type: "axis:plugin",
      name: "crosshair",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "CrosshairModule"
    },
    {
      type: "axis:plugin",
      name: "bandHighlight",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "BandHighlightModule"
    },
    {
      type: "series:plugin",
      name: "errorBar",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "ErrorBarsModule"
    },
    {
      type: "preset",
      name: "gauge-preset",
      chartType: "standalone",
      enterprise: true,
      moduleId: "GaugePresetModule"
    },
    {
      type: "preset",
      name: "price-volume",
      chartType: "cartesian",
      enterprise: true,
      moduleId: "PriceVolumePresetModule"
    },
    {
      type: "preset",
      name: "sparkline",
      moduleId: "SparklinePresetModule"
    }
  ].map((m) => [m.name, m])
);
function getSeriesExpectedChartType(seriesName) {
  const expectedModule = ExpectedModules.get(seriesName);
  return expectedModule?.type === "series" /* Series */ ? expectedModule.chartType : void 0;
}

// packages/ag-charts-community/src/chart/mapping/types.ts
function detectChartType(input) {
  const mainSeriesType = input.series?.[0]?.type ?? "line";
  return moduleRegistry_exports.getSeriesModule(mainSeriesType)?.chartType ?? getSeriesExpectedChartType(mainSeriesType) ?? "unknown";
}
function isAgCartesianChartOptions(input) {
  return detectChartType(input) === "cartesian";
}

// packages/ag-charts-community/src/chart/modulesManager.ts
var ModulesManager = class extends ModuleMap {
  *legends() {
    for (const module2 of moduleRegistry_exports.listModulesByType("plugin" /* Plugin */)) {
      if (module2.name === "legend" || module2.name === "gradientLegend") {
        yield {
          legendType: module2.name === "legend" ? "category" : "gradient",
          legend: this.getModule(module2.name)
        };
      }
    }
  }
};

// packages/ag-charts-community/src/chart/overlay/overlay.ts
var DEFAULT_OVERLAY_CLASS = "ag-charts-overlay";
var DEFAULT_OVERLAY_DARK_CLASS = "ag-charts-dark-overlay";
var Overlay = class extends BaseProperties {
  constructor(className, defaultMessageId) {
    super();
    this.className = className;
    this.defaultMessageId = defaultMessageId;
    this.enabled = true;
  }
  getText(localeManager) {
    if (isArray(this.text)) {
      return toPlainText(this.text);
    }
    if (this.rendererAsText) {
      return this.rendererAsText;
    }
    return localeManager.t(toTextString(this.text) || this.defaultMessageId);
  }
  getElement(callers, animationManager, localeManager, rect2) {
    this.content?.remove();
    this.rendererAsText = void 0;
    this.focusBox = rect2;
    if (this.renderer) {
      const params = {};
      const htmlContent = callWithContext(callers, this.renderer, params);
      if (isHTMLElement(htmlContent)) {
        this.content = htmlContent;
      } else {
        const tempDiv = createElement("div");
        tempDiv.innerHTML = htmlContent;
        const { firstElementChild } = tempDiv;
        if (isHTMLElement(firstElementChild) && tempDiv.childElementCount === 1) {
          this.content = firstElementChild;
        } else {
          this.content = tempDiv;
        }
      }
      this.rendererAsText = this.content?.textContent?.trim() ?? void 0;
    } else {
      const content = createElement("div", {
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        boxSizing: "border-box",
        height: "100%",
        margin: "8px",
        fontFamily: "var(--ag-charts-font-family)",
        fontSize: "var(--ag-charts-font-size)",
        fontWeight: "var(--ag-charts-font-weight)"
      });
      if (isArray(this.text)) {
        const container = createElement("div");
        for (const segment of this.text) {
          const el = createElement("span", {
            color: segment.color,
            fontSize: `${segment.fontSize}px`,
            fontFamily: segment.fontFamily ?? "inherit",
            fontWeight: String(segment.fontWeight),
            fontStyle: segment.fontStyle
          });
          el.innerText = toTextString(segment.text);
          container.appendChild(el);
        }
        content.appendChild(container);
      } else {
        content.innerText = this.getText(localeManager);
      }
      this.content = content;
      this.content.classList.add(this.className);
      animationManager?.animate({
        from: 0,
        to: 1,
        id: "overlay",
        phase: "add",
        groupId: "opacity",
        onUpdate(value) {
          content.style.opacity = String(value);
        },
        onStop() {
          content.style.opacity = "1";
        }
      });
    }
    return this.content;
  }
  removeElement(cleanup = () => this.content?.remove(), animationManager) {
    if (!this.content)
      return;
    if (animationManager) {
      const { content } = this;
      animationManager.animate({
        from: 1,
        to: 0,
        phase: "remove",
        id: "overlay",
        groupId: "opacity",
        onUpdate(value) {
          content.style.opacity = String(value);
        },
        onStop() {
          cleanup?.();
        }
      });
    } else {
      cleanup?.();
    }
    this.content = void 0;
    this.focusBox = void 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], Overlay.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Overlay.prototype, "text", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Overlay.prototype, "renderer", 2);

// packages/ag-charts-community/src/chart/overlay/chartOverlays.ts
var ChartOverlays = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.darkTheme = false;
    this.loading = new Overlay("ag-charts-loading-overlay", "overlayLoadingData");
    this.noData = new Overlay("ag-charts-no-data-overlay", "overlayNoData");
    this.noVisibleSeries = new Overlay("ag-charts-no-visible-series", "overlayNoVisibleSeries");
    this.unsupportedBrowser = new Overlay("ag-charts-unsupported-browser", "overlayUnsupportedBrowser");
  }
  getFocusInfo(localeManager) {
    for (const overlay of [this.loading, this.noData, this.noVisibleSeries, this.unsupportedBrowser]) {
      if (overlay.focusBox !== void 0) {
        return { text: overlay.getText(localeManager), rect: overlay.focusBox };
      }
    }
    return void 0;
  }
  destroy() {
    this.loading.removeElement();
    this.noData.removeElement();
    this.noVisibleSeries.removeElement();
    this.unsupportedBrowser.removeElement();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ChartOverlays.prototype, "darkTheme", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChartOverlays.prototype, "loading", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChartOverlays.prototype, "noData", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChartOverlays.prototype, "noVisibleSeries", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChartOverlays.prototype, "unsupportedBrowser", 2);

// packages/ag-charts-community/src/chart/overlay/loadingSpinner.ts
function getLoadingSpinner(text2, defaultDuration) {
  const { animationDuration } = PHASE_METADATA["add"];
  const duration = animationDuration * defaultDuration;
  const container = createElement("div", `${DEFAULT_OVERLAY_CLASS}--loading`, {
    display: "flex",
    alignItems: "center",
    justifyContent: "center",
    flexDirection: "column",
    height: "100%",
    boxSizing: "border-box",
    font: "13px Verdana, sans-serif",
    // FONT_SIZE.MEDIUM
    userSelect: "none",
    animation: `ag-charts-loading ${duration}ms linear 50ms both`
  });
  const matrix = createElement("span", {
    width: "45px",
    height: "40px",
    backgroundImage: [
      "linear-gradient(#0000 calc(1 * 100% / 6), #ccc 0 calc(3 * 100% / 6), #0000 0), ",
      "linear-gradient(#0000 calc(2 * 100% / 6), #ccc 0 calc(4 * 100% / 6), #0000 0), ",
      "linear-gradient(#0000 calc(3 * 100% / 6), #ccc 0 calc(5 * 100% / 6), #0000 0)"
    ].join(""),
    backgroundSize: "10px 400%",
    backgroundRepeat: "no-repeat",
    animation: "ag-charts-loading-matrix 1s infinite linear"
  });
  const label = createElement("p", { marginTop: "1em" });
  label.innerText = text2;
  const background = createElement("div", `${DEFAULT_OVERLAY_CLASS}__loading-background`, {
    position: "absolute",
    inset: "0",
    opacity: "0.5",
    zIndex: "-1"
  });
  const animationStyles = createElement("style");
  animationStyles.innerText = [
    "@keyframes ag-charts-loading { from { opacity: 0 } to { opacity: 1 } }",
    "@keyframes ag-charts-loading-matrix {",
    "0% { background-position: 0% 0%, 50% 0%, 100% 0%; }",
    "100% { background-position: 0% 100%, 50% 100%, 100% 100%; }",
    "}"
  ].join(" ");
  container.replaceChildren(animationStyles, matrix, label, background);
  return container;
}

// packages/ag-charts-community/src/chart/series-area/seriesArea.ts
var SeriesArea = class extends BaseProperties {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.rectNode = new Rect();
    this.border = new Border(this.rectNode);
    this.cornerRadius = 0;
    this.padding = 0;
    this.cleanup = new CleanupRegistry();
    this.node = this.createNode();
    this.node.append([this.rectNode]);
    this.rectNode.fill = void 0;
    this.cleanup.register(
      ctx.scene.attachNode(this.node),
      ctx.eventsHub.on("layout:complete", (e) => this.onLayoutComplete(e))
    );
  }
  destroy() {
    this.cleanup.flush();
  }
  getPadding() {
    const { border, padding: padding2 } = this;
    const strokeWidth = border.enabled ? border.strokeWidth : 0;
    if (typeof padding2 === "number") {
      const total = padding2 + strokeWidth;
      return { top: total, right: total, bottom: total, left: total };
    }
    return {
      top: (padding2.top ?? 0) + strokeWidth,
      right: (padding2.right ?? 0) + strokeWidth,
      bottom: (padding2.bottom ?? 0) + strokeWidth,
      left: (padding2.left ?? 0) + strokeWidth
    };
  }
  createNode() {
    return new Group({ name: "series-area-container", zIndex: 4 /* SERIES_AREA_CONTAINER */ });
  }
  onLayoutComplete(event) {
    const { x, y, width: width2, height: height2 } = event.series.paddedRect;
    this.rectNode.x = x;
    this.rectNode.y = y;
    this.rectNode.width = width2;
    this.rectNode.height = height2;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesArea.prototype, "border", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesArea.prototype, "clip", 2);
__decorateClass([
  ProxyPropertyOnWrite("rectNode", "cornerRadius"),
  addFakeTransformToInstanceProperty
], SeriesArea.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesArea.prototype, "padding", 2);

// packages/ag-charts-community/src/chart/series/shapeUtil.ts
function getShapeFill(fill, defaultGradient, defaultPattern, defaultImage) {
  if (isGradientFill(fill)) {
    return {
      type: "gradient",
      gradient: fill.gradient ?? defaultGradient.gradient,
      colorStops: fill.colorStops ?? defaultGradient.colorStops,
      bounds: fill.bounds ?? defaultGradient.bounds,
      rotation: fill.rotation ?? defaultGradient.rotation,
      reverse: fill.reverse ?? defaultGradient.reverse,
      colorSpace: fill.colorSpace ?? defaultGradient.colorSpace
    };
  }
  if (isPatternFill(fill)) {
    const pattern = fill.pattern ?? defaultPattern.pattern;
    let strokeWidth = fill.strokeWidth;
    if (pattern === "backward-slanted-lines" || pattern === "forward-slanted-lines" || pattern === "horizontal-lines" || pattern === "vertical-lines") {
      strokeWidth ?? (strokeWidth = defaultPattern.strokeWidth);
    } else {
      strokeWidth ?? (strokeWidth = 0);
    }
    const width2 = fill.width ?? fill.height ?? defaultPattern.width;
    const height2 = fill.height ?? fill.width ?? defaultPattern.height;
    return {
      type: "pattern",
      pattern,
      width: width2,
      height: height2,
      path: fill.path,
      padding: fill.padding ?? defaultPattern.padding,
      fill: fill.fill ?? defaultPattern.fill,
      fillOpacity: fill.fillOpacity ?? defaultPattern.fillOpacity,
      backgroundFill: fill.backgroundFill ?? defaultPattern.backgroundFill,
      backgroundFillOpacity: fill.backgroundFillOpacity ?? defaultPattern.backgroundFillOpacity,
      stroke: fill.stroke ?? defaultPattern.stroke,
      strokeOpacity: fill.strokeOpacity ?? defaultPattern.strokeOpacity,
      strokeWidth,
      rotation: fill.rotation ?? defaultPattern.rotation,
      scale: fill.scale ?? defaultPattern.scale
    };
  }
  if (isImageFill(fill)) {
    return {
      type: "image",
      url: fill.url,
      width: fill.width,
      height: fill.height,
      backgroundFill: fill.backgroundFill ?? defaultImage.backgroundFill,
      backgroundFillOpacity: fill.backgroundFillOpacity ?? defaultImage.backgroundFillOpacity,
      rotation: fill.rotation ?? defaultImage.rotation,
      repeat: fill.repeat ?? defaultImage.repeat,
      fit: fill.fit ?? defaultImage.fit
    };
  }
  return fill;
}
function getShapeStyle(style2, defaultGradient, defaultPattern, defaultImage) {
  if (!isGradientFill(style2?.fill) && !isPatternFill(style2?.fill) && !isImageFill(style2?.fill))
    return style2;
  return {
    ...style2,
    fill: getShapeFill(style2.fill, defaultGradient, defaultPattern, defaultImage)
  };
}

// packages/ag-charts-community/src/chart/series/series.ts
var SeriesNodePickMode = /* @__PURE__ */ ((SeriesNodePickMode18) => {
  SeriesNodePickMode18[SeriesNodePickMode18["EXACT_SHAPE_MATCH"] = 0] = "EXACT_SHAPE_MATCH";
  SeriesNodePickMode18[SeriesNodePickMode18["NEAREST_NODE"] = 1] = "NEAREST_NODE";
  SeriesNodePickMode18[SeriesNodePickMode18["AXIS_ALIGNED"] = 2] = "AXIS_ALIGNED";
  return SeriesNodePickMode18;
})(SeriesNodePickMode || {});
var CROSS_FILTER_MARKER_FILL_OPACITY_FACTOR = 0.25;
var CROSS_FILTER_MARKER_STROKE_OPACITY_FACTOR = 0.125;
var SeriesNodeEvent = class {
  constructor(type, event, nodeDatum, series) {
    this.type = type;
    this.event = event;
    this.defaultPrevented = false;
    this.datum = nodeDatum.datum;
    this.seriesId = series.id;
  }
  preventDefault() {
    this.defaultPrevented = true;
  }
};
var SeriesGroupingChangedEvent = class {
  constructor(series, seriesGrouping) {
    this.series = series;
    this.seriesGrouping = seriesGrouping;
    this.type = "groupingChanged";
  }
};
function propertyAxisDirection(property) {
  switch (property) {
    case "x":
      return "x" /* X */;
    case "y":
      return "y" /* Y */;
    case "angle":
      return "angle" /* Angle */;
    case "radius":
      return "radius" /* Radius */;
  }
}
function axisDirectionProperty(direction) {
  switch (direction) {
    case "x" /* X */:
      return "x";
    case "y" /* Y */:
      return "y";
    case "angle" /* Angle */:
      return "angle";
    case "radius" /* Radius */:
      return "radius";
    default:
      return "x";
  }
}
var Series = class extends Observable {
  constructor(seriesOpts) {
    super();
    this.cleanup = new CleanupRegistry();
    this.usesPlacedLabels = false;
    this.alwaysClip = false;
    this.hasChangesOnHighlight = false;
    this.seriesGrouping = void 0;
    this.NodeEvent = SeriesNodeEvent;
    this.internalId = createId(this);
    // The group node that contains the series rendering in its default (non-highlighted) state.
    this.contentGroup = new TranslatableGroup({
      name: `${this.internalId}-content`,
      zIndex: 1 /* ANY_CONTENT */
    });
    // The group node that contains all highlighted series items. This is a performance optimisation
    // for large-scale data-sets, where the only thing that routinely varies is the currently
    // highlighted node.
    this.highlightGroup = new TranslatableGroup({
      name: `${this.internalId}-highlight`,
      zIndex: 1 /* ANY_CONTENT */
    });
    this.highlightNodeGroup = this.highlightGroup.appendChild(
      new Group({ name: `${this.internalId}-highlight-node` })
    );
    this.highlightLabelGroup = this.highlightGroup.appendChild(
      new Group({
        name: `${this.internalId}-highlight-label`,
        zIndex: 2 /* LABEL */
      })
    );
    // Error bars etc.
    this.annotationGroup = new TranslatableGroup({
      name: `${this.internalId}-annotation`
    });
    // Lazily initialised labelGroup for label presentation.
    this.labelGroup = new TranslatableGroup({
      name: `${this.internalId}-series-labels`
    });
    this.axes = {};
    this.directions = ["x" /* X */, "y" /* Y */];
    // Flag to determine if we should recalculate node data.
    this.nodeDataRefresh = true;
    this.processedDataUpdated = true;
    this.moduleMap = new ModuleMap();
    this.datumCallbackCache = /* @__PURE__ */ new Map();
    this.connectsToYAxis = false;
    this.declarationOrder = -1;
    this._broughtToFront = false;
    this.events = new EventEmitter();
    this._pickNodeCache = new LRUCache(5);
    // Use a wrapper to comply with the @typescript-eslint/unbound-method rule.
    this.fireEventWrapper = (event) => super.fireEvent(event);
    const {
      moduleCtx,
      pickModes,
      propertyKeys = {},
      propertyNames = {},
      canHaveAxes = false,
      usesPlacedLabels = false,
      alwaysClip = false
    } = seriesOpts;
    this.ctx = moduleCtx;
    this.propertyKeys = propertyKeys;
    this.propertyNames = propertyNames;
    this.canHaveAxes = canHaveAxes;
    this.usesPlacedLabels = usesPlacedLabels;
    this.pickModes = pickModes;
    this.alwaysClip = alwaysClip;
    this.highlightLabelGroup.pointerEvents = 1 /* None */;
    this.cleanup.register(
      this.ctx.eventsHub.on("data:update", (data) => this.setChartData(data)),
      this.ctx.eventsHub.on("highlight:change", (event) => this.onChangeHighlight(event))
    );
  }
  get pickModeAxis() {
    return "main";
  }
  get id() {
    return this.properties?.id ?? this.internalId;
  }
  get type() {
    return this.constructor.type ?? "";
  }
  get focusable() {
    return true;
  }
  get data() {
    return this._data ?? this._chartData;
  }
  set visible(newVisibility) {
    this.properties.visible = newVisibility;
    this.ctx.legendManager.toggleItem(newVisibility, this.id);
    this.ctx.legendManager.update();
    this.visibleMaybeChanged();
  }
  get visible() {
    return this.ctx.legendManager.getSeriesEnabled(this.id) ?? this.properties.visible;
  }
  get hasData() {
    const dataSet = this.data;
    if (dataSet == null)
      return false;
    return dataSet.netSize() > 0;
  }
  get tooltipEnabled() {
    return this.properties.tooltip?.enabled;
  }
  onDataChange() {
    this.nodeDataRefresh = true;
    this.processedDataUpdated = true;
    this._pickNodeCache.clear();
  }
  setOptionsData(input) {
    this._data = input;
    this.onDataChange();
  }
  isHighlightEnabled() {
    return this.properties.highlight.enabled;
  }
  setChartData(input) {
    this._chartData = input;
    if (this.data === input) {
      this.onDataChange();
    }
  }
  onSeriesGroupingChange(prev, next) {
    const { internalId, type, visible } = this;
    if (prev) {
      this.ctx.seriesStateManager.deregisterSeries(this);
    }
    if (next) {
      this.ctx.seriesStateManager.registerSeries({
        internalId,
        type,
        visible,
        seriesGrouping: next,
        // TODO: is there a better way to pass width through here?
        width: "width" in this.properties ? this.properties.width : 0
      });
    }
    this.fireEvent(new SeriesGroupingChangedEvent(this, next));
  }
  getBandScalePadding() {
    return { inner: 1, outer: 0 };
  }
  attachSeries(seriesContentNode, seriesNode, annotationNode) {
    seriesContentNode.appendChild(this.contentGroup);
    seriesNode.appendChild(this.highlightGroup);
    seriesNode.appendChild(this.labelGroup);
    annotationNode?.appendChild(this.annotationGroup);
  }
  detachSeries(_seriesContentNode, _seriesNode, _annotationNode) {
    this.contentGroup.remove();
    this.highlightGroup.remove();
    this.labelGroup.remove();
    this.annotationGroup.remove();
  }
  setSeriesIndex(index, forceUpdate = false) {
    const bringToFront = this.bringToFront();
    if (!forceUpdate && index === this.declarationOrder && bringToFront === this._broughtToFront)
      return false;
    this.declarationOrder = index;
    this._broughtToFront = bringToFront;
    this.setZIndex(bringToFront ? Number.MAX_VALUE : index);
    this.fireEvent(new SeriesGroupingChangedEvent(this, this.seriesGrouping));
    return true;
  }
  setZIndex(zIndex) {
    this.contentGroup.zIndex = [1 /* ANY_CONTENT */, zIndex, 0 /* FOREGROUND */];
    this.highlightGroup.zIndex = [1 /* ANY_CONTENT */, zIndex, 1 /* HIGHLIGHT */];
    this.labelGroup.zIndex = [1 /* ANY_CONTENT */, zIndex, 2 /* LABEL */];
    this.annotationGroup.zIndex = zIndex;
  }
  renderToOffscreenCanvas() {
    return false;
  }
  hasHighlightOpacity() {
    if (!this.properties.highlight.enabled)
      return false;
    if (this.ctx.highlightManager.getActiveHighlight() == null)
      return false;
    const { unhighlightedItem, unhighlightedSeries } = this.properties.highlight;
    return hasDimmedOpacity(unhighlightedItem) || hasDimmedOpacity(unhighlightedSeries);
  }
  getDrawingMode(isHighlight, highlightDrawingMode = "cutout") {
    if (isHighlight) {
      return highlightDrawingMode;
    }
    return this.hasHighlightOpacity() ? this.ctx.chartService.highlight?.drawingMode ?? "overlay" : "overlay";
  }
  getAnimationDrawingModes() {
    const drawingMode = this.getDrawingMode(false);
    return {
      start: { drawingMode: "overlay" },
      finish: { drawingMode }
    };
  }
  addEventListener(type, listener) {
    return super.addEventListener(type, listener);
  }
  removeEventListener(type, listener) {
    return super.removeEventListener(type, listener);
  }
  hasEventListener(type) {
    return super.hasEventListener(type);
  }
  updatedDomains() {
  }
  destroy() {
    this.cleanup.flush();
    this.resetDatumCallbackCache();
    this.ctx.seriesStateManager.deregisterSeries(this);
  }
  getPropertyValues(property, properties) {
    const direction = propertyAxisDirection(property);
    const resolvedProperty = direction == null ? property : axisDirectionProperty(this.resolveKeyDirection(direction));
    const keys = properties?.[resolvedProperty];
    const values = [];
    if (!keys) {
      return values;
    }
    const addValues = (...items) => {
      for (const value of items) {
        if (Array.isArray(value)) {
          addValues(...value);
        } else if (typeof value === "object") {
          addValues(...Object.values(value));
        } else {
          values.push(value);
        }
      }
    };
    addValues(...keys.map((key) => this.properties[key]));
    return values;
  }
  getKeyAxis(_direction) {
    return void 0;
  }
  getKeys(direction) {
    return this.getPropertyValues(axisDirectionProperty(direction), this.propertyKeys);
  }
  getKeyProperties(direction) {
    return this.propertyKeys[this.resolveKeyDirection(direction)] ?? [];
  }
  getNames(direction) {
    return this.getPropertyValues(axisDirectionProperty(direction), this.propertyNames);
  }
  getFormatterContext(property) {
    const { id: seriesId } = this;
    const keys = this.getPropertyValues(property, this.propertyKeys);
    const names = this.getPropertyValues(property, this.propertyNames);
    const out = [];
    for (let idx = 0; idx < keys.length; idx++) {
      out.push({ seriesId, key: keys[idx], name: names[idx] });
    }
    return out;
  }
  resolveKeyDirection(direction) {
    return direction;
  }
  // The union of the series domain ('community') and series-option domains ('enterprise').
  getDomain(direction) {
    const seriesDomain = this.getSeriesDomain(direction);
    const moduleDomains = this.moduleMap.mapModules((module2) => module2.getDomain(direction)).flat();
    if (moduleDomains.length === 0) {
      return seriesDomain;
    }
    return { domain: seriesDomain.domain.concat(moduleDomains) };
  }
  getRange(direction, visibleRange) {
    return this.getSeriesRange(direction, visibleRange);
  }
  getMinimumRangeSeries(_range) {
  }
  getMinimumRangeChart(_ranges) {
    return 0;
  }
  getZoomRangeFittingItems(_xVisibleRange, _yVisibleRange, _minVisibleItems) {
    return void 0;
  }
  getVisibleItems(_xVisibleRange, _yVisibleRange, _minVisibleItems) {
    return Infinity;
  }
  toCanvasFromMidPoint(nodeDatum) {
    const { x = 0, y = 0 } = nodeDatum.midPoint ?? {};
    return Transformable.toCanvasPoint(this.contentGroup, x, y);
  }
  // Indicate that something external changed and we should recalculate nodeData.
  markNodeDataDirty() {
    this.nodeDataRefresh = true;
    this._pickNodeCache.clear();
    this.visibleMaybeChanged();
  }
  visibleMaybeChanged() {
    const { internalId, seriesGrouping, type, visible } = this;
    this.ctx.seriesStateManager.updateSeries({
      internalId,
      type,
      visible,
      seriesGrouping,
      // TODO: is there a better way to pass width through here?
      width: "width" in this.properties ? this.properties.width : 0
    });
  }
  getOpacity() {
    const defaultOpacity = 1;
    if (!this.properties.highlight) {
      return defaultOpacity;
    }
    const { opacity = defaultOpacity } = this.getHighlightStyle();
    return opacity;
  }
  getHighlightState(highlightedDatum, isHighlight, datumIndex, legendItemValues) {
    if (!this.properties.highlight.enabled) {
      return 0 /* None */;
    }
    if (isHighlight) {
      return 1 /* Item */;
    }
    if (highlightedDatum?.series == null) {
      return 0 /* None */;
    }
    if (this.isSeriesHighlighted(highlightedDatum, legendItemValues)) {
      const itemHighlighted = this.isItemHighlighted(highlightedDatum, datumIndex);
      if (itemHighlighted == null) {
        return 2 /* Series */;
      }
      return 4 /* OtherItem */;
    }
    return 3 /* OtherSeries */;
  }
  getHighlightStateString(datum, isHighlight, datumIndex, legendItemValues) {
    return toHighlightString(this.getHighlightState(datum, isHighlight, datumIndex, legendItemValues));
  }
  onChangeHighlight(event) {
    const previousHighlightedDatum = event.previousHighlight;
    const currentHighlightedDatum = event.currentHighlight;
    const currentHighlightState = this.getHighlightState(currentHighlightedDatum);
    const previousHighlightState = this.getHighlightState(previousHighlightedDatum);
    this.setSeriesIndex(this.declarationOrder);
    const hasItemStylers = this.hasItemStylers();
    if (!hasItemStylers && currentHighlightState === previousHighlightState) {
      this.hasChangesOnHighlight = false;
      return;
    }
    const { highlightedSeries, unhighlightedItem, unhighlightedSeries } = this.properties.highlight;
    this.hasChangesOnHighlight = hasItemStylers || !isEmptyObject(highlightedSeries) || !isEmptyObject(unhighlightedItem) || !isEmptyObject(unhighlightedSeries);
  }
  bringToFront() {
    return this.properties.highlight.enabled && this.properties.highlight.bringToFront && this.isSeriesHighlighted(this.ctx.highlightManager.getActiveHighlight());
  }
  isSeriesHighlighted(highlightedDatum, _legendItemValues) {
    if (!this.properties.highlight.enabled) {
      return false;
    }
    return highlightedDatum?.series === this;
  }
  isItemHighlighted(highlightedDatum, datumIndex) {
    if (highlightedDatum?.datumIndex == null || datumIndex == null)
      return;
    return highlightedDatum.datumIndex === datumIndex;
  }
  getHighlightStyle(isHighlight, datumIndex, highlightState, legendItemValues) {
    const highlightedDatum = this.ctx.highlightManager?.getActiveHighlight();
    highlightState ?? (highlightState = this.getHighlightState(highlightedDatum, isHighlight, datumIndex, legendItemValues));
    return this.properties.highlight.getStyle(highlightState);
  }
  resolveMarkerDrawingModeForState(drawingMode, style2) {
    return resolveMarkerDrawingMode(drawingMode, style2);
  }
  filterItemStylerFillParams(fill) {
    if (isGradientFill(fill)) {
      return without(fill, ["bounds", "colorSpace", "gradient", "reverse"]);
    } else if (isPatternFill(fill)) {
      return without(fill, ["padding"]);
    }
    return fill;
  }
  getModuleTooltipParams() {
    return this.moduleMap.mapModules((module2) => module2.getTooltipParams()).reduce((total, current) => Object.assign(total, current), {});
  }
  pickNodes(point, intent, exactMatchOnly = false) {
    const { pickModes, pickModeAxis, visible, contentGroup } = this;
    if (!visible || !contentGroup.visible)
      return;
    if (intent === "highlight" && !this.properties.highlight.enabled)
      return;
    if (intent === "highlight-tooltip" && !this.properties.highlight.enabled)
      return;
    let maxDistance = Infinity;
    if (intent === "tooltip" || intent === "highlight-tooltip") {
      const { tooltip } = this.properties;
      maxDistance = typeof tooltip.range === "number" ? tooltip.range : Infinity;
      exactMatchOnly || (exactMatchOnly = tooltip.range === "exact");
    } else if (intent === "event" || intent === "context-menu") {
      const { nodeClickRange } = this.properties;
      maxDistance = typeof nodeClickRange === "number" ? nodeClickRange : Infinity;
      exactMatchOnly || (exactMatchOnly = nodeClickRange === "exact");
    }
    const selectedPickModes = pickModes.filter(
      (m) => !exactMatchOnly || m === 0 /* EXACT_SHAPE_MATCH */
    );
    const { x, y } = point;
    const key = JSON.stringify({ x, y, maxDistance, selectedPickModes });
    if (this._pickNodeCache.has(key)) {
      return this._pickNodeCache.get(key);
    }
    for (const pickMode of selectedPickModes) {
      let result;
      switch (pickMode) {
        case 0 /* EXACT_SHAPE_MATCH */: {
          const exact = this.pickNodesExactShape(point);
          result = exact.length === 0 ? void 0 : { datums: exact, distance: 0 };
          break;
        }
        case 1 /* NEAREST_NODE */: {
          const closest = this.pickNodeClosestDatum(point);
          const exact = closest?.distance === 0 ? this.pickNodesExactShape(point) : void 0;
          if (exact != null && exact.length !== 0) {
            result = { datums: exact, distance: 0 };
          } else if (closest) {
            result = { datums: [closest.datum], distance: closest.distance };
          } else {
            result = void 0;
          }
          break;
        }
        case 2 /* AXIS_ALIGNED */: {
          const closest = pickModeAxis == null ? void 0 : this.pickNodeMainAxisFirst(point, pickModeAxis === "main-category");
          result = closest == null ? void 0 : { datums: [closest.datum], distance: closest.distance };
          break;
        }
      }
      if (result && result.distance <= maxDistance) {
        return this._pickNodeCache.set(key, { pickMode, datums: result.datums, distance: result.distance });
      }
    }
    return this._pickNodeCache.set(key, void 0);
  }
  pickNodesExactShape(point) {
    const datums = [];
    for (const node of this.contentGroup.pickNodes(point.x, point.y)) {
      const datum = node.closestDatum();
      if (datum != null && datum.missing !== true) {
        datums.push(datum);
      }
    }
    return datums;
  }
  pickNodeClosestDatum(_point) {
    throw new Error("AG Charts - Series.pickNodeClosestDatum() not implemented");
  }
  pickNodeNearestDistantObject(point, items) {
    const match = nearestSquared(point.x, point.y, items);
    const datum = match.nearest?.closestDatum();
    if (datum != null && datum.missing !== true) {
      return { datum, distance: Math.sqrt(match.distanceSquared) };
    }
  }
  pickNodeMainAxisFirst(_point, _requireCategoryAxis) {
    throw new Error("AG Charts - Series.pickNodeMainAxisFirst() not implemented");
  }
  getLabelData() {
    return [];
  }
  updatePlacedLabelData(_labels) {
    return;
  }
  fireEvent(event) {
    callWithContext([this.properties, this.ctx.chartService], this.fireEventWrapper, event);
  }
  fireNodeClickEvent(event, datum) {
    const clickEvent = new this.NodeEvent("seriesNodeClick", event, datum, this);
    this.fireEvent(clickEvent);
    return !clickEvent.defaultPrevented;
  }
  fireNodeDoubleClickEvent(event, datum) {
    const clickEvent = new this.NodeEvent("seriesNodeDoubleClick", event, datum, this);
    this.fireEvent(clickEvent);
    return !clickEvent.defaultPrevented;
  }
  createNodeContextMenuActionEvent(event, datum) {
    return new this.NodeEvent("nodeContextMenuAction", event, datum, this);
  }
  onLegendInitialState(legendType, initialState) {
    const { visible = true, itemId, legendItemName } = initialState ?? {};
    this.toggleSeriesItem(visible, legendType, itemId, legendItemName);
  }
  onLegendItemClick(event) {
    const { enabled, itemId, series, legendType } = event;
    const legendItemName = "legendItemName" in this.properties ? this.properties.legendItemName : void 0;
    const legendItemKey = "legendItemKey" in this.properties ? this.properties.legendItemKey : void 0;
    const matchedLegendItemName = legendItemName != void 0 && legendItemName === event.legendItemName;
    if (series.id === this.id || matchedLegendItemName || legendItemKey != void 0) {
      this.toggleSeriesItem(enabled, legendType, itemId, legendItemName, event);
    }
  }
  onLegendItemDoubleClick(event) {
    const { enabled, itemId, series, numVisibleItems, legendType } = event;
    const legendItemName = "legendItemName" in this.properties ? this.properties.legendItemName : void 0;
    const legendItemKey = "legendItemKey" in this.properties ? this.properties.legendItemKey : void 0;
    const matchedLegendItemName = legendItemName != void 0 && legendItemName === event.legendItemName;
    if (series.id === this.id || matchedLegendItemName || legendItemKey != void 0) {
      this.toggleSeriesItem(true, legendType, itemId, legendItemName, event);
    } else if (enabled && numVisibleItems === 1) {
      this.toggleSeriesItem(true, legendType, void 0, legendItemName);
    } else {
      this.toggleSeriesItem(false, legendType, void 0, legendItemName);
    }
  }
  toggleSeriesItem(enabled, legendType, itemId, legendItemName, legendEvent) {
    const seriesId = this.id;
    if (enabled || legendType !== "category") {
      this.visible = enabled;
    }
    this.nodeDataRefresh = true;
    this._pickNodeCache.clear();
    const event = {
      type: "seriesVisibilityChange",
      seriesId,
      itemId,
      legendItemName: legendEvent?.legendItemName ?? legendItemName,
      visible: enabled
    };
    this.fireEvent(event);
    this.ctx.legendManager.toggleItem(enabled, seriesId, itemId, legendItemName);
  }
  isEnabled() {
    return this.visible;
  }
  getModuleMap() {
    return this.moduleMap;
  }
  createModuleContext() {
    return { ...this.ctx, series: this };
  }
  getAxisValueText(axis, source, value, datum, key, legendItemName, allowNull) {
    const { id: seriesId, properties } = this;
    return axis.formatDatum(
      properties,
      value,
      source,
      seriesId,
      legendItemName,
      datum,
      key,
      void 0,
      void 0,
      void 0,
      allowNull
    );
  }
  getLabelText(value, datum, key, property, domain, label, baseParams, allowNullValue = false) {
    if (value == null && !allowNullValue)
      return "";
    const { axes, canHaveAxes, ctx, id: seriesId, properties } = this;
    const source = "series-label";
    const legendItemName = "legendItemName" in properties ? properties.legendItemName : void 0;
    const params = {
      seriesId: this.id,
      ...baseParams
    };
    const direction = canHaveAxes ? propertyAxisDirection(property) : void 0;
    const axis = direction == null ? void 0 : axes[this.resolveKeyDirection(direction)];
    if (axis != null) {
      return axis.formatDatum(
        properties,
        value,
        source,
        seriesId,
        legendItemName,
        datum,
        key,
        domain,
        label,
        params,
        allowNullValue
      );
    }
    const { formatManager } = ctx;
    const formatInContext = this.callWithContext.bind(this);
    const format = (formatParams) => label.formatValue(formatInContext, formatParams.type, formatParams.value, params) ?? formatManager.format(formatInContext, formatParams) ?? (value == null ? "" : String(value));
    const boundSeries = this.getFormatterContext(property);
    switch (property) {
      case "y":
      case "color":
      case "size": {
        const fractionDigits = void 0;
        return format({
          type: "number",
          value,
          datum,
          seriesId,
          legendItemName,
          key,
          source,
          property,
          domain,
          boundSeries,
          fractionDigits,
          visibleDomain: void 0
        });
      }
      case "x":
      case "radius":
      case "angle":
      case "label":
      case "secondaryLabel":
      case "calloutLabel":
      case "sectorLabel":
      case "legendItem":
        return format({
          type: "category",
          value,
          datum,
          seriesId,
          legendItemName,
          key,
          source,
          property,
          domain,
          boundSeries
        });
    }
  }
  getMarkerStyle(marker, { datumIndex, datum, point }, params, opts, defaultOverrideStyle = { size: point?.size ?? marker.size ?? 0 }, inheritedStyle) {
    const { itemStyler } = marker;
    const {
      highlightState,
      isHighlight = false,
      checkForHighlight = true,
      resolveMarkerSubPath = ["marker"],
      resolveStyler = false
    } = opts ?? {};
    const resolvePath2 = ["series", `${this.declarationOrder}`, ...resolveMarkerSubPath];
    if (resolveStyler) {
      const resolveOpt = { permissivePath: true };
      const resolved = this.ctx.optionsGraphService.resolvePartial(resolvePath2, defaultOverrideStyle, resolveOpt);
      if (resolved) {
        defaultOverrideStyle = { ...resolved, size: resolved.size ?? defaultOverrideStyle.size };
      }
    }
    const highlightStyle = checkForHighlight ? this.getHighlightStyle(isHighlight, datumIndex, highlightState) : void 0;
    const baseStyle = mergeDefaults(highlightStyle, defaultOverrideStyle, marker.getStyle(), inheritedStyle);
    let markerStyle = baseStyle;
    if (itemStyler && params) {
      const highlight5 = this.ctx.highlightManager?.getActiveHighlight();
      const highlightStateString = this.getHighlightStateString(highlight5, isHighlight, datumIndex);
      const fill = this.filterItemStylerFillParams(markerStyle.fill);
      const style2 = this.cachedCallWithContext(itemStyler, {
        seriesId: this.id,
        ...markerStyle,
        fill,
        ...params,
        highlightState: highlightStateString,
        datum
      });
      const resolved = this.ctx.optionsGraphService.resolvePartial(resolvePath2, style2);
      markerStyle = mergeDefaults(resolved, markerStyle);
    }
    return markerStyle;
  }
  applyMarkerStyle(style2, markerNode, point, fillBBox, { applyTranslation = true, selected = true } = {}) {
    const { shape, size = 0 } = style2;
    const visible = this.visible && size > 0 && point && !Number.isNaN(point.x) && !Number.isNaN(point.y);
    markerNode.setStyleProperties(style2, fillBBox);
    if (applyTranslation) {
      markerNode.setProperties({
        visible,
        shape,
        size,
        x: point?.x,
        y: point?.y,
        scalingCenterX: point?.x,
        scalingCenterY: point?.y
      });
    } else {
      markerNode.setProperties({ visible, shape, size });
    }
    if (!selected) {
      markerNode.fillOpacity *= CROSS_FILTER_MARKER_FILL_OPACITY_FACTOR;
      markerNode.strokeOpacity *= CROSS_FILTER_MARKER_STROKE_OPACITY_FACTOR;
    }
    if (typeof shape === "function" && !markerNode.dirtyPath) {
      markerNode.path.clear(true);
      markerNode.updatePath();
      markerNode.checkPathDirty();
      const bb = markerNode.getBBox();
      if (point != null && bb.isFinite()) {
        const center2 = bb.computeCenter();
        const [dx2, dy2] = ["x", "y"].map(
          (key) => (style2.strokeWidth ?? 0) + Math.abs(center2[key] - point[key])
        );
        point.focusSize = Math.max(bb.width + dx2, bb.height + dy2);
      }
    }
  }
  get nodeDataDependencies() {
    return this._nodeDataDependencies ?? { seriesRectWidth: Number.NaN, seriesRectHeight: Number.NaN };
  }
  checkResize(newSeriesRect) {
    const { width: seriesRectWidth, height: seriesRectHeight } = newSeriesRect ?? {
      width: Number.NaN,
      height: Number.NaN
    };
    const newNodeDataDependencies = newSeriesRect ? { seriesRectWidth, seriesRectHeight } : void 0;
    const resize = jsonDiff(this.nodeDataDependencies, newNodeDataDependencies) != null;
    if (resize) {
      this._nodeDataDependencies = newNodeDataDependencies;
      this.markNodeDataDirty();
    }
    return resize;
  }
  pickFocus(_opts) {
    return void 0;
  }
  resetDatumCallbackCache() {
    this.datumCallbackCache.clear();
  }
  cachedDatumCallback(id, fn) {
    const { datumCallbackCache } = this;
    const existing = datumCallbackCache.get(id);
    if (existing != null)
      return existing;
    try {
      const value = fn();
      datumCallbackCache.set(id, value);
      return value;
    } catch (error2) {
      logger_exports.error(String(error2));
    }
  }
  cachedCallWithContext(fn, params) {
    return this.ctx.callbackCache.call([this.properties, this.ctx.chartService], fn, params);
  }
  callWithContext(fn, params) {
    return callWithContext([this.properties, this.ctx.chartService], fn, params);
  }
  formatTooltipWithContext(tooltip, content, params) {
    return tooltip.formatTooltip([this.properties, this.ctx.chartService], content, params);
  }
  // @todo(AG-13777) - Remove this function (see CartesianSeries.ts)
  minTimeInterval() {
    return;
  }
  needsDataModelDiff() {
    return !this.ctx.animationManager.isSkipped() || !!this.chart?.flashOnUpdateEnabled;
  }
};
Series.className = "Series";
__decorateClass([
  ActionOnSet({
    changeValue: function(newVal, oldVal) {
      this.onSeriesGroupingChange(oldVal, newVal);
    }
  })
], Series.prototype, "seriesGrouping", 2);

// packages/ag-charts-community/src/dom/focusIndicator.ts
var FocusIndicator = class {
  constructor(swapChain) {
    this.swapChain = swapChain;
    this.hasBeenActivated = false;
    this.div = createElement("div");
    this.svg = createSvgElement("svg");
    this.outerPath = createSvgElement("path");
    this.innerPath = createSvgElement("path");
    this.svg.append(this.outerPath);
    this.svg.append(this.innerPath);
    this.outerPath.classList.add("ag-charts-focus-svg-outer-path");
    this.innerPath.classList.add("ag-charts-focus-svg-inner-path");
    this.element = createElement("div", "ag-charts-focus-indicator");
    this.element.ariaHidden = "true";
    this.element.append(this.svg);
    this.swapChain.addListener("swap", (parent) => this.onSwap(parent));
  }
  clear() {
  }
  update(focus, rect2, clip) {
    if (rect2 == null)
      return;
    if (focus instanceof Path) {
      const transform = (localX, localY) => {
        let { x, y } = Transformable.toCanvasPoint(focus, localX, localY);
        x -= rect2.x ?? 0;
        y -= rect2.y ?? 0;
        return { x, y };
      };
      const d = focus.svgPathData(transform);
      this.outerPath.setAttribute("d", d);
      this.innerPath.setAttribute("d", d);
      this.show(this.svg);
    } else {
      let bbox;
      if (clip) {
        const x0 = Math.max(focus.x - rect2.x, 0);
        const y0 = Math.max(focus.y - rect2.y, 0);
        const x1 = Math.min(focus.x + focus.width - rect2.x, rect2.width);
        const y1 = Math.min(focus.y + focus.height - rect2.y, rect2.height);
        bbox = new BBox(x0, y0, x1 - x0, y1 - y0);
      } else {
        bbox = new BBox(focus.x - rect2.x, focus.y - rect2.y, focus.width, focus.height);
      }
      setElementBBox(this.div, bbox);
      this.show(this.div);
    }
  }
  onSwap(newParent) {
    if (newParent === this.element.parentElement)
      return;
    this.element.remove();
    newParent.appendChild(this.element);
    this.overrideFocusVisible(this.focusVisible);
  }
  show(child) {
    this.hasBeenActivated = true;
    this.element.innerHTML = "";
    this.element.append(child);
  }
  overrideFocusVisible(focusVisible) {
    this.focusVisible = focusVisible;
    const opacity = { true: "1", false: "0", undefined: "" };
    const parent = this.element.parentElement;
    parent?.style.setProperty("opacity", opacity[`${focusVisible}`]);
  }
  // Get the `:focus-visible` CSS state.
  isFocusVisible(force = false) {
    if (!force && !this.hasBeenActivated)
      return false;
    const parent = this.element.parentElement;
    return parent != null && getWindow().getComputedStyle(parent).opacity === "1";
  }
};

// packages/ag-charts-community/src/dom/focusSwapChain.ts
var FocusSwapChain = class {
  constructor(label1, label2, announcerRole, initialAltText) {
    this.label1 = label1;
    this.label2 = label2;
    this.hasFocus = false;
    this.skipDispatch = false;
    this.listeners = {
      blur: [],
      focus: [],
      swap: []
    };
    this.onBlur = (e) => {
      setElementStyle(e.target, "pointer-events", void 0);
      return !this.skipDispatch && this.dispatch("blur", e);
    };
    this.onFocus = (e) => {
      setElementStyle(e.target, "pointer-events", "auto");
      return !this.skipDispatch && this.dispatch("focus", e);
    };
    setAttribute(this.label1, "id", createElementId());
    setAttribute(this.label2, "id", createElementId());
    setElementStyle(this.label1, "display", "none");
    setElementStyle(this.label2, "display", "none");
    this.label1.textContent = initialAltText;
    this.label2.textContent = initialAltText;
    this.activeAnnouncer = this.createAnnouncer(announcerRole);
    this.inactiveAnnouncer = this.createAnnouncer(announcerRole);
    setAttribute(this.activeAnnouncer, "tabindex", 0);
    this.label2.insertAdjacentElement("afterend", this.activeAnnouncer);
    this.label2.insertAdjacentElement("afterend", this.inactiveAnnouncer);
    this.swap(initialAltText);
  }
  createAnnouncer(role) {
    const announcer = createElement("div");
    announcer.role = role;
    announcer.className = "ag-charts-swapchain";
    announcer.addEventListener("blur", this.onBlur);
    announcer.addEventListener("focus", this.onFocus);
    return announcer;
  }
  destroy() {
    for (const announcer of [this.activeAnnouncer, this.inactiveAnnouncer]) {
      announcer.removeEventListener("blur", this.onBlur);
      announcer.removeEventListener("focus", this.onFocus);
      announcer.remove();
    }
  }
  focus(opts) {
    this.focusOptions = opts;
    this.activeAnnouncer.focus(opts);
    this.focusOptions = void 0;
  }
  update(newLabel) {
    this.skipDispatch = true;
    this.swap(newLabel);
    if (this.hasFocus) {
      this.activeAnnouncer.focus(this.focusOptions);
    }
    this.skipDispatch = false;
  }
  addListener(type, handler) {
    this.listeners[type].push(handler);
    if (type === "swap") {
      const swapHandler = handler;
      swapHandler(this.activeAnnouncer);
    }
  }
  dispatch(type, param) {
    if (type === "focus")
      this.hasFocus = true;
    else if (type === "blur")
      this.hasFocus = false;
    for (const fn of this.listeners[type]) {
      fn(param);
    }
  }
  swap(newLabel) {
    const userTabIndex = this.activeAnnouncer.tabIndex;
    this.label2.textContent = newLabel;
    [this.inactiveAnnouncer, this.activeAnnouncer] = [this.activeAnnouncer, this.inactiveAnnouncer];
    [this.label1, this.label2] = [this.label2, this.label1];
    setAttributes(this.inactiveAnnouncer, {
      "aria-labelledby": this.label1.id,
      "aria-hidden": true,
      tabindex: void 0
    });
    setAttributes(this.activeAnnouncer, {
      "aria-labelledby": this.label1.id,
      "aria-hidden": false,
      tabindex: userTabIndex
    });
    this.dispatch("swap", this.activeAnnouncer);
  }
};

// packages/ag-charts-community/src/chart/interaction/keyBindings.ts
var KEY_BINDINGS = {
  arrowdown: { bindings: [{ code: "ArrowDown" }] },
  arrowleft: { bindings: [{ code: "ArrowLeft" }] },
  arrowright: { bindings: [{ code: "ArrowRight" }] },
  arrowup: { bindings: [{ code: "ArrowUp" }] },
  delete: { bindings: [{ key: "Backspace" }, { key: "Delete" }], activatesFocusIndicator: false },
  redo: {
    bindings: [
      { key: "y", ctrlOrMeta: true },
      { key: "z", ctrlOrMeta: true, shift: true }
    ],
    activatesFocusIndicator: false
  },
  undo: { bindings: [{ key: "z", ctrlOrMeta: true }], activatesFocusIndicator: false },
  submit: { bindings: [{ key: "Enter" }, { code: "Enter" }, { code: "Space" }] },
  zoomin: { bindings: [{ key: "+" }, { code: "ZoomIn" }, { code: "Add" }], activatesFocusIndicator: false },
  zoomout: { bindings: [{ key: "-" }, { code: "ZoomOut" }, { code: "Substract" }], activatesFocusIndicator: false }
};
function matchesKeyBinding(e, bindings) {
  for (const kb of bindings) {
    if ("code" in kb) {
      if (kb.code === e.code)
        return true;
    } else {
      const matches = kb.key === e.key && (kb.shift === void 0 || kb.shift === e.shiftKey) && (kb.ctrlOrMeta === void 0 || kb.ctrlOrMeta === e.ctrlKey || kb.ctrlOrMeta === e.metaKey);
      if (matches)
        return true;
    }
  }
  return false;
}
function mapKeyboardEventToAction(event) {
  for (const [actionName, { activatesFocusIndicator = true, bindings }] of entries(KEY_BINDINGS)) {
    if (matchesKeyBinding(event, bindings)) {
      return { name: actionName, activatesFocusIndicator };
    }
  }
  return void 0;
}

// packages/ag-charts-community/src/chart/keyboardUtil.ts
function computeCenter(series, hoverRect, pick2) {
  const refPoint = getDatumRefPoint(series, pick2.datum, pick2.movedBounds);
  if (refPoint != null)
    return { x: refPoint.canvasX, y: refPoint.canvasY };
  const bboxOrPath = pick2.bounds;
  if (bboxOrPath == null)
    return;
  if (bboxOrPath instanceof BBox) {
    const { x: centerX, y: centerY } = bboxOrPath.computeCenter();
    return {
      x: hoverRect.x + centerX,
      y: hoverRect.y + centerY
    };
  }
  return Transformable.toCanvas(bboxOrPath).computeCenter();
}
function getPickedFocusBBox({ bounds }) {
  if (bounds instanceof BBox)
    return bounds;
  if (bounds != null)
    return Transformable.toCanvas(bounds);
  return BBox.NaN;
}
function makeKeyboardPointerEvent(series, hoverRect, pick2) {
  const { x: canvasX, y: canvasY } = computeCenter(series, hoverRect, pick2) ?? {};
  if (canvasX !== void 0 && canvasY !== void 0) {
    return { type: "keyboard", canvasX, canvasY };
  }
  return void 0;
}

// packages/ag-charts-community/src/chart/tooltip/springAnimation.ts
var M = 0.1;
var K = 200;
var C = 12;
var DELTA = 0.5;
var SpringAnimation = class {
  constructor() {
    this.events = new EventEmitter();
    this.x1 = Number.NaN;
    this.y1 = Number.NaN;
    this.x = Number.NaN;
    this.y = Number.NaN;
    this.vx = 0;
    this.vy = 0;
    this.t0 = Number.NaN;
    this.animationFrameHandle = void 0;
  }
  reset() {
    this.x = Number.NaN;
    this.y = Number.NaN;
    if (this.animationFrameHandle != null) {
      cancelAnimationFrame(this.animationFrameHandle);
      this.animationFrameHandle = void 0;
    }
  }
  update(x, y) {
    if (Number.isNaN(this.x) || Number.isNaN(this.y)) {
      this.x = x;
      this.y = y;
      this.vx = 0;
      this.vy = 0;
      this.emitUpdate();
      if (this.animationFrameHandle != null) {
        cancelAnimationFrame(this.animationFrameHandle);
        this.animationFrameHandle = void 0;
      }
      return;
    }
    this.x1 = x;
    this.y1 = y;
    this.t0 = Date.now();
    this.animationFrameHandle ?? (this.animationFrameHandle = requestAnimationFrame(this.onFrame.bind(this)));
  }
  onFrame() {
    this.animationFrameHandle = void 0;
    const { x1, y1, t0 } = this;
    const t1 = Date.now();
    const dt = t1 - t0;
    this.t0 = t1;
    const stepT = 1e-3;
    const iterations = Math.trunc(Math.ceil(dt / (stepT * 1e3)));
    let { x, y, vx, vy } = this;
    for (let i = 0; i < iterations; i += 1) {
      const dx2 = x - x1;
      const dy2 = y - y1;
      const ax = -(K * dx2 + C * vx) / M;
      const ay = -(K * dy2 + C * vy) / M;
      vx += ax * stepT;
      vy += ay * stepT;
      x += vx * stepT;
      y += vy * stepT;
    }
    if (Math.hypot(x - x1, y - y1) < DELTA) {
      this.x = this.x1;
      this.y = this.y1;
      this.vx = 0;
      this.vy = 0;
    } else {
      this.x = x;
      this.y = y;
      this.vx = vx;
      this.vy = vy;
      this.animationFrameHandle = requestAnimationFrame(this.onFrame.bind(this));
    }
    this.emitUpdate();
  }
  emitUpdate() {
    this.events.emit("update", { x: this.x, y: this.y });
  }
};

// packages/ag-charts-community/src/util/sanitize.ts
var element = null;
function sanitizeHtml(text2) {
  const plainText = toPlainText(text2);
  if (plainText === "")
    return "";
  element ?? (element = createElement("div"));
  element.textContent = plainText;
  return element.innerHTML.replaceAll("\n", "<br>");
}

// packages/ag-charts-community/src/chart/marker/shapes.ts
function drawMarkerUnitPolygon(params, moves) {
  const { path, size } = params;
  const { x: x0, y: y0 } = params;
  path.clear();
  let didMove = false;
  for (const [dx2, dy2] of moves) {
    const x = x0 + (dx2 - 0.5) * size;
    const y = y0 + (dy2 - 0.5) * size;
    if (didMove) {
      path.lineTo(x, y);
    } else {
      path.moveTo(x, y);
    }
    didMove = true;
  }
  path.closePath();
}
var MARKER_SHAPES = {
  circle({ path, x, y, size }) {
    const r = size / 2;
    path.arc(x, y, r, 0, Math.PI * 2);
    path.closePath();
  },
  cross(params) {
    drawMarkerUnitPolygon(params, [
      [0.25, 0],
      [0.5, 0.25],
      [0.75, 0],
      [1, 0.25],
      [0.75, 0.5],
      [1, 0.75],
      [0.75, 1],
      [0.5, 0.75],
      [0.25, 1],
      [0, 0.75],
      [0.25, 0.5],
      [0, 0.25]
    ]);
  },
  diamond(params) {
    drawMarkerUnitPolygon(params, [
      [0.5, 0],
      [1, 0.5],
      [0.5, 1],
      [0, 0.5]
    ]);
  },
  heart({ path, x, y, size }) {
    const r = size / 4;
    y = y + r / 2;
    path.arc(x - r, y - r, r, toRadians(130), toRadians(330));
    path.arc(x + r, y - r, r, toRadians(220), toRadians(50));
    path.lineTo(x, y + r);
    path.closePath();
  },
  pin({ path, x, y, size: s }) {
    const cx = 0.5;
    const cy = 0.5;
    path.moveTo(x + (0.891 - cx) * s, y + (0.391 - cy) * s);
    path.cubicCurveTo(
      x + (0.891 - cx) * s,
      y + (0.606 - cy) * s,
      x + (0.5 - cx) * s,
      y + (1 - cy) * s,
      x + (0.5 - cx) * s,
      y + (1 - cy) * s
    );
    path.cubicCurveTo(
      x + (0.5 - cx) * s,
      y + (1 - cy) * s,
      x + (0.109 - cx) * s,
      y + (0.606 - cy) * s,
      x + (0.109 - cx) * s,
      y + (0.391 - cy) * s
    );
    path.cubicCurveTo(
      x + (0.109 - cx) * s,
      y + (0.175 - cy) * s,
      x + (0.284 - cx) * s,
      y + (0 - cy) * s,
      x + (0.5 - cx) * s,
      y + (0 - cy) * s
    );
    path.cubicCurveTo(
      x + (0.716 - cx) * s,
      y + (0 - cy) * s,
      x + (0.891 - cx) * s,
      y + (0.175 - cy) * s,
      x + (0.891 - cx) * s,
      y + (0.391 - cy) * s
    );
    path.closePath();
  },
  plus(params) {
    drawMarkerUnitPolygon(params, [
      [1 / 3, 0],
      [2 / 3, 0],
      [2 / 3, 1 / 3],
      [1, 1 / 3],
      [1, 2 / 3],
      [2 / 3, 2 / 3],
      [2 / 3, 1],
      [1 / 3, 1],
      [1 / 3, 2 / 3],
      [0, 2 / 3],
      [0, 1 / 3],
      [1 / 3, 1 / 3]
    ]);
  },
  square({ path, x, y, size, pixelRatio }) {
    const hs = size / 2;
    path.moveTo(align(pixelRatio, x - hs), align(pixelRatio, y - hs));
    path.lineTo(align(pixelRatio, x + hs), align(pixelRatio, y - hs));
    path.lineTo(align(pixelRatio, x + hs), align(pixelRatio, y + hs));
    path.lineTo(align(pixelRatio, x - hs), align(pixelRatio, y + hs));
    path.closePath();
  },
  star({ path, x, y, size }) {
    const spikes = 5;
    const outerRadius = size / 2;
    const innerRadius = outerRadius / 2;
    const rotation = Math.PI / 2;
    for (let i = 0; i < spikes * 2; i++) {
      const radius = i % 2 === 0 ? outerRadius : innerRadius;
      const angle2 = i * Math.PI / spikes - rotation;
      const xCoordinate = x + Math.cos(angle2) * radius;
      const yCoordinate = y + Math.sin(angle2) * radius;
      path.lineTo(xCoordinate, yCoordinate);
    }
    path.closePath();
  },
  triangle(params) {
    drawMarkerUnitPolygon(params, [
      [0.5, 0],
      [1, 0.87],
      [0, 0.87]
    ]);
  }
};

// packages/ag-charts-community/src/chart/marker/marker.ts
var InternalMarker = class extends Path {
  constructor() {
    super(...arguments);
    this.shape = "square";
    this.x = 0;
    this.y = 0;
    this.size = 12;
  }
  // optimised field accessor
  isPointInPath(x, y) {
    return this.distanceSquared(x, y) <= 0;
  }
  get midPoint() {
    return { x: this.x, y: this.y };
  }
  distanceSquared(x, y) {
    const anchor = Marker.anchor(this.shape);
    const dx2 = x - this.x + (anchor.x - 0.5) * this.size;
    const dy2 = y - this.y + (anchor.y - 0.5) * this.size;
    const radius = this.size / 2;
    return Math.max(dx2 * dx2 + dy2 * dy2 - radius * radius, 0);
  }
  updatePath() {
    const { path, shape, x, y, size } = this;
    const pixelRatio = this.layerManager?.canvas?.pixelRatio ?? 1;
    const anchor = Marker.anchor(shape);
    const drawParams = {
      path,
      x: x - (anchor.x - 0.5) * size,
      y: y - (anchor.y - 0.5) * size,
      size,
      pixelRatio
    };
    path.clear();
    if (typeof shape === "string") {
      MARKER_SHAPES[shape](drawParams);
    } else if (typeof shape === "function") {
      shape(drawParams);
    }
  }
  computeBBox() {
    const { x, y, size } = this;
    const anchor = Marker.anchor(this.shape);
    return new BBox(x - size * anchor.x, y - size * anchor.y, size, size);
  }
  executeFill(ctx, path) {
    if (!path)
      return;
    return super.executeFill(ctx, path);
  }
  executeStroke(ctx, path) {
    if (!path)
      return;
    return super.executeStroke(ctx, path);
  }
};
__decorateClass([
  DeclaredSceneObjectChangeDetection({ equals: TRIPLE_EQ })
], InternalMarker.prototype, "shape", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], InternalMarker.prototype, "x", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], InternalMarker.prototype, "y", 2);
__decorateClass([
  DeclaredSceneChangeDetection({ convertor: Math.abs })
], InternalMarker.prototype, "size", 2);
var Marker = class extends Rotatable(Scalable(Translatable(InternalMarker))) {
  static anchor(shape) {
    if (shape === "pin") {
      return { x: 0.5, y: 1 };
    } else if (typeof shape === "function" && "anchor" in shape) {
      return shape.anchor;
    }
    return { x: 0.5, y: 0.5 };
  }
  constructor(options) {
    super(options);
    if (options?.shape != null) {
      this.shape = options.shape;
    }
  }
  /**
   * Optimised reset for animation hot paths.
   * Bypasses SceneChangeDetection decorators by writing directly to backing fields.
   *
   * This avoids per-property overhead from:
   * - Equality checks (comparing old vs new values)
   * - Change callbacks (triggering downstream updates)
   * - Object.keys() iteration
   *
   * A single markDirty() call at the end ensures the scene graph is properly invalidated.
   * WARNING: Only use for animation hot paths where performance is critical.
   */
  resetAnimationProperties(x, y, size, opacity, scalingX, scalingY) {
    this.__x = x;
    this.__y = y;
    this.__size = size;
    this.__opacity = opacity;
    this.resetScalingProperties(scalingX, scalingY, x, y);
    this.dirtyPath = true;
    this.markDirty();
  }
};

// packages/ag-charts-community/src/chart/legend/legendSymbol.ts
function legendSymbolSvg(symbol, size, lineSize = size * (5 / 3)) {
  const group = new Group();
  const markerStrokeWidth = Math.min(symbol.marker.strokeWidth ?? 1, 2);
  const lineStrokeWidth = symbol.line?.enabled ? Math.min(symbol.line.strokeWidth, 2) : 0;
  const width2 = Math.max(symbol.marker.enabled === false ? 0 : size, symbol.line == null ? 0 : lineSize);
  const height2 = Math.max(symbol.marker.enabled === false ? 0 : size, lineStrokeWidth);
  if (symbol.line?.enabled) {
    const { stroke: stroke3, strokeOpacity, lineDash } = symbol.line;
    const line = new Line();
    line.x1 = 0;
    line.y1 = height2 / 2;
    line.x2 = width2;
    line.y2 = height2 / 2;
    line.stroke = stroke3;
    line.strokeOpacity = strokeOpacity;
    line.strokeWidth = lineStrokeWidth;
    line.lineDash = lineDash;
    group.append(line);
  }
  if (symbol.marker.enabled !== false) {
    const { shape, fill, fillOpacity, stroke: stroke3, strokeOpacity, lineDash, lineDashOffset } = symbol.marker;
    const marker = new Marker();
    marker.shape = shape ?? "square";
    marker.size = size;
    marker.fill = fill;
    marker.fillOpacity = fillOpacity ?? 1;
    marker.stroke = stroke3;
    marker.strokeOpacity = strokeOpacity ?? 1;
    marker.strokeWidth = markerStrokeWidth;
    marker.lineDash = lineDash;
    marker.lineDashOffset = lineDashOffset ?? 0;
    const anchor = Marker.anchor(shape);
    const x = width2 / 2 + (anchor.x - 0.5) * size;
    const y = height2 / 2 + (anchor.y - 0.5) * size;
    const scale2 = size / (size + markerStrokeWidth);
    marker.x = x;
    marker.y = y;
    marker.scalingCenterX = x;
    marker.scalingCenterY = y;
    marker.scalingX = scale2;
    marker.scalingY = scale2;
    group.append(marker);
  }
  return Group.toSVG(group, width2, height2);
}

// packages/ag-charts-community/src/chart/tooltip/tooltipContent.ts
var DEFAULT_TOOLTIP_CLASS = "ag-charts-tooltip";
var DEFAULT_TOOLTIP_DARK_CLASS = "ag-charts-tooltip--dark";
function textOrSegmentsIsDefined(value) {
  if (value == null) {
    return false;
  } else if (Array.isArray(value)) {
    return value.some((segment) => textOrSegmentsIsDefined(segment.text));
  } else {
    return toTextString(value).trim() !== "";
  }
}
function isTooltipValueMissing(value, allowNull = false) {
  if (value == null)
    return !allowNull;
  return typeof value === "number" && !Number.isFinite(value);
}
function hasAllMissingData(content) {
  if (content.type === "raw")
    return false;
  if (!content.data || content.data.length === 0)
    return false;
  return content.data.every((datum) => datum.missing === true);
}
function aggregateTooltipContent(content) {
  const out = [];
  const groupedContents = /* @__PURE__ */ new Map();
  for (const item of content) {
    if (hasAllMissingData(item))
      continue;
    if (item.type === "structured") {
      const { heading } = item;
      const insertionTarget = textOrSegmentsIsDefined(heading) ? groupedContents.get(heading) : void 0;
      const groupedItem = { type: "structured", heading, items: [item] };
      if (insertionTarget == null) {
        groupedContents.set(heading, groupedItem);
        out.push(groupedItem);
      } else {
        insertionTarget.items.push(item);
      }
    } else {
      out.push(item);
    }
  }
  return out;
}
function tooltipContentAriaLabel(ungroupedContent) {
  const content = aggregateTooltipContent(ungroupedContent);
  const ariaLabel = [];
  for (const c of content) {
    if (c.type === "raw") {
      continue;
    }
    if (textOrSegmentsIsDefined(c.heading)) {
      ariaLabel.push(toPlainText(c.heading));
    }
    for (const i of c.items) {
      if (textOrSegmentsIsDefined(i.title)) {
        ariaLabel.push(toPlainText(i.title));
      }
      if (i.data) {
        for (const datum of i.data) {
          if (datum.missing === true)
            continue;
          ariaLabel.push(datum.label ?? datum.fallbackLabel, toPlainText(datum.value));
        }
      }
    }
  }
  return ariaLabel.filter((s) => s !== "").join("; ");
}
function dataHtml(label, value, inline) {
  let rowHtml = "";
  if (textOrSegmentsIsDefined(label)) {
    rowHtml += `<span class="${DEFAULT_TOOLTIP_CLASS}-label">${sanitizeHtml(label)}</span>`;
    rowHtml += " ";
    rowHtml += `<span class="${DEFAULT_TOOLTIP_CLASS}-value">${sanitizeHtml(value)}</span>`;
  } else {
    rowHtml += `<span class="${DEFAULT_TOOLTIP_CLASS}-label">${sanitizeHtml(value)}</span>`;
  }
  const rowClassNames = [`${DEFAULT_TOOLTIP_CLASS}-row`];
  if (inline)
    rowClassNames.push(`${DEFAULT_TOOLTIP_CLASS}-row--inline`);
  rowHtml = `<div class="${rowClassNames.join(" ")}">${rowHtml}</div>`;
  return rowHtml;
}
function tooltipRowContentHtml(content) {
  let html = "";
  if (content.data?.length && content.data.every((datum) => datum.missing === true)) {
    return html;
  }
  const titleDefined = textOrSegmentsIsDefined(content.title);
  const dataInline = !titleDefined && content.data?.length === 1;
  const symbol = content.symbol == null ? void 0 : legendSymbolSvg(content.symbol, 12);
  if (symbol != null && (titleDefined || content.data?.length)) {
    html += `<span class="${DEFAULT_TOOLTIP_CLASS}-symbol">${symbol}</span>`;
  }
  if (titleDefined) {
    html += `<span class="${DEFAULT_TOOLTIP_CLASS}-title">${sanitizeHtml(content.title)}</span>`;
    html += " ";
  }
  if (content.data) {
    for (const datum of content.data) {
      if (datum.missing === true)
        continue;
      html += dataHtml(datum.label ?? datum.fallbackLabel, toPlainText(datum.value), dataInline);
      html += " ";
    }
  }
  return html;
}
function tooltipPaginationContentHtml(localeManager, pagination) {
  if (localeManager == null || pagination.length === 1)
    return;
  const text2 = localeManager?.t("tooltipPaginationStatus", {
    index: pagination.index + 1,
    count: pagination.length
  });
  return `<div class="${DEFAULT_TOOLTIP_CLASS}-footer">${text2}</div>`;
}
function tooltipContentHtml(localeManager, content, mode, pagination) {
  const singleItem = content.items.length === 1 ? content.items[0] : void 0;
  let compact;
  let compactTitle;
  let compactFallbackLabel;
  switch (mode) {
    case "compact":
      compact = true;
      compactTitle = toPlainText(singleItem?.title);
      break;
    case "single":
      const headingDefined = textOrSegmentsIsDefined(content.heading);
      compact = singleItem != null && (!headingDefined || singleItem.title == null) && singleItem.data?.length === 1 && singleItem.data[0].label == null && singleItem.data[0].value != null;
      compactFallbackLabel = toPlainText(headingDefined ? content.heading : singleItem?.title);
      break;
    case "shared":
      compact = false;
  }
  let html = "";
  if (compact && singleItem != null) {
    if (textOrSegmentsIsDefined(compactTitle)) {
      html += `<span class="${DEFAULT_TOOLTIP_CLASS}-title">${sanitizeHtml(compactTitle)}</span>`;
    }
    if (singleItem.data) {
      for (const datum of singleItem.data) {
        if (datum.missing === true)
          continue;
        html += dataHtml(datum.label ?? compactFallbackLabel, toPlainText(datum.value), false);
        html += " ";
      }
    }
  } else {
    if (textOrSegmentsIsDefined(content.heading)) {
      html += `<span class="${DEFAULT_TOOLTIP_CLASS}-heading">${sanitizeHtml(toPlainText(content.heading))}</span>`;
      html += " ";
    }
    for (const item of content.items) {
      html += tooltipRowContentHtml(item);
    }
  }
  if (html.length === 0)
    return;
  const paginationContent = mode !== "compact" && pagination != null ? tooltipPaginationContentHtml(localeManager, pagination) : void 0;
  if (paginationContent + null) {
    html += paginationContent;
  }
  html = `<div class="${DEFAULT_TOOLTIP_CLASS}-content">${html.trimEnd()}</div>`;
  return html;
}
function tooltipPaginationHtml(localeManager, pagination) {
  const paginationContent = pagination == null ? void 0 : tooltipPaginationContentHtml(localeManager, pagination);
  if (paginationContent == null)
    return "";
  return `<div class="${DEFAULT_TOOLTIP_CLASS}-content">${paginationContent}</div>`;
}
function tooltipHtml(localeManager, content, mode, pagination) {
  const aggregatedContent = aggregateTooltipContent(content);
  if (aggregatedContent.length === 0)
    return;
  if (aggregatedContent.length === 1 && aggregatedContent[0].type === "structured") {
    return tooltipContentHtml(localeManager, aggregatedContent[0], mode, pagination);
  } else {
    const htmlRows = aggregatedContent.map((c) => {
      return c.type === "structured" ? tooltipContentHtml(localeManager, c, mode) : c.rawHtmlString;
    });
    if (pagination != null) {
      htmlRows.push(tooltipPaginationHtml(localeManager, pagination) ?? "");
    }
    return htmlRows.join("");
  }
}

// packages/ag-charts-community/src/chart/tooltip/tooltip.ts
var horizontalAlignments = {
  left: -1,
  "top-left": -1,
  "bottom-left": -1,
  top: 0,
  center: 0,
  bottom: 0,
  right: 1,
  "top-right": 1,
  "bottom-right": 1
};
var verticalAlignments = {
  "top-left": -1,
  top: -1,
  "top-right": -1,
  left: 0,
  center: 0,
  right: 0,
  "bottom-left": 1,
  bottom: 1,
  "bottom-right": 1
};
var arrowPositions = {
  left: 3 /* Right */,
  "top-left": void 0,
  "bottom-left": void 0,
  top: 2 /* Bottom */,
  center: void 0,
  bottom: 1 /* Top */,
  right: 0 /* Left */,
  "top-right": void 0,
  "bottom-right": void 0
};
var directionChecks = {
  top: 2 /* Vertical */,
  bottom: 2 /* Vertical */,
  left: 1 /* Horizontal */,
  right: 1 /* Horizontal */,
  "top-right": 3 /* Both */,
  "top-left": 3 /* Both */,
  "bottom-right": 3 /* Both */,
  "bottom-left": 3 /* Both */,
  center: 0 /* None */
};
var defaultPlacements = {
  pointer: "top",
  node: "top",
  chart: "top-left"
};
var TooltipPosition = class extends BaseProperties {
  constructor() {
    super(...arguments);
    /** The horizontal offset in pixels for the position of the tooltip. */
    this.xOffset = 0;
    /** The vertical offset in pixels for the position of the tooltip. */
    this.yOffset = 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], TooltipPosition.prototype, "xOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TooltipPosition.prototype, "yOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TooltipPosition.prototype, "anchorTo", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TooltipPosition.prototype, "placement", 2);
var Tooltip = class extends BaseProperties {
  constructor() {
    super();
    this.enabled = true;
    this.mode = "single";
    this.delay = 0;
    this.range = void 0;
    this.wrapping = "hyphenate";
    this.position = new TooltipPosition();
    this.pagination = false;
    this.darkTheme = false;
    this.bounds = "extended";
    this.cleanup = new CleanupRegistry();
    this.springAnimation = new SpringAnimation();
    this.enableInteraction = false;
    this.wrapTypes = ["always", "hyphenate", "on-space", "never"];
    this.sizeMonitor = new SizeMonitor();
    // Reading the element size is expensive, so cache the result
    this._elementSize = void 0;
    this._showTimeout = void 0;
    this.arrowPosition = void 0;
    this._visible = false;
    this.positionParams = void 0;
    this.localeManager = void 0;
    this.cleanup.register(this.springAnimation.events.on("update", this.updateTooltipPosition.bind(this)));
  }
  get interactive() {
    return this.enableInteraction;
  }
  setup(localeManager, domManager) {
    if ("togglePopover" in getWindow().HTMLElement.prototype) {
      this.element = domManager.addChild("tooltip-container", DEFAULT_TOOLTIP_CLASS);
      this.element.setAttribute("popover", "manual");
      this.element.className = DEFAULT_TOOLTIP_CLASS;
      this.element.style.positionAnchor = domManager.anchorName;
      this.sizeMonitor.observe(this.element, (size) => {
        this._elementSize = size;
        this.updateTooltipPosition();
      });
    }
    this.localeManager = localeManager;
    return () => {
      domManager.removeChild("tooltip-container", DEFAULT_TOOLTIP_CLASS);
      this.cleanup.flush();
      if (this.element) {
        this.sizeMonitor.unobserve(this.element);
      }
    };
  }
  isVisible() {
    return this._visible;
  }
  contains(node) {
    return this.element?.contains(node) ?? false;
  }
  updateTooltipPosition() {
    const { element: element2, _elementSize: elementSize, positionParams } = this;
    if (element2 == null || elementSize == null || positionParams == null)
      return;
    const { canvasRect, relativeRect, meta } = positionParams;
    const { x: canvasX, y: canvasY } = this.springAnimation;
    const anchorTo = meta.position?.anchorTo ?? "pointer";
    let placements2 = meta.position?.placement ?? defaultPlacements[anchorTo];
    if (!Array.isArray(placements2)) {
      placements2 = [placements2];
    }
    const xOffset = meta.position?.xOffset ?? 0;
    const yOffset = meta.position?.yOffset ?? 0;
    const minX = relativeRect.x;
    const minY = relativeRect.y;
    const maxX = relativeRect.width - elementSize.width - 1 + minX;
    const maxY = relativeRect.height - elementSize.height + minY;
    let i = 0;
    let placement;
    let position;
    let constrained = false;
    do {
      placement = placements2[i];
      i += 1;
      const tooltipBounds = this.getTooltipBounds({
        elementSize,
        placement,
        anchorTo,
        canvasX,
        canvasY,
        yOffset,
        xOffset,
        canvasRect
      });
      position = calculatePlacement(elementSize.width, elementSize.height, relativeRect, tooltipBounds);
      constrained = false;
      if (directionChecks[placement] & 1 /* Horizontal */) {
        constrained || (constrained = position.x < minX || position.x > maxX);
      }
      if (directionChecks[placement] & 2 /* Vertical */) {
        constrained || (constrained = position.y < minY || position.y > maxY);
      }
    } while (i < placements2.length && constrained);
    const left = clamp(minX, position.x, maxX);
    const top = clamp(minY, position.y, maxY);
    constrained || (constrained = left !== position.x || top !== position.y);
    const defaultShowArrow = anchorTo !== "chart" && !constrained && !xOffset && !yOffset;
    const showArrow = meta.showArrow ?? this.showArrow ?? defaultShowArrow;
    this.arrowPosition = showArrow ? arrowPositions[placement] : void 0;
    this.updateClassModifiers();
    element2.style.translate = `${left}px ${top}px`;
  }
  /**
   * Shows tooltip at the given event's coordinates.
   * If the `html` parameter is missing, moves the existing tooltip to the new position.
   */
  show(boundingRect, canvasRect, meta, content, pagination, instantly = false) {
    const { element: element2 } = this;
    if (element2 != null && content != null && content.length !== 0) {
      const html = tooltipHtml(this.localeManager, content, this.mode, this.pagination ? pagination : void 0);
      if (html == null) {
        element2.innerHTML = "";
        this.toggle(false);
        return;
      }
      element2.innerHTML = html;
    } else if (element2 == null || element2.innerHTML === "") {
      this.toggle(false);
      return;
    }
    const relativeRect = {
      x: boundingRect.x - canvasRect.x,
      y: boundingRect.y - canvasRect.y,
      width: boundingRect.width,
      height: boundingRect.height
    };
    this.positionParams = {
      canvasRect,
      relativeRect,
      meta
    };
    const anchorTo = meta.position?.anchorTo ?? "pointer";
    switch (anchorTo) {
      case "node":
        this.springAnimation.update(meta.nodeCanvasX ?? meta.canvasX, meta.nodeCanvasY ?? meta.canvasY);
        break;
      case "pointer":
        this.springAnimation.update(meta.canvasX, meta.canvasY);
        break;
      case "chart":
        this.springAnimation.reset();
    }
    if (meta.enableInteraction) {
      this.enableInteraction = true;
      element2.style.pointerEvents = "auto";
      element2.removeAttribute("aria-hidden");
      element2.tabIndex = -1;
    } else {
      this.enableInteraction = false;
      element2.style.pointerEvents = "none";
      element2.setAttribute("aria-hidden", "true");
      element2.removeAttribute("tabindex");
    }
    element2.style.setProperty("--top", `${canvasRect.top}px`);
    element2.style.setProperty("--left", `${canvasRect.left}px`);
    this.updateClassModifiers();
    this.toggle(true, instantly);
  }
  hide() {
    this.toggle(false);
  }
  maybeEnterInteractiveTooltip({ relatedTarget }, callback2) {
    const { interactive, interactiveLeave, enabled, element: element2 } = this;
    if (element2 == null)
      return false;
    if (interactiveLeave)
      return true;
    const isEntering = interactive && enabled && this.isVisible() && isNode(relatedTarget) && this.contains(relatedTarget);
    if (isEntering) {
      this.interactiveLeave = {
        callback: callback2,
        listener: (popoverEvent) => {
          const isLeaving = popoverEvent.relatedTarget == null || isNode(popoverEvent.relatedTarget) && !this.contains(popoverEvent.relatedTarget);
          if (isLeaving) {
            this.popInteractiveLeaveCallback();
          }
        }
      };
      element2.addEventListener("focusout", this.interactiveLeave.listener);
      element2.addEventListener("mouseout", this.interactiveLeave.listener);
    }
    return isEntering;
  }
  popInteractiveLeaveCallback() {
    const { interactiveLeave, element: element2 } = this;
    this.interactiveLeave = void 0;
    if (interactiveLeave) {
      if (element2) {
        element2.removeEventListener("focusout", interactiveLeave.listener);
        element2.removeEventListener("mouseout", interactiveLeave.listener);
      }
      interactiveLeave.callback();
    }
  }
  toggle(visible, instantly = false) {
    const { delay } = this;
    if (visible && delay > 0 && !instantly) {
      this._showTimeout ?? (this._showTimeout = setTimeout(() => {
        this._showTimeout = void 0;
        this.toggleCallback(true);
      }, delay));
    } else {
      clearTimeout(this._showTimeout);
      this._showTimeout = void 0;
      this.toggleCallback(visible);
    }
  }
  toggleCallback(visible) {
    if (!this.element?.isConnected)
      return;
    if (this._visible === visible)
      return;
    this._visible = visible;
    this.element.togglePopover(visible);
    if (visible) {
      this.updateTooltipPosition();
    } else {
      this.springAnimation.reset();
      this.popInteractiveLeaveCallback();
    }
  }
  updateClassModifiers() {
    if (!this.element?.isConnected)
      return;
    const { classList } = this.element;
    const toggleClass = (name, include) => classList.toggle(`${DEFAULT_TOOLTIP_CLASS}--${name}`, include);
    toggleClass("no-interaction", !this.enableInteraction);
    toggleClass("arrow-top", this.arrowPosition === 1 /* Top */);
    toggleClass("arrow-right", this.arrowPosition === 3 /* Right */);
    toggleClass("arrow-bottom", this.arrowPosition === 2 /* Bottom */);
    toggleClass("arrow-left", this.arrowPosition === 0 /* Left */);
    toggleClass("compact", this.mode === "compact");
    classList.toggle(DEFAULT_TOOLTIP_DARK_CLASS, this.darkTheme);
    for (const wrapType of this.wrapTypes) {
      classList.toggle(`${DEFAULT_TOOLTIP_CLASS}--wrap-${wrapType}`, wrapType === this.wrapping);
    }
  }
  getTooltipBounds(opts) {
    const { elementSize, anchorTo, placement, canvasX, canvasY, yOffset, xOffset, canvasRect } = opts;
    const { width: tooltipWidth, height: tooltipHeight } = elementSize;
    const bounds = { width: tooltipWidth, height: tooltipHeight };
    if (anchorTo === "node" || anchorTo === "pointer") {
      const horizontalAlignment = horizontalAlignments[placement];
      const verticalAlignment = verticalAlignments[placement];
      bounds.top = canvasY + yOffset + tooltipHeight * (verticalAlignment - 1) / 2 + 8 * verticalAlignment;
      bounds.left = canvasX + xOffset + tooltipWidth * (horizontalAlignment - 1) / 2 + 8 * horizontalAlignment;
      return bounds;
    }
    switch (placement) {
      case "top": {
        bounds.top = yOffset;
        bounds.left = canvasRect.width / 2 - tooltipWidth / 2 + xOffset;
        return bounds;
      }
      case "right": {
        bounds.top = canvasRect.height / 2 - tooltipHeight / 2 + yOffset;
        bounds.left = canvasRect.width - tooltipWidth + xOffset;
        return bounds;
      }
      case "left": {
        bounds.top = canvasRect.height / 2 - tooltipHeight / 2 + yOffset;
        bounds.left = xOffset;
        return bounds;
      }
      case "bottom": {
        bounds.top = canvasRect.height - tooltipHeight + yOffset;
        bounds.left = canvasRect.width / 2 - tooltipWidth / 2 + xOffset;
        return bounds;
      }
      case "top-left": {
        bounds.top = yOffset;
        bounds.left = xOffset;
        return bounds;
      }
      case "top-right": {
        bounds.top = yOffset;
        bounds.left = canvasRect.width - tooltipWidth + xOffset;
        return bounds;
      }
      case "bottom-right": {
        bounds.top = canvasRect.height - tooltipHeight + yOffset;
        bounds.left = canvasRect.width - tooltipWidth + xOffset;
        return bounds;
      }
      case "bottom-left": {
        bounds.top = canvasRect.height - tooltipHeight + yOffset;
        bounds.left = xOffset;
        return bounds;
      }
    }
    return bounds;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], Tooltip.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Tooltip.prototype, "mode", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Tooltip.prototype, "showArrow", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Tooltip.prototype, "delay", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Tooltip.prototype, "range", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Tooltip.prototype, "wrapping", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Tooltip.prototype, "position", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Tooltip.prototype, "pagination", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Tooltip.prototype, "darkTheme", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Tooltip.prototype, "bounds", 2);

// packages/ag-charts-community/src/chart/series/pickManager.ts
function getItemId(node) {
  if (node.datum.itemId !== void 0) {
    return node.datum.itemId;
  } else if (typeof node.datum.datumIndex === "number") {
    return node.datum.datumIndex;
  } else {
    return JSON.stringify(node.datum.datumIndex);
  }
}
function pickedNodesEqual(a, b) {
  return a.series === b.series && objectsEqual(a.datumIndex, b.datumIndex);
}
function indexOf(candidates, node) {
  return node == void 0 ? -1 : candidates.findIndex((c) => pickedNodesEqual(c, node));
}
var PickManager = class {
  constructor(activeManager, tooltipProperties, focusState) {
    this.activeManager = activeManager;
    this.tooltipProperties = tooltipProperties;
    this.focusState = focusState;
    this.candidates = [];
    this.activeState = new StateTracker();
  }
  getActive() {
    return this.activeState.stateValue();
  }
  clear() {
    this.activeState.clear();
    this.lastNotifiedActive = void 0;
    this.candidates.length = 0;
    this.pendingPickedNodes = void 0;
  }
  setSource(source, node) {
    if (node === void 0) {
      this.activeState.delete(source);
    } else {
      this.activeState.set(source, node);
    }
    this.syncActiveManager();
  }
  syncActiveManager() {
    const resolved = this.getActive();
    const prev = this.lastNotifiedActive;
    if (resolved === prev)
      return;
    if (resolved !== void 0 && prev !== void 0 && pickedNodesEqual(resolved, prev))
      return;
    this.lastNotifiedActive = resolved;
    if (resolved === void 0) {
      this.activeManager.clear();
    } else {
      const seriesId = resolved.series.id;
      const itemId = getItemId(resolved);
      this.activeManager.update({ type: "series-node", seriesId, itemId }, resolved.datum);
    }
  }
  popPendingPickedNodes() {
    const result = this.pendingPickedNodes;
    this.pendingPickedNodes = void 0;
    return result;
  }
  // Some user interactive (e.g. mouseleave, blur) has cleared the active datum.
  onClearUI() {
    this.activeManager.clear();
    this.clear();
  }
  // Active datum was cleared by ActiveManager (`setState` or legend).
  onClearAPI() {
    this.clear();
  }
  onPickedNodesHighlight(pickedNodes) {
    if (pickedNodes !== void 0) {
      const previousActive = this.getActive();
      if (this.tooltipProperties.pagination && previousActive !== void 0) {
        const tooltipMatch = pickedNodes.matches.find((m) => pickedNodesEqual(m, previousActive));
        if (tooltipMatch) {
          return tooltipMatch;
        }
      }
    }
    const node = pickedNodes?.matches[0];
    this.setSource("highlight", node);
    return node;
  }
  onPickedNodesTooltip(pickedNodes) {
    if (pickedNodes !== void 0 && this.tooltipProperties.pagination) {
      const previous = this.getActive();
      const nextCandidates = pickedNodes.matches;
      this.candidates = nextCandidates;
      let nextIndex = indexOf(nextCandidates, previous);
      if (nextIndex === -1)
        nextIndex = 0;
      const node2 = nextCandidates[nextIndex];
      this.setSource("tooltip", node2);
      const paginationState = { index: nextIndex, length: nextCandidates.length };
      return { active: node2, paginationState };
    }
    const node = pickedNodes?.matches[0];
    this.setSource("tooltip", node);
    return { active: node };
  }
  onPickedNodesFocus(pickedFocus) {
    const { series } = this.focusState;
    this.clear();
    if (series !== void 0 && pickedFocus !== void 0) {
      const { datum, datumIndex } = pickedFocus;
      this.setSource("focus", { series, datum, datumIndex });
    }
  }
  onPickedNodesAPI(debouncedPickedNodes) {
    this.pendingPickedNodes = debouncedPickedNodes;
    return debouncedPickedNodes.matches[0];
  }
  onPickedNodesAPIDebounced() {
    return { active: this.onPickedNodesHighlight(this.popPendingPickedNodes()) };
  }
  nextCandidate() {
    if (this.tooltipProperties.pagination) {
      const { candidates } = this;
      const previous = this.getActive();
      const hoverIndex = previous == null ? -1 : candidates.findIndex((c) => pickedNodesEqual(c, previous));
      if (hoverIndex === -1)
        return { active: void 0, paginationState: void 0 };
      let nextIndex = hoverIndex + 1;
      if (nextIndex >= candidates.length) {
        nextIndex = 0;
      }
      const node = candidates[nextIndex];
      this.setSource("tooltip", node);
      const paginationState = { index: nextIndex, length: this.candidates.length };
      return { active: node, paginationState };
    }
    return { active: this.getActive() };
  }
};

// packages/ag-charts-community/src/chart/series/seriesAreaManager.ts
var SeriesAreaManager = class extends BaseManager {
  constructor(chart) {
    super();
    this.chart = chart;
    this.id = createId(this);
    this.series = [];
    this.announceMode = "when-changed";
    this.highlight = {
      /** Last received event that still needs to be applied. */
      pendingHoverEvent: void 0,
      /** Last applied event. */
      appliedHoverEvent: void 0,
      /** Last applied event, which has been temporarily stashed during the main chart update cycle. */
      stashedHoverEvent: void 0
    };
    this.tooltip = {
      lastHover: void 0
    };
    this.activeState = {
      lastActive: void 0
    };
    /**
     * A11y Requirements for Tooltip/Highlight (see AG-13051 for details):
     *
     *   -   When the series-area is blurred, allow the mouse to update the tooltip/highlight.
     *
     *   -   When the series-area receives a `focus` event, use `:focus-visible` to guess the input device.
     *       (this is decided by the browser).
     *
     *   -   For keyboard users, `focus` and `keydown` events always updates & shows the tooltip/highlight on
     *       the currently (or newly) focused datum.
     *
     *   -   For keyboard users, `mousemove` events update the tooltip/highlight iff `pickNode` finds a match
     *       for the mouse event offsets.
     */
    this.hoverDevice = "pointer";
    this.focus = {
      sortedSeries: [],
      series: void 0,
      seriesIndex: 0,
      datumIndex: 0,
      datum: void 0
    };
    this.cachedTooltipContent = void 0;
    this.hoverScheduler = debouncedAnimationFrame(() => {
      if (this.hoverDevice === "setState") {
        return this.handleHoverFromState();
      }
      if (!this.tooltip.lastHover && !this.highlight.pendingHoverEvent)
        return;
      if (this.chart.getUpdateType() <= 7 /* SERIES_UPDATE */) {
        this.hoverScheduler.schedule();
        return;
      }
      if (this.highlight.pendingHoverEvent) {
        this.handleHoverHighlight(false);
      }
      if (this.tooltip.lastHover) {
        this.handleHoverTooltip(this.tooltip.lastHover, false);
      }
    });
    this.pickManager = new PickManager(chart.ctx.activeManager, chart.tooltip, this.focus);
    const initialAltText = chart.ctx.localeManager.t("ariaInitSeriesArea");
    const label1 = chart.ctx.domManager.addChild("series-area", "series-area-aria-label1");
    const label2 = chart.ctx.domManager.addChild("series-area", "series-area-aria-label2");
    this.swapChain = new FocusSwapChain(label1, label2, "img", initialAltText);
    this.swapChain.addListener("blur", (event) => this.onBlur(event));
    this.swapChain.addListener("focus", () => this.onFocus());
    if (chart.ctx.domManager.mode === "normal") {
      this.focusIndicator = new FocusIndicator(this.swapChain);
      this.focusIndicator.overrideFocusVisible(chart.mode === "integrated" ? false : void 0);
    }
    const { seriesDragInterpreter, seriesWidget, containerWidget } = chart.ctx.widgets;
    seriesWidget.setTabIndex(-1);
    this.cleanup.register(
      () => chart.ctx.domManager.removeChild("series-area", "series-area-aria-label1"),
      () => chart.ctx.domManager.removeChild("series-area", "series-area-aria-label2"),
      seriesWidget.addListener("focus", () => this.swapChain.focus({ preventScroll: true })),
      seriesWidget.addListener("mousemove", (event) => this.onHover(event, seriesWidget)),
      seriesWidget.addListener("wheel", (event) => this.onWheel(event)),
      seriesWidget.addListener("mouseleave", (event) => this.onLeave(event)),
      seriesWidget.addListener("keydown", (event) => this.onKeyDown(event)),
      seriesWidget.addListener("contextmenu", (event, current) => this.onContextMenu(event, current)),
      containerWidget.addListener("contextmenu", (event, current) => this.onContextMenu(event, current)),
      containerWidget.addListener("click", (event, current) => this.onClick(event, current)),
      containerWidget.addListener("dblclick", (event, current) => this.onClick(event, current)),
      chart.ctx.animationManager.addListener("animation-start", () => this.onAnimationStart()),
      chart.ctx.eventsHub.on("active:load-memento", (event) => this.onActiveLoadMemento(event)),
      chart.ctx.eventsHub.on("active:update", (event) => this.onActiveUpdate(event)),
      chart.ctx.eventsHub.on("dom:resize", () => this.clearAll()),
      chart.ctx.eventsHub.on("highlight:change", (event) => this.changeHighlightDatum(event)),
      chart.ctx.eventsHub.on("layout:complete", (event) => this.layoutComplete(event)),
      chart.ctx.updateService.addListener("pre-scene-render", () => this.preSceneRender()),
      chart.ctx.updateService.addListener("update-complete", () => this.updateComplete()),
      chart.ctx.eventsHub.on("zoom:change-complete", () => this.clearAll()),
      chart.ctx.eventsHub.on("zoom:pan-start", () => this.clearAll())
    );
    if (seriesDragInterpreter) {
      this.cleanup.register(
        seriesDragInterpreter.events.on("drag-move", (event) => this.onDragMove(event, seriesWidget)),
        seriesDragInterpreter.events.on("click", (event) => this.onClick(event, seriesWidget)),
        seriesDragInterpreter.events.on("dblclick", (event) => this.onClick(event, seriesWidget))
      );
    }
  }
  get bbox() {
    return (this.seriesRect ?? BBox.zero).clone();
  }
  isState(allowedStates) {
    return this.chart.ctx.interactionManager.isState(allowedStates);
  }
  isIgnoredTouch(event) {
    if (event.device !== "touch" || event.type === "click")
      return false;
    if (this.chart.ctx.chartService.touch.dragAction === "hover")
      return false;
    if (this.chart.ctx.chartService.touch.dragAction === "drag") {
      if (this.isState(18 /* AnnotationsMoveable */)) {
        return false;
      }
    }
    return true;
  }
  dataChanged() {
    var _a;
    this.cachedTooltipContent = void 0;
    if (this.highlight.appliedHoverEvent) {
      (_a = this.highlight).stashedHoverEvent ?? (_a.stashedHoverEvent = this.highlight.appliedHoverEvent);
      this.clearHighlight();
    }
    if (this.hoverDevice !== "setState") {
      this.chart.ctx.tooltipManager.removeTooltip(this.id);
      this.focusIndicator?.clear();
    }
  }
  preSceneRender() {
    if (this.highlight.stashedHoverEvent != null) {
      this.highlight.pendingHoverEvent = this.tooltip.lastHover ?? this.highlight.stashedHoverEvent;
      this.highlight.stashedHoverEvent = void 0;
      this.handleHoverHighlight(true);
    }
    if (this.tooltip.lastHover != null) {
      this.handleHoverTooltip(this.tooltip.lastHover, true);
    }
    if (this.hoverDevice === "setState") {
      this.refreshSetState();
    }
  }
  updateComplete() {
    if (this.isState(68 /* Focusable */) && this.focusIndicator?.isFocusVisible()) {
      if (this.announceMode !== "always") {
        this.announceMode = "never";
      }
      this.handleFocus(0, 0);
    }
  }
  update(type, opts) {
    this.chart.ctx.updateService.update(type, opts);
  }
  seriesChanged(series) {
    this.focus.sortedSeries = [...series].sort((a, b) => {
      let fpA = a.properties.focusPriority ?? Infinity;
      let fpB = b.properties.focusPriority ?? Infinity;
      if (fpA === fpB) {
        [fpA, fpB] = [a.declarationOrder, b.declarationOrder];
      }
      if (fpA < fpB) {
        return -1;
      } else if (fpA > fpB) {
        return 1;
      }
      return 0;
    });
    this.series = series;
  }
  layoutComplete(event) {
    this.seriesRect = event.series.rect;
    this.hoverRect = event.series.rect;
    this.chart.ctx.widgets.seriesWidget.setBounds(event.series.rect);
    if (this.chart.ctx.domManager.mode === "normal") {
      this.chart.ctx.widgets.chartWidget.setBounds(event.chart);
    }
  }
  onAnimationStart() {
    if (this.hoverDevice !== "setState") {
      this.clearAll();
    }
  }
  onContextMenu(event, current) {
    const { sourceEvent } = event;
    if (sourceEvent.currentTarget != current.getElement())
      return;
    if (current !== this.chart.ctx.widgets.seriesWidget) {
      if (this.isState(72 /* ContextMenuable */)) {
        const { currentX: canvasX2, currentY: canvasY2 } = event;
        this.chart.ctx.contextMenuRegistry.dispatchContext(
          "always",
          { widgetEvent: event, canvasX: canvasX2, canvasY: canvasY2 },
          void 0
        );
      }
      return;
    }
    let pickedNode;
    let position;
    if (this.focusIndicator?.isFocusVisible()) {
      pickedNode = this.chart.ctx.highlightManager.getActiveHighlight();
      if (pickedNode && this.seriesRect && pickedNode.midPoint) {
        position = Transformable.toCanvasPoint(
          pickedNode.series.contentGroup,
          pickedNode.midPoint.x,
          pickedNode.midPoint.y
        );
      }
    } else if (this.isState(72 /* ContextMenuable */)) {
      const pick2 = this.pickNodes({ x: event.currentX, y: event.currentY }, "context-menu");
      if (pick2) {
        this.chart.ctx.highlightManager.updateHighlight(this.id);
        pickedNode = pick2.matches[0].datum;
      }
    }
    const pickedSeries = pickedNode?.series;
    this.clearAll();
    const canvasX = event.currentX + current.cssLeft();
    const canvasY = event.currentY + current.cssTop();
    const { datumIndex } = pickedNode ?? {};
    if (pickedSeries && pickedNode && datumIndex != null) {
      this.chart.ctx.contextMenuRegistry.dispatchContext(
        "series-node",
        { widgetEvent: event, canvasX, canvasY },
        { pickedSeries, pickedNode: { ...pickedNode, datumIndex } },
        position
      );
    } else {
      this.chart.ctx.contextMenuRegistry.dispatchContext(
        "series-area",
        { widgetEvent: event, canvasX, canvasY },
        void 0,
        position
      );
    }
  }
  onLeave(event) {
    if (!this.isState(82 /* Clickable */))
      return;
    const relatedTarget = event.sourceEvent.relatedTarget;
    if (relatedTarget?.className === "ag-charts-text-input__textarea") {
      return;
    }
    if (this.maybeEnterInteractiveTooltip(event.sourceEvent)) {
      return;
    }
    this.chart.ctx.domManager.updateCursor(this.id);
    if (this.hoverDevice !== "keyboard")
      this.clearAll(true);
  }
  onWheel(_event) {
    if (!this.isState(82 /* Clickable */))
      return;
    this.focusIndicator?.overrideFocusVisible(false);
    this.hoverDevice = "pointer";
  }
  onDragMove(event, current) {
    if (!this.isState(82 /* Clickable */))
      return;
    this.focusIndicator?.overrideFocusVisible(false);
    this.onHoverLikeEvent(event, current);
  }
  onHover(event, current) {
    if (!this.isState(82 /* Clickable */))
      return;
    this.onHoverLikeEvent(event, current);
  }
  onHoverLikeEvent(event, current) {
    if (this.isIgnoredTouch(event))
      return;
    if (event.device === "touch" && this.chart.ctx.chartService.touch.dragAction === "hover") {
      event.sourceEvent.preventDefault();
    }
    if (current !== this.chart.ctx.widgets.seriesWidget)
      return;
    this.tooltip.lastHover = event;
    this.hoverDevice = "pointer";
    this.highlight.pendingHoverEvent = event;
    this.hoverScheduler.schedule();
    let pick2;
    if (this.isState(64 /* Default */)) {
      const { currentX: x, currentY: y } = event;
      pick2 = this.pickNodes({ x, y }, "event");
      const matches = pick2?.matches;
      const found = matches?.[0];
      if (found?.series.hasEventListener("seriesNodeClick") || found?.series.hasEventListener("seriesNodeDoubleClick") || matches != null && matches.length > 1 && this.chart.tooltip.pagination) {
        this.chart.ctx.domManager.updateCursor(this.id, "pointer");
      } else {
        this.chart.ctx.domManager.updateCursor(this.id);
      }
    }
    const consumed = Boolean(pick2?.matches.length);
    this.emitSeriesAreaHoverEvent(event, consumed);
  }
  onClick(event, current) {
    if (event.device === "keyboard") {
      return;
    }
    if (current === this.chart.ctx.widgets.seriesWidget && this.chart.ctx.animationManager.isActive()) {
      this.chart.ctx.animationManager.skipCurrentBatch();
    }
    if (event.device === "touch" && current === this.chart.ctx.widgets.seriesWidget) {
      this.swapChain.focus({ preventScroll: true });
    }
    if (!this.isState(82 /* Clickable */))
      return;
    if (current === this.chart.ctx.widgets.seriesWidget) {
      if (!current.getElement().contains(event.sourceEvent.target)) {
        return;
      }
    } else if (event.sourceEvent.target != current.getElement()) {
      return;
    }
    this.focusIndicator?.overrideFocusVisible(false);
    this.onHoverLikeEvent(event, current);
    const isSeriesWidget = current === this.chart.ctx.widgets.seriesWidget;
    if (!this.isState(64 /* Default */)) {
      if (isSeriesWidget) {
        this.emitSeriesAreaClickEvent(event, false);
      }
      return;
    }
    if (isSeriesWidget) {
      const consumed = this.checkSeriesNodeClick(event);
      if (consumed) {
        this.emitSeriesAreaClickEvent(event, true);
        this.update(7 /* SERIES_UPDATE */);
        event.sourceEvent.preventDefault();
        return;
      }
      this.emitSeriesAreaClickEvent(event, false);
    }
    const newEvent = { type: event.type === "click" ? "click" : "doubleClick", event: event.sourceEvent };
    this.chart.fireEvent(newEvent);
  }
  emitSeriesAreaHoverEvent(event, consumed) {
    const { canvasX, canvasY } = this.toCanvasCoordinates(event);
    const payload = { canvasX, canvasY, consumed, sourceEvent: event.sourceEvent };
    this.chart.ctx.eventsHub.emit("series-area:hover", payload);
  }
  emitSeriesAreaClickEvent(event, consumed) {
    if (!("currentX" in event))
      return;
    const { canvasX, canvasY } = this.toCanvasCoordinates(event);
    const payload = { canvasX, canvasY, consumed, sourceEvent: event.sourceEvent };
    this.chart.ctx.eventsHub.emit("series-area:click", payload);
  }
  toCanvasCoordinates(event) {
    return {
      canvasX: event.currentX + (this.hoverRect?.x ?? this.seriesRect?.x ?? 0),
      canvasY: event.currentY + (this.hoverRect?.y ?? this.seriesRect?.y ?? 0)
    };
  }
  onFocus() {
    if (!this.isState(68 /* Focusable */))
      return;
    this.hoverDevice = this.focusIndicator?.isFocusVisible(true) ? "keyboard" : "pointer";
    this.handleFocus(0, 0);
  }
  onBlur(event) {
    if (!this.isState(68 /* Focusable */))
      return;
    this.hoverDevice = "pointer";
    if (!this.maybeEnterInteractiveTooltip(event)) {
      this.clearAll(true);
    }
    this.focusIndicator?.overrideFocusVisible(void 0);
  }
  onKeyDown(widgetEvent) {
    if (!this.isState(86 /* Keyable */))
      return;
    const action = mapKeyboardEventToAction(widgetEvent.sourceEvent);
    if (action?.activatesFocusIndicator === false) {
      this.focusIndicator?.overrideFocusVisible(this.hoverDevice === "keyboard");
    }
    switch (action?.name) {
      case "redo":
        return this.chart.ctx.eventsHub.emit("series:redo", null);
      case "undo":
        return this.chart.ctx.eventsHub.emit("series:undo", null);
      case "zoomin":
        return this.chart.ctx.eventsHub.emit("series:keynav-zoom", { delta: 1, widgetEvent });
      case "zoomout":
        return this.chart.ctx.eventsHub.emit("series:keynav-zoom", { delta: -1, widgetEvent });
      case "arrowup":
        return this.onArrow(-1, 0, widgetEvent);
      case "arrowdown":
        return this.onArrow(1, 0, widgetEvent);
      case "arrowleft":
        return this.onArrow(0, -1, widgetEvent);
      case "arrowright":
        return this.onArrow(0, 1, widgetEvent);
      case "submit":
        return this.onSubmit(widgetEvent);
    }
  }
  onArrow(seriesIndexDelta, datumIndexDelta, event) {
    if (!this.isState(68 /* Focusable */))
      return;
    this.hoverDevice = "keyboard";
    this.focusIndicator?.overrideFocusVisible(true);
    this.focus.seriesIndex += seriesIndexDelta;
    this.focus.datumIndex += datumIndexDelta;
    this.handleFocus(seriesIndexDelta, datumIndexDelta);
    event.sourceEvent.preventDefault();
    this.chart.ctx.eventsHub.emit("series:focus-change", null);
  }
  onSubmit(event) {
    if (!this.isState(68 /* Focusable */))
      return;
    const { series, datum } = this.focus;
    const sourceEvent = event.sourceEvent;
    if (series != null && datum != null) {
      series.fireNodeClickEvent(sourceEvent, datum);
    } else {
      this.chart.fireEvent({
        type: "click",
        event: sourceEvent
      });
    }
    sourceEvent.preventDefault();
  }
  checkSeriesNodeClick(event) {
    var _a;
    const pickedNodes = this.pickNodes({ x: event.currentX, y: event.currentY }, "event");
    const updated = this.pickManager.onPickedNodesTooltip(pickedNodes);
    if (pickedNodes === void 0 || updated.active === void 0)
      return false;
    const { series, datum } = updated.active;
    const distance2 = updated.paginationState == null ? pickedNodes.distance : 0;
    if (event.type === "click") {
      const defaultBehavior = series.fireNodeClickEvent(event.sourceEvent, datum);
      if (defaultBehavior) {
        const next = this.pickManager.nextCandidate();
        if (next.active !== void 0) {
          const { canvasX, canvasY } = this.toCanvasCoordinates(event);
          (_a = this.highlight).pendingHoverEvent ?? (_a.pendingHoverEvent = this.highlight.appliedHoverEvent);
          this.handleHoverHighlight(false);
          this.showTooltip(next.active, canvasX, canvasY, next.paginationState);
        }
      }
      return true;
    }
    if (event.type === "dblclick") {
      event.preventZoomDblClick = distance2 === 0;
      series.fireNodeDoubleClickEvent(event.sourceEvent, datum);
      return true;
    }
    return false;
  }
  handleFocus(seriesIndexDelta, datumIndexDelta) {
    const overlayFocus = this.chart.overlays.getFocusInfo(this.chart.ctx.localeManager);
    if (overlayFocus == null) {
      if (this.handleSeriesFocus(seriesIndexDelta, datumIndexDelta) === 0 /* SUCCESS */) {
        this.announceMode = "when-changed";
      } else {
        this.announceMode = "always";
      }
    } else {
      this.focusIndicator?.update(overlayFocus.rect, this.seriesRect, false);
      this.swapChain.update(overlayFocus.text);
      this.announceMode = "always";
    }
  }
  handleSeriesFocus(otherIndexDelta, datumIndexDelta) {
    if (this.chart.chartType === "standalone") {
      return this.handleSoloSeriesFocus(otherIndexDelta, datumIndexDelta);
    }
    const { focus } = this;
    const visibleSeries = focus.sortedSeries.filter((s) => s.visible && s.focusable);
    if (visibleSeries.length === 0)
      return 1 /* SERIES_NOT_FOUND */;
    const oldDatumIndex = focus.datumIndex - datumIndexDelta;
    const oldOtherIndex = focus.seriesIndex - otherIndexDelta;
    focus.seriesIndex = clamp(0, focus.seriesIndex, visibleSeries.length - 1);
    focus.series = visibleSeries[focus.seriesIndex];
    const datumIndex = this.focus.datumIndex;
    const otherIndex = this.focus.seriesIndex;
    return this.updatePickedFocus(
      datumIndex,
      datumIndexDelta,
      oldDatumIndex,
      otherIndex,
      otherIndexDelta,
      oldOtherIndex
    );
  }
  handleSoloSeriesFocus(otherIndexDelta, datumIndexDelta) {
    this.focus.series = this.focus.sortedSeries[0];
    const datumIndex = this.focus.datumIndex;
    const otherIndex = this.focus.seriesIndex;
    const oldDatumIndex = this.focus.datumIndex - datumIndexDelta;
    const oldOtherIndex = this.focus.seriesIndex - otherIndexDelta;
    return this.updatePickedFocus(
      datumIndex,
      datumIndexDelta,
      oldDatumIndex,
      otherIndex,
      otherIndexDelta,
      oldOtherIndex
    );
  }
  pickFocus(series, opts) {
    const pick2 = series.pickFocus(opts);
    if (this.hoverDevice === "keyboard") {
      this.pickManager.onPickedNodesFocus(pick2);
    }
    return pick2;
  }
  updatePickedFocus(datumIndex, datumIndexDelta, oldDatumIndex, otherIndex, otherIndexDelta, oldOtherIndex) {
    const { focus, hoverRect, seriesRect } = this;
    if (focus.series == null || hoverRect == null)
      return 1 /* SERIES_NOT_FOUND */;
    const focusInputs = { datumIndex, datumIndexDelta, otherIndex, otherIndexDelta, seriesRect };
    const pick2 = this.pickFocus(focus.series, focusInputs);
    if (!pick2)
      return 2 /* DATUM_NOT_FOUND */;
    const { datum } = pick2;
    focus.datum = datum;
    focus.datumIndex = pick2.datumIndex;
    if (pick2.otherIndex != null) {
      focus.seriesIndex = pick2.otherIndex;
    }
    if (this.focusIndicator?.isFocusVisible()) {
      this.chart.ctx.animationManager.reset();
      const focusBBox = getPickedFocusBBox(pick2);
      const { x, y } = focusBBox.computeCenter();
      if (!hoverRect.containsPoint(x, y)) {
        const panSuccess = this.chart.ctx.zoomManager.panToBBox(hoverRect, focusBBox);
        if (panSuccess) {
          return 3 /* PAN_REQUIRED */;
        }
      }
      const { x1, x2, y1, y2 } = vector4_exports.from(focusBBox);
      const nw = hoverRect.containsPoint(x1, y1);
      const ne = hoverRect.containsPoint(x2, y1);
      const sw = hoverRect.containsPoint(x1, y2);
      const se = hoverRect.containsPoint(x2, y2);
      if (!(nw || ne || sw || se)) {
        const hoverBounds = vector4_exports.from(hoverRect);
        pick2.movedBounds = focusBBox.clone();
        if (x1 < hoverBounds.x1 && x2 < hoverBounds.x1) {
          pick2.movedBounds.x = hoverBounds.x1 - 2;
          pick2.movedBounds.width = 4;
        } else if (x1 > hoverBounds.x2 && x2 > hoverBounds.x2) {
          pick2.movedBounds.x = hoverBounds.x2 - 2;
          pick2.movedBounds.width = 4;
        }
        if (y1 < hoverBounds.y1 && y2 < hoverBounds.y1) {
          pick2.movedBounds.y = hoverBounds.y1 - 2;
          pick2.movedBounds.height = 4;
        } else if (y1 > hoverBounds.y2 && y2 > hoverBounds.y2) {
          pick2.movedBounds.y = hoverBounds.y2 - 2;
          pick2.movedBounds.height = 4;
        }
      }
    }
    this.focusIndicator?.update(pick2.movedBounds ?? pick2.bounds, this.seriesRect, pick2.clipFocusBox);
    const tooltipContent = this.getTooltipContent(focus.series, datum.datumIndex, datum, "aria-label");
    const keyboardEvent = makeKeyboardPointerEvent(focus.series, hoverRect, pick2);
    if (keyboardEvent != null && this.hoverDevice === "keyboard") {
      this.clearCachedEvents();
      const meta = TooltipManager.makeTooltipMeta(keyboardEvent, focus.series, datum, pick2.movedBounds);
      this.chart.ctx.highlightManager.updateHighlight(this.id, datum);
      if (this.isTooltipEnabled(focus.series)) {
        this.chart.ctx.tooltipManager.updateTooltip(this.id, meta, tooltipContent);
      }
    }
    this.maybeAnnouncePickedFocus(
      datumIndexDelta,
      oldDatumIndex,
      otherIndexDelta,
      oldOtherIndex,
      pick2,
      tooltipContent
    );
    return 0 /* SUCCESS */;
  }
  maybeAnnouncePickedFocus(datumIndexDelta, oldDatumIndex, otherIndexDelta, oldOtherIndex, pick2, tooltipContent) {
    const { focus } = this;
    let mode;
    if (this.announceMode === "when-changed") {
      const shouldAnnouncePick = datumIndexDelta === 0 && otherIndexDelta === 0 || oldDatumIndex !== pick2.datumIndex || oldOtherIndex !== (pick2.otherIndex ?? focus.seriesIndex);
      if (shouldAnnouncePick) {
        mode = "always";
      } else {
        mode = "never";
      }
    } else {
      mode = this.announceMode;
    }
    if (mode === "always") {
      this.swapChain.update(this.getDatumAriaText(pick2.datum, tooltipContent));
    }
  }
  getDatumAriaText(datum, tooltipContent) {
    const description = tooltipContent == null ? "" : tooltipContentAriaLabel(tooltipContent);
    return this.chart.ctx.localeManager.t("ariaAnnounceHoverDatum", {
      datum: datum.series.getDatumAriaText?.(datum, description) ?? description
    });
  }
  clearHighlight(delayed = false) {
    this.highlight.pendingHoverEvent = void 0;
    this.highlight.appliedHoverEvent = void 0;
    this.chart.ctx.highlightManager.updateHighlight(this.id, void 0, delayed);
  }
  clearTooltip(delayed = false) {
    this.chart.ctx.tooltipManager.removeTooltip(this.id, void 0, delayed);
    this.tooltip.lastHover = void 0;
  }
  clearAll(delayed = false) {
    this.pickManager.onClearUI();
    this.clearHighlight(delayed);
    this.clearTooltip(delayed);
    this.focusIndicator?.clear();
  }
  clearCachedEvents() {
    this.tooltip.lastHover = void 0;
    this.highlight.appliedHoverEvent = void 0;
    this.highlight.pendingHoverEvent = void 0;
    this.highlight.stashedHoverEvent = void 0;
  }
  handleHoverFromState() {
    const { active, paginationState } = this.pickManager.onPickedNodesAPIDebounced();
    if (active === void 0)
      return;
    this.chart.ctx.highlightManager.updateHighlight(this.id, active.datum);
    const refPoint = getDatumRefPoint(active.series, active.datum, void 0);
    if (this.chart.tooltip.enabled) {
      if (refPoint) {
        const { canvasX, canvasY } = refPoint;
        this.showTooltip(active, canvasX, canvasY, paginationState);
      }
    }
  }
  handleHoverHighlight(redisplay) {
    this.highlight.appliedHoverEvent = this.highlight.pendingHoverEvent;
    this.highlight.pendingHoverEvent = void 0;
    const event = this.highlight.appliedHoverEvent;
    if (!event || !this.isState(82 /* Clickable */))
      return;
    const { canvasX, canvasY } = this.toCanvasCoordinates(event);
    if (redisplay ? this.chart.ctx.animationManager.isActive() : !this.hoverRect?.containsPoint(canvasX, canvasY)) {
      this.clearHighlight();
      return;
    }
    const { range: range3 } = this.chart.highlight;
    const intent = range3 === "tooltip" ? "highlight-tooltip" : "highlight";
    const pick2 = this.pickNodes({ x: event.currentX, y: event.currentY }, intent);
    const active = this.pickManager.onPickedNodesHighlight(pick2);
    if (active === void 0) {
      this.chart.ctx.highlightManager.updateHighlight(this.id, void 0, true);
    } else {
      this.chart.ctx.highlightManager.updateHighlight(this.id, active.datum, false);
    }
  }
  handleHoverTooltip(event, redisplay) {
    if (!this.isState(82 /* Clickable */))
      return;
    const { canvasX, canvasY } = this.toCanvasCoordinates(event);
    const targetElement = event.sourceEvent.target;
    if (redisplay ? this.chart.ctx.animationManager.isActive() : !this.hoverRect?.containsPoint(canvasX, canvasY)) {
      if (this.hoverDevice == "pointer")
        this.clearTooltip();
      return;
    }
    if (targetElement && this.chart.tooltip.interactive && this.chart.ctx.domManager.isManagedChildDOMElement(targetElement, "canvas-overlay", DEFAULT_TOOLTIP_CLASS)) {
      return;
    }
    const pick2 = this.pickNodes({ x: event.currentX, y: event.currentY }, "tooltip");
    const { active, paginationState } = this.pickManager.onPickedNodesTooltip(pick2);
    if (active === void 0) {
      if (this.hoverDevice == "pointer") {
        this.clearTooltip(true);
      }
    } else {
      this.showTooltip(active, canvasX, canvasY, paginationState);
    }
  }
  showTooltip({ series, datum, datumIndex }, canvasX, canvasY, pagination) {
    const tooltipContent = this.getTooltipContent(series, datumIndex, datum, "tooltip");
    const shouldUpdateTooltip = tooltipContent != null;
    if (shouldUpdateTooltip) {
      const meta = TooltipManager.makeTooltipMeta(
        { type: "pointermove", canvasX, canvasY },
        series,
        datum,
        void 0
      );
      this.chart.ctx.tooltipManager.updateTooltip(this.id, meta, tooltipContent, pagination);
    } else {
      this.chart.ctx.tooltipManager.removeTooltip(this.id, void 0, true);
    }
  }
  maybeEnterInteractiveTooltip(event) {
    return this.chart.tooltip.maybeEnterInteractiveTooltip(event, () => {
      this.tooltip.lastHover = void 0;
      this.chart.ctx.tooltipManager.removeTooltip(this.id);
      this.chart.ctx.highlightManager.updateHighlight(this.id, void 0, true);
    });
  }
  changeHighlightDatum(event) {
    const lastSeries = event.previousHighlight?.series;
    const newSeries = event.currentHighlight?.series;
    if (lastSeries?.properties.cursor && event.previousHighlight?.datum) {
      this.chart.ctx.domManager.updateCursor(lastSeries.id);
    }
    if (newSeries?.properties.cursor && newSeries.properties.cursor !== "default" && event.currentHighlight?.datum) {
      this.chart.ctx.domManager.updateCursor(newSeries.id, newSeries.properties.cursor);
    }
    if (this.hoverDevice === "setState" || newSeries == null || lastSeries == null) {
      this.update(7 /* SERIES_UPDATE */, { clearCallbackCache: true });
    } else {
      this.update(7 /* SERIES_UPDATE */, {
        seriesToUpdate: new Set([lastSeries, newSeries].filter(Boolean)),
        clearCallbackCache: true
      });
    }
  }
  pickNodes(point, intent, exactMatchOnly) {
    const reverseSeries = [...this.series].reverse();
    const clickIntent = intent === "event" || intent === "context-menu";
    const tooltipIntent = intent === "tooltip" || intent === "highlight-tooltip";
    const getIntentRange = (series) => {
      if (clickIntent)
        return series.properties.nodeClickRange;
      if (tooltipIntent)
        return series.properties.tooltip.range;
      return void 0;
    };
    const { x, y } = point;
    const seriesContainingPoint = /* @__PURE__ */ new Set();
    for (const series of reverseSeries) {
      if (series.visible && series.contentGroup.visible && getIntentRange(series) === "area") {
        if (series.isPointInArea?.(x, y)) {
          seriesContainingPoint.add(series);
        }
      }
    }
    const hasSeriesContainingPoint = seriesContainingPoint.size > 0;
    let result;
    for (const series of reverseSeries) {
      if (!series.visible || !series.contentGroup.visible)
        continue;
      if (hasSeriesContainingPoint) {
        const hasAreaHit = getIntentRange(series) === "area" && seriesContainingPoint.has(series);
        if (!hasAreaHit)
          continue;
      }
      const pick2 = series.pickNodes(point, intent, exactMatchOnly);
      if (pick2 == null || pick2.datums.length === 0)
        continue;
      const { datums, distance: distance2 } = pick2;
      if (pick2.datums.length === 0)
        continue;
      if (distance2 === 0) {
        if (result?.distance !== 0) {
          result = { matches: [], distance: 0 };
        }
        for (const datum of datums) {
          const { datumIndex } = datum;
          result.matches.push({ series, datum, datumIndex });
        }
      } else if (result == null || result.distance > distance2) {
        const [datum] = datums;
        const { datumIndex } = datum;
        result = { matches: [{ series, datum, datumIndex }], distance: distance2 };
      }
    }
    return result;
  }
  isTooltipEnabled(series) {
    return series.tooltipEnabled ?? this.chart.tooltip.enabled;
  }
  getTooltipContent(series, datumIndex, datum, purpose) {
    let result;
    if (purpose === "aria-label" || this.isTooltipEnabled(series)) {
      const { cachedTooltipContent } = this;
      if (cachedTooltipContent?.series === series && cachedTooltipContent.datumIndex === datumIndex) {
        result = cachedTooltipContent.content;
      } else {
        const content = this.chart.getTooltipContent(series, datumIndex, datum, purpose);
        this.cachedTooltipContent = { series, datumIndex, content };
        result = content;
      }
      purpose;
      result;
    } else {
      this.cachedTooltipContent = void 0;
      purpose;
      result;
    }
    return result;
  }
  onActiveLoadMemento(event) {
    switch (event.activeItem?.type) {
      case void 0:
      case "legend":
        return this.onActiveClear();
      case "series-node":
        return this.onActiveDatum(event.activeItem, event);
      default:
        return event.activeItem?.type;
    }
  }
  onActiveUpdate(activeItem) {
    if (activeItem?.type === "legend") {
      if (this.hoverDevice === "setState") {
        this.clearHighlight();
        this.clearTooltip();
      }
      this.activeState.lastActive = "legend";
    }
  }
  onActiveClear() {
    this.pickManager.onClearAPI();
    this.hoverDevice = "setState";
    this.activeState.lastActive = void 0;
    this.clearHighlight();
    this.clearTooltip();
  }
  refreshSetState() {
    if (this.activeState.lastActive === void 0) {
      this.clearAll();
    } else if (this.activeState.lastActive !== "legend") {
      const { seriesId, itemId } = this.activeState.lastActive;
      const desiredPickedNodes = this.findPickedNodes(seriesId, itemId);
      if (desiredPickedNodes) {
        this.pickManager.onPickedNodesAPI(desiredPickedNodes);
        this.hoverScheduler.schedule();
      }
    }
  }
  onActiveDatum(activeItem, event) {
    const { seriesId, itemId } = activeItem;
    const desiredPickedNodes = this.findPickedNodes(seriesId, itemId);
    if (desiredPickedNodes === void 0) {
      event.reject();
      this.onActiveClear();
    } else {
      const picked = this.pickManager.onPickedNodesAPI(desiredPickedNodes);
      event.setDatum(picked?.datum);
      this.hoverDevice = "setState";
      this.activeState.lastActive = { seriesId, itemId };
      if (event.initialState) {
        this.chart.ctx.scene.applyPendingResize();
        this.handleHoverFromState();
      } else {
        this.clearCachedEvents();
        this.hoverScheduler.schedule();
      }
    }
  }
  findPickedNodes(desiredSeriesId, desiredItemId) {
    const desiredSeries = this.series.find((s) => s.id === desiredSeriesId);
    if (desiredSeries == void 0) {
      logger_exports.warn(`Cannot find seriesId: "${desiredSeriesId}"`);
      return void 0;
    }
    const desiredDatum = desiredSeries.findNodeDatum(desiredItemId);
    if (desiredDatum == void 0) {
      logger_exports.warn(`Cannot find itemId: ${JSON.stringify(desiredItemId)}`);
      return void 0;
    }
    const restoredPick = {
      datum: desiredDatum,
      datumIndex: desiredDatum.datumIndex,
      series: desiredSeries
    };
    return { matches: [restoredPick], distance: 0 };
  }
};
SeriesAreaManager.className = "SeriesAreaManager";

// packages/ag-charts-community/src/chart/series/seriesLayerManager.ts
var SERIES_THRESHOLD_FOR_AGGRESSIVE_LAYER_REDUCTION = 30;
var SeriesLayerManager = class {
  constructor(seriesRoot) {
    this.seriesRoot = seriesRoot;
    this.groups = /* @__PURE__ */ new Map();
    this.series = /* @__PURE__ */ new Map();
    this.expectedSeriesCount = 1;
    this.mode = "normal";
  }
  setSeriesCount(count) {
    this.expectedSeriesCount = count;
  }
  getGroupIndex(seriesConfig) {
    const { internalId, seriesGrouping } = seriesConfig;
    return seriesGrouping?.groupIndex ?? internalId;
  }
  getGroupType(seriesConfig, bringToFront) {
    return bringToFront ? "top" : seriesConfig.type;
  }
  requestGroup(seriesConfig) {
    const { internalId, contentGroup: seriesContentGroup } = seriesConfig;
    const bringToFront = seriesConfig.bringToFront();
    const type = this.getGroupType(seriesConfig, bringToFront);
    const groupIndex = this.getGroupIndex(seriesConfig);
    const seriesInfo = this.series.get(internalId);
    if (seriesInfo != null) {
      throw new Error(`AG Charts - series already has an allocated layer: ${JSON.stringify(seriesInfo)}`);
    }
    if (this.series.size === 0) {
      this.mode = this.expectedSeriesCount >= SERIES_THRESHOLD_FOR_AGGRESSIVE_LAYER_REDUCTION ? "aggressive-grouping" : "normal";
    }
    let group = this.groups.get(type);
    if (group == null) {
      group = /* @__PURE__ */ new Map();
      this.groups.set(type, group);
    }
    const lookupIndex = this.lookupIdx(groupIndex);
    let groupInfo = group.get(lookupIndex);
    if (groupInfo == null) {
      groupInfo = {
        type,
        id: lookupIndex,
        seriesIds: [],
        group: this.seriesRoot.appendChild(
          new Group({
            name: `${seriesConfig.contentGroup.name ?? type}-managed-layer`,
            zIndex: seriesConfig.contentGroup.zIndex,
            // Set in updateLayerCompositing
            renderToOffscreenCanvas: false
          })
        )
      };
      group.set(lookupIndex, groupInfo);
    }
    this.series.set(internalId, { layerState: groupInfo, seriesConfig, bringToFront });
    groupInfo.seriesIds.push(internalId);
    groupInfo.group.appendChild(seriesContentGroup);
    return groupInfo.group;
  }
  changeGroup(seriesConfig) {
    const { internalId, contentGroup } = seriesConfig;
    const bringToFront = seriesConfig.bringToFront();
    const type = this.getGroupType(seriesConfig, bringToFront);
    const oldGroup = this.series.get(internalId);
    const oldType = oldGroup ? this.getGroupType(oldGroup.seriesConfig, oldGroup.bringToFront) : void 0;
    const groupIndex = this.getGroupIndex(seriesConfig);
    const lookupIndex = this.lookupIdx(groupIndex);
    const groupInfo = this.groups.get(type)?.get(lookupIndex);
    if (oldType === type && groupInfo?.seriesIds.includes(internalId) === true) {
      return;
    }
    if (this.series.has(internalId)) {
      this._releaseGroup({ internalId, contentGroup, type: oldType });
    }
    return this.requestGroup(seriesConfig);
  }
  releaseGroup(seriesConfig) {
    const { internalId, contentGroup } = seriesConfig;
    const type = this.getGroupType(seriesConfig, seriesConfig.bringToFront());
    this._releaseGroup({ internalId, contentGroup, type });
  }
  _releaseGroup(seriesConfig) {
    const { internalId, contentGroup, type } = seriesConfig;
    if (!this.series.has(internalId)) {
      throw new Error(`AG Charts - series doesn't have an allocated layer: ${internalId}`);
    }
    const groupInfo = this.series.get(internalId)?.layerState;
    if (groupInfo) {
      groupInfo.seriesIds = groupInfo.seriesIds.filter((v) => v !== internalId);
      contentGroup.remove();
    }
    if (groupInfo?.seriesIds.length === 0) {
      groupInfo.group.remove();
      this.groups.get(groupInfo.type)?.delete(groupInfo.id);
      this.groups.get(type)?.delete(internalId);
    } else if (groupInfo != null && groupInfo.seriesIds.length > 0) {
      groupInfo.group.zIndex = this.getLowestSeriesZIndex(groupInfo.seriesIds);
    }
    this.series.delete(internalId);
  }
  updateLayerCompositing() {
    for (const groups of this.groups.values()) {
      for (const groupInfo of groups.values()) {
        const { group, seriesIds } = groupInfo;
        let renderToOffscreenCanvas;
        if (seriesIds.length === 0) {
          renderToOffscreenCanvas = false;
        } else if (seriesIds.length > 1) {
          renderToOffscreenCanvas = true;
        } else {
          const series = this.series.get(seriesIds[0]);
          renderToOffscreenCanvas = series?.seriesConfig.renderToOffscreenCanvas() === true;
        }
        group.renderToOffscreenCanvas = renderToOffscreenCanvas;
        group.zIndex = this.getLowestSeriesZIndex(seriesIds);
      }
    }
  }
  lookupIdx(groupIndex) {
    if (this.mode === "normal") {
      return groupIndex;
    }
    if (typeof groupIndex === "string") {
      groupIndex = Number(groupIndex.split("-").at(-1));
      if (!Number.isFinite(groupIndex)) {
        return 0;
      }
    }
    return Math.floor(
      clamp(0, groupIndex / this.expectedSeriesCount, 1) * SERIES_THRESHOLD_FOR_AGGRESSIVE_LAYER_REDUCTION
    );
  }
  destroy() {
    for (const groups of this.groups.values()) {
      for (const groupInfo of groups.values()) {
        groupInfo.group.remove();
      }
    }
    this.groups.clear();
    this.series.clear();
  }
  getLowestSeriesZIndex(seriesIds) {
    let lowestSeriesZIndex = void 0;
    for (const seriesId of seriesIds) {
      const series = this.series.get(seriesId);
      const zIndex = series?.seriesConfig.contentGroup.zIndex ?? 1 /* ANY_CONTENT */;
      if (lowestSeriesZIndex == null || zIndex == null) {
        lowestSeriesZIndex = zIndex;
        continue;
      }
      lowestSeriesZIndex = compareZIndex(lowestSeriesZIndex, zIndex) <= 0 ? lowestSeriesZIndex : zIndex;
    }
    return lowestSeriesZIndex ?? 1 /* ANY_CONTENT */;
  }
};

// packages/ag-charts-community/src/chart/touch.ts
var Touch = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.dragAction = "drag";
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], Touch.prototype, "dragAction", 2);

// packages/ag-charts-community/src/chart/update/dataWindowProcessor.ts
var DataWindowProcessor = class {
  constructor(chart, eventsHub, dataService, updateService, zoomManager, animationManager) {
    this.chart = chart;
    this.eventsHub = eventsHub;
    this.dataService = dataService;
    this.updateService = updateService;
    this.zoomManager = zoomManager;
    this.animationManager = animationManager;
    this.dirtyZoom = false;
    this.dirtyDataSource = false;
    this.lastAxisZooms = /* @__PURE__ */ new Map();
    this.cleanup = new CleanupRegistry();
    this.cleanup.register(
      this.eventsHub.on("data:source-change", () => this.onDataSourceChange()),
      this.eventsHub.on("data:load", () => this.onDataLoad()),
      this.eventsHub.on("data:error", () => this.onDataError()),
      this.updateService.addListener("update-complete", (e) => this.onUpdateComplete(e)),
      this.eventsHub.on("zoom:change-complete", () => this.onZoomChange())
    );
  }
  destroy() {
    this.cleanup.flush();
  }
  onDataLoad() {
    this.animationManager.skip();
    this.updateService.update(1 /* UPDATE_DATA */);
  }
  onDataError() {
    this.updateService.update(5 /* PERFORM_LAYOUT */);
  }
  onDataSourceChange() {
    this.dirtyDataSource = true;
  }
  onUpdateComplete(event) {
    if (!event.apiUpdate && !this.dirtyZoom && !this.dirtyDataSource)
      return;
    if (event.wasShortcut)
      return;
    this.updateWindow(event);
  }
  onZoomChange() {
    this.dirtyZoom = true;
  }
  updateWindow(event) {
    if (!this.dataService.isLazy())
      return;
    const axis = this.getValidAxis();
    let window;
    let shouldRefresh = true;
    if (axis) {
      const zoom = this.zoomManager.getAxisZoom(axis.id);
      window = this.getAxisWindow(axis, zoom);
      shouldRefresh = this.shouldRefresh(event, axis, zoom);
    }
    this.dirtyZoom = false;
    this.dirtyDataSource = false;
    if (!shouldRefresh)
      return;
    this.dataService.load({ windowStart: window?.min, windowEnd: window?.max });
  }
  getValidAxis() {
    return this.chart.axes.find((axis) => axis.type === "time");
  }
  shouldRefresh(event, axis, zoom) {
    if (event.apiUpdate)
      return true;
    if (this.dirtyDataSource)
      return true;
    if (!this.dirtyZoom)
      return false;
    const lastZoom = this.lastAxisZooms.get(axis.id);
    if (lastZoom && zoom.min === lastZoom.min && zoom.max === lastZoom.max) {
      return false;
    }
    this.lastAxisZooms.set(axis.id, zoom);
    return true;
  }
  getAxisWindow(axis, zoom) {
    const { domain } = axis.scale;
    if (!zoom || domain.length === 0 || Number.isNaN(Number(domain[0])))
      return;
    const diff9 = Number(domain[1]) - Number(domain[0]);
    const min = new Date(Number(domain[0]) + diff9 * zoom.min);
    const max = new Date(Number(domain[0]) + diff9 * zoom.max);
    return { min, max };
  }
};

// packages/ag-charts-community/src/util/browser.ts
var isSafariRegexp = /^((?!chrome|android).)*safari/i;
var safariVersionRegexp = /Version\/(\d+(\.\d+)?)/;
var isChromeRegexp = /Chrome/;
var chromeVersionRegexp = /Chrome\/(\d+)/;
var isEdge = /Edg/;
var isOpera = /OPR/;
function isUnsupportedBrowser() {
  const { userAgent } = getWindow("navigator");
  if (isSafariRegexp.test(userAgent)) {
    const versionExec = safariVersionRegexp.exec(userAgent);
    if (versionExec == null)
      return false;
    const version = Number.parseFloat(versionExec[1]);
    const supported = Math.floor(version) > 16;
    if (!supported) {
      logger_exports.warnOnce(`Unsupported Safari version: ${version}; ${userAgent}`);
    }
    return !supported;
  } else if (isChromeRegexp.test(userAgent) && !isEdge.test(userAgent) && !isOpera.test(userAgent)) {
    const versionExec = chromeVersionRegexp.exec(userAgent);
    if (versionExec == null)
      return false;
    const version = Number.parseInt(versionExec[1], 10);
    const supported = version > 126;
    if (!supported) {
      logger_exports.warnOnce(`Unsupported Chrome version: ${version}; ${userAgent}`);
    }
    return !supported;
  }
  return false;
}

// packages/ag-charts-community/src/chart/update/overlaysProcessor.ts
var visibleIgnoredSeries = /* @__PURE__ */ new Set(["map-shape-background", "map-line-background"]);
var OverlaysProcessor = class {
  constructor(chartLike, overlays, eventsHub, dataService, localeManager, animationManager, domManager) {
    this.chartLike = chartLike;
    this.overlays = overlays;
    this.eventsHub = eventsHub;
    this.dataService = dataService;
    this.localeManager = localeManager;
    this.animationManager = animationManager;
    this.domManager = domManager;
    this.cleanup = new CleanupRegistry();
    this.overlayElem = this.domManager.addChild("canvas-overlay", "overlay");
    this.overlayElem.role = "status";
    this.overlayElem.ariaAtomic = "false";
    this.overlayElem.ariaLive = "polite";
    this.overlayElem.classList.toggle(DEFAULT_OVERLAY_CLASS);
    this.cleanup.register(this.eventsHub.on("layout:complete", (e) => this.onLayoutComplete(e)));
  }
  destroy() {
    this.cleanup.flush();
    this.domManager.removeChild("canvas-overlay", "overlay");
  }
  onLayoutComplete({ series: { rect: rect2 } }) {
    const isLoading = this.dataService.isLoading();
    const hasData = this.chartLike.series.some((s) => s.hasData);
    const anySeriesVisible = this.chartLike.series.some((s) => s.visible && !visibleIgnoredSeries.has(s.type));
    if (this.overlays.darkTheme) {
      this.overlayElem.classList.add(DEFAULT_OVERLAY_DARK_CLASS);
    } else {
      this.overlayElem.classList.remove(DEFAULT_OVERLAY_DARK_CLASS);
    }
    this.overlayElem.style.left = `${rect2.x}px`;
    this.overlayElem.style.top = `${rect2.y}px`;
    this.overlayElem.style.width = `${rect2.width}px`;
    this.overlayElem.style.height = `${rect2.height}px`;
    const loadingShown = isLoading;
    const noDataShown = !isLoading && !hasData;
    const noVisibleSeriesShown = hasData && !anySeriesVisible;
    const unsupportedBrowser = this.overlays.unsupportedBrowser.enabled && isUnsupportedBrowser();
    if (loadingShown) {
      this.showOverlay(this.overlays.loading, rect2);
    } else {
      this.hideOverlay(this.overlays.loading);
    }
    if (noDataShown) {
      this.showOverlay(this.overlays.noData, rect2);
    } else {
      this.hideOverlay(this.overlays.noData);
    }
    if (noVisibleSeriesShown) {
      this.showOverlay(this.overlays.noVisibleSeries, rect2);
    } else {
      this.hideOverlay(this.overlays.noVisibleSeries);
    }
    if (unsupportedBrowser) {
      this.showOverlay(this.overlays.unsupportedBrowser, rect2);
    } else {
      this.hideOverlay(this.overlays.unsupportedBrowser);
    }
    const shown = loadingShown || noDataShown || noVisibleSeriesShown || unsupportedBrowser;
    setAttribute(this.overlayElem, "aria-hidden", !shown);
  }
  showOverlay(overlay, seriesRect) {
    if (!overlay.enabled)
      return;
    const element2 = overlay.getElement(this.chartLike, this.animationManager, this.localeManager, seriesRect);
    this.overlayElem.appendChild(element2);
  }
  hideOverlay(overlay) {
    overlay.removeElement(() => {
      this.overlayElem.innerText = "\xA0";
    }, this.animationManager);
  }
};

// packages/ag-charts-community/src/chart/chart.ts
var debug = debugLogger_exports.create(true, "opts");
var _Chart = class _Chart extends Observable {
  constructor(options, resources) {
    var _a;
    super();
    this.id = createId(this);
    this.seriesRoot = new TranslatableGroup({
      name: `${this.id}-series-root`,
      zIndex: 7 /* SERIES_LAYER */
    });
    this.annotationRoot = new TranslatableGroup({
      name: `${this.id}-annotation-root`,
      zIndex: 11 /* SERIES_ANNOTATION */
    });
    this.titleGroup = new Group({
      name: "titles",
      zIndex: 15 /* SERIES_LABEL */
    });
    this.debug = debugLogger_exports.create(true, "chart");
    this.extraDebugStats = {};
    this.data = DataSet.empty();
    this._firstAutoSize = true;
    this._autoSizeNotify = new AsyncAwaitQueue();
    this._requiredRange = 0;
    this._requiredRangeDirection = "x" /* X */;
    this.chartCaptions = new ChartCaptions();
    this.padding = new Padding(20);
    this.keyboard = new Keyboard();
    this.touch = new Touch();
    this.mode = "standalone";
    this.styleNonce = void 0;
    this.formatter = void 0;
    this.suppressFieldDotNotation = false;
    this.loadGoogleFonts = false;
    this.destroyed = false;
    this.cleanup = new CleanupRegistry();
    this.chartAnimationPhase = "initial";
    this.modulesManager = new ModulesManager();
    this.processors = [];
    this.queuedUserOptions = [];
    this.queuedChartOptions = [];
    this.firstApply = true;
    this.syncStatus = "init";
    // Use a wrapper to comply with the @typescript-eslint/unbound-method rule.
    this.fireEventWrapper = (event) => super.fireEvent(event);
    this.apiUpdate = false;
    this._pendingFactoryUpdatesCount = 0;
    this._performUpdateSkipAnimations = false;
    this._performUpdateNotify = new AsyncAwaitQueue();
    this.performUpdateType = 10 /* NONE */;
    this.runningUpdateType = 10 /* NONE */;
    this.updateShortcutCount = 0;
    this.seriesToUpdate = /* @__PURE__ */ new Set();
    this.updateMutex = new Mutex();
    this.clearCallbackCacheOnUpdate = false;
    this.updateRequestors = {};
    this.performUpdateTrigger = debouncedCallback(({ count }) => {
      if (this.destroyed)
        return;
      this.updateMutex.acquire(this.tryPerformUpdate.bind(this, count)).catch((e) => logger_exports.errorOnce(e));
    });
    this._performUpdateSplits = {};
    this._previousSplit = 0;
    this.axes = this.createChartAxes();
    this.series = [];
    this._cachedData = void 0;
    this.onSeriesNodeClick = (event) => {
      this.fireEvent(event);
    };
    this.onSeriesNodeDoubleClick = (event) => {
      this.fireEvent(event);
    };
    this.onSeriesVisibilityChange = (event) => {
      this.fireEvent(event);
    };
    this.seriesGroupingChanged = (event) => {
      if (!(event instanceof SeriesGroupingChangedEvent))
        return;
      const { series, seriesGrouping } = event;
      if (series.contentGroup.isRoot())
        return;
      const seriesContentNode = this.seriesLayerManager.changeGroup({
        internalId: series.internalId,
        type: series.type,
        contentGroup: series.contentGroup,
        bringToFront: () => series.bringToFront(),
        renderToOffscreenCanvas: () => series.renderToOffscreenCanvas(),
        seriesGrouping
      });
      if (seriesContentNode != null) {
        series.attachSeries(seriesContentNode, this.seriesRoot, this.annotationRoot);
      }
    };
    this.chartOptions = options;
    const scene = resources?.scene;
    const container = resources?.container ?? options.processedOptions.container ?? void 0;
    const styleContainer = resources?.styleContainer ?? options.specialOverrides.styleContainer;
    const skipCss = options.specialOverrides.skipCss;
    if (scene) {
      this._firstAutoSize = false;
      this._lastAutoSize = [scene.width, scene.height, scene.pixelRatio];
    }
    const root = new Group({ name: "root" });
    root.visible = false;
    root.append(this.seriesRoot);
    root.append(this.annotationRoot);
    root.append(this.titleGroup);
    this.titleGroup.append(this.title.node);
    this.titleGroup.append(this.subtitle.node);
    this.titleGroup.append(this.footnote.node);
    this.tooltip = new Tooltip();
    this.seriesLayerManager = new SeriesLayerManager(this.seriesRoot);
    this.mode = options.userOptions.mode ?? this.mode;
    this.styleNonce = options.processedOptions.styleNonce;
    const ctx = this.ctx = new ChartContext(this, {
      chartType: this.getChartType(),
      scene,
      root,
      container,
      styleContainer,
      skipCss,
      domMode: options.optionMetadata.domMode,
      withDragInterpretation: options.optionMetadata.withDragInterpretation ?? true,
      syncManager: new SyncManager(this),
      fireEvent: (event) => this.fireEvent(event),
      updateCallback: (type, opts) => this.update(type, opts),
      updateMutex: this.updateMutex
    });
    if (options.optionMetadata.presetType === "sparkline") {
      ctx.highlightManager.unhighlightDelay = 0;
      ctx.tooltipManager.removeDelay = 0;
    }
    this.cleanup.register(ctx.eventsHub.on("dom:resize", () => this.parentResize(ctx.domManager.containerSize)));
    this.overlays = new ChartOverlays();
    (_a = this.overlays.loading).renderer ?? (_a.renderer = () => getLoadingSpinner(this.overlays.loading.getText(ctx.localeManager), ctx.animationManager.defaultDuration));
    this.processors = [
      new DataWindowProcessor(
        this,
        ctx.eventsHub,
        ctx.dataService,
        ctx.updateService,
        ctx.zoomManager,
        ctx.animationManager
      ),
      new OverlaysProcessor(
        this,
        this.overlays,
        ctx.eventsHub,
        ctx.dataService,
        ctx.localeManager,
        ctx.animationManager,
        ctx.domManager
      )
    ];
    this.highlight = new ChartHighlight();
    this.container = container;
    const moduleContext = this.getModuleContext();
    this.background = enterpriseRegistry.createBackground?.(moduleContext) ?? new Background(moduleContext);
    this.foreground = enterpriseRegistry.createForeground?.(moduleContext);
    this.seriesArea = new SeriesArea(moduleContext);
    ctx.domManager.setDataBoolean("animating", false);
    ctx.domManager.setDataNumber("animationTimeMs", 0);
    this.seriesAreaManager = new SeriesAreaManager(this.initSeriesAreaDependencies());
    this.cleanup.register(
      ctx.layoutManager.registerElement(0 /* Caption */, (e) => {
        e.layoutBox.shrink(this.padding.toJson());
        this.chartCaptions.positionCaptions(e);
      }),
      ctx.eventsHub.on("layout:complete", (e) => this.chartCaptions.positionAbsoluteCaptions(e)),
      ctx.eventsHub.on("data:load", (event) => {
        this.data = new DataSet(event.data);
      }),
      this.title.registerInteraction(moduleContext, "beforebegin"),
      this.subtitle.registerInteraction(moduleContext, "beforebegin"),
      this.footnote.registerInteraction(moduleContext, "afterend"),
      () => this.title.destroy(),
      () => this.subtitle.destroy(),
      () => this.footnote.destroy(),
      Widget.addWindowEvent("page-left", () => this.destroy()),
      ctx.animationManager.addListener("animation-frame", () => {
        this.update(9 /* SCENE_RENDER */);
        ctx.domManager.setDataNumber("animationTimeMs", ctx.animationManager.getCumulativeAnimationTime());
      }),
      ctx.animationManager.addListener("animation-start", () => ctx.domManager.setDataBoolean("animating", true)),
      ctx.animationManager.addListener("animation-stop", () => {
        ctx.domManager.setDataBoolean("animating", false);
        ctx.domManager.setDataNumber("animationTimeMs", ctx.animationManager.getCumulativeAnimationTime());
      }),
      ctx.eventsHub.on("zoom:change-complete", () => {
        for (const s of this.series) {
          s.animationState?.transition("updateData");
        }
        const skipAnimations = this.chartAnimationPhase !== "initial";
        this.update(5 /* PERFORM_LAYOUT */, { forceNodeDataRefresh: true, skipAnimations });
      })
    );
    this.parentResize(ctx.domManager.containerSize);
  }
  static getInstance(element2) {
    return _Chart.chartsInstances.get(element2);
  }
  /** NOTE: This is exposed for use by Integrated charts only. */
  get canvasElement() {
    return this.ctx.scene.canvas.element;
  }
  download(fileName, fileFormat) {
    this.ctx.scene.download(fileName, fileFormat);
  }
  getCanvasDataURL(fileFormat) {
    return this.ctx.scene.getDataURL(fileFormat);
  }
  toSVG() {
    return this.ctx.scene.toSVG();
  }
  get seriesAreaBoundingBox() {
    return this.seriesAreaManager.bbox;
  }
  getOptions() {
    return this.queuedUserOptions.at(-1) ?? this.chartOptions.userOptions;
  }
  getChartOptions() {
    return this.queuedChartOptions.at(-1) ?? this.chartOptions;
  }
  isDataTransactionSupported() {
    return true;
  }
  overrideFocusVisible(visible) {
    this.seriesAreaManager.focusIndicator?.overrideFocusVisible(visible);
  }
  fireEvent(event) {
    callWithContext(this, this.fireEventWrapper, event);
  }
  initSeriesAreaDependencies() {
    const { ctx, tooltip, highlight: highlight5, overlays, seriesRoot, mode } = this;
    const chartType = this.getChartType();
    const fireEvent = this.fireEvent.bind(this);
    const getUpdateType = () => this.performUpdateType;
    const getTooltipContent = (series, datumIndex, removeThisDatum, purpose) => this.getTooltipContent(series, datumIndex, removeThisDatum, purpose);
    return {
      fireEvent,
      getUpdateType,
      getTooltipContent,
      chartType,
      ctx,
      tooltip,
      highlight: highlight5,
      overlays,
      seriesRoot,
      mode
    };
  }
  getModuleContext() {
    return this.ctx;
  }
  getTooltipContent(series, datumIndex, removeMeDatum, purpose) {
    const useTooltip = purpose === "aria-label" || series.properties.tooltip.enabled !== false;
    const baseTooltipContent = useTooltip ? series.getTooltipContent(datumIndex, removeMeDatum) : void 0;
    const tooltipContent = baseTooltipContent == null ? [] : [baseTooltipContent];
    if (this.tooltip.mode !== "shared" || this.series.length === 1) {
      return tooltipContent;
    }
    const categoryValue = series.getCategoryValue(datumIndex);
    if (categoryValue == null)
      return tooltipContent;
    return this.series.flatMap((s) => {
      if (s === series)
        return tooltipContent;
      if (!s.isEnabled() || s.properties.tooltip.enabled === false)
        return [];
      const seriesDatumIndex = s.datumIndexForCategoryValue(categoryValue);
      const seriesTooltipContent = seriesDatumIndex == null ? void 0 : s.getTooltipContent(seriesDatumIndex, void 0);
      if (seriesTooltipContent == null)
        return [];
      return [seriesTooltipContent];
    });
  }
  getCaptionText() {
    return [this.title, this.subtitle, this.footnote].filter((caption) => caption.enabled && caption.text).map((caption) => caption.text).join(". ");
  }
  getAriaLabel() {
    return this.ctx.localeManager.t("ariaAnnounceChart", { seriesCount: this.series.length });
  }
  refreshSeriesUserVisibility(outdatedOptions, seriesWithUserVisibility) {
    for (let i = 0; i < this.series.length; i++) {
      const src = this.series[i];
      const dst = outdatedOptions.processedOptions.series?.[i];
      if (seriesWithUserVisibility.identifiers.has(src.id) || seriesWithUserVisibility.indices.has(i)) {
        if (dst !== void 0 && "visible" in dst) {
          dst.visible = src.visible;
        }
      }
    }
  }
  resetAnimations() {
    this.chartAnimationPhase = "initial";
    for (const series of this.series) {
      series.resetAnimation(this.chartAnimationPhase);
    }
    for (const axis of this.axes) {
      axis.resetAnimation(this.chartAnimationPhase);
    }
    this.animationRect = void 0;
    this.ctx.animationManager.reset();
  }
  skipAnimations() {
    this.ctx.animationManager.skipCurrentBatch();
    this._performUpdateSkipAnimations = true;
  }
  detachAndClear() {
    this.container = void 0;
    this.ctx.scene.clearCanvas();
  }
  destroy(opts) {
    if (this.destroyed) {
      return;
    }
    const keepTransferableResources = opts?.keepTransferableResources;
    let result;
    this.performUpdateType = 10 /* NONE */;
    this.cleanup.flush();
    for (const p of this.processors) {
      p.destroy();
    }
    this.overlays.destroy();
    this.modulesManager.destroy();
    this.background.destroy();
    this.foreground?.destroy();
    this.seriesArea.destroy();
    if (keepTransferableResources) {
      this.ctx.scene.strip();
      result = {
        container: this.container,
        scene: this.ctx.scene
      };
    } else {
      this.ctx.scene.destroy();
      this.container = void 0;
    }
    this.destroySeries(this.series);
    this.seriesLayerManager.destroy();
    this.axes.destroy();
    this.animationRect = void 0;
    this.ctx.destroy();
    this.destroyed = true;
    Object.freeze(this);
    return result;
  }
  requestFactoryUpdate(cb) {
    if (this.destroyed)
      return;
    this._pendingFactoryUpdatesCount++;
    this.updateMutex.acquire(async () => {
      if (this.destroyed)
        return;
      try {
        await cb(this);
      } finally {
        if (!this.destroyed) {
          this._pendingFactoryUpdatesCount--;
        }
      }
    }).catch((e) => logger_exports.errorOnce(e));
  }
  clearCallbackCache() {
    this.ctx.callbackCache.invalidateCache();
    for (const series of this.series) {
      series.resetDatumCallbackCache();
    }
  }
  update(type = 0 /* FULL */, opts) {
    if (this.destroyed)
      return;
    const {
      forceNodeDataRefresh = false,
      skipAnimations,
      seriesToUpdate = this.series,
      newAnimationBatch,
      apiUpdate = false,
      clearCallbackCache = false
    } = opts ?? {};
    this.apiUpdate = apiUpdate;
    this.ctx.widgets.seriesWidget.setDragTouchEnabled(this.touch.dragAction !== "none");
    if (forceNodeDataRefresh) {
      for (const series of this.series) {
        series.markNodeDataDirty();
      }
    }
    for (const series of seriesToUpdate) {
      this.seriesToUpdate.add(series);
    }
    if (skipAnimations) {
      this.ctx.animationManager.skipCurrentBatch();
      this._performUpdateSkipAnimations = true;
    }
    if (newAnimationBatch && this.ctx.animationManager.isActive()) {
      this._performUpdateSkipAnimations = true;
    }
    if (type === 0 /* FULL */ || clearCallbackCache) {
      this.clearCallbackCacheOnUpdate = true;
    }
    if (this.debug.check()) {
      let stack = new Error("Stack trace for update tracking").stack ?? "<unknown>";
      stack = stack.replaceAll(/\([^)]*/g, "");
      this.updateRequestors[stack] = type;
    }
    if (type < this.performUpdateType) {
      this.performUpdateType = type;
      this.ctx.domManager.setDataBoolean("updatePending", true);
      this.performUpdateTrigger.schedule(opts?.backOffMs);
    }
  }
  updateSplits(splitName) {
    const splits = this._performUpdateSplits;
    splits[splitName] ?? (splits[splitName] = 0);
    splits[splitName] += performance.now() - this._previousSplit;
    this._previousSplit = performance.now();
  }
  async tryPerformUpdate(count) {
    try {
      await this.performUpdate(count);
    } catch (error2) {
      logger_exports.error("update error", error2, error2.stack);
    }
  }
  async performUpdate(count) {
    const { performUpdateType, extraDebugStats, _performUpdateSplits: splits, ctx } = this;
    const seriesToUpdate = [...this.seriesToUpdate];
    if (this.clearCallbackCacheOnUpdate) {
      this.clearCallbackCacheOnUpdate = false;
      this.clearCallbackCache();
    }
    this.performUpdateType = 10 /* NONE */;
    this.seriesToUpdate.clear();
    this.runningUpdateType = performUpdateType;
    if (this.updateShortcutCount === 0 && performUpdateType < 9 /* SCENE_RENDER */) {
      ctx.animationManager.startBatch(this._performUpdateSkipAnimations);
      ctx.animationManager.onBatchStop(() => this.chartAnimationPhase = "ready");
    }
    this.ctx.scene.updateDebugFlags();
    this.debug("Chart.performUpdate() - start", ChartUpdateType[performUpdateType]);
    this._previousSplit = performance.now();
    splits.start ?? (splits.start = this._previousSplit);
    switch (performUpdateType) {
      case 0 /* FULL */:
        if (this.checkUpdateShortcut(0 /* FULL */))
          break;
        this.ctx.updateService.dispatchPreDomUpdate();
        this.updateDOM();
      case 1 /* UPDATE_DATA */:
        if (this.checkUpdateShortcut(1 /* UPDATE_DATA */))
          break;
        this.updateData();
        this.updateSplits("\u2B07\uFE0F");
      case 2 /* PROCESS_DATA */:
        if (this.checkUpdateShortcut(2 /* PROCESS_DATA */))
          break;
        await this.processData();
        this.seriesAreaManager.dataChanged();
        if (this.pendingLocaleText) {
          const localeModule = this.modulesManager.getModule("locale");
          if (localeModule && "localeText" in localeModule) {
            localeModule.localeText = this.pendingLocaleText;
          }
          this.pendingLocaleText = void 0;
        }
        this.updateSplits("\u{1F4CA}");
      case 3 /* PROCESS_DOMAIN */:
        if (this.checkUpdateShortcut(3 /* PROCESS_DOMAIN */))
          break;
        await this.processDomains();
        this.updateSplits("\u26F0\uFE0F");
      case 4 /* PROCESS_RANGE */:
        if (this.checkUpdateShortcut(4 /* PROCESS_RANGE */))
          break;
        this.processRanges();
        this.updateSplits("\u{1F4D0}");
      case 5 /* PERFORM_LAYOUT */:
        await this.checkFirstAutoSize();
        if (this.checkUpdateShortcut(5 /* PERFORM_LAYOUT */))
          break;
        await this.processLayout();
        this.updateSplits("\u2316");
      case 6 /* PRE_SERIES_UPDATE */:
        if (this.checkUpdateShortcut(6 /* PRE_SERIES_UPDATE */))
          break;
        this.preSeriesUpdate();
        this.updateSplits("\u2753");
      case 7 /* SERIES_UPDATE */: {
        if (this.checkUpdateShortcut(7 /* SERIES_UPDATE */))
          break;
        this.seriesRoot.renderToOffscreenCanvas = this.highlight.drawingMode === "cutout";
        await this.updateSeries(seriesToUpdate);
        this.updateAriaLabels();
        this.seriesLayerManager.updateLayerCompositing();
        this.updateSplits("\u{1F914}");
      }
      case 8 /* PRE_SCENE_RENDER */:
        if (this.checkUpdateShortcut(8 /* PRE_SCENE_RENDER */))
          break;
        ctx.updateService.dispatchPreSceneRender();
        this.updateSplits("\u2196");
      case 9 /* SCENE_RENDER */:
        if (this.checkUpdateShortcut(9 /* SCENE_RENDER */))
          break;
        ctx.animationManager.endBatch();
        extraDebugStats["updateShortcutCount"] = this.updateShortcutCount;
        ctx.scene.render({
          debugSplitTimes: splits,
          extraDebugStats,
          seriesRect: this.seriesRect,
          debugColors: this.getDebugColors()
        });
        this.extraDebugStats = {};
        for (const key of Object.keys(splits)) {
          delete splits[key];
        }
        this.ctx.domManager.incrementDataCounter("sceneRenders");
        this.ctx.domManager.postRenderUpdate();
      case 10 /* NONE */:
        this.updateShortcutCount = 0;
        this.updateRequestors = {};
        this._performUpdateSkipAnimations = false;
        ctx.animationManager.endBatch();
    }
    if (!this.destroyed) {
      ctx.updateService.dispatchUpdateComplete(this.apiUpdate, this.updateShortcutCount > 0);
      this.apiUpdate = false;
      this.ctx.domManager.setDataBoolean("updatePending", false);
      this.runningUpdateType = 10 /* NONE */;
      this.syncStatus = "ready";
    }
    this._performUpdateNotify.notify();
    const end3 = performance.now();
    this.debug("Chart.performUpdate() - end", {
      chart: this,
      durationMs: roundTo(end3 - splits["start"]),
      count,
      performUpdateType: ChartUpdateType[performUpdateType]
    });
  }
  updateThemeClassName() {
    const themeClassNamePrefix = "ag-charts-theme-";
    const validThemeClassNames = [`${themeClassNamePrefix}default`, `${themeClassNamePrefix}default-dark`];
    let themeClassName = validThemeClassNames[0];
    let isDark = false;
    let { theme } = this.chartOptions.processedOptions;
    while (typeof theme !== "string" && theme != null) {
      theme = theme.baseTheme;
    }
    if (typeof theme === "string") {
      themeClassName = theme.replace("ag-", themeClassNamePrefix);
      isDark = theme.includes("-dark");
    }
    if (!validThemeClassNames.includes(themeClassName)) {
      themeClassName = isDark ? validThemeClassNames[1] : validThemeClassNames[0];
    }
    this.ctx.domManager.setThemeClass(themeClassName);
  }
  updateDOM() {
    this.updateThemeClassName();
    const { enabled, tabIndex } = this.keyboard;
    this.ctx.domManager.setTabGuardIndex(enabled ? tabIndex ?? 0 : -1);
    this.ctx.domManager.setThemeParameters(this.chartOptions.themeParameters);
  }
  updateAriaLabels() {
    this.ctx.domManager.updateCanvasLabel(this.getAriaLabel());
  }
  checkUpdateShortcut(checkUpdateType) {
    const maxShortcuts = 3;
    if (this.destroyed)
      return true;
    if (this.updateShortcutCount > maxShortcuts) {
      logger_exports.warn(
        `exceeded the maximum number of simultaneous updates (${maxShortcuts + 1}), discarding changes and rendering`,
        this.updateRequestors
      );
      return false;
    }
    if (this.performUpdateType <= checkUpdateType) {
      this.debug("Chart.checkUpdateShortcut() - BLOCKED AT: ", ChartUpdateType[checkUpdateType]);
      this.updateShortcutCount++;
      return true;
    }
    this.debug("Chart.checkUpdateShortcut() - PROCEEDING TO: ", ChartUpdateType[checkUpdateType]);
    return false;
  }
  async checkFirstAutoSize() {
    if (this.width != null && this.height != null) {
    } else if (!this._lastAutoSize) {
      const success = await this._autoSizeNotify.waitForCompletion(500);
      if (!success) {
        this.debug("Chart.checkFirstAutoSize() - timeout for first size update.");
      }
    }
  }
  createChartAxes() {
    return new ChartAxes();
  }
  onAxisChange(newValue, oldValue) {
    if (oldValue == null && newValue.length === 0)
      return;
    this.ctx.axisManager.updateAxes(oldValue ?? [], newValue);
  }
  onSeriesChange(newValue, oldValue) {
    const seriesToDestroy = oldValue?.filter((series) => !newValue.includes(series)) ?? [];
    this.destroySeries(seriesToDestroy);
    this.seriesLayerManager?.setSeriesCount(newValue.length);
    for (const series of newValue) {
      if (oldValue?.includes(series))
        continue;
      const seriesContentNode = this.seriesLayerManager.requestGroup(series);
      series.attachSeries(seriesContentNode, this.seriesRoot, this.annotationRoot);
      series.chart = {};
      Object.defineProperty(series.chart, "mode", {
        get: () => this.mode
      });
      Object.defineProperty(series.chart, "isMiniChart", {
        get: () => false
      });
      Object.defineProperty(series.chart, "flashOnUpdateEnabled", {
        get: () => !!this.modulesManager.getModule("flashOnUpdate")?.enabled
      });
      Object.defineProperty(series.chart, "seriesRect", {
        get: () => this.seriesRect
      });
      series.resetAnimation(this.chartAnimationPhase);
      this.addSeriesListeners(series);
    }
    this.seriesAreaManager?.seriesChanged(newValue);
  }
  destroySeries(allSeries) {
    if (allSeries) {
      for (const series of allSeries) {
        series.removeEventListener("seriesNodeClick", this.onSeriesNodeClick);
        series.removeEventListener("seriesNodeDoubleClick", this.onSeriesNodeDoubleClick);
        series.removeEventListener("groupingChanged", this.seriesGroupingChanged);
        series.destroy();
        this.seriesLayerManager.releaseGroup(series);
        series.detachSeries(void 0, this.seriesRoot, this.annotationRoot);
        series.chart = void 0;
      }
    }
  }
  addSeriesListeners(series) {
    if (this.hasEventListener("seriesNodeClick")) {
      series.addEventListener("seriesNodeClick", this.onSeriesNodeClick);
    }
    if (this.hasEventListener("seriesNodeDoubleClick")) {
      series.addEventListener("seriesNodeDoubleClick", this.onSeriesNodeDoubleClick);
    }
    if (this.hasEventListener("seriesVisibilityChange")) {
      series.addEventListener("seriesVisibilityChange", this.onSeriesVisibilityChange);
    }
    series.addEventListener("groupingChanged", this.seriesGroupingChanged);
  }
  assignSeriesToAxes() {
    for (const axis of this.axes) {
      let seriesPredicateFn2 = function(s) {
        return s.axes[axis.direction] === axis;
      };
      var seriesPredicateFn = seriesPredicateFn2;
      axis.boundSeries = this.series.filter(seriesPredicateFn2);
    }
  }
  assignAxesToSeries() {
    for (const series of this.series) {
      for (const direction of series.directions) {
        const seriesAxisId = series.getKeyAxis(direction) ?? direction;
        const newAxis = this.axes.findById(seriesAxisId);
        if (!newAxis) {
          logger_exports.warnOnce(
            `no matching axis for direction [${direction}] and id [${seriesAxisId}]; check series and axes configuration.`
          );
          return;
        }
        series.axes[direction] = newAxis;
      }
    }
  }
  parentResize(size) {
    if (size == null || this.width != null && this.height != null)
      return;
    let { width: width2, height: height2 } = size;
    const { pixelRatio } = size;
    width2 = Math.floor(width2);
    height2 = Math.floor(height2);
    if (width2 === 0 && height2 === 0)
      return;
    const [autoWidth = 0, autoHeight = 0, autoPixelRatio = 1] = this._lastAutoSize ?? [];
    if (autoWidth === width2 && autoHeight === height2 && autoPixelRatio === pixelRatio)
      return;
    this._lastAutoSize = [width2, height2, pixelRatio];
    this.resize("SizeMonitor", {});
  }
  resize(source, opts) {
    const { scene, animationManager } = this.ctx;
    const { inWidth, inHeight, inMinWidth, inMinHeight, inOverrideDevicePixelRatio } = opts;
    this.ctx.domManager.setSizeOptions(
      inMinWidth ?? this.minWidth,
      inMinHeight ?? this.minHeight,
      inWidth ?? this.width,
      inHeight ?? this.height
    );
    const width2 = inWidth ?? this.width ?? this._lastAutoSize?.[0];
    const height2 = inHeight ?? this.height ?? this._lastAutoSize?.[1];
    const pixelRatio = inOverrideDevicePixelRatio ?? this.overrideDevicePixelRatio ?? this._lastAutoSize?.[2];
    this.debug(`Chart.resize() from ${source}`, {
      width: width2,
      height: height2,
      pixelRatio,
      stack: new Error("Stack trace for resize tracking").stack
    });
    if (width2 == null || height2 == null || !isFiniteNumber(width2) || !isFiniteNumber(height2))
      return;
    if (scene.resize(width2, height2, pixelRatio)) {
      animationManager.reset();
      let skipAnimations = true;
      if ((this.width == null || this.height == null) && this._firstAutoSize) {
        skipAnimations = false;
        this._firstAutoSize = false;
      }
      let updateType = 5 /* PERFORM_LAYOUT */;
      for (const axis of this.axes) {
        const axisUpdateType = axis.getUpdateTypeOnResize();
        if (axisUpdateType < updateType) {
          updateType = axisUpdateType;
        }
      }
      this.update(updateType, { forceNodeDataRefresh: true, skipAnimations });
      this._autoSizeNotify.notify();
    }
  }
  updateData() {
    this.ctx.eventsHub.emit("data:update", this.data);
  }
  async processData() {
    if (this.series.some((s) => s.canHaveAxes)) {
      this.assignAxesToSeries();
      this.assignSeriesToAxes();
    }
    const dataController = new DataController(this.mode, this.suppressFieldDotNotation, this.ctx.eventsHub);
    const promises = [];
    for (const series of this.series) {
      promises.push(series.processData(dataController) ?? Promise.resolve());
    }
    for (const module2 of this.modulesManager.modules()) {
      if (module2?.processData) {
        promises.push(module2.processData(dataController) ?? Promise.resolve());
      }
    }
    this._cachedData = dataController.execute(this._cachedData);
    this.updateSplits("\u{1F3ED}");
    await Promise.all(promises);
    this.updateLegends();
  }
  // eslint-disable-next-line @typescript-eslint/require-await
  async processDomains() {
    for (const axis of this.axes) {
      axis.processData();
    }
    for (const series of this.series) {
      series.updatedDomains();
    }
  }
  processRanges() {
    var _a;
    const seriesRanges = {};
    const chartRanges = {};
    const seriesTypes = /* @__PURE__ */ new Map();
    this._requiredRangeDirection = "x" /* X */;
    for (const series of this.series) {
      if (!series.visible)
        continue;
      seriesRanges[_a = series.type] ?? (seriesRanges[_a] = []);
      series.getMinimumRangeSeries(seriesRanges[series.type]);
      if (series.resolveKeyDirection("x" /* X */) === "y" /* Y */) {
        this._requiredRangeDirection = "y" /* Y */;
      }
      if (!seriesTypes.has(series.type)) {
        seriesTypes.set(series.type, series);
      }
    }
    for (const [type, firstSeries] of seriesTypes) {
      chartRanges[type] = firstSeries.getMinimumRangeChart(seriesRanges[type]);
    }
    if (Object.keys(chartRanges).length === 0) {
      this._requiredRange = 0;
    } else {
      this._requiredRange = Math.ceil(Math.max(...Object.values(chartRanges)));
    }
    for (const axis of this.axes) {
      axis.requiredRange = this._requiredRange;
    }
  }
  updateLegends(initialStateLegend) {
    for (const module2 of moduleRegistry_exports.listModulesByType("plugin" /* Plugin */)) {
      switch (module2.name) {
        case "legend":
          this.setCategoryLegendData(initialStateLegend);
          break;
        case "gradientLegend":
          const moduleInstance = this.modulesManager.getModule("gradientLegend");
          moduleInstance.data = this.series.filter((s) => s.properties.showInLegend).flatMap((s) => s.getLegendData("gradient"));
          break;
      }
    }
  }
  setCategoryLegendData(initialState) {
    const { legendManager, stateManager } = this.ctx;
    if (initialState) {
      for (const s of this.series) {
        const seriesState = initialState.find((init) => init.seriesId === s.id);
        s.onLegendInitialState("category", seriesState);
      }
    }
    const legendData = this.series.flatMap((s) => {
      const seriesLegendData = s.getLegendData("category");
      legendManager.updateData(s.id, seriesLegendData);
      return seriesLegendData;
    });
    if (initialState) {
      stateManager.setStateAndRestore(legendManager, initialState);
      return;
    }
    if (this.mode !== "integrated") {
      const seriesMarkerFills = {};
      const seriesMap = new Map(this.series.map((s) => [s.id, s]));
      for (const {
        seriesId,
        symbol: { marker },
        label
      } of legendData.filter((d) => !d.hideInLegend)) {
        if (marker.fill == null)
          continue;
        const series = seriesMap.get(seriesId);
        if (!series?.hasData)
          continue;
        const seriesType = series.type;
        const markerFill = seriesMarkerFills[seriesType] ?? (seriesMarkerFills[seriesType] = /* @__PURE__ */ new Map());
        if (markerFill.has(label.text)) {
          if (markerFill.get(label.text) !== marker.fill) {
            logger_exports.warnOnce(
              `legend item '${toPlainText(label.text)}' has multiple fill colours, this may cause unexpected behaviour.`
            );
          }
        } else {
          markerFill.set(label.text, marker.fill);
        }
      }
    }
    legendManager.update();
  }
  async processLayout() {
    const oldRect = this.animationRect;
    const { width: width2, height: height2 } = this.ctx.scene;
    const ctx = this.ctx.layoutManager.createContext(width2, height2);
    await this.performLayout(ctx);
    if (oldRect && !this.animationRect?.equals(oldRect)) {
      this.ctx.animationManager.skipCurrentBatch();
    }
    this.debug("Chart.performUpdate() - seriesRect", this.seriesRect);
  }
  getDebugColors() {
    const bg = this.background.fill;
    if (!bg)
      return void 0;
    try {
      const color2 = Color.fromString(bg);
      const [lightness] = Color.RGBtoOKLCH(color2.r, color2.g, color2.b);
      return { background: bg, foreground: lightness > 0.5 ? "black" : "white" };
    } catch {
      return { background: bg };
    }
  }
  preSeriesUpdate() {
    const { _requiredRange, seriesRect } = this;
    if (seriesRect == null)
      return;
    const dimension = this._requiredRangeDirection === "x" /* X */ ? seriesRect.width : seriesRect.height;
    const requiredRangeRatio = _requiredRange / dimension || 0;
    this.ctx.updateService.dispatchPreSeriesUpdate(requiredRangeRatio, this._requiredRangeDirection);
  }
  async updateSeries(seriesToUpdate) {
    const { seriesRect } = this;
    function seriesUpdate(series) {
      return series.update({ seriesRect });
    }
    await Promise.all(seriesToUpdate.map(seriesUpdate).filter((p) => p != null));
    this.ctx.seriesLabelLayoutManager.updateLabels(
      this.series.filter((s) => s.visible && s.usesPlacedLabels),
      this.padding,
      this.seriesRect
    );
  }
  async waitForUpdate(timeoutMs, failOnTimeout) {
    const agChartsDebugTimeout = getWindow("agChartsDebugTimeout");
    if (agChartsDebugTimeout == null) {
      timeoutMs ?? (timeoutMs = 1e4);
      failOnTimeout ?? (failOnTimeout = false);
    } else {
      timeoutMs = agChartsDebugTimeout;
      failOnTimeout ?? (failOnTimeout = true);
    }
    const start2 = performance.now();
    while (this._pendingFactoryUpdatesCount > 0 || this.performUpdateType !== 10 /* NONE */ || this.runningUpdateType !== 10 /* NONE */ || this.ctx.scene.waitingForUpdate() || this.data.hasPendingTransactions()) {
      if (this.destroyed)
        break;
      if (this._pendingFactoryUpdatesCount > 0) {
        await this.updateMutex.waitForClearAcquireQueue();
      }
      if (this.performUpdateType !== 10 /* NONE */ || this.runningUpdateType !== 10 /* NONE */ || this.data.hasPendingTransactions()) {
        await this._performUpdateNotify.waitForCompletion();
      }
      if (performance.now() - start2 > timeoutMs) {
        const message = `Chart.waitForUpdate() timeout of ${timeoutMs} reached - first chart update taking too long.`;
        if (failOnTimeout) {
          throw new Error(message);
        } else {
          logger_exports.warnOnce(message);
        }
      }
      if (isInputPending()) {
        await pause();
      }
      if (this.ctx.scene.waitingForUpdate()) {
        await pause(50);
      }
    }
  }
  filterMiniChartSeries(series) {
    return series?.filter((s) => s.showInMiniChart !== false);
  }
  applyOptions(newChartOptions) {
    if (newChartOptions.seriesWithUserVisibility) {
      this.refreshSeriesUserVisibility(this.chartOptions, newChartOptions.seriesWithUserVisibility);
    }
    const minimumUpdateType = 5 /* PERFORM_LAYOUT */;
    const deltaOptions = this.firstApply ? newChartOptions.processedOptions : newChartOptions.diffOptions(this.chartOptions);
    if (deltaOptions == null || Object.keys(deltaOptions).length === 0) {
      debug("Chart.applyOptions() - no delta, forcing re-layout", deltaOptions);
      this.update(minimumUpdateType, { apiUpdate: true, newAnimationBatch: true });
      return;
    }
    const oldOpts = this.firstApply ? {} : this.chartOptions.processedOptions;
    const newOpts = newChartOptions.processedOptions;
    debug("Chart.applyOptions() - applying delta", deltaOptions);
    const modulesChanged = this.applyModules();
    const skip = [
      "type",
      "data",
      "series",
      "listeners",
      "preset",
      "theme",
      "legend.listeners",
      "navigator.miniChart.series",
      "navigator.miniChart.label",
      "locale.localeText",
      "axes",
      "topology",
      "nodes",
      "initialState",
      "styleContainer",
      "formatter",
      "displayNullData"
    ];
    if ("listeners" in deltaOptions) {
      this.registerListeners(this, deltaOptions.listeners);
    }
    jsonApply(this, deltaOptions, { skip });
    let forceNodeDataRefresh = false;
    let seriesStatus = "no-op";
    if (deltaOptions.series != null) {
      seriesStatus = this.applySeries(this, deltaOptions.series, oldOpts?.series);
      forceNodeDataRefresh = true;
    }
    if (seriesStatus === "replaced") {
      this.resetAnimations();
    }
    if (this.applyAxes(this, newOpts, oldOpts, seriesStatus, [])) {
      forceNodeDataRefresh = true;
    }
    const { userDeltaKeys } = newChartOptions;
    const userExplicitlyPassedData = userDeltaKeys === void 0 || userDeltaKeys.has("data");
    if (deltaOptions.data && userExplicitlyPassedData) {
      const suppliedData = deltaOptions.data;
      const userOptionsData = newChartOptions.userOptions.data;
      const needsClone = Array.isArray(suppliedData) && suppliedData !== userOptionsData;
      const dataForDataSet = needsClone ? suppliedData.slice() : suppliedData;
      this.data = new DataSet(dataForDataSet);
    }
    if ("legend" in deltaOptions && deltaOptions.legend && "listeners" in deltaOptions.legend && this.modulesManager.isEnabled("legend")) {
      const legendListeners = deltaOptions.legend.listeners;
      if (legendListeners) {
        Object.assign(this.legend.listeners, legendListeners);
      } else {
        this.legend.listeners.clear();
      }
    }
    if (deltaOptions.locale?.localeText) {
      this.pendingLocaleText = deltaOptions.locale?.localeText;
    }
    this.chartOptions = newChartOptions;
    const navigatorModule = this.modulesManager.getModule("navigator");
    const zoomModule = this.modulesManager.getModule("zoom");
    const scrollbarModule = this.modulesManager.getModule("scrollbar");
    if (!navigatorModule?.enabled && !zoomModule?.enabled && !scrollbarModule?.enabled) {
      this.ctx.zoomManager.updateZoom(
        { source: "chart-update", sourceDetail: "internal-applyOptions" },
        { x: { min: 0, max: 1 } }
      );
    }
    const miniChart = navigatorModule?.miniChart;
    const miniChartSeries = newOpts.navigator?.miniChart?.series ?? newOpts.series;
    if (miniChart?.enabled === true && miniChartSeries != null) {
      this.applyMiniChartOptions(miniChart, miniChartSeries, newOpts, oldOpts);
    } else if (miniChart?.enabled === false) {
      miniChart.series = [];
      miniChart.axes = [];
    }
    this.ctx.annotationManager.setAnnotationStyles(newChartOptions.annotationThemes);
    forceNodeDataRefresh || (forceNodeDataRefresh = this.shouldForceNodeDataRefresh(deltaOptions, seriesStatus));
    const majorChange = forceNodeDataRefresh || modulesChanged;
    const updateType = majorChange ? 0 /* FULL */ : minimumUpdateType;
    this.maybeResetAnimations(seriesStatus);
    if (this.shouldClearLegendData(newOpts, oldOpts, seriesStatus)) {
      this.ctx.legendManager.clearData();
    }
    this.applyInitialState(newOpts);
    this.ctx.formatManager.setFormatter(newOpts.formatter);
    debug("Chart.applyOptions() - update type", ChartUpdateType[updateType], {
      seriesStatus,
      forceNodeDataRefresh
    });
    if (newChartOptions.optionsProcessingTime !== void 0) {
      this._performUpdateSplits["\u2699\uFE0F"] = newChartOptions.optionsProcessingTime;
      const optionsStartTime = performance.now() - newChartOptions.optionsProcessingTime;
      this._performUpdateSplits.start = optionsStartTime;
    }
    this.update(updateType, {
      apiUpdate: true,
      forceNodeDataRefresh,
      newAnimationBatch: true,
      clearCallbackCache: true
    });
    this.firstApply = false;
  }
  applyInitialState(options) {
    const { activeManager, annotationManager, chartTypeOriginator, historyManager, stateManager, zoomManager } = this.ctx;
    const { initialState } = options;
    if ("annotations" in options && options.annotations?.enabled && initialState?.annotations != null) {
      const annotations = initialState.annotations.map((annotation) => {
        const annotationTheme = annotationManager.getAnnotationTypeStyles(annotation.type);
        return mergeDefaults(annotation, annotationTheme);
      });
      stateManager.setState(annotationManager, annotations);
    }
    if (initialState?.chartType != null) {
      stateManager.setState(chartTypeOriginator, initialState.chartType);
    }
    if ((options.navigator?.enabled || options.zoom?.enabled || options.scrollbar?.enabled) && initialState?.zoom != null) {
      stateManager.setState(zoomManager, initialState.zoom);
    }
    if (initialState?.active != null) {
      stateManager.setState(activeManager, initialState.active);
    }
    if (initialState?.legend != null) {
      this.updateLegends(initialState.legend);
    }
    if (initialState != null) {
      historyManager.clear();
    }
  }
  maybeResetAnimations(seriesStatus) {
    if (this.mode !== "standalone")
      return;
    switch (seriesStatus) {
      case "series-grouping-change":
      case "replaced":
        this.resetAnimations();
        break;
      default:
    }
  }
  shouldForceNodeDataRefresh(deltaOptions, seriesStatus) {
    const seriesDataUpdate = !!deltaOptions.data || seriesStatus === "data-change" || seriesStatus === "replaced";
    const optionsHaveLegend = ["legend", "gradientLegend"].some(
      (legendKey) => deltaOptions[legendKey] != null
    );
    const otherRefreshUpdate = deltaOptions.title != null && deltaOptions.subtitle != null || deltaOptions.formatter != null;
    return seriesDataUpdate || optionsHaveLegend || otherRefreshUpdate;
  }
  shouldClearLegendData(options, oldOpts, seriesStatus) {
    const seriesChanged = seriesStatus === "replaced" || seriesStatus === "series-count-changed" || seriesStatus === "series-grouping-change" || seriesStatus === "updated" && (options.series?.length !== oldOpts.series?.length || !options.series?.every((s, i) => s.type === oldOpts.series?.[i].type));
    const legendRemoved = oldOpts.legend != null && oldOpts.legend.enabled !== false && (options.legend == null || options.legend.enabled === false);
    return seriesChanged || legendRemoved;
  }
  applyMiniChartOptions(miniChart, miniChartSeries, completeOptions, oldOpts) {
    const oldSeries = oldOpts?.navigator?.miniChart?.series ?? oldOpts?.series;
    const miniChartSeriesStatus = this.applySeries(
      miniChart,
      this.filterMiniChartSeries(miniChartSeries),
      this.filterMiniChartSeries(oldSeries)
    );
    this.applyAxes(miniChart, completeOptions, oldOpts, miniChartSeriesStatus, [
      "tick",
      "thickness",
      "title",
      "crosshair",
      "gridLine",
      "label"
    ]);
    const series = miniChart.series;
    for (const s of series) {
      s.properties.id = void 0;
    }
    const axes = miniChart.axes;
    const horizontalAxis = axes.find((axis) => axis.direction === "x" /* X */);
    for (const axis of axes) {
      axis.nice = false;
      axis.gridLine.enabled = false;
      axis.label.enabled = axis === horizontalAxis;
      axis.tick.enabled = false;
      axis.interactionEnabled = false;
    }
    if (horizontalAxis != null) {
      const miniChartOpts = completeOptions.navigator?.miniChart;
      const labelOptions2 = miniChartOpts?.label;
      const intervalOptions = miniChartOpts?.label?.interval;
      horizontalAxis.line.enabled = false;
      horizontalAxis.label.set(
        without(labelOptions2, [
          "interval",
          "autoRotate",
          "autoRotateAngle",
          "itemStyler",
          "minSpacing",
          "rotation"
        ])
      );
      if (horizontalAxis.type === "grouped-category") {
        horizontalAxis.label.enabled = false;
        horizontalAxis.label.rotation = 0;
        const { depthOptions } = horizontalAxis;
        if (depthOptions.length === 0) {
          depthOptions.set([{ label: { enabled: true } }]);
        } else {
          for (let i = 1; i < depthOptions.length; i++) {
            depthOptions[i].label.enabled = false;
          }
        }
      } else if (horizontalAxis.type === "time" || horizontalAxis.type === "unit-time" || horizontalAxis.type === "ordinal-time") {
        horizontalAxis.parentLevel.enabled = false;
      }
      horizontalAxis.interval.step = intervalOptions?.step;
      horizontalAxis.interval.values = intervalOptions?.values;
      horizontalAxis.interval.minSpacing = intervalOptions?.minSpacing;
      horizontalAxis.interval.maxSpacing = intervalOptions?.maxSpacing;
    }
  }
  applyModules() {
    const { type: chartType } = this.constructor;
    let modulesChanged = false;
    for (const module2 of moduleRegistry_exports.listModulesByType("plugin" /* Plugin */)) {
      const shouldBeEnabled = !module2.chartType || module2.chartType === chartType;
      if (shouldBeEnabled === this.modulesManager.isEnabled(module2.name))
        continue;
      if (shouldBeEnabled) {
        const moduleInstance = module2.create(this.getModuleContext());
        this.modulesManager.addModule(module2.name, moduleInstance);
        this[module2.name] = moduleInstance;
      } else {
        this.modulesManager.removeModule(module2.name);
        delete this[module2.name];
      }
      modulesChanged = true;
    }
    return modulesChanged;
  }
  initSeriesDeclarationOrder(series) {
    for (let idx = 0; idx < series.length; idx++) {
      series[idx].setSeriesIndex(idx);
    }
  }
  applySeries(chart, optSeries, oldOptSeries) {
    if (!optSeries) {
      return "no-change";
    }
    const matchResult = matchSeriesOptions(chart.series, optSeries, oldOptSeries);
    if (matchResult.status === "no-overlap") {
      debug(`Chart.applySeries() - creating new series instances, status: ${matchResult.status}`, matchResult);
      const chartSeries = optSeries.map((opts) => this.createSeries(opts));
      this.initSeriesDeclarationOrder(chartSeries);
      chart.series = chartSeries;
      return "replaced";
    }
    debug(`Chart.applySeries() - matchResult`, matchResult);
    const seriesInstances = [];
    let dataChanged = false;
    let groupingChanged = false;
    let isUpdated = false;
    let seriesCountChanged = false;
    const changes = matchResult.changes.toSorted((a, b) => a.targetIdx - b.targetIdx);
    for (const change of changes) {
      groupingChanged || (groupingChanged = change.status === "series-grouping");
      dataChanged || (dataChanged = change.diff?.data != null);
      isUpdated || (isUpdated = change.status !== "no-op");
      seriesCountChanged || (seriesCountChanged = change.status === "add" || change.status === "remove");
      switch (change.status) {
        case "add": {
          const newSeries = this.createSeries(change.opts);
          seriesInstances.push(newSeries);
          debug(`Chart.applySeries() - created new series`, newSeries);
          break;
        }
        case "remove":
          debug(`Chart.applySeries() - removing series at previous idx ${change.idx}`, change.series);
          break;
        case "no-op":
          seriesInstances.push(change.series);
          debug(`Chart.applySeries() - no change to series at previous idx ${change.idx}`, change.series);
          break;
        case "series-grouping":
        case "update":
        default: {
          const { series, diff: diff9, idx } = change;
          debug(`Chart.applySeries() - applying series diff previous idx ${idx}`, diff9, series);
          this.applySeriesValues(series, diff9);
          series.markNodeDataDirty();
          seriesInstances.push(series);
        }
      }
    }
    this.initSeriesDeclarationOrder(seriesInstances);
    debug(`Chart.applySeries() - final series instances`, seriesInstances);
    chart.series = seriesInstances;
    if (groupingChanged) {
      return "series-grouping-change";
    }
    if (seriesCountChanged) {
      return "series-count-changed";
    }
    if (dataChanged) {
      return "data-change";
    }
    return isUpdated ? "updated" : "no-op";
  }
  applyAxes(chart, options, oldOpts, seriesStatus, skip = []) {
    if (!("axes" in options) || !options.axes) {
      return false;
    }
    skip = ["type", ...skip];
    const axes = options.axes;
    const forceRecreate = seriesStatus === "replaced";
    const matchingTypes = !forceRecreate && chart.axes.matches(axes);
    if (matchingTypes && isAgCartesianChartOptions(oldOpts)) {
      for (const axis of chart.axes) {
        const previousOpts = oldOpts.axes?.[axis.id] ?? {};
        const axisDiff = jsonDiff(previousOpts, axes[axis.id]);
        debug(`Chart.applyAxes() - applying axis diff idx ${axis.id}`, axisDiff);
        jsonApply(axis, axisDiff, { skip });
      }
      return true;
    }
    debug(`Chart.applyAxes() - creating new axes instances; seriesStatus: ${seriesStatus}`);
    chart.axes = this.createAxes(axes, skip);
    return true;
  }
  createSeries(seriesOptions) {
    const seriesModule = moduleRegistry_exports.getSeriesModule(seriesOptions.type);
    const seriesInstance = seriesModule.create(this.getModuleContext());
    this.applySeriesOptionModules(seriesInstance, seriesOptions);
    this.applySeriesValues(seriesInstance, seriesOptions);
    return seriesInstance;
  }
  applySeriesOptionModules(series, options) {
    const moduleContext = series.createModuleContext();
    const moduleMap = series.getModuleMap();
    for (const module2 of moduleRegistry_exports.listModulesByType("series:plugin" /* SeriesPlugin */)) {
      if (module2.name in options && (module2.seriesTypes?.includes(series.type) ?? true)) {
        moduleMap.addModule(module2.name, module2.create(moduleContext));
      }
    }
  }
  applySeriesValues(target, options) {
    const moduleMap = target.getModuleMap();
    const { type, data, listeners, seriesGrouping, showInMiniChart, ...seriesOptions } = options;
    for (const module2 of moduleRegistry_exports.listModulesByType("series:plugin" /* SeriesPlugin */)) {
      if (module2.name in seriesOptions) {
        const moduleInstance = moduleMap.getModule(module2.name);
        if (moduleInstance) {
          const moduleOptions = seriesOptions[module2.name];
          moduleInstance.properties.set(moduleOptions);
          delete seriesOptions[module2.name];
        }
      }
    }
    if (seriesOptions.visible != null) {
      target.visible = seriesOptions.visible;
    }
    target.properties.set(seriesOptions);
    if ("data" in options) {
      target.setOptionsData(data == null ? void 0 : DataSet.wrap(data));
    }
    if ("listeners" in options) {
      this.registerListeners(target, listeners);
      if (this.series.includes(target)) {
        this.addSeriesListeners(target);
      }
    }
    if ("seriesGrouping" in options) {
      if (seriesGrouping == null) {
        target.seriesGrouping = void 0;
      } else {
        target.seriesGrouping = { ...target.seriesGrouping, ...seriesGrouping };
      }
    }
  }
  createAxes(options, skip) {
    const newAxes = this.createChartAxes();
    const moduleContext = this.getModuleContext();
    for (const [id, axisOptions] of entries(options)) {
      const axis = moduleRegistry_exports.getAxisModule(axisOptions.type).create(moduleContext);
      axis.id = id;
      this.applyAxisModules(axis, axisOptions);
      jsonApply(axis, axisOptions, { skip });
      newAxes.push(axis);
    }
    guessInvalidPositions(newAxes);
    return newAxes;
  }
  applyAxisModules(axis, options) {
    const moduleContext = axis.createModuleContext();
    const moduleMap = axis.getModuleMap();
    for (const module2 of moduleRegistry_exports.listModulesByType("axis:plugin" /* AxisPlugin */)) {
      const shouldBeEnabled = options[module2.name] != null;
      if (shouldBeEnabled === moduleMap.isEnabled(module2.name))
        continue;
      if (shouldBeEnabled) {
        moduleMap.addModule(module2.name, module2.create(moduleContext));
        axis[module2.name] = moduleMap.getModule(module2.name);
      } else {
        moduleMap.removeModule(module2.name);
        delete axis[module2.name];
      }
    }
  }
  registerListeners(source, listeners) {
    source.clearEventListeners();
    if (listeners && typeof listeners === "object") {
      for (const [property, listener] of entries(listeners)) {
        if (listener == null) {
          continue;
        }
        source.addEventListener(property, listener);
      }
    }
  }
  async applyTransaction(transaction) {
    await this.updateMutex.acquire(() => {
      this.data.addTransaction(transaction);
      this.update(1 /* UPDATE_DATA */, {
        apiUpdate: true,
        skipAnimations: true
      });
    });
    await this.waitForUpdate();
  }
  onSyncActiveClear() {
    this.seriesAreaManager.onActiveClear();
  }
};
_Chart.className = "Chart";
_Chart.chartsInstances = /* @__PURE__ */ new WeakMap();
__decorateClass([
  ActionOnSet({
    newValue(value) {
      if (this.destroyed)
        return;
      this.ctx.domManager.setContainer(value);
      _Chart.chartsInstances.set(value, this);
    },
    oldValue(value) {
      _Chart.chartsInstances.delete(value);
    }
  })
], _Chart.prototype, "container", 2);
__decorateClass([
  ActionOnSet({
    newValue(value) {
      this.resize("width option", { inWidth: value });
    }
  })
], _Chart.prototype, "width", 2);
__decorateClass([
  ActionOnSet({
    newValue(value) {
      this.resize("height option", { inHeight: value });
    }
  })
], _Chart.prototype, "height", 2);
__decorateClass([
  ActionOnSet({
    newValue(value) {
      this.resize("minWidth option", { inMinWidth: value });
    }
  })
], _Chart.prototype, "minWidth", 2);
__decorateClass([
  ActionOnSet({
    newValue(value) {
      this.resize("minHeight option", { inMinHeight: value });
    }
  })
], _Chart.prototype, "minHeight", 2);
__decorateClass([
  ActionOnSet({
    newValue(value) {
      this.resize("overrideDevicePixelRatio option", { inOverrideDevicePixelRatio: value });
    }
  })
], _Chart.prototype, "overrideDevicePixelRatio", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], _Chart.prototype, "padding", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], _Chart.prototype, "keyboard", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], _Chart.prototype, "touch", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], _Chart.prototype, "mode", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], _Chart.prototype, "styleNonce", 2);
__decorateClass([
  ProxyProperty("chartCaptions.title")
], _Chart.prototype, "title", 2);
__decorateClass([
  ProxyProperty("chartCaptions.subtitle")
], _Chart.prototype, "subtitle", 2);
__decorateClass([
  ProxyProperty("chartCaptions.footnote")
], _Chart.prototype, "footnote", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], _Chart.prototype, "formatter", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], _Chart.prototype, "suppressFieldDotNotation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], _Chart.prototype, "loadGoogleFonts", 2);
__decorateClass([
  ActionOnSet({
    changeValue(newValue, oldValue) {
      this.onAxisChange(newValue, oldValue);
    }
  })
], _Chart.prototype, "axes", 2);
__decorateClass([
  ActionOnSet({
    changeValue(newValue, oldValue) {
      this.onSeriesChange(newValue, oldValue);
    }
  })
], _Chart.prototype, "series", 2);
var Chart = _Chart;

// packages/ag-charts-community/src/module/coreModulesTypes.ts
function paletteType(partial) {
  if (partial?.up || partial?.down || partial?.neutral) {
    return "user-full";
  } else if (partial?.fills || partial?.strokes) {
    return "user-indexed";
  }
  return "inbuilt";
}

// packages/ag-charts-community/src/chart/themes/defaultColors.ts
var DEFAULT_FILLS = {
  BLUE: "#5090dc",
  ORANGE: "#ffa03a",
  GREEN: "#459d55",
  CYAN: "#34bfe1",
  YELLOW: "#e1cc00",
  VIOLET: "#9669cb",
  GRAY: "#b5b5b5",
  MAGENTA: "#bd5aa7",
  BROWN: "#8a6224",
  RED: "#ef5452"
};
var DEFAULT_STROKES = {
  BLUE: "#2b5c95",
  ORANGE: "#cc6f10",
  GREEN: "#1e652e",
  CYAN: "#18859e",
  YELLOW: "#a69400",
  VIOLET: "#603c88",
  GRAY: "#575757",
  MAGENTA: "#7d2f6d",
  BROWN: "#4f3508",
  RED: "#a82529"
};

// packages/ag-charts-community/src/chart/themes/chartTheme.ts
var DEFAULT_BACKGROUND_FILL = "white";
var PRESET_OVERRIDES_TYPES = {
  "radial-gauge": true,
  "linear-gauge": true
};
function hasUserOptionLessThan1(key) {
  return {
    $some: [
      {
        $and: [
          {
            $or: [
              { $isSeriesType: "line" },
              { $isSeriesType: "scatter" },
              { $isSeriesType: "area" },
              { $isSeriesType: "radar" },
              { $isSeriesType: "rangeArea" }
            ]
          },
          {
            $isUserOption: [
              `/series/$index/${key}`,
              { $lessThan: [{ $path: `/series/$index/${key}` }, 1] },
              false
            ]
          }
        ]
      },
      { $path: "/series" }
    ]
  };
}
function isPresetOverridesType(type) {
  return PRESET_OVERRIDES_TYPES[type] === true;
}
var _ChartTheme = class _ChartTheme {
  static getDefaultColors() {
    return {
      fills: DEFAULT_FILLS,
      fillsFallback: Object.values(DEFAULT_FILLS),
      strokes: DEFAULT_STROKES,
      sequentialColors: getSequentialColors(DEFAULT_FILLS),
      divergingColors: [DEFAULT_FILLS.ORANGE, DEFAULT_FILLS.YELLOW, DEFAULT_FILLS.GREEN],
      hierarchyColors: ["#fff", "#e0e5ea", "#c1ccd5", "#a3b4c1", "#859cad"],
      secondSequentialColors: Color.interpolate(
        [
          Color.fromHexString(DEFAULT_FILLS.BLUE),
          Color.fromHexString("#cbdef5")
          // TODO: Color.lighten(DEFAULT_FILLS.BLUE, ?)
        ],
        8
      ).map((color2) => color2.toString()),
      secondDivergingColors: [DEFAULT_FILLS.GREEN, DEFAULT_FILLS.YELLOW, DEFAULT_FILLS.RED],
      secondHierarchyColors: ["#fff", "#c5cbd1", "#a4b1bd", "#8498a9", "#648096"],
      up: { fill: DEFAULT_FILLS.GREEN, stroke: DEFAULT_STROKES.GREEN },
      down: { fill: DEFAULT_FILLS.RED, stroke: DEFAULT_STROKES.RED },
      neutral: { fill: DEFAULT_FILLS.GRAY, stroke: DEFAULT_STROKES.GRAY },
      altUp: { fill: DEFAULT_FILLS.BLUE, stroke: DEFAULT_STROKES.BLUE },
      altDown: { fill: DEFAULT_FILLS.ORANGE, stroke: DEFAULT_STROKES.ORANGE },
      altNeutral: { fill: DEFAULT_FILLS.GRAY, stroke: DEFAULT_STROKES.GRAY }
    };
  }
  static getDefaultPublicParameters() {
    return {
      accentColor: "#2196f3",
      axisColor: { $foregroundBackgroundMix: 0.325 },
      backgroundColor: DEFAULT_BACKGROUND_FILL,
      borderColor: { $foregroundOpacity: 0.15 },
      borderRadius: 4,
      chartBackgroundColor: { $ref: "backgroundColor" },
      chartPadding: 20,
      focusShadow: "0 0 0 3px var(--ag-charts-accent-color)",
      foregroundColor: "#181d1f",
      fontFamily: "Verdana, sans-serif",
      fontSize: BASE_FONT_SIZE,
      fontWeight: 400,
      gridLineColor: { $foregroundBackgroundMix: 0.1 },
      popupShadow: "0 0 16px rgba(0, 0, 0, 0.15)",
      subtleTextColor: { $mix: [{ $ref: "textColor" }, { $ref: "chartBackgroundColor" }, 0.38] },
      textColor: { $ref: "foregroundColor" },
      separationLinesColor: { $foregroundBackgroundMix: 0.17 },
      chromeBackgroundColor: { $foregroundBackgroundMix: 0.02 },
      chromeFontFamily: { $ref: "fontFamily" },
      chromeFontSize: { $ref: "fontSize" },
      chromeFontWeight: { $ref: "fontWeight" },
      chromeTextColor: { $ref: "foregroundColor" },
      chromeSubtleTextColor: { $mix: [{ $ref: "chromeTextColor" }, { $ref: "backgroundColor" }, 0.38] },
      buttonBackgroundColor: { $ref: "backgroundColor" },
      buttonBorder: true,
      buttonFontWeight: 400,
      buttonTextColor: { $ref: "textColor" },
      inputBackgroundColor: { $ref: "backgroundColor" },
      inputBorder: true,
      inputTextColor: { $ref: "textColor" },
      menuBackgroundColor: { $ref: "chromeBackgroundColor" },
      menuBorder: true,
      menuTextColor: { $ref: "chromeTextColor" },
      panelBackgroundColor: { $ref: "chromeBackgroundColor" },
      panelSubtleTextColor: { $ref: "chromeSubtleTextColor" },
      tooltipBackgroundColor: { $ref: "chromeBackgroundColor" },
      tooltipBorder: true,
      tooltipTextColor: { $ref: "chromeTextColor" },
      tooltipSubtleTextColor: { $ref: "chromeSubtleTextColor" },
      crosshairLabelBackgroundColor: { $ref: "foregroundColor" },
      crosshairLabelTextColor: { $ref: "chartBackgroundColor" }
    };
  }
  static getAxisDefaults({ title, time: time3 }) {
    return mergeDefaults(
      title && {
        title: {
          enabled: false,
          text: "Axis Title",
          spacing: 25,
          fontWeight: { $ref: "fontWeight" },
          fontSize: { $rem: FONT_SIZE_RATIO.MEDIUM },
          fontFamily: { $ref: "fontFamily" },
          color: { $ref: "textColor" }
        }
      },
      time3 && {
        parentLevel: {
          enabled: false,
          label: {
            // TODO: { $merge: [{ $path: '../../label' }, { fontWeight: 'bold' }]}
            enabled: { $path: "../../label/enabled" },
            border: {
              enabled: {
                $or: [
                  { $isUserOption: ["../border", true, false] },
                  { $path: "../../../label/border/enabled" }
                ]
              },
              strokeWidth: { $path: "../../../label/border/strokeWidth" },
              stroke: { $path: "../../../label/border/stroke" }
            },
            fill: { $path: "../../label/fill" },
            fontSize: { $path: "../../label/fontSize" },
            fontFamily: { $path: "../../label/fontFamily" },
            fontWeight: "bold",
            spacing: { $path: "../../label/spacing" },
            color: { $path: "../../label/color" },
            cornerRadius: { $path: "../../label/cornerRadius" },
            padding: { $path: "../../label/padding" },
            avoidCollisions: { $path: "../../label/avoidCollisions" }
          },
          tick: {
            enabled: { $path: "../../tick/enabled" },
            width: { $path: "../../tick/width" },
            size: { $path: "../../tick/size" },
            stroke: { $path: "../../tick/stroke" }
          }
        }
      },
      {
        label: {
          enabled: true,
          fontSize: { $ref: "fontSize" },
          fontFamily: { $ref: "fontFamily" },
          fontWeight: { $ref: "fontWeight" },
          spacing: 11,
          color: { $ref: "textColor" },
          avoidCollisions: true,
          cornerRadius: 4,
          border: {
            enabled: { $isUserOption: ["../border", true, false] },
            strokeWidth: 1,
            stroke: { $foregroundOpacity: 0.08 }
          },
          padding: {
            $if: [
              { $eq: [{ $path: "./border/enabled" }, true] },
              { left: 12, right: 12, top: 8, bottom: 8 },
              void 0
            ]
          }
        },
        line: {
          enabled: true,
          width: 1,
          stroke: { $ref: "axisColor" }
        },
        tick: {
          enabled: false,
          size: 6,
          width: 1,
          stroke: { $ref: "axisColor" }
        },
        gridLine: {
          enabled: true,
          width: 1,
          style: {
            $apply: [
              {
                fillOpacity: 1,
                stroke: { $ref: "gridLineColor" },
                strokeWidth: { $path: "../../width" },
                lineDash: []
              },
              [
                {
                  fillOpacity: 1,
                  stroke: { $ref: "gridLineColor" },
                  strokeWidth: { $path: "../../width" },
                  lineDash: []
                }
              ]
            ]
          }
        },
        crossLines: {
          $apply: [
            {
              enabled: true,
              fill: { $ref: "foregroundColor" },
              stroke: { $ref: "foregroundColor" },
              fillOpacity: 0.08,
              strokeWidth: 1,
              label: {
                fontSize: { $ref: "fontSize" },
                fontFamily: { $ref: "fontFamily" },
                fontWeight: { $ref: "fontWeight" },
                padding: 5,
                color: { $ref: "textColor" },
                border: {
                  enabled: false,
                  stroke: { $ref: "foregroundColor" },
                  strokeOpacity: 1,
                  strokeWidth: { $isUserOption: ["./stroke", 1, 0] }
                }
              }
            },
            void 0,
            // TODO: can we just infer this common path?
            // `axisType` path is relative to the axis that is currently being resolved
            // e.g. `/axes/x/crossLines/[variables]` + `../type` = `/axes/x/type`
            { $pathString: ["/common/axes/$axisType/crossLines", { axisType: { $path: ["../type"] } }] },
            {
              $pathString: [
                "/$seriesType/axes/$axisType/crossLines",
                {
                  seriesType: { $path: ["/series/0/type", "line"] },
                  axisType: { $path: ["../type"] }
                }
              ]
            }
          ]
        }
      }
    );
  }
  getChartDefaults() {
    return {
      minHeight: 300,
      minWidth: 300,
      background: { visible: true, fill: { $ref: "chartBackgroundColor" } },
      padding: {
        top: { $ref: "chartPadding" },
        right: { $ref: "chartPadding" },
        bottom: { $ref: "chartPadding" },
        left: { $ref: "chartPadding" }
      },
      seriesArea: {
        border: {
          enabled: false,
          stroke: { $ref: "foregroundColor" },
          strokeOpacity: 1,
          strokeWidth: 1
        },
        cornerRadius: 4,
        padding: { $if: [{ $eq: [{ $path: "./border/enabled" }, true] }, 5, 0] }
      },
      keyboard: { enabled: true },
      title: {
        enabled: false,
        text: "Title",
        spacing: { $if: [{ $path: "../subtitle/enabled" }, 10, 20] },
        fontWeight: { $ref: "fontWeight" },
        fontSize: { $rem: FONT_SIZE_RATIO.LARGEST },
        fontFamily: { $ref: "fontFamily" },
        color: { $ref: "textColor" },
        wrapping: "hyphenate",
        layoutStyle: DEFAULT_CAPTION_LAYOUT_STYLE,
        textAlign: DEFAULT_CAPTION_ALIGNMENT
      },
      subtitle: {
        enabled: false,
        text: "Subtitle",
        spacing: 20,
        fontWeight: { $ref: "fontWeight" },
        fontSize: { $rem: FONT_SIZE_RATIO.MEDIUM },
        fontFamily: { $ref: "fontFamily" },
        color: { $ref: "subtleTextColor" },
        wrapping: "hyphenate",
        layoutStyle: DEFAULT_CAPTION_LAYOUT_STYLE,
        textAlign: DEFAULT_CAPTION_ALIGNMENT
      },
      footnote: {
        enabled: false,
        text: "Footnote",
        spacing: 20,
        fontSize: { $rem: FONT_SIZE_RATIO.MEDIUM },
        fontFamily: { $ref: "fontFamily" },
        fontWeight: { $ref: "fontWeight" },
        color: { $ref: "subtleTextColor" },
        wrapping: "hyphenate",
        layoutStyle: DEFAULT_CAPTION_LAYOUT_STYLE,
        textAlign: DEFAULT_CAPTION_ALIGNMENT
      },
      highlight: {
        drawingMode: {
          $if: [
            {
              $or: [
                hasUserOptionLessThan1("highlight/highlightedItem/opacity"),
                hasUserOptionLessThan1("highlight/unhighlightedItem/opacity"),
                hasUserOptionLessThan1("highlight/highlightedSeries/opacity"),
                hasUserOptionLessThan1("highlight/unhighlightedSeries/opacity"),
                hasUserOptionLessThan1("fillOpacity"),
                hasUserOptionLessThan1("marker/fillOpacity")
              ]
            },
            "overlap",
            "cutout"
          ]
        }
      },
      tooltip: {
        enabled: true,
        darkTheme: IS_DARK_THEME,
        delay: 0,
        pagination: false,
        mode: {
          $if: [
            {
              $or: [
                {
                  $and: [
                    { $isChartType: "cartesian" },
                    { $not: { $hasSeriesType: "bubble" } },
                    { $not: { $hasSeriesType: "scatter" } },
                    { $greaterThan: [{ $size: { $path: "/series" } }, 1] },
                    { $lessThan: [{ $size: { $path: "/series" } }, 4] }
                  ]
                },
                {
                  $and: [
                    { $isChartType: "polar" },
                    { $greaterThan: [{ $size: { $path: "/series" } }, 1] },
                    { $lessThan: [{ $size: { $path: "/series" } }, 4] }
                  ]
                }
              ]
            },
            "shared",
            "single"
          ]
        }
      },
      overlays: { darkTheme: IS_DARK_THEME },
      listeners: {},
      // TODO: remove this
      series: {
        tooltip: {
          range: {
            $if: [
              { $eq: [{ $path: ["/tooltip/range", "exact"] }, "area"] },
              "exact",
              { $path: ["/tooltip/range", "exact"] }
            ]
          },
          position: {
            anchorTo: { $path: ["/tooltip/position/anchorTo", "pointer"] },
            placement: { $path: ["/tooltip/position/placement", void 0] },
            xOffset: { $path: ["/tooltip/position/xOffset", 0] },
            yOffset: { $path: ["/tooltip/position/yOffset", 0] }
          }
        }
      }
    };
  }
  constructor(options = {}) {
    const { overrides, palette, params } = deepClone(options);
    const defaults = this.createChartConfigPerChartType(this.getDefaults());
    const presets = {};
    if (overrides) {
      this.processOverrides(presets, overrides);
    }
    const { fills, strokes, sequentialColors, ...otherColors } = this.getDefaultColors();
    this.palette = deepFreeze(
      mergeDefaults(palette, {
        fills: Object.values(fills),
        strokes: Object.values(strokes),
        sequentialColors: Object.values(sequentialColors),
        ...otherColors
      })
    );
    this.paletteType = paletteType(palette);
    this.params = mergeDefaults(params, this.getPublicParameters());
    this.config = deepFreeze(deepClone(defaults));
    this.overrides = deepFreeze(overrides);
    this.presets = deepFreeze(presets);
  }
  processOverrides(presets, overrides) {
    for (const s of moduleRegistry_exports.listModulesByType("series" /* Series */)) {
      const seriesType = s.name;
      const seriesOverrides = overrides[seriesType];
      if (isPresetOverridesType(seriesType)) {
        presets[seriesType] = seriesOverrides;
        delete overrides[seriesType];
      }
    }
  }
  createChartConfigPerChartType(config) {
    var _a;
    for (const chartModule of moduleRegistry_exports.listModulesByType("chart" /* Chart */)) {
      for (const seriesModule of moduleRegistry_exports.listModulesByType("series" /* Series */)) {
        if (seriesModule.chartType !== chartModule.name)
          continue;
        config[_a = seriesModule.name] ?? (config[_a] = chartModule.themeTemplate);
      }
    }
    return config;
  }
  getDefaults() {
    const getOverridesByType = (chartType, seriesTypes) => {
      const result = {};
      const chartTypeDefaults = mergeDefaults(
        { axes: {} },
        ...Array.from(moduleRegistry_exports.listModulesByType("plugin" /* Plugin */), (p) => ({
          [p.name]: p.themeTemplate
        })),
        moduleRegistry_exports.getChartModule(chartType)?.themeTemplate,
        this.getChartDefaults()
      );
      for (const seriesType of seriesTypes) {
        result[seriesType] = mergeDefaults(
          getSeriesThemeTemplate(seriesType),
          result[seriesType] ?? chartTypeDefaults
        );
        const { axes } = result[seriesType];
        for (const axisModule of moduleRegistry_exports.listModulesByType("axis" /* Axis */)) {
          axes[axisModule.name] = mergeDefaults(
            axes[axisModule.name],
            !axisModule.chartType || axisModule.chartType === chartType ? getAxisThemeTemplate(axisModule.name) : null,
            _ChartTheme.axisDefault[axisModule.name]
          );
        }
        if (seriesType === "map-shape-background" || seriesType === "map-line-background") {
          delete result[seriesType].series.tooltip;
        }
      }
      return result;
    };
    const seriesModules = [...moduleRegistry_exports.listModulesByType("series" /* Series */)];
    const seriesByChartType = groupBy(seriesModules, (s) => s.chartType || "unknown");
    return mergeDefaults(
      ...Object.keys(seriesByChartType).map(
        (chartType) => getOverridesByType(chartType, seriesByChartType[chartType]?.map((s) => s.name) ?? [])
      )
    );
  }
  static applyTemplateTheme(node, _other, params) {
    if (isArray(node)) {
      for (let i = 0; i < node.length; i++) {
        const symbol = node[i];
        if (typeof symbol === "symbol" && params?.has(symbol)) {
          node[i] = params.get(symbol);
        }
      }
    } else {
      for (const name of Object.keys(node)) {
        const value = node[name];
        if (typeof value === "symbol" && params?.has(value)) {
          node[name] = params.get(value);
        }
      }
    }
  }
  templateTheme(themeTemplate10, clone2 = true) {
    const themeInstance = clone2 ? deepClone(themeTemplate10) : themeTemplate10;
    const params = this.getTemplateParameters();
    jsonWalk(themeInstance, _ChartTheme.applyTemplateTheme, void 0, void 0, params);
    return themeInstance;
  }
  getDefaultColors() {
    return _ChartTheme.getDefaultColors();
  }
  getPublicParameters() {
    return _ChartTheme.getDefaultPublicParameters();
  }
  // Private parameters that are not exposed in the themes API.
  getTemplateParameters() {
    const params = /* @__PURE__ */ new Map();
    params.set(IS_DARK_THEME, false);
    params.set(DEFAULT_SHADOW_COLOUR, "#00000080");
    params.set(DEFAULT_SPARKLINE_CROSSHAIR_STROKE, "#aaa");
    params.set(DEFAULT_CAPTION_LAYOUT_STYLE, "block");
    params.set(DEFAULT_CAPTION_ALIGNMENT, "center");
    params.set(DEFAULT_FIBONACCI_STROKES, [
      "#797b86",
      "#e24c4a",
      "#f49d2d",
      "#65ab58",
      "#409682",
      "#4db9d2",
      "#5090dc",
      "#3068f9",
      "#e24c4a",
      "#913aac",
      "#d93e64"
    ]);
    params.set(DEFAULT_POLAR_SERIES_STROKE, DEFAULT_BACKGROUND_FILL);
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, DEFAULT_FILLS.BLUE);
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, DEFAULT_FILLS.BLUE);
    params.set(DEFAULT_TEXT_ANNOTATION_COLOR, DEFAULT_FILLS.BLUE);
    params.set(DEFAULT_ANNOTATION_HANDLE_FILL, DEFAULT_BACKGROUND_FILL);
    params.set(DEFAULT_ANNOTATION_STATISTICS_FILL, "#fafafa");
    params.set(DEFAULT_ANNOTATION_STATISTICS_STROKE, "#ddd");
    params.set(DEFAULT_ANNOTATION_STATISTICS_COLOR, "#000");
    params.set(DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE, "#181d1f");
    params.set(DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL, "#e35c5c");
    params.set(DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE, "#e35c5c");
    params.set(DEFAULT_TEXTBOX_FILL, "#fafafa");
    params.set(DEFAULT_TEXTBOX_STROKE, "#ddd");
    params.set(DEFAULT_TEXTBOX_COLOR, "#000");
    params.set(DEFAULT_TOOLBAR_POSITION, "top");
    const defaultColors = this.getDefaultColors();
    params.set(PALETTE_UP_STROKE, this.palette.up?.stroke ?? defaultColors.up.stroke);
    params.set(PALETTE_UP_FILL, this.palette.up?.fill ?? defaultColors.up.fill);
    params.set(PALETTE_DOWN_STROKE, this.palette.down?.stroke ?? defaultColors.down.stroke);
    params.set(PALETTE_DOWN_FILL, this.palette.down?.fill ?? defaultColors.down.fill);
    params.set(PALETTE_NEUTRAL_STROKE, this.palette.neutral?.stroke ?? defaultColors.neutral.stroke);
    params.set(PALETTE_NEUTRAL_FILL, this.palette.neutral?.fill ?? defaultColors.neutral.fill);
    params.set(PALETTE_ALT_UP_STROKE, this.palette.altUp?.stroke ?? defaultColors.up.stroke);
    params.set(PALETTE_ALT_UP_FILL, this.palette.altUp?.fill ?? defaultColors.up.fill);
    params.set(PALETTE_ALT_DOWN_STROKE, this.palette.altDown?.stroke ?? defaultColors.down.stroke);
    params.set(PALETTE_ALT_DOWN_FILL, this.palette.altDown?.fill ?? defaultColors.down.fill);
    params.set(PALETTE_ALT_NEUTRAL_FILL, this.palette.altNeutral?.fill ?? defaultColors.altNeutral.fill);
    params.set(PALETTE_ALT_NEUTRAL_STROKE, this.palette.altNeutral?.stroke ?? defaultColors.altNeutral.stroke);
    return params;
  }
};
_ChartTheme.axisDefault = {
  ["number" /* NUMBER */]: _ChartTheme.getAxisDefaults({ title: true, time: false }),
  ["log" /* LOG */]: _ChartTheme.getAxisDefaults({ title: true, time: false }),
  ["category" /* CATEGORY */]: _ChartTheme.getAxisDefaults({ title: true, time: false }),
  ["grouped-category" /* GROUPED_CATEGORY */]: _ChartTheme.getAxisDefaults({ title: true, time: false }),
  ["time" /* TIME */]: _ChartTheme.getAxisDefaults({ title: true, time: true }),
  ["unit-time" /* UNIT_TIME */]: _ChartTheme.getAxisDefaults({ title: true, time: true }),
  ["ordinal-time" /* ORDINAL_TIME */]: _ChartTheme.getAxisDefaults({ title: true, time: true }),
  ["angle-category" /* ANGLE_CATEGORY */]: _ChartTheme.getAxisDefaults({ title: false, time: false }),
  ["angle-number" /* ANGLE_NUMBER */]: _ChartTheme.getAxisDefaults({ title: false, time: false }),
  ["radius-category" /* RADIUS_CATEGORY */]: _ChartTheme.getAxisDefaults({ title: true, time: false }),
  ["radius-number" /* RADIUS_NUMBER */]: _ChartTheme.getAxisDefaults({ title: true, time: false })
};
var ChartTheme = _ChartTheme;
function getAxisThemeTemplate(axisType) {
  let themeTemplate10 = moduleRegistry_exports.getAxisModule(axisType)?.themeTemplate ?? {};
  for (const module2 of moduleRegistry_exports.listModulesByType("axis:plugin" /* AxisPlugin */)) {
    if (module2.axisTypes?.includes(axisType) ?? true) {
      themeTemplate10 = mergeDefaults({ [module2.name]: module2.themeTemplate }, themeTemplate10);
    }
  }
  return themeTemplate10;
}
function getSeriesThemeTemplate(seriesType) {
  let themeTemplate10 = moduleRegistry_exports.getSeriesModule(seriesType)?.themeTemplate ?? {};
  for (const module2 of moduleRegistry_exports.listModulesByType("series:plugin" /* SeriesPlugin */)) {
    if (module2.seriesTypes?.includes(seriesType) ?? true) {
      themeTemplate10 = mergeDefaults({ series: { [module2.name]: module2.themeTemplate } }, themeTemplate10);
    }
  }
  return themeTemplate10;
}

// packages/ag-charts-community/src/chart/factory/processModuleOptions.ts
var SkippedModules = /* @__PURE__ */ new Set(["foreground"]);
function sanitizeThemeModules(theme) {
  const missingModules = /* @__PURE__ */ new Map();
  for (const [name, { type }] of ExpectedModules) {
    if (moduleRegistry_exports.hasModule(name))
      continue;
    if (missingModules.has(type)) {
      missingModules.get(type).add(name);
    } else {
      missingModules.set(type, /* @__PURE__ */ new Set([name]));
    }
  }
  if (missingModules.size === 0)
    return theme;
  function prunePlugins(target) {
    const missingPlugins = missingModules.get("plugin" /* Plugin */);
    if (!isObject(target) || !missingPlugins)
      return;
    for (const pluginName of missingPlugins) {
      if (pluginName in target && target[pluginName].enabled !== true) {
        delete target[pluginName];
      }
    }
  }
  function pruneSeriesPlugins(target) {
    const missingSeriesPlugins = missingModules.get("series:plugin" /* SeriesPlugin */);
    if (!isObject(target) || !missingSeriesPlugins)
      return;
    for (const pluginName of missingSeriesPlugins) {
      if (pluginName in target) {
        delete target[pluginName];
      }
    }
  }
  function pruneAxisPlugins(target) {
    const missingAxisPlugins = missingModules.get("axis:plugin" /* AxisPlugin */);
    if (!isObject(target) || !missingAxisPlugins)
      return;
    for (const pluginName of missingAxisPlugins) {
      if (pluginName in target && target[pluginName].enabled !== true) {
        delete target[pluginName];
      }
    }
  }
  function pruneAxes(axes) {
    if (!isObject(axes))
      return;
    for (const axisName of Object.keys(axes)) {
      if (missingModules.get("axis" /* Axis */)?.has(axisName)) {
        delete axes[axisName];
        continue;
      }
      pruneAxisPlugins(axes[axisName]);
    }
  }
  function pruneSeriesEntry(entry) {
    if (!isObject(entry))
      return;
    pruneAxes(entry.axes);
    prunePlugins(entry);
    pruneSeriesPlugins(entry.series);
  }
  const config = deepClone(theme.config);
  const overrides = deepClone(theme.overrides);
  const presets = deepClone(theme.presets);
  for (const seriesType of Object.keys(config)) {
    if (missingModules.get("series" /* Series */)?.has(seriesType)) {
      delete config[seriesType];
      continue;
    }
    pruneSeriesEntry(config[seriesType]);
  }
  if (isObject(overrides)) {
    const overridesObj = overrides;
    if (isObject(overridesObj.common)) {
      pruneAxes(overridesObj.common.axes);
      prunePlugins(overridesObj.common);
    }
    for (const seriesType of Object.keys(overridesObj)) {
      if (seriesType === "common")
        continue;
      if (missingModules.get("series" /* Series */)?.has(seriesType)) {
        delete overridesObj[seriesType];
        continue;
      }
      pruneSeriesEntry(overridesObj[seriesType]);
    }
  }
  if (isObject(presets)) {
    const presetsObj = presets;
    for (const presetName of Object.keys(presetsObj)) {
      if (missingModules.get("preset" /* Preset */)?.has(presetName) || missingModules.get("series" /* Series */)?.has(presetName)) {
        delete presetsObj[presetName];
        continue;
      }
      prunePlugins(presetsObj[presetName]);
      pruneAxes(presetsObj[presetName]?.axes);
    }
  }
  return Object.create(theme, {
    config: { value: deepFreeze(config), enumerable: true },
    overrides: { value: isObject(overrides) ? deepFreeze(overrides) : overrides, enumerable: true },
    presets: { value: isObject(presets) ? deepFreeze(presets) : presets, enumerable: true }
  });
}
function processModuleOptions(chartType, options, additionalMissingModules) {
  const missingModules = unique(removeUnregisteredModuleOptions(chartType, options).concat(additionalMissingModules));
  if (!missingModules.length)
    return;
  const installationReferenceUrl = moduleRegistry_exports.isIntegrated() ? "https://www.ag-grid.com/data-grid/integrated-charts-installation/" : "https://www.ag-grid.com/charts/r/module-registry/";
  const missingOptions = groupBy(missingModules, (module2) => module2.enterprise ? "enterprise" : "community");
  if (missingModules.length) {
    const packageName = moduleRegistry_exports.isEnterprise() || missingOptions.enterprise?.length ? "enterprise" : "community";
    logger_exports.errorOnce(
      [
        "required modules are not registered. Check if you have registered the modules:",
        "",
        moduleRegistry_exports.isUmd() ? `Install and register 'ag-charts-enterprise' before creating the chart.` : createRegistrySnippet(missingModules.map(formatMissingModuleName), packageName),
        "",
        `See ${installationReferenceUrl} for more details.`
      ].join("\n")
    );
  }
}
function formatMissingModuleName(module2) {
  return module2.moduleId ?? module2.name;
}
function formatImportItem(name) {
  return `    ${name},`;
}
function formatImports(imports, packageName) {
  return imports.length ? `import {
${imports.map(formatImportItem).join("\n")}
} from 'ag-charts-${packageName}';` : null;
}
function createRegistrySnippet(moduleNames, packageName) {
  const imports = formatImports(["ModuleRegistry"].concat(moduleNames), packageName);
  const moduleList = moduleNames.map(formatImportItem).join("\n");
  return `${imports}

ModuleRegistry.registerModules([
${moduleList}
]);`;
}
function removeUnregisteredModuleOptions(chartType, options) {
  const missingModules = /* @__PURE__ */ new Map();
  const optionsAxes = "axes" in options && isObject(options.axes) ? options.axes : {};
  const axisTypesInOptions = new Set(
    Object.values(optionsAxes).map((axis) => axis?.type).filter(isDefined)
  );
  const seriesTypesInOptions = new Set(options.series?.map((series) => series.type).filter(isDefined));
  function addMissingModule(module2) {
    missingModules.set(module2.name, module2);
  }
  for (const module2 of ExpectedModules.values()) {
    if (moduleRegistry_exports.hasModule(module2.name))
      continue;
    if (SkippedModules.has(module2.name))
      continue;
    if (chartType && module2.chartType && chartType !== module2.chartType)
      continue;
    switch (module2.type) {
      case "chart":
        break;
      case "axis":
        if (axisTypesInOptions.has(module2.name)) {
          for (const key of Object.keys(optionsAxes)) {
            if (optionsAxes?.[key].type === module2.name) {
              delete optionsAxes[key];
            }
          }
          addMissingModule(module2);
        }
        break;
      case "series":
        if (seriesTypesInOptions.has(module2.name)) {
          options.series = options.series.filter((series) => series.type !== module2.name);
          addMissingModule(module2);
        }
        break;
      case "plugin":
        const optionsKey = module2.name;
        const pluginValue = options[optionsKey];
        if (isObject(pluginValue)) {
          if (pluginValue.enabled !== false) {
            addMissingModule(module2);
          }
          delete options[optionsKey];
        }
        break;
      case "axis:plugin":
        for (const axis of Object.values(optionsAxes)) {
          const axisModuleKey = module2.name;
          if (axis?.[axisModuleKey]) {
            if (axis[axisModuleKey].enabled !== false) {
              addMissingModule(module2);
            }
            delete axis[axisModuleKey];
          }
        }
        break;
      case "series:plugin":
        for (const series of options.series ?? []) {
          if (series[module2.name]) {
            delete series[module2.name];
            addMissingModule(module2);
          }
        }
        break;
    }
  }
  for (const seriesType of seriesTypesInOptions) {
    const expectedSeriesModule = ExpectedModules.get(seriesType);
    if (expectedSeriesModule?.type === "series" /* Series */ && !moduleRegistry_exports.hasModule(expectedSeriesModule.name) && !missingModules.has(expectedSeriesModule.name)) {
      options.series = options.series.filter((series) => series.type !== expectedSeriesModule.name);
      addMissingModule(expectedSeriesModule);
    }
  }
  return Array.from(missingModules.values());
}
function removeIncompatibleModuleOptions(chartType, options) {
  const hasAxesOptions = "axes" in options && isObject(options.axes);
  const hasSeriesOptions = "series" in options && isArray(options.series);
  const matchChartType = (module2) => chartType == null || !module2.chartType || module2.chartType === chartType;
  const incompatibleModules = [];
  for (const module2 of moduleRegistry_exports.listModules()) {
    if (moduleRegistry_exports.isModuleType("plugin" /* Plugin */, module2)) {
      if (!matchChartType(module2)) {
        delete options[module2.name];
        incompatibleModules.push(module2.name);
      }
    } else if (moduleRegistry_exports.isModuleType("axis:plugin" /* AxisPlugin */, module2)) {
      if (hasAxesOptions && !matchChartType(module2)) {
        for (const axis of Object.values(options.axes)) {
          delete axis[module2.name];
        }
        incompatibleModules.push(module2.name);
      }
    } else if (moduleRegistry_exports.isModuleType("series:plugin" /* SeriesPlugin */, module2)) {
      if (hasSeriesOptions && !matchChartType(module2)) {
        for (const series of options.series) {
          delete series[module2.name];
        }
        incompatibleModules.push(module2.name);
      }
    }
  }
  return incompatibleModules;
}

// packages/ag-charts-community/src/chart/themes/darkTheme.ts
var DEFAULT_DARK_BACKGROUND_FILL = "#192232";
var DEFAULT_DARK_FILLS = {
  BLUE: "#5090dc",
  ORANGE: "#ffa03a",
  GREEN: "#459d55",
  CYAN: "#34bfe1",
  YELLOW: "#e1cc00",
  VIOLET: "#9669cb",
  GRAY: "#b5b5b5",
  MAGENTA: "#bd5aa7",
  BROWN: "#8a6224",
  RED: "#ef5452"
};
var DEFAULT_DARK_STROKES = {
  BLUE: "#74a8e6",
  ORANGE: "#ffbe70",
  GREEN: "#6cb176",
  CYAN: "#75d4ef",
  YELLOW: "#f6e559",
  VIOLET: "#aa86d8",
  GRAY: "#a1a1a1",
  MAGENTA: "#ce7ab9",
  BROWN: "#997b52",
  RED: "#ff7872"
};
var DarkTheme = class extends ChartTheme {
  getDefaultColors() {
    return {
      fills: DEFAULT_DARK_FILLS,
      fillsFallback: Object.values(DEFAULT_DARK_FILLS),
      strokes: DEFAULT_DARK_STROKES,
      sequentialColors: getSequentialColors(DEFAULT_DARK_FILLS),
      divergingColors: [DEFAULT_DARK_FILLS.ORANGE, DEFAULT_DARK_FILLS.YELLOW, DEFAULT_DARK_FILLS.GREEN],
      hierarchyColors: ["#192834", "#253746", "#324859", "#3f596c", "#4d6a80"],
      secondSequentialColors: [
        "#5090dc",
        "#4882c6",
        "#4073b0",
        "#38659a",
        "#305684",
        "#28486e",
        "#203a58",
        "#182b42"
      ],
      secondDivergingColors: [DEFAULT_DARK_FILLS.GREEN, DEFAULT_DARK_FILLS.YELLOW, DEFAULT_DARK_FILLS.RED],
      secondHierarchyColors: ["#192834", "#3b5164", "#496275", "#577287", "#668399"],
      up: { fill: DEFAULT_DARK_FILLS.GREEN, stroke: DEFAULT_DARK_STROKES.GREEN },
      down: { fill: DEFAULT_DARK_FILLS.RED, stroke: DEFAULT_DARK_STROKES.RED },
      neutral: { fill: DEFAULT_DARK_FILLS.GRAY, stroke: DEFAULT_DARK_STROKES.GRAY },
      altUp: { fill: DEFAULT_DARK_FILLS.BLUE, stroke: DEFAULT_DARK_STROKES.BLUE },
      altDown: { fill: DEFAULT_DARK_FILLS.ORANGE, stroke: DEFAULT_DARK_STROKES.ORANGE },
      altNeutral: { fill: DEFAULT_DARK_FILLS.GRAY, stroke: DEFAULT_DARK_STROKES.GRAY }
    };
  }
  getPublicParameters() {
    return {
      ...super.getPublicParameters(),
      axisColor: { $foregroundBackgroundMix: 0.737 },
      backgroundColor: DEFAULT_DARK_BACKGROUND_FILL,
      borderColor: { $foregroundBackgroundMix: 0.216 },
      chromeBackgroundColor: { $foregroundBackgroundMix: 0.07 },
      foregroundColor: "#fff",
      gridLineColor: { $foregroundBackgroundMix: 0.257 },
      popupShadow: "0 0 16px rgba(0, 0, 0, 0.33)",
      subtleTextColor: { $mix: [{ $ref: "textColor" }, { $ref: "chartBackgroundColor" }, 0.57] },
      separationLinesColor: { $foregroundBackgroundMix: 0.44 },
      crosshairLabelBackgroundColor: { $foregroundBackgroundMix: 0.65 }
    };
  }
  getTemplateParameters() {
    const params = super.getTemplateParameters();
    params.set(IS_DARK_THEME, true);
    params.set(DEFAULT_POLAR_SERIES_STROKE, DEFAULT_DARK_BACKGROUND_FILL);
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, DEFAULT_DARK_FILLS.BLUE);
    params.set(DEFAULT_TEXT_ANNOTATION_COLOR, "#fff");
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, DEFAULT_DARK_FILLS.BLUE);
    params.set(DEFAULT_ANNOTATION_HANDLE_FILL, DEFAULT_DARK_BACKGROUND_FILL);
    params.set(DEFAULT_ANNOTATION_STATISTICS_FILL, "#28313e");
    params.set(DEFAULT_ANNOTATION_STATISTICS_STROKE, "#4b525d");
    params.set(DEFAULT_ANNOTATION_STATISTICS_COLOR, "#fff");
    params.set(DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE, "#fff");
    params.set(DEFAULT_TEXTBOX_FILL, "#28313e");
    params.set(DEFAULT_TEXTBOX_STROKE, "#4b525d");
    params.set(DEFAULT_TEXTBOX_COLOR, "#fff");
    return params;
  }
  constructor(options) {
    super(options);
  }
};

// packages/ag-charts-community/src/chart/themes/financialDark.ts
var FINANCIAL_DARK_FILLS = {
  GREEN: "#089981",
  RED: "#F23645",
  BLUE: "#5090dc",
  GRAY: "#A9A9A9"
};
var FINANCIAL_DARK_STROKES = {
  GREEN: "#089981",
  RED: "#F23645",
  BLUE: "#5090dc",
  GRAY: "#909090"
};
var FinancialDark = class extends DarkTheme {
  getDefaultColors() {
    return {
      ...super.getDefaultColors(),
      fills: { ...FINANCIAL_DARK_FILLS },
      fillsFallback: Object.values({ ...FINANCIAL_DARK_FILLS }),
      strokes: { ...FINANCIAL_DARK_STROKES },
      sequentialColors: getSequentialColors(FINANCIAL_DARK_FILLS),
      divergingColors: [FINANCIAL_DARK_FILLS.GREEN, FINANCIAL_DARK_FILLS.BLUE, FINANCIAL_DARK_FILLS.RED],
      // hierarchyColors: [],
      secondSequentialColors: [
        "#5090dc",
        "#4882c6",
        "#4073b0",
        "#38659a",
        "#305684",
        "#28486e",
        "#203a58",
        "#182b42"
      ],
      // secondDivergingColors: [],
      // secondHierarchyColors: [],
      up: { fill: FINANCIAL_DARK_FILLS.GREEN, stroke: FINANCIAL_DARK_STROKES.GREEN },
      down: { fill: FINANCIAL_DARK_FILLS.RED, stroke: FINANCIAL_DARK_STROKES.RED },
      neutral: { fill: FINANCIAL_DARK_FILLS.BLUE, stroke: FINANCIAL_DARK_STROKES.BLUE },
      altUp: { fill: FINANCIAL_DARK_FILLS.GREEN, stroke: FINANCIAL_DARK_STROKES.GREEN },
      altDown: { fill: FINANCIAL_DARK_FILLS.RED, stroke: FINANCIAL_DARK_STROKES.RED },
      altNeutral: { fill: FINANCIAL_DARK_FILLS.GRAY, stroke: FINANCIAL_DARK_STROKES.GRAY }
    };
  }
  getPublicParameters() {
    return {
      ...super.getPublicParameters(),
      chartPadding: 0,
      gridLineColor: { $foregroundBackgroundMix: 0.12 }
    };
  }
  getTemplateParameters() {
    const params = super.getTemplateParameters();
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, FINANCIAL_DARK_FILLS.BLUE);
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, FINANCIAL_DARK_FILLS.BLUE);
    params.set(DEFAULT_CAPTION_LAYOUT_STYLE, "overlay");
    params.set(DEFAULT_CAPTION_ALIGNMENT, "left");
    params.set(DEFAULT_TOOLBAR_POSITION, "bottom");
    return params;
  }
};

// packages/ag-charts-community/src/chart/themes/financialLight.ts
var FINANCIAL_LIGHT_FILLS = {
  GREEN: "#089981",
  RED: "#F23645",
  BLUE: "#5090dc",
  GRAY: "#A9A9A9"
};
var FINANCIAL_LIGHT_STROKES = {
  GREEN: "#089981",
  RED: "#F23645",
  BLUE: "#5090dc",
  GRAY: "#909090"
};
var FinancialLight = class extends ChartTheme {
  getDefaultColors() {
    return {
      ...super.getDefaultColors(),
      fills: { ...FINANCIAL_LIGHT_FILLS },
      fillsFallback: Object.values({ ...FINANCIAL_LIGHT_FILLS }),
      strokes: { ...FINANCIAL_LIGHT_STROKES },
      sequentialColors: getSequentialColors(FINANCIAL_LIGHT_FILLS),
      divergingColors: [FINANCIAL_LIGHT_FILLS.GREEN, FINANCIAL_LIGHT_FILLS.BLUE, FINANCIAL_LIGHT_FILLS.RED],
      // hierarchyColors: [],
      // secondSequentialColors: [],
      // secondDivergingColors: [],
      // secondHierarchyColors: [],
      up: { fill: FINANCIAL_LIGHT_FILLS.GREEN, stroke: FINANCIAL_LIGHT_STROKES.GREEN },
      down: { fill: FINANCIAL_LIGHT_FILLS.RED, stroke: FINANCIAL_LIGHT_STROKES.RED },
      neutral: { fill: FINANCIAL_LIGHT_FILLS.BLUE, stroke: FINANCIAL_LIGHT_STROKES.BLUE },
      altUp: { fill: FINANCIAL_LIGHT_FILLS.GREEN, stroke: FINANCIAL_LIGHT_STROKES.GREEN },
      altDown: { fill: FINANCIAL_LIGHT_FILLS.RED, stroke: FINANCIAL_LIGHT_STROKES.RED },
      altNeutral: { fill: FINANCIAL_LIGHT_FILLS.GRAY, stroke: FINANCIAL_LIGHT_STROKES.GRAY }
    };
  }
  getPublicParameters() {
    return {
      ...super.getPublicParameters(),
      chartPadding: 0,
      gridLineColor: { $foregroundBackgroundMix: 0.06 }
    };
  }
  getTemplateParameters() {
    const params = super.getTemplateParameters();
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, FINANCIAL_LIGHT_FILLS.BLUE);
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, FINANCIAL_LIGHT_FILLS.BLUE);
    params.set(DEFAULT_CAPTION_LAYOUT_STYLE, "overlay");
    params.set(DEFAULT_CAPTION_ALIGNMENT, "left");
    params.set(DEFAULT_TOOLBAR_POSITION, "bottom");
    return params;
  }
};

// packages/ag-charts-community/src/chart/themes/materialDark.ts
var MATERIAL_DARK_FILLS = {
  BLUE: "#2196F3",
  ORANGE: "#FF9800",
  GREEN: "#4CAF50",
  CYAN: "#00BCD4",
  YELLOW: "#FFEB3B",
  VIOLET: "#7E57C2",
  GRAY: "#9E9E9E",
  MAGENTA: "#F06292",
  BROWN: "#795548",
  RED: "#F44336"
};
var MATERIAL_DARK_STROKES = {
  BLUE: "#90CAF9",
  ORANGE: "#FFCC80",
  GREEN: "#A5D6A7",
  CYAN: "#80DEEA",
  YELLOW: "#FFF9C4",
  VIOLET: "#B39DDB",
  GRAY: "#E0E0E0",
  MAGENTA: "#F48FB1",
  BROWN: "#A1887F",
  RED: "#EF9A9A"
};
var MaterialDark = class extends DarkTheme {
  getDefaultColors() {
    return {
      ...super.getDefaultColors(),
      fills: MATERIAL_DARK_FILLS,
      fillsFallback: Object.values(MATERIAL_DARK_FILLS),
      strokes: MATERIAL_DARK_STROKES,
      sequentialColors: getSequentialColors(MATERIAL_DARK_FILLS),
      divergingColors: [MATERIAL_DARK_FILLS.ORANGE, MATERIAL_DARK_FILLS.YELLOW, MATERIAL_DARK_FILLS.GREEN],
      // hierarchyColors: [],
      secondSequentialColors: [
        "#2196f3",
        // 500
        "#208FEC",
        // (interpolated)
        "#1E88E5",
        // 600
        "#1C7FDC",
        // (interpolated)
        "#1976d2",
        // 700
        "#176EC9",
        // (interpolated)
        "#1565c0"
        // 800
      ],
      secondDivergingColors: [MATERIAL_DARK_FILLS.GREEN, MATERIAL_DARK_FILLS.YELLOW, MATERIAL_DARK_FILLS.RED],
      // secondHierarchyColors: [],
      up: { fill: MATERIAL_DARK_FILLS.GREEN, stroke: MATERIAL_DARK_STROKES.GREEN },
      down: { fill: MATERIAL_DARK_FILLS.RED, stroke: MATERIAL_DARK_STROKES.RED },
      neutral: { fill: MATERIAL_DARK_FILLS.GRAY, stroke: MATERIAL_DARK_STROKES.GRAY },
      altUp: { fill: MATERIAL_DARK_FILLS.BLUE, stroke: MATERIAL_DARK_STROKES.BLUE },
      altDown: { fill: MATERIAL_DARK_FILLS.RED, stroke: MATERIAL_DARK_STROKES.RED },
      altNeutral: { fill: MATERIAL_DARK_FILLS.GRAY, stroke: MATERIAL_DARK_STROKES.GRAY }
    };
  }
  getTemplateParameters() {
    const params = super.getTemplateParameters();
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, MATERIAL_DARK_FILLS.BLUE);
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, MATERIAL_DARK_FILLS.BLUE);
    return params;
  }
};

// packages/ag-charts-community/src/chart/themes/materialLight.ts
var MATERIAL_LIGHT_FILLS = {
  BLUE: "#2196F3",
  ORANGE: "#FF9800",
  GREEN: "#4CAF50",
  CYAN: "#00BCD4",
  YELLOW: "#FFEB3B",
  VIOLET: "#7E57C2",
  GRAY: "#9E9E9E",
  MAGENTA: "#F06292",
  BROWN: "#795548",
  RED: "#F44336"
};
var MATERIAL_LIGHT_STROKES = {
  BLUE: "#1565C0",
  ORANGE: "#E65100",
  GREEN: "#2E7D32",
  CYAN: "#00838F",
  YELLOW: "#F9A825",
  VIOLET: "#4527A0",
  GRAY: "#616161",
  MAGENTA: "#C2185B",
  BROWN: "#4E342E",
  RED: "#B71C1C"
};
var MaterialLight = class extends ChartTheme {
  getDefaultColors() {
    return {
      ...super.getDefaultColors(),
      fills: MATERIAL_LIGHT_FILLS,
      fillsFallback: Object.values(MATERIAL_LIGHT_FILLS),
      strokes: MATERIAL_LIGHT_STROKES,
      sequentialColors: getSequentialColors(MATERIAL_LIGHT_FILLS),
      divergingColors: [MATERIAL_LIGHT_FILLS.ORANGE, MATERIAL_LIGHT_FILLS.YELLOW, MATERIAL_LIGHT_FILLS.GREEN],
      // hierarchyColors: [],
      secondSequentialColors: [
        "#2196f3",
        // 500
        "#329EF4",
        // (interpolated)
        "#42a5f5",
        // 400
        "#53ADF6",
        // (interpolated)
        "#64b5f6",
        // 300
        "#7AC0F8",
        // (interpolated)
        "#90caf9"
        // 200
      ],
      secondDivergingColors: [MATERIAL_LIGHT_FILLS.GREEN, MATERIAL_LIGHT_FILLS.YELLOW, MATERIAL_LIGHT_FILLS.RED],
      // secondHierarchyColors: [],
      up: { fill: MATERIAL_LIGHT_FILLS.GREEN, stroke: MATERIAL_LIGHT_STROKES.GREEN },
      down: { fill: MATERIAL_LIGHT_FILLS.RED, stroke: MATERIAL_LIGHT_STROKES.RED },
      neutral: { fill: MATERIAL_LIGHT_FILLS.GRAY, stroke: MATERIAL_LIGHT_STROKES.GRAY },
      altUp: { fill: MATERIAL_LIGHT_FILLS.BLUE, stroke: MATERIAL_LIGHT_STROKES.BLUE },
      altDown: { fill: MATERIAL_LIGHT_FILLS.RED, stroke: MATERIAL_LIGHT_STROKES.RED },
      altNeutral: { fill: MATERIAL_LIGHT_FILLS.GRAY, stroke: MATERIAL_LIGHT_STROKES.GRAY }
    };
  }
  getTemplateParameters() {
    const params = super.getTemplateParameters();
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, MATERIAL_LIGHT_FILLS.BLUE);
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, MATERIAL_LIGHT_FILLS.BLUE);
    return params;
  }
};

// packages/ag-charts-community/src/chart/themes/polychromaDark.ts
var POLYCHROMA_DARK_FILLS = {
  BLUE: "#436ff4",
  PURPLE: "#9a7bff",
  MAGENTA: "#d165d2",
  PINK: "#f0598b",
  RED: "#f47348",
  ORANGE: "#f2a602",
  YELLOW: "#e9e201",
  GREEN: "#21b448",
  CYAN: "#00b9a2",
  MODERATE_BLUE: "#00aee4",
  GRAY: "#bbbbbb"
};
var POLYCHROMA_DARK_STROKES = {
  BLUE: "#6698ff",
  PURPLE: "#c0a3ff",
  MAGENTA: "#fc8dfc",
  PINK: "#ff82b1",
  RED: "#ff9b70",
  ORANGE: "#ffcf4e",
  YELLOW: "#ffff58",
  GREEN: "#58dd70",
  CYAN: "#51e2c9",
  MODERATE_BLUE: "#4fd7ff",
  GRAY: "#eeeeee"
};
var PolychromaDark = class extends DarkTheme {
  getDefaultColors() {
    return {
      fills: POLYCHROMA_DARK_FILLS,
      fillsFallback: Object.values(POLYCHROMA_DARK_FILLS),
      strokes: POLYCHROMA_DARK_STROKES,
      sequentialColors: getSequentialColors(POLYCHROMA_DARK_FILLS),
      divergingColors: [POLYCHROMA_DARK_FILLS.BLUE, POLYCHROMA_DARK_FILLS.RED],
      hierarchyColors: [],
      secondSequentialColors: [
        POLYCHROMA_DARK_FILLS.BLUE,
        POLYCHROMA_DARK_FILLS.PURPLE,
        POLYCHROMA_DARK_FILLS.MAGENTA,
        POLYCHROMA_DARK_FILLS.PINK,
        POLYCHROMA_DARK_FILLS.RED,
        POLYCHROMA_DARK_FILLS.ORANGE,
        POLYCHROMA_DARK_FILLS.YELLOW,
        POLYCHROMA_DARK_FILLS.GREEN
      ],
      secondDivergingColors: [POLYCHROMA_DARK_FILLS.BLUE, POLYCHROMA_DARK_FILLS.RED],
      secondHierarchyColors: [],
      up: { fill: POLYCHROMA_DARK_FILLS.GREEN, stroke: POLYCHROMA_DARK_STROKES.GREEN },
      down: { fill: POLYCHROMA_DARK_FILLS.RED, stroke: POLYCHROMA_DARK_STROKES.RED },
      neutral: { fill: POLYCHROMA_DARK_FILLS.GRAY, stroke: POLYCHROMA_DARK_STROKES.GRAY },
      altUp: { fill: POLYCHROMA_DARK_FILLS.BLUE, stroke: POLYCHROMA_DARK_STROKES.BLUE },
      altDown: { fill: POLYCHROMA_DARK_FILLS.RED, stroke: POLYCHROMA_DARK_STROKES.RED },
      altNeutral: { fill: POLYCHROMA_DARK_FILLS.GRAY, stroke: POLYCHROMA_DARK_STROKES.GRAY }
    };
  }
  getTemplateParameters() {
    const params = super.getTemplateParameters();
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, POLYCHROMA_DARK_FILLS.BLUE);
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, POLYCHROMA_DARK_FILLS.BLUE);
    return params;
  }
};

// packages/ag-charts-community/src/chart/themes/polychromaLight.ts
var POLYCHROMA_LIGHT_FILLS = {
  BLUE: "#436ff4",
  PURPLE: "#9a7bff",
  MAGENTA: "#d165d2",
  PINK: "#f0598b",
  RED: "#f47348",
  ORANGE: "#f2a602",
  YELLOW: "#e9e201",
  GREEN: "#21b448",
  CYAN: "#00b9a2",
  MODERATE_BLUE: "#00aee4",
  GRAY: "#bbbbbb"
};
var POLYCHROMA_LIGHT_STROKES = {
  BLUE: "#2346c9",
  PURPLE: "#7653d4",
  MAGENTA: "#a73da9",
  PINK: "#c32d66",
  RED: "#c84b1c",
  ORANGE: "#c87f00",
  YELLOW: "#c1b900",
  GREEN: "#008c1c",
  CYAN: "#00927c",
  MODERATE_BLUE: "#0087bb",
  GRAY: "#888888"
};
var PolychromaLight = class extends ChartTheme {
  getDefaultColors() {
    return {
      ...super.getDefaultColors(),
      fills: POLYCHROMA_LIGHT_FILLS,
      fillsFallback: Object.values(POLYCHROMA_LIGHT_FILLS),
      strokes: POLYCHROMA_LIGHT_STROKES,
      sequentialColors: getSequentialColors(POLYCHROMA_LIGHT_FILLS),
      divergingColors: [POLYCHROMA_LIGHT_FILLS.BLUE, POLYCHROMA_LIGHT_FILLS.RED],
      hierarchyColors: [],
      secondSequentialColors: [
        POLYCHROMA_LIGHT_FILLS.BLUE,
        POLYCHROMA_LIGHT_FILLS.PURPLE,
        POLYCHROMA_LIGHT_FILLS.MAGENTA,
        POLYCHROMA_LIGHT_FILLS.PINK,
        POLYCHROMA_LIGHT_FILLS.RED,
        POLYCHROMA_LIGHT_FILLS.ORANGE,
        POLYCHROMA_LIGHT_FILLS.YELLOW,
        POLYCHROMA_LIGHT_FILLS.GREEN
      ],
      secondDivergingColors: [POLYCHROMA_LIGHT_FILLS.BLUE, POLYCHROMA_LIGHT_FILLS.RED],
      secondHierarchyColors: [],
      up: { fill: POLYCHROMA_LIGHT_FILLS.GREEN, stroke: POLYCHROMA_LIGHT_STROKES.GREEN },
      down: { fill: POLYCHROMA_LIGHT_FILLS.RED, stroke: POLYCHROMA_LIGHT_STROKES.RED },
      neutral: { fill: POLYCHROMA_LIGHT_FILLS.GRAY, stroke: POLYCHROMA_LIGHT_STROKES.GRAY },
      altUp: { fill: POLYCHROMA_LIGHT_FILLS.BLUE, stroke: POLYCHROMA_LIGHT_STROKES.BLUE },
      altDown: { fill: POLYCHROMA_LIGHT_FILLS.RED, stroke: POLYCHROMA_LIGHT_STROKES.RED },
      altNeutral: { fill: POLYCHROMA_LIGHT_FILLS.GRAY, stroke: POLYCHROMA_LIGHT_STROKES.GRAY }
    };
  }
  getTemplateParameters() {
    const params = super.getTemplateParameters();
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, POLYCHROMA_LIGHT_FILLS.BLUE);
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, POLYCHROMA_LIGHT_FILLS.BLUE);
    return params;
  }
};

// packages/ag-charts-community/src/chart/themes/sheetsDark.ts
var SHEETS_DARK_FILLS = {
  BLUE: "#4472C4",
  ORANGE: "#ED7D31",
  GRAY: "#A5A5A5",
  YELLOW: "#FFC000",
  MODERATE_BLUE: "#5B9BD5",
  GREEN: "#70AD47",
  DARK_GRAY: "#7B7B7B",
  DARK_BLUE: "#264478",
  VERY_DARK_GRAY: "#636363",
  DARK_YELLOW: "#997300"
};
var SHEETS_DARK_STROKES = {
  BLUE: "#6899ee",
  ORANGE: "#ffa55d",
  GRAY: "#cdcdcd",
  YELLOW: "#ffea53",
  MODERATE_BLUE: "#82c3ff",
  GREEN: "#96d56f",
  DARK_GRAY: "#a1a1a1",
  DARK_BLUE: "#47689f",
  VERY_DARK_GRAY: "#878787",
  DARK_YELLOW: "#c0993d"
};
var SheetsDark = class extends DarkTheme {
  getDefaultColors() {
    return {
      ...super.getDefaultColors(),
      fills: { ...SHEETS_DARK_FILLS, RED: SHEETS_DARK_FILLS.ORANGE },
      fillsFallback: Object.values({ ...SHEETS_DARK_FILLS, RED: SHEETS_DARK_FILLS.ORANGE }),
      strokes: { ...SHEETS_DARK_STROKES, RED: SHEETS_DARK_STROKES.ORANGE },
      sequentialColors: getSequentialColors({ ...SHEETS_DARK_FILLS, RED: SHEETS_DARK_FILLS.ORANGE }),
      divergingColors: [SHEETS_DARK_FILLS.ORANGE, SHEETS_DARK_FILLS.YELLOW, SHEETS_DARK_FILLS.GREEN],
      // hierarchyColors: [],
      secondSequentialColors: [
        "#5090dc",
        "#4882c6",
        "#4073b0",
        "#38659a",
        "#305684",
        "#28486e",
        "#203a58",
        "#182b42"
      ],
      secondDivergingColors: [SHEETS_DARK_FILLS.GREEN, SHEETS_DARK_FILLS.YELLOW, SHEETS_DARK_FILLS.ORANGE],
      // secondHierarchyColors: [],
      up: { fill: SHEETS_DARK_FILLS.GREEN, stroke: SHEETS_DARK_STROKES.GREEN },
      down: { fill: SHEETS_DARK_FILLS.ORANGE, stroke: SHEETS_DARK_STROKES.ORANGE },
      neutral: { fill: SHEETS_DARK_FILLS.GRAY, stroke: SHEETS_DARK_STROKES.GRAY },
      altUp: { fill: SHEETS_DARK_FILLS.BLUE, stroke: SHEETS_DARK_STROKES.BLUE },
      altDown: { fill: SHEETS_DARK_FILLS.ORANGE, stroke: SHEETS_DARK_STROKES.ORANGE },
      altNeutral: { fill: SHEETS_DARK_FILLS.GRAY, stroke: SHEETS_DARK_STROKES.GRAY }
    };
  }
  getTemplateParameters() {
    const params = super.getTemplateParameters();
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, SHEETS_DARK_FILLS.BLUE);
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, SHEETS_DARK_FILLS.BLUE);
    return params;
  }
};

// packages/ag-charts-community/src/chart/themes/sheetsLight.ts
var SHEETS_LIGHT_FILLS = {
  BLUE: "#5281d5",
  ORANGE: "#ff8d44",
  GRAY: "#b5b5b5",
  YELLOW: "#ffd02f",
  MODERATE_BLUE: "#6aabe6",
  GREEN: "#7fbd57",
  DARK_GRAY: "#8a8a8a",
  DARK_BLUE: "#335287",
  VERY_DARK_GRAY: "#717171",
  DARK_YELLOW: "#a98220"
};
var SHEETS_LIGHT_STROKES = {
  BLUE: "#214d9b",
  ORANGE: "#c25600",
  GRAY: "#7f7f7f",
  YELLOW: "#d59800",
  MODERATE_BLUE: "#3575ac",
  GREEN: "#4b861a",
  DARK_GRAY: "#575757",
  DARK_BLUE: "#062253",
  VERY_DARK_GRAY: "#414141",
  DARK_YELLOW: "#734f00"
};
var SheetsLight = class extends ChartTheme {
  getDefaultColors() {
    return {
      ...super.getDefaultColors(),
      fills: { ...SHEETS_LIGHT_FILLS, RED: SHEETS_LIGHT_FILLS.ORANGE },
      fillsFallback: Object.values({ ...SHEETS_LIGHT_FILLS, RED: SHEETS_LIGHT_FILLS.ORANGE }),
      strokes: { ...SHEETS_LIGHT_STROKES, RED: SHEETS_LIGHT_STROKES.ORANGE },
      sequentialColors: getSequentialColors({ ...SHEETS_LIGHT_FILLS, RED: SHEETS_LIGHT_FILLS.ORANGE }),
      divergingColors: [SHEETS_LIGHT_FILLS.ORANGE, SHEETS_LIGHT_FILLS.YELLOW, SHEETS_LIGHT_FILLS.GREEN],
      // hierarchyColors: [],
      secondSequentialColors: [
        "#5090dc",
        "#629be0",
        "#73a6e3",
        "#85b1e7",
        "#96bcea",
        "#a8c8ee",
        "#b9d3f1",
        "#cbdef5"
      ],
      secondDivergingColors: [SHEETS_LIGHT_FILLS.GREEN, SHEETS_LIGHT_FILLS.YELLOW, SHEETS_LIGHT_FILLS.ORANGE],
      secondHierarchyColors: [],
      up: { fill: SHEETS_LIGHT_FILLS.GREEN, stroke: SHEETS_LIGHT_STROKES.GREEN },
      down: { fill: SHEETS_LIGHT_FILLS.ORANGE, stroke: SHEETS_LIGHT_STROKES.ORANGE },
      neutral: { fill: SHEETS_LIGHT_STROKES.GRAY, stroke: SHEETS_LIGHT_STROKES.GRAY },
      altUp: { fill: SHEETS_LIGHT_FILLS.BLUE, stroke: SHEETS_LIGHT_STROKES.BLUE },
      altDown: { fill: SHEETS_LIGHT_FILLS.ORANGE, stroke: SHEETS_LIGHT_STROKES.ORANGE },
      altNeutral: { fill: SHEETS_LIGHT_FILLS.GRAY, stroke: SHEETS_LIGHT_STROKES.GRAY }
    };
  }
  getTemplateParameters() {
    const params = super.getTemplateParameters();
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, SHEETS_LIGHT_FILLS.BLUE);
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, SHEETS_LIGHT_FILLS.BLUE);
    return params;
  }
};

// packages/ag-charts-community/src/chart/axesOptionsDefs.ts
var timeIntervalUnit = union("millisecond", "second", "minute", "hour", "day", "month", "year");
var timeIntervalDefs = {
  unit: required(timeIntervalUnit),
  step: positiveNumberNonZero,
  epoch: date,
  utc: boolean
};
timeIntervalDefs.every = callback;
var timeInterval2 = optionsDefs(timeIntervalDefs, "a time interval object");
var commonCrossLineLabelOptionsDefs = {
  enabled: boolean,
  text: string,
  padding: number,
  border: borderOptionsDef,
  cornerRadius: number,
  ...fontOptionsDef,
  ...fillOptionsDef
};
var commonCrossLineOptionsDefs = attachDescription(
  {
    enabled: boolean,
    type: required(union("line", "range")),
    range: and(
      attachDescription((_, { options }) => options.type === "range", "crossLine type to be 'range'"),
      arrayOf(defined),
      arrayLength(2, 2)
    ),
    value: and(
      attachDescription((_, { options }) => options.type === "line", "crossLine type to be 'line'"),
      defined
    ),
    label: commonCrossLineLabelOptionsDefs,
    fill: color,
    fillOpacity: ratio,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  },
  "cross-line options"
);
var cartesianCrossLineOptionsDefs = {
  ...commonCrossLineOptionsDefs,
  label: {
    ...commonCrossLineLabelOptionsDefs,
    position: union(
      "top",
      "left",
      "right",
      "bottom",
      "top-left",
      "top-right",
      "bottom-left",
      "bottom-right",
      "inside",
      "inside-left",
      "inside-right",
      "inside-top",
      "inside-bottom",
      "inside-top-left",
      "inside-bottom-left",
      "inside-top-right",
      "inside-bottom-right"
    ),
    rotation: number
  }
};
var commonAxisLabelOptionsDefs = {
  enabled: boolean,
  rotation: number,
  avoidCollisions: boolean,
  minSpacing: positiveNumber,
  spacing: positiveNumber,
  formatter: callbackOf(textOrSegments),
  itemStyler: callbackDefs({
    ...fontOptionsDef,
    ...labelBoxOptionsDef,
    spacing: number
  }),
  ...fontOptionsDef,
  ...labelBoxOptionsDef
};
var cartesianAxisLabelOptionsDefs = {
  autoRotate: boolean,
  autoRotateAngle: number,
  wrapping: union("never", "always", "hyphenate", "on-space"),
  truncate: boolean,
  ...commonAxisLabelOptionsDefs
};
var cartesianNumericAxisLabel = {
  format: numberFormatValidator,
  ...cartesianAxisLabelOptionsDefs
};
var cartesianTimeAxisLabel = {
  format: or(string, object),
  ...cartesianAxisLabelOptionsDefs
};
var cartesianAxisTick = {
  enabled: boolean,
  width: positiveNumber,
  size: positiveNumber,
  stroke: color
};
var cartesianTimeAxisParentLevel = {
  enabled: boolean,
  label: cartesianTimeAxisLabel,
  tick: cartesianAxisTick
};
var commonAxisIntervalOptionsDefs = {
  values: arrayOf(defined),
  minSpacing: positiveNumber
};
var commonAxisOptionsDefs = {
  reverse: boolean,
  gridLine: {
    enabled: boolean,
    width: positiveNumber,
    style: arrayOfDefs(
      {
        fill: color,
        fillOpacity: positiveNumber,
        stroke: or(color, themeOperator),
        strokeWidth: positiveNumber,
        lineDash: arrayOf(positiveNumber)
      },
      "a grid-line style object array"
    )
  },
  interval: commonAxisIntervalOptionsDefs,
  label: commonAxisLabelOptionsDefs,
  line: {
    enabled: boolean,
    width: positiveNumber,
    stroke: color
  },
  tick: cartesianAxisTick,
  context: () => true
};
commonAxisOptionsDefs.layoutConstraints = undocumented({
  stacked: required(boolean),
  align: required(union("start", "end")),
  unit: required(union("percent", "px")),
  width: required(positiveNumber)
});
var cartesianAxisOptionsDefs = {
  ...commonAxisOptionsDefs,
  crossAt: {
    value: required(or(number, date, string, arrayOf(string))),
    sticky: boolean
  },
  crossLines: arrayOfDefs(cartesianCrossLineOptionsDefs, "a cross-line options array"),
  position: union("top", "right", "bottom", "left"),
  thickness: positiveNumber,
  maxThicknessRatio: ratio,
  title: {
    enabled: boolean,
    text: textOrSegments,
    spacing: positiveNumber,
    formatter: callbackOf(textOrSegments),
    ...fontOptionsDef
  }
};
cartesianAxisOptionsDefs.title._enabledFromTheme = undocumented(boolean);
var cartesianAxisBandHighlightOptions = {
  enabled: boolean,
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef
};
function cartesianAxisCrosshairOptions(canFormat, timeFormat) {
  const baseCrosshairLabel = {
    enabled: boolean,
    xOffset: number,
    yOffset: number,
    formatter: callbackOf(string),
    renderer: callbackOf(
      or(
        string,
        optionsDefs(
          {
            text: string,
            color,
            backgroundColor: color,
            opacity: ratio
          },
          "crosshair label renderer result object"
        )
      )
    )
  };
  let crosshairLabel;
  if (canFormat) {
    crosshairLabel = {
      ...baseCrosshairLabel,
      format: timeFormat ? or(
        string,
        optionsDefs({
          millisecond: string,
          second: string,
          hour: string,
          day: string,
          month: string,
          year: string
        })
      ) : string
    };
  }
  return {
    enabled: boolean,
    snap: boolean,
    label: crosshairLabel ?? baseCrosshairLabel,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  };
}
function continuousAxisOptions(validDatum, supportTimeInterval) {
  return {
    min: and(validDatum, lessThan("max")),
    max: and(validDatum, greaterThan("min")),
    preferredMin: and(validDatum, lessThan("preferredMax"), lessThan("max")),
    preferredMax: and(validDatum, greaterThan("preferredMin"), greaterThan("min")),
    nice: boolean,
    interval: {
      step: supportTimeInterval ? or(positiveNumberNonZero, timeIntervalUnit, timeInterval2) : positiveNumberNonZero,
      values: arrayOf(validDatum),
      minSpacing: and(positiveNumber, lessThan("maxSpacing")),
      maxSpacing: and(positiveNumber, greaterThan("minSpacing"))
    }
  };
}
var discreteTimeAxisIntervalOptionsDefs = {
  step: or(positiveNumberNonZero, timeIntervalUnit, timeInterval2),
  values: arrayOf(or(number, date)),
  minSpacing: and(positiveNumber, lessThan("maxSpacing")),
  maxSpacing: and(positiveNumber, greaterThan("minSpacing")),
  placement: union("on", "between")
};
var categoryAxisOptionsDefs = {
  ...cartesianAxisOptionsDefs,
  type: constant("category"),
  label: cartesianAxisLabelOptionsDefs,
  paddingInner: ratio,
  paddingOuter: ratio,
  groupPaddingInner: ratio,
  crosshair: cartesianAxisCrosshairOptions(),
  bandAlignment: union("justify", "start", "center", "end"),
  bandHighlight: cartesianAxisBandHighlightOptions,
  interval: {
    ...commonAxisIntervalOptionsDefs,
    placement: union("on", "between")
  }
};
var groupedCategoryAxisOptionsDefs = {
  ...cartesianAxisOptionsDefs,
  type: constant("grouped-category"),
  label: cartesianAxisLabelOptionsDefs,
  crosshair: cartesianAxisCrosshairOptions(),
  bandHighlight: cartesianAxisBandHighlightOptions,
  paddingInner: ratio,
  groupPaddingInner: ratio,
  depthOptions: arrayOfDefs(
    {
      label: {
        enabled: boolean,
        avoidCollisions: boolean,
        wrapping: union("never", "always", "hyphenate", "on-space"),
        truncate: boolean,
        rotation: number,
        spacing: number,
        ...fontOptionsDef,
        ...labelBoxOptionsDef
      },
      tick: {
        enabled: boolean,
        stroke: color,
        width: positiveNumber
      }
    },
    "depth options objects array"
  )
};
var numberAxisOptionsDefs = {
  ...cartesianAxisOptionsDefs,
  ...continuousAxisOptions(number),
  type: constant("number"),
  label: cartesianNumericAxisLabel,
  crosshair: cartesianAxisCrosshairOptions(true)
};
var logAxisOptionsDefs = {
  ...cartesianAxisOptionsDefs,
  ...continuousAxisOptions(number),
  type: constant("log"),
  base: and(
    positiveNumberNonZero,
    attachDescription((value) => value !== 1, "not equal to 1")
  ),
  label: cartesianNumericAxisLabel,
  crosshair: cartesianAxisCrosshairOptions(true)
};
var timeAxisOptionsDefs = {
  ...cartesianAxisOptionsDefs,
  ...continuousAxisOptions(or(number, date), true),
  type: constant("time"),
  label: cartesianTimeAxisLabel,
  parentLevel: cartesianTimeAxisParentLevel,
  crosshair: cartesianAxisCrosshairOptions(true, true)
};
var unitTimeAxisOptionsDefs = {
  ...cartesianAxisOptionsDefs,
  type: constant("unit-time"),
  unit: or(timeInterval2, timeIntervalUnit),
  label: cartesianTimeAxisLabel,
  parentLevel: cartesianTimeAxisParentLevel,
  paddingInner: ratio,
  paddingOuter: ratio,
  groupPaddingInner: ratio,
  crosshair: cartesianAxisCrosshairOptions(true, true),
  bandAlignment: union("justify", "start", "center", "end"),
  bandHighlight: cartesianAxisBandHighlightOptions,
  min: and(or(number, date), lessThan("max")),
  max: and(or(number, date), greaterThan("min")),
  preferredMin: and(or(number, date), lessThan("preferredMax"), lessThan("max")),
  preferredMax: and(or(number, date), greaterThan("preferredMin"), greaterThan("min")),
  interval: discreteTimeAxisIntervalOptionsDefs
};

// packages/ag-charts-community/src/chart/axesOptionsEnterpriseDefs.ts
var ordinalTimeAxisOptionsDefs = {
  ...cartesianAxisOptionsDefs,
  type: constant("ordinal-time"),
  paddingInner: ratio,
  paddingOuter: ratio,
  groupPaddingInner: ratio,
  label: cartesianTimeAxisLabel,
  parentLevel: cartesianTimeAxisParentLevel,
  interval: discreteTimeAxisIntervalOptionsDefs,
  crosshair: cartesianAxisCrosshairOptions(true, true),
  bandHighlight: cartesianAxisBandHighlightOptions,
  bandAlignment: union("justify", "start", "center", "end")
};
var angleNumberAxisOptionsDefs = {
  ...commonAxisOptionsDefs,
  ...continuousAxisOptions(number),
  type: constant("angle-number"),
  crossLines: arrayOfDefs(commonCrossLineOptionsDefs),
  startAngle: number,
  endAngle: number,
  label: {
    ...commonAxisLabelOptionsDefs,
    orientation: union("fixed", "parallel", "perpendicular"),
    format: numberFormatValidator
  }
};
var angleCategoryAxisOptionsDefs = {
  ...commonAxisOptionsDefs,
  type: constant("angle-category"),
  shape: union("polygon", "circle"),
  crossLines: arrayOfDefs(commonCrossLineOptionsDefs),
  startAngle: number,
  endAngle: number,
  paddingInner: ratio,
  groupPaddingInner: ratio,
  label: {
    ...commonAxisLabelOptionsDefs,
    orientation: union("fixed", "parallel", "perpendicular")
  }
};
angleCategoryAxisOptionsDefs.innerRadiusRatio = ratio;
var radiusNumberAxisOptionsDefs = {
  ...commonAxisOptionsDefs,
  ...continuousAxisOptions(number),
  type: constant("radius-number"),
  shape: union("polygon", "circle"),
  positionAngle: number,
  innerRadiusRatio: ratio,
  crossLines: arrayOfDefs(
    {
      ...commonCrossLineOptionsDefs,
      label: {
        ...commonCrossLineLabelOptionsDefs,
        positionAngle: number
      }
    },
    "cross-line options"
  ),
  title: {
    enabled: boolean,
    text: textOrSegments,
    spacing: positiveNumber,
    formatter: callbackOf(textOrSegments),
    ...fontOptionsDef
  },
  label: {
    ...commonAxisLabelOptionsDefs,
    format: numberFormatValidator
  }
};
var radiusCategoryAxisOptionsDefs = {
  ...commonAxisOptionsDefs,
  type: constant("radius-category"),
  positionAngle: number,
  innerRadiusRatio: ratio,
  paddingInner: ratio,
  paddingOuter: ratio,
  groupPaddingInner: ratio,
  label: commonAxisLabelOptionsDefs,
  crossLines: arrayOfDefs(
    {
      ...commonCrossLineOptionsDefs,
      label: {
        ...commonCrossLineLabelOptionsDefs,
        positionAngle: number
      }
    },
    "cross-line options"
  ),
  title: {
    enabled: boolean,
    text: textOrSegments,
    spacing: positiveNumber,
    formatter: callbackOf(textOrSegments),
    ...fontOptionsDef
  }
};

// packages/ag-charts-community/src/chart/series/cartesian/areaSeriesOptionsDef.ts
var highlight = multiSeriesHighlightOptionsDef(shapeHighlightOptionsDef, shapeHighlightOptionsDef);
var areaStyler = callbackDefs({
  ...strokeOptionsDef,
  ...fillOptionsDef,
  ...lineDashOptionsDef,
  marker: markerStyleOptionsDefs
});
var areaSeriesThemeableOptionsDef = {
  showInMiniChart: boolean,
  connectMissingData: boolean,
  interpolation: interpolationOptionsDefs,
  label: seriesLabelOptionsDefs,
  styler: areaStyler,
  marker: markerOptionsDefs,
  tooltip: tooltipOptionsDefsWithArea,
  shadow: shadowOptionsDefs,
  ...commonSeriesThemeableOptionsDefs,
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  highlight,
  segmentation: shapeSegmentation
};
var areaSeriesOptionsDef = {
  ...areaSeriesThemeableOptionsDef,
  ...commonSeriesOptionsDefs,
  highlight,
  type: required(constant("area")),
  xKey: required(string),
  yKey: required(string),
  xKeyAxis: string,
  yKeyAxis: string,
  xName: string,
  yName: string,
  legendItemName: string,
  stacked: boolean,
  stackGroup: string,
  normalizedTo: number
};
areaSeriesOptionsDef.yFilterKey = undocumented(string);

// packages/ag-charts-community/src/chart/series/cartesian/barSeriesOptionsDef.ts
var highlight2 = multiSeriesHighlightOptionsDef(barHighlightOptionsDef, barHighlightOptionsDef);
var barStyler = callbackDefs({
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  cornerRadius: positiveNumber
});
var barSeriesThemeableOptionsDef = {
  direction: union("horizontal", "vertical"),
  showInMiniChart: boolean,
  cornerRadius: positiveNumber,
  styler: barStyler,
  itemStyler: barStyler,
  crisp: boolean,
  label: {
    ...seriesLabelOptionsDefs,
    placement: union("inside-center", "inside-start", "inside-end", "outside-start", "outside-end"),
    spacing: positiveNumber
  },
  errorBar: errorBarThemeableOptionsDefs,
  shadow: shadowOptionsDefs,
  tooltip: tooltipOptionsDefs,
  ...commonSeriesThemeableOptionsDefs,
  highlight: highlight2,
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  segmentation: shapeSegmentation,
  width: positiveNumberNonZero,
  widthRatio: ratio
};
barSeriesThemeableOptionsDef.sparklineMode = undocumented(boolean);
var barSeriesOptionsDef = {
  ...barSeriesThemeableOptionsDef,
  ...commonSeriesOptionsDefs,
  highlight: highlight2,
  type: required(constant("bar")),
  xKey: required(string),
  yKey: required(string),
  xKeyAxis: string,
  yKeyAxis: string,
  xName: string,
  yName: string,
  direction: union("horizontal", "vertical"),
  grouped: boolean,
  stacked: boolean,
  stackGroup: string,
  normalizedTo: number,
  legendItemName: string,
  errorBar: errorBarOptionsDefs
};
barSeriesOptionsDef.yFilterKey = undocumented(string);
barSeriesOptionsDef.pickOutsideVisibleMinorAxis = undocumented(boolean);
barSeriesOptionsDef.focusPriority = undocumented(number);
barSeriesOptionsDef.simpleItemStyler = undocumented(callback);

// packages/ag-charts-community/src/chart/series/cartesian/bubbleSeriesOptionsDef.ts
var bubbleSeriesThemeableOptionsDef = {
  title: string,
  domain: arrayOf(number),
  maxSize: positiveNumber,
  showInMiniChart: boolean,
  label: {
    placement: union("top", "right", "bottom", "left"),
    ...seriesLabelOptionsDefs
  },
  tooltip: tooltipOptionsDefs,
  styler: callbackDefs({
    ...markerOptionsDefs,
    maxSize: positiveNumber
  }),
  maxRenderedItems: number,
  ...commonSeriesThemeableOptionsDefs,
  ...without(markerOptionsDefs, ["enabled"]),
  highlight: multiSeriesHighlightOptionsDef(shapeHighlightOptionsDef, shapeHighlightOptionsDef)
};
var bubbleSeriesOptionsDef = {
  ...bubbleSeriesThemeableOptionsDef,
  ...commonSeriesOptionsDefs,
  type: required(constant("bubble")),
  xKey: required(string),
  yKey: required(string),
  sizeKey: required(string),
  labelKey: string,
  xName: string,
  yName: string,
  sizeName: string,
  labelName: string,
  legendItemName: string,
  xKeyAxis: string,
  yKeyAxis: string,
  highlight: multiSeriesHighlightOptionsDef(shapeHighlightOptionsDef, shapeHighlightOptionsDef)
};
bubbleSeriesOptionsDef.xFilterKey = undocumented(string);
bubbleSeriesOptionsDef.yFilterKey = undocumented(string);
bubbleSeriesOptionsDef.sizeFilterKey = undocumented(string);

// packages/ag-charts-community/src/chart/series/cartesian/histogramSeriesOptionsDef.ts
var histogramSeriesThemeableOptionsDef = {
  showInMiniChart: boolean,
  cornerRadius: positiveNumber,
  label: seriesLabelOptionsDefs,
  tooltip: tooltipOptionsDefs,
  shadow: shadowOptionsDefs,
  ...commonSeriesThemeableOptionsDefs,
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  highlight: multiSeriesHighlightOptionsDef(shapeHighlightOptionsDef, shapeHighlightOptionsDef),
  areaPlot: boolean,
  aggregation: union("count", "sum", "mean"),
  bins: arrayOf(arrayOf(number)),
  binCount: positiveNumber
};
var histogramSeriesOptionsDef = {
  ...commonSeriesOptionsDefs,
  ...histogramSeriesThemeableOptionsDef,
  type: required(constant("histogram")),
  xKey: required(string),
  yKey: string,
  xKeyAxis: string,
  yKeyAxis: string,
  xName: string,
  yName: string
};

// packages/ag-charts-community/src/chart/series/cartesian/lineSeriesOptionsDef.ts
var highlight3 = multiSeriesHighlightOptionsDef(shapeHighlightOptionsDef, lineHighlightOptionsDef);
var lineStyler = callbackDefs({
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  marker: markerStyleOptionsDefs
});
var lineSeriesThemeableOptionsDef = {
  title: string,
  showInMiniChart: boolean,
  connectMissingData: boolean,
  interpolation: interpolationOptionsDefs,
  label: seriesLabelOptionsDefs,
  styler: lineStyler,
  marker: markerOptionsDefs,
  tooltip: tooltipOptionsDefs,
  errorBar: errorBarThemeableOptionsDefs,
  ...commonSeriesThemeableOptionsDefs,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  highlight: highlight3,
  segmentation: lineSegmentation
};
lineSeriesThemeableOptionsDef.sparklineMode = undocumented(boolean);
var lineSeriesOptionsDef = {
  ...lineSeriesThemeableOptionsDef,
  ...commonSeriesOptionsDefs,
  highlight: highlight3,
  type: required(constant("line")),
  xKey: required(string),
  yKey: required(string),
  xKeyAxis: string,
  yKeyAxis: string,
  xName: string,
  yName: string,
  stacked: boolean,
  stackGroup: string,
  normalizedTo: number,
  legendItemName: string,
  errorBar: errorBarOptionsDefs
};
lineSeriesOptionsDef.yFilterKey = undocumented(string);
lineSeriesOptionsDef.pickOutsideVisibleMinorAxis = undocumented(boolean);
lineSeriesOptionsDef.focusPriority = undocumented(number);

// packages/ag-charts-community/src/chart/series/cartesian/scatterSeriesOptionsDef.ts
var scatterSeriesThemeableOptionsDef = {
  title: string,
  showInMiniChart: boolean,
  label: {
    placement: union("top", "right", "bottom", "left"),
    ...seriesLabelOptionsDefs
  },
  tooltip: tooltipOptionsDefs,
  errorBar: errorBarThemeableOptionsDefs,
  styler: callbackDefs(markerOptionsDefs),
  maxRenderedItems: number,
  ...commonSeriesThemeableOptionsDefs,
  ...without(markerOptionsDefs, ["enabled"]),
  highlight: multiSeriesHighlightOptionsDef(shapeHighlightOptionsDef, shapeHighlightOptionsDef)
};
var scatterSeriesOptionsDef = {
  ...scatterSeriesThemeableOptionsDef,
  ...commonSeriesOptionsDefs,
  type: required(constant("scatter")),
  xKey: required(string),
  yKey: required(string),
  labelKey: string,
  xName: string,
  yName: string,
  labelName: string,
  legendItemName: string,
  xKeyAxis: string,
  yKeyAxis: string,
  errorBar: errorBarOptionsDefs,
  highlight: multiSeriesHighlightOptionsDef(shapeHighlightOptionsDef, shapeHighlightOptionsDef)
};
scatterSeriesOptionsDef.xFilterKey = undocumented(string);
scatterSeriesOptionsDef.yFilterKey = undocumented(string);
scatterSeriesOptionsDef.sizeFilterKey = undocumented(string);

// packages/ag-charts-community/src/chart/series/polar/pieSeriesOptionsDef.ts
var highlight4 = multiSeriesHighlightOptionsDef(shapeHighlightOptionsDef, shapeHighlightOptionsDef);
var pieSeriesThemeableOptionsDef = {
  ...commonSeriesThemeableOptionsDefs,
  radiusMin: positiveNumber,
  radiusMax: positiveNumber,
  rotation: number,
  outerRadiusOffset: number,
  outerRadiusRatio: ratio,
  hideZeroValueSectorsInLegend: boolean,
  sectorSpacing: positiveNumber,
  cornerRadius: positiveNumber,
  itemStyler: callbackDefs({
    ...fillOptionsDef,
    ...strokeOptionsDef,
    ...lineDashOptionsDef,
    cornerRadius: positiveNumber
  }),
  title: {
    enabled: boolean,
    text: string,
    showInLegend: boolean,
    spacing: positiveNumber,
    ...fontOptionsDef
  },
  calloutLabel: {
    enabled: boolean,
    offset: number,
    minAngle: positiveNumber,
    avoidCollisions: boolean,
    formatter: callbackOf(textOrSegments),
    format: string,
    itemStyler: callbackDefs({
      enabled: boolean,
      ...labelBoxOptionsDef,
      ...fontOptionsDef
    }),
    ...labelBoxOptionsDef,
    ...fontOptionsDef
  },
  sectorLabel: {
    enabled: boolean,
    positionOffset: number,
    positionRatio: ratio,
    formatter: callbackOf(textOrSegments),
    format: string,
    itemStyler: callbackDefs({
      enabled: boolean,
      ...labelBoxOptionsDef,
      ...fontOptionsDef
    }),
    ...labelBoxOptionsDef,
    ...fontOptionsDef
  },
  calloutLine: {
    colors: arrayOf(color),
    length: positiveNumber,
    strokeWidth: positiveNumber,
    itemStyler: callbackDefs({
      color,
      length: positiveNumber,
      strokeWidth: positiveNumber
    })
  },
  fills: arrayOf(colorUnion),
  strokes: arrayOf(color),
  tooltip: tooltipOptionsDefs,
  shadow: shadowOptionsDefs,
  highlight: highlight4,
  ...lineDashOptionsDef,
  ...without(fillOptionsDef, ["fill"]),
  ...without(strokeOptionsDef, ["stroke"])
};
var pieSeriesOptionsDef = {
  ...pieSeriesThemeableOptionsDef,
  ...commonSeriesOptionsDefs,
  type: required(constant("pie")),
  angleKey: required(string),
  radiusKey: string,
  calloutLabelKey: string,
  sectorLabelKey: string,
  legendItemKey: string,
  angleName: string,
  radiusName: string,
  calloutLabelName: string,
  sectorLabelName: string,
  highlight: highlight4
};
pieSeriesOptionsDef.angleFilterKey = undocumented(string);
pieSeriesOptionsDef.defaultColorRange = undocumented(arrayOf(arrayOf(color)));
pieSeriesOptionsDef.defaultPatternFills = undocumented(arrayOf(color));
pieSeriesOptionsDef.title._enabledFromTheme = undocumented(boolean);
pieSeriesOptionsDef.calloutLabel._enabledFromTheme = undocumented(boolean);
pieSeriesOptionsDef.sectorLabel._enabledFromTheme = undocumented(boolean);
pieSeriesOptionsDef.angleKeyAxis = undocumented(string);
pieSeriesOptionsDef.radiusKeyAxis = undocumented(string);

// packages/ag-charts-community/src/chart/series/polar/donutSeriesOptionsDef.ts
var donutSeriesThemeableOptionsDef = {
  ...pieSeriesThemeableOptionsDef,
  innerRadiusOffset: number,
  innerRadiusRatio: ratio,
  innerCircle: {
    fill: string,
    fillOpacity: ratio
  },
  innerLabels: {
    spacing: positiveNumber,
    ...fontOptionsDef,
    ...labelBoxOptionsDef
  }
};
var donutSeriesOptionsDef = {
  ...donutSeriesThemeableOptionsDef,
  ...pieSeriesOptionsDef,
  type: required(constant("donut")),
  innerLabels: arrayOfDefs(
    {
      text: required(string),
      spacing: positiveNumber,
      ...fontOptionsDef,
      ...labelBoxOptionsDef
    },
    "inner label options array"
  )
};
donutSeriesOptionsDef.angleFilterKey = undocumented(string);

// packages/ag-charts-community/src/chart/themes/annotationOptionsDef.ts
var annotationLineOptionsDef = {
  lineStyle: union("solid", "dashed", "dotted"),
  ...lineDashOptionsDef
};
var annotationHandleStylesDefs = {
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef
};
var annotationTextStylesDef = {
  visible: boolean,
  locked: boolean,
  readOnly: boolean,
  handle: annotationHandleStylesDefs,
  ...fontOptionsDef
};
var annotationLineTextDefs = {
  position: union("top", "center", "bottom"),
  alignment: union("left", "center", "right"),
  ...fontOptionsDef
};
var annotationChannelTextDefs = {
  position: union("top", "inside", "bottom"),
  alignment: union("left", "center", "right"),
  ...fontOptionsDef
};
var annotationAxisLabelOptionsDef = {
  enabled: boolean,
  cornerRadius: positiveNumber,
  ...fontOptionsDef,
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef
};
var annotationChannelMiddleDefs = {
  visible: boolean,
  ...annotationLineOptionsDef,
  ...strokeOptionsDef
};
var annotationMeasurerStatisticsOptionsDefs = {
  divider: strokeOptionsDef,
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...fontOptionsDef
};
var annotationQuickMeasurerDirectionStylesDefs = {
  handle: annotationHandleStylesDefs,
  statistics: annotationMeasurerStatisticsOptionsDefs,
  ...annotationLineOptionsDef,
  ...fillOptionsDef,
  ...strokeOptionsDef
};
var annotationLineStyleDefs = {
  visible: boolean,
  locked: boolean,
  readOnly: boolean,
  extendStart: boolean,
  extendEnd: boolean,
  handle: annotationHandleStylesDefs,
  text: annotationLineTextDefs,
  ...annotationLineOptionsDef,
  ...strokeOptionsDef
};
var annotationCrossLineStyleDefs = {
  visible: boolean,
  locked: boolean,
  readOnly: boolean,
  axisLabel: annotationAxisLabelOptionsDef,
  handle: annotationHandleStylesDefs,
  text: annotationLineTextDefs,
  ...annotationLineOptionsDef,
  ...strokeOptionsDef
};
var annotationChannelStyleDefs = {
  visible: boolean,
  locked: boolean,
  readOnly: boolean,
  extendStart: boolean,
  extendEnd: boolean,
  handle: annotationHandleStylesDefs,
  text: annotationChannelTextDefs,
  background: fillOptionsDef,
  ...annotationLineOptionsDef,
  ...strokeOptionsDef
};
var annotationDisjointChannelStyleDefs = {
  ...annotationChannelStyleDefs
};
var annotationParallelChannelStyleDefs = {
  ...annotationChannelStyleDefs,
  middle: annotationChannelMiddleDefs
};
var annotationFibonacciStylesDefs = {
  label: fontOptionsDef,
  showFill: boolean,
  isMultiColor: boolean,
  strokes: arrayOf(color),
  rangeStroke: color,
  bands: union(4, 6, 10),
  ...annotationLineStyleDefs
};
var annotationCalloutStylesDefs = {
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...annotationTextStylesDef
};
var annotationCommentStylesDefs = {
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...annotationTextStylesDef
};
var annotationNoteStylesDefs = {
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...annotationTextStylesDef,
  background: {
    ...fillOptionsDef,
    ...strokeOptionsDef
  }
};
var annotationShapeStylesDefs = {
  visible: boolean,
  locked: boolean,
  readOnly: boolean,
  handle: annotationHandleStylesDefs,
  ...fillOptionsDef
};
var annotationMeasurerStylesDefs = {
  visible: boolean,
  locked: boolean,
  readOnly: boolean,
  extendStart: boolean,
  extendEnd: boolean,
  handle: annotationHandleStylesDefs,
  text: annotationLineTextDefs,
  background: fillOptionsDef,
  statistics: annotationMeasurerStatisticsOptionsDefs,
  ...annotationLineOptionsDef,
  ...strokeOptionsDef
};
var annotationQuickMeasurerStylesDefs = {
  visible: boolean,
  up: annotationQuickMeasurerDirectionStylesDefs,
  down: annotationQuickMeasurerDirectionStylesDefs
};
var annotationOptionsDef = {
  enabled: boolean,
  axesButtons: {
    enabled: boolean,
    axes: union("x", "y", "xy")
  },
  toolbar: {
    enabled: boolean,
    padding: positiveNumber,
    buttons: arrayOfDefs(
      {
        ...toolbarButtonOptionsDefs,
        value: union(
          "line-menu",
          "fibonacci-menu",
          "text-menu",
          "shape-menu",
          "measurer-menu",
          "line",
          "horizontal-line",
          "vertical-line",
          "parallel-channel",
          "disjoint-channel",
          "fibonacci-retracement",
          "fibonacci-retracement-trend-based",
          "text",
          "comment",
          "callout",
          "note",
          "clear"
        )
      },
      "annotation toolbar buttons array"
    )
  },
  optionsToolbar: {
    enabled: boolean,
    buttons: arrayOf(
      or(
        optionsDefs({
          ...toolbarButtonOptionsDefs,
          value: required(
            union(
              "line-stroke-width",
              "line-style-type",
              "line-color",
              "fill-color",
              "text-color",
              "text-size",
              "delete",
              "settings"
            )
          )
        }),
        optionsDefs({
          ...toolbarButtonOptionsDefs,
          value: required(union("lock")),
          checkedOverrides: toolbarButtonOptionsDefs
        })
      )
    )
  }
};
annotationOptionsDef.data = undocumented(array);
annotationOptionsDef.xKey = undocumented(string);
annotationOptionsDef.volumeKey = undocumented(string);
annotationOptionsDef.snap = undocumented(boolean);

// packages/ag-charts-community/src/chart/themes/enterpriseThemeableOptionsDef.ts
var hierarchyHighlightStyleOptionsDef = {
  ...fillOptionsDef,
  ...strokeOptionsDef,
  opacity: ratio
};
var boxPlotStyleOptionsDef = {
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  cornerRadius: positiveNumber,
  whisker: {
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  },
  cap: {
    lengthRatio: ratio
  }
};
var boxPlotHighlightStyleOptionsDef = {
  ...boxPlotStyleOptionsDef,
  opacity: ratio
};
var boxPlotStyler = callbackDefs({
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  cornerRadius: positiveNumber,
  whisker: {
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  },
  cap: {
    lengthRatio: ratio
  }
});
var boxPlotSeriesThemeableOptionsDef = {
  direction: union("horizontal", "vertical"),
  showInMiniChart: boolean,
  styler: boxPlotStyler,
  itemStyler: boxPlotStyler,
  tooltip: tooltipOptionsDefs,
  ...commonSeriesThemeableOptionsDefs,
  ...boxPlotStyleOptionsDef,
  highlight: multiSeriesHighlightOptionsDef(boxPlotHighlightStyleOptionsDef, boxPlotHighlightStyleOptionsDef),
  segmentation: shapeSegmentation,
  width: positiveNumberNonZero,
  widthRatio: ratio
};
var candlestickSeriesItemOptionsDef = {
  cornerRadius: positiveNumber,
  wick: {
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  },
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef
};
var candlestickHighlightStyleOptionsDef = {
  ...candlestickSeriesItemOptionsDef,
  opacity: ratio
};
var candlestickSeriesThemeableOptionsDef = {
  item: {
    up: candlestickSeriesItemOptionsDef,
    down: candlestickSeriesItemOptionsDef
  },
  itemStyler: callbackDefs({
    ...fillOptionsDef,
    ...strokeOptionsDef,
    ...lineDashOptionsDef,
    cornerRadius: positiveNumber,
    wick: {
      ...strokeOptionsDef,
      ...lineDashOptionsDef
    }
  }),
  showInMiniChart: boolean,
  tooltip: tooltipOptionsDefs,
  ...commonSeriesThemeableOptionsDefs,
  highlight: multiSeriesHighlightOptionsDef(candlestickHighlightStyleOptionsDef, candlestickHighlightStyleOptionsDef)
};
var chordSeriesThemeableOptionsDef = {
  fills: arrayOf(colorUnion),
  strokes: arrayOf(color),
  label: {
    spacing: positiveNumber,
    maxWidth: positiveNumber,
    ...seriesLabelOptionsDefs
  },
  link: {
    tension: ratio,
    itemStyler: callbackDefs({
      ...fillOptionsDef,
      ...strokeOptionsDef,
      ...lineDashOptionsDef,
      tension: ratio
    }),
    ...fillOptionsDef,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  },
  node: {
    width: positiveNumber,
    spacing: positiveNumber,
    itemStyler: callbackDefs({
      ...fillOptionsDef,
      ...strokeOptionsDef,
      ...lineDashOptionsDef
    }),
    ...fillOptionsDef,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  },
  tooltip: tooltipOptionsDefs,
  ...commonSeriesThemeableOptionsDefs
};
var coneFunnelSeriesThemeableOptionsDef = {
  direction: union("horizontal", "vertical"),
  fills: arrayOf(colorUnion),
  strokes: arrayOf(color),
  label: {
    spacing: positiveNumber,
    placement: union("before", "middle", "after"),
    ...seriesLabelOptionsDefs
  },
  stageLabel: {
    placement: union("before", "after"),
    format: numberFormatValidator,
    ...commonAxisLabelOptionsDefs
  },
  tooltip: tooltipOptionsDefs,
  ...without(commonSeriesThemeableOptionsDefs, ["showInLegend"]),
  ...without(fillOptionsDef, ["fill"]),
  ...without(strokeOptionsDef, ["stroke"]),
  ...lineDashOptionsDef,
  highlight: highlightOptionsDef(lineHighlightOptionsDef)
};
var funnelSeriesThemeableOptionsDef = {
  direction: union("horizontal", "vertical"),
  fills: arrayOf(colorUnion),
  strokes: arrayOf(color),
  itemStyler: callbackDefs({
    ...fillOptionsDef,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  }),
  spacingRatio: ratio,
  crisp: boolean,
  dropOff: {
    enabled: boolean,
    ...fillOptionsDef,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  },
  stageLabel: {
    placement: union("before", "after"),
    format: numberFormatValidator,
    ...commonAxisLabelOptionsDefs
  },
  label: seriesLabelOptionsDefs,
  tooltip: tooltipOptionsDefs,
  shadow: shadowOptionsDefs,
  ...without(commonSeriesThemeableOptionsDefs, ["showInLegend"]),
  ...without(fillOptionsDef, ["fill"]),
  ...without(strokeOptionsDef, ["stroke"]),
  ...lineDashOptionsDef
};
var heatmapSeriesThemeableOptionsDef = {
  title: string,
  textAlign: union("left", "center", "right"),
  verticalAlign: union("top", "middle", "bottom"),
  itemPadding: positiveNumber,
  itemStyler: callbackDefs({
    ...fillOptionsDef,
    ...strokeOptionsDef
  }),
  showInMiniChart: boolean,
  label: autoSizedLabelOptionsDefs,
  tooltip: tooltipOptionsDefs,
  ...commonSeriesThemeableOptionsDefs,
  ...strokeOptionsDef
};
var ohlcSeriesThemeableOptionsDef = {
  showInMiniChart: boolean,
  itemStyler: callbackDefs({
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  }),
  item: {
    up: {
      ...strokeOptionsDef,
      ...lineDashOptionsDef
    },
    down: {
      ...strokeOptionsDef,
      ...lineDashOptionsDef
    }
  },
  tooltip: tooltipOptionsDefs,
  ...commonSeriesThemeableOptionsDefs,
  highlight: multiSeriesHighlightOptionsDef(lineHighlightOptionsDef, lineHighlightOptionsDef)
};
var mapLineSeriesThemeableOptionsDef = {
  maxStrokeWidth: positiveNumber,
  itemStyler: callbackDefs({
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  }),
  sizeDomain: arrayOf(positiveNumber),
  label: seriesLabelOptionsDefs,
  tooltip: tooltipOptionsDefs,
  ...commonSeriesThemeableOptionsDefs,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  highlight: multiSeriesHighlightOptionsDef(lineHighlightOptionsDef, lineHighlightOptionsDef)
};
var mapLineBackgroundSeriesThemeableOptionsDef = {
  ...strokeOptionsDef,
  ...lineDashOptionsDef
};
var mapMarkerSeriesThemeableOptionsDef = {
  colorRange: arrayOf(color),
  maxSize: positiveNumber,
  sizeDomain: arrayOf(positiveNumber),
  label: {
    placement: union("top", "bottom", "left", "right"),
    ...seriesLabelOptionsDefs
  },
  tooltip: tooltipOptionsDefs,
  ...commonSeriesThemeableOptionsDefs,
  ...without(markerOptionsDefs, ["enabled"]),
  highlight: multiSeriesHighlightOptionsDef(shapeHighlightOptionsDef, shapeHighlightOptionsDef)
};
var mapShapeSeriesThemeableOptionsDef = {
  colorRange: arrayOf(color),
  padding: positiveNumber,
  itemStyler: callbackDefs({
    ...fillOptionsDef,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  }),
  label: autoSizedLabelOptionsDefs,
  tooltip: tooltipOptionsDefs,
  ...commonSeriesThemeableOptionsDefs,
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  highlight: multiSeriesHighlightOptionsDef(shapeHighlightOptionsDef, shapeHighlightOptionsDef)
};
var mapShapeBackgroundSeriesThemeableOptionsDef = {
  ...commonSeriesThemeableOptionsDefs,
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef
};
var radialSeriesStylerDef = callbackDefs({
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  cornerRadius: positiveNumber
});
var nightingaleSeriesThemeableOptionsDef = {
  cornerRadius: positiveNumber,
  styler: radialSeriesStylerDef,
  itemStyler: radialSeriesStylerDef,
  label: seriesLabelOptionsDefs,
  tooltip: tooltipOptionsDefs,
  ...commonSeriesThemeableOptionsDefs,
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  highlight: multiSeriesHighlightOptionsDef(barHighlightOptionsDef, barHighlightOptionsDef)
};
var pyramidSeriesThemeableOptionsDef = {
  direction: union("horizontal", "vertical"),
  aspectRatio: positiveNumber,
  spacing: positiveNumber,
  reverse: boolean,
  itemStyler: callbackDefs({
    ...fillOptionsDef,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  }),
  fills: arrayOf(colorUnion),
  strokes: arrayOf(color),
  label: seriesLabelOptionsDefs,
  stageLabel: {
    spacing: positiveNumber,
    placement: union("before", "after"),
    ...seriesLabelOptionsDefs
  },
  tooltip: tooltipOptionsDefs,
  shadow: shadowOptionsDefs,
  ...commonSeriesThemeableOptionsDefs,
  ...without(fillOptionsDef, ["fill"]),
  ...without(strokeOptionsDef, ["stroke"]),
  ...lineDashOptionsDef
};
var radarAreaSeriesThemeableOptionsDef = {
  connectMissingData: boolean,
  marker: markerOptionsDefs,
  styler: callbackDefs({
    marker: markerStyleOptionsDefs,
    ...fillOptionsDef,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  }),
  label: seriesLabelOptionsDefs,
  tooltip: tooltipOptionsDefs,
  ...commonSeriesThemeableOptionsDefs,
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  highlight: multiSeriesHighlightOptionsDef(shapeHighlightOptionsDef, shapeHighlightOptionsDef)
};
var radarLineSeriesThemeableOptionsDef = {
  connectMissingData: boolean,
  marker: markerOptionsDefs,
  styler: callbackDefs({
    marker: markerStyleOptionsDefs,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  }),
  label: seriesLabelOptionsDefs,
  tooltip: tooltipOptionsDefs,
  ...commonSeriesThemeableOptionsDefs,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  highlight: multiSeriesHighlightOptionsDef(shapeHighlightOptionsDef, lineHighlightOptionsDef)
};
var radialBarSeriesThemeableOptionsDef = {
  cornerRadius: positiveNumber,
  styler: radialSeriesStylerDef,
  itemStyler: radialSeriesStylerDef,
  label: seriesLabelOptionsDefs,
  tooltip: tooltipOptionsDefs,
  ...commonSeriesThemeableOptionsDefs,
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  highlight: multiSeriesHighlightOptionsDef(barHighlightOptionsDef, barHighlightOptionsDef)
};
var radialColumnSeriesThemeableOptionsDef = {
  cornerRadius: positiveNumber,
  columnWidthRatio: ratio,
  maxColumnWidthRatio: ratio,
  styler: radialSeriesStylerDef,
  itemStyler: radialSeriesStylerDef,
  label: seriesLabelOptionsDefs,
  tooltip: tooltipOptionsDefs,
  ...commonSeriesThemeableOptionsDefs,
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  highlight: multiSeriesHighlightOptionsDef(barHighlightOptionsDef, barHighlightOptionsDef)
};
var rangeAreaSeriesLineThemeableOptionsDef = {
  marker: markerOptionsDefs,
  ...strokeOptionsDef,
  ...lineDashOptionsDef
};
var rangeAreaSeriesItemLineThemeableOptionsDef = {
  marker: {
    enabled: boolean,
    ...markerStyleOptionsDefs
  },
  ...strokeOptionsDef,
  ...lineDashOptionsDef
};
var rangeAreaSeriesLineStyleDef = {
  marker: markerStyleOptionsDefs,
  ...strokeOptionsDef,
  ...lineDashOptionsDef
};
var rangeAreaSeriesThemeableOptionsDef = {
  showInMiniChart: boolean,
  connectMissingData: boolean,
  interpolation: interpolationOptionsDefs,
  label: {
    ...seriesLabelOptionsDefs,
    placement: union("inside", "outside"),
    spacing: positiveNumber
  },
  tooltip: tooltipOptionsDefs,
  shadow: shadowOptionsDefs,
  ...commonSeriesThemeableOptionsDefs,
  ...fillOptionsDef,
  ...rangeAreaSeriesLineThemeableOptionsDef,
  item: {
    low: { ...rangeAreaSeriesItemLineThemeableOptionsDef },
    high: { ...rangeAreaSeriesItemLineThemeableOptionsDef }
  },
  styler: callbackDefs({
    ...fillOptionsDef,
    item: {
      low: { ...rangeAreaSeriesLineStyleDef },
      high: { ...rangeAreaSeriesLineStyleDef }
    }
  }),
  highlight: multiSeriesHighlightOptionsDef(shapeHighlightOptionsDef, shapeHighlightOptionsDef),
  segmentation: shapeSegmentation,
  invertedStyle: {
    enabled: boolean,
    ...fillOptionsDef
  }
};
var rangeBarStyleCallback = callbackDefs({
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  cornerRadius: positiveNumber
});
var rangeBarSeriesThemeableOptionsDef = {
  direction: union("horizontal", "vertical"),
  grouped: boolean,
  showInMiniChart: boolean,
  cornerRadius: positiveNumber,
  styler: rangeBarStyleCallback,
  itemStyler: rangeBarStyleCallback,
  label: {
    ...seriesLabelOptionsDefs,
    placement: union("inside", "outside"),
    spacing: positiveNumber
  },
  tooltip: tooltipOptionsDefs,
  shadow: shadowOptionsDefs,
  ...commonSeriesThemeableOptionsDefs,
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  highlight: multiSeriesHighlightOptionsDef(barHighlightOptionsDef, barHighlightOptionsDef),
  segmentation: shapeSegmentation,
  width: positiveNumberNonZero,
  widthRatio: ratio
};
var sankeySeriesThemeableOptionsDef = {
  fills: arrayOf(colorUnion),
  strokes: arrayOf(color),
  label: {
    ...seriesLabelOptionsDefs,
    spacing: positiveNumber,
    placement: union("left", "right", "center"),
    edgePlacement: union("inside", "outside")
  },
  link: {
    itemStyler: callbackDefs({
      ...fillOptionsDef,
      ...strokeOptionsDef,
      ...lineDashOptionsDef
    }),
    ...fillOptionsDef,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  },
  node: {
    width: positiveNumber,
    spacing: positiveNumber,
    minSpacing: and(positiveNumber, lessThanOrEqual("spacing")),
    alignment: union("left", "center", "right", "justify"),
    verticalAlignment: union("top", "bottom", "center"),
    sort: union("data", "ascending", "descending", "auto"),
    itemStyler: callbackDefs({
      ...fillOptionsDef,
      ...strokeOptionsDef,
      ...lineDashOptionsDef
    }),
    ...fillOptionsDef,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  },
  tooltip: tooltipOptionsDefs,
  ...commonSeriesThemeableOptionsDefs
};
var sunburstSeriesThemeableOptionsDef = {
  fills: arrayOf(colorUnion),
  strokes: arrayOf(color),
  colorRange: arrayOf(color),
  sectorSpacing: positiveNumber,
  cornerRadius: positiveNumber,
  padding: positiveNumber,
  itemStyler: callbackDefs({
    ...fillOptionsDef,
    ...strokeOptionsDef
  }),
  label: {
    spacing: positiveNumber,
    ...autoSizedLabelOptionsDefs
  },
  secondaryLabel: autoSizedLabelOptionsDefs,
  tooltip: tooltipOptionsDefs,
  ...without(commonSeriesThemeableOptionsDefs, ["highlight", "showInLegend"]),
  ...without(fillOptionsDef, ["fill"]),
  ...without(strokeOptionsDef, ["stroke"]),
  highlight: {
    highlightedItem: hierarchyHighlightStyleOptionsDef,
    highlightedBranch: hierarchyHighlightStyleOptionsDef,
    unhighlightedItem: hierarchyHighlightStyleOptionsDef,
    unhighlightedBranch: hierarchyHighlightStyleOptionsDef
  }
};
var treemapSeriesThemeableOptionsDef = {
  fills: arrayOf(colorUnion),
  strokes: arrayOf(color),
  colorRange: arrayOf(color),
  itemStyler: callbackDefs({
    ...fillOptionsDef,
    ...strokeOptionsDef
  }),
  group: {
    gap: positiveNumber,
    padding: positiveNumber,
    cornerRadius: positiveNumber,
    textAlign: union("left", "center", "right"),
    interactive: boolean,
    highlight: {
      highlightedItem: hierarchyHighlightStyleOptionsDef,
      unhighlightedItem: hierarchyHighlightStyleOptionsDef
    },
    label: {
      ...seriesLabelOptionsDefs,
      spacing: positiveNumber
    },
    ...fillOptionsDef,
    ...strokeOptionsDef
  },
  tile: {
    gap: positiveNumber,
    padding: positiveNumber,
    cornerRadius: positiveNumber,
    textAlign: union("left", "center", "right"),
    verticalAlign: union("top", "middle", "bottom"),
    label: {
      ...seriesLabelOptionsDefs,
      spacing: positiveNumber,
      lineHeight: positiveNumber,
      minimumFontSize: positiveNumber,
      wrapping: union("never", "always", "hyphenate", "on-space"),
      overflowStrategy: union("ellipsis", "hide")
    },
    secondaryLabel: {
      ...seriesLabelOptionsDefs,
      lineHeight: positiveNumber,
      minimumFontSize: positiveNumber,
      wrapping: union("never", "always", "hyphenate", "on-space"),
      overflowStrategy: union("ellipsis", "hide")
    },
    highlight: {
      highlightedItem: hierarchyHighlightStyleOptionsDef,
      highlightedBranch: hierarchyHighlightStyleOptionsDef,
      unhighlightedItem: hierarchyHighlightStyleOptionsDef,
      unhighlightedBranch: hierarchyHighlightStyleOptionsDef
    },
    ...fillOptionsDef,
    ...strokeOptionsDef
  },
  tooltip: tooltipOptionsDefs,
  ...without(commonSeriesThemeableOptionsDefs, ["highlight", "showInLegend"])
};
var waterfallSeriesItemOptionsDef = {
  name: string,
  cornerRadius: positiveNumber,
  itemStyler: callbackDefs({
    ...fillOptionsDef,
    ...strokeOptionsDef,
    ...lineDashOptionsDef,
    cornerRadius: positiveNumber
  }),
  label: {
    ...seriesLabelOptionsDefs,
    placement: union("inside-start", "inside-center", "inside-end", "outside-start", "outside-end"),
    spacing: positiveNumber
  },
  tooltip: tooltipOptionsDefs,
  shadow: shadowOptionsDefs,
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef
};
var waterfallSeriesThemeableOptionsDef = {
  direction: union("horizontal", "vertical"),
  showInMiniChart: boolean,
  item: {
    positive: waterfallSeriesItemOptionsDef,
    negative: waterfallSeriesItemOptionsDef,
    total: waterfallSeriesItemOptionsDef
  },
  line: {
    enabled: boolean,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  },
  tooltip: tooltipOptionsDefs,
  width: positiveNumberNonZero,
  widthRatio: ratio,
  ...commonSeriesThemeableOptionsDefs
};

// packages/ag-charts-community/src/chart/themes/themeOptionsDef.ts
var serializableDate = optionsDefs(
  {
    __type: required(constant("date")),
    value: or(string, number)
  },
  "a serializable date object"
);
var navigatorHandleOptionsDef = {
  width: positiveNumber,
  height: positiveNumber,
  grip: boolean,
  fill: color,
  stroke: color,
  strokeWidth: positiveNumber,
  cornerRadius: positiveNumber
};
var navigatorOptionsDef = {
  enabled: boolean,
  height: positiveNumber,
  spacing: positiveNumber,
  cornerRadius: number,
  mask: {
    fill: color,
    fillOpacity: ratio,
    stroke: color,
    strokeWidth: positiveNumber
  },
  minHandle: navigatorHandleOptionsDef,
  maxHandle: navigatorHandleOptionsDef,
  miniChart: {
    enabled: boolean,
    padding: {
      top: positiveNumber,
      bottom: positiveNumber
    },
    label: {
      enabled: boolean,
      avoidCollisions: boolean,
      spacing: positiveNumber,
      format: numberFormatValidator,
      formatter: callbackOf(textOrSegments),
      interval: {
        minSpacing: positiveNumber,
        maxSpacing: positiveNumber,
        values: array,
        step: number
      },
      ...fontOptionsDef
    },
    series: defined
  }
};
var scrollbarTrackOptionsDef = {
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  cornerRadius: positiveNumber,
  opacity: ratio
};
var scrollbarThumbOptionsDef = {
  ...scrollbarTrackOptionsDef,
  minSize: positiveNumber,
  hoverStyle: {
    fill: fillOptionsDef.fill,
    stroke: strokeOptionsDef.stroke
  }
};
var scrollbarBaseOptionsDef = {
  enabled: boolean,
  thickness: positiveNumber,
  spacing: positiveNumber,
  tickSpacing: positiveNumber,
  visible: union("auto", "always", "never"),
  placement: union("outer", "inner"),
  track: scrollbarTrackOptionsDef,
  thumb: scrollbarThumbOptionsDef
};
var scrollbarHorizontalOrientationOptionsDef = {
  ...scrollbarBaseOptionsDef,
  position: union("top", "bottom")
};
var scrollbarVerticalOrientationOptionsDef = {
  ...scrollbarBaseOptionsDef,
  position: union("left", "right")
};
var scrollbarOptionsDef = {
  enabled: boolean,
  thickness: positiveNumber,
  spacing: positiveNumber,
  tickSpacing: positiveNumber,
  visible: union("auto", "always", "never"),
  placement: union("outer", "inner"),
  track: scrollbarTrackOptionsDef,
  thumb: scrollbarThumbOptionsDef,
  horizontal: scrollbarHorizontalOrientationOptionsDef,
  vertical: scrollbarVerticalOrientationOptionsDef
};
var cartesianCrossLineThemeableOptionsDefs = without(cartesianCrossLineOptionsDefs, ["type", "value", "range"]);
var cartesianAxesThemeDef = {
  number: {
    ...without(numberAxisOptionsDefs, ["type", "crossLines"]),
    top: without(numberAxisOptionsDefs, ["type", "crossLines", "position"]),
    right: without(numberAxisOptionsDefs, ["type", "crossLines", "position"]),
    bottom: without(numberAxisOptionsDefs, ["type", "crossLines", "position"]),
    left: without(numberAxisOptionsDefs, ["type", "crossLines", "position"]),
    crossLines: cartesianCrossLineThemeableOptionsDefs
  },
  log: {
    ...without(logAxisOptionsDefs, ["type", "crossLines"]),
    top: without(logAxisOptionsDefs, ["type", "crossLines", "position"]),
    right: without(logAxisOptionsDefs, ["type", "crossLines", "position"]),
    bottom: without(logAxisOptionsDefs, ["type", "crossLines", "position"]),
    left: without(logAxisOptionsDefs, ["type", "crossLines", "position"]),
    crossLines: cartesianCrossLineThemeableOptionsDefs
  },
  category: {
    ...without(categoryAxisOptionsDefs, ["type", "crossLines"]),
    top: without(categoryAxisOptionsDefs, ["type", "crossLines", "position"]),
    right: without(categoryAxisOptionsDefs, ["type", "crossLines", "position"]),
    bottom: without(categoryAxisOptionsDefs, ["type", "crossLines", "position"]),
    left: without(categoryAxisOptionsDefs, ["type", "crossLines", "position"]),
    crossLines: cartesianCrossLineThemeableOptionsDefs
  },
  time: {
    ...without(timeAxisOptionsDefs, ["type", "crossLines"]),
    top: without(timeAxisOptionsDefs, ["type", "crossLines", "position"]),
    right: without(timeAxisOptionsDefs, ["type", "crossLines", "position"]),
    bottom: without(timeAxisOptionsDefs, ["type", "crossLines", "position"]),
    left: without(timeAxisOptionsDefs, ["type", "crossLines", "position"]),
    crossLines: cartesianCrossLineThemeableOptionsDefs
  },
  "unit-time": {
    ...without(unitTimeAxisOptionsDefs, ["type", "crossLines"]),
    top: without(unitTimeAxisOptionsDefs, ["type", "crossLines", "position"]),
    right: without(unitTimeAxisOptionsDefs, ["type", "crossLines", "position"]),
    bottom: without(unitTimeAxisOptionsDefs, ["type", "crossLines", "position"]),
    left: without(unitTimeAxisOptionsDefs, ["type", "crossLines", "position"]),
    crossLines: cartesianCrossLineThemeableOptionsDefs
  },
  "grouped-category": {
    ...without(groupedCategoryAxisOptionsDefs, ["type"]),
    top: without(groupedCategoryAxisOptionsDefs, ["type", "position"]),
    right: without(groupedCategoryAxisOptionsDefs, ["type", "position"]),
    bottom: without(groupedCategoryAxisOptionsDefs, ["type", "position"]),
    left: without(groupedCategoryAxisOptionsDefs, ["type", "position"]),
    crossLines: cartesianCrossLineThemeableOptionsDefs
  },
  "ordinal-time": {
    ...without(ordinalTimeAxisOptionsDefs, ["type", "crossLines"]),
    top: without(ordinalTimeAxisOptionsDefs, ["type", "crossLines", "position"]),
    right: without(ordinalTimeAxisOptionsDefs, ["type", "crossLines", "position"]),
    bottom: without(ordinalTimeAxisOptionsDefs, ["type", "crossLines", "position"]),
    left: without(ordinalTimeAxisOptionsDefs, ["type", "crossLines", "position"]),
    crossLines: cartesianCrossLineThemeableOptionsDefs
  }
};
var polarAxesThemeDef = {
  "angle-category": {
    ...without(angleCategoryAxisOptionsDefs, ["type", "crossLines"]),
    crossLines: without(commonCrossLineOptionsDefs, ["type"])
  },
  "angle-number": {
    ...without(angleNumberAxisOptionsDefs, ["type", "crossLines"]),
    crossLines: without(commonCrossLineOptionsDefs, ["type"])
  },
  "radius-category": {
    ...without(radiusCategoryAxisOptionsDefs, ["type", "crossLines"]),
    crossLines: {
      ...without(commonCrossLineOptionsDefs, ["type"]),
      label: {
        ...commonCrossLineLabelOptionsDefs,
        positionAngle: number
      }
    }
  },
  "radius-number": {
    ...without(radiusNumberAxisOptionsDefs, ["type", "crossLines"]),
    crossLines: {
      ...without(commonCrossLineOptionsDefs, ["type"]),
      label: {
        ...commonCrossLineLabelOptionsDefs,
        positionAngle: number
      }
    }
  }
};
var undocumentedSeriesOptionsDef = {
  visible: undocumented(boolean)
};
var themeOverridesOptionsDef = {
  common: {
    ...commonChartOptionsDefs,
    navigator: navigatorOptionsDef,
    scrollbar: scrollbarOptionsDef,
    axes: {
      ...cartesianAxesThemeDef,
      ...polarAxesThemeDef
    },
    annotations: {
      ...annotationOptionsDef,
      line: annotationLineStyleDefs,
      "horizontal-line": annotationCrossLineStyleDefs,
      "vertical-line": annotationCrossLineStyleDefs,
      "disjoint-channel": annotationDisjointChannelStyleDefs,
      "parallel-channel": annotationParallelChannelStyleDefs,
      "fibonacci-retracement": annotationFibonacciStylesDefs,
      "fibonacci-retracement-trend-based": annotationFibonacciStylesDefs,
      callout: annotationCalloutStylesDefs,
      comment: annotationCommentStylesDefs,
      note: annotationNoteStylesDefs,
      text: annotationTextStylesDef,
      arrow: annotationLineStyleDefs,
      "arrow-up": annotationShapeStylesDefs,
      "arrow-down": annotationShapeStylesDefs,
      "date-range": annotationMeasurerStylesDefs,
      "price-range": annotationMeasurerStylesDefs,
      "date-price-range": annotationMeasurerStylesDefs,
      "quick-date-price-range": annotationQuickMeasurerStylesDefs
    },
    chartToolbar: {
      enabled: boolean
    },
    initialState: {
      legend: arrayOfDefs(
        {
          visible: boolean,
          seriesId: string,
          itemId: string,
          legendItemName: string
        },
        "legend state array"
      ),
      zoom: {
        rangeX: {
          start: or(number, serializableDate),
          end: or(number, serializableDate)
        },
        rangeY: {
          start: or(number, serializableDate),
          end: or(number, serializableDate)
        },
        ratioX: {
          start: ratio,
          end: ratio
        },
        ratioY: {
          start: ratio,
          end: ratio
        },
        autoScaledAxes: arrayOf(constant("y"))
      }
    }
  },
  line: {
    ...commonChartOptionsDefs,
    axes: cartesianAxesThemeDef,
    series: lineSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    scrollbar: scrollbarOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  scatter: {
    ...commonChartOptionsDefs,
    axes: cartesianAxesThemeDef,
    series: scatterSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    scrollbar: scrollbarOptionsDef,
    ...undocumentedSeriesOptionsDef,
    // @ts-expect-error undocumented option - required by grid
    paired: undocumented(boolean)
  },
  bubble: {
    ...commonChartOptionsDefs,
    axes: cartesianAxesThemeDef,
    series: bubbleSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    scrollbar: scrollbarOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  area: {
    ...commonChartOptionsDefs,
    axes: cartesianAxesThemeDef,
    series: areaSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    scrollbar: scrollbarOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  bar: {
    ...commonChartOptionsDefs,
    axes: cartesianAxesThemeDef,
    series: barSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    scrollbar: scrollbarOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  "box-plot": {
    ...commonChartOptionsDefs,
    axes: cartesianAxesThemeDef,
    series: boxPlotSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    scrollbar: scrollbarOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  candlestick: {
    ...commonChartOptionsDefs,
    axes: cartesianAxesThemeDef,
    series: candlestickSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    scrollbar: scrollbarOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  "cone-funnel": {
    ...commonChartOptionsDefs,
    axes: cartesianAxesThemeDef,
    series: coneFunnelSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    scrollbar: scrollbarOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  funnel: {
    ...commonChartOptionsDefs,
    axes: cartesianAxesThemeDef,
    series: funnelSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    scrollbar: scrollbarOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  ohlc: {
    ...commonChartOptionsDefs,
    axes: cartesianAxesThemeDef,
    series: ohlcSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    scrollbar: scrollbarOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  histogram: {
    ...commonChartOptionsDefs,
    axes: without(cartesianAxesThemeDef, ["category", "grouped-category", "unit-time", "ordinal-time"]),
    series: histogramSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    scrollbar: scrollbarOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  heatmap: {
    ...commonChartOptionsDefs,
    axes: cartesianAxesThemeDef,
    series: heatmapSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    scrollbar: scrollbarOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  waterfall: {
    ...commonChartOptionsDefs,
    axes: cartesianAxesThemeDef,
    series: waterfallSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    scrollbar: scrollbarOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  "range-bar": {
    ...commonChartOptionsDefs,
    axes: cartesianAxesThemeDef,
    series: rangeBarSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    scrollbar: scrollbarOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  "range-area": {
    ...commonChartOptionsDefs,
    axes: cartesianAxesThemeDef,
    series: rangeAreaSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    scrollbar: scrollbarOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  donut: {
    ...commonChartOptionsDefs,
    series: donutSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  pie: {
    ...commonChartOptionsDefs,
    series: pieSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  "radar-line": {
    ...commonChartOptionsDefs,
    axes: polarAxesThemeDef,
    series: radarLineSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  "radar-area": {
    ...commonChartOptionsDefs,
    axes: polarAxesThemeDef,
    series: radarAreaSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  "radial-bar": {
    ...commonChartOptionsDefs,
    axes: polarAxesThemeDef,
    series: radialBarSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  "radial-column": {
    ...commonChartOptionsDefs,
    axes: polarAxesThemeDef,
    series: radialColumnSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  nightingale: {
    ...commonChartOptionsDefs,
    axes: polarAxesThemeDef,
    series: nightingaleSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  sunburst: {
    ...commonChartOptionsDefs,
    series: sunburstSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  treemap: {
    ...commonChartOptionsDefs,
    series: treemapSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  "map-shape": {
    ...commonChartOptionsDefs,
    series: mapShapeSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  "map-line": {
    ...commonChartOptionsDefs,
    series: mapLineSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  "map-marker": {
    ...commonChartOptionsDefs,
    series: mapMarkerSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  "map-shape-background": {
    ...commonChartOptionsDefs,
    series: mapShapeBackgroundSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  "map-line-background": {
    ...commonChartOptionsDefs,
    series: mapLineBackgroundSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  sankey: {
    ...commonChartOptionsDefs,
    series: sankeySeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  chord: {
    ...commonChartOptionsDefs,
    series: chordSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  pyramid: {
    ...commonChartOptionsDefs,
    series: pyramidSeriesThemeableOptionsDef,
    navigator: navigatorOptionsDef,
    ...undocumentedSeriesOptionsDef
  },
  "radial-gauge": {
    ...commonChartOptionsDefs,
    ...radialGaugeSeriesThemeableOptionsDef,
    targets: without(radialGaugeTargetOptionsDef, ["value"]),
    tooltip: {
      ...radialGaugeSeriesThemeableOptionsDef.tooltip,
      ...commonChartOptionsDefs.tooltip
    }
  },
  "linear-gauge": {
    ...commonChartOptionsDefs,
    ...linearGaugeSeriesThemeableOptionsDef,
    targets: without(linearGaugeTargetOptionsDef, ["value"]),
    tooltip: {
      ...linearGaugeSeriesThemeableOptionsDef.tooltip,
      ...commonChartOptionsDefs.tooltip
    }
  }
};
function mapValues2(object2, mapper) {
  const result = {};
  for (const key of Reflect.ownKeys(object2)) {
    result[key] = mapper(object2[key], key, object2);
  }
  return result;
}
var themeOverridesOptionsWithOperatorsDef = mapValues2(
  themeOverridesOptionsDef,
  function themeOperatorMapper(value, key) {
    if (isSymbol(key))
      return value;
    if (isFunction(value)) {
      return or(value, themeOperator, isSymbol);
    } else if (isObject(value)) {
      return or(
        optionsDefs(
          unionSymbol in value ? mapValues2(value, (val) => isObject(val) ? mapValues2(val, themeOperatorMapper) : val) : mapValues2(value, themeOperatorMapper)
        ),
        themeOperator,
        isSymbol
      );
    }
    throw new Error(`Invalid theme override value: ${String(value)}`);
  }
);

// packages/ag-charts-community/src/chart/themes/vividDark.ts
var VIVID_DARK_FILLS = {
  BLUE: "#0083ff",
  ORANGE: "#ff6600",
  GREEN: "#00af00",
  CYAN: "#00ccff",
  YELLOW: "#f7c700",
  VIOLET: "#ac26ff",
  GRAY: "#a7a7b7",
  MAGENTA: "#e800c5",
  BROWN: "#b54300",
  RED: "#ff0000"
};
var VIVID_DARK_STROKES = {
  BLUE: "#67b7ff",
  ORANGE: "#ffc24d",
  GREEN: "#5cc86f",
  CYAN: "#54ebff",
  VIOLET: "#fff653",
  YELLOW: "#c18aff",
  GRAY: "#aeaeae",
  MAGENTA: "#f078d4",
  BROWN: "#ba8438",
  RED: "#ff726e"
};
var VividDark = class extends DarkTheme {
  getDefaultColors() {
    return {
      fills: VIVID_DARK_FILLS,
      fillsFallback: Object.values(VIVID_DARK_FILLS),
      strokes: VIVID_DARK_STROKES,
      sequentialColors: getSequentialColors(VIVID_DARK_FILLS),
      divergingColors: [VIVID_DARK_FILLS.ORANGE, VIVID_DARK_FILLS.YELLOW, VIVID_DARK_FILLS.GREEN],
      hierarchyColors: [],
      secondSequentialColors: [
        "#0083ff",
        "#0076e6",
        "#0069cc",
        "#005cb3",
        "#004f99",
        "#004280",
        "#003466",
        "#00274c"
      ],
      secondDivergingColors: [VIVID_DARK_FILLS.GREEN, VIVID_DARK_FILLS.YELLOW, VIVID_DARK_FILLS.RED],
      secondHierarchyColors: [],
      up: { fill: VIVID_DARK_FILLS.GREEN, stroke: VIVID_DARK_STROKES.GREEN },
      down: { fill: VIVID_DARK_FILLS.RED, stroke: VIVID_DARK_STROKES.RED },
      neutral: { fill: VIVID_DARK_FILLS.GRAY, stroke: VIVID_DARK_STROKES.GRAY },
      altUp: { fill: VIVID_DARK_FILLS.BLUE, stroke: VIVID_DARK_STROKES.BLUE },
      altDown: { fill: VIVID_DARK_FILLS.ORANGE, stroke: VIVID_DARK_STROKES.ORANGE },
      altNeutral: { fill: VIVID_DARK_FILLS.GRAY, stroke: VIVID_DARK_STROKES.GRAY }
    };
  }
  getTemplateParameters() {
    const params = super.getTemplateParameters();
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, VIVID_DARK_FILLS.BLUE);
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, VIVID_DARK_FILLS.BLUE);
    return params;
  }
};

// packages/ag-charts-community/src/chart/themes/vividLight.ts
var VIVID_FILLS = {
  BLUE: "#0083ff",
  ORANGE: "#ff6600",
  GREEN: "#00af00",
  CYAN: "#00ccff",
  YELLOW: "#f7c700",
  VIOLET: "#ac26ff",
  GRAY: "#a7a7b7",
  MAGENTA: "#e800c5",
  BROWN: "#b54300",
  RED: "#ff0000"
};
var VIVID_STROKES = {
  BLUE: "#0f68c0",
  ORANGE: "#d47100",
  GREEN: "#007922",
  CYAN: "#009ac2",
  VIOLET: "#bca400",
  YELLOW: "#753cac",
  GRAY: "#646464",
  MAGENTA: "#9b2685",
  BROWN: "#6c3b00",
  RED: "#cb0021"
};
var VividLight = class extends ChartTheme {
  getDefaultColors() {
    return {
      ...super.getDefaultColors(),
      fills: VIVID_FILLS,
      fillsFallback: Object.values(VIVID_FILLS),
      strokes: VIVID_STROKES,
      sequentialColors: getSequentialColors(VIVID_FILLS),
      divergingColors: [VIVID_FILLS.ORANGE, VIVID_FILLS.YELLOW, VIVID_FILLS.GREEN],
      hierarchyColors: [],
      secondSequentialColors: [
        "#0083ff",
        "#1a8fff",
        "#339cff",
        "#4da8ff",
        "#66b5ff",
        "#80c1ff",
        "#99cdff",
        "#b3daff"
      ],
      secondDivergingColors: [VIVID_FILLS.GREEN, VIVID_FILLS.YELLOW, VIVID_FILLS.RED],
      secondHierarchyColors: [],
      up: { fill: VIVID_FILLS.GREEN, stroke: VIVID_STROKES.GREEN },
      down: { fill: VIVID_FILLS.RED, stroke: VIVID_STROKES.RED },
      neutral: { fill: VIVID_FILLS.GRAY, stroke: VIVID_STROKES.GRAY },
      altUp: { fill: VIVID_FILLS.BLUE, stroke: VIVID_STROKES.BLUE },
      altDown: { fill: VIVID_FILLS.ORANGE, stroke: VIVID_STROKES.ORANGE },
      altNeutral: { fill: VIVID_FILLS.GRAY, stroke: VIVID_STROKES.GRAY }
    };
  }
  getTemplateParameters() {
    const params = super.getTemplateParameters();
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR, VIVID_FILLS.BLUE);
    params.set(DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL, VIVID_FILLS.BLUE);
    return params;
  }
};

// packages/ag-charts-community/src/chart/mapping/themes.ts
var lightTheme = simpleMemorize(() => new ChartTheme());
var themeCacheDebug = debugLogger_exports.create(true, "perf");
var cacheCallback = (status, fn, keys) => {
  themeCacheDebug(`[CACHE] ChartTheme`, status, fn.name, keys);
};
var themes = {
  // darkThemes,
  "ag-default-dark": simpleMemorize(() => new DarkTheme()),
  "ag-sheets-dark": simpleMemorize(() => new SheetsDark(), cacheCallback),
  "ag-polychroma-dark": simpleMemorize(() => new PolychromaDark(), cacheCallback),
  "ag-vivid-dark": simpleMemorize(() => new VividDark(), cacheCallback),
  "ag-material-dark": simpleMemorize(() => new MaterialDark(), cacheCallback),
  "ag-financial-dark": simpleMemorize(() => new FinancialDark(), cacheCallback),
  // lightThemes,
  "ag-default": lightTheme,
  "ag-sheets": simpleMemorize(() => new SheetsLight(), cacheCallback),
  "ag-polychroma": simpleMemorize(() => new PolychromaLight(), cacheCallback),
  "ag-vivid": simpleMemorize(() => new VividLight(), cacheCallback),
  "ag-material": simpleMemorize(() => new MaterialLight(), cacheCallback),
  "ag-financial": simpleMemorize(() => new FinancialLight(), cacheCallback)
};
var getChartTheme = simpleMemorize(createChartTheme, cacheCallback);
function createChartTheme(value) {
  if (value instanceof ChartTheme) {
    return value;
  } else if (!validateStructure(value)) {
    return lightTheme();
  }
  if (value == null || typeof value === "string") {
    const stockTheme = themes[value ?? "ag-default"];
    if (stockTheme) {
      return stockTheme();
    }
    throw new Error(`Cannot find theme \`${value}\`.`);
  }
  const { cleared, invalid } = validate(reduceThemeOptions(value), themeOptionsDef, "theme");
  for (const error2 of invalid) {
    logger_exports.warnOnce(String(error2));
  }
  const baseTheme = cleared?.baseTheme ? getChartTheme(cleared.baseTheme) : lightTheme();
  return cleared ? new baseTheme.constructor(cleared) : baseTheme;
}
function reduceThemeOptions(options) {
  if (!isObject(options) || !isObject(options.baseTheme))
    return options;
  let maybeNested = options;
  let palette;
  let params;
  const overrides = [];
  while (typeof maybeNested === "object") {
    palette ?? (palette = maybeNested.palette);
    params ?? (params = maybeNested.params);
    if (maybeNested.overrides) {
      overrides.push(maybeNested.overrides);
    }
    maybeNested = maybeNested.baseTheme;
  }
  return {
    baseTheme: maybeNested,
    overrides: mergeDefaults(...overrides),
    params,
    palette
  };
}
var themeOptionsDef = {
  baseTheme: or(string, object),
  overrides: themeOverridesOptionsWithOperatorsDef,
  params: {
    accentColor: color,
    axisColor: color,
    backgroundColor: color,
    borderColor: color,
    borderRadius: number,
    chartBackgroundColor: color,
    chartPadding: number,
    focusShadow: string,
    foregroundColor: color,
    fontFamily: fontFamilyFull,
    fontSize: number,
    fontWeight,
    gridLineColor: color,
    popupShadow: string,
    subtleTextColor: color,
    textColor: color,
    separationLinesColor: color,
    chromeBackgroundColor: color,
    chromeFontFamily: fontFamilyFull,
    chromeFontSize: number,
    chromeFontWeight: fontWeight,
    chromeSubtleTextColor: color,
    chromeTextColor: color,
    buttonBackgroundColor: color,
    buttonBorder: boolean,
    buttonFontWeight: fontWeight,
    buttonTextColor: color,
    inputBackgroundColor: color,
    inputBorder: boolean,
    inputTextColor: color,
    menuBackgroundColor: color,
    menuBorder: boolean,
    menuTextColor: color,
    panelBackgroundColor: color,
    panelSubtleTextColor: color,
    tooltipBackgroundColor: color,
    tooltipBorder: boolean,
    tooltipTextColor: color,
    tooltipSubtleTextColor: color,
    crosshairLabelBackgroundColor: color,
    crosshairLabelTextColor: color
  },
  palette: {
    fills: arrayOf(colorUnion),
    strokes: arrayOf(color),
    up: { fill: or(color, gradientStrict), stroke: color },
    down: { fill: or(color, gradientStrict), stroke: color },
    neutral: { fill: or(color, gradientStrict), stroke: color }
  }
};
var themeNameValidator = union(
  "ag-default",
  "ag-default-dark",
  "ag-sheets",
  "ag-sheets-dark",
  "ag-polychroma",
  "ag-polychroma-dark",
  "ag-vivid",
  "ag-vivid-dark",
  "ag-material",
  "ag-material-dark",
  "ag-financial",
  "ag-financial-dark"
);
function validateStructure(value) {
  const { invalid } = validate(
    { theme: value },
    { theme: or(themeNameValidator, object) }
  );
  for (const error2 of invalid) {
    logger_exports.warnOnce(String(error2));
  }
  return invalid.length === 0;
}

// packages/ag-charts-community/src/module/optionsGraphUtils.ts
var PATH_EDGE = "path";
var PATH_ARRAY_EDGE = "pathArray";
var DEFAULTS_EDGE = "default";
var OVERRIDES_EDGE = "override";
var USER_OPTIONS_EDGE = "user";
var USER_PARTIAL_OPTIONS_EDGE = "userPartial";
var OPERATION_EDGE = "operation";
var OPERATION_VALUE_EDGE = "operationValue";
var DEPENDENCY_EDGE = "dependency";
var AUTO_ENABLE_EDGE = "autoEnable";
var AUTO_ENABLE_VALUE_EDGE = "autoEnableValue";
var PRUNE_EDGE = "prune";
var CHILDREN_SOURCE_EDGE = "childrenSource";
function isRatio(value) {
  return isNumber(value) && value >= 0 && value <= 1;
}
function hasPathSafe(object2, path) {
  let result = object2;
  for (const part of path) {
    const isPartKey = typeof part === "string" && result != null && (typeof result === "object" || Array.isArray(result)) && part in result;
    if (!isPartKey)
      return false;
    result = result[part];
  }
  return true;
}
function getPathSafe(object2, path) {
  let result = object2;
  for (const part of path) {
    const isPartKey = typeof part === "string" && result != null && (typeof result === "object" || Array.isArray(result)) && part in result;
    if (!isPartKey)
      return;
    result = result[part];
  }
  return result;
}
function setPathSafe(object2, path, value) {
  const pathLength = path.length;
  if (pathLength === 0)
    return;
  let result = object2;
  const lastIndex = pathLength - 1;
  const lastPart = path[lastIndex];
  for (let i = 0; i < lastIndex; i++) {
    const part = path[i];
    const nextPart = path[i + 1];
    let currentValue = result[part];
    if (currentValue == null || !isObjectLike(currentValue)) {
      currentValue = Number.isNaN(Number(nextPart)) ? {} : [];
      result[part] = currentValue;
    }
    result = currentValue;
  }
  result[lastPart] = value;
}
var DIGITS_ONLY_REGEX = /^\d+$/;
function getPathLastIndexIndex(pathArray, offset = 0) {
  let count = 0;
  for (let i = pathArray.length - 1; i >= 0; i--) {
    const part = pathArray[i];
    if (DIGITS_ONLY_REGEX.test(part)) {
      count++;
      if (count > offset)
        return i;
    }
  }
  return -1;
}
function getPathLastIndex(pathArray, offset = 0) {
  const indexIndex = getPathLastIndexIndex(pathArray, offset);
  return Number(pathArray[indexIndex]);
}
function resolvePath(currentPath, path, variables) {
  const relativePathParts = path.split("/");
  let resolvedPath = [...currentPath];
  if (path.startsWith("/")) {
    resolvedPath = [];
    relativePathParts.shift();
  }
  let prevPartWasTwoDots = false;
  for (const part of relativePathParts) {
    if (part === "..") {
      resolvedPath.pop();
      if (!prevPartWasTwoDots)
        resolvedPath.pop();
    } else if (part === ".") {
      resolvedPath.pop();
    } else if (part === "$index") {
      const index = getPathLastIndex(currentPath);
      if (Number.isNaN(index))
        return UNRESOLVABLE_PATH;
      resolvedPath.push(`${index}`);
    } else if (part === "$prevIndex") {
      const index = getPathLastIndex(currentPath);
      if (Number.isNaN(index) || Number(index) <= 0)
        return UNRESOLVABLE_PATH;
      resolvedPath.push(`${Number(index) - 1}`);
    } else if (part.startsWith("$")) {
      const variable = variables?.[part.slice(1)];
      if (variable == null)
        return UNRESOLVABLE_PATH;
      resolvedPath.push(variable);
    } else if (part.length !== 0) {
      resolvedPath.push(part);
    }
    prevPartWasTwoDots = part === "..";
  }
  return resolvedPath;
}
var UNRESOLVABLE_PATH = Symbol("unresolvable-path");
var RESOLVED_TO_BRANCH = Symbol("resolved-to-branch");

// packages/ag-charts-community/src/module/optionsGraphOperations.ts
function getOperation(value, keys) {
  if (value == null || typeof value !== "object" || Array.isArray(value))
    return;
  keys ?? (keys = Object.keys(value));
  if (keys.length === 0)
    return;
  const operation = keys[0];
  if (!operationTypes.has(operation))
    return;
  return {
    operation,
    values: Array.isArray(value[operation]) ? value[operation] : [value[operation]]
  };
}
function getOperationTargetVertex(graph, vertex, valueVertex) {
  const operation = getOperation(graph.getVertexValue(valueVertex));
  switch (operation?.operation) {
    case "$path" /* Path */: {
      const [relativePath] = operation.values;
      const pathArray = graph.getPathArray(vertex);
      const path = resolvePath(pathArray, relativePath);
      if (path === UNRESOLVABLE_PATH)
        return;
      return graph.findVertexAtPath(path);
    }
    case "$value" /* Value */:
      return vertex;
  }
}
var cacheOperations = {
  $cacheMax: cacheMaxOperation
};
function cacheMaxOperation(graph, vertex, values) {
  const [valueVertex] = values;
  const pathArray = graph.getPathArray(vertex);
  const cached = graph.getCachedValue(pathArray, "$cacheMax" /* CacheMax */);
  const value = graph.resolveVertexValue(vertex, valueVertex);
  if (typeof value !== "number")
    return cached;
  if (typeof cached !== "number") {
    graph.setCachedValue(pathArray, "$cacheMax" /* CacheMax */, value);
    return value;
  }
  const maxValue = Math.max(cached, value);
  graph.setCachedValue(pathArray, "$cacheMax" /* CacheMax */, maxValue);
  return maxValue;
}
var chartOperations = {
  $hasSeriesType: { dependencies: seriesTypeDependencyFactory, resolve: hasSeriesTypeOperation },
  $isChartType: { dependencies: seriesTypeDependencyFactory, resolve: isChartTypeOperation },
  $isSeriesType: { dependencies: seriesTypeDependencyFactory, resolve: isSeriesTypeOperation }
};
function seriesTypeDependencyFactory(graph, vertex, _values) {
  const dependencyVertex = graph.findVertexAtPath(["series", "0", "type"]);
  if (dependencyVertex) {
    graph.addEdge(vertex, dependencyVertex, DEPENDENCY_EDGE);
  }
}
function hasSeriesTypeOperation(graph, vertex, values) {
  const [valueVertex] = values;
  const value = graph.resolveVertexValue(vertex, valueVertex);
  const series = graph.getResolvedPath(["series"]);
  if (!Array.isArray(series))
    return false;
  for (const s of series) {
    if (s.type === value)
      return true;
  }
  return false;
}
function isSeriesTypeOperation(graph, vertex, values) {
  const [valueVertex] = values;
  const value = graph.resolveVertexValue(vertex, valueVertex);
  const seriesType = graph.getResolvedPath(["series", "0", "type"]);
  return seriesType === value;
}
function isChartTypeOperation(graph, vertex, values) {
  const [valueVertex] = values;
  const value = graph.resolveVertexValue(vertex, valueVertex);
  const seriesType = graph.getResolvedPath(["series", "0", "type"]);
  if (typeof seriesType !== "string")
    return false;
  const seriesModule = moduleRegistry_exports.getSeriesModule(seriesType);
  if (seriesModule == null)
    return false;
  switch (value) {
    case "cartesian":
      return seriesModule.chartType === "cartesian";
    case "polar":
      return seriesModule.chartType === "polar";
    case "standalone":
      return seriesModule.chartType === "standalone";
  }
  return false;
}
var colorOperations = {
  $foregroundBackgroundMix: foregroundBackgroundMixOperation,
  $foregroundOpacity: foregroundOpacityOperation,
  $interpolate: interpolateOperation,
  $isGradient: isGradientOperation,
  $isImage: isImageOperation,
  $isPattern: isPatternOperation,
  $mix: mixOperation
};
function foregroundBackgroundMixOperation(graph, vertex, values) {
  const [foregroundRatioVertex] = values;
  const foregroundRatio = graph.resolveVertexValue(vertex, foregroundRatioVertex);
  const foregroundColor = graph.getParamValue("foregroundColor");
  const backgroundColor = graph.getParamValue("backgroundColor");
  if (typeof foregroundColor === "string" && typeof backgroundColor === "string" && isRatio(foregroundRatio)) {
    return Color.mix(
      Color.fromString(foregroundColor),
      Color.fromString(backgroundColor),
      1 - foregroundRatio
    ).toString();
  }
  debugLogger_exports.inDevelopmentMode(
    () => logger_exports.warnOnce(
      `\`$foregroundBackgroundMix\` json operation failed on [${String(foregroundRatio)}}}] at [${graph.getPathArray(vertex).join(".")}], expecting a number between 0 and 1.`
    )
  );
}
function foregroundOpacityOperation(graph, vertex, values) {
  const [opacityVertex] = values;
  const opacity = graph.resolveVertexValue(vertex, opacityVertex);
  const foregroundColor = graph.getParamValue("foregroundColor");
  if (typeof foregroundColor === "string" && isRatio(opacity)) {
    const color2 = Color.fromString(foregroundColor);
    return new Color(color2.r, color2.g, color2.b, opacity).toString();
  }
  debugLogger_exports.inDevelopmentMode(
    () => logger_exports.warnOnce(
      `\`$foregroundOpacity\` json operation failed on [${String(opacity)}}}] at [${graph.getPathArray(vertex).join(".")}], expecting a number between 0 and 1.`
    )
  );
}
function interpolateOperation(graph, vertex, values) {
  const [colorsVertex, countVertex] = values;
  const colors = graph.resolveVertexValue(vertex, colorsVertex);
  const count = graph.resolveVertexValue(vertex, countVertex);
  if (!isArray(colors) || !isNumber(count))
    return;
  return Color.interpolate(
    colors.map((color2) => Color.fromString(color2)),
    count
  ).map((color2) => color2.toString());
}
function isGradientOperation(graph, vertex, values) {
  const [valueVertex] = values;
  const value = graph.resolveVertexValue(vertex, valueVertex);
  return isGradientFill(value);
}
function isImageOperation(graph, vertex, values) {
  const [valueVertex] = values;
  const value = graph.resolveVertexValue(vertex, valueVertex);
  return isImageFill(value);
}
function isPatternOperation(graph, vertex, values) {
  const [valueVertex] = values;
  const value = graph.resolveVertexValue(vertex, valueVertex);
  return isPatternFill(value);
}
function mixOperation(graph, vertex, values) {
  const [colorAVertex, colorBVertex, ratioVertex] = values;
  const colorA = graph.resolveVertexValue(vertex, colorAVertex);
  const colorB = graph.resolveVertexValue(vertex, colorBVertex);
  const ratio2 = graph.resolveVertexValue(vertex, ratioVertex);
  const pathArray = graph.getPathArray(vertex);
  const warningPrefix = `\`$mix\` json operation failed on [${String(colorA)}, ${String(colorB)}, ${String(ratio2)}] at [${pathArray.join(".")}], expecting`;
  const warningMessage = `${warningPrefix} two colors and a number between 0 and 1.`;
  if (typeof colorB !== "string" || !isRatio(ratio2)) {
    debugLogger_exports.inDevelopmentMode(() => logger_exports.warnOnce(warningMessage));
    return;
  }
  if (typeof colorA === "string") {
    try {
      return Color.mix(Color.fromString(colorA), Color.fromString(colorB), ratio2).toString();
    } catch {
      debugLogger_exports.inDevelopmentMode(() => logger_exports.warnOnce(warningMessage));
      return;
    }
  }
  if (!isGradientFill(colorA)) {
    debugLogger_exports.inDevelopmentMode(() => logger_exports.warnOnce(warningMessage));
    return;
  }
  let colorStops = colorA.colorStops;
  try {
    colorStops = colorStops?.map((value) => {
      let color2;
      if (typeof value.color === "string") {
        color2 = Color.mix(Color.fromString(value.color), Color.fromString(colorB), ratio2).toString();
      }
      return { ...value, color: color2 };
    });
  } catch {
    debugLogger_exports.inDevelopmentMode(
      () => logger_exports.warnOnce(`${warningPrefix} a gradient, a color and a number between 0 and 1.`)
    );
    return;
  }
  return { ...colorA, colorStops };
}
var fontOperations = {
  $rem: remOperation
};
function remOperation(graph, vertex, values) {
  const [valueVertex] = values;
  const value = graph.getVertexValue(valueVertex);
  const fontSize = graph.getParamValue("fontSize");
  if (typeof fontSize === "number" && typeof value === "number") {
    return Math.round(value * fontSize);
  }
  debugLogger_exports.inDevelopmentMode(
    () => logger_exports.warnOnce(
      `\`$rem\` json operation failed on [${String(value)}] at [${graph.getPathArray(vertex).join(".")}], expecting a number.`
    )
  );
}
var logicOperations = {
  $and: andOperation,
  $eq: eqOperation,
  $every: everyOperation,
  $greaterThan: greaterThanOperation,
  $if: ifOperation,
  $lessThan: lessThanOperation,
  $not: notOperation,
  $or: orOperation,
  $some: someOperation,
  $switch: switchOperation
};
function andOperation(graph, vertex, values) {
  for (const valueVertex of values) {
    const value = graph.resolveVertexValue(vertex, valueVertex);
    if (values.length === 1 && Array.isArray(value)) {
      return value.every((v) => Boolean(v));
    }
    if (!value)
      return false;
  }
  return true;
}
function eqOperation(graph, vertex, values) {
  let compare;
  let first2 = true;
  for (const valueVertex of values) {
    const value = graph.resolveVertexValue(vertex, valueVertex);
    if (first2) {
      compare = value;
      first2 = false;
    } else if (value !== compare) {
      return false;
    }
  }
  return true;
}
function everyOperation(graph, vertex, values) {
  const [mapOperationVertex, mapValuesVertex] = values;
  const mapOperationValue = graph.getVertexValue(mapOperationVertex);
  const mapValues3 = graph.resolveVertexValue(vertex, mapValuesVertex);
  if (!Array.isArray(mapValues3))
    return;
  let index = 0;
  for (const value of mapValues3) {
    const resolved = graph.graftAndResolveOrphanValue(vertex, `${index}`, mapOperationValue, value);
    if (!resolved)
      return false;
    index++;
  }
  return true;
}
function greaterThanOperation(graph, vertex, values) {
  const [value, compare] = values;
  return graph.resolveVertexValue(vertex, value) > graph.resolveVertexValue(vertex, compare);
}
function ifOperation(graph, vertex, values) {
  const [conditionVertex, thenVertex, elseVertex] = values;
  const condition = graph.resolveVertexValue(vertex, conditionVertex);
  const valueVertex = condition ? thenVertex : elseVertex;
  const neighbours = graph.neighboursWithEdgeValue(valueVertex, PATH_EDGE);
  if (neighbours) {
    for (const neighbour of neighbours) {
      graph.addEdge(vertex, neighbour, PATH_EDGE);
    }
  }
  return graph.resolveVertexValue(vertex, valueVertex);
}
function lessThanOperation(graph, vertex, values) {
  const [value, compare] = values;
  return graph.resolveVertexValue(vertex, value) < graph.resolveVertexValue(vertex, compare);
}
function notOperation(graph, vertex, values) {
  const [valueVertex] = values;
  if (!valueVertex)
    return;
  return !graph.resolveVertexValue(vertex, valueVertex);
}
function orOperation(graph, vertex, values) {
  for (const valueVertex of values) {
    const value = graph.resolveVertexValue(vertex, valueVertex);
    if (values.length === 1 && Array.isArray(value)) {
      return value.some((v) => Boolean(v));
    }
    if (value)
      return true;
  }
  return false;
}
function someOperation(graph, vertex, values) {
  const [mapOperationVertex, mapValuesVertex] = values;
  const mapOperationValue = graph.getVertexValue(mapOperationVertex);
  const mapValues3 = graph.resolveVertexValue(vertex, mapValuesVertex);
  if (!Array.isArray(mapValues3))
    return;
  let index = 0;
  for (const value of mapValues3) {
    const resolved = graph.graftAndResolveOrphanValue(vertex, `${index}`, mapOperationValue, value);
    if (resolved)
      return true;
    index++;
  }
  return false;
}
function switchOperation(graph, vertex, values) {
  const [conditionValueVertex, defaultValueVertex, ...caseVertices] = values;
  const conditionValue = graph.resolveVertexValue(vertex, conditionValueVertex);
  for (const caseVertex of caseVertices) {
    const caseValue = graph.getVertexValue(caseVertex);
    if (!Array.isArray(caseValue))
      continue;
    const [caseConditionValue, caseResultValue] = caseValue;
    if (conditionValue === caseConditionValue || Array.isArray(caseConditionValue) && caseConditionValue.includes(conditionValue)) {
      return caseResultValue;
    }
  }
  return graph.resolveVertexValue(vertex, defaultValueVertex);
}
var locationOperations = {
  $isUserOption: isUserOptionOperation,
  $palette: paletteOperation,
  $mapPalette: mapPaletteOperation,
  $path: {
    dependencies: pathOperationDependenciesFactory,
    resolve: pathOperation
  },
  $pathString: {
    dependencies: pathOperationDependenciesFactory,
    resolve: pathStringOperation
  },
  $ref: refOperation
};
function isUserOptionOperation(graph, vertex, values) {
  const [relativePathVertices, thenVertex, elseVertex] = values;
  const children = graph.neighboursWithEdgeValue(relativePathVertices, PATH_EDGE);
  if (children) {
    for (const child of children) {
      const relativePathVertex = graph.findNeighbour(child, DEFAULTS_EDGE);
      if (relativePathVertex && isUserOptionCheck(graph, vertex, relativePathVertex)) {
        return graph.resolveVertexValue(vertex, thenVertex);
      }
    }
  } else if (isUserOptionCheck(graph, vertex, relativePathVertices)) {
    return graph.resolveVertexValue(vertex, thenVertex);
  }
  return graph.resolveVertexValue(vertex, elseVertex);
}
function isUserOptionCheck(graph, vertex, relativePathVertex) {
  const relativePath = graph.resolveVertexValue(vertex, relativePathVertex);
  if (!isString(relativePath)) {
    throw new Error(`\`$isUserOption\` json operation failed on [${String(relativePath)}], expecting a string.`);
  }
  const pathArray = graph.getPathArray(vertex);
  const path = resolvePath(pathArray, relativePath);
  if (path === UNRESOLVABLE_PATH)
    return false;
  return graph.hasUserOption(path);
}
var PALETTE_INDEX_KEYS = /* @__PURE__ */ new Set(["fill", "fillFallback", "stroke", "gradient", "range2"]);
function paletteOperation(graph, vertex, values) {
  const [keyVertex] = values;
  const key = graph.resolveVertexValue(vertex, keyVertex);
  if (!isString(key))
    return;
  if (PALETTE_INDEX_KEYS.has(key)) {
    const pathArray = graph.getPathArray(vertex);
    const index = getPathLastIndex(pathArray);
    if (Number.isNaN(index))
      return;
    switch (key) {
      case "fill":
        return circularSliceArray(graph.palette.fills, 1, index)[0];
      case "fillFallback":
        return circularSliceArray(graph.palette.fillsFallback, 1, index)[0];
      case "stroke":
        return circularSliceArray(graph.palette.strokes, 1, index)[0];
      case "gradient":
        return circularSliceArray(graph.palette.sequentialColors, 1, index)[0];
      case "range2":
        return circularSliceArray(graph.palette.fills, 2, index);
    }
    return;
  }
  if (key === "gradients") {
    return graph.palette.sequentialColors;
  }
  if (key === "type") {
    return graph.paletteType;
  }
  const value = getPathSafe(graph.palette, key.split("."));
  if (Array.isArray(value))
    return [...value];
  if (typeof value === "object")
    return { ...value };
  return value;
}
function mapPaletteOperation(graph, vertex, values) {
  const [keyVertex] = values;
  const key = graph.resolveVertexValue(vertex, keyVertex);
  if (!isString(key))
    return;
  if (PALETTE_INDEX_KEYS.has(key)) {
    const pathArray = graph.getPathArray(vertex);
    let index = getPathLastIndex(pathArray);
    let ignoreIndexOffset = 0;
    const path = ["series", "0", "type"];
    for (let i = 0; i < index; i++) {
      path[1] = `${i}`;
      const siblingSeriesType = graph.getResolvedPath(path);
      if ("map-shape-background" === siblingSeriesType || "map-line-background" === siblingSeriesType) {
        ignoreIndexOffset++;
      }
    }
    index -= ignoreIndexOffset;
    if (Number.isNaN(index))
      return;
    switch (key) {
      case "fill":
        return circularSliceArray(graph.palette.fills, 1, index)[0];
      case "fillFallback":
        return circularSliceArray(graph.palette.fillsFallback, 1, index)[0];
      case "stroke":
        return circularSliceArray(graph.palette.strokes, 1, index)[0];
      case "gradient":
        return circularSliceArray(graph.palette.sequentialColors, 1, index)[0];
      case "range2":
        return circularSliceArray(graph.palette.fills, 2, index);
    }
    return;
  }
  if (key === "gradients") {
    return graph.palette.sequentialColors;
  }
  if (key === "type") {
    return graph.paletteType;
  }
  const value = getPathSafe(graph.palette, key.split("."));
  if (Array.isArray(value))
    return [...value];
  if (typeof value === "object")
    return { ...value };
  return value;
}
function pathOperationDependenciesFactory(graph, vertex, values) {
  const [relativePathVertex] = values;
  const relativePath = graph.getVertexValue(relativePathVertex);
  if (isString(relativePath)) {
    const pathArray = graph.getPathArray(vertex);
    const path = resolvePath(pathArray, relativePath);
    if (path === UNRESOLVABLE_PATH) {
      return;
    }
    const dependencyVertex = graph.findVertexAtPath(path);
    if (dependencyVertex) {
      graph.addEdge(vertex, dependencyVertex, DEPENDENCY_EDGE);
    }
  }
}
function pathOperation(graph, vertex, values) {
  const hasDefaultValue = values.length > 1;
  const hasCustomBranch = values.length > 2;
  const [relativePathVertex, defaultValueVertex, customBranchVertex] = values;
  const relativePath = graph.resolveVertexValue(vertex, relativePathVertex);
  const customBranch = hasCustomBranch ? graph.resolveVertexValue(vertex, customBranchVertex) : null;
  if (!isString(relativePath)) {
    throw new Error(`\`$path\` json operation failed on [${String(relativePath)}], expecting a string.`);
  }
  const pathArray = graph.getPathArray(vertex);
  const path = resolvePath(pathArray, relativePath);
  if (path === UNRESOLVABLE_PATH) {
    return;
  }
  const resolved = customBranch ? getPathSafe(customBranch, path) : graph.getResolvedPath(path);
  if (resolved != null) {
    return resolved;
  }
  if (hasDefaultValue) {
    return graph.resolveVertexValue(vertex, defaultValueVertex);
  }
}
function pathStringOperation(graph, vertex, values) {
  const [relativePathVertex, variablesVertex] = values;
  const relativePath = graph.resolveVertexValue(vertex, relativePathVertex);
  if (!isString(relativePath)) {
    throw new Error(`\`$path\` json operation failed on [${String(relativePath)}], expecting a string.`);
  }
  let variables;
  if (variablesVertex) {
    variables = graph.graftAndResolveOrphan(vertex, variablesVertex);
  }
  const pathArray = graph.getPathArray(vertex);
  const path = resolvePath(pathArray, relativePath, variables);
  if (path === UNRESOLVABLE_PATH) {
    throw new Error(`Unresolvable path [${relativePath}] at [${pathArray.join(".")}]`);
  }
  return path;
}
function refOperation(graph, _vertex, values) {
  const [value] = values;
  const paramKey = graph.getVertexValue(value);
  return graph.getParamValue(paramKey);
}
var transformOperations = {
  $apply: applyOperation,
  $applyCycle: applyCycleOperation,
  $applySwitch: applySwitchOperation,
  $applyTheme: applyThemeOperation,
  $clone: cloneOperation,
  $findFirstSiblingNotOperation: findFirstSiblingNotOperationOperation,
  $map: mapOperation,
  $merge: mergeOperation,
  $omit: omitOperation,
  $size: sizeOperation,
  $shallow: shallowOperation,
  $shallowSimple: shallowSimpleOperation,
  $value: valueOperation
};
function applyOperation(graph, vertex, values) {
  const [objectVertex, defaultValueVertex, overridesPathVertex1, overridesPathVertex2] = values;
  const object2 = graph.getVertexValue(objectVertex);
  if (!isPlainObject(object2))
    return;
  const defaultValue = defaultValueVertex ? graph.getVertexValue(defaultValueVertex) : void 0;
  const children = graph.neighboursWithEdgeValue(vertex, PATH_EDGE);
  const hasChildren = children && children.length > 0;
  if (!hasChildren && defaultValue == null) {
    return RESOLVED_TO_BRANCH;
  }
  const overridesPath1 = overridesPathVertex1 ? graph.resolveVertexValue(vertex, overridesPathVertex1) : void 0;
  const overridesPath2 = overridesPathVertex2 ? graph.resolveVertexValue(vertex, overridesPathVertex2) : void 0;
  if (!hasChildren && defaultValue != null) {
    if (getOperation(defaultValue)) {
      const resolvedDefaultValue = graph.resolveVertexValue(vertex, defaultValueVertex);
      if (isPlainObject(resolvedDefaultValue)) {
        graph.graftObject(vertex, resolvedDefaultValue, [overridesPath1, overridesPath2]);
      }
    } else {
      graph.graftObject(vertex, defaultValue, [overridesPath1, overridesPath2]);
    }
  }
  if (!hasChildren)
    return RESOLVED_TO_BRANCH;
  for (const child of children) {
    const childNeighbours = graph.neighboursWithEdgeValue(child, PATH_EDGE);
    if (!childNeighbours || childNeighbours.length === 0) {
      const stubVertex = graph.addVertex({});
      graph.addEdge(child, stubVertex, DEFAULTS_EDGE);
    } else {
      graph.graftObject(child, object2, [overridesPath1, overridesPath2]);
    }
  }
  return RESOLVED_TO_BRANCH;
}
function applyCycleOperation(graph, vertex, values) {
  const [sizeVertex, defaultValuesVertex, operationVertex] = values;
  const size = graph.resolveVertexValue(vertex, sizeVertex);
  if (typeof size !== "number")
    return;
  const pathArray = graph.getPathArray(vertex);
  const userOption = graph.dangerouslyGetUserOption(pathArray);
  const hasThemeOverride = graph.hasThemeOverride(pathArray);
  const graftEdge = userOption == null ? void 0 : USER_OPTIONS_EDGE;
  const cycledValues = userOption ?? graph.resolveVertexValue(vertex, defaultValuesVertex);
  if (!Array.isArray(cycledValues))
    return;
  const operation = operationVertex ? graph.getVertexValue(operationVertex) : void 0;
  for (let index = 0; index < size; index++) {
    const value = cycledValues[index % cycledValues.length];
    if (value == null)
      continue;
    if (userOption || !hasThemeOverride) {
      graph.graftValue(vertex, `${index}`, value, void 0, graftEdge);
    }
    if (operation) {
      graph.graftValue(vertex, `${index}`, operation, value, graftEdge);
    }
  }
  return RESOLVED_TO_BRANCH;
}
function applySwitchOperation(graph, vertex, values) {
  const [conditionValueVertex, defaultValueVertex, ...caseVertices] = values;
  const conditionValue = graph.resolveVertexValue(vertex, conditionValueVertex);
  for (const caseVertex of caseVertices) {
    const caseValue = graph.getVertexValue(caseVertex);
    if (!Array.isArray(caseValue))
      continue;
    const [caseConditionValue, caseResultValue] = caseValue;
    if (conditionValue === caseConditionValue || Array.isArray(caseConditionValue) && caseConditionValue.includes(conditionValue)) {
      graph.graftObject(vertex, caseResultValue, [], DEFAULTS_EDGE);
      return RESOLVED_TO_BRANCH;
    }
  }
  return graph.resolveVertexValue(vertex, defaultValueVertex);
}
function applyThemeOperation(graph, vertex, values) {
  const [fromPathVertex, variablesVertex, ignorePathsVertex] = values;
  let fromPaths = graph.getVertexValue(fromPathVertex);
  if (typeof fromPaths === "string") {
    fromPaths = [fromPaths];
  }
  if (!Array.isArray(fromPaths))
    return;
  const children = graph.neighboursWithEdgeValue(vertex, PATH_EDGE);
  const ignorePathsValue = ignorePathsVertex ? graph.getVertexValue(ignorePathsVertex) : [];
  const ignorePaths = Array.isArray(ignorePathsValue) ? new Set(ignorePathsValue) : /* @__PURE__ */ new Set();
  if (!children)
    return RESOLVED_TO_BRANCH;
  for (const child of children) {
    const variables = graph.graftAndResolveOrphan(child, variablesVertex);
    for (const fromPath of fromPaths) {
      const fromPathResolved = resolvePath([], fromPath, variables);
      if (fromPathResolved === UNRESOLVABLE_PATH) {
        continue;
      }
      graph.graftConfig(child, fromPathResolved, ignorePaths);
    }
  }
  return RESOLVED_TO_BRANCH;
}
function cloneOperation(graph, vertex, values) {
  const [valueVertex] = values;
  const value = graph.resolveVertexValue(vertex, valueVertex);
  if (!isPlainObject(value))
    return;
  graph.graftObject(vertex, value, void 0, USER_OPTIONS_EDGE);
  return RESOLVED_TO_BRANCH;
}
function findFirstSiblingNotOperationOperation(graph, vertex, values) {
  const [defaultValueVertex] = values;
  const pathArray = graph.getPathArray(vertex);
  const parentPathArray = resolvePath(pathArray, "..");
  if (parentPathArray === UNRESOLVABLE_PATH)
    return;
  const parentVertex = graph.findVertexAtPath(parentPathArray);
  if (!parentVertex) {
    return graph.resolveVertexValue(vertex, defaultValueVertex);
  }
  const siblings = graph.neighboursWithEdgeValue(parentVertex, PATH_EDGE);
  if (siblings) {
    for (const sibling of siblings) {
      const siblingPathArray = graph.getPathArray(sibling);
      if (siblingPathArray[parentPathArray.length] === pathArray[parentPathArray.length])
        continue;
      const siblingChildPathArray = siblingPathArray.concat(pathArray.slice(parentPathArray.length + 1));
      const siblingChildVertex = graph.findVertexAtPath(siblingChildPathArray);
      if (!siblingChildVertex)
        continue;
      const siblingChildUserOptionsValue = graph.findNeighbourValue(siblingChildVertex, USER_OPTIONS_EDGE);
      if (siblingChildUserOptionsValue != null) {
        return siblingChildUserOptionsValue;
      }
      const siblingChildOverridesValue = graph.findNeighbourValue(siblingChildVertex, OVERRIDES_EDGE);
      if (siblingChildOverridesValue != null) {
        return siblingChildOverridesValue;
      }
    }
  }
  return graph.resolveVertexValue(vertex, defaultValueVertex);
}
function mapOperation(graph, vertex, values) {
  const [mapOperationVertex, mapValuesVertex] = values;
  const mapOperationValue = graph.getVertexValue(mapOperationVertex);
  const mapValues3 = graph.resolveVertexValue(vertex, mapValuesVertex);
  if (!Array.isArray(mapValues3))
    return;
  const neighbours = graph.neighboursWithEdgeValue(vertex, PATH_EDGE);
  if (neighbours && neighbours.length > 0) {
    return;
  }
  let index = 0;
  for (const value of mapValues3) {
    graph.graftValue(vertex, `${index}`, mapOperationValue, value);
    index++;
  }
  return RESOLVED_TO_BRANCH;
}
function mergeOperation(graph, vertex, values) {
  for (const valueVertex of values) {
    const value = graph.resolveVertexValue(vertex, valueVertex);
    if (!isPlainObject(value))
      continue;
    graph.graftObject(vertex, value);
  }
  return RESOLVED_TO_BRANCH;
}
function omitOperation(graph, vertex, values) {
  const [keysVertex, objectVertex] = values;
  let keys = graph.getVertexValue(keysVertex);
  if (!Array.isArray(keys)) {
    const targetVertex = getOperationTargetVertex(graph, vertex, objectVertex);
    if (!targetVertex)
      return;
    keys = graph.resolveVertexValue(targetVertex, keysVertex);
  }
  const object2 = graph.resolveVertexValue(vertex, objectVertex);
  if (!Array.isArray(keys) || !isPlainObject(object2))
    return;
  return without(object2, keys);
}
function sizeOperation(graph, vertex, values) {
  const [valueVertex] = values;
  const value = graph.resolveVertexValue(vertex, valueVertex);
  if (!isObjectLike(value))
    return 0;
  if ("length" in value)
    return value.length;
  return Object.keys(value).length;
}
function shallowSimpleOperation(graph, _vertex, values) {
  const shallowValues = [];
  for (const valueVertex of values) {
    shallowValues.push(graph.getVertexValue(valueVertex));
  }
  return shallowValues;
}
function shallowOperation(graph, vertex, values) {
  const pathArray = graph.getPathArray(vertex);
  const hasUserOption = graph.hasUserOption(pathArray);
  if (!hasUserOption && values.length === 1) {
    return graph.resolveVertexValue(vertex, values[0]);
  }
  const shallowValues = [];
  for (const valueVertex of values) {
    shallowValues.push(graph.getVertexValue(valueVertex));
  }
  if (hasUserOption) {
    graph.prune(vertex, [OVERRIDES_EDGE, DEFAULTS_EDGE]);
    return RESOLVED_TO_BRANCH;
  }
  graph.graftObject(vertex, shallowValues);
  return RESOLVED_TO_BRANCH;
}
function valueOperation(graph, vertex, values) {
  const [valueVertex] = values;
  const value = graph.getVertexValue(valueVertex);
  const pathArray = graph.getPathArray(vertex);
  if (value === "$index") {
    return getPathLastIndex(pathArray);
  }
  if (value === "$parentIndex") {
    return getPathLastIndex(pathArray, 1);
  }
  if (value === "$1") {
    return graph.resolveValue$1(pathArray);
  }
}
var numericOperations = {
  $isEven: isEvenOperation
};
function isEvenOperation(graph, vertex, values) {
  const [valueVertex] = values;
  const value = graph.resolveVertexValue(vertex, valueVertex);
  if (Number.isNaN(Number(value)))
    return false;
  return Number(value) % 2 === 0;
}
var operations = {
  ...cacheOperations,
  ...chartOperations,
  ...colorOperations,
  ...fontOperations,
  ...locationOperations,
  ...logicOperations,
  ...numericOperations,
  ...transformOperations
};
var operationTypes = new Set(Object.keys(operations));
function isOperation(value) {
  return operationTypes.has(value);
}

// packages/ag-charts-community/src/module/optionsGraph.ts
var debug2 = debugLogger_exports.create("opts", "options-graph");
var createOptionsGraph = simpleMemorize(createOptionsGraphFn);
function createOptionsGraphFn(theme, options) {
  return debug2.group("OptionsGraph.constructor()", () => {
    const optionsGraph = new OptionsGraph(
      theme.config,
      options,
      theme.params,
      theme.palette,
      theme.overrides,
      theme.getTemplateParameters()
    );
    return {
      resolve() {
        return optionsGraph.resolve();
      },
      resolveParams() {
        return optionsGraph.resolveParams();
      },
      resolveAnnotationThemes() {
        return optionsGraph.resolveAnnotationThemes();
      },
      resolvePartial(path, partialOptions, resolveOptions) {
        return optionsGraph.resolvePartial(path, partialOptions, resolveOptions);
      },
      clearSafe() {
        return optionsGraph.clearSafe();
      }
    };
  });
}
var _OptionsGraph = class _OptionsGraph extends AdjacencyListGraph {
  constructor(config = {}, userOptions = {}, params = void 0, palette = {}, overrides = void 0, internalParams = /* @__PURE__ */ new Map()) {
    super(PATH_EDGE, OPERATION_EDGE, /* @__PURE__ */ new Set([USER_PARTIAL_OPTIONS_EDGE, USER_OPTIONS_EDGE]));
    this.config = config;
    this.userOptions = userOptions;
    this.palette = palette;
    this.overrides = overrides;
    this.internalParams = internalParams;
    // The current priority order in which to resolve options values.
    this.edgePriority = [..._OptionsGraph.EDGE_PRIORITY];
    // The edge value to use when grafting new branches onto the graph from operations.
    this.graftEdge = _OptionsGraph.GRAFT_EDGE;
    this.resolvedParams = {};
    this.resolvedAnnotations = {};
    // The current value referenced by operations that use `$1`.
    this.value$1 = /* @__PURE__ */ new Map();
    this.cachedPathVertices = /* @__PURE__ */ new Map();
    this.hasUnsafeClearKeys = false;
    this.rollbackVertices = [];
    this.rollbackEdgesFrom = [];
    this.rollbackEdgesTo = [];
    this.rollbackEdgesValue = [];
    this.isRollingBack = false;
    // Records the already resolved root ancestors, i.e. vertices with a path of a single segment
    this.resolvedRootAncestorsPaths = /* @__PURE__ */ new Set();
    this.EMPTY_PATH_ARRAY_VERTEX = this.addVertex([]);
    this.root = this.addVertex("root");
    this.params = this.addVertex("params");
    this.annotations = this.addVertex("annotations");
    this.paletteType = isObject(userOptions?.theme) ? paletteType(userOptions.theme?.palette) : "inbuilt";
    const seriesType = userOptions.series?.[0]?.type ?? "line";
    debug2("build user");
    this.buildGraphFromObject(this.root, USER_OPTIONS_EDGE, without(userOptions, ["theme"]));
    debug2("build defaults");
    this.buildGraphFromObject(this.root, DEFAULTS_EDGE, without(config[seriesType], _OptionsGraph.COMPLEX_KEYS));
    const seriesOverrides = overrides ? without(overrides[seriesType], _OptionsGraph.COMPLEX_KEYS) : {};
    if (Object.keys(seriesOverrides).length > 0) {
      debug2("build series overrides");
      this.buildGraphFromObject(this.root, OVERRIDES_EDGE, seriesOverrides);
    }
    const commonOverrides = overrides ? without(overrides.common, _OptionsGraph.COMPLEX_KEYS) : {};
    if (Object.keys(commonOverrides).length > 0) {
      debug2("build common overrides");
      this.buildGraphFromObject(
        this.root,
        OVERRIDES_EDGE,
        moduleRegistry_exports.getSeriesModule(seriesType)?.chartType === "cartesian" ? commonOverrides : without(commonOverrides, ["zoom", "navigator"])
      );
    }
    if (params) {
      debug2("build params");
      this.buildGraphFromObject(this.params, DEFAULTS_EDGE, params);
    }
    const axesVertex = this.findNeighbourWithValue(this.root, "axes", PATH_EDGE);
    const seriesVertex = this.findNeighbourWithValue(this.root, "series", PATH_EDGE);
    if (axesVertex) {
      debug2("build axes");
      this.buildGraphFromObject(axesVertex, DEFAULTS_EDGE, {
        $applyTheme: [
          ["/$seriesType/axes/$axisType/$position", "/$seriesType/axes/$axisType"],
          {
            seriesType: { $path: ["/series/0/type", "line"] },
            axisType: { $path: ["./type", "category"] },
            position: { $path: ["./position"] }
          },
          ["top", "right", "bottom", "left"]
        ]
      });
    }
    if (seriesVertex) {
      debug2("build series");
      this.buildGraphFromObject(seriesVertex, DEFAULTS_EDGE, {
        $applyTheme: ["/$seriesType/series", { seriesType: { $path: ["./type", "line"] } }]
      });
    }
    const annotationsTypeConfig = without(
      config[seriesType]?.annotations ?? {},
      _OptionsGraph.ANNOTATIONS_OPTIONS_KEYS
    );
    if (Object.keys(annotationsTypeConfig).length > 0) {
      debug2("build annotations type config");
      this.buildGraphFromObject(this.annotations, DEFAULTS_EDGE, annotationsTypeConfig);
    }
    const annotationsTypeOverrides = without(
      overrides?.common?.annotations ?? {},
      _OptionsGraph.ANNOTATIONS_OPTIONS_KEYS
    );
    if (Object.keys(annotationsTypeOverrides).length > 0) {
      debug2("build annotations type overrides");
      this.buildGraphFromObject(this.annotations, OVERRIDES_EDGE, annotationsTypeOverrides);
    }
    const annotationsConfig = pick(config[seriesType]?.annotations ?? {}, _OptionsGraph.ANNOTATIONS_OPTIONS_KEYS);
    if (Object.keys(annotationsConfig).length > 0) {
      debug2("build annotations config");
      this.buildGraphFromObject(this.root, DEFAULTS_EDGE, { annotations: annotationsConfig });
    }
    const annotationsOverrides = pick(overrides?.common?.annotations ?? {}, _OptionsGraph.ANNOTATIONS_OPTIONS_KEYS);
    if (Object.keys(annotationsOverrides).length > 0) {
      debug2("build annotations overrides");
      this.buildGraphFromObject(this.root, OVERRIDES_EDGE, { annotations: annotationsOverrides });
    }
    this.buildDependencyGraph();
  }
  static clearValueCache() {
    _OptionsGraph.valueCache.clear();
  }
  clear() {
    debug2.group("OptionsGraph.clear()", () => {
      super.clear();
      this.cachedPathVertices.clear();
      this.root = void 0;
      this.params = void 0;
      this.annotations = void 0;
      debug2("cleared");
    });
  }
  clearSafe() {
    if (this.hasUnsafeClearKeys)
      return;
    this.clear();
  }
  resolve() {
    return debug2.group("OptionsGraph.resolve()", () => {
      this.resolved = {};
      this.resolvedParams = {};
      this.resolvedAnnotations = {};
      debug2("resolve params");
      this.resolveVertex(this.params, this.resolvedParams);
      debug2("resolve annotations");
      this.resolveVertex(this.annotations, this.resolvedAnnotations);
      debug2("resolve root");
      this.resolveVertex(this.root);
      debug2("resolved root", this.resolved);
      debug2("vertex count", this.getVertexCount());
      debug2("edge count", this.getEdgeCount());
      return this.resolved;
    });
  }
  resolveParams() {
    return this.resolvedParams;
  }
  resolveAnnotationThemes() {
    return this.resolvedAnnotations;
  }
  addVertex(value) {
    const vertex = super.addVertex(value);
    if (this.isRollingBack) {
      this.rollbackVertices.push(vertex);
    }
    return vertex;
  }
  addEdge(from3, to, edge) {
    const hasEdge = (this.neighboursWithEdgeValue(from3, edge)?.indexOf(to) ?? -1) !== -1;
    if (this.isRollingBack && !hasEdge) {
      this.rollbackEdgesFrom.push(from3);
      this.rollbackEdgesTo.push(to);
      this.rollbackEdgesValue.push(edge);
    }
    super.addEdge(from3, to, edge);
  }
  /**
   * Resolve partial options against the existing graph at a given path without overriding the existing user values.
   * Returns an object with only those keys that were also present within `partialOptions`.
   */
  resolvePartial(path, partialOptions, resolveOptions) {
    if (!partialOptions)
      return;
    if (!this.root)
      return;
    const { permissivePath, proxyPaths } = resolveOptions ?? {};
    const partialKeys = Object.keys(partialOptions);
    if (debug2.check()) {
      console.groupCollapsed(`OptionsGraph.resolvePartial() - ${path.join(".")} [${partialKeys}]`);
    }
    if (partialKeys.length === 0)
      return {};
    const parentVertex = this.findVertexAtPath(path);
    if (!parentVertex) {
      if (permissivePath) {
        return void 0;
      } else {
        throw new Error(`Could not find vertex in OptionsGraph at path [${path.join(".")}].`);
      }
    }
    const pathArrayVertex = this.findNeighbour(parentVertex, PATH_ARRAY_EDGE);
    this.userPartialOptions = {};
    setPathSafe(this.userPartialOptions, path, partialOptions);
    if (proxyPaths) {
      for (const proxyFrom of Object.keys(proxyPaths)) {
        const proxyTo = proxyPaths[proxyFrom];
        const proxyValue = getPathSafe(partialOptions, [proxyFrom]);
        if (proxyValue != null) {
          setPathSafe(partialOptions, proxyTo, proxyValue);
          setPathSafe(this.userPartialOptions, [...path, ...proxyTo], proxyValue);
          delete partialOptions[proxyFrom];
          delete this.userPartialOptions[proxyFrom];
        }
      }
    }
    this.graftEdge = USER_PARTIAL_OPTIONS_EDGE;
    this.edgePriority = [USER_PARTIAL_OPTIONS_EDGE, ..._OptionsGraph.EDGE_PRIORITY];
    this.snapshot();
    this.buildGraphFromObject(parentVertex, USER_PARTIAL_OPTIONS_EDGE, partialOptions, pathArrayVertex);
    for (const key of partialKeys) {
      const childVertex = proxyPaths?.[key] ? this.findVertexAtPath([...path, ...proxyPaths[key]]) : this.findNeighbourWithValue(parentVertex, key, PATH_EDGE);
      if (childVertex) {
        this.refreshPendingProcessingEdges(childVertex);
      }
    }
    this.buildDependencyGraph();
    const resolved = {};
    this.resolveVertex(parentVertex, resolved);
    this.rollback();
    this.graftEdge = _OptionsGraph.GRAFT_EDGE;
    this.edgePriority = _OptionsGraph.EDGE_PRIORITY;
    this.userPartialOptions = void 0;
    if (proxyPaths) {
      for (const proxyFrom of Object.keys(proxyPaths)) {
        const proxyTo = proxyPaths[proxyFrom];
        const proxyValue = getPathSafe(resolved, [...path, ...proxyTo]);
        setPathSafe(resolved, [...path, proxyFrom], proxyValue);
      }
    }
    const pathed = getPathSafe(resolved, path);
    const shouldPick = resolveOptions?.pick ?? true;
    const partial = shouldPick ? pick(getPathSafe(resolved, path), partialKeys) : pathed;
    debug2("vertex count", this.getVertexCount());
    debug2("edge count", this.getEdgeCount());
    debug2("resolved partial", partial);
    if (debug2.check()) {
      console.groupEnd();
    }
    return partial;
  }
  findVertexAtPath(path) {
    const key = path.join(".");
    if (this.cachedPathVertices.has(key)) {
      return this.cachedPathVertices.get(key);
    }
    const vertex = this.findVertexAlongEdge(this.root, path, PATH_EDGE);
    if (!vertex)
      return;
    this.cachedPathVertices.set(key, vertex);
    return vertex;
  }
  hasUserOption(path) {
    const hasUserOptionSimple = hasPathSafe(this.userOptions, path);
    if (hasUserOptionSimple)
      return true;
    const pathVertex = this.findVertexAtPath(path);
    if (pathVertex) {
      if (this.findNeighbour(pathVertex, USER_OPTIONS_EDGE) != null)
        return true;
      if (this.findNeighbour(pathVertex, USER_PARTIAL_OPTIONS_EDGE) != null)
        return true;
      const childrenSource = this.findNeighbourValue(pathVertex, CHILDREN_SOURCE_EDGE);
      return childrenSource === USER_OPTIONS_EDGE || childrenSource === USER_PARTIAL_OPTIONS_EDGE;
    }
    return false;
  }
  /**
   * Get the value from the user options at the given path. This method is dangerous since it does not resolve
   * through the graph, however is useful for operations that operate on their own path where attempting to
   * resolve would cause an infinite loop.
   */
  dangerouslyGetUserOption(path) {
    if (this.userPartialOptions) {
      const value = getPathSafe(this.userPartialOptions, path);
      if (value != null)
        return value;
    }
    return getPathSafe(this.userOptions, path);
  }
  hasThemeOverride(path) {
    if (this.overrides == null)
      return false;
    if (path[0] === "axes" && path.length > 1) {
      const axisType = this.getResolvedPath(["axes", path[1], "type"]);
      if (hasPathSafe(this.overrides, ["common", "axes", axisType, ...path.slice(2)])) {
        return true;
      }
      const seriesType = this.getResolvedPath(["series", "0", "type"]);
      return hasPathSafe(this.overrides, [seriesType, "axes", axisType, ...path.slice(2)]);
    }
    if (path[0] === "series" && path.length > 1) {
      const seriesType = this.getResolvedPath(["series", path[1], "type"]);
      return hasPathSafe(this.overrides, [seriesType, "series", ...path.slice(2)]);
    }
    return hasPathSafe(this.overrides, path);
  }
  getParamValue(path) {
    if (this.resolvedParams[path] != null) {
      return this.resolvedParams[path];
    }
    const paramVertex = this.findVertexAlongEdge(this.params, [path], PATH_EDGE);
    if (!paramVertex)
      return;
    const defaultValueVertex = this.findNeighbour(paramVertex, DEFAULTS_EDGE);
    if (!defaultValueVertex)
      return;
    const resolved = this.resolveVertexValue(paramVertex, defaultValueVertex);
    this.resolvedParams[path] = resolved;
    return resolved;
  }
  getPathArray(vertex) {
    return this.findNeighbourValue(vertex, PATH_ARRAY_EDGE) ?? [];
  }
  getResolvedPath(path) {
    return getPathSafe(this.resolved, path);
  }
  getCachedValue(path, key) {
    const cacheKey = [...path, key].join(".");
    return _OptionsGraph.valueCache.get(cacheKey);
  }
  setCachedValue(path, key, value) {
    const cacheKey = [...path, key].join(".");
    _OptionsGraph.valueCache.set(cacheKey, value);
  }
  prune(vertex, edges) {
    this.addEdge(vertex, this.addVertex(edges), PRUNE_EDGE);
  }
  resolveVertexValue(vertex, valueVertex) {
    this.resolveVertexDependencies(valueVertex);
    const operation = this.findNeighbourValue(valueVertex, OPERATION_EDGE);
    if (operation && isOperation(operation)) {
      const operationValues = this.neighboursWithEdgeValue(valueVertex, OPERATION_VALUE_EDGE);
      const operator = operations[operation];
      const operatorFn = typeof operator === "function" ? operator : operator.resolve;
      const resolved = operatorFn?.(this, vertex, operationValues ?? []);
      return resolved === RESOLVED_TO_BRANCH ? void 0 : resolved;
    }
    let value = this.getVertexValue(valueVertex);
    if (Array.isArray(value)) {
      const object2 = {};
      this.resolveVertexChildren(valueVertex, object2);
      value = getPathSafe(object2, this.getPathArray(vertex));
    }
    return this.resolveValueOrSymbol(value);
  }
  /**
   * Resolve the value currently referenced by `$1` by the nearest self-or-ancestor that has a defined value.
   */
  resolveValue$1(pathArray) {
    for (let i = pathArray.length; i >= 0; i--) {
      const key = pathArray.slice(0, i).join(".");
      const resolvedValue = this.value$1.get(key);
      if (resolvedValue != void 0) {
        return resolvedValue;
      }
    }
  }
  /**
   * Graft a branch of the theme config onto the target vertex.
   */
  graftConfig(target, configPathArray, ignorePaths) {
    const targetConfigObject = getPathSafe(this.config, configPathArray);
    const targetPathArrayVertex = this.findNeighbour(target, PATH_ARRAY_EDGE);
    if (isObject(targetConfigObject)) {
      this.buildGraphFromObject(
        target,
        DEFAULTS_EDGE,
        targetConfigObject,
        targetPathArrayVertex,
        void 0,
        ignorePaths
      );
    }
    if (this.overrides) {
      const targetOverridesObject = getPathSafe(this.overrides, configPathArray);
      if (isObject(targetOverridesObject)) {
        this.buildGraphFromObject(
          target,
          OVERRIDES_EDGE,
          targetOverridesObject,
          targetPathArrayVertex,
          void 0,
          ignorePaths
        );
      }
      const commonOverridesObject = getPathSafe(this.overrides, ["common", ...configPathArray.slice(1)]);
      if (isObject(commonOverridesObject)) {
        this.buildGraphFromObject(
          target,
          OVERRIDES_EDGE,
          commonOverridesObject,
          targetPathArrayVertex,
          void 0,
          ignorePaths
        );
      }
    }
    this.buildDependencyGraph();
  }
  /**
   * Graft a given object onto the target vertex.
   */
  graftObject(target, object2, overridesPathArrays, edgeValue = this.graftEdge) {
    const pathArrayVertex = this.findNeighbour(target, PATH_ARRAY_EDGE);
    this.buildGraphFromObject(target, edgeValue, object2, pathArrayVertex);
    if (this.overrides && overridesPathArrays) {
      for (const overridePathArray of overridesPathArrays) {
        if (overridePathArray == null)
          continue;
        const overrides = getPathSafe(this.overrides, overridePathArray);
        if (overrides) {
          this.buildGraphFromObject(target, OVERRIDES_EDGE, overrides, pathArrayVertex);
        }
      }
    }
    this.buildDependencyGraph();
  }
  /**
   * Graft a given operation and value onto `path` child of the target vertex. The `ontoObject` value is built onto
   * the graph each time this function is called, at the given path, while `value` is used for value$1 where
   * `ontoObject` is an operation that invokes value$1.
   */
  graftValue(target, path, ontoObject, value, edgeValue = this.graftEdge) {
    const pathArray = [...this.getPathArray(target), path];
    const pathVertex = this.findVertexAtPath(pathArray) ?? this.addVertex(path);
    this.value$1.set(pathArray.join("."), value);
    this.buildGraphFromValue(target, pathVertex, edgeValue, pathArray, ontoObject);
    this.buildDependencyGraph();
  }
  /**
   * Resolve a branch as if it were a child of the context vertex, but without attaching it to the resolved root.
   */
  graftAndResolveOrphan(context, branch) {
    const orphan = {};
    const orphanVertex = this.addVertex(orphan);
    const contextPathArray = this.getPathArray(context);
    this.graftAndResolveChildren(branch, orphanVertex, contextPathArray, []);
    this.resolveVertex(orphanVertex, orphan);
    return getPathSafe(orphan, contextPathArray);
  }
  /**
   * Resolve a value as if it were a child of the context vertex, but without attaching it to the resolved root.
   */
  graftAndResolveOrphanValue(context, path, ontoObject, value, edgeValue = this.graftEdge) {
    const orphan = {};
    const orphanVertex = this.addVertex(orphan);
    const contextPathArray = this.getPathArray(context);
    const pathArray = [...contextPathArray, path];
    const pathVertex = this.findVertexAtPath(pathArray) ?? this.addVertex(path);
    this.value$1.set(pathArray.join("."), value);
    this.buildGraphFromValue(orphanVertex, pathVertex, edgeValue, pathArray, ontoObject);
    this.resolveVertex(orphanVertex, orphan);
    return getPathSafe(orphan, pathArray);
  }
  buildGraphFromObject(parentVertex, edgeValue, object2, pathArrayVertex, shallowPaths = _OptionsGraph.SHALLOW_KEYS, ignorePaths) {
    const keys = Object.keys(object2);
    const operation = getOperation(object2, keys);
    if (operation) {
      const valueVertex = this.addVertex(object2);
      this.addEdge(parentVertex, valueVertex, edgeValue);
      this.buildGraphFromOperation(valueVertex, edgeValue, operation, pathArrayVertex);
      return;
    }
    if (keys.length === 0) {
      this.addEdge(parentVertex, this.addVertex(Array.isArray(object2) ? [] : {}), edgeValue);
      this.buildGraphAutoEnable(parentVertex, edgeValue, object2, void 0);
      return;
    }
    const pathVertices = this.getVertexChildrenByKey(parentVertex);
    const pathArray = pathArrayVertex ? this.getVertexValue(pathArrayVertex) : [];
    let enabledVertex;
    if (Array.isArray(object2)) {
      this.addEdge(parentVertex, this.addVertex(edgeValue), CHILDREN_SOURCE_EDGE);
    }
    const childPathArray = [...pathArray];
    const pathArrayLength = pathArray.length;
    for (const key of keys) {
      if (ignorePaths?.has(key))
        continue;
      const childPathVertex = pathVertices?.get(key) ?? this.addVertex(key);
      childPathArray[pathArrayLength] = key;
      if (shallowPaths?.has(key)) {
        this.buildShallowGraphFromValue(parentVertex, childPathVertex, edgeValue, childPathArray, object2[key]);
      } else {
        this.buildGraphFromValue(
          parentVertex,
          childPathVertex,
          edgeValue,
          childPathArray,
          object2[key],
          shallowPaths
        );
      }
      if (key === "enabled") {
        enabledVertex = childPathVertex;
      }
    }
    this.buildGraphAutoEnable(parentVertex, edgeValue, object2, enabledVertex);
  }
  buildGraphAutoEnable(parentVertex, edgeValue, object2, enabledVertex) {
    if (edgeValue === DEFAULTS_EDGE && !enabledVertex)
      return;
    if (edgeValue === USER_OPTIONS_EDGE && enabledVertex)
      return;
    if (edgeValue !== DEFAULTS_EDGE && edgeValue !== USER_OPTIONS_EDGE && edgeValue !== USER_PARTIAL_OPTIONS_EDGE && edgeValue !== OVERRIDES_EDGE)
      return;
    let autoEnableVertex = this.findNeighbour(parentVertex, AUTO_ENABLE_EDGE);
    if (!autoEnableVertex) {
      autoEnableVertex = this.addVertex(AUTO_ENABLE_EDGE);
      this.addEdge(parentVertex, autoEnableVertex, AUTO_ENABLE_EDGE);
    }
    if (enabledVertex) {
      this.addEdge(enabledVertex, autoEnableVertex, AUTO_ENABLE_VALUE_EDGE);
    }
    const { enabled, _enabledFromTheme } = object2;
    this.addEdge(
      autoEnableVertex,
      this.addVertex({ enabled, _enabledFromTheme, keys: Object.keys(object2).length }),
      edgeValue
    );
  }
  getVertexChildrenByKey(vertex) {
    const pathNeighbours = this.neighboursWithEdgeValue(vertex, PATH_EDGE);
    if (!pathNeighbours)
      return;
    const pathVertices = /* @__PURE__ */ new Map();
    for (const neighbour of pathNeighbours) {
      pathVertices.set(this.getVertexValue(neighbour), neighbour);
    }
    return pathVertices;
  }
  buildGraphFromValue(parentVertex, pathVertex, edgeValue, pathArray, value, shallowPaths) {
    this.addEdge(parentVertex, pathVertex, PATH_EDGE);
    let pathArrayVertex = this.findNeighbour(pathVertex, PATH_ARRAY_EDGE);
    if (!pathArrayVertex) {
      pathArrayVertex = this.addVertex([...pathArray]);
      this.addEdge(pathVertex, pathArrayVertex, PATH_ARRAY_EDGE);
    }
    const operation = getOperation(value);
    if (operation) {
      const valueVertex = this.addVertex(value);
      this.addEdge(pathVertex, valueVertex, edgeValue);
      this.addEdge(valueVertex, pathArrayVertex, PATH_ARRAY_EDGE);
      this.buildGraphFromOperation(valueVertex, edgeValue, operation, pathArrayVertex);
    } else if (isObjectLike(value)) {
      this.buildGraphFromObject(pathVertex, edgeValue, value, pathArrayVertex, shallowPaths);
    } else {
      const neighbour = this.findNeighbour(pathVertex, edgeValue);
      if (neighbour && this.getVertexValue(neighbour) === value) {
        return;
      }
      const valueVertex = this.addVertex(value);
      this.addEdge(pathVertex, valueVertex, edgeValue);
    }
  }
  buildShallowGraphFromValue(parentVertex, pathVertex, edgeValue, pathArray, value) {
    this.addEdge(parentVertex, pathVertex, PATH_EDGE);
    let pathArrayVertex = this.findNeighbour(pathVertex, PATH_ARRAY_EDGE);
    if (!pathArrayVertex) {
      pathArrayVertex = this.addVertex([...pathArray]);
      this.addEdge(pathVertex, pathArrayVertex, PATH_ARRAY_EDGE);
    }
    const valueVertex = this.addVertex(value);
    this.addEdge(pathVertex, valueVertex, edgeValue);
  }
  buildGraphFromOperation(valueVertex, edgeValue, operation, pathArrayVertex) {
    const operationVertex = this.addVertex(operation.operation);
    this.addEdge(valueVertex, operationVertex, OPERATION_EDGE);
    for (const operationValue of operation.values) {
      this.buildGraphFromOperationValue(valueVertex, operationValue, edgeValue, pathArrayVertex);
    }
  }
  buildGraphFromOperationValue(valueVertex, operationValue, edgeValue, pathArrayVertex = this.EMPTY_PATH_ARRAY_VERTEX) {
    const operationValueVertex = this.addVertex(operationValue);
    this.addEdge(valueVertex, pathArrayVertex, PATH_ARRAY_EDGE);
    this.addEdge(valueVertex, operationValueVertex, OPERATION_VALUE_EDGE);
    const innerOperation = getOperation(operationValue);
    if (innerOperation) {
      this.buildGraphFromOperation(operationValueVertex, edgeValue, innerOperation, pathArrayVertex);
    } else if (isObjectLike(operationValue)) {
      this.buildGraphFromObject(operationValueVertex, edgeValue, operationValue, pathArrayVertex);
    }
  }
  /**
   * Add dependency edges on operations that require other vertices to be resolved before the operation can be
   * resolved. Then clear the list of pending edges.
   */
  buildDependencyGraph() {
    for (let i = 0; i < this.pendingProcessingEdgesFrom.length; i++) {
      const valueVertex = this.pendingProcessingEdgesFrom[i];
      const operationKeyVertex = this.pendingProcessingEdgesTo[i];
      const operation = this.getVertexValue(operationKeyVertex);
      if (!isOperation(operation))
        continue;
      const operationValues = this.neighboursWithEdgeValue(valueVertex, OPERATION_VALUE_EDGE);
      const operator = operations[operation];
      const dependenciesFn = typeof operator === "function" ? void 0 : operator.dependencies;
      dependenciesFn?.(this, valueVertex, operationValues ?? []);
    }
    this.pendingProcessingEdgesFrom = [];
    this.pendingProcessingEdgesTo = [];
  }
  /**
   * Within the branch starting at the given vertex, reassign any value vertices and their operation key vertices to
   * the pending processing edges. These can then be built with `this.buildDependencyGraph()`.
   */
  refreshPendingProcessingEdges(vertex) {
    const defaultValueVertex = this.findNeighbour(vertex, DEFAULTS_EDGE);
    const valueVertex = defaultValueVertex ?? vertex;
    const operationVertex = this.findNeighbour(valueVertex, OPERATION_EDGE);
    if (operationVertex) {
      this.pendingProcessingEdgesFrom.push(valueVertex);
      this.pendingProcessingEdgesTo.push(operationVertex);
      const neighbours2 = this.neighboursWithEdgeValue(valueVertex, OPERATION_VALUE_EDGE);
      if (neighbours2) {
        for (const neighbour of neighbours2) {
          this.refreshPendingProcessingEdges(neighbour);
        }
      }
    }
    const neighbours = this.neighboursWithEdgeValue(vertex, PATH_EDGE);
    if (neighbours) {
      for (const neighbour of neighbours) {
        this.refreshPendingProcessingEdges(neighbour);
      }
    }
  }
  resolveVertex(vertex, object2 = this.resolved, prune) {
    const pathArray = this.getPathArray(vertex);
    const rootAncestorPath = pathArray[0];
    if (pathArray.length === 1) {
      this.resolvedRootAncestorsPaths.add(rootAncestorPath);
    }
    if (pathArray.length > 1 && !this.resolvedRootAncestorsPaths.has(rootAncestorPath)) {
      const rootAncestorVertex = this.findVertexAtPath([rootAncestorPath]);
      if (rootAncestorVertex) {
        this.resolveVertex(rootAncestorVertex, object2, prune);
        return;
      }
    }
    if (this.userPartialOptions == null && object2 === this.resolved && pathArray.length > 0) {
      const resolvedVertexValue = getPathSafe(object2, pathArray);
      if (resolvedVertexValue != null && !isPlainObject(resolvedVertexValue)) {
        return;
      }
    }
    this.resolveVertexInEdgePriority(vertex, object2, pathArray, prune);
    this.resolveVertexAutoEnable(vertex, object2, pathArray);
    this.resolveVertexChildren(vertex, object2, prune);
  }
  resolveVertexInEdgePriority(vertex, object2, pathArray, prune) {
    const children = this.neighboursWithEdgeValue(vertex, PATH_EDGE);
    const [highestPriority] = this.edgePriority;
    for (const edgeValue of this.edgePriority) {
      const valueVertex = this.findNeighbour(vertex, edgeValue);
      if (valueVertex == null)
        continue;
      const value = this.resolveVertexValueInternal(vertex, valueVertex);
      if (value == null && edgeValue !== highestPriority)
        continue;
      if (children && children.length > 0 && edgeValue !== highestPriority)
        continue;
      if (Array.isArray(prune) && prune.includes(edgeValue))
        continue;
      this.hasUnsafeClearKeys || (this.hasUnsafeClearKeys = value != null && _OptionsGraph.UNSAFE_CLEAR_KEYS.has(pathArray.at(-1)));
      if (pathArray.length === 0) {
        if (value == null)
          continue;
        this.resolved = value;
      } else {
        setPathSafe(object2, pathArray, value);
      }
      break;
    }
  }
  resolveVertexValueInternal(vertex, valueVertex) {
    this.resolveVertexDependencies(valueVertex);
    const operation = this.findNeighbourValue(valueVertex, OPERATION_EDGE);
    if (operation && isOperation(operation)) {
      const operationValues = this.neighboursWithEdgeValue(valueVertex, OPERATION_VALUE_EDGE);
      const operator = operations[operation];
      const operatorFn = typeof operator === "function" ? operator : operator.resolve;
      const resolved = operatorFn?.(this, vertex, operationValues ?? []);
      return resolved === RESOLVED_TO_BRANCH ? void 0 : resolved;
    }
    return this.resolveValueOrSymbol(this.getVertexValue(valueVertex));
  }
  resolveVertexAutoEnable(vertex, object2, pathArray) {
    const autoEnableValueVertex = this.neighboursWithEdgeValue(vertex, AUTO_ENABLE_VALUE_EDGE)?.[0];
    if (!autoEnableValueVertex)
      return;
    const pathVertex = this.findVertexAtPath(pathArray);
    const defaultsEnabled = this.findNeighbourValue(autoEnableValueVertex, DEFAULTS_EDGE);
    const overridesEnabled = this.findNeighbourValue(autoEnableValueVertex, OVERRIDES_EDGE);
    const userOptionsEnabled = this.findNeighbourValue(autoEnableValueVertex, USER_OPTIONS_EDGE);
    const hasUserOptionEnabled = pathVertex && this.findNeighbour(pathVertex, USER_OPTIONS_EDGE) != null;
    const userPartialOptionsEnabled = hasUserOptionEnabled ? void 0 : this.findNeighbourValue(autoEnableValueVertex, USER_PARTIAL_OPTIONS_EDGE);
    const isUserEnabled = userOptionsEnabled != null && userOptionsEnabled.enabled == null || userPartialOptionsEnabled != null && userPartialOptionsEnabled.enabled == null;
    if (isUserEnabled && !defaultsEnabled?._enabledFromTheme && !overridesEnabled?._enabledFromTheme) {
      setPathSafe(object2, pathArray, true);
    }
  }
  resolveVertexChildren(vertex, object2, prune) {
    const children = this.neighboursWithEdgeValue(vertex, PATH_EDGE);
    if (!children)
      return;
    prune ?? (prune = this.findNeighbourValue(vertex, PRUNE_EDGE));
    for (const child of children) {
      const path = this.getVertexValue(child);
      if (children.length > 1 && isOperation(path))
        continue;
      if (path === "_enabledFromTheme")
        continue;
      this.resolveVertex(child, object2, prune);
    }
  }
  resolveVertexDependencies(vertex) {
    const dependencies = this.neighboursWithEdgeValue(vertex, DEPENDENCY_EDGE);
    if (!dependencies)
      return;
    for (const dependency of dependencies) {
      this.resolveVertex(dependency);
    }
  }
  graftAndResolveChildren(remoteBranch, orphanBranch, contextPathArray, orphanPathArray) {
    const remoteChildren = this.neighboursWithEdgeValue(remoteBranch, PATH_EDGE);
    if (!remoteChildren)
      return;
    for (const remoteChild of remoteChildren) {
      const remoteChildPath = this.getVertexValue(remoteChild);
      const childContextPathArray = [...contextPathArray, remoteChildPath];
      const childOrphanPathArray = [...orphanPathArray, remoteChildPath];
      const orphanChildPathVertex = this.addVertex(remoteChildPath);
      const defaultValue = this.findNeighbourValue(remoteChild, DEFAULTS_EDGE);
      this.addEdge(orphanBranch, orphanChildPathVertex, PATH_EDGE);
      const orphanChildPathArrayVertex = this.addVertex(childContextPathArray);
      this.addEdge(orphanChildPathVertex, orphanChildPathArrayVertex, PATH_ARRAY_EDGE);
      if (isObject(defaultValue)) {
        this.buildGraphFromObject(
          orphanChildPathVertex,
          DEFAULTS_EDGE,
          defaultValue,
          orphanChildPathArrayVertex
        );
        const orphanChildValueVertex = this.findNeighbour(orphanChildPathVertex, DEFAULTS_EDGE);
        this.addEdge(orphanChildValueVertex, this.addVertex(childContextPathArray), PATH_ARRAY_EDGE);
        const operation = this.findNeighbourValue(orphanChildValueVertex, OPERATION_EDGE);
        if (isOperation(operation)) {
          const operationValues = this.neighboursWithEdgeValue(orphanChildValueVertex, OPERATION_VALUE_EDGE);
          const operator = operations[operation];
          const dependenciesFn = typeof operator === "function" ? void 0 : operator.dependencies;
          dependenciesFn?.(this, orphanChildValueVertex, operationValues ?? []);
        }
      }
      this.graftAndResolveChildren(
        remoteChild,
        orphanChildPathVertex,
        childContextPathArray,
        childOrphanPathArray
      );
    }
  }
  resolveValueOrSymbol(value) {
    return typeof value === "symbol" && this.internalParams?.has(value) ? this.internalParams.get(value) : value;
  }
  snapshot() {
    debug2(`snapshot`);
    this.isRollingBack = true;
  }
  rollback() {
    debug2(`rollback ${this.rollbackEdgesFrom.length} edges and ${this.rollbackVertices.length} vertices`);
    for (let i = 0; i < this.rollbackEdgesFrom.length; i++) {
      const from3 = this.rollbackEdgesFrom[i];
      const to = this.rollbackEdgesTo[i];
      const edgeValue = this.rollbackEdgesValue[i];
      this.removeEdge(from3, to, edgeValue);
    }
    for (const vertex of this.rollbackVertices) {
      this.removeVertex(vertex);
    }
    this.cachedPathVertices.clear();
    this.rollbackVertices = [];
    this.rollbackEdgesFrom = [];
    this.rollbackEdgesTo = [];
    this.rollbackEdgesValue = [];
    this.isRollingBack = false;
  }
  /**
   * Console log a flowchart diagram of the graph at the given path.
   */
  diagram(pathArray, maxDepth = 2) {
    this.diagramKeys = /* @__PURE__ */ new Map();
    this.diagramEdges = /* @__PURE__ */ new Map();
    const vertex = this.findVertexAtPath(pathArray);
    const diagram = [
      "---",
      "config:",
      "  layout: elk",
      "  look: neo",
      "  theme: redux",
      "---",
      "flowchart TB"
    ];
    if (vertex) {
      this.diagramVertex(diagram, vertex, 1, maxDepth);
    }
    diagram.push("classDef UO fill: #e8f5e8, stroke: #4caf50");
    diagram.push("classDef DE fill: #e3f2fd, stroke: #2196f3");
    diagram.push("classDef DEP fill: #ffe0fd, stroke: #ff00f2");
    diagram.push("classDef OP fill: #fff3e0, stroke: #ff9800");
    diagram.push("classDef OPV fill: #fff3e0, stroke: #ff9800, stroke-width: 1px");
    diagram.push("classDef OV fill: #e8f5ee, stroke: #4caf87");
    console.log(diagram.join("\n"));
  }
  diagramKey(path) {
    let diagramKey = this.diagramKeys.get(path);
    if (!diagramKey) {
      diagramKey = `${this.diagramKeys.size}`;
      this.diagramKeys.set(path, diagramKey);
    }
    return diagramKey;
  }
  diagramLabel(path, vertex, edge) {
    let diagramKey = this.diagramKeys.get(path);
    if (diagramKey)
      return diagramKey;
    diagramKey = this.diagramKey(path);
    const classNames = {
      [USER_OPTIONS_EDGE]: "UO",
      [DEFAULTS_EDGE]: "DE",
      [DEPENDENCY_EDGE]: "DEP",
      [OPERATION_EDGE]: "OP",
      [OPERATION_VALUE_EDGE]: "OPV",
      [OVERRIDES_EDGE]: "OV"
    };
    let className = edge ? classNames[edge] ?? void 0 : void 0;
    className = className ? `:::${className}` : "";
    if (typeof vertex.value === "symbol") {
      return `${diagramKey}[/"[symbol]"\\]${className}`;
    } else if (Array.isArray(vertex.value)) {
      return `${diagramKey}[/"[array]"\\]${className}`;
    } else if (typeof vertex.value === "object") {
      return `${diagramKey}[/"[object]"\\]${className}`;
    } else if (edge === DEFAULTS_EDGE || edge === USER_OPTIONS_EDGE || edge === OVERRIDES_EDGE) {
      return `${diagramKey}("${vertex.value}")${className}`;
    } else {
      return `${diagramKey}["${vertex.value}"]${className}`;
    }
  }
  diagramVertex(diagram, vertex, depth, maxDepth) {
    const pathArray = this.getPathArray(vertex);
    const path = pathArray.length > 0 ? pathArray.join(".") : "root";
    this.diagramNeighbours(diagram, path, vertex, depth + 1, maxDepth);
    let diagramKey = this.diagramKeys.get(path);
    if (!diagramKey) {
      diagramKey = this.diagramKey(path);
      diagram.push(`	${diagramKey}["${vertex.value}"]`);
    }
  }
  diagramNeighbours(diagram, path, vertex, depth, maxDepth) {
    for (const neighbour of this.neighboursWithEdgeValue(vertex, PATH_EDGE) ?? []) {
      const neighbourPathArray = this.getPathArray(neighbour);
      const neighbourPath = neighbourPathArray.length > 0 ? neighbourPathArray.join(".") : "root";
      if (depth < maxDepth) {
        this.diagramVertex(diagram, neighbour, depth + 1, maxDepth);
      }
      this.diagramChild(diagram, PATH_EDGE, path, vertex, neighbourPath, vertex);
    }
    const userValues = this.neighboursWithEdgeValue(vertex, USER_OPTIONS_EDGE) ?? [];
    let index = 0;
    for (const userValue of userValues) {
      this.diagramChild(
        diagram,
        USER_OPTIONS_EDGE,
        path,
        vertex,
        `${path}.${USER_OPTIONS_EDGE}.${index}`,
        userValue
      );
      index++;
    }
    const defaultValues = this.neighboursWithEdgeValue(vertex, DEFAULTS_EDGE) ?? [];
    index = 0;
    for (const defaultValue of defaultValues) {
      this.diagramChildWithNeighbours(
        diagram,
        DEFAULTS_EDGE,
        path,
        vertex,
        `${path}.${DEFAULTS_EDGE}.${index}`,
        defaultValue,
        depth + 1,
        maxDepth
      );
      index++;
    }
    const operationVertices = this.neighboursWithEdgeValue(vertex, OPERATION_EDGE) ?? [];
    index = 0;
    const [operation] = operationVertices;
    if (operation) {
      this.diagramChildWithNeighbours(
        diagram,
        OPERATION_EDGE,
        path,
        vertex,
        `${path}.${OPERATION_EDGE}.${index}`,
        operation,
        depth + 1,
        maxDepth
      );
      index++;
    }
    const operationValueVertices = this.neighboursWithEdgeValue(vertex, OPERATION_VALUE_EDGE) ?? [];
    index = 0;
    for (const operationValue of operationValueVertices) {
      this.diagramChildWithNeighbours(
        diagram,
        OPERATION_VALUE_EDGE,
        path,
        vertex,
        `${path}.${OPERATION_VALUE_EDGE}.${index}`,
        operationValue,
        depth + 1,
        maxDepth
      );
      index++;
    }
    const dependencyVertices = this.neighboursWithEdgeValue(vertex, DEPENDENCY_EDGE) ?? [];
    index = 0;
    for (const dependency of dependencyVertices) {
      this.diagramChildWithNeighbours(
        diagram,
        DEPENDENCY_EDGE,
        path,
        vertex,
        this.getPathArray(dependency).join("."),
        dependency,
        depth + 1,
        maxDepth
      );
      index++;
    }
  }
  diagramChild(diagram, edge, parentPath, parentVertex, childPath, childVertex) {
    let edges = this.diagramEdges.get(parentPath);
    if (edges?.has(childPath))
      return;
    if (!edges) {
      edges = /* @__PURE__ */ new Set();
      this.diagramEdges.set(parentPath, edges);
    }
    edges.add(childPath);
    const edgeString = edge === PATH_EDGE ? "" : `|${edge}|`;
    diagram.push(
      `	${this.diagramLabel(parentPath, parentVertex)} -->${edgeString} ${this.diagramLabel(childPath, childVertex, edge)}`
    );
  }
  diagramChildWithNeighbours(diagram, edge, parentPath, parentVertex, childPath, childVertex, depth, maxDepth) {
    this.diagramChild(diagram, edge, parentPath, parentVertex, childPath, childVertex);
    this.diagramNeighbours(diagram, childPath, childVertex, depth + 1, maxDepth);
  }
};
// The default priority order in which to resolve options values.
_OptionsGraph.EDGE_PRIORITY = [USER_OPTIONS_EDGE, OVERRIDES_EDGE, DEFAULTS_EDGE];
_OptionsGraph.GRAFT_EDGE = DEFAULTS_EDGE;
// These keys must be stored as shallow objects in the graph and not manipulated.
_OptionsGraph.SHALLOW_KEYS = /* @__PURE__ */ new Set(["context", "data", "topology"]);
// These keys must be excluded when building the graph, they are instead resolved separately since they are objects
// that must be applied to arrays.
_OptionsGraph.COMPLEX_KEYS = ["annotations", "axes", "series"];
_OptionsGraph.ANNOTATIONS_OPTIONS_KEYS = [
  "axesButtons",
  "data",
  "enabled",
  "optionsToolbar",
  "snap",
  "toolbar",
  "xKey",
  "volumeKey"
];
// If any of these keys are present in the resolved object then calling `clearSafe()` will not clear the graph.
_OptionsGraph.UNSAFE_CLEAR_KEYS = /* @__PURE__ */ new Set(["itemStyler", "styler"]);
// A cache of values that persists between chart updates, use sparingly.
_OptionsGraph.valueCache = /* @__PURE__ */ new Map();
var OptionsGraph = _OptionsGraph;

// packages/ag-charts-community/src/module/optionsModule.ts
var stringFormat = (value) => `'${value}'`;
var AXIS_ID_PREFIX = "__AXIS_ID_";
var POSITION_DIRECTIONS = {
  top: "x" /* X */,
  bottom: "x" /* X */,
  left: "y" /* Y */,
  right: "y" /* Y */
};
var _ChartOptions = class _ChartOptions {
  constructor(currentUserOptions, newUserOptions, processedOverrides, specialOverrides, metadata, deltaOptions, stripSymbols = false, apiStartTime) {
    this.themeParameters = {};
    this.optionMetadata = metadata ?? {};
    this.processedOverrides = processedOverrides ?? {};
    let baseChartOptions = null;
    if (currentUserOptions instanceof _ChartOptions) {
      baseChartOptions = currentUserOptions;
      this.specialOverrides = baseChartOptions.specialOverrides;
      if (deltaOptions) {
        this.userDeltaKeys = new Set(Object.keys(deltaOptions));
      }
      deltaOptions ?? (deltaOptions = jsonDiff(
        baseChartOptions.userOptions,
        newUserOptions,
        _ChartOptions.JSON_DIFF_OPTS
      ));
      this.userOptions = deepClone(merge(deltaOptions, baseChartOptions.userOptions), {
        ..._ChartOptions.OPTIONS_CLONE_OPTS_SLOW,
        seen: []
      });
    } else {
      this.userOptions = deepClone(currentUserOptions ?? newUserOptions, {
        ..._ChartOptions.OPTIONS_CLONE_OPTS_SLOW,
        seen: []
      });
      this.specialOverrides = this.specialOverridesDefaults({ ...specialOverrides });
    }
    this.findSeriesWithUserVisiblity(newUserOptions, deltaOptions);
    if (stripSymbols) {
      this.removeLeftoverSymbols(this.userOptions);
    }
    const dataChangedLength = currentUserOptions instanceof _ChartOptions && deltaOptions?.data !== void 0 && deltaOptions?.data?.length !== currentUserOptions.userOptions.data?.length;
    let activeTheme, processedOptions, fastDelta, themeParameters, annotationThemes, googleFonts, optionsGraph;
    if (!stripSymbols && this.seriesWithUserVisibility == void 0 && deltaOptions !== void 0 && _ChartOptions.isFastPathDelta(deltaOptions) && baseChartOptions != null && !dataChangedLength) {
      ({ activeTheme, processedOptions, fastDelta } = this.fastSetup(deltaOptions, baseChartOptions));
      themeParameters = baseChartOptions.themeParameters;
      annotationThemes = baseChartOptions.annotationThemes;
    } else {
      _ChartOptions.perfDebug(`ChartOptions.slowSetup()`);
      ({ activeTheme, processedOptions, themeParameters, annotationThemes, googleFonts, optionsGraph } = this.slowSetup(processedOverrides, deltaOptions, stripSymbols));
    }
    this.activeTheme = activeTheme;
    this.processedOptions = processedOptions;
    this.fastDelta = fastDelta ?? void 0;
    this.themeParameters = themeParameters;
    this.annotationThemes = annotationThemes;
    this.googleFonts = googleFonts;
    this.optionsGraph = optionsGraph;
    if (apiStartTime !== void 0 && typeof apiStartTime === "number" && !Number.isNaN(apiStartTime)) {
      const endTime = performance.now();
      this.optionsProcessingTime = endTime - apiStartTime;
    }
    debugLogger_exports.inDevelopmentMode(() => deepFreeze(this));
  }
  static isFastPathDelta(deltaOptions) {
    for (const key of Object.keys(deltaOptions ?? {})) {
      if (!this.FAST_PATH_OPTIONS.has(key)) {
        _ChartOptions.perfDebug("ChartOptions.isFastPathDelta() - slow path required due to presence of: ", key);
        return false;
      }
    }
    _ChartOptions.perfDebug(`ChartOptions.isFastPathDelta() - fast path possible.`);
    return true;
  }
  findSeriesWithUserVisiblity(newUserOptions, deltaOptions) {
    for (const o of [newUserOptions, deltaOptions]) {
      const series = o?.series;
      if (!Array.isArray(series))
        continue;
      for (let index = 0; index < series.length; index++) {
        const s = series[index];
        if (!("visible" in s))
          continue;
        this.seriesWithUserVisibility ?? (this.seriesWithUserVisibility = {
          identifiers: /* @__PURE__ */ new Set(),
          indices: /* @__PURE__ */ new Set()
        });
        if (s.id) {
          this.seriesWithUserVisibility.identifiers.add(s.id);
        } else {
          this.seriesWithUserVisibility.indices.add(index);
        }
      }
    }
  }
  fastSetup(deltaOptions, baseChartOptions) {
    const { activeTheme, processedOptions: baseOptions } = baseChartOptions;
    const { presetType } = this.optionMetadata;
    if (presetType != null && deltaOptions?.data != null) {
      const presetDef = moduleRegistry_exports.getPresetModule(presetType);
      if (presetDef?.processData) {
        const { series, data } = presetDef.processData(deltaOptions.data);
        deltaOptions = mergeDefaults({ series, data }, deltaOptions);
      }
    }
    this.fastSeriesSetup(deltaOptions, baseOptions);
    const processedOptions = mergeDefaults(deltaOptions, baseOptions);
    _ChartOptions.debug("ChartOptions.fastSetup() - processed options", processedOptions);
    return { activeTheme, processedOptions, fastDelta: deltaOptions };
  }
  fastSeriesSetup(deltaOptions, baseOptions) {
    if (!deltaOptions?.series)
      return;
    if (deltaOptions.series?.every((s, i) => jsonPropertyCompare(s, baseOptions.series?.[i] ?? {}))) {
      delete deltaOptions["series"];
    } else {
      deltaOptions.series = deltaOptions.series.map((s, i) => {
        return merge(s, baseOptions.series?.[i] ?? {});
      });
    }
  }
  slowSetup(processedOverrides, deltaOptions, stripSymbols = false) {
    let options = deepClone(this.userOptions, _ChartOptions.OPTIONS_CLONE_OPTS_FAST);
    if (deltaOptions) {
      options = mergeDefaults(deltaOptions, options);
      if (stripSymbols) {
        this.removeLeftoverSymbols(options);
      }
    }
    let activeTheme = sanitizeThemeModules(getChartTheme(options.theme));
    const { presetType } = this.optionMetadata;
    if (presetType != null) {
      const presetDef = moduleRegistry_exports.getPresetModule(presetType);
      if (presetDef) {
        const { validate: validatePreset = validate } = presetDef;
        const presetParams = options;
        const presetSubType = options.type;
        const presetTheme = presetSubType == null ? void 0 : activeTheme.presets[presetSubType];
        const { cleared, invalid } = validatePreset(presetParams, presetDef.options, "");
        for (const error2 of invalid) {
          logger_exports.warn(error2);
        }
        if (hasRequiredInPath(invalid, "")) {
          options = {};
        } else {
          _ChartOptions.debug(">>> AgCharts.createOrUpdate() - applying preset", cleared);
          options = presetDef.create(cleared, presetTheme, () => this.activeTheme);
          activeTheme = sanitizeThemeModules(getChartTheme(options.theme));
        }
      }
    }
    this.soloSeriesIntegrity(options);
    if (presetType != null) {
      activeTheme.templateTheme(options, false);
    }
    removeIncompatibleModuleOptions(void 0, options);
    const missingSeriesModules = this.validateSeriesOptions(options);
    const chartType = detectChartType(options);
    this.chartDef = moduleRegistry_exports.getChartModule(chartType);
    if (!this.chartDef.placeholder) {
      const { validate: validateChart = validate } = this.chartDef;
      const { cleared, invalid } = validateChart(options, this.chartDef.options, "");
      for (const error2 of invalid) {
        logger_exports.warn(error2);
      }
      options = cleared;
    }
    this.validateAxesOptions(options);
    this.removeDisabledOptions(options);
    let googleFonts = this.processFonts(activeTheme.params);
    googleFonts = this.processFonts(options, googleFonts);
    this.processSeriesOptions(options);
    const unmappedAxisKeys = this.processAxesOptions(options, chartType);
    const optionsGraph = createOptionsGraph(activeTheme, options);
    const resolvedOptions = optionsGraph.resolve();
    const themeParameters = optionsGraph.resolveParams();
    const annotationThemes = optionsGraph.resolveAnnotationThemes();
    optionsGraph.clearSafe();
    const processedOptions = mergeDefaults(processedOverrides, resolvedOptions);
    removeIncompatibleModuleOptions(this.chartDef.name, processedOptions);
    processModuleOptions(this.chartDef.name, processedOptions, missingSeriesModules);
    this.validateSeriesOptions(processedOptions);
    this.validateAxesOptions(processedOptions, unmappedAxisKeys);
    this.validatePluginOptions(processedOptions);
    this.processMiniChartSeriesOptions(processedOptions);
    if (!processedOptions.loadGoogleFonts) {
      googleFonts.clear();
    }
    _ChartOptions.debug(() => ["ChartOptions.slowSetup() - processed options", deepClone(processedOptions)]);
    return { activeTheme, processedOptions, themeParameters, annotationThemes, googleFonts, optionsGraph };
  }
  validatePluginOptions(options) {
    for (const pluginDef of moduleRegistry_exports.listModulesByType("plugin" /* Plugin */)) {
      const pluginKey = pluginDef.name;
      if (pluginKey in options && pluginDef.options != null && (!pluginDef.chartType || pluginDef.chartType === this.chartDef?.name)) {
        const { cleared, invalid } = validate(options[pluginKey], pluginDef.options, pluginDef.name);
        for (const error2 of invalid) {
          logger_exports.warn(error2);
        }
        options[pluginKey] = cleared;
      }
    }
  }
  validateSeriesOptions(options) {
    const chartType = this.chartDef?.name;
    const validatedSeriesOptions = [];
    const seriesCount = options.series?.length ?? 0;
    const missingModules = [];
    let validSeriesTypes;
    for (let index = 0; index < seriesCount; index++) {
      const keyPath = `series[${index}]`;
      const seriesOptions = options.series[index];
      const seriesDef = moduleRegistry_exports.getSeriesModule(seriesOptions.type);
      if (seriesDef == null) {
        const isEnterprise2 = moduleRegistry_exports.isEnterprise();
        validSeriesTypes ?? (validSeriesTypes = joinFormatted(
          Array.from(ExpectedModules.values()).filter(
            (def) => def.type === "series" /* Series */ && (isEnterprise2 || !def.enterprise) && (!chartType || def.chartType === chartType)
          ).map((def) => def.name),
          "or",
          stringFormat
        ));
        const modulePlaceholder = ExpectedModules.get(seriesOptions.type);
        if (seriesOptions.type != null && modulePlaceholder?.type === "series" /* Series */) {
          missingModules.push(modulePlaceholder);
          continue;
        }
        logger_exports.warn(
          seriesOptions.type == null ? `Option \`${keyPath}.type\` is required and has not been provided; expecting ${validSeriesTypes}, ignoring.` : `Unknown type \`${seriesOptions.type}\` at \`${keyPath}.type\`; expecting ${validSeriesTypes}, ignoring.`
        );
        continue;
      } else if (chartType && seriesDef.chartType !== chartType) {
        logger_exports.warn(
          `Series type \`${seriesDef.name}\` at \`${keyPath}.type\` is not supported by chart type \`${chartType}\`, ignoring.`
        );
        continue;
      }
      if (seriesDef.options == null) {
        validatedSeriesOptions.push(seriesOptions);
        continue;
      }
      const { validate: validateSeries = validate } = seriesDef;
      const { cleared, invalid } = validateSeries(seriesOptions, seriesDef.options, keyPath);
      for (const error2 of invalid) {
        logger_exports.warn(error2);
      }
      if (!hasRequiredInPath(invalid, keyPath)) {
        validatedSeriesOptions.push(cleared);
      }
    }
    options.series = validatedSeriesOptions;
    return missingModules;
  }
  validateAxesOptions(options, unmappedAxisKeys) {
    if (!("axes" in options) || !options.axes)
      return;
    const chartType = this.chartDef?.name;
    const validatedAxesOptions = {};
    let validAxesTypes;
    for (const [key, axisOptions] of entries(options.axes)) {
      if (!axisOptions)
        continue;
      if (axisOptions.type == null) {
        validatedAxesOptions[key] = axisOptions;
        continue;
      }
      const keyPath = `axes.${unmappedAxisKeys?.get(key) ?? key}`;
      const axisDef = moduleRegistry_exports.getAxisModule(axisOptions.type);
      if (axisDef == null) {
        const isEnterprise2 = moduleRegistry_exports.isEnterprise();
        validAxesTypes ?? (validAxesTypes = joinFormatted(
          Array.from(ExpectedModules.values()).filter(
            (def) => def.type === "axis" /* Axis */ && (isEnterprise2 || !def.enterprise) && def.chartType === chartType
          ).map((def) => def.name),
          "or",
          stringFormat
        ));
        const modulePlaceholder = ExpectedModules.get(axisOptions.type);
        if (modulePlaceholder?.type !== "axis" /* Axis */) {
          logger_exports.warn(
            `Unknown type \`${axisOptions.type}\` at \`${keyPath}.type\`; expecting one of ${validAxesTypes}, ignoring.`
          );
        }
        continue;
      } else if (axisDef.chartType !== chartType) {
        logger_exports.warn(
          `Axis type \`${axisDef.name}\` at  \`${keyPath}.type\` is not supported by chart type \`${chartType}\`, ignoring.`
        );
        break;
      }
      const { validate: validateAxis = validate } = axisDef;
      const { cleared, invalid } = validateAxis(axisOptions, axisDef.options, keyPath);
      for (const error2 of invalid) {
        logger_exports.warn(error2);
      }
      if (!hasRequiredInPath(invalid, keyPath)) {
        validatedAxesOptions[key] = cleared;
      }
    }
    options.axes = validatedAxesOptions;
  }
  diffOptions(other) {
    if (this === other)
      return {};
    if (other == null)
      return this.processedOptions;
    return this.fastDelta ?? jsonDiff(other.processedOptions, this.processedOptions, _ChartOptions.JSON_DIFF_OPTS);
  }
  optionsType(options) {
    return options.series?.[0]?.type ?? "line";
  }
  processSeriesOptions(options) {
    const displayNullData = options.displayNullData;
    const processedSeries = options.series?.map((series) => {
      const seriesDef = moduleRegistry_exports.getSeriesModule(series.type);
      const visibleDefined = Boolean(seriesDef?.options?.visible);
      const seriesDefaults = {};
      if (visibleDefined) {
        seriesDefaults.visible = true;
      }
      if (displayNullData !== void 0 && series.allowNullKeys === void 0) {
        seriesDefaults.allowNullKeys = displayNullData;
      }
      return mergeDefaults(this.getSeriesGroupingOptions(series), series, seriesDefaults);
    });
    options.series = this.setSeriesGroupingOptions(processedSeries ?? []);
  }
  /**
   * Collates axis keys from the axis and series options to determine the full set of axis keys, defaults series to
   * the primary axes and renames the primary axes to the internal direction-based names.
   */
  processAxesOptions(options, chartType) {
    const directions2 = chartType === "polar" ? ["angle" /* Angle */, "radius" /* Radius */] : ["x" /* X */, "y" /* Y */];
    const hasAxes = "axes" in options && Object.keys(options.axes ?? {}).length > 0;
    const nonDefaultSeriesAxisKeysCount = this.countNonDefaultSeriesAxisKeys(options, directions2);
    const hasNonDefaultSeriesAxisKeys = nonDefaultSeriesAxisKeysCount > 0;
    const hasExtraImplicitDefaultSeriesAxisKeys = hasNonDefaultSeriesAxisKeys && nonDefaultSeriesAxisKeysCount < (options?.series?.length ?? 0);
    const primarySeriesOptions = options.series?.[0];
    const seriesType = this.optionsType(options);
    const defaultAxes = this.predictAxes(seriesType, directions2, primarySeriesOptions, options.data) ?? this.cloneDefaultAxes(seriesType);
    const isPrimarySeriesFlipped = isObject(primarySeriesOptions) && "direction" in primarySeriesOptions && primarySeriesOptions.direction === "horizontal" && moduleRegistry_exports.getSeriesModule(primarySeriesOptions.type)?.axisKeysFlipped != null;
    if (!hasAxes && !hasNonDefaultSeriesAxisKeys && !isPrimarySeriesFlipped) {
      options.axes = defaultAxes;
      return;
    }
    const axisKeys = "axes" in options ? new Set(Object.keys(options.axes ?? {})) : /* @__PURE__ */ new Set();
    const primaryAxisKeys = this.getPrimaryAxisKeys(options, directions2, axisKeys, hasNonDefaultSeriesAxisKeys);
    const remappedAxisKeys = this.getRemappedAxisKeys(
      axisKeys,
      primaryAxisKeys,
      directions2,
      hasExtraImplicitDefaultSeriesAxisKeys
    );
    const newAxes = {};
    const unmappedAxisKeys = /* @__PURE__ */ new Map();
    for (const [fromAxisKey, toAxisKey] of remappedAxisKeys) {
      newAxes[toAxisKey] = "axes" in options ? shallowClone(options.axes?.[fromAxisKey]) : void 0;
      unmappedAxisKeys.set(toAxisKey, fromAxisKey);
    }
    this.remapSeriesAxisKeys(
      options,
      directions2,
      newAxes,
      remappedAxisKeys,
      defaultAxes,
      hasExtraImplicitDefaultSeriesAxisKeys
    );
    this.predictAxesMissingTypesAndPositions(options, directions2, newAxes, defaultAxes);
    this.alternateSecondaryAxisPositions(options, newAxes, unmappedAxisKeys);
    options.axes = newAxes;
    return unmappedAxisKeys;
  }
  /**
   * These keys are used to map a series to an axis for each direction. They are retrieved per-series to allow a
   * mixture of flipped and non-flipped series within the same chart.
   */
  getSeriesDirectionAxisKey(seriesOptions, direction) {
    const seriesModule = moduleRegistry_exports.getSeriesModule(seriesOptions.type);
    if (!seriesModule)
      return;
    const isFlipped = "direction" in seriesOptions && seriesOptions.direction === "horizontal";
    return isFlipped && seriesModule.axisKeysFlipped ? seriesModule.axisKeysFlipped[direction] : seriesModule.axisKeys?.[direction];
  }
  /**
   * Check if any of the series' axis keys have values that do not match the expected value, i.e. the direction.
   */
  countNonDefaultSeriesAxisKeys(options, directions2) {
    let count = 0;
    for (const seriesOptions of options.series ?? []) {
      for (const direction of directions2) {
        const directionAxisKey = this.getSeriesDirectionAxisKey(seriesOptions, direction);
        if (!directionAxisKey || !isKeyOf(directionAxisKey, seriesOptions))
          continue;
        if (seriesOptions[directionAxisKey] === direction)
          continue;
        count++;
      }
    }
    return count;
  }
  /**
   * The primary axes are defined, for each direction, as those first in the `axes` object or referenced by a series.
   * This is irregardless of the specific key of the axis, e.g. an axis with the key `y` may have the position `top`,
   * and would therefore be classified as the primary `x` axis.
   */
  getPrimaryAxisKeys(options, directions2, axisKeys, hasNonDefaultSeriesAxisKeys) {
    const primaryAxisKeys = /* @__PURE__ */ new Map();
    for (const direction of directions2) {
      let foundPrimaryAxisKey = false;
      if (
        // has axes
        "axes" in options && options.axes && // does not have standard-name primary axis without position
        !(direction in options.axes && isObject(options.axes[direction]) && !("position" in options.axes[direction]))
      ) {
        for (const [axisKey, axisOptions] of entries(options.axes)) {
          if ("position" in axisOptions && axisOptions.position && direction === POSITION_DIRECTIONS[axisOptions.position]) {
            primaryAxisKeys.set(direction, axisKey);
            foundPrimaryAxisKey = true;
            break;
          }
        }
      }
      if (foundPrimaryAxisKey)
        continue;
      if (!hasNonDefaultSeriesAxisKeys)
        continue;
      for (const seriesOptions of options.series ?? []) {
        const directionAxisKey = this.getSeriesDirectionAxisKey(seriesOptions, direction);
        if (!directionAxisKey)
          continue;
        const seriesAxisKey = seriesOptions[directionAxisKey];
        if (axisKeys.has(seriesAxisKey))
          continue;
        if (!seriesAxisKey) {
          primaryAxisKeys.set(direction, direction);
          break;
        }
        primaryAxisKeys.set(direction, seriesAxisKey);
        break;
      }
    }
    if (axisKeys.size === 0 || !("axes" in options) || !options.axes)
      return primaryAxisKeys;
    if (primaryAxisKeys.size === 0) {
      for (const direction of directions2) {
        if (direction in options.axes) {
          primaryAxisKeys.set(direction, direction);
        }
      }
    }
    if (primaryAxisKeys.size === 0) {
      for (const direction of directions2) {
        for (const [axisKey, axisOptions] of entries(options.axes)) {
          if (axisOptions.type?.startsWith(direction)) {
            primaryAxisKeys.set(direction, axisKey);
            break;
          }
        }
      }
    }
    if (primaryAxisKeys.size === 0 && (options.series?.length ?? 0) > 0) {
      for (const direction of directions2) {
        for (const seriesOptions of options.series) {
          const directionAxisKey = this.getSeriesDirectionAxisKey(seriesOptions, direction);
          if (!directionAxisKey)
            continue;
          const seriesAxisKey = seriesOptions[directionAxisKey];
          if (!axisKeys.has(seriesAxisKey))
            continue;
          primaryAxisKeys.set(direction, seriesAxisKey);
          break;
        }
      }
    }
    if (primaryAxisKeys.size < 2) {
      const primaryAxisIdsFound = new Set(primaryAxisKeys.values());
      for (const [axisKey, axisOptions] of entries(options.axes)) {
        if (primaryAxisIdsFound.has(axisKey) || "position" in axisOptions)
          continue;
        for (const direction of directions2) {
          if (primaryAxisKeys.has(direction))
            continue;
          primaryAxisKeys.set(direction, axisKey);
          primaryAxisIdsFound.add(axisKey);
          break;
        }
        if (primaryAxisKeys.size === 2)
          break;
      }
    }
    return primaryAxisKeys;
  }
  getRemappedAxisKeys(axisKeys, primaryAxisKeys, directions2, hasExtraImplicitDefaultSeriesAxisKeys) {
    const remappedAxisKeys = /* @__PURE__ */ new Map();
    for (const [direction, axisKey] of primaryAxisKeys) {
      remappedAxisKeys.set(axisKey, direction);
    }
    for (const axisKey of axisKeys) {
      if (remappedAxisKeys.has(axisKey))
        continue;
      remappedAxisKeys.set(axisKey, `${AXIS_ID_PREFIX}${remappedAxisKeys.size}`);
    }
    if (hasExtraImplicitDefaultSeriesAxisKeys) {
      for (const direction of directions2) {
        if (!remappedAxisKeys.has(direction)) {
          remappedAxisKeys.set(direction, `${AXIS_ID_PREFIX}${remappedAxisKeys.size}`);
        }
      }
    }
    return remappedAxisKeys;
  }
  /**
   * Update each series' axis keys to match the name used internally, such as the direction or a constant suffixed by
   * the index for secondary axes.
   */
  remapSeriesAxisKeys(options, directions2, newAxes, remappedAxisKeys, defaultAxes, hasExtraImplicitDefaultSeriesAxisKeys) {
    for (const seriesOptions of options.series ?? []) {
      for (const direction of directions2) {
        const directionAxisKey = this.getSeriesDirectionAxisKey(seriesOptions, direction);
        if (!directionAxisKey)
          continue;
        newAxes[direction] ?? (newAxes[direction] = shallowClone(defaultAxes[direction]));
        let remappedSeriesAxisKey = direction;
        if (directionAxisKey in seriesOptions) {
          const seriesAxisKey = seriesOptions[directionAxisKey];
          if (remappedAxisKeys.has(seriesAxisKey)) {
            remappedSeriesAxisKey = remappedAxisKeys.get(seriesAxisKey);
          } else {
            remappedSeriesAxisKey = `${AXIS_ID_PREFIX}${remappedAxisKeys.size}`;
            remappedAxisKeys.set(seriesAxisKey, remappedSeriesAxisKey);
            newAxes[remappedSeriesAxisKey] = shallowClone(defaultAxes[direction]);
          }
        } else if (remappedAxisKeys.has(direction) && hasExtraImplicitDefaultSeriesAxisKeys) {
          remappedSeriesAxisKey = remappedAxisKeys.get(direction);
          newAxes[remappedSeriesAxisKey] ?? (newAxes[remappedSeriesAxisKey] = shallowClone(defaultAxes[direction]));
        }
        seriesOptions[directionAxisKey] = remappedSeriesAxisKey;
      }
    }
  }
  /**
   * Attempt to predict the axes for each direction based on a subset of the data. Each series has its own prediction
   * algorithm.
   */
  predictAxes(seriesType, directions2, userSeriesOptions, data) {
    if (!userSeriesOptions)
      return;
    const seriesData = userSeriesOptions?.data ?? data;
    if (!seriesData?.length)
      return;
    const predictAxis = moduleRegistry_exports.getSeriesModule(seriesType)?.predictAxis;
    if (!predictAxis)
      return;
    const axes = /* @__PURE__ */ new Map();
    const indices = distribute(0, seriesData.length - 1, 5);
    for (const index of indices) {
      const datum = seriesData[index];
      for (const direction of directions2) {
        const axis = predictAxis(direction, datum, userSeriesOptions);
        if (!axes.has(direction)) {
          axes.set(direction, axis);
          continue;
        }
        const prevAxis = axes.get(direction);
        if (!axis && !prevAxis)
          continue;
        if (!axis || !prevAxis)
          return;
        for (const key of Object.keys(prevAxis)) {
          if (prevAxis[key] !== axis[key])
            return;
        }
      }
    }
    for (const [direction, axis] of axes) {
      if (!axis)
        axes.delete(direction);
    }
    if (axes.size === 0)
      return;
    if (axes.size === 1) {
      const [predictedAxis] = axes.values();
      const defaultAxes = this.cloneDefaultAxes(seriesType);
      if (!("position" in predictedAxis))
        return;
      return mapValues(defaultAxes, (axis) => {
        if (!("position" in axis))
          return axis;
        return axis.position === predictedAxis.position ? predictedAxis : axis;
      });
    }
    return Object.fromEntries(axes);
  }
  cloneDefaultAxes(seriesType) {
    const seriesModule = moduleRegistry_exports.getSeriesModule(seriesType);
    return seriesModule?.defaultAxes ? deepClone(seriesModule.defaultAxes) : {};
  }
  predictAxesMissingTypesAndPositions(options, directions2, newAxes, defaultAxes) {
    for (const [key, axis] of entries(newAxes)) {
      if (!isPlainObject(axis))
        continue;
      if ("type" in axis && "position" in axis)
        continue;
      if (key in defaultAxes) {
        axis.type ?? (axis.type = defaultAxes[key].type);
        axis.position ?? (axis.position = defaultAxes[key].position);
        continue;
      }
      const predictedType = this.predictAxisMissingTypeFromPosition(axis, defaultAxes);
      if (predictedType)
        continue;
      this.predictAxisMissingTypeAndPositionFromSeries(options, directions2, key, axis, defaultAxes);
      if (!("type" in axis)) {
        delete newAxes[key];
      }
    }
  }
  predictAxisMissingTypeFromPosition(axis, defaultAxes) {
    if (!("position" in axis) || !isKeyOf(axis.position, POSITION_DIRECTIONS)) {
      return false;
    }
    for (const defaultAxis of Object.values(defaultAxes)) {
      if (isKeyOf(defaultAxis.position, POSITION_DIRECTIONS) && POSITION_DIRECTIONS[axis.position] === POSITION_DIRECTIONS[defaultAxis.position]) {
        axis.type = defaultAxis.type;
        return true;
      }
    }
    for (const [position, positionDirection] of entries(POSITION_DIRECTIONS)) {
      if (axis.position !== position && positionDirection === POSITION_DIRECTIONS[axis.position]) {
        axis.type = defaultAxes[positionDirection].type;
        return true;
      }
    }
    return false;
  }
  predictAxisMissingTypeAndPositionFromSeries(options, directions2, axisKey, axis, defaultAxes) {
    for (const seriesOptions of options.series ?? []) {
      for (const direction of directions2) {
        const directionAxisKey = this.getSeriesDirectionAxisKey(seriesOptions, direction);
        if (!directionAxisKey || !isKeyOf(directionAxisKey, seriesOptions))
          continue;
        if (seriesOptions[directionAxisKey] !== axisKey)
          continue;
        axis.type ?? (axis.type = defaultAxes[direction].type);
        axis.position ?? (axis.position = defaultAxes[direction].position);
        return direction === "y" /* Y */;
      }
    }
    return false;
  }
  /**
   * If the first secondary axis in either direction does not have a specified position, it will be placed in the
   * alternate position to the primary axis (i.e. right or top).
   */
  alternateSecondaryAxisPositions(options, newAxes, unmappedAxisKeys) {
    let xAxisCount = 0;
    let yAxisCount = 0;
    for (const [axisKey, axis] of entries(newAxes)) {
      if (!isPlainObject(axis) || !("position" in axis))
        continue;
      const unmappedAxisKey = unmappedAxisKeys.get(axisKey);
      const unmappedAxis = "axes" in options && options.axes && unmappedAxisKey && unmappedAxisKey in options.axes ? options.axes[unmappedAxisKey] : void 0;
      const unmappedAxisPosition = unmappedAxis && "position" in unmappedAxis ? unmappedAxis.position : void 0;
      if (axis.position === "top" || axis.position === "bottom") {
        xAxisCount += 1;
        if (xAxisCount === 2 && unmappedAxisPosition == null) {
          axis.position = "top";
        }
      } else if (axis.position === "left" || axis.position === "right") {
        yAxisCount += 1;
        if (yAxisCount === 2 && unmappedAxisPosition == null) {
          axis.position = "right";
        }
      }
      if (xAxisCount > 1 && yAxisCount > 1)
        break;
    }
  }
  processMiniChartSeriesOptions(options) {
    const miniChartSeries = options.navigator?.miniChart?.series;
    if (miniChartSeries == null)
      return;
    options.navigator.miniChart.series = this.setSeriesGroupingOptions(
      miniChartSeries
    );
  }
  getSeriesGroupingOptions(series) {
    const { groupable, stackable, stackedByDefault = false } = moduleRegistry_exports.getSeriesModule(series.type);
    if (series.grouped && !groupable) {
      logger_exports.warnOnce(`unsupported grouping of series type "${series.type}".`);
    }
    if ((series.stacked || series.stackGroup) && !stackable) {
      logger_exports.warnOnce(`unsupported stacking of series type "${series.type}".`);
    }
    let { grouped, stacked } = series;
    stacked ?? (stacked = (stackedByDefault || series.stackGroup != null) && !(groupable && grouped));
    grouped ?? (grouped = true);
    return {
      stacked: stackable && stacked,
      grouped: groupable && grouped && !(stackable && stacked)
    };
  }
  setSeriesGroupingOptions(allSeries) {
    const seriesGroups = this.getSeriesGrouping(allSeries);
    _ChartOptions.debug("ChartOptions.setSeriesGroupingOptions() - series grouping: ", seriesGroups);
    const groupIdx = {};
    const groupCount2 = seriesGroups.reduce((countMap, seriesGroup) => {
      var _a;
      if (seriesGroup.groupType === "default" /* DEFAULT */) {
        return countMap;
      }
      countMap[_a = seriesGroup.seriesType] ?? (countMap[_a] = 0);
      countMap[seriesGroup.seriesType] += seriesGroup.groupType === "stack" /* STACK */ ? 1 : seriesGroup.series.length;
      return countMap;
    }, {});
    return seriesGroups.flatMap((seriesGroup) => {
      var _a;
      groupIdx[_a = seriesGroup.seriesType] ?? (groupIdx[_a] = 0);
      switch (seriesGroup.groupType) {
        case "stack" /* STACK */: {
          const groupIndex = groupIdx[seriesGroup.seriesType]++;
          return seriesGroup.series.map(
            (series, stackIndex) => Object.assign(series, {
              seriesGrouping: {
                groupId: seriesGroup.groupId,
                groupIndex,
                groupCount: groupCount2[seriesGroup.seriesType],
                stackIndex,
                stackCount: seriesGroup.series.length
              }
            })
          );
        }
        case "group" /* GROUP */:
          return seriesGroup.series.map(
            (series) => Object.assign(series, {
              seriesGrouping: {
                groupId: seriesGroup.groupId,
                groupIndex: groupIdx[seriesGroup.seriesType]++,
                groupCount: groupCount2[seriesGroup.seriesType],
                stackIndex: 0,
                stackCount: 0
              }
            })
          );
      }
      return seriesGroup.series;
    }).map(({ stacked: _, grouped: __, ...seriesOptions }) => seriesOptions);
  }
  getSeriesGroupId(series) {
    return [series.type, series.xKey, series.stacked ? series.stackGroup ?? "stacked" : "grouped"].filter(Boolean).join("-");
  }
  getSeriesGrouping(allSeries) {
    const groupMap = /* @__PURE__ */ new Map();
    return allSeries.reduce((result, series) => {
      const seriesType = series.type;
      if (!series.stacked && !series.grouped) {
        result.push({ groupType: "default" /* DEFAULT */, seriesType, series: [series], groupId: "__default__" });
      } else {
        const groupId = this.getSeriesGroupId(series);
        if (!groupMap.has(groupId)) {
          const groupType = series.stacked ? "stack" /* STACK */ : "group" /* GROUP */;
          const record2 = { groupType, seriesType, series: [], groupId };
          groupMap.set(groupId, record2);
          result.push(record2);
        }
        groupMap.get(groupId).series.push(series);
      }
      return result;
    }, []);
  }
  soloSeriesIntegrity(options) {
    if (!isArray(options.series))
      return;
    const isSolo = (seriesType) => moduleRegistry_exports.getSeriesModule(seriesType)?.solo ?? false;
    const allSeries = options.series;
    if (allSeries && allSeries.length > 1 && allSeries.some((series) => isSolo(series.type))) {
      const mainSeriesType = this.optionsType(options);
      if (isSolo(mainSeriesType)) {
        logger_exports.warn(
          `series[0] of type '${mainSeriesType}' is incompatible with other series types. Only processing series[0]`
        );
        options.series = allSeries.slice(0, 1);
      } else {
        const { solo, nonSolo } = groupBy(allSeries, (s) => isSolo(s.type) ? "solo" : "nonSolo");
        const rejects = unique(solo.map((s) => s.type)).join(", ");
        logger_exports.warn(`Unable to mix these series types with the lead series type: ${rejects}`);
        options.series = nonSolo;
      }
    }
  }
  static processFontOptions(node, _, __, googleFonts = /* @__PURE__ */ new Set()) {
    if (typeof node === "object" && "fontFamily" in node) {
      if (Array.isArray(node.fontFamily)) {
        const fontFamily = [];
        for (const font3 of node.fontFamily) {
          if (typeof font3 === "object" && "googleFont" in font3) {
            fontFamily.push(font3.googleFont);
            googleFonts?.add(font3.googleFont);
          } else {
            fontFamily.push(font3);
          }
        }
        node.fontFamily = fontFamily.join(", ");
      } else if (typeof node.fontFamily === "object" && "googleFont" in node.fontFamily) {
        node.fontFamily = node.fontFamily.googleFont;
        googleFonts?.add(node.fontFamily);
      }
    }
    return googleFonts;
  }
  processFonts(options, googleFonts = /* @__PURE__ */ new Set()) {
    return jsonWalk(
      options,
      _ChartOptions.processFontOptions,
      /* @__PURE__ */ new Set(["data", "theme"]),
      void 0,
      void 0,
      googleFonts
    );
  }
  static removeDisabledOptionJson(optionsNode) {
    if ("enabled" in optionsNode && optionsNode.enabled === false) {
      for (const key of Object.keys(optionsNode)) {
        if (key === "enabled")
          continue;
        delete optionsNode[key];
      }
    }
  }
  removeDisabledOptions(options) {
    jsonWalk(options, _ChartOptions.removeDisabledOptionJson, /* @__PURE__ */ new Set(["data", "theme", "contextMenu"]));
  }
  static removeLeftoverSymbolsJson(optionsNode) {
    if (!optionsNode || !isObject(optionsNode))
      return;
    for (const key of Object.keys(optionsNode)) {
      const value = optionsNode[key];
      if (isSymbol(value)) {
        delete optionsNode[key];
      }
    }
  }
  removeLeftoverSymbols(options) {
    jsonWalk(options, _ChartOptions.removeLeftoverSymbolsJson, /* @__PURE__ */ new Set(["data"]));
  }
  specialOverridesDefaults(options) {
    if (options.window == null) {
      options.window = getWindow();
    } else {
      setWindow(options.window);
    }
    if (options.document == null) {
      options.document = getDocument();
    } else {
      setDocument(options.document);
    }
    if (options.window == null) {
      throw new Error("AG Charts - unable to resolve global window");
    }
    if (options.document == null) {
      throw new Error("AG Charts - unable to resolve global document");
    }
    return options;
  }
};
_ChartOptions.OPTIONS_CLONE_OPTS_SLOW = {
  shallow: /* @__PURE__ */ new Set(["data", "container"]),
  assign: /* @__PURE__ */ new Set(["context", "theme"])
};
_ChartOptions.OPTIONS_CLONE_OPTS_FAST = {
  shallow: /* @__PURE__ */ new Set(["container"]),
  assign: /* @__PURE__ */ new Set(["data", "context", "theme"])
};
_ChartOptions.JSON_DIFF_OPTS = /* @__PURE__ */ new Set(["data", "localeText"]);
_ChartOptions.perfDebug = debugLogger_exports.create(true, "perf");
_ChartOptions.FAST_PATH_OPTIONS = /* @__PURE__ */ new Set(["data", "width", "height", "container"]);
// AG-16389: Track keys the user passed in deltaOptions
_ChartOptions.debug = debugLogger_exports.create(true, "opts");
var ChartOptions = _ChartOptions;

// packages/ag-charts-community/src/chart/chartProxy.ts
var debug3 = debugLogger_exports.create(true, "opts");
var DESTROYED_ERROR = "AG Charts - Chart was destroyed, cannot perform request.";
var _AgChartInstanceProxy = class _AgChartInstanceProxy {
  constructor(chart, factoryApi, licenseManager) {
    this.factoryApi = factoryApi;
    this.licenseManager = licenseManager;
    this.chart = chart;
  }
  async update(options) {
    if (!this.chart)
      throw new Error(DESTROYED_ERROR);
    return debug3.group("AgChartInstance.update()", async () => {
      const apiStartTime = debugLogger_exports.check("scene:stats", "scene:stats:verbose") ? performance.now() : void 0;
      this.factoryApi.update(options, this, void 0, apiStartTime);
      await this.chart?.waitForUpdate();
    });
  }
  async updateDelta(deltaOptions) {
    if (!this.chart)
      throw new Error(DESTROYED_ERROR);
    return debug3.group("AgChartInstance.updateDelta()", async () => {
      const apiStartTime = debugLogger_exports.check("scene:stats", "scene:stats:verbose") ? performance.now() : void 0;
      this.factoryApi.updateUserDelta(this, deltaOptions, apiStartTime);
      await this.chart?.waitForUpdate();
    });
  }
  getOptions() {
    if (!this.chart)
      throw new Error(DESTROYED_ERROR);
    const options = deepClone(this.chart.getOptions(), ChartOptions.OPTIONS_CLONE_OPTS_FAST);
    for (const key of Object.keys(options)) {
      if (key.startsWith("_")) {
        delete options[key];
      }
    }
    return options;
  }
  waitForUpdate() {
    if (!this.chart)
      throw new Error(DESTROYED_ERROR);
    return this.chart.waitForUpdate();
  }
  applyTransaction(transaction) {
    const { chart } = this;
    if (!chart)
      throw new Error(DESTROYED_ERROR);
    if (transaction == null || typeof transaction !== "object") {
      throw new Error("AG Charts - applyTransaction expects a transaction object.");
    }
    const { add: add2, addIndex, remove, update } = transaction;
    if (add2 != null && !Array.isArray(add2)) {
      throw new Error('AG Charts - transaction "add" must be an array.');
    }
    if (addIndex != null) {
      if (typeof addIndex !== "number" || !Number.isSafeInteger(addIndex) || addIndex < 0) {
        throw new Error(
          'AG Charts - transaction "addIndex" must be a safe non-negative integer (0 to 9007199254740991).'
        );
      }
      if (add2 == null || add2.length === 0) {
        throw new Error('AG Charts - transaction "addIndex" requires a non-empty "add" array.');
      }
    }
    if (remove != null && !Array.isArray(remove)) {
      throw new Error('AG Charts - transaction "remove" must be an array.');
    }
    if (update != null && !Array.isArray(update)) {
      throw new Error('AG Charts - transaction "update" must be an array.');
    }
    return debug3.group("AgChartInstance.applyTransaction()", async () => {
      if (!chart.isDataTransactionSupported()) {
        const dataSet = chart.data.deepClone();
        dataSet.addTransaction(transaction);
        dataSet.commitPendingTransactions();
        return this.updateDelta({ data: dataSet.data });
      }
      debug3("transaction", transaction);
      return await this.chart?.applyTransaction(transaction);
    });
  }
  async download(opts) {
    if (!this.chart)
      throw new Error(DESTROYED_ERROR);
    const clone2 = await this.prepareResizedChart(this, this.chart, opts);
    try {
      clone2.chart?.download(opts?.fileName, opts?.fileFormat);
    } finally {
      clone2.destroy();
    }
  }
  async __toSVG(opts) {
    if (!this.chart)
      throw new Error(DESTROYED_ERROR);
    const clone2 = await this.prepareResizedChart(this, this.chart, { width: 600, height: 300, ...opts });
    try {
      return clone2?.chart?.toSVG();
    } finally {
      clone2?.destroy();
    }
  }
  async getImageDataURL(opts) {
    if (!this.chart)
      throw new Error(DESTROYED_ERROR);
    const clone2 = await this.prepareResizedChart(this, this.chart, opts);
    try {
      return clone2.chart.getCanvasDataURL(opts?.fileFormat);
    } finally {
      clone2.destroy();
    }
  }
  getState() {
    return this.factoryApi.caretaker.save(...this.getEnabledOriginators());
  }
  async setState(state) {
    const { chart } = this;
    if (!chart)
      return;
    const originators = this.getEnabledOriginators();
    if (!originators.includes(chart.ctx.legendManager)) {
      await this.setStateOriginators(state, originators);
      return;
    }
    await this.setStateOriginators(
      state,
      originators.filter((originator) => originator !== chart.ctx.zoomManager)
    );
    await this.setStateOriginators(state, [chart.ctx.zoomManager]);
  }
  resetAnimations() {
    this.chart?.resetAnimations();
  }
  skipAnimations() {
    this.chart?.skipAnimations();
  }
  destroy() {
    if (this.releaseChart) {
      this.releaseChart();
      this.releaseChart = void 0;
    } else if (this.chart) {
      this.chart.publicApi = void 0;
      this.chart.destroy();
    }
    this.chart = void 0;
  }
  async prepareResizedChart(proxy, chart, opts = {}) {
    const width2 = opts.width ?? chart.width ?? chart.ctx.scene.canvas.width;
    const height2 = opts.height ?? chart.height ?? chart.ctx.scene.canvas.height;
    const state = proxy.getState();
    const processedOverrides = {
      ...chart.chartOptions.processedOverrides,
      container: getDocument().createElement("div"),
      width: width2,
      height: height2
    };
    if (opts.width != null && opts.height != null) {
      processedOverrides.overrideDevicePixelRatio = 1;
    }
    const userOptions = chart.getOptions();
    if (moduleRegistry_exports.isEnterprise()) {
      processedOverrides.animation = { enabled: false };
      const foreground = this.licenseManager?.getWatermarkForegroundConfigForBrowser();
      if (foreground) {
        processedOverrides.foreground = foreground;
      }
    }
    const specialOverrides = { ...chart.chartOptions.specialOverrides };
    const optionsMetadata = { ...chart.chartOptions.optionMetadata };
    const data = await this.chart?.ctx.dataService.getData();
    const cloneProxy = this.factoryApi.create(
      userOptions,
      processedOverrides,
      specialOverrides,
      optionsMetadata,
      data
    );
    if (state.legend) {
      this.syncLegend(chart, cloneProxy, state);
    }
    cloneProxy.chart?.update(0 /* FULL */, { forceNodeDataRefresh: true });
    await cloneProxy.waitForUpdate();
    await cloneProxy.setState(state);
    const sourcing = { source: "chart-update", sourceDetail: "internal-prepareResizedChart" };
    cloneProxy.chart?.ctx.zoomManager.updateZoom(sourcing, chart.ctx.zoomManager.getZoom());
    cloneProxy.chart?.update(0 /* FULL */, { forceNodeDataRefresh: true });
    await cloneProxy.waitForUpdate();
    const legendPages = [];
    for (const legend of chart.modulesManager.legends()) {
      legendPages.push(legend.legend.pagination?.currentPage ?? 0);
    }
    for (const legend of cloneProxy.chart.modulesManager.legends()) {
      const page = legendPages.shift() ?? 0;
      if (!legend.legend.pagination)
        continue;
      legend.legend.pagination.setPage(page);
    }
    cloneProxy.chart?.update(0 /* FULL */, { forceNodeDataRefresh: true });
    await cloneProxy.waitForUpdate();
    return cloneProxy;
  }
  syncLegend(chart, cloneProxy, state) {
    const seriesIdMap = /* @__PURE__ */ new Map();
    for (const [index, series] of chart.series.entries()) {
      const cloneSeries = cloneProxy.chart?.series[index];
      if (!cloneSeries)
        continue;
      seriesIdMap.set(series.id, cloneSeries.id);
    }
    state.legend = state.legend?.map((legend) => {
      return {
        ...legend,
        seriesId: seriesIdMap.get(legend.seriesId ?? "") ?? legend.seriesId
      };
    });
  }
  getEnabledOriginators() {
    if (!this.chart)
      return [];
    const {
      chartOptions: { processedOptions, optionMetadata },
      ctx: { annotationManager, chartTypeOriginator, zoomManager, legendManager },
      modulesManager
    } = this.chart;
    const originators = [];
    if ("annotations" in processedOptions && processedOptions.annotations?.enabled) {
      originators.push(annotationManager);
    }
    const isFinancialChart = optionMetadata.presetType === "price-volume";
    if (isFinancialChart) {
      originators.push(chartTypeOriginator);
    }
    if (processedOptions.navigator?.enabled || processedOptions.zoom?.enabled) {
      originators.push(zoomManager);
    }
    const legendEnabled = modulesManager.isEnabled("legend") && processedOptions.legend?.enabled !== false;
    if (legendEnabled) {
      originators.push(legendManager);
    }
    originators.push(this.chart.ctx.activeManager);
    return originators;
  }
  async setStateOriginators(state, originators) {
    this.factoryApi.caretaker.restore(state, ...originators);
    this.chart?.ctx.updateService.update(2 /* PROCESS_DATA */, { forceNodeDataRefresh: true });
    await this.chart?.waitForUpdate();
  }
};
_AgChartInstanceProxy.chartInstances = /* @__PURE__ */ new WeakMap();
__decorateClass([
  ActionOnSet({
    oldValue(chart) {
      if (!chart.destroyed) {
        chart.publicApi = void 0;
      }
      _AgChartInstanceProxy.chartInstances.delete(chart);
    },
    newValue(chart) {
      if (!chart)
        return;
      chart.publicApi = this;
      _AgChartInstanceProxy.chartInstances.set(chart, this);
    }
  })
], _AgChartInstanceProxy.prototype, "chart", 2);
var AgChartInstanceProxy = _AgChartInstanceProxy;

// packages/ag-charts-community/src/util/pool.ts
var CLEANUP_TIMEOUT_MS = 1e3;
var _Pool = class _Pool {
  constructor(name, buildItem, releaseItem, destroyItem, maxPoolSize, cleanupTimeMs = CLEANUP_TIMEOUT_MS) {
    this.name = name;
    this.buildItem = buildItem;
    this.releaseItem = releaseItem;
    this.destroyItem = destroyItem;
    this.maxPoolSize = maxPoolSize;
    this.cleanupTimeMs = cleanupTimeMs;
    this.freePool = [];
    this.busyPool = /* @__PURE__ */ new Set();
  }
  static getPool(name, buildItem, releaseItem, destroyItem, maxPoolSize) {
    if (!this.pools.has(name)) {
      this.pools.set(name, new _Pool(name, buildItem, releaseItem, destroyItem, maxPoolSize));
    }
    return this.pools.get(name);
  }
  isFull() {
    return this.freePool.length + this.busyPool.size >= this.maxPoolSize;
  }
  hasFree() {
    return this.freePool.length > 0;
  }
  obtain(params) {
    if (!this.hasFree() && this.isFull()) {
      throw new Error("AG Charts - pool exhausted");
    }
    let nextFree = this.freePool.pop();
    if (nextFree == null) {
      nextFree = this.buildItem(params);
      _Pool.debug(() => [
        `Pool[name=${this.name}]: Created instance (${this.freePool.length} / ${this.busyPool.size + 1} / ${this.maxPoolSize})`,
        nextFree
      ]);
    } else {
      _Pool.debug(() => [
        `Pool[name=${this.name}]: Re-used instance (${this.freePool.length} / ${this.busyPool.size + 1} / ${this.maxPoolSize})`,
        nextFree
      ]);
    }
    this.busyPool.add(nextFree);
    return { item: nextFree, release: () => this.release(nextFree) };
  }
  obtainFree() {
    const nextFree = this.freePool.pop();
    if (nextFree == null) {
      throw new Error("AG Charts - pool has no free instances");
    }
    _Pool.debug(() => [
      `Pool[name=${this.name}]: Re-used instance (${this.freePool.length} / ${this.busyPool.size + 1} / ${this.maxPoolSize})`,
      nextFree
    ]);
    this.busyPool.add(nextFree);
    return { item: nextFree, release: () => this.release(nextFree) };
  }
  release(item) {
    if (!this.busyPool.has(item)) {
      throw new Error("AG Charts - cannot free item from pool which is not tracked as busy.");
    }
    _Pool.debug(() => [
      `Pool[name=${this.name}]: Releasing instance (${this.freePool.length} / ${this.busyPool.size} / ${this.maxPoolSize})`,
      item
    ]);
    this.releaseItem(item);
    this.busyPool.delete(item);
    this.freePool.push(item);
    _Pool.debug(() => [
      `Pool[name=${this.name}]: Returned instance to free pool (${this.freePool.length} / ${this.busyPool.size} / ${this.maxPoolSize})`,
      item
    ]);
    const now = Date.now();
    const earliestClean = now + this.cleanupTimeMs * 0.5;
    if (this.cleanPoolTimer && (this.cleanPoolDue ?? Infinity) < earliestClean) {
      clearTimeout(this.cleanPoolTimer);
      this.cleanPoolTimer = void 0;
    }
    if (!this.cleanPoolTimer) {
      this.cleanPoolDue = now + this.cleanupTimeMs;
      this.cleanPoolTimer = setTimeout(this.cleanPool.bind(this), this.cleanupTimeMs);
    }
  }
  cleanPool() {
    const itemsToFree = this.freePool.splice(0);
    for (const item of itemsToFree) {
      this.destroyItem(item);
    }
    _Pool.debug(() => [
      `Pool[name=${this.name}]: Cleaned pool of ${itemsToFree.length} items (${this.freePool.length} / ${this.busyPool.size} / ${this.maxPoolSize})`
    ]);
  }
  destroy() {
    this.cleanPool();
    for (const item of this.busyPool.values()) {
      this.destroyItem(item);
    }
    this.busyPool.clear();
  }
};
_Pool.pools = /* @__PURE__ */ new Map();
_Pool.debug = debugLogger_exports.create(true, "pool");
var Pool = _Pool;

// packages/ag-charts-community/src/api/agCharts.ts
var debug4 = debugLogger_exports.create(true, "opts");
var AgCharts = class {
  static licenseCheck(options) {
    if (this.licenseChecked)
      return;
    this.licenseManager = enterpriseRegistry.licenseManager?.(options);
    this.licenseManager?.validateLicense();
    this.licenseChecked = true;
  }
  static getLicenseDetails(licenseKey) {
    return enterpriseRegistry.licenseManager?.({}).getLicenseDetails(licenseKey);
  }
  /**
   * Returns the `AgChartInstance` for a DOM node, if there is one.
   */
  static getInstance(element2) {
    return AgChartsInternal.getInstance(element2);
  }
  /**
   * Create a new `AgChartInstance` based upon the given configuration options.
   */
  static create(userOptions, optionsMetadata) {
    const apiStartTime = debugLogger_exports.check("scene:stats", "scene:stats:verbose") ? performance.now() : void 0;
    return debug4.group("AgCharts.create()", () => {
      userOptions = debugLogger_exports.inDevelopmentMode(() => deepFreeze(deepClone(userOptions))) ?? userOptions;
      this.licenseCheck(userOptions);
      const chart = AgChartsInternal.createOrUpdate({
        userOptions,
        licenseManager: this.licenseManager,
        optionsMetadata,
        apiStartTime
      });
      if (this.licenseManager?.isDisplayWatermark()) {
        enterpriseRegistry.injectWatermark?.(
          chart.chart.ctx.domManager,
          this.licenseManager.getWatermarkMessage()
        );
      }
      return chart;
    });
  }
  static createFinancialChart(options) {
    return debug4.group("AgCharts.createFinancialChart()", () => {
      return this.create(options, { presetType: "price-volume" });
    });
  }
  static createGauge(options) {
    return debug4.group("AgCharts.createGauge()", () => {
      return this.create(options, { presetType: "gauge-preset" });
    });
  }
  static __createSparkline(options) {
    return debug4.group("AgCharts.__createSparkline()", () => {
      const { pool, ...normalOptions } = options;
      return this.create(normalOptions, {
        presetType: "sparkline",
        pool: pool ?? true,
        domMode: "minimal",
        withDragInterpretation: false
      });
    });
  }
};
AgCharts.licenseChecked = false;
var _AgChartsInternal = class _AgChartsInternal {
  static getInstance(element2) {
    const chart = Chart.getInstance(element2);
    return chart ? AgChartInstanceProxy.chartInstances.get(chart) : void 0;
  }
  static createOrUpdate(opts) {
    let { proxy } = opts;
    const {
      userOptions,
      licenseManager,
      processedOverrides = proxy?.chart?.chartOptions.processedOverrides ?? {},
      specialOverrides = proxy?.chart?.chartOptions.specialOverrides ?? {},
      optionsMetadata = proxy?.chart?.chartOptions.optionMetadata ?? {},
      deltaOptions,
      data,
      stripSymbols = false,
      apiStartTime
    } = opts;
    const styles = enterpriseRegistry.styles == null ? [] : [["ag-charts-enterprise", enterpriseRegistry.styles]];
    if (moduleRegistry_exports.listModules().next().done) {
      throw new Error(
        [
          "AG Charts - No modules have been registered.",
          "",
          "Call ModuleRegistry.registerModules(...) with the modules you need before using AgCharts.create().",
          "",
          "See https://www.ag-grid.com/charts/r/module-registry/ for more details."
        ].join("\n")
      );
    }
    debug4(() => [">>> AgCharts.createOrUpdate() user options", deepClone(userOptions)]);
    const { presetType } = optionsMetadata;
    let mutableOptions = userOptions;
    if (AgCharts.optionsMutationFn && mutableOptions) {
      mutableOptions = AgCharts.optionsMutationFn(
        deepClone(mutableOptions, ChartOptions.OPTIONS_CLONE_OPTS_FAST),
        presetType
      );
      debug4(() => [">>> AgCharts.createOrUpdate() MUTATED user options", deepClone(mutableOptions)]);
    }
    const pool = this.getPool(optionsMetadata);
    let create2 = false;
    let poolResult;
    let chart = proxy?.chart;
    if (chart == null && pool?.hasFree()) {
      poolResult = pool.obtainFree();
      chart = poolResult.item;
    }
    const { document: document2, window: userWindow, styleContainer, skipCss, ...options } = mutableOptions ?? {};
    const baseOptions = chart?.getChartOptions();
    const chartOptions = new ChartOptions(
      baseOptions,
      options,
      processedOverrides,
      {
        ...specialOverrides,
        document: document2,
        window: userWindow,
        styleContainer,
        skipCss
      },
      optionsMetadata,
      deltaOptions,
      stripSymbols,
      apiStartTime
    );
    if (chart == null || detectChartType(chartOptions.processedOptions) !== detectChartType(chart.chartOptions.processedOptions)) {
      poolResult?.release();
      poolResult = this.getPool(chartOptions.optionMetadata)?.obtain(chartOptions);
      if (poolResult) {
        chart = poolResult.item;
      } else {
        create2 = true;
        chart = _AgChartsInternal.createChartInstance(chartOptions, chart);
      }
    }
    if (chartOptions.optionsGraph) {
      chart.ctx.optionsGraphService.updateCallback((path, partialOptions, resolveOptions) => {
        return chartOptions.optionsGraph?.resolvePartial(path, partialOptions, resolveOptions);
      });
    }
    for (const [id, css] of styles) {
      chart.ctx.domManager.addStyles(id, css);
    }
    chart.ctx.fontManager.updateFonts(chartOptions.googleFonts);
    if (data != null) {
      chart.ctx.dataService.restoreData(data);
    }
    if (proxy == null) {
      proxy = new AgChartInstanceProxy(chart, _AgChartsInternal.callbackApi, licenseManager);
      proxy.releaseChart = poolResult?.release;
    } else if (poolResult || create2) {
      proxy.releaseChart?.();
      proxy.chart = chart;
      proxy.releaseChart = poolResult?.release;
    }
    if (debug4.check() && typeof globalThis.window !== "undefined") {
      globalThis.agChartInstances ?? (globalThis.agChartInstances = {});
      globalThis.agChartInstances[chart.id] = chart;
    }
    chart.queuedUserOptions.push(chartOptions.userOptions);
    chart.queuedChartOptions.push(chartOptions);
    chart.requestFactoryUpdate((chartRef) => {
      debug4.group(">>>> Chart.applyOptions()", () => {
        chartRef.applyOptions(chartOptions);
        const queueIdx = chartRef.queuedUserOptions.indexOf(chartOptions.userOptions) + 1;
        chartRef.queuedUserOptions.splice(0, queueIdx);
        chartRef.queuedChartOptions.splice(0, queueIdx);
      });
    });
    return proxy;
  }
  static updateUserDelta(proxy, deltaOptions, apiStartTime) {
    deltaOptions = deepClone(deltaOptions, ChartOptions.OPTIONS_CLONE_OPTS_FAST);
    const stripSymbols = jsonWalk(
      deltaOptions,
      _AgChartsInternal.markRemovedProperties,
      /* @__PURE__ */ new Set(["data"]),
      void 0,
      void 0,
      false
    );
    debug4(() => [">>> AgCharts.updateUserDelta() user delta", deepClone(deltaOptions)]);
    _AgChartsInternal.createOrUpdate({
      proxy,
      deltaOptions,
      stripSymbols,
      apiStartTime
    });
  }
  static createChartInstance(options, oldChart) {
    const transferableResource = oldChart?.destroy({ keepTransferableResources: true });
    const chartType = detectChartType(options.processedOptions);
    const chartDef = moduleRegistry_exports.getChartModule(chartType);
    return chartDef.create(options, transferableResource);
  }
  static getPool(optionMetadata) {
    if (optionMetadata.pool !== true)
      return;
    return Pool.getPool(
      optionMetadata.presetType ?? "default",
      this.createChartInstance,
      this.detachAndClear,
      this.destroy,
      Infinity
      // AG-13480 - Prevent Grid exhausting pool during sorting.
    );
  }
};
_AgChartsInternal.caretaker = new MementoCaretaker(VERSION);
_AgChartsInternal.callbackApi = {
  caretaker: _AgChartsInternal.caretaker,
  create(userOptions, processedOverrides, specialOverrides, optionsMetadata, data) {
    return _AgChartsInternal.createOrUpdate({
      userOptions,
      processedOverrides,
      specialOverrides,
      optionsMetadata,
      data
    });
  },
  update(opts, chart, specialOverrides, apiStartTime) {
    return _AgChartsInternal.createOrUpdate({
      userOptions: opts,
      proxy: chart,
      specialOverrides,
      apiStartTime
    });
  },
  updateUserDelta(chart, deltaOptions, apiStartTime) {
    return _AgChartsInternal.updateUserDelta(chart, deltaOptions, apiStartTime);
  }
};
// CRT-1018 Use `Parameters` and `unknown` to strictly enforce type-safety
_AgChartsInternal.markRemovedProperties = (node, _parallelNode, _ctx, previousModified) => {
  let modified = previousModified ?? false;
  if (typeof node !== "object" || node == null)
    return modified;
  for (const key of strictObjectKeys(node)) {
    const value = node[key];
    if (value === void 0) {
      Object.assign(node, { [key]: Symbol("UNSET") });
      modified || (modified = true);
    }
  }
  return modified;
};
_AgChartsInternal.detachAndClear = (chart) => chart.detachAndClear();
_AgChartsInternal.destroy = (chart) => chart.destroy();
var AgChartsInternal = _AgChartsInternal;

// packages/ag-charts-community/src/module-support.ts
var module_support_exports = {};
__export(module_support_exports, {
  APPROXIMATE_THRESHOLD: () => APPROXIMATE_THRESHOLD,
  AbstractBarSeries: () => AbstractBarSeries,
  AbstractBarSeriesProperties: () => AbstractBarSeriesProperties,
  AggregationManager: () => AggregationManager,
  AnchoredPopover: () => AnchoredPopover,
  ApproximateOrdinalTimeScale: () => ApproximateOrdinalTimeScale,
  Arc: () => Arc,
  Axis: () => Axis,
  AxisGroupZIndexMap: () => AxisGroupZIndexMap,
  AxisInterval: () => AxisInterval,
  AxisLabel: () => AxisLabel,
  AxisTick: () => AxisTick,
  BBox: () => BBox,
  Background: () => Background,
  BandScale: () => BandScale,
  BaseToolbar: () => BaseToolbar,
  Caption: () => Caption,
  CartesianAxis: () => CartesianAxis,
  CartesianCrossLine: () => CartesianCrossLine,
  CartesianSeries: () => CartesianSeries,
  CartesianSeriesNodeEvent: () => CartesianSeriesNodeEvent,
  CartesianSeriesProperties: () => CartesianSeriesProperties,
  CategoryAxis: () => CategoryAxis,
  CategoryScale: () => CategoryScale,
  Chart: () => Chart,
  ChartAxes: () => ChartAxes,
  ChartOptions: () => ChartOptions,
  CollapseMode: () => CollapseMode,
  ColorScale: () => ColorScale,
  ContextMenuRegistry: () => ContextMenuRegistry,
  ContinuousScale: () => ContinuousScale,
  DEFAULT_CARTESIAN_DIRECTION_KEYS: () => DEFAULT_CARTESIAN_DIRECTION_KEYS,
  DEFAULT_CARTESIAN_DIRECTION_NAMES: () => DEFAULT_CARTESIAN_DIRECTION_NAMES,
  DEFAULT_POLAR_DIRECTION_KEYS: () => DEFAULT_POLAR_DIRECTION_KEYS,
  DEFAULT_POLAR_DIRECTION_NAMES: () => DEFAULT_POLAR_DIRECTION_NAMES,
  DOMManager: () => DOMManager,
  DataController: () => DataController,
  DataModel: () => DataModel,
  DataModelSeries: () => DataModelSeries,
  DataSet: () => DataSet,
  DiscreteTimeAxis: () => DiscreteTimeAxis,
  DraggablePopover: () => DraggablePopover,
  DropShadow: () => DropShadow,
  ExtendedPath2D: () => ExtendedPath2D,
  FillGradientDefaults: () => FillGradientDefaults,
  FillImageDefaults: () => FillImageDefaults,
  FillPatternDefaults: () => FillPatternDefaults,
  FloatingToolbar: () => FloatingToolbar,
  FormatManager: () => FormatManager,
  Group: () => Group,
  GroupWidget: () => GroupWidget,
  HierarchyHighlightState: () => HierarchyHighlightState,
  HierarchyNode: () => HierarchyNode,
  HierarchySeries: () => HierarchySeries,
  HierarchySeriesProperties: () => HierarchySeriesProperties,
  HighlightManager: () => HighlightManager,
  HighlightProperties: () => HighlightProperties,
  HighlightState: () => HighlightState,
  Image: () => Image2,
  InteractionManager: () => InteractionManager,
  InteractionState: () => InteractionState,
  LARGEST_KEY_INTERVAL: () => LARGEST_KEY_INTERVAL,
  Label: () => Label,
  LabelStyle: () => LabelStyle,
  LayoutElement: () => LayoutElement,
  Line: () => Line,
  LinearScale: () => LinearScale,
  LogScale: () => LogScale,
  Marker: () => Marker,
  Menu: () => Menu,
  MercatorScale: () => MercatorScale,
  NODE_UPDATE_STATE_TO_PHASE_MAPPING: () => NODE_UPDATE_STATE_TO_PHASE_MAPPING,
  NativeWidget: () => NativeWidget,
  NiceMode: () => NiceMode,
  Node: () => Node2,
  OrdinalTimeScale: () => OrdinalTimeScale,
  Path: () => Path,
  PointerEvents: () => PointerEvents,
  PolarAxis: () => PolarAxis,
  PolarSeries: () => PolarSeries,
  QuadtreeNearest: () => QuadtreeNearest,
  RadialColumnShape: () => RadialColumnShape,
  Range: () => Range,
  Rect: () => Rect,
  Rotatable: () => Rotatable,
  RotatableText: () => RotatableText,
  SMALLEST_KEY_INTERVAL: () => SMALLEST_KEY_INTERVAL,
  Scalable: () => Scalable,
  ScalableGroup: () => ScalableGroup,
  Scene: () => Scene,
  Sector: () => Sector,
  SectorBox: () => SectorBox,
  SegmentedPath: () => SegmentedPath,
  Selection: () => Selection,
  Series: () => Series,
  SeriesItemHighlightStyle: () => SeriesItemHighlightStyle,
  SeriesMarker: () => SeriesMarker,
  SeriesNodeEvent: () => SeriesNodeEvent,
  SeriesNodePickMode: () => SeriesNodePickMode,
  SeriesProperties: () => SeriesProperties,
  SeriesTooltip: () => SeriesTooltip,
  Shape: () => Shape,
  SliderWidget: () => SliderWidget,
  StopProperties: () => StopProperties,
  SvgPath: () => SvgPath,
  Text: () => Text,
  TimeAxisParentLevel: () => TimeAxisParentLevel,
  TimeScale: () => TimeScale,
  Toolbar: () => Toolbar,
  ToolbarButtonWidget: () => ToolbarButtonWidget,
  ToolbarWidget: () => ToolbarWidget,
  TooltipManager: () => TooltipManager,
  Transformable: () => Transformable,
  TransformableGroup: () => TransformableGroup,
  TransformableText: () => TransformableText,
  Translatable: () => Translatable,
  TranslatableGroup: () => TranslatableGroup,
  TranslatableSvgPath: () => TranslatableSvgPath,
  UnitTimeScale: () => UnitTimeScale,
  ZoomManager: () => ZoomManager,
  accumulativeValueProperty: () => accumulativeValueProperty,
  addHitTestersToQuadtree: () => addHitTestersToQuadtree,
  adjustLabelPlacement: () => adjustLabelPlacement,
  angleCategoryAxisOptionsDefs: () => angleCategoryAxisOptionsDefs,
  angleNumberAxisOptionsDefs: () => angleNumberAxisOptionsDefs,
  animationValidation: () => animationValidation,
  annotationCalloutStylesDefs: () => annotationCalloutStylesDefs,
  annotationChannelTextDefs: () => annotationChannelTextDefs,
  annotationCommentStylesDefs: () => annotationCommentStylesDefs,
  annotationCrossLineStyleDefs: () => annotationCrossLineStyleDefs,
  annotationDisjointChannelStyleDefs: () => annotationDisjointChannelStyleDefs,
  annotationFibonacciStylesDefs: () => annotationFibonacciStylesDefs,
  annotationLineStyleDefs: () => annotationLineStyleDefs,
  annotationLineTextDefs: () => annotationLineTextDefs,
  annotationMeasurerStylesDefs: () => annotationMeasurerStylesDefs,
  annotationNoteStylesDefs: () => annotationNoteStylesDefs,
  annotationOptionsDef: () => annotationOptionsDef,
  annotationParallelChannelStyleDefs: () => annotationParallelChannelStyleDefs,
  annotationQuickMeasurerStylesDefs: () => annotationQuickMeasurerStylesDefs,
  annotationShapeStylesDefs: () => annotationShapeStylesDefs,
  annotationTextStylesDef: () => annotationTextStylesDef,
  boxPlotSeriesThemeableOptionsDef: () => boxPlotSeriesThemeableOptionsDef,
  buildResetPathFn: () => buildResetPathFn,
  calculateDataDiff: () => calculateDataDiff,
  calculateLabelTranslation: () => calculateLabelTranslation,
  calculateSegments: () => calculateSegments,
  candlestickSeriesThemeableOptionsDef: () => candlestickSeriesThemeableOptionsDef,
  checkCrisp: () => checkCrisp,
  chordSeriesThemeableOptionsDef: () => chordSeriesThemeableOptionsDef,
  clippedRoundRect: () => clippedRoundRect,
  collapsedStartingBarPosition: () => collapsedStartingBarPosition,
  computeBarFocusBounds: () => computeBarFocusBounds,
  computeMarkerFocusBounds: () => computeMarkerFocusBounds,
  coneFunnelSeriesThemeableOptionsDef: () => coneFunnelSeriesThemeableOptionsDef,
  createDatumId: () => createDatumId,
  diff: () => diff,
  drawCorner: () => drawCorner,
  drawMarkerUnitPolygon: () => drawMarkerUnitPolygon,
  findNodeDatumInArray: () => findNodeDatumInArray,
  findQuadtreeMatch: () => findQuadtreeMatch,
  fixNumericExtent: () => fixNumericExtent,
  fromToMotion: () => fromToMotion,
  funnelSeriesThemeableOptionsDef: () => funnelSeriesThemeableOptionsDef,
  generateTicks: () => generateTicks,
  getColorStops: () => getColorStops,
  getCrossLineValue: () => getCrossLineValue,
  getItemStyles: () => getItemStyles,
  getItemStylesPerItemId: () => getItemStylesPerItemId,
  getLabelStyles: () => getLabelStyles,
  getMarkerStyles: () => getMarkerStyles,
  getMissCount: () => getMissCount,
  getRadialColumnWidth: () => getRadialColumnWidth,
  getShapeFill: () => getShapeFill,
  getShapeStyle: () => getShapeStyle,
  groupAccumulativeValueProperty: () => groupAccumulativeValueProperty,
  hasDimmedOpacity: () => hasDimmedOpacity,
  heatmapSeriesThemeableOptionsDef: () => heatmapSeriesThemeableOptionsDef,
  initialStatePickedOptionsDef: () => initialStatePickedOptionsDef,
  interpolatePoints: () => interpolatePoints,
  isTooltipValueMissing: () => isTooltipValueMissing,
  keyProperty: () => keyProperty,
  makeSeriesTooltip: () => makeSeriesTooltip,
  mapLineBackgroundSeriesThemeableOptionsDef: () => mapLineBackgroundSeriesThemeableOptionsDef,
  mapLineSeriesThemeableOptionsDef: () => mapLineSeriesThemeableOptionsDef,
  mapMarkerSeriesThemeableOptionsDef: () => mapMarkerSeriesThemeableOptionsDef,
  mapShapeBackgroundSeriesThemeableOptionsDef: () => mapShapeBackgroundSeriesThemeableOptionsDef,
  mapShapeSeriesThemeableOptionsDef: () => mapShapeSeriesThemeableOptionsDef,
  markerEnabled: () => markerEnabled,
  markerFadeInAnimation: () => markerFadeInAnimation,
  markerSwipeScaleInAnimation: () => markerSwipeScaleInAnimation,
  midpointStartingBarPosition: () => midpointStartingBarPosition,
  minimumTimeAxisDatumGranularity: () => minimumTimeAxisDatumGranularity,
  motion: () => motion,
  nightingaleSeriesThemeableOptionsDef: () => nightingaleSeriesThemeableOptionsDef,
  normaliseGroupTo: () => normaliseGroupTo,
  ohlcSeriesThemeableOptionsDef: () => ohlcSeriesThemeableOptionsDef,
  ordinalTimeAxisOptionsDefs: () => ordinalTimeAxisOptionsDefs,
  pairUpSpans: () => pairUpSpans,
  pathFadeInAnimation: () => pathFadeInAnimation,
  pathMotion: () => pathMotion,
  pathSwipeInAnimation: () => pathSwipeInAnimation,
  plotAreaPathFill: () => plotAreaPathFill,
  plotInterpolatedLinePathStroke: () => plotInterpolatedLinePathStroke,
  plotLinePathStroke: () => plotLinePathStroke,
  predictCartesianFinancialAxis: () => predictCartesianFinancialAxis,
  predictCartesianNonPrimitiveAxis: () => predictCartesianNonPrimitiveAxis,
  prepareAreaFillAnimationFns: () => prepareAreaFillAnimationFns,
  prepareBarAnimationFunctions: () => prepareBarAnimationFunctions,
  prepareLinePathPropertyAnimation: () => prepareLinePathPropertyAnimation,
  processedDataIsAnimatable: () => processedDataIsAnimatable,
  pyramidSeriesThemeableOptionsDef: () => pyramidSeriesThemeableOptionsDef,
  radarAreaSeriesThemeableOptionsDef: () => radarAreaSeriesThemeableOptionsDef,
  radarLineSeriesThemeableOptionsDef: () => radarLineSeriesThemeableOptionsDef,
  radialBarSeriesThemeableOptionsDef: () => radialBarSeriesThemeableOptionsDef,
  radialColumnSeriesThemeableOptionsDef: () => radialColumnSeriesThemeableOptionsDef,
  radiusCategoryAxisOptionsDefs: () => radiusCategoryAxisOptionsDefs,
  radiusNumberAxisOptionsDefs: () => radiusNumberAxisOptionsDefs,
  rangeAreaSeriesThemeableOptionsDef: () => rangeAreaSeriesThemeableOptionsDef,
  rangeBarSeriesThemeableOptionsDef: () => rangeBarSeriesThemeableOptionsDef,
  resetAxisLabelSelectionFn: () => resetAxisLabelSelectionFn,
  resetBarSelectionsDirect: () => resetBarSelectionsDirect,
  resetBarSelectionsFn: () => resetBarSelectionsFn,
  resetLabelFn: () => resetLabelFn,
  resetMarkerFn: () => resetMarkerFn,
  resetMarkerPositionFn: () => resetMarkerPositionFn,
  resetMarkerSelectionsDirect: () => resetMarkerSelectionsDirect,
  resetMotion: () => resetMotion,
  sankeySeriesThemeableOptionsDef: () => sankeySeriesThemeableOptionsDef,
  sectorBox: () => sectorBox,
  seriesLabelFadeInAnimation: () => seriesLabelFadeInAnimation,
  seriesLabelFadeOutAnimation: () => seriesLabelFadeOutAnimation,
  stackCartesianSeries: () => stackCartesianSeries,
  standaloneChartOptionsDefs: () => standaloneChartOptionsDefs,
  sunburstSeriesThemeableOptionsDef: () => sunburstSeriesThemeableOptionsDef,
  toHierarchyHighlightString: () => toHierarchyHighlightString,
  toHighlightString: () => toHighlightString,
  topologyChartOptionsDefs: () => topologyChartOptionsDefs,
  trailingAccumulatedValueProperty: () => trailingAccumulatedValueProperty,
  treemapSeriesThemeableOptionsDef: () => treemapSeriesThemeableOptionsDef,
  updateClipPath: () => updateClipPath,
  updateLabelNode: () => updateLabelNode,
  upsertNodeDatum: () => upsertNodeDatum,
  userInteraction: () => userInteraction,
  validateCrossLineValue: () => validateCrossLineValue,
  valueProperty: () => valueProperty,
  visibleRangeIndices: () => visibleRangeIndices,
  waterfallSeriesThemeableOptionsDef: () => waterfallSeriesThemeableOptionsDef
});

// packages/ag-charts-community/src/chart/series/cartesian/util.ts
function isAxisReversed(axis) {
  return axis.isReversed() !== axis.range[1] < axis.range[0];
}
function calculateSegments(segmentation, xAxis, yAxis, seriesRect, chartSize, applyOffset = true) {
  if (xAxis.scale.domain.length === 0 || yAxis.scale.domain.length === 0) {
    return;
  }
  const axis = segmentation.key === "x" /* X */ ? xAxis : yAxis;
  const { scale: scale2, direction } = axis;
  const isXDirection = direction === "x" /* X */;
  const bandwidth = scale2.bandwidth ?? 0;
  const offset = applyOffset ? ((scale2.step ?? 0) - bandwidth) / 2 : 0;
  const horizontalMargin = Math.max(seriesRect.x, chartSize.width - (seriesRect.x + seriesRect.width));
  const verticalMargin = Math.max(seriesRect.y, chartSize.height - (seriesRect.y + seriesRect.height));
  const getDefaultStart = () => {
    if (isAxisReversed(isXDirection ? xAxis : yAxis)) {
      return isXDirection ? seriesRect.width + horizontalMargin : seriesRect.height + verticalMargin;
    }
    return isXDirection ? -horizontalMargin : -verticalMargin;
  };
  const getDefaultStop = () => {
    if (isAxisReversed(isXDirection ? xAxis : yAxis)) {
      return isXDirection ? -horizontalMargin : -verticalMargin;
    }
    return isXDirection ? seriesRect.width + horizontalMargin : seriesRect.height + verticalMargin;
  };
  const getSegments = (segments) => {
    const result = [];
    let previousDefinedStopIndex = -1;
    for (let i = 0; i < segments.length; i++) {
      const segment = segments[i];
      if (isEmptyObject(segment)) {
        continue;
      }
      const { start: start2, stop, ...styles } = segments[i];
      const startFallback = segments[previousDefinedStopIndex]?.stop;
      const stopFallback = segments.slice(i + 1).find((s) => s.start != null)?.start;
      let startPosition = scale2.convert(start2 ?? startFallback) - offset;
      let stopPosition = scale2.convert(stop ?? stopFallback) + 2 * offset;
      const invalidStart = start2 != null && Number.isNaN(startPosition);
      const invalidStop = stop != null && Number.isNaN(stopPosition);
      if (invalidStart || invalidStop) {
        continue;
      }
      if (Number.isNaN(startPosition))
        startPosition = getDefaultStart();
      if (Number.isNaN(stopPosition))
        stopPosition = getDefaultStop();
      if (stop != null) {
        previousDefinedStopIndex = i;
      }
      result.push({ start: startPosition, stop: stopPosition, ...styles });
    }
    return result;
  };
  return getSegments(segmentation.segments).map(({ stop, start: start2, ...style2 }) => {
    const x0 = isXDirection ? start2 : -horizontalMargin;
    const y0 = isXDirection ? -verticalMargin : start2;
    const x1 = isXDirection ? stop + bandwidth : seriesRect.width + horizontalMargin;
    const y1 = isXDirection ? seriesRect.height + verticalMargin : stop + bandwidth;
    return { clipRect: { x0, y0, x1, y1 }, ...style2 };
  });
}
var TIME_AXIS_KEYS = /* @__PURE__ */ new Set(["time", "timestamp", "date", "datetime"]);
function predictCartesianAxis(direction, datum, seriesOptions, { allowPrimitiveTypes = true } = {}) {
  if (direction !== "x" /* X */ && direction !== "y" /* Y */)
    return;
  if (!isObject(datum))
    return;
  const key = getSeriesOptionsKey(direction, seriesOptions);
  if (key == null || !(key in datum))
    return;
  const value = datum[key];
  const position = getAxisPosition(direction, seriesOptions);
  const groupedCategory = predictGroupedCategoryAxisType(value);
  if (groupedCategory) {
    return { type: groupedCategory, position };
  }
  const timeAxis = predictTimeAxisType(key, value);
  if (timeAxis) {
    return { type: timeAxis, position };
  }
  if (!allowPrimitiveTypes)
    return;
  if (typeof value === "number") {
    return {
      type: "number" /* NUMBER */,
      position
    };
  }
  return {
    type: "category" /* CATEGORY */,
    position
  };
}
function predictCartesianNonPrimitiveAxis(direction, datum, seriesOptions) {
  return predictCartesianAxis(direction, datum, seriesOptions, { allowPrimitiveTypes: false });
}
function predictCartesianFinancialAxis(direction, datum, seriesOptions) {
  if (direction !== "x" /* X */)
    return;
  if (!isObject(datum))
    return;
  const key = getSeriesOptionsKey(direction, seriesOptions);
  if (key == null || !(key in datum))
    return;
  const value = datum[key];
  const position = getAxisPosition(direction, seriesOptions);
  const ordinalTimeAxis = predictOrdinalTimeAxisType(key, value);
  if (ordinalTimeAxis) {
    return { type: ordinalTimeAxis, position };
  }
  if (isString(value)) {
    return { type: "category", position };
  }
}
function predictGroupedCategoryAxisType(value) {
  if (isArray(value) && value.every((v) => isString(v) || v === null)) {
    return "grouped-category" /* GROUPED_CATEGORY */;
  }
}
function predictTimeAxisType(key, value) {
  if (isDate(value) || TIME_AXIS_KEYS.has(key) && isNumber(value)) {
    return "time" /* TIME */;
  }
}
function predictOrdinalTimeAxisType(key, value) {
  if (isDate(value) || TIME_AXIS_KEYS.has(key) && isNumber(value)) {
    return "ordinal-time" /* ORDINAL_TIME */;
  }
}
function getSeriesOptionsKey(direction, seriesOptions) {
  if (direction === "x" /* X */ && "xKey" in seriesOptions) {
    return seriesOptions.xKey;
  } else if (direction === "y" /* Y */ && "yKey" in seriesOptions) {
    return seriesOptions.yKey;
  }
}
function getAxisPosition(direction, seriesOptions) {
  if ("direction" in seriesOptions && seriesOptions.direction === "horizontal") {
    return direction === "x" /* X */ ? "left" /* LEFT */ : "bottom" /* BOTTOM */;
  }
  return direction === "x" /* X */ ? "bottom" /* BOTTOM */ : "left" /* LEFT */;
}

// packages/ag-charts-community/src/scale/logScale.ts
var logFunctions = {
  2: (_base, x) => Math.log2(x),
  [Math.E]: (_base, x) => Math.log(x),
  10: (_base, x) => Math.log10(x)
};
var DEFAULT_LOG = (base, x) => Math.log(x) / Math.log(base);
function log2(base, domain, x) {
  const start2 = Math.min(...domain);
  const fn = logFunctions[base] ?? DEFAULT_LOG;
  return start2 >= 0 ? fn(base, x) : -fn(base, -x);
}
var powFunctions = {
  [Math.E]: (_base, x) => Math.exp(x),
  10: (_base, x) => x >= 0 ? 10 ** x : 1 / 10 ** -x
};
var DEFAULT_POW = (base, x) => base ** x;
function pow(base, domain, x) {
  const start2 = Math.min(...domain);
  const fn = powFunctions[base] ?? DEFAULT_POW;
  return start2 >= 0 ? fn(base, x) : -fn(base, -x);
}
var LogScale = class _LogScale extends ContinuousScale {
  constructor(d = [1, 10], r = [0, 1]) {
    super(d, r);
    this.type = "log";
    // Handling <1 and crossing 0 cases is tricky, easiest solution is to default to clamping.
    this.defaultClamp = true;
    this.base = 10;
    this.log = (x) => log2(this.base, this.domain, x);
    this.pow = (x) => pow(this.base, this.domain, x);
  }
  static is(value) {
    return value instanceof _LogScale;
  }
  transform(x) {
    const [min, max] = findMinMax(this.domain);
    if (min >= 0 !== max >= 0)
      return Number.NaN;
    return min >= 0 ? Math.log(x) : -Math.log(-x);
  }
  transformInvert(x) {
    const [min, max] = findMinMax(this.domain);
    if (min >= 0 !== max >= 0)
      return Number.NaN;
    return min >= 0 ? Math.exp(x) : -Math.exp(-x);
  }
  toDomain(d) {
    return d;
  }
  niceDomain(ticks, domain = this.domain) {
    if (domain.length < 2)
      return [];
    const { base } = this;
    const [d0, d1] = domain;
    const roundStart = d0 > d1 ? Math.ceil : Math.floor;
    const roundStop = d0 > d1 ? Math.floor : Math.ceil;
    const n0 = pow(base, domain, roundStart(log2(base, domain, d0)));
    const n1 = pow(base, domain, roundStop(log2(base, domain, d1)));
    return [ticks.nice[0] ? n0 : domain[0], ticks.nice[1] ? n1 : domain[1]];
  }
  ticks({ interval, tickCount = ContinuousScale.defaultTickCount }, domain = this.domain, visibleRange) {
    if (!domain || domain.length < 2 || tickCount < 1) {
      return;
    }
    const base = this.base;
    const [d0, d1] = domain;
    const start2 = Math.min(d0, d1);
    const stop = Math.max(d0, d1);
    let p0 = this.log(start2);
    let p1 = this.log(stop);
    if (interval) {
      const inBounds = (tick) => tick >= start2 && tick <= stop;
      const step = Math.min(Math.abs(interval), Math.abs(p1 - p0));
      const { ticks: rangeTicks, count, firstTickIndex } = range(p0, p1, step, visibleRange);
      const ticks2 = rangeTicks.map(this.pow).filter(inBounds);
      if (!isDenseInterval(ticks2.length, this.getPixelRange())) {
        return { ticks: ticks2, count, firstTickIndex };
      }
    }
    if (!isInteger(base) || p1 - p0 >= tickCount) {
      const step = Math.min(p1 - p0, tickCount);
      const { ticks: ticks2, count, firstTickIndex } = createTicks(p0, p1, step, void 0, void 0, visibleRange);
      return {
        ticks: ticks2.map(this.pow),
        count,
        firstTickIndex
      };
    }
    const ticks = [];
    const isPositive = start2 > 0;
    p0 = Math.floor(p0) - 1;
    p1 = Math.round(p1) + 1;
    const availableSpacing = findRangeExtent(this.range) / tickCount;
    let lastTickPosition = Infinity;
    for (let p = p0; p <= p1; p++) {
      const nextMagnitudeTickPosition = this.convert(this.pow(p + 1));
      for (let k = 1; k < base; k++) {
        const q = isPositive ? k : base - k + 1;
        const t = this.pow(p) * q;
        const tickPosition = this.convert(t);
        const prevSpacing = Math.abs(lastTickPosition - tickPosition);
        const nextSpacing = Math.abs(tickPosition - nextMagnitudeTickPosition);
        const fits = prevSpacing >= availableSpacing && nextSpacing >= availableSpacing;
        if (t >= start2 && t <= stop && (k === 1 || fits || ticks.length === 0)) {
          ticks.push(t);
          lastTickPosition = tickPosition;
        }
      }
    }
    return filterVisibleTicks(ticks, isPositive, visibleRange);
  }
};

// packages/ag-charts-community/src/scene/shape/segmentedPath.ts
var SegmentedPath = class extends Path {
  constructor() {
    super(...arguments);
    this.segmentPath = new Path();
  }
  drawPath(ctx) {
    if (!this.segments || this.segments.length === 0) {
      super.drawPath(ctx);
      return;
    }
    ctx.save();
    const Path2DCtor = getPath2D();
    const inverse = new Path2DCtor();
    rect(inverse, { x0: 0, y0: 0, x1: ctx.canvas.width, y1: ctx.canvas.height }, false);
    for (const s of this.segments) {
      rect(inverse, s.clipRect);
    }
    ctx.clip(inverse);
    super.drawPath(ctx);
    ctx.restore();
    const { segmentPath } = this;
    segmentPath.setProperties({
      opacity: this.opacity,
      visible: this.visible,
      lineCap: this.lineCap,
      lineJoin: this.lineJoin,
      pointerEvents: this.pointerEvents
    });
    for (const { clipRect, fill, stroke: stroke3, ...styles } of this.segments) {
      ctx.save();
      segmentPath.path = this.path;
      segmentPath.setProperties(styles);
      segmentPath.fill = this.fill == null ? "none" : fill;
      segmentPath.stroke = this.stroke == null ? "none" : stroke3;
      const clipPath = new Path2DCtor();
      rect(clipPath, clipRect);
      ctx.clip(clipPath);
      segmentPath.drawPath(ctx);
      ctx.restore();
    }
  }
};
__decorateClass([
  SceneRefChangeDetection()
], SegmentedPath.prototype, "segments", 2);
function rect(path, { x0, y0, x1, y1 }, clockwise = true) {
  const minX = Math.min(x0, x1);
  const minY = Math.min(y0, y1);
  const maxX = Math.max(x0, x1);
  const maxY = Math.max(y0, y1);
  path.moveTo(minX, minY);
  if (clockwise) {
    path.lineTo(maxX, minY);
    path.lineTo(maxX, maxY);
    path.lineTo(minX, maxY);
  } else {
    path.lineTo(minX, maxY);
    path.lineTo(maxX, maxY);
    path.lineTo(maxX, minY);
  }
  path.closePath();
}

// packages/ag-charts-community/src/scene/segmentedGroup.ts
var SegmentedGroup = class extends TranslatableGroup {
  constructor() {
    super(...arguments);
    this.segments = [];
    this.scalablePath = new (Scalable(Path))();
  }
  renderInContext(childRenderCtx) {
    if (!this.visible)
      return;
    const { ctx } = childRenderCtx;
    if (!this.segments || this.segments?.length === 0) {
      return super.renderInContext(childRenderCtx);
    }
    ctx.save();
    const Path2DCtor = getPath2D();
    const inverse = new Path2DCtor();
    rect(inverse, { x0: 0, y0: 0, x1: ctx.canvas.width, y1: ctx.canvas.height }, false);
    for (const s of this.segments) {
      rect(inverse, s.clipRect);
    }
    ctx.clip(inverse);
    for (const child of this.children()) {
      if (!child.visible)
        continue;
      child.render(childRenderCtx);
    }
    ctx.restore();
    const { scalablePath } = this;
    for (const { clipRect, ...styles } of this.segments) {
      ctx.save();
      const clipPath = new Path2DCtor();
      rect(clipPath, clipRect);
      ctx.clip(clipPath);
      scalablePath.setProperties(styles);
      for (const child of this.children()) {
        if (!child.visible || !(child instanceof Path))
          continue;
        scalablePath.path = child.path;
        scalablePath.setProperties({
          opacity: child.opacity,
          lineCap: child.lineCap,
          lineJoin: child.lineJoin,
          ...isScalable(child) && {
            scalingX: child.scalingX,
            scalingY: child.scalingY,
            scalingCenterX: child.scalingCenterX,
            scalingCenterY: child.scalingCenterY
          }
        });
        scalablePath.render(childRenderCtx);
      }
      ctx.restore();
    }
  }
};
__decorateClass([
  SceneRefChangeDetection()
], SegmentedGroup.prototype, "segments", 2);

// packages/ag-charts-community/src/scene/util/quadtree.ts
var QuadtreeNearest = class {
  constructor(capacity, maxdepth, boundary) {
    this.root = new QuadtreeNodeNearest(capacity, maxdepth, boundary);
  }
  clear(boundary) {
    this.root.clear(boundary);
  }
  addValue(hitTester, value) {
    const elem = {
      hitTester,
      value,
      distanceSquared: (x, y) => {
        return hitTester.distanceSquared(x, y);
      }
    };
    this.root.addElem(elem);
  }
  find(x, y) {
    const arg = { best: { nearest: void 0, distanceSquared: Infinity } };
    this.root.find(x, y, arg);
    return arg.best;
  }
};
var QuadtreeSubdivisions = class {
  constructor(nw, ne, sw, se) {
    this.nw = nw;
    this.ne = ne;
    this.sw = sw;
    this.se = se;
  }
  addElem(elem) {
    this.nw.addElem(elem);
    this.ne.addElem(elem);
    this.sw.addElem(elem);
    this.se.addElem(elem);
  }
  find(x, y, arg) {
    this.nw.find(x, y, arg);
    this.ne.find(x, y, arg);
    this.sw.find(x, y, arg);
    this.se.find(x, y, arg);
  }
};
var QuadtreeNode = class {
  constructor(capacity, maxdepth, boundary) {
    this.capacity = capacity;
    this.maxdepth = maxdepth;
    this.boundary = boundary ?? BBox.NaN;
    this.elems = [];
    this.subdivisions = void 0;
  }
  clear(boundary) {
    this.elems.length = 0;
    this.boundary = boundary;
    this.subdivisions = void 0;
  }
  addElem(e) {
    if (this.addCondition(e)) {
      if (this.subdivisions === void 0) {
        if (this.maxdepth === 0 || this.elems.length < this.capacity) {
          this.elems.push(e);
        } else {
          this.subdivide(e);
        }
      } else {
        this.subdivisions.addElem(e);
      }
    }
  }
  find(x, y, arg) {
    if (this.findCondition(x, y, arg)) {
      if (this.subdivisions === void 0) {
        this.findAction(x, y, arg);
      } else {
        this.subdivisions.find(x, y, arg);
      }
    }
  }
  subdivide(newElem) {
    this.subdivisions = this.makeSubdivisions();
    for (const e of this.elems) {
      this.subdivisions.addElem(e);
    }
    this.subdivisions.addElem(newElem);
    this.elems.length = 0;
  }
  makeSubdivisions() {
    const { x, y, width: width2, height: height2 } = this.boundary;
    const { capacity } = this;
    const depth = this.maxdepth - 1;
    const halfWidth = width2 / 2;
    const halfHeight = height2 / 2;
    const nwBoundary = new BBox(x, y, halfWidth, halfHeight);
    const neBoundary = new BBox(x + halfWidth, y, halfWidth, halfHeight);
    const swBoundary = new BBox(x, y + halfHeight, halfWidth, halfHeight);
    const seBoundary = new BBox(x + halfWidth, y + halfHeight, halfWidth, halfHeight);
    return new QuadtreeSubdivisions(
      this.child(capacity, depth, nwBoundary),
      this.child(capacity, depth, neBoundary),
      this.child(capacity, depth, swBoundary),
      this.child(capacity, depth, seBoundary)
    );
  }
};
var QuadtreeNodeNearest = class _QuadtreeNodeNearest extends QuadtreeNode {
  addCondition(e) {
    const { x, y } = e.hitTester.midPoint;
    return this.boundary.containsPoint(x, y);
  }
  findCondition(x, y, arg) {
    const { best } = arg;
    return best.distanceSquared !== 0 && this.boundary.distanceSquared(x, y) < best.distanceSquared;
  }
  findAction(x, y, arg) {
    const other = nearestSquared(x, y, this.elems, arg.best.distanceSquared);
    if (other.nearest !== void 0 && other.distanceSquared < arg.best.distanceSquared) {
      arg.best = other;
    }
  }
  child(capacity, depth, boundary) {
    return new _QuadtreeNodeNearest(capacity, depth, boundary);
  }
};

// packages/ag-charts-community/src/scale/linearScale.ts
var LinearScale = class _LinearScale extends ContinuousScale {
  constructor() {
    super([0, 1], [0, 1]);
    this.type = "number";
  }
  static is(value) {
    return value instanceof _LinearScale;
  }
  static getTickStep(start2, stop, ticks) {
    const { interval, tickCount = ContinuousScale.defaultTickCount, minTickCount, maxTickCount } = ticks;
    return interval ?? tickStep(start2, stop, tickCount, minTickCount, maxTickCount);
  }
  toDomain(d) {
    return d;
  }
  ticks({ interval, tickCount = ContinuousScale.defaultTickCount, minTickCount, maxTickCount }, domain = this.domain, visibleRange) {
    if (!domain || domain.length < 2 || tickCount < 1 || !domain.every(Number.isFinite)) {
      return { ticks: [], count: 0, firstTickIndex: 0 };
    }
    const [d0, d1] = domain;
    if (interval) {
      const step = Math.abs(interval);
      if (!isDenseInterval((d1 - d0) / step, this.getPixelRange())) {
        return range(d0, d1, step, visibleRange);
      }
    }
    return createTicks(d0, d1, tickCount, minTickCount, maxTickCount, visibleRange);
  }
  niceDomain(ticks, domain = this.domain) {
    if (domain.length < 2)
      return [];
    const { tickCount = ContinuousScale.defaultTickCount } = ticks;
    let [start2, stop] = domain;
    if (tickCount === 1) {
      [start2, stop] = niceTicksDomain(start2, stop);
    } else if (tickCount > 1) {
      const roundStart = start2 > stop ? Math.ceil : Math.floor;
      const roundStop = start2 > stop ? Math.floor : Math.ceil;
      const maxAttempts = 4;
      for (let i = 0; i < maxAttempts; i++) {
        const prev0 = start2;
        const prev1 = stop;
        const step = _LinearScale.getTickStep(start2, stop, ticks);
        const [d0, d1] = domain;
        start2 = roundStart(d0 / step) * step;
        stop = roundStop(d1 / step) * step;
        if (start2 === prev0 && stop === prev1)
          break;
      }
    }
    return [ticks.nice[0] ? start2 : domain[0], ticks.nice[1] ? stop : domain[1]];
  }
};

// packages/ag-charts-community/src/chart/axis/numberAxis.ts
var NumberAxis = class extends CartesianAxis {
  constructor(moduleCtx, scale2 = new LinearScale()) {
    super(moduleCtx, scale2);
  }
  hasDefinedDomain() {
    const { min, max } = this;
    return min != null && max != null && min < max;
  }
  normaliseDataDomain(d) {
    const { min, max, preferredMin, preferredMax } = this;
    const { extent: extent2, clipped } = normalisedExtentWithMetadata(
      d.domain,
      min,
      max,
      preferredMin,
      preferredMax,
      void 0,
      d.sortMetadata?.sortOrder
    );
    return { domain: extent2, clipped };
  }
  getDomainExtentsNice() {
    return [this.min == null && this.nice, this.max == null && this.nice];
  }
  getVisibleDomain(domain) {
    const [d0, d1] = domain;
    const [r0, r1] = this.visibleRange;
    const length2 = d1 - d0;
    return [d0 + r0 * length2, d1 - (1 - r1) * length2];
  }
  tickFormatParams(domain, _ticks, fractionDigits) {
    return { type: "number", visibleDomain: this.getVisibleDomain(domain), fractionDigits };
  }
  datumFormatParams(value, params, fractionDigits) {
    const { datum, seriesId, legendItemName, key, source, property, domain, boundSeries } = params;
    const visibleDomain = this.getVisibleDomain(domain);
    return {
      type: "number",
      value,
      datum,
      seriesId,
      legendItemName,
      key,
      source,
      property,
      domain,
      visibleDomain,
      boundSeries,
      fractionDigits
    };
  }
};
NumberAxis.className = "NumberAxis";
NumberAxis.type = "number";
__decorateClass([
  addFakeTransformToInstanceProperty
], NumberAxis.prototype, "min", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], NumberAxis.prototype, "max", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], NumberAxis.prototype, "preferredMin", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], NumberAxis.prototype, "preferredMax", 2);

// packages/ag-charts-community/src/chart/axis/timeAxis.ts
var TimeAxisParentLevel = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = false;
    this.label = new AxisLabel();
    this.tick = new AxisTick();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], TimeAxisParentLevel.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TimeAxisParentLevel.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TimeAxisParentLevel.prototype, "tick", 2);
var TimeAxis = class extends CartesianAxis {
  constructor(moduleCtx) {
    super(moduleCtx, new TimeScale());
    this.parentLevel = new TimeAxisParentLevel();
    this.min = void 0;
    this.max = void 0;
    this.preferredMin = void 0;
    this.preferredMax = void 0;
  }
  // eslint-disable-next-line sonarjs/use-type-alias
  get _unit() {
    return void 0;
  }
  set _unit(_unit) {
    logger_exports.warnOnce(`To use 'unit', use an axis with type 'unit-time' instead of 'time'.`);
  }
  hasDefinedDomain() {
    const { min, max } = this;
    return min != null && max != null && min < max;
  }
  isCategoryLike() {
    return false;
  }
  get primaryLabel() {
    return this.parentLevel.enabled ? this.parentLevel.label : void 0;
  }
  get primaryTick() {
    return this.parentLevel.enabled ? this.parentLevel.tick : void 0;
  }
  normaliseDataDomain(d) {
    const { extent: extent2, clipped } = normalisedTimeExtentWithMetadata(
      d,
      this.min,
      this.max,
      this.preferredMin,
      this.preferredMax
    );
    return { domain: extent2, clipped };
  }
  processData() {
    super.processData();
    const { boundSeries, direction, min, max } = this;
    this.minimumTimeGranularity = minimumTimeAxisDatumGranularity(boundSeries, direction, min, max);
  }
  tickFormatParams(domain, ticks, _fractionDigits, timeInterval3) {
    timeInterval3 ?? (timeInterval3 = lowestGranularityUnitForTicks(ticks));
    const truncateDate = dateTruncationForDomain(domain);
    const unit = intervalUnit(timeInterval3);
    const step = intervalStep(timeInterval3);
    const epoch = intervalEpoch(timeInterval3);
    return { type: "date", unit, step, epoch, truncateDate };
  }
  datumFormatParams(value, params, _fractionDigits, timeInterval3, style2) {
    if (typeof value === "number") {
      value = new Date(value);
    }
    if (timeInterval3 == null) {
      const { minimumTimeGranularity } = this;
      const datumGranularity = lowestGranularityUnitForValue(value);
      if (minimumTimeGranularity != null && intervalMilliseconds(minimumTimeGranularity) < intervalMilliseconds(datumGranularity)) {
        timeInterval3 = minimumTimeGranularity;
      } else {
        timeInterval3 = datumGranularity;
      }
    }
    const { datum, seriesId, legendItemName, key, source, property, domain, boundSeries } = params;
    const unit = intervalUnit(timeInterval3);
    const step = intervalStep(timeInterval3);
    const epoch = intervalEpoch(timeInterval3);
    return {
      type: "date",
      value,
      datum,
      seriesId,
      legendItemName,
      key,
      source,
      property,
      domain,
      boundSeries,
      unit,
      step,
      epoch,
      style: style2
    };
  }
};
TimeAxis.className = "TimeAxis";
TimeAxis.type = "time";
__decorateClass([
  addFakeTransformToInstanceProperty
], TimeAxis.prototype, "parentLevel", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TimeAxis.prototype, "min", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TimeAxis.prototype, "max", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TimeAxis.prototype, "preferredMin", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TimeAxis.prototype, "preferredMax", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ProxyPropertyOnWrite("_unit")
], TimeAxis.prototype, "unit", 2);
function minimumTimeAxisDatumGranularity(boundSeries, direction, min, max) {
  const minTimeInterval = boundSeries.reduce((t, series) => {
    return Math.min(series.minTimeInterval() ?? Infinity, t);
  }, Infinity);
  if (Number.isFinite(minTimeInterval)) {
    return lowestGranularityForInterval(minTimeInterval);
  } else {
    return calculateDefaultUnit(boundSeries, direction, min, max)?.unit;
  }
}
function calculateDefaultUnit(boundSeries, direction, min, max) {
  let start2 = Infinity;
  let end3 = -Infinity;
  let interval;
  let maxDataCount = 0;
  const domainValues = [];
  for (const series of boundSeries) {
    if (!series.visible)
      continue;
    const { extent: domain } = normalisedTimeExtentWithMetadata(series.getDomain(direction));
    if (domain.length === 0)
      continue;
    const d0 = domain[0].valueOf();
    const d1 = domain.at(-1).valueOf();
    domainValues.push(d0, d1);
    start2 = Math.min(start2 ?? Infinity, d0, d1);
    end3 = Math.max(end3 ?? -Infinity, d0, d1);
    const domainExtent = Math.abs(d1 - d0);
    if (domainExtent === 0)
      continue;
    const dataCount = series.dataCount();
    maxDataCount = Math.max(maxDataCount, dataCount);
    if (dataCount <= 1)
      continue;
    const i = domainExtent / (dataCount - 1);
    interval = Math.min(interval ?? Infinity, i);
  }
  start2 = Math.min(start2, min?.valueOf() ?? Infinity, max?.valueOf() ?? Infinity);
  end3 = Math.max(end3, min?.valueOf() ?? -Infinity, max?.valueOf() ?? -Infinity);
  if (!Number.isFinite(start2) || !Number.isFinite(end3))
    return;
  interval ?? (interval = Math.abs(end3 - start2));
  interval = Math.min(interval, minNonZeroDifference(domainValues));
  const unit = lowestGranularityForInterval(interval);
  let step = interval / intervalMilliseconds(unit);
  if (maxDataCount <= 2) {
    step = Math.floor(step);
  } else {
    step = Math.round(step);
  }
  step = Math.max(step, 1);
  const epoch = step === 1 ? void 0 : intervalFloor(unit, start2);
  return { unit, step, epoch };
}
function minNonZeroDifference(values) {
  values.sort((a, b) => a - b);
  let minDiff = Infinity;
  for (let i = 1; i < values.length; i++) {
    const d0 = values[i - 1];
    const d1 = values[i];
    const delta5 = d1 - d0;
    if (delta5 > 0) {
      minDiff = Math.min(minDiff, Math.abs(d1 - d0));
    }
  }
  return minDiff;
}

// packages/ag-charts-community/src/chart/series/dataModelSeries.ts
var DataModelSeries = class extends Series {
  constructor({ clipFocusBox, categoryKey, ...seriesOpts }) {
    super(seriesOpts);
    this.categoryKey = categoryKey;
    this.clipFocusBox = clipFocusBox ?? true;
  }
  dataCount() {
    return this.processedData?.dataSources?.get(this.id)?.data?.length ?? 0;
  }
  invalidDataCount() {
    return this.processedData?.invalidDataCount?.get(this.id) ?? 0;
  }
  missingDataCount() {
    return this.dataModel?.resolveMissingDataCount(this) ?? 0;
  }
  get hasData() {
    return Math.max(0, this.dataCount() - this.invalidDataCount() - this.missingDataCount()) > 0;
  }
  getScaleInformation({
    xScale,
    yScale
  }) {
    const isContinuousX = ContinuousScale.is(xScale);
    const isContinuousY = ContinuousScale.is(yScale);
    return { isContinuousX, isContinuousY, xScaleType: xScale?.type, yScaleType: yScale?.type };
  }
  getModulePropertyDefinitions() {
    const xScale = this.axes["x" /* X */]?.scale;
    const yScale = this.axes["y" /* Y */]?.scale;
    return this.moduleMap.mapModules((m) => m.getPropertyDefinitions(this.getScaleInformation({ xScale, yScale }))).flat();
  }
  // Request data, but with message dispatching to series-options (modules).
  async requestDataModel(dataController, dataSet, opts) {
    opts.props.push(...this.getModulePropertyDefinitions());
    const { dataModel, processedData } = await dataController.request(
      this.id,
      dataSet ?? DataSet.empty(),
      opts
    );
    this.dataModel = dataModel;
    this.processedData = processedData;
    this.events.emit("data-processed", { dataModel, processedData });
    return { dataModel, processedData };
  }
  isProcessedDataAnimatable() {
    const { processedData, ctx } = this;
    if (!processedData)
      return false;
    const nodeData = this.getNodeData();
    if (nodeData != null && nodeData.length > ctx.animationManager.maxAnimatableItems)
      return false;
    const validationResults = processedData.reduced?.animationValidation;
    if (!validationResults)
      return true;
    const { orderedKeys, uniqueKeys } = validationResults;
    return orderedKeys && uniqueKeys;
  }
  checkProcessedDataAnimatable() {
    if (!this.isProcessedDataAnimatable()) {
      this.ctx.animationManager.skipCurrentBatch();
    }
  }
  findNodeDatum(itemId) {
    return findNodeDatumInArray(itemId, this.getNodeData());
  }
  pickFocus(opts) {
    const nodeData = this.getNodeData();
    if (nodeData === void 0 || nodeData.length === 0) {
      return;
    }
    const datumIndex = this.computeFocusDatumIndex(opts, nodeData);
    if (datumIndex === void 0) {
      return;
    }
    const { clipFocusBox } = this;
    const datum = nodeData[datumIndex];
    const derivedOpts = { ...opts, datumIndex };
    const bounds = this.computeFocusBounds(derivedOpts);
    if (bounds !== void 0) {
      return { bounds, clipFocusBox, datum, datumIndex };
    }
  }
  pickNodesExactShape(point) {
    const datums = super.pickNodesExactShape(point);
    datums.sort((a, b) => a.datumIndex - b.datumIndex);
    return datums;
  }
  isDatumEnabled(nodeData, datumIndex) {
    const { missing = false, enabled = true, focusable = true } = nodeData[datumIndex];
    return !missing && enabled && focusable;
  }
  computeFocusDatumIndex(opts, nodeData) {
    const searchBackward = (datumIndex2, delta5) => {
      while (datumIndex2 >= 0 && !this.isDatumEnabled(nodeData, datumIndex2)) {
        datumIndex2 += delta5;
      }
      return datumIndex2 === -1 ? void 0 : datumIndex2;
    };
    const searchForward = (datumIndex2, delta5) => {
      while (datumIndex2 < nodeData.length && !this.isDatumEnabled(nodeData, datumIndex2)) {
        datumIndex2 += delta5;
      }
      return datumIndex2 === nodeData.length ? void 0 : datumIndex2;
    };
    let datumIndex;
    const clampedIndex = clamp(0, opts.datumIndex, nodeData.length - 1);
    if (opts.datumIndexDelta < 0) {
      datumIndex = searchBackward(clampedIndex, opts.datumIndexDelta);
    } else if (opts.datumIndexDelta > 0) {
      datumIndex = searchForward(clampedIndex, opts.datumIndexDelta);
    } else {
      datumIndex = searchForward(clampedIndex, 1) ?? searchBackward(clampedIndex, -1);
    }
    if (datumIndex === void 0) {
      if (opts.datumIndexDelta === 0) {
        return;
      } else {
        return opts.datumIndex - opts.datumIndexDelta;
      }
    } else {
      return datumIndex;
    }
  }
  // Workaround - it would be nice if this difference didn't exist
  dataModelPropertyIsKey(key) {
    const { processedData } = this;
    if (!processedData)
      return false;
    return processedData.defs.keys.some((def) => def.id === key && def.idsMap?.get(this.id)?.has(key) === true);
  }
  keysOrValues(xKey) {
    const { dataModel, processedData } = this;
    if (!dataModel || !processedData)
      return [];
    return this.dataModelPropertyIsKey(xKey) ? dataModel.resolveKeysById(this, xKey, processedData) : dataModel.resolveColumnById(this, xKey, processedData);
  }
  sortOrder(xKey) {
    const { dataModel, processedData } = this;
    if (!dataModel || !processedData)
      return;
    return this.dataModelPropertyIsKey(xKey) ? dataModel.getKeySortOrder(this, xKey, processedData) : dataModel.getColumnSortOrder(this, xKey, processedData);
  }
  getCategoryKey() {
    return this.categoryKey;
  }
  getCategoryValue(datumIndex) {
    const { processedData, dataModel } = this;
    const categoryKey = this.getCategoryKey();
    if (!processedData || !dataModel || !categoryKey)
      return;
    const invalid = processedData.invalidData?.get(this.id)?.[datumIndex] ?? false;
    return invalid ? void 0 : this.keysOrValues(categoryKey)[datumIndex];
  }
  datumIndexForCategoryValue(categoryValue) {
    const { processedData, dataModel } = this;
    const categoryKey = this.getCategoryKey();
    if (!processedData || !dataModel || !categoryKey)
      return;
    categoryValue = categoryValue.valueOf();
    const invalidValues = processedData.invalidData?.get(this.id);
    const xValues = this.keysOrValues(categoryKey);
    for (let datumIndex = 0; datumIndex < xValues.length; datumIndex += 1) {
      if (invalidValues?.[datumIndex] === true)
        continue;
      const xValue = xValues[datumIndex]?.valueOf();
      if (objectsEqual(categoryValue, xValue))
        return datumIndex;
    }
  }
};

// packages/ag-charts-community/src/chart/series/cartesian/cartesianSeries.ts
var DEFAULT_CARTESIAN_DIRECTION_KEYS = {
  ["x" /* X */]: ["xKey"],
  ["y" /* Y */]: ["yKey"]
};
var DEFAULT_CARTESIAN_DIRECTION_NAMES = {
  ["x" /* X */]: ["xName"],
  ["y" /* Y */]: ["yName"]
};
var CartesianSeriesNodeEvent = class extends SeriesNodeEvent {
  constructor(type, nativeEvent, datum, series) {
    super(type, nativeEvent, datum, series);
    this.xKey = series.properties.xKey;
    this.yKey = series.properties.yKey;
  }
};
var CartesianSeriesProperties = class extends SeriesProperties {
  constructor() {
    super(...arguments);
    this.xKeyAxis = "x";
    this.yKeyAxis = "y";
    this.pickOutsideVisibleMinorAxis = false;
    this.segmentation = new Segmentation();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianSeriesProperties.prototype, "xKeyAxis", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianSeriesProperties.prototype, "yKeyAxis", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianSeriesProperties.prototype, "legendItemName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianSeriesProperties.prototype, "pickOutsideVisibleMinorAxis", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CartesianSeriesProperties.prototype, "segmentation", 2);
var RENDER_TO_OFFSCREEN_CANVAS_THRESHOLD = 100;
var CartesianSeries = class extends DataModelSeries {
  constructor({
    pathsPerSeries = ["path"],
    pathsZIndexSubOrderOffset = [],
    datumSelectionGarbageCollection = true,
    animationAlwaysUpdateSelections = false,
    animationAlwaysPopulateNodeData = false,
    segmentedDataNodes = true,
    animationResetFns,
    propertyKeys,
    propertyNames,
    ...otherOpts
  }) {
    super({
      propertyKeys,
      propertyNames,
      canHaveAxes: true,
      ...otherOpts
    });
    this.NodeEvent = CartesianSeriesNodeEvent;
    this.dataNodeGroup = this.contentGroup.appendChild(
      new SegmentedGroup({ name: `${this.id}-series-dataNodes`, zIndex: 1 })
    );
    this.labelGroup = this.contentGroup.appendChild(
      new TranslatableGroup({ name: `${this.id}-series-labels` })
    );
    this.labelSelection = Selection.select(this.labelGroup, Text);
    this.highlightSelection = Selection.select(this.highlightNodeGroup, () => this.nodeFactory());
    this.highlightLabelSelection = Selection.select(
      this.highlightLabelGroup,
      Text
    );
    this.annotationSelections = /* @__PURE__ */ new Set();
    this.seriesBelowStackContext = void 0;
    this.debug = debugLogger_exports.create();
    if (!propertyKeys || !propertyNames)
      throw new Error(`Unable to initialise series type ${this.type}`);
    this.opts = {
      pathsPerSeries,
      pathsZIndexSubOrderOffset,
      propertyKeys,
      propertyNames,
      animationResetFns,
      animationAlwaysUpdateSelections,
      animationAlwaysPopulateNodeData,
      datumSelectionGarbageCollection,
      segmentedDataNodes
    };
    this.paths = pathsPerSeries.map((path) => {
      return new SegmentedPath({ name: `${this.id}-${path}` });
    });
    this.datumSelection = Selection.select(
      this.dataNodeGroup,
      () => this.nodeFactory(),
      datumSelectionGarbageCollection
    );
    this.animationState = new StateMachine(
      "empty",
      {
        empty: {
          update: {
            target: "ready",
            action: (data) => this.animateEmptyUpdateReady(data)
          },
          reset: "empty",
          skip: "ready",
          disable: "disabled"
        },
        ready: {
          updateData: "waiting",
          clear: "clearing",
          highlight: (data) => this.animateReadyHighlight(data),
          resize: (data) => this.animateReadyResize(data),
          reset: "empty",
          skip: "ready",
          disable: "disabled"
        },
        waiting: {
          update: {
            target: "ready",
            action: (data) => {
              if (this.ctx.animationManager.isSkipped()) {
                this.resetAllAnimation(data);
              } else {
                this.animateWaitingUpdateReady(data);
              }
            }
          },
          reset: "empty",
          skip: "ready",
          disable: "disabled"
        },
        disabled: {
          update: (data) => this.resetAllAnimation(data),
          reset: "empty"
        },
        clearing: {
          update: {
            target: "empty",
            action: (data) => this.animateClearingUpdateEmpty(data)
          },
          reset: "empty",
          skip: "ready"
        }
      },
      this.checkProcessedDataAnimatable.bind(this)
    );
    this.cleanup.register(
      this.ctx.eventsHub.on("legend:item-click", (event) => this.onLegendItemClick(event)),
      this.ctx.eventsHub.on("legend:item-double-click", (event) => this.onLegendItemDoubleClick(event))
    );
  }
  get contextNodeData() {
    return this._contextNodeData;
  }
  getNodeData() {
    return this.contextNodeData?.nodeData;
  }
  getKeyAxis(direction) {
    if (this.shouldFlipXY()) {
      if (direction === "x" /* X */)
        return this.properties.yKeyAxis;
      if (direction === "y" /* Y */)
        return this.properties.xKeyAxis;
    }
    if (direction === "x" /* X */)
      return this.properties.xKeyAxis;
    if (direction === "y" /* Y */)
      return this.properties.yKeyAxis;
  }
  attachSeries(seriesContentNode, seriesNode, annotationNode) {
    super.attachSeries(seriesContentNode, seriesNode, annotationNode);
    this.attachPaths(this.paths);
  }
  detachSeries(seriesContentNode, seriesNode, annotationNode) {
    super.detachSeries(seriesContentNode, seriesNode, annotationNode);
    this.detachPaths(this.paths);
  }
  updatedDomains() {
    this.animationState.transition("updateData");
  }
  attachPaths(paths) {
    for (const path of paths) {
      this.contentGroup.appendChild(path);
    }
  }
  detachPaths(paths) {
    for (const path of paths) {
      path.remove();
    }
  }
  renderToOffscreenCanvas() {
    const nodeData = this.getNodeData();
    return nodeData != null && nodeData.length > RENDER_TO_OFFSCREEN_CANVAS_THRESHOLD;
  }
  resetAnimation(phase) {
    if (phase === "initial") {
      this.animationState.transition("reset");
    } else if (phase === "ready") {
      this.animationState.transition("skip");
    } else if (phase === "disabled") {
      this.animationState.transition("disable");
    }
  }
  destroy() {
    super.destroy();
    this._contextNodeData = void 0;
  }
  isSeriesHighlighted(highlightedDatum) {
    if (!this.properties.highlight.enabled) {
      return false;
    }
    const { series, legendItemName: activeLegendItemName } = highlightedDatum ?? {};
    const { legendItemName } = this.properties;
    return series === this || legendItemName != null && legendItemName === activeLegendItemName;
  }
  strokewidthChange() {
    const unhighlightedStrokeWidth = ("strokeWidth" in this.properties && this.properties.strokeWidth) ?? 0;
    const highlightedSeriesStrokeWidth = this.properties.highlight.highlightedSeries.strokeWidth ?? unhighlightedStrokeWidth;
    const highlightedItemStrokeWidth = this.properties.highlight.highlightedItem?.strokeWidth ?? unhighlightedStrokeWidth;
    return unhighlightedStrokeWidth > highlightedItemStrokeWidth || highlightedSeriesStrokeWidth > highlightedItemStrokeWidth;
  }
  update({ seriesRect }) {
    const { _contextNodeData: previousContextData } = this;
    const resize = this.checkResize(seriesRect);
    const itemHighlighted = this.updateHighlightSelection();
    const series = this;
    this.contentGroup.batchedUpdate(function updateSelections() {
      const dataChanged = series.updateSelections();
      const segments = series.contextNodeData?.segments;
      if (series.opts.segmentedDataNodes) {
        series.dataNodeGroup.segments = segments ?? series.dataNodeGroup.segments;
      } else {
        series.dataNodeGroup.segments = void 0;
      }
      series.updateNodes(itemHighlighted, resize || dataChanged);
    });
    const animationData = this.getAnimationData(seriesRect, previousContextData);
    if (!animationData)
      return;
    if (resize) {
      this.animationState.transition("resize", animationData);
    }
    this.animationState.transition("update", animationData);
    this.processedDataUpdated = false;
  }
  createStackContext() {
    return void 0;
  }
  // ============================================================================
  // createNodeData() Pattern Helpers
  // ============================================================================
  // These methods support the optimized createNodeData() pattern with incremental updates.
  // See series-performance-optimization.md for detailed documentation.
  /**
   * Determines if incremental node updates are possible based on common criteria.
   *
   * Returns true if existing nodeData exists AND either:
   * - processedData has a changeDescription (partial update), OR
   * - animation is disabled (large dataset)
   *
   * Series may extend with additional conditions by OR'ing additional checks:
   * ```
   * const canIncrementallyUpdate =
   *     this.canIncrementallyUpdateNodes() || (existingNodeData && seriesSpecificCondition);
   * ```
   *
   * @param additionalCondition - Optional series-specific condition to OR with base conditions
   */
  canIncrementallyUpdateNodes(additionalCondition = false) {
    const existingNodeData = this.contextNodeData?.nodeData;
    if (existingNodeData == null)
      return false;
    const { processedData } = this;
    if (!processedData)
      return false;
    return processedData.changeDescription != null || !processedDataIsAnimatable(processedData) || additionalCondition;
  }
  /**
   * Trims the node array after incremental updates.
   *
   * Call at the end of createNodeData() when using incremental updates:
   * ```
   * if (ctx.canIncrementallyUpdate) {
   *     this.trimIncrementalNodeArray(ctx.nodes, ctx.nodeIndex);
   * }
   * ```
   *
   * @param nodes - The node array to trim
   * @param nodeIndex - The final write position (new array length)
   */
  trimIncrementalNodeArray(nodes, nodeIndex) {
    if (nodeIndex < nodes.length) {
      nodes.length = nodeIndex;
    }
  }
  // ============================================================================
  // createNodeData() Template Method Pattern
  // ============================================================================
  // The template method pattern pulls the common createNodeData() flow into the
  // base class. Subclasses implement hooks to customize behaviour.
  //
  // Subclasses that have been migrated implement:
  // - createNodeDatumContext() - cache expensive lookups
  // - populateNodeData() - iterate and create/update datums
  // - initializeResult() - create result object shell
  //
  // And optionally override:
  // - validateCreateNodeDataPreconditions() - custom axis validation
  // - finalizeNodeData() - custom cleanup (multiple arrays, sorting)
  // - assembleResult() - add computed fields (segments)
  /**
   * Template method for creating node data.
   *
   * This implementation provides the common algorithm skeleton:
   * 1. Validate preconditions (axes, dataModel, processedData)
   * 2. Create context with cached values
   * 3. Initialise result object
   * 4. Populate node data (strategy selection inside)
   * 5. Finalize (trim arrays, post-processing)
   * 6. Assemble and return result
   *
   * Subclasses that have been migrated to the template pattern should NOT
   * override this method. Instead, implement the abstract hooks.
   *
   * Subclasses that haven't been migrated yet can override this method entirely.
   */
  createNodeData() {
    const validation = this.validateCreateNodeDataPreconditions();
    if (!validation)
      return void 0;
    const { xAxis, yAxis } = validation;
    const ctx = this.createNodeDatumContext(xAxis, yAxis);
    if (!ctx)
      return this.getEmptyResult();
    const result = this.initializeResult(ctx);
    if (!this.visible && (this.seriesGrouping == null && !this.opts.animationAlwaysPopulateNodeData || !ctx.animationEnabled))
      return result;
    this.populateNodeData(ctx);
    this.finalizeNodeData(ctx);
    return this.assembleResult(ctx, result);
  }
  // ============================================================================
  // Template Method Hooks (Subclasses MUST implement when NOT overriding createNodeData)
  // ============================================================================
  // Series that override createNodeData() entirely don't need these hooks.
  // Series using the template method MUST implement createNodeDatumContext,
  // populateNodeData, and initializeResult.
  /**
   * Creates the shared context for datum creation/update operations.
   * Called once per createNodeData() invocation.
   *
   * MUST return an object extending CartesianCreateNodeDataContext with:
   * - Cached data arrays (resolved from dataModel)
   * - Cached scales (from axes)
   * - Pre-computed positioning values
   * - Property key lookups
   * - Incremental update state (canIncrementallyUpdate, nodes, nodeIndex)
   *
   * @returns Context object or undefined if context cannot be created
   */
  createNodeDatumContext(_xAxis, _yAxis) {
    throw new Error(
      `${this.constructor.name}: createNodeDatumContext() must be implemented when using the template method pattern`
    );
  }
  /**
   * Populates the node data array by iterating over data.
   *
   * Strategy selection happens inside this method:
   * - Simple iteration for ungrouped data
   * - Grouped iteration for grouped data
   * - Aggregation iteration for large datasets
   *
   * Implementations should use the upsert pattern:
   * - prepareNodeDatumState() → validate and compute state
   * - upsertNodeDatum() → create or update node in place
   */
  populateNodeData(_ctx) {
    throw new Error(
      `${this.constructor.name}: populateNodeData() must be implemented when using the template method pattern`
    );
  }
  /**
   * Initializes the result context object that will be returned.
   * Called before populate phase to allow early return for invisible series.
   *
   * Should create the context with:
   * - itemId
   * - nodeData (reference to ctx.nodes)
   * - labelData (reference or separate array)
   * - scales
   * - visible
   * - styles
   */
  initializeResult(_ctx) {
    throw new Error(
      `${this.constructor.name}: initializeResult() must be implemented when using the template method pattern`
    );
  }
  // ============================================================================
  // Virtual Hooks (Subclasses MAY Override)
  // ============================================================================
  /**
   * Validates preconditions for createNodeData.
   * Default: checks axes, dataModel, and processedData exist.
   *
   * Override for specialized axis requirements (e.g., category vs value axis in bar series).
   */
  validateCreateNodeDataPreconditions() {
    const xAxis = this.axes["x" /* X */];
    const yAxis = this.axes["y" /* Y */];
    if (!xAxis || !yAxis || !this.dataModel || !this.processedData) {
      return void 0;
    }
    return { xAxis, yAxis };
  }
  /**
   * Returns empty result when context creation fails.
   * Default: returns undefined.
   */
  getEmptyResult() {
    return void 0;
  }
  /**
   * Finalizes node data after population phase.
   * Default: trims incremental node arrays.
   *
   * Override to add post-processing (sorting, additional cleanup, multiple arrays).
   */
  finalizeNodeData(ctx) {
    if (ctx.canIncrementallyUpdate) {
      this.trimIncrementalNodeArray(ctx.nodes, ctx.nodeIndex);
    }
  }
  /**
   * Assembles final result from context and initialized result.
   * Default: returns the initialized result unchanged.
   *
   * Override to add computed fields (segments, groupScale).
   */
  assembleResult(_ctx, result) {
    return result;
  }
  updateSelections() {
    var _a;
    const animationSkipUpdate = !this.opts.animationAlwaysUpdateSelections && this.ctx.animationManager.isSkipped();
    if (!this.visible && animationSkipUpdate) {
      return false;
    }
    const { nodeDataRefresh } = this;
    if (!nodeDataRefresh && !this.isPathOrSelectionDirty()) {
      return false;
    }
    if (nodeDataRefresh) {
      this.nodeDataRefresh = false;
      this.debug(`CartesianSeries.updateSelections() - calling createNodeData() for`, this.id);
      this.markQuadtreeDirty();
      this._contextNodeData = this.createNodeData();
      const animationValid = this.isProcessedDataAnimatable();
      if (this._contextNodeData) {
        (_a = this._contextNodeData).animationValid ?? (_a.animationValid = animationValid);
        const nodeDataSize = this._contextNodeData.nodeData?.length;
        if (nodeDataSize != null) {
          debugMetrics_exports.record(`${this.type}:nodeData`, nodeDataSize);
        }
      }
      const { dataModel, processedData } = this;
      if (dataModel !== void 0 && processedData !== void 0) {
        this.events.emit("data-update", { dataModel, processedData });
      }
      this.updateSeriesSelections();
    }
    return nodeDataRefresh;
  }
  updateSeriesSelections() {
    const { datumSelection, labelSelection, paths } = this;
    const contextData = this._contextNodeData;
    if (!contextData)
      return;
    const { nodeData, labelData, itemId } = contextData;
    this.updatePaths({ itemId, contextData, paths });
    this.datumSelection = this.updateDatumSelection({ nodeData, datumSelection });
    this.labelGroup.batchedUpdate(() => {
      this.labelSelection = this.updateLabelSelection({ labelData, labelSelection }) ?? labelSelection;
    });
  }
  getShapeFillBBox() {
    const { axes } = this;
    const xAxis = axes["x" /* X */];
    const yAxis = axes["y" /* Y */];
    const [axisX1, axisX2] = findMinMax(xAxis?.range ?? [0, 1]);
    const [axisY1, axisY2] = findMinMax(yAxis?.range ?? [0, 1]);
    const xSeriesDomain = extractDomain(this.getSeriesDomain("x" /* X */));
    const xSeriesRange = [xAxis?.scale.convert(xSeriesDomain.at(0)), xAxis?.scale.convert(xSeriesDomain.at(-1))];
    const ySeriesDomain = extractDomain(this.getSeriesDomain("y" /* Y */));
    const ySeriesRange = [yAxis?.scale.convert(ySeriesDomain.at(0)), yAxis?.scale.convert(ySeriesDomain.at(-1))];
    const [seriesX1, seriesX2] = findMinMax(xSeriesRange);
    const [seriesY1, seriesY2] = findMinMax(ySeriesRange);
    return {
      axis: new BBox(axisX1, axisY1, axisX2 - axisX1, axisY2 - axisY1),
      series: new BBox(seriesX1, seriesY1, seriesX2 - seriesX1, seriesY2 - seriesY1)
    };
  }
  updateNodes(itemHighlighted, nodeRefresh) {
    const { highlightSelection, datumSelection } = this;
    const animationEnabled = !this.ctx.animationManager.isSkipped();
    const visible = this.visible && this._contextNodeData != null;
    this.contentGroup.visible = animationEnabled || visible;
    this.highlightGroup.visible = (animationEnabled || visible) && itemHighlighted;
    this.updateDatumStyles({ datumSelection: highlightSelection, isHighlight: true });
    const drawingMode = this.ctx.chartService.highlight?.drawingMode ?? "overlay";
    this.updateDatumNodes({
      datumSelection: highlightSelection,
      isHighlight: true,
      drawingMode
    });
    this.highlightLabelGroup.batchedUpdate(() => {
      this.updateLabelNodes({ labelSelection: this.highlightLabelSelection, isHighlight: true });
    });
    this.animationState.transition("highlight", highlightSelection);
    const { dataNodeGroup, labelSelection, paths, labelGroup } = this;
    const { itemId } = this.contextNodeData ?? {};
    this.updatePathNodes({ itemId, paths, visible, animationEnabled });
    dataNodeGroup.visible = animationEnabled || visible;
    labelGroup.visible = visible;
    if (!dataNodeGroup.visible) {
      return;
    }
    if (this.hasItemStylers()) {
      this.updateDatumStyles({ datumSelection, isHighlight: false });
    }
    const redrawAll = this.strokewidthChange() || this.hasChangesOnHighlight;
    if (nodeRefresh || redrawAll) {
      this.updateDatumNodes({ datumSelection, isHighlight: false, drawingMode: "overlay" });
      if (!this.usesPlacedLabels) {
        this.labelGroup.batchedUpdate(() => {
          this.updateLabelNodes({ labelSelection, isHighlight: false });
        });
      }
    }
  }
  getHighlightData(_nodeData, highlightedItem) {
    return highlightedItem ? [{ ...highlightedItem }] : void 0;
  }
  getHighlightLabelData(labelData, highlightedItem) {
    const labelItems = labelData.filter(
      (ld) => ld.datum === highlightedItem.datum && ld.itemId === highlightedItem.itemId
    );
    return labelItems.length === 0 ? void 0 : labelItems;
  }
  updateHighlightSelection() {
    const { highlightSelection, highlightLabelSelection, _contextNodeData: contextNodeData } = this;
    if (!contextNodeData)
      return false;
    const highlightedDatum = this.ctx.highlightManager?.getActiveHighlight();
    const seriesHighlighted = this.isSeriesHighlighted(highlightedDatum);
    const item = seriesHighlighted && highlightedDatum?.datum ? highlightedDatum : void 0;
    if (item == null)
      return false;
    const { nodeData, labelData } = contextNodeData;
    const highlightItems = this.getHighlightData(nodeData, item);
    this.highlightSelection = this.updateHighlightSelectionItem({
      items: highlightItems,
      highlightSelection
    });
    const highlightLabelItems = this.getHighlightLabelData(labelData, item) ?? [];
    this.highlightLabelSelection = this.updateLabelSelection({
      labelData: highlightLabelItems,
      labelSelection: highlightLabelSelection
    }) ?? highlightLabelSelection;
    return true;
  }
  markQuadtreeDirty() {
    this.quadtree = void 0;
  }
  *datumNodesIter() {
    for (const { node } of this.datumSelection) {
      if (node.datum.missing === true)
        continue;
      yield node;
    }
  }
  getQuadTree() {
    if (this.quadtree === void 0) {
      const canvas = this.ctx.scene?.canvas ?? { width: 0, height: 0 };
      const canvasRect = new BBox(0, 0, canvas.width, canvas.height);
      this.quadtree = new QuadtreeNearest(100, 10, canvasRect);
      this.initQuadTree(this.quadtree);
    }
    return this.quadtree;
  }
  initQuadTree(_quadtree) {
  }
  pickNodeDataExactShape(point) {
    const { x, y } = point;
    const { dataNodeGroup } = this;
    const matches = dataNodeGroup.pickNodes(x, y).filter((match) => match.datum.missing !== true);
    if (matches.length !== 0) {
      const datums = matches.map((match) => match.datum);
      return datums;
    }
  }
  pickModulesExactShape(point) {
    for (const mod of this.moduleMap.modules()) {
      const { datum } = mod.pickNodeExact(point) ?? {};
      if (datum == null)
        continue;
      if (datum?.missing === true)
        continue;
      return [datum];
    }
  }
  pickNodesExactShape(point) {
    const result = super.pickNodesExactShape(point);
    if (result.length !== 0) {
      return result;
    }
    return this.pickNodeDataExactShape(point) ?? this.pickModulesExactShape(point) ?? [];
  }
  pickNodeDataClosestDatum(point) {
    const { x, y } = point;
    const { axes, _contextNodeData: contextNodeData } = this;
    if (!contextNodeData)
      return;
    const xAxis = axes["x" /* X */];
    const yAxis = axes["y" /* Y */];
    const hitPoint = { x, y };
    let minDistanceSquared = Infinity;
    let closestDatum;
    for (const datum of contextNodeData.nodeData) {
      const { point: { x: datumX = Number.NaN, y: datumY = Number.NaN } = {} } = datum;
      if (Number.isNaN(datumX) || Number.isNaN(datumY)) {
        continue;
      }
      const isInRange = xAxis?.inRange(datumX) && yAxis?.inRange(datumY);
      if (!isInRange) {
        continue;
      }
      const distanceSquared2 = Math.max((hitPoint.x - datumX) ** 2 + (hitPoint.y - datumY) ** 2, 0);
      if (distanceSquared2 < minDistanceSquared) {
        minDistanceSquared = distanceSquared2;
        closestDatum = datum;
      }
    }
    if (minDistanceSquared != null) {
      return { datum: closestDatum, distance: Math.sqrt(minDistanceSquared) };
    }
  }
  pickModulesClosestDatum(point) {
    let minDistanceSquared = Infinity;
    let closestDatum;
    for (const mod of this.moduleMap.modules()) {
      const modPick = mod.pickNodeNearest(point);
      if (modPick !== void 0 && modPick.distanceSquared < minDistanceSquared) {
        minDistanceSquared = modPick.distanceSquared;
        closestDatum = modPick.datum;
      }
    }
    if (minDistanceSquared != null) {
      return { datum: closestDatum, distance: Math.sqrt(minDistanceSquared) };
    }
  }
  pickNodeClosestDatum(point) {
    let minDistance = Infinity;
    let closestDatum;
    const pick2 = this.pickNodeDataClosestDatum(point);
    if (pick2 != null && pick2.distance < minDistance) {
      minDistance = pick2.distance;
      closestDatum = pick2.datum;
    }
    const modPick = this.pickModulesClosestDatum(point);
    if (modPick != null && modPick.distance < minDistance) {
      minDistance = modPick.distance;
      closestDatum = modPick.datum;
    }
    if (closestDatum) {
      const distance2 = Math.max(minDistance - (closestDatum.point?.size ?? 0) / 2, 0);
      return { datum: closestDatum, distance: distance2 };
    }
  }
  pickNodeMainAxisFirst(point, requireCategoryAxis) {
    const { x, y } = point;
    const { axes, _contextNodeData: contextNodeData } = this;
    const { pickOutsideVisibleMinorAxis } = this.properties;
    if (!contextNodeData)
      return;
    const xAxis = axes["x" /* X */];
    const yAxis = axes["y" /* Y */];
    if (xAxis == null || yAxis == null)
      return;
    const directions2 = [xAxis, yAxis].filter((axis) => axis.isCategoryLike()).map((a) => a.direction);
    if (requireCategoryAxis && directions2.length === 0)
      return;
    const [majorDirection = "x" /* X */] = directions2;
    const hitPointCoords = [x, y];
    if (majorDirection !== "x" /* X */)
      hitPointCoords.reverse();
    const minDistance = [Infinity, Infinity];
    let closestDatum;
    for (const datum of contextNodeData.nodeData) {
      const { x: datumX = Number.NaN, y: datumY = Number.NaN } = datum.point ?? datum.midPoint ?? {};
      if (Number.isNaN(datumX) || Number.isNaN(datumY) || datum.missing === true)
        continue;
      const visible = [xAxis?.inRange(datumX, 1), yAxis?.inRange(datumY, 1)];
      if (majorDirection !== "x" /* X */) {
        visible.reverse();
      }
      if (!visible[0] || !pickOutsideVisibleMinorAxis && !visible[1])
        continue;
      const datumPoint = [datumX, datumY];
      if (majorDirection !== "x" /* X */) {
        datumPoint.reverse();
      }
      let newMinDistance = true;
      for (let i = 0; i < datumPoint.length; i++) {
        const dist = Math.abs(datumPoint[i] - hitPointCoords[i]);
        if (dist > minDistance[i]) {
          newMinDistance = false;
          break;
        } else if (dist < minDistance[i]) {
          minDistance[i] = dist;
          minDistance.fill(Infinity, i + 1, minDistance.length);
        }
      }
      if (newMinDistance) {
        closestDatum = datum;
      }
    }
    if (closestDatum) {
      let closestDistanceSquared = Math.max(
        minDistance[0] ** 2 + minDistance[1] ** 2 - (closestDatum.point?.size ?? 0),
        0
      );
      for (const mod of this.moduleMap.modules()) {
        const modPick = mod.pickNodeMainAxisFirst(point, majorDirection);
        if (modPick != null && modPick.distanceSquared < closestDistanceSquared) {
          closestDatum = modPick.datum;
          closestDistanceSquared = modPick.distanceSquared;
          break;
        }
      }
      return {
        datum: closestDatum,
        distance: Math.sqrt(closestDistanceSquared)
      };
    }
  }
  isPathOrSelectionDirty() {
    return false;
  }
  shouldFlipXY() {
    return false;
  }
  visibleRangeIndices(axisKey, visibleRange, indices, sortOrderParams) {
    let sortOrder;
    if (sortOrderParams == null) {
      const { processedData, dataModel } = this;
      sortOrder = dataModel.getColumnSortOrder(this, axisKey, processedData) ?? 1;
    } else {
      sortOrder = sortOrderParams.sortOrder;
    }
    const xValues = this.keysOrValues(axisKey);
    const pixelSize = 0;
    const [start2, end3] = visibleRangeIndices(
      sortOrder,
      indices?.length ?? xValues.length,
      visibleRange,
      (topIndex) => {
        const datumIndex = indices?.[topIndex] ?? topIndex;
        return this.xCoordinateRange(xValues[datumIndex], pixelSize, datumIndex);
      }
    );
    return start2 < end3 ? [start2, end3] : [end3, start2];
  }
  domainForVisibleRange(_direction, axisKeys, crossAxisKey, visibleRange, indices) {
    const { processedData, dataModel } = this;
    const [r0, r1] = visibleRange;
    const crossAxisValues = this.keysOrValues(crossAxisKey);
    const sortOrder = this.sortOrder(crossAxisKey);
    if (sortOrder != null) {
      const crossAxisRange = this.visibleRangeIndices(crossAxisKey, visibleRange, indices, { sortOrder });
      return dataModel.getDomainBetweenRange(this, axisKeys, crossAxisRange, processedData);
    }
    const allAxisValues = axisKeys.map((axisKey) => this.keysOrValues(axisKey));
    let axisMin = Infinity;
    let axisMax = -Infinity;
    for (const [i, crossAxisValue] of crossAxisValues.entries()) {
      const [x0, x1] = this.xCoordinateRange(crossAxisValue, 0, i);
      if (x1 < r0 || x0 > r1)
        continue;
      for (let j = 0; j < axisKeys.length; j++) {
        const axisValue = allAxisValues[j][i];
        axisMin = Math.min(axisMin, axisValue);
        axisMax = Math.max(axisMax, axisValue);
      }
    }
    return axisMin > axisMax ? [Number.NaN, Number.NaN] : [axisMin, axisMax];
  }
  domainForClippedRange(direction, axisKeys, crossAxisKey) {
    const { processedData, dataModel, axes } = this;
    const crossDirection = direction === "x" /* X */ ? "y" /* Y */ : "x" /* X */;
    const crossAxisRange = axisExtent(axes[crossDirection]);
    if (!crossAxisRange) {
      return axisKeys.flatMap((axisKey) => dataModel.getDomain(this, axisKey, "value", processedData).domain);
    }
    const crossAxisValues = this.keysOrValues(crossAxisKey);
    const sortOrder = dataModel.getColumnSortOrder(this, crossAxisKey, processedData);
    if (sortOrder != null) {
      const crossRange = clippedRangeIndices(
        sortOrder,
        crossAxisValues.length,
        crossAxisRange,
        (index) => crossAxisValues[index]
      );
      return dataModel.getDomainBetweenRange(this, axisKeys, crossRange, processedData);
    }
    const allAxisValues = axisKeys.map((axisKey) => this.keysOrValues(axisKey));
    const range0 = crossAxisRange[0].valueOf();
    const range1 = crossAxisRange[1].valueOf();
    const axisValues = [];
    for (const [i, crossAxisValue] of crossAxisValues.entries()) {
      const c = crossAxisValue.valueOf();
      if (c < range0 || c > range1)
        continue;
      const values = allAxisValues.map((v) => v[i]);
      if (c >= range0) {
        axisValues.push(...values);
      }
      if (c <= range1) {
        axisValues.push(...values);
      }
    }
    return axisValues;
  }
  zoomFittingVisibleItems(crossAxisKey, _axisKeys, xVisibleRange, yVisibleRange, minVisibleItems) {
    const { dataModel, processedData } = this;
    if (!dataModel || !processedData)
      return;
    const crossAxis = this.axes["x" /* X */];
    if (yVisibleRange != null)
      return;
    const sortOrder = this.sortOrder(crossAxisKey);
    if (sortOrder == null)
      return;
    const xValues = this.keysOrValues(crossAxisKey);
    if (minVisibleItems > xValues.length) {
      return { x: [0, 1], y: void 0 };
    }
    const crossScale = crossAxis.scale;
    const crossScaleRange = crossScale.range;
    crossScale.range = [0, 1];
    let [r0, r1] = this.visibleRangeIndices(crossAxisKey, xVisibleRange, void 0, { sortOrder });
    r1 -= 1;
    const pixelSize = 0;
    if (this.xCoordinateRange(xValues[r0], pixelSize, r0)[0] < xVisibleRange[0]) {
      r0 += 1;
    }
    if (this.xCoordinateRange(xValues[r1], pixelSize, r1)[1] > xVisibleRange[1]) {
      r1 -= 1;
    }
    let xZoom;
    if (Math.abs(r1 - r0) >= minVisibleItems - 1) {
      xZoom = xVisibleRange;
    } else {
      const midPoint = (xVisibleRange[0] + xVisibleRange[1]) / 2;
      while (Math.abs(r1 - r0) < minVisibleItems - 1 && (r0 > 0 || r1 < xValues.length - 1)) {
        if (r0 === 0) {
          r1 += 1;
        } else if (r1 === xValues.length - 1) {
          r0 -= 1;
        } else {
          const nextR0X = this.xCoordinateRange(xValues[r0 - 1], pixelSize, r0 - 1)[0];
          const nextR1X = this.xCoordinateRange(xValues[r1 + 1], pixelSize, r1 + 1)[1];
          if (Math.abs(nextR0X - midPoint) < Math.abs(nextR1X - midPoint)) {
            r0 -= 1;
          } else {
            r1 += 1;
          }
        }
      }
      const x0 = this.xCoordinateRange(xValues[r0], pixelSize, r0)[0];
      const x1 = this.xCoordinateRange(xValues[r1], pixelSize, r1)[1];
      xZoom = [Math.min(xVisibleRange[0], x0), Math.max(xVisibleRange[1], x1)];
    }
    crossScale.range = crossScaleRange;
    return { x: xZoom, y: void 0 };
  }
  countVisibleItems(crossAxisKey, axisKeys, xVisibleRange, yVisibleRange, minVisibleItems) {
    const { dataModel, processedData } = this;
    if (!dataModel || !processedData)
      return Infinity;
    const crossValues = this.keysOrValues(crossAxisKey);
    const allAxisValues = axisKeys.map((axisKey) => dataModel.resolveColumnById(this, axisKey, processedData));
    const shouldFlipXY = this.shouldFlipXY();
    const crossAxis = shouldFlipXY ? this.axes["y" /* Y */] : this.axes["x" /* X */];
    const axis = shouldFlipXY ? this.axes["x" /* X */] : this.axes["y" /* Y */];
    const crossVisibleRange = shouldFlipXY ? yVisibleRange ?? [0, 1] : xVisibleRange;
    const axisVisibleRange = shouldFlipXY ? xVisibleRange : yVisibleRange ?? [0, 1];
    if (yVisibleRange == null) {
      const sortOrder = this.sortOrder(crossAxisKey);
      if (sortOrder != null) {
        const crossScale = crossAxis.scale;
        const crossScaleRange = crossScale.range;
        crossScale.range = [0, 1];
        const xValues = this.keysOrValues(crossAxisKey);
        let [r0, r1] = this.visibleRangeIndices(crossAxisKey, crossVisibleRange, void 0, { sortOrder });
        r1 -= 1;
        if (r1 < r0)
          return 0;
        const pixelSize2 = 0;
        if (this.xCoordinateRange(xValues[r0], pixelSize2, r0)[0] < crossVisibleRange[0]) {
          r0 += 1;
        }
        if (this.xCoordinateRange(xValues[r1], pixelSize2, r1)[1] > crossVisibleRange[1]) {
          r1 -= 1;
        }
        const xItemsVisible = Math.abs(r1 - r0) + 1;
        crossScale.range = crossScaleRange;
        return xItemsVisible;
      }
    }
    const convert2 = (d, r, v) => {
      return d[0] + (v - r[0]) / (r[1] - r[0]) * (d[1] - d[0]);
    };
    const crossAxisRange = crossAxis.range.toSorted();
    const axisRange = axis.range.toSorted();
    const crossMin = convert2(crossAxisRange, crossAxis.visibleRange, crossVisibleRange[0]);
    const crossMax = convert2(crossAxisRange, crossAxis.visibleRange, crossVisibleRange[1]);
    const axisMin = convert2(axisRange, axis.visibleRange, Math.min(...axisVisibleRange));
    const axisMax = convert2(axisRange, axis.visibleRange, Math.max(...axisVisibleRange));
    const startIndex = Math.round(
      (crossVisibleRange[0] + (crossVisibleRange[1] - crossVisibleRange[0]) / 2) * crossValues.length
    );
    const pixelSize = 0;
    return countExpandingSearch(0, crossValues.length - 1, startIndex, minVisibleItems, (index) => {
      const [cross0, cross1] = this.xCoordinateRange(crossValues[index], pixelSize, index);
      const [axis0, axis1] = this.yCoordinateRange(
        allAxisValues.map((axisValues) => axisValues[index]),
        pixelSize,
        index
      );
      if (!isFiniteNumber(cross0) || !isFiniteNumber(cross1) || !isFiniteNumber(axis0) || !isFiniteNumber(axis1)) {
        return false;
      }
      return cross0 >= crossMin && cross1 <= crossMax && axis0 >= axisMin && axis1 <= axisMax;
    });
  }
  // @todo(AG-13777) - Remove this function.
  // We need data model updates to know if a data set is sorted & unique - and at the same time
  // it should generate the equivalent of `SMALLEST_KEY_INTERVAL`. We'll use that value here
  minTimeInterval() {
    let xValues;
    try {
      xValues = this.keysOrValues("xValue");
    } catch {
    }
    if (xValues == null || xValues.length > 1e3)
      return;
    let minInterval = Infinity;
    let x0 = xValues[0];
    let sortOrder;
    for (let i = 1; i < xValues.length; i++) {
      const x1 = xValues[i];
      if (x1 != null && x0 != null) {
        const interval = x1.valueOf() - x0.valueOf();
        const sign = Math.sign(interval);
        if (sign === 0)
          continue;
        if (sortOrder !== void 0 && sign !== sortOrder)
          return;
        minInterval = Math.min(minInterval, Math.abs(interval));
        sortOrder = sign;
      }
      x0 = x1;
    }
    if (Number.isFinite(minInterval))
      return minInterval;
  }
  updateHighlightSelectionItem(opts) {
    const { items, highlightSelection } = opts;
    const nodeData = items ?? [];
    return this.updateDatumSelection({
      nodeData,
      datumSelection: highlightSelection
    });
  }
  updateDatumSelection(opts) {
    return opts.datumSelection;
  }
  updateDatumNodes(_opts) {
  }
  updateDatumStyles(_opts) {
  }
  updatePaths(opts) {
    for (const p of opts.paths) {
      p.visible = false;
    }
  }
  updatePathNodes(opts) {
    const { paths, visible } = opts;
    for (const path of paths) {
      path.visible = visible;
    }
  }
  resetPathAnimation(data) {
    const { path } = this.opts?.animationResetFns ?? {};
    if (path) {
      for (const paths of data.paths) {
        resetMotion([paths], path);
      }
    }
  }
  resetDatumAnimation(data) {
    const { datum } = this.opts?.animationResetFns ?? {};
    if (datum) {
      resetMotion([data.datumSelection], datum);
    }
  }
  resetLabelAnimation(data) {
    const { label } = this.opts?.animationResetFns ?? {};
    if (label) {
      resetMotion([data.labelSelection], label);
    }
  }
  resetAllAnimation(data) {
    this.ctx.animationManager.stopByAnimationGroupId(this.id);
    this.resetPathAnimation(data);
    this.resetDatumAnimation(data);
    this.resetLabelAnimation(data);
    if (data.contextData?.animationValid === false) {
      this.ctx.animationManager.skipCurrentBatch();
    }
  }
  animateEmptyUpdateReady(data) {
    this.ctx.animationManager.skipCurrentBatch();
    this.resetAllAnimation(data);
  }
  animateWaitingUpdateReady(data) {
    this.ctx.animationManager.skipCurrentBatch();
    this.resetAllAnimation(data);
  }
  animateReadyHighlight(data) {
    const { datum } = this.opts?.animationResetFns ?? {};
    if (datum) {
      resetMotion([data], datum);
    }
  }
  animateReadyResize(data) {
    this.resetAllAnimation(data);
  }
  animateClearingUpdateEmpty(data) {
    this.ctx.animationManager.skipCurrentBatch();
    this.resetAllAnimation(data);
  }
  getAnimationData(seriesRect, previousContextData) {
    const { _contextNodeData: contextData } = this;
    if (!contextData)
      return;
    const animationData = {
      datumSelection: this.datumSelection,
      labelSelection: this.labelSelection,
      annotationSelections: [...this.annotationSelections],
      contextData,
      previousContextData,
      paths: this.paths,
      seriesRect
    };
    return animationData;
  }
  updateLabelSelection(opts) {
    return opts.labelSelection;
  }
  getScaling(scale2) {
    if (scale2 instanceof LogScale) {
      const { range: range3, domain } = scale2;
      return {
        type: "log",
        convert: (d) => scale2.convert(d),
        domain: [domain[0], domain[1]],
        range: [range3[0], range3[1]]
      };
    } else if (scale2 instanceof ContinuousScale) {
      const { range: range3, domain } = scale2;
      return {
        type: "continuous",
        domain: [domain[0], domain[1]],
        range: [range3[0], range3[1]]
      };
    } else if (scale2 instanceof BandScale) {
      if (scale2 instanceof UnitTimeScale) {
        const linearParams = scale2.getLinearParams();
        const bandCount = scale2.getBandCountForUpdate();
        if (linearParams != null && bandCount > 0) {
          return {
            type: "category",
            variant: "unit-time",
            firstBandTime: linearParams.firstBandTime,
            lastBandTime: linearParams.firstBandTime + (bandCount - 1) * linearParams.intervalMs,
            bandCount,
            intervalMs: linearParams.intervalMs,
            inset: scale2.inset,
            step: scale2.step
          };
        }
      }
      return {
        type: "category",
        domain: scale2.domain,
        inset: scale2.inset,
        step: scale2.step
      };
    }
  }
  calculateScaling() {
    const result = {};
    for (const direction of Object.values(ChartAxisDirection)) {
      const axis = this.axes[direction];
      if (!axis)
        continue;
      const scalingResult = this.getScaling(axis.scale);
      if (scalingResult != null) {
        result[direction] = scalingResult;
      }
    }
    return result;
  }
};
function axisExtent(axis) {
  let min;
  let max;
  if (axis instanceof NumberAxis || axis instanceof TimeAxis) {
    ({ min, max } = axis);
  }
  if (min == null && max == null)
    return;
  min ?? (min = -Infinity);
  max ?? (max = Infinity);
  return [min, max];
}
function clippedRangeIndices(sortOrder, length2, range3, xValue) {
  const range0 = range3[0].valueOf();
  const range1 = range3[1].valueOf();
  let xMinIndex = findMinIndex(0, length2 - 1, (i) => {
    const index = sortOrder === 1 ? i : length2 - i;
    const x = xValue(index)?.valueOf();
    return !Number.isFinite(x) || x >= range0;
  });
  let xMaxIndex = findMaxIndex(0, length2 - 1, (i) => {
    const index = sortOrder === 1 ? i : length2 - i;
    const x = xValue(index)?.valueOf();
    return !Number.isFinite(x) || x <= range1;
  });
  if (xMinIndex == null || xMaxIndex == null)
    return [0, 0];
  if (sortOrder === -1) {
    [xMinIndex, xMaxIndex] = [length2 - xMaxIndex, length2 - xMinIndex];
  }
  xMinIndex = Math.max(xMinIndex, 0);
  xMaxIndex = Math.min(xMaxIndex + 1, length2);
  return [xMinIndex, xMaxIndex];
}

// packages/ag-charts-community/src/chart/cartesianUtil.ts
function stackCartesianSeries(series) {
  const seriesGroups = /* @__PURE__ */ new Map();
  for (const s of series) {
    if (!(s instanceof CartesianSeries))
      continue;
    const stackCount = s.seriesGrouping?.stackCount ?? 0;
    const groupIndex = stackCount > 0 ? s.seriesGrouping?.groupIndex : void 0;
    if (groupIndex == null) {
      s.seriesBelowStackContext = void 0;
      s.createStackContext();
      continue;
    }
    const groupKey = `${s.type}-${groupIndex}`;
    let group = seriesGroups.get(groupKey);
    if (group == null) {
      group = [];
      seriesGroups.set(groupKey, group);
    }
    group.push(s);
  }
  for (const group of seriesGroups.values()) {
    group.sort((a, b) => (a.seriesGrouping?.stackIndex ?? 0) - (b.seriesGrouping?.stackIndex ?? 0));
    let seriesBelowStackContext;
    for (const s of group) {
      s.seriesBelowStackContext = seriesBelowStackContext;
      seriesBelowStackContext = s.createStackContext();
    }
  }
}

// packages/ag-charts-community/src/chart/labelUtil.ts
function getLabelStyles(series, nodeDatum, params, label, isHighlight, activeHighlight, labelPath = ["series", `${series.declarationOrder}`, "label"]) {
  if (series.visible && label.itemStyler) {
    const highlightState = series.getHighlightStateString(
      activeHighlight,
      isHighlight || nodeDatum != null && activeHighlight?.series === nodeDatum.series && activeHighlight?.datumIndex === nodeDatum.datumIndex,
      nodeDatum?.datumIndex
    );
    const itemId = typeof nodeDatum?.datumIndex === "number" ? nodeDatum.datumIndex : nodeDatum?.itemId;
    const styleParams = {
      border: label.border,
      color: label.color,
      cornerRadius: label.cornerRadius,
      datum: nodeDatum?.datum,
      enabled: label.enabled,
      fill: label.fill,
      fillOpacity: label.fillOpacity,
      fontFamily: label.fontFamily,
      fontSize: label.fontSize,
      fontStyle: label.fontStyle,
      fontWeight: label.fontWeight,
      itemId,
      itemType: nodeDatum?.itemType,
      seriesId: series.id,
      padding: label.padding,
      highlightState
    };
    const stylerResult = series.ctx.optionsGraphService.resolvePartial(
      labelPath,
      series.cachedCallWithContext(label.itemStyler, { ...params, ...styleParams }),
      { pick: false }
    ) ?? {};
    return mergeDefaults(stylerResult, styleParams);
  }
  return label;
}
function updateLabelNode(series, textNode, params, label, labelDatum, isHighlight, activeHighlight) {
  if (series.visible && label.enabled && labelDatum) {
    const style2 = getLabelStyles(series, textNode.datum, params, label, isHighlight, activeHighlight);
    textNode.visible = true;
    textNode.x = labelDatum.x;
    textNode.y = labelDatum.y;
    textNode.text = labelDatum.text;
    textNode.fill = style2.color;
    textNode.setAlign(labelDatum);
    textNode.setFont(style2);
    textNode.setBoxing(style2);
  } else {
    textNode.visible = false;
  }
}
var placements = {
  "inside-start": { inside: true, direction: -1, textAlignment: 1 },
  "inside-end": { inside: true, direction: 1, textAlignment: -1 },
  "outside-start": { inside: false, direction: -1, textAlignment: -1 },
  "outside-end": { inside: false, direction: 1, textAlignment: 1 }
};
function adjustLabelPlacement({
  isUpward,
  isVertical,
  placement,
  spacing = 0,
  rect: rect2
}) {
  let x = rect2.x + rect2.width / 2;
  let y = rect2.y + rect2.height / 2;
  let textAlign = "center";
  let textBaseline = "middle";
  if (placement !== "inside-center") {
    const barDirection = (isUpward ? 1 : -1) * (isVertical ? -1 : 1);
    const { direction, textAlignment } = placements[placement];
    const displacementRatio = (direction + 1) * 0.5;
    if (isVertical) {
      const y0 = isUpward ? rect2.y + rect2.height : rect2.y;
      const height2 = rect2.height * barDirection;
      y = y0 + height2 * displacementRatio + spacing * textAlignment * barDirection;
      textBaseline = textAlignment === barDirection ? "top" : "bottom";
    } else {
      const x0 = isUpward ? rect2.x : rect2.x + rect2.width;
      const width2 = rect2.width * barDirection;
      x = x0 + width2 * displacementRatio + spacing * textAlignment * barDirection;
      textAlign = textAlignment === barDirection ? "left" : "right";
    }
  }
  return { x, y, textAlign, textBaseline };
}

// packages/ag-charts-community/src/chart/series/seriesLabelUtil.ts
function seriesLabelFadeInAnimation({ id }, subId, animationManager, ...labelSelections) {
  for (const labelSelection of labelSelections) {
    labelSelection.cleanup();
  }
  staticFromToMotion(
    id,
    subId,
    animationManager,
    labelSelections,
    { opacity: 0 },
    { opacity: 1 },
    { phase: "trailing" }
  );
}
function seriesLabelFadeOutAnimation({ id }, subId, animationManager, ...labelSelections) {
  staticFromToMotion(
    id,
    subId,
    animationManager,
    labelSelections,
    { opacity: 1 },
    { opacity: 0 },
    { phase: "remove" }
  );
}
function resetLabelFn(_node) {
  return { opacity: 1 };
}

// packages/ag-charts-community/src/chart/series/seriesMarker.ts
var SeriesMarker = class extends ChangeDetectableProperties {
  constructor() {
    super(...arguments);
    this.enabled = true;
    this.shape = "circle";
    this.size = 0;
    this.fillOpacity = 1;
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
  }
  getStyle() {
    const { size, shape, fill, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this;
    return {
      size,
      shape,
      fill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset
    };
  }
  getDiameter() {
    return this.size + this.strokeWidth;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], SeriesMarker.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneObjectChangeDetection({ equals: TRIPLE_EQ })
], SeriesMarker.prototype, "shape", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], SeriesMarker.prototype, "size", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneObjectChangeDetection({ equals: objectsEqual })
], SeriesMarker.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], SeriesMarker.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], SeriesMarker.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], SeriesMarker.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], SeriesMarker.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesMarker.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesMarker.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneObjectChangeDetection({ equals: TRIPLE_EQ })
], SeriesMarker.prototype, "itemStyler", 2);

// packages/ag-charts-community/src/chart/series/seriesTooltip.ts
function buildLineWithMarkerDefaults(line, marker) {
  if (line == null)
    return void 0;
  return {
    enabled: line.enabled ?? true,
    stroke: line.stroke ?? marker?.stroke ?? "transparent",
    strokeWidth: line.strokeWidth ?? marker?.strokeWidth ?? 1,
    strokeOpacity: line.strokeOpacity ?? marker?.strokeOpacity ?? 1,
    lineDash: line.lineDash ?? marker?.lineDash ?? []
  };
}
var SeriesTooltipInteraction = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = false;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesTooltipInteraction.prototype, "enabled", 2);
var SeriesTooltip = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.interaction = new SeriesTooltipInteraction();
    this.position = new TooltipPosition();
    this.range = void 0;
    this.class = void 0;
  }
  formatTooltip(callers, content, params) {
    const overrides = this.renderer == null ? void 0 : callWithContext(callers, this.renderer, params);
    if (isString(overrides) || isNumber(overrides) || isDate(overrides)) {
      return { type: "raw", rawHtmlString: toTextString(overrides) };
    }
    if (overrides != null) {
      const mergedMarker = mergeDefaults(overrides.symbol?.marker, content.symbol?.marker);
      const mergedLineInput = overrides.symbol?.line ?? content.symbol?.line ? mergeDefaults(overrides.symbol?.line, content.symbol?.line) : void 0;
      const symbol = content.symbol || overrides.symbol ? {
        marker: mergedMarker,
        line: buildLineWithMarkerDefaults(mergedLineInput, mergedMarker)
      } : void 0;
      return { type: "structured", ...content, ...overrides, symbol };
    }
    return { type: "structured", ...content };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesTooltip.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesTooltip.prototype, "showArrow", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesTooltip.prototype, "renderer", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesTooltip.prototype, "interaction", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesTooltip.prototype, "position", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesTooltip.prototype, "range", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SeriesTooltip.prototype, "class", 2);
function makeSeriesTooltip() {
  return new SeriesTooltip();
}

// packages/ag-charts-community/src/chart/axis/categoryAxis.ts
var _CategoryAxis = class _CategoryAxis extends CartesianAxis {
  constructor(moduleCtx, scale2 = new CategoryScale(), includeInvisibleDomains = true) {
    super(moduleCtx, scale2);
    this.groupPaddingInner = 0.1;
    this.includeInvisibleDomains = includeInvisibleDomains;
    this.nice = false;
  }
  static is(value) {
    return value instanceof _CategoryAxis;
  }
  isCategoryLike() {
    return true;
  }
  hasDefinedDomain() {
    return false;
  }
  normaliseDataDomain(d) {
    return { domain: d.domain, clipped: false };
  }
  getUpdateTypeOnResize() {
    if (this.bandAlignment == null || this.bandAlignment === "justify") {
      return super.getUpdateTypeOnResize();
    }
    return 3 /* PROCESS_DOMAIN */;
  }
  updateScale() {
    super.updateScale();
    let { paddingInner, paddingOuter } = this;
    if (!isFiniteNumber(paddingInner) || !isFiniteNumber(paddingOuter)) {
      const padding2 = this.reduceBandScalePadding();
      paddingInner ?? (paddingInner = padding2.inner);
      paddingOuter ?? (paddingOuter = padding2.outer);
    }
    this.scale.paddingInner = paddingInner ?? 0;
    this.scale.paddingOuter = paddingOuter ?? 0;
  }
  calculateGridLines(ticks, p1, p2) {
    const gridLines = super.calculateGridLines(ticks, p1, p2);
    if (this.interval.placement === "between" && ticks.length > 0) {
      gridLines.push(
        super.calculateGridLine(
          {
            index: ticks.at(-1).index + 1,
            tickId: `after:${ticks.at(-1).tickId}`,
            translation: this.range[1]
          },
          ticks.length,
          p1,
          p2,
          ticks
        )
      );
    }
    return gridLines;
  }
  calculateGridLine({ index: tickIndex, tickId, translation }, index, p1, p2, ticks) {
    const { gridLine, horizontal, interval, scale: scale2 } = this;
    if (interval.placement !== "between") {
      return super.calculateGridLine({ index: tickIndex, tickId, translation }, index, p1, p2, ticks);
    }
    const halfStep = translation < scale2.step ? Math.floor(scale2.step / 2) : scale2.step / 2;
    const offset = translation - halfStep;
    const [x1, y1, x2, y2] = horizontal ? [offset, Math.max(p1, p2), offset, Math.min(p1, p2)] : [Math.min(p1, p2), offset, Math.max(p1, p2), offset];
    const { style: style2 } = gridLine;
    const { stroke: stroke3, strokeWidth = 0, lineDash } = style2[tickIndex % style2.length] ?? {};
    return { tickId, offset, x1, y1, x2, y2, stroke: stroke3, strokeWidth, lineDash };
  }
  calculateGridFills(ticks, p1, p2) {
    const { horizontal, range: range3, scale: scale2 } = this;
    if (this.interval.placement !== "between") {
      return super.calculateGridFills(ticks, p1, p2);
    }
    const gridFills = [];
    if (ticks.length == 0)
      return gridFills;
    const firstTick = ticks[0];
    const firstFillOffCanvas = firstTick.translation > range3[0] + scale2.step / 2;
    const lastTick = ticks.at(-1);
    const lastFillOffCanvas = horizontal && lastTick.translation < range3[1] - scale2.step / 2;
    if (firstFillOffCanvas) {
      const tick = { tickId: `before:${firstTick.tickId}`, translation: firstTick.translation - scale2.step };
      gridFills.push(this.calculateGridFill(tick, -1, firstTick.index - 1, p1, p2, ticks));
    }
    gridFills.push(...ticks.map((tick, index) => this.calculateGridFill(tick, index, tick.index, p1, p2, ticks)));
    if (lastFillOffCanvas) {
      const tick = { tickId: `after:${lastTick.tickId}`, translation: lastTick.translation + scale2.step };
      gridFills.push(this.calculateGridFill(tick, ticks.length, lastTick.index + 1, p1, p2, ticks));
    }
    return gridFills;
  }
  calculateGridFill({ tickId, translation }, index, gridFillIndex, p1, p2, ticks) {
    const { gridLine, horizontal, interval, scale: scale2 } = this;
    if (interval.placement !== "between") {
      return super.calculateGridFill({ tickId, translation }, index, gridFillIndex, p1, p2, ticks);
    }
    const startOffset = translation - scale2.step / 2;
    const endOffset = translation + scale2.step / 2;
    const [x1, y1, x2, y2] = horizontal ? [startOffset, Math.max(p1, p2), endOffset, Math.min(p1, p2)] : [Math.min(p1, p2), startOffset, Math.max(p1, p2), endOffset];
    const { fill, fillOpacity } = gridLine.style[gridFillIndex % gridLine.style.length] ?? {};
    return { tickId, x1, y1, x2, y2, fill, fillOpacity };
  }
  calculateTickLines(ticks, direction, scrollbarThickness = 0) {
    const tickLines = super.calculateTickLines(ticks, direction, scrollbarThickness);
    if (this.interval.placement === "between" && ticks.length > 0) {
      tickLines.push(
        super.calculateTickLine(
          { isPrimary: false, tickId: `after:${ticks.at(-1)?.tickId}`, translation: this.range[1] },
          ticks.length,
          direction,
          ticks,
          scrollbarThickness
        )
      );
    }
    return tickLines;
  }
  calculateTickLine({ isPrimary, tickId, translation }, index, direction, ticks, scrollbarThickness = 0) {
    const { horizontal, interval, primaryTick, scale: scale2, tick } = this;
    if (interval.placement !== "between") {
      return super.calculateTickLine(
        { isPrimary, tickId, translation },
        index,
        direction,
        ticks,
        scrollbarThickness
      );
    }
    const datumTick = isPrimary && primaryTick?.enabled ? primaryTick : tick;
    const h = -direction * this.getTickSize(datumTick);
    const halfStep = translation < scale2.step ? Math.floor(scale2.step / 2) : scale2.step / 2;
    const offset = translation - halfStep;
    const tickOffset = -direction * (scrollbarThickness + this.getTickSpacing(datumTick));
    const [x1, y1, x2, y2] = horizontal ? [offset, tickOffset, offset, tickOffset + h] : [tickOffset, offset, tickOffset + h, offset];
    const { stroke: stroke3, width: strokeWidth } = datumTick;
    const lineDash = void 0;
    return { tickId, offset, x1, y1, x2, y2, stroke: stroke3, strokeWidth, lineDash };
  }
  reduceBandScalePadding() {
    return this.boundSeries.reduce(
      (result, series) => {
        const padding2 = series.getBandScalePadding?.();
        if (padding2) {
          if (result.inner > padding2.inner) {
            result.inner = padding2.inner;
          }
          if (result.outer < padding2.outer) {
            result.outer = padding2.outer;
          }
        }
        return result;
      },
      { inner: Infinity, outer: -Infinity }
    );
  }
  tickFormatParams(_domain, _ticks, _fractionDigits, _timeInterval) {
    return { type: "category" };
  }
  datumFormatParams(value, params, _fractionDigits, _timeInterval, _style) {
    const { datum, seriesId, legendItemName, key, source, property, domain, boundSeries } = params;
    if (Array.isArray(value) && value.some((v) => typeof v !== "string")) {
      value = value.map(String);
    }
    return { type: "category", value, datum, seriesId, legendItemName, key, source, property, domain, boundSeries };
  }
};
_CategoryAxis.className = "CategoryAxis";
_CategoryAxis.type = "category";
__decorateClass([
  addFakeTransformToInstanceProperty
], _CategoryAxis.prototype, "groupPaddingInner", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], _CategoryAxis.prototype, "paddingInner", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], _CategoryAxis.prototype, "paddingOuter", 2);
__decorateClass([
  ProxyPropertyOnWrite("layoutConstraints", "align")
], _CategoryAxis.prototype, "bandAlignment", 2);
__decorateClass([
  ActionOnSet({
    newValue(value) {
      if (value == null || value <= 0) {
        this.layoutConstraints.width = 100;
        this.layoutConstraints.unit = "percent";
      } else {
        this.layoutConstraints.width = value;
        this.layoutConstraints.unit = "px";
        this.animationManager.skipCurrentBatch();
      }
    }
  })
], _CategoryAxis.prototype, "requiredRange", 2);
var CategoryAxis = _CategoryAxis;

// packages/ag-charts-community/src/scale/groupedCategoryScale.ts
var MAX_ANIMATABLE_NODES2 = 1e3;
var GroupedCategoryScale = class _GroupedCategoryScale extends CategoryScale {
  constructor() {
    super(...arguments);
    this.previousDomainJson = void 0;
    /** Whether the current domain update is animatable (initial load or no domain change). */
    this.animatable = true;
  }
  static is(value) {
    return value instanceof _GroupedCategoryScale;
  }
  set domain(values) {
    if (values.length <= MAX_ANIMATABLE_NODES2) {
      const currentDomainJson = JSON.stringify(values);
      this.animatable = this.previousDomainJson === void 0 || this.previousDomainJson === currentDomainJson;
      this.previousDomainJson = currentDomainJson;
    } else {
      this.animatable = this.previousDomainJson === void 0;
      this.previousDomainJson = "";
    }
    super.domain = values;
  }
  get domain() {
    return super.domain;
  }
  normalizeDomains(...domains) {
    const { domain } = super.normalizeDomains(...domains);
    return { domain, animatable: false };
  }
  findIndex(value) {
    return super.findIndex(value) ?? this.getMatchIndex(value);
  }
  getMatchIndex(value) {
    const key = JSON.stringify(value);
    const match = this._domain.find((d) => JSON.stringify(d) === key);
    if (match != null) {
      return super.findIndex(match);
    }
  }
};

// packages/ag-charts-community/src/chart/axis/tree.ts
var Dimensions = class {
  constructor() {
    this.top = Infinity;
    this.right = -Infinity;
    this.bottom = -Infinity;
    this.left = Infinity;
  }
  update(x, y) {
    if (x > this.right) {
      this.right = x;
    }
    if (x < this.left) {
      this.left = x;
    }
    if (y > this.bottom) {
      this.bottom = y;
    }
    if (y < this.top) {
      this.top = y;
    }
  }
};
var TreeNode = class _TreeNode {
  constructor(label = "", parent, refId) {
    this.label = label;
    this.parent = parent;
    this.refId = refId;
    this.position = 0;
    this.subtreeLeft = Number.NaN;
    this.subtreeRight = Number.NaN;
    this.children = [];
    this.leafCount = 0;
    this.prelim = 0;
    this.mod = 0;
    this.ancestor = this;
    this.change = 0;
    this.shift = 0;
    this.index = 0;
    // screen is meant to be recomputed from (layout) when the tree is resized (without performing another layout)
    this.screen = 0;
    this.depth = parent ? parent.depth + 1 : 0;
  }
  insertTick(tick, index) {
    let current = this;
    let endNode;
    for (let i = 0; i < tick.length; i++) {
      const pathPart = tick[i];
      const isNotLeaf = i !== tick.length - 1;
      const { children } = current;
      const existingNode = children.find((child) => child.label === pathPart);
      if (existingNode && isNotLeaf) {
        current = existingNode;
        endNode = existingNode;
      } else {
        const node = new _TreeNode(pathPart, current, index);
        node.index = children.length;
        children.push(node);
        if (isNotLeaf) {
          current = node;
        }
        endNode = node;
      }
    }
    return endNode;
  }
  getLeftSibling() {
    return this.index > 0 ? this.parent?.children[this.index - 1] : void 0;
  }
  getLeftmostSibling() {
    return this.index > 0 ? this.parent?.children[0] : void 0;
  }
  // traverse the left contour of a subtree, return the successor of v on this contour
  nextLeft() {
    return this.children[0];
  }
  // traverse the right contour of a subtree, return the successor of v on this contour
  nextRight() {
    return this.children.at(-1);
  }
  getSiblings() {
    return this.parent?.children.filter((_, i) => i !== this.index) ?? [];
  }
};
function ticksToTree(ticks) {
  const maxDepth = ticks.reduce((depth, tick) => Math.max(depth, tick.length), 0);
  const root = new TreeNode();
  const tickNodes = /* @__PURE__ */ new Map();
  for (let i = 0; i < ticks.length; i++) {
    const tick = ticks[i];
    while (tick.length < maxDepth) {
      tick.push("");
    }
    const node = root.insertTick(tick, i);
    if (node != null) {
      tickNodes.set(tick, node);
    }
  }
  return { root, tickNodes };
}
function moveSubtree(wm, wp, shift) {
  const subtrees = wp.index - wm.index;
  const ratio2 = shift / subtrees;
  wp.change -= ratio2;
  wp.shift += shift;
  wm.change += ratio2;
  wp.prelim += shift;
  wp.mod += shift;
}
function ancestor(vim, v, defaultAncestor) {
  return v.getSiblings().includes(vim.ancestor) ? vim.ancestor : defaultAncestor;
}
function executeShifts({ children }) {
  let shift = 0;
  let change = 0;
  for (let i = children.length - 1; i >= 0; i--) {
    const w = children[i];
    w.prelim += shift;
    w.mod += shift;
    change += w.change;
    shift += w.shift + change;
  }
}
function apportion(v, defaultAncestor) {
  const w = v.getLeftSibling();
  if (w) {
    let vop = v;
    let vip = v;
    let vim = w;
    let vom = vip.getLeftmostSibling();
    let sip = vip.mod;
    let sop = vop.mod;
    let sim = vim.mod;
    let som = vom.mod;
    while (vim.nextRight() && vip.nextLeft()) {
      vim = vim.nextRight();
      vip = vip.nextLeft();
      vom = vom.nextLeft();
      vop = vop.nextRight();
      vop.ancestor = v;
      const shift = vim.prelim + sim - (vip.prelim + sip) + 1;
      if (shift > 0) {
        moveSubtree(ancestor(vim, v, defaultAncestor), v, shift);
        sip += shift;
        sop += shift;
      }
      sim += vim.mod;
      sip += vip.mod;
      som += vom.mod;
      sop += vop.mod;
    }
    if (vim.nextRight() && !vop.nextRight()) {
      vop.mod += sim - sop;
    } else {
      if (vip.nextLeft() && !vom.nextLeft()) {
        vom.mod += sip - som;
      }
      defaultAncestor = v;
    }
  }
  return defaultAncestor;
}
function firstWalk(node) {
  const { children } = node;
  if (children.length) {
    let [defaultAncestor] = children;
    for (const child of children) {
      firstWalk(child);
      defaultAncestor = apportion(child, defaultAncestor);
    }
    executeShifts(node);
    const midpoint = (children[0].prelim + children.at(-1).prelim) / 2;
    const leftSibling = node.getLeftSibling();
    if (leftSibling) {
      node.prelim = leftSibling.prelim + 1;
      node.mod = node.prelim - midpoint;
    } else {
      node.prelim = midpoint;
    }
  } else {
    const leftSibling = node.getLeftSibling();
    node.prelim = leftSibling ? leftSibling.prelim + 1 : 0;
  }
}
function secondWalk(v, m, layout) {
  v.position = v.prelim + m;
  layout.insertNode(v);
  for (const w of v.children) {
    secondWalk(w, m + v.mod, layout);
  }
}
function thirdWalk(v) {
  const { children } = v;
  let leafCount = 0;
  for (const w of children) {
    thirdWalk(w);
    if (w.children.length) {
      leafCount += w.leafCount;
    } else {
      leafCount++;
    }
  }
  v.leafCount = leafCount;
  if (children.length) {
    v.subtreeLeft = children[0].subtreeLeft;
    v.subtreeRight = children.at(-1).subtreeRight;
    v.position = (v.subtreeLeft + v.subtreeRight) / 2;
  } else {
    v.subtreeLeft = v.position;
    v.subtreeRight = v.position;
  }
}
function treeLayout(ticks) {
  const layout = new TreeLayout();
  const { root, tickNodes } = ticksToTree(ticks);
  firstWalk(root);
  secondWalk(root, -root.prelim, layout);
  thirdWalk(root);
  return { layout, tickNodes };
}
var TreeLayout = class {
  constructor() {
    this.dimensions = new Dimensions();
    this.nodes = [];
    this.depth = 0;
  }
  insertNode(node) {
    if (this.depth < node.depth) {
      this.depth = node.depth;
    }
    this.dimensions.update(node.position, node.depth);
    this.nodes.push(node);
  }
  scaling(extent2, flip) {
    let scaling = 1;
    if (extent2 > 0) {
      const { left, right } = this.dimensions;
      if (right !== left) {
        scaling = extent2 / (right - left);
      }
    }
    if (flip) {
      scaling *= -1;
    }
    return scaling;
  }
};

// packages/ag-charts-community/src/chart/axis/groupedCategoryAxis.ts
var MIN_CATEGORY_SPACING = 5;
var DepthLabelProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = true;
    this.border = new LabelBorder();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthLabelProperties.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthLabelProperties.prototype, "avoidCollisions", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthLabelProperties.prototype, "border", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthLabelProperties.prototype, "color", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthLabelProperties.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthLabelProperties.prototype, "spacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthLabelProperties.prototype, "rotation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthLabelProperties.prototype, "wrapping", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthLabelProperties.prototype, "truncate", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthLabelProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthLabelProperties.prototype, "fontStyle", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthLabelProperties.prototype, "fontWeight", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthLabelProperties.prototype, "fontSize", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthLabelProperties.prototype, "fontFamily", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthLabelProperties.prototype, "padding", 2);
var DepthTickProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = true;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthTickProperties.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthTickProperties.prototype, "width", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthTickProperties.prototype, "stroke", 2);
var DepthProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.label = new DepthLabelProperties();
    this.tick = new DepthTickProperties();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DepthProperties.prototype, "tick", 2);
var GroupedCategoryAxis = class extends CategoryAxis {
  constructor(moduleCtx) {
    super(moduleCtx, new GroupedCategoryScale());
    // Label scale (labels are positioned between ticks, tick count = label count + 1).
    // We don't call is `labelScale` for consistency with other axes.
    this.tickScale = new GroupedCategoryScale();
    this.computedLayout = void 0;
    this.tickTreeLayout = void 0;
    this.tickNodes = void 0;
    this.depthOptions = new PropertiesArray(DepthProperties);
    this.includeInvisibleDomains = true;
    this.tickScale.paddingInner = 1;
    this.tickScale.paddingOuter = 0;
  }
  resizeTickTree() {
    if (!this.tickTreeLayout)
      return;
    const { nodes } = this.tickTreeLayout;
    const { range: range3, step, inset, bandwidth } = this.scale;
    const width2 = Math.abs(range3[1] - range3[0]) - step;
    const scaling = this.tickTreeLayout.scaling(width2, range3[0] > range3[1]);
    const shift = inset + bandwidth / 2;
    let offset = 0;
    for (const node of nodes) {
      const screen = node.position * scaling;
      if (offset > screen) {
        offset = screen;
      }
      node.screen = screen + shift;
    }
    for (const node of nodes) {
      node.screen -= offset;
    }
  }
  getDepthOptionsMap(maxDepth) {
    const optionsMap = [];
    const { depthOptions, label } = this;
    const defaultNonLeafRotation = this.horizontal ? 0 : -90;
    for (let i = 0; i < maxDepth; i++) {
      optionsMap.push(
        depthOptions[i]?.label.enabled ?? label.enabled ? {
          enabled: true,
          spacing: depthOptions[i]?.label.spacing ?? label.spacing,
          wrapping: depthOptions[i]?.label.wrapping ?? label.wrapping,
          truncate: depthOptions[i]?.label.truncate ?? label.truncate,
          rotation: depthOptions[i]?.label.rotation ?? (i ? defaultNonLeafRotation : label.rotation),
          // Default top-level label rotation only applies to label leaves
          avoidCollisions: depthOptions[i]?.label.avoidCollisions ?? label.avoidCollisions
        } : { enabled: false, spacing: 0, rotation: 0, avoidCollisions: false }
      );
    }
    return optionsMap;
  }
  updateCategoryLabels() {
    if (!this.computedLayout)
      return;
    this.tickLabelGroupSelection.update(this.computedLayout.tickLabelLayout).each((node, datum) => {
      node.fill = datum.color;
      node.text = datum.text;
      node.textBaseline = datum.textBaseline;
      node.textAlign = datum.textAlign ?? "center";
      node.pointerEvents = datum.textUntruncated == null ? 1 /* None */ : 0 /* All */;
      node.setFont(datum);
      node.setBoxing(datum);
    });
  }
  updateAxisLine() {
    if (!this.computedLayout)
      return;
    this.lineNode.visible = this.line.enabled;
    this.lineNode.stroke = this.line.stroke;
    this.lineNode.strokeWidth = this.line.width;
  }
  computeLayout() {
    this.updateDirection();
    this.updateScale();
    const { step } = this.scale;
    const { title, label, range: range3, depthOptions, horizontal, line } = this;
    const scrollbar = this.chartLayout?.scrollbars?.[this.id];
    const scrollbarThickness = this.getScrollbarThickness(scrollbar);
    this.lineNode.datum = horizontal ? { x1: range3[0], x2: range3[1], y1: 0, y2: 0 } : { x1: 0, x2: 0, y1: range3[0], y2: range3[1] };
    this.lineNode.setProperties({ stroke: line.stroke, strokeWidth: line.enabled ? line.width : 0 });
    this.resizeTickTree();
    if (!this.tickTreeLayout?.depth) {
      return { bbox: BBox.zero, spacing: 0, depthLabelMaxSize: {}, tickLabelLayout: [] };
    }
    const { depth: maxDepth, nodes: treeLabels } = this.tickTreeLayout;
    const sideFlag = horizontal ? -label.getSideFlag() : label.getSideFlag();
    const tickLabelLayout = [];
    const labelBBoxes = /* @__PURE__ */ new Map();
    const truncatedLabelText = /* @__PURE__ */ new Map();
    const tempText = new TransformableText();
    const optionsMap = this.getDepthOptionsMap(maxDepth);
    const labelSpacing = sideFlag * (optionsMap[0].spacing + this.getTickSpacing() + scrollbarThickness);
    const tickFormatter = this.tickFormatter(this.scale.domain, this.scale.domain, false);
    const setLabelProps = (datum, index) => {
      const depth = maxDepth - datum.depth;
      if (!optionsMap[depth]?.enabled || !inRange(datum.screen, range3))
        return false;
      let maxWidth = (datum.leafCount || 1) * step;
      if (maxWidth < MIN_CATEGORY_SPACING)
        return false;
      const inputText = tickFormatter(datum.label, index - 1);
      let text2 = inputText;
      const labelStyles = this.getLabelStyles(
        { value: datum.index, formattedValue: text2, depth },
        depthOptions[depth]?.label
      );
      if (label.avoidCollisions) {
        const rotation = optionsMap[depth].rotation;
        let maxHeight = this.thickness;
        if (rotation != null) {
          const innerRect = getMaxInnerRectSize(rotation, maxWidth, maxHeight);
          maxWidth = innerRect.width;
          maxHeight = innerRect.height;
        }
        const wrapOptions = {
          font: labelStyles,
          textWrap: optionsMap[depth].wrapping,
          overflow: optionsMap[depth].truncate ? "ellipsis" : "hide",
          maxWidth,
          maxHeight
        };
        text2 = wrapTextOrSegments(text2, wrapOptions) || text2;
      }
      if (text2 !== inputText && isTruncated(text2)) {
        truncatedLabelText.set(index, toPlainText(inputText));
      } else {
        truncatedLabelText.delete(index);
      }
      tempText.x = horizontal ? datum.screen : labelSpacing;
      tempText.y = horizontal ? labelSpacing : datum.screen;
      tempText.rotation = 0;
      tempText.fill = labelStyles.color;
      tempText.text = text2;
      tempText.textAlign = "center";
      tempText.textBaseline = label.parallel ? "top" : "bottom";
      tempText.setFont(labelStyles);
      tempText.setBoxing(labelStyles);
      return true;
    };
    const depthLabelMaxSize = {};
    for (const [index, datum] of treeLabels.entries()) {
      const depth = maxDepth - datum.depth;
      depthLabelMaxSize[depth] ?? (depthLabelMaxSize[depth] = 0);
      const isLeaf = !datum.children.length;
      if (isLeaf && step < MIN_CATEGORY_SPACING)
        continue;
      const isVisible = setLabelProps(datum, index);
      if (!isVisible || !tempText.getBBox())
        continue;
      labelBBoxes.set(index, tempText.getBBox());
      tempText.rotation = normalizeAngle360FromDegrees(optionsMap[depth]?.rotation);
      const { width: width2, height: height2 } = tempText.getBBox();
      const labelSize = horizontal ? height2 : width2;
      if (depthLabelMaxSize[depth] < labelSize) {
        depthLabelMaxSize[depth] = labelSize;
      }
    }
    const idGenerator = createIdsGenerator();
    const nestedPadding = (d) => {
      if (d === 0)
        return 0;
      let v = depthLabelMaxSize[0];
      for (let i = 1; i <= d; i++) {
        v += optionsMap[i].spacing;
        if (i !== d) {
          v += depthLabelMaxSize[i];
        }
      }
      return v;
    };
    for (const [index, datum] of treeLabels.entries()) {
      if (index === 0)
        continue;
      const visible = setLabelProps(datum, index);
      const isLeaf = !datum.children.length;
      const depth = maxDepth - datum.depth;
      if (isLeaf && step < MIN_CATEGORY_SPACING)
        continue;
      if (!visible)
        continue;
      const labelRotation = normalizeAngle360FromDegrees(optionsMap[depth].rotation);
      const labelBBox = labelBBoxes.get(index);
      if (!labelBBox)
        continue;
      const { width: w, height: h } = labelBBox;
      const depthPadding = nestedPadding(depth);
      tempText.textAlign = "center";
      tempText.textBaseline = "middle";
      tempText.rotation = labelRotation;
      if (horizontal) {
        tempText.y += (depthPadding + angularPadding(w / 2, h / 2, labelRotation)) * sideFlag;
        tempText.rotationCenterX = datum.screen;
        tempText.rotationCenterY = tempText.y;
      } else {
        tempText.x += depthPadding * sideFlag + angularPadding(
          (optionsMap[depth].spacing * sideFlag + w) / 2,
          label.mirrored ? w : 0,
          labelRotation
        ) - w / 2;
        tempText.rotationCenterX = tempText.x;
        tempText.rotationCenterY = datum.screen;
      }
      if (optionsMap[depth].avoidCollisions) {
        const { width: width2, height: height2 } = tempText.getBBox();
        const labelSize = horizontal ? width2 : height2;
        const availableRange = isLeaf ? step : datum.leafCount * step;
        if (labelSize > availableRange) {
          labelBBoxes.delete(index);
          continue;
        }
      }
      const text2 = tempText.getPlainText();
      const boxing = tempText.getBoxingProperties();
      tickLabelLayout.push({
        text: text2,
        textUntruncated: truncatedLabelText.get(index),
        visible: true,
        tickId: idGenerator(text2),
        range: this.scale.range,
        border: boxing.border,
        color: tempText.fill,
        cornerRadius: boxing.cornerRadius,
        fill: boxing.fill,
        fontFamily: tempText.fontFamily,
        fontSize: tempText.fontSize,
        fontStyle: tempText.fontStyle,
        fontWeight: tempText.fontWeight,
        padding: boxing.padding,
        rotation: tempText.rotation,
        rotationCenterX: tempText.rotationCenterX,
        rotationCenterY: tempText.rotationCenterY,
        textAlign: tempText.textAlign,
        textBaseline: tempText.textBaseline,
        x: tempText.x,
        y: tempText.y
      });
      labelBBoxes.set(index, Transformable.toCanvas(tempText));
    }
    let maxTickSize = depthLabelMaxSize[0];
    for (let i = 0; i < maxDepth; i++) {
      maxTickSize += optionsMap[i].spacing;
      if (i !== 0) {
        maxTickSize += depthLabelMaxSize[i];
      }
    }
    const maxTickSizeWithScrollbar = maxTickSize + scrollbarThickness;
    const bboxes = [
      this.lineNodeBBox(),
      BBox.merge(labelBBoxes.values()),
      new BBox(0, 0, maxTickSizeWithScrollbar * sideFlag, 0)
    ];
    const combined = BBox.merge(bboxes);
    const labelThickness = horizontal ? combined.height : combined.width;
    const { spacing, scrollbarLayout } = this.applyScrollbarLayout(bboxes, labelThickness, scrollbar);
    this.layout.labelThickness = labelThickness;
    this.layout.scrollbar = scrollbarLayout;
    if (title.enabled) {
      bboxes.push(this.titleBBox(this.scale.domain, spacing));
    }
    const mergedBBox = BBox.merge(bboxes);
    this.layoutCrossLines();
    return { bbox: mergedBBox, spacing, depthLabelMaxSize, tickLabelLayout };
  }
  /**
   * Creates/removes/updates the scene graph nodes that constitute the axis.
   * Supposed to be called _manually_ after changing _any_ of the axis properties.
   * This allows to bulk set axis properties before updating the nodes.
   * The node changes made by this method are rendered on the next animation frame.
   * We could schedule this method call automatically on the next animation frame
   * when any of the axis properties change (the way we do when properties of scene graph's
   * nodes change), but this will mean that we first wait for the next animation
   * frame to make changes to the nodes of the axis, then wait for another animation
   * frame to render those changes. It's nice to have everything update automatically,
   * but this extra level of async indirection will not just introduce an unwanted delay,
   * it will also make it harder to reason about the program.
   */
  update() {
    if (!this.computedLayout)
      return;
    if (!this.scale.animatable) {
      this.moduleCtx.animationManager.skipCurrentBatch();
    }
    const { tickScale, tick, gridLine, gridLength, visibleRange, tickTreeLayout } = this;
    if (!tickTreeLayout)
      return;
    const { depthLabelMaxSize, spacing } = this.computedLayout;
    const { depth: maxDepth } = tickTreeLayout;
    const optionsMap = this.getDepthOptionsMap(maxDepth);
    const scrollbar = this.chartLayout?.scrollbars?.[this.id];
    const scrollbarThickness = this.getScrollbarThickness(scrollbar);
    const { position, horizontal, gridPadding } = this;
    const direction = position === "bottom" || position === "right" ? -1 : 1;
    const p1 = gridPadding;
    const p2 = direction * gridLength - gridPadding;
    const tickParams = {
      nice: [false, false],
      interval: void 0,
      tickCount: void 0,
      minTickCount: 0,
      maxTickCount: Infinity
    };
    const { ticks: allTicks } = tickScale.ticks(tickParams, void 0, visibleRange);
    const { tickInfos: allTickInfos, minSpacingByDepth } = buildTickInfos(
      allTicks,
      this.tickNodes,
      tickScale,
      maxDepth
    );
    const minDepthToShow = getMinDepthToShow(minSpacingByDepth);
    const visibleTickInfos = selectVisibleTickInfos(allTickInfos, minDepthToShow, maxDepth, minSpacingByDepth);
    const gridLineData = visibleTickInfos.map(
      ({ tickLabel, position: tickPosition }, index) => ({
        index: tickScale.findIndex(tickLabel),
        tickId: createDatumId(index, ...tickLabel),
        translation: Math.round(tickPosition)
      })
    );
    this.gridLineGroupSelection.update(
      gridLine.enabled && gridLength ? this.calculateGridLines(gridLineData, p1, p2) : []
    );
    this.gridFillGroupSelection.update(
      gridLine.enabled && gridLength ? this.calculateGridFills(gridLineData, p1, p2) : []
    );
    this.tickLineGroupSelection.update(
      tick.enabled ? visibleTickInfos.map(({ depth }, index) => {
        const { tickId, translation: offset } = gridLineData[index];
        const tickOptions = this.depthOptions[depth]?.tick;
        let tickSize = depthLabelMaxSize[0];
        for (let i = 0; i <= depth; i++) {
          tickSize += optionsMap[i].spacing;
          if (i !== 0) {
            tickSize += depthLabelMaxSize[i];
          }
        }
        const stroke3 = tickOptions?.stroke ?? tick.stroke;
        const strokeWidth = tickOptions?.enabled === false ? 0 : tickOptions?.width ?? tick.width;
        const h = -direction * tickSize;
        const tickOffset = -direction * (scrollbarThickness + this.getTickSpacing());
        const [x1, y1, x2, y2] = horizontal ? [offset, tickOffset, offset, tickOffset + h] : [tickOffset, offset, tickOffset + h, offset];
        const lineDash = void 0;
        return { tickId, offset, x1, y1, x2, y2, stroke: stroke3, strokeWidth, lineDash };
      }) : []
    );
    this.updatePosition();
    this.updateCategoryLabels();
    this.updateAxisLine();
    this.updateGridLines();
    this.updateGridFills();
    this.updateTickLines();
    this.updateTitle(this.scale.domain, spacing);
    this.updateCrossLines();
    this.resetSelectionNodes();
  }
  calculateLayout(_primaryTickCount, chartLayout) {
    this.chartLayout = chartLayout;
    const { depthLabelMaxSize, tickLabelLayout, spacing, bbox } = this.computeLayout();
    this.computedLayout = { depthLabelMaxSize, tickLabelLayout, spacing };
    return { bbox, niceDomain: this.scale.domain };
  }
  /**
   * The length of the grid. The grid is only visible in case of a non-zero value.
   */
  onGridVisibilityChange() {
    super.onGridVisibilityChange();
    this.tickLabelGroupSelection.clear();
  }
  updateScale() {
    super.updateScale();
    this.tickScale.range = this.scale.range;
    this.scale.paddingOuter = this.scale.paddingInner / 2;
  }
  processData() {
    const { direction } = this;
    const flatDomains = this.boundSeries.filter((s) => s.visible).flatMap((series) => extractDomain(series.getDomain(direction)));
    this.dataDomain = { domain: extent(flatDomains) ?? this.filterDuplicateArrays(flatDomains), clipped: false };
    if (this.isReversed()) {
      this.dataDomain.domain.reverse();
    }
    const domain = this.dataDomain.domain.map(convertIntegratedCategoryValue);
    const { layout, tickNodes } = treeLayout(domain);
    this.tickTreeLayout = layout;
    this.tickNodes = tickNodes;
    const orderedDomain = [];
    for (const node of this.tickTreeLayout.nodes) {
      if (node.leafCount || node.refId == null)
        continue;
      orderedDomain.push(this.dataDomain.domain[node.refId]);
    }
    const sortedDomain = sortBasedOnArray(this.dataDomain.domain, orderedDomain);
    this.scale.domain = sortedDomain;
    const tickScaleDomain = sortedDomain.map(convertIntegratedCategoryValue);
    tickScaleDomain.push([""]);
    this.tickScale.domain = tickScaleDomain;
  }
  filterDuplicateArrays(array2) {
    const seen = /* @__PURE__ */ new Set();
    return array2.filter((item) => {
      const key = isArray(item) ? JSON.stringify(item) : item;
      if (seen.has(key))
        return false;
      seen.add(key);
      return true;
    });
  }
};
GroupedCategoryAxis.className = "GroupedCategoryAxis";
GroupedCategoryAxis.type = "grouped-category";
__decorateClass([
  addFakeTransformToInstanceProperty
], GroupedCategoryAxis.prototype, "depthOptions", 2);
function separatorDepth2(node) {
  let depth = 0;
  let current = node;
  while (current?.index === 0) {
    depth += 1;
    current = current.parent;
  }
  return depth;
}
function buildTickInfos(ticks, tickNodes, tickScale, maxDepth) {
  const tickInfos = new Array(ticks.length);
  const minSpacingByDepth = new Array(maxDepth).fill(Infinity);
  const lastPositionByDepth = new Array(maxDepth).fill(Number.NaN);
  for (let i = 0; i < ticks.length; i++) {
    const tickLabel = ticks[i];
    const node = tickNodes?.get(tickLabel);
    const depth = node == null ? maxDepth - 1 : Math.min(separatorDepth2(node), maxDepth - 1);
    const position = tickScale.convert(tickLabel);
    tickInfos[i] = { tickLabel, depth, position };
    if (!Number.isFinite(position))
      continue;
    for (let d = 0; d <= depth; d++) {
      const lastPosition = lastPositionByDepth[d];
      if (Number.isFinite(lastPosition)) {
        minSpacingByDepth[d] = Math.min(minSpacingByDepth[d], Math.abs(position - lastPosition));
      }
      lastPositionByDepth[d] = position;
    }
  }
  return { tickInfos, minSpacingByDepth };
}
function getMinDepthToShow(minSpacingByDepth) {
  for (let depth = 0; depth < minSpacingByDepth.length; depth++) {
    const minSpacing = minSpacingByDepth[depth];
    if (!Number.isFinite(minSpacing) || minSpacing >= MIN_CATEGORY_SPACING) {
      return depth;
    }
  }
  return minSpacingByDepth.length;
}
function getTickStepForSpacing(minSpacing) {
  if (!Number.isFinite(minSpacing) || minSpacing <= 0) {
    return 1;
  }
  return Math.max(1, Math.ceil(MIN_CATEGORY_SPACING / minSpacing));
}
function selectVisibleTickInfos(allTickInfos, minDepthToShow, maxDepth, minSpacingByDepth) {
  if (minDepthToShow <= 0) {
    return allTickInfos;
  }
  const removedDepth = Math.min(minDepthToShow - 1, maxDepth - 1);
  if (removedDepth < 0) {
    return allTickInfos;
  }
  const tickStep2 = getTickStepForSpacing(minSpacingByDepth[removedDepth]);
  const visibleTickInfos = [];
  let removedIndex = 0;
  for (const info of allTickInfos) {
    if (info.depth >= minDepthToShow) {
      visibleTickInfos.push(info);
      continue;
    }
    if (info.depth !== removedDepth)
      continue;
    if (removedIndex % tickStep2 === 0) {
      visibleTickInfos.push(info);
    }
    removedIndex++;
  }
  return visibleTickInfos;
}
function convertIntegratedCategoryValue(datum) {
  return toArray(isObject(datum) && "value" in datum ? datum.value : datum);
}

// packages/ag-charts-community/src/chart/series/cartesian/quadtreeUtil.ts
function addHitTestersToQuadtree(quadtree, hitTesters) {
  for (const node of hitTesters) {
    const datum = node.datum;
    if (datum === void 0) {
      logger_exports.error("undefined datum");
    } else {
      quadtree.addValue(node, datum);
    }
  }
}
function findQuadtreeMatch(series, point) {
  const { x, y } = point;
  const { nearest, distanceSquared: distanceSquared2 } = series.getQuadTree().find(x, y);
  if (nearest !== void 0) {
    return { datum: nearest.value, distance: Math.sqrt(distanceSquared2) };
  }
  return void 0;
}

// packages/ag-charts-community/src/chart/series/cartesian/abstractBarSeries.ts
var AbstractBarSeriesProperties = class extends CartesianSeriesProperties {
  constructor() {
    super(...arguments);
    this.direction = "vertical";
    this.width = void 0;
    this.widthRatio = void 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], AbstractBarSeriesProperties.prototype, "direction", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AbstractBarSeriesProperties.prototype, "width", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AbstractBarSeriesProperties.prototype, "widthRatio", 2);
var AbstractBarSeries = class extends CartesianSeries {
  constructor() {
    super(...arguments);
    this.smallestDataInterval = void 0;
    this.largestDataInterval = void 0;
  }
  padBandExtent(keys, alignStart) {
    const ratio2 = typeof alignStart === "boolean" ? 1 : 0.5;
    const scalePadding = isFiniteNumber(this.smallestDataInterval) ? this.smallestDataInterval * ratio2 : 0;
    const keysExtent = extent(keys) ?? [Number.NaN, Number.NaN];
    if (typeof alignStart === "boolean") {
      keysExtent[alignStart ? 0 : 1] -= (alignStart ? 1 : -1) * scalePadding;
    } else {
      keysExtent[0] -= scalePadding;
      keysExtent[1] += scalePadding;
    }
    return fixNumericExtent(keysExtent);
  }
  getBandScalePadding() {
    return { inner: 0.3, outer: 0.15 };
  }
  shouldFlipXY() {
    return !this.isVertical();
  }
  isVertical() {
    return this.properties.direction === "vertical";
  }
  getBarDirection() {
    return this.shouldFlipXY() ? "x" /* X */ : "y" /* Y */;
  }
  getCategoryDirection() {
    return this.shouldFlipXY() ? "y" /* Y */ : "x" /* X */;
  }
  getValueAxis() {
    const direction = this.getBarDirection();
    return this.axes[direction];
  }
  getCategoryAxis() {
    const direction = this.getCategoryDirection();
    return this.axes[direction];
  }
  getMinimumRangeSeries(ranges) {
    const { width: width2 } = this.properties;
    if (width2 == null)
      return;
    const axis = this.getCategoryAxis();
    if (!axis)
      return;
    const { index } = this.ctx.seriesStateManager.getVisiblePeerGroupIndex(this);
    ranges[index] = Math.max(ranges[index] ?? 0, width2);
  }
  getMinimumRangeChart(ranges) {
    if (ranges.length === 0)
      return 0;
    const axis = this.getCategoryAxis();
    if (!(axis instanceof GroupedCategoryAxis || axis instanceof CategoryAxis))
      return 0;
    const dataSize = this.data?.netSize() ?? 0;
    if (dataSize === 0)
      return 0;
    const defaultPadding = this.getBandScalePadding();
    const { paddingInner = defaultPadding.inner, paddingOuter = defaultPadding.outer, groupPaddingInner } = axis;
    const width2 = ranges.reduce((sum, range3) => sum + range3, 0);
    const averageWidth = width2 / ranges.length;
    const { visibleGroupCount } = this.ctx.seriesStateManager.getVisiblePeerGroupIndex(this);
    const bandWidth = width2 + groupPaddingInner * averageWidth * (visibleGroupCount - 1);
    const paddingFactor = (dataSize - paddingInner + paddingOuter * 2) / (1 - paddingInner);
    return bandWidth * paddingFactor;
  }
  /**
   * Override to use bar-specific axis resolution (category/value vs X/Y).
   * Bar series can be horizontal or vertical, so we use getCategoryAxis/getValueAxis.
   */
  validateCreateNodeDataPreconditions() {
    const xAxis = this.getCategoryAxis();
    const yAxis = this.getValueAxis();
    if (!xAxis || !yAxis || !this.dataModel || !this.processedData) {
      return void 0;
    }
    return { xAxis, yAxis };
  }
  getBandwidth(xAxis, minWidth) {
    return ContinuousScale.is(xAxis.scale) ? xAxis.scale.calcBandwidth(this.smallestDataInterval, minWidth) : xAxis.scale.bandwidth;
  }
  xCoordinateRange(xValue) {
    const xAxis = this.axes[this.getCategoryDirection()];
    const xScale = xAxis.scale;
    const bandWidth = this.getBandwidth(xAxis, 0) ?? 0;
    const barOffset = ContinuousScale.is(xScale) ? bandWidth * -0.5 : 0;
    const x = xScale.convert(xValue) + barOffset;
    return [x, x + bandWidth];
  }
  yCoordinateRange(yValues) {
    const yAxis = this.axes[this.getBarDirection()];
    const yScale = yAxis.scale;
    const ys = yValues.map((yValue) => yScale.convert(yValue));
    if (ys.length === 1) {
      const y0 = yScale.convert(0);
      return [Math.min(ys[0], y0), Math.max(ys[0], y0)];
    }
    return [Math.min(...ys), Math.max(...ys)];
  }
  getBarDimensions() {
    const categoryAxis = this.getCategoryAxis();
    const bandwidth = this.getBandwidth(categoryAxis) ?? 0;
    this.ctx.seriesStateManager.updateGroupScale(this, bandwidth, categoryAxis);
    const groupOffset = this.getGroupOffset();
    const barWidth = this.getBarWidth();
    const barOffset = this.getBarOffset(barWidth);
    return { groupOffset, barOffset, barWidth };
  }
  getGroupOffset() {
    return this.ctx.seriesStateManager.getGroupOffset(this);
  }
  getBarOffset(barWidth) {
    const groupScale = this.ctx.seriesStateManager.getGroupScale(this);
    const xAxis = this.getCategoryAxis();
    let barOffset = 0;
    if (ContinuousScale.is(xAxis.scale)) {
      barOffset = -barWidth / 2;
    } else if (this.seriesGrouping == null && groupScale) {
      const rangeWidth = this.getGroupScaleRangeWidth(groupScale);
      barOffset = (rangeWidth - barWidth) / 2;
    } else if (groupScale && this.properties.widthRatio != null) {
      barOffset = (groupScale.bandwidth - barWidth) / 2;
    }
    const stackOffset = this.ctx.seriesStateManager.getStackOffset(this, barWidth);
    return barOffset + stackOffset;
  }
  getBarWidth() {
    const { seriesGrouping } = this;
    const { width: width2 } = this.properties;
    let { widthRatio } = this.properties;
    const groupScale = this.ctx.seriesStateManager.getGroupScale(this);
    const bandwidth = groupScale?.bandwidth ?? 0;
    if (seriesGrouping == null) {
      widthRatio ?? (widthRatio = 1);
    }
    if (widthRatio != null) {
      let relativeWidth = width2;
      if (seriesGrouping == null && relativeWidth == null && groupScale) {
        relativeWidth = this.getGroupScaleRangeWidth(groupScale);
      }
      if (relativeWidth == null && bandwidth < 1 && groupScale) {
        return groupScale.rawBandwidth;
      }
      return (relativeWidth ?? bandwidth) * widthRatio;
    }
    if (width2 != null) {
      return width2;
    }
    if (bandwidth < 1 && groupScale) {
      return groupScale.rawBandwidth;
    }
    return bandwidth;
  }
  getGroupScaleRangeWidth(groupScale) {
    let rangeWidth = groupScale.range[1] - groupScale.range[0];
    if (groupScale.round && rangeWidth > 0)
      rangeWidth = Math.floor(rangeWidth);
    return rangeWidth;
  }
  resolveKeyDirection(direction) {
    if (this.getBarDirection() === "x" /* X */) {
      if (direction === "x" /* X */) {
        return "y" /* Y */;
      }
      return "x" /* X */;
    }
    return direction;
  }
  initQuadTree(quadtree) {
    addHitTestersToQuadtree(quadtree, this.datumNodesIter());
  }
  pickNodeClosestDatum(point) {
    return findQuadtreeMatch(this, point);
  }
};

// packages/ag-charts-community/src/chart/series/cartesian/lineInterpolationPlotting.ts
function lerp2(a, b, ratio2) {
  return (b - a) * ratio2 + a;
}
function linearSupertype(span, stepX) {
  const { x0, y0, x1, y1 } = span;
  const m = (y1 - y0) / (x1 - x0);
  const stepY = m * (stepX - x0) + y0;
  return {
    leftCp1x: x0,
    leftCp1y: y0,
    leftCp2x: stepX,
    leftCp2y: stepY,
    stepX,
    stepY0: stepY,
    stepY1: stepY,
    rightCp1x: stepX,
    rightCp1y: stepY,
    rightCp2x: x1,
    rightCp2y: y1
  };
}
function bezierSupertype(span, stepX) {
  const { cp0x, cp0y, cp1x, cp1y, cp2x, cp2y, cp3x, cp3y } = span;
  const t = solveBezier(cp0x, cp1x, cp2x, cp3x, stepX);
  const [left, right] = splitBezier2D(cp0x, cp0y, cp1x, cp1y, cp2x, cp2y, cp3x, cp3y, t);
  const stepY = left[3].y;
  return {
    leftCp1x: left[1].x,
    leftCp1y: left[1].y,
    leftCp2x: left[2].x,
    leftCp2y: left[2].y,
    stepX,
    stepY0: stepY,
    stepY1: stepY,
    rightCp1x: right[1].x,
    rightCp1y: right[1].y,
    rightCp2x: right[2].x,
    rightCp2y: right[2].y
  };
}
function stepSupertype(span) {
  const { x0, y0, x1, y1, stepX } = span;
  return {
    leftCp1x: (x0 + stepX) / 2,
    leftCp1y: y0,
    leftCp2x: (x0 + stepX) / 2,
    leftCp2y: y0,
    stepX,
    stepY0: y0,
    stepY1: y1,
    rightCp1x: (stepX + x1) / 2,
    rightCp1y: y1,
    rightCp2x: (stepX + x1) / 2,
    rightCp2y: y1
  };
}
function spanSupertype(span, stepX) {
  if (span.type === "linear") {
    return linearSupertype(span, stepX);
  } else if (span.type === "cubic") {
    return bezierSupertype(span, stepX);
  } else if (span.type === "step") {
    return stepSupertype(span);
  } else {
    return linearSupertype(span, stepX);
  }
}
function plotStart(path, moveTo2, x0, y0, x1, y1, reversed) {
  switch (moveTo2) {
    case 0 /* MoveTo */:
      if (reversed) {
        path.moveTo(x1, y1);
      } else {
        path.moveTo(x0, y0);
      }
      break;
    case 1 /* LineTo */:
      if (reversed) {
        path.lineTo(x1, y1);
      } else {
        path.lineTo(x0, y0);
      }
      break;
    case 2 /* Skip */:
      break;
  }
}
function plotLinear(path, x0, y0, x1, y1, reversed) {
  if (reversed) {
    path.lineTo(x0, y0);
  } else {
    path.lineTo(x1, y1);
  }
}
function plotCubic(path, cp0x, cp0y, cp1x, cp1y, cp2x, cp2y, cp3x, cp3y, reversed) {
  if (reversed) {
    path.cubicCurveTo(cp2x, cp2y, cp1x, cp1y, cp0x, cp0y);
  } else {
    path.cubicCurveTo(cp1x, cp1y, cp2x, cp2y, cp3x, cp3y);
  }
}
function plotStep(path, x0, y0, x1, y1, stepX, reversed) {
  if (reversed) {
    path.lineTo(stepX, y1);
    path.lineTo(stepX, y0);
    path.lineTo(x0, y0);
  } else {
    path.lineTo(stepX, y0);
    path.lineTo(stepX, y1);
    path.lineTo(x1, y1);
  }
}
function plotMultiLine(path, x0, y0, x1, y1, midPoints, reversed) {
  if (reversed) {
    for (let i = midPoints.length - 1; i >= 0; i--) {
      const { x, y } = midPoints[i];
      path.lineTo(x, y);
    }
    path.lineTo(x0, y0);
  } else {
    for (const { x, y } of midPoints) {
      path.lineTo(x, y);
    }
    path.lineTo(x1, y1);
  }
}
function plotSpan(path, span, moveTo2, reversed) {
  const [start2, end3] = spanRange(span);
  plotStart(path, moveTo2, start2.x, start2.y, end3.x, end3.y, reversed);
  switch (span.type) {
    case "linear":
      plotLinear(path, span.x0, span.y0, span.x1, span.y1, reversed);
      break;
    case "cubic":
      plotCubic(
        path,
        span.cp0x,
        span.cp0y,
        span.cp1x,
        span.cp1y,
        span.cp2x,
        span.cp2y,
        span.cp3x,
        span.cp3y,
        reversed
      );
      break;
    case "step":
      plotStep(path, span.x0, span.y0, span.x1, span.y1, span.stepX, reversed);
      break;
    case "multi-line":
      plotMultiLine(path, span.x0, span.y0, span.x1, span.y1, span.midPoints, reversed);
      break;
  }
}
function interpolatedSpanRange(a, b, ratio2) {
  const [aStart, aEnd] = spanRange(a);
  const [bStart, bEnd] = spanRange(b);
  const x0 = lerp2(aStart.x, bStart.x, ratio2);
  const y0 = lerp2(aStart.y, bStart.y, ratio2);
  const x1 = lerp2(aEnd.x, bEnd.x, ratio2);
  const y1 = lerp2(aEnd.y, bEnd.y, ratio2);
  return [
    { x: x0, y: y0 },
    { x: x1, y: y1 }
  ];
}
function plotInterpolatedSpans(path, a, b, ratio2, moveTo2, reversed) {
  const [{ x: x0, y: y0 }, { x: x1, y: y1 }] = interpolatedSpanRange(a, b, ratio2);
  plotStart(path, moveTo2, x0, y0, x1, y1, reversed);
  if (a.type === "cubic" && b.type === "cubic") {
    const cp1x = lerp2(a.cp1x, b.cp1x, ratio2);
    const cp1y = lerp2(a.cp1y, b.cp1y, ratio2);
    const cp2x = lerp2(a.cp2x, b.cp2x, ratio2);
    const cp2y = lerp2(a.cp2y, b.cp2y, ratio2);
    plotCubic(path, x0, y0, cp1x, cp1y, cp2x, cp2y, x1, y1, reversed);
  } else if (a.type === "step" && b.type === "step") {
    const stepX = lerp2(a.stepX, b.stepX, ratio2);
    plotStep(path, x0, y0, x1, y1, stepX, reversed);
  } else if (a.type === "linear" && b.type === "linear") {
    plotLinear(path, x0, y0, x1, y1, reversed);
  } else {
    let defaultStepX;
    if (a.type === "step") {
      defaultStepX = a.stepX;
    } else if (b.type === "step") {
      defaultStepX = b.stepX;
    } else {
      defaultStepX = (x0 + x1) / 2;
    }
    const as = spanSupertype(a, defaultStepX);
    const bs = spanSupertype(b, defaultStepX);
    const leftCp1x = lerp2(as.leftCp1x, bs.leftCp1x, ratio2);
    const leftCp1y = lerp2(as.leftCp1y, bs.leftCp1y, ratio2);
    const leftCp2x = lerp2(as.leftCp2x, bs.leftCp2x, ratio2);
    const leftCp2y = lerp2(as.leftCp2y, bs.leftCp2y, ratio2);
    const stepX = lerp2(as.stepX, bs.stepX, ratio2);
    const stepY0 = lerp2(as.stepY0, bs.stepY0, ratio2);
    const stepY1 = lerp2(as.stepY1, bs.stepY1, ratio2);
    const rightCp1x = lerp2(as.rightCp1x, bs.rightCp1x, ratio2);
    const rightCp1y = lerp2(as.rightCp1y, bs.rightCp1y, ratio2);
    const rightCp2x = lerp2(as.rightCp2x, bs.rightCp2x, ratio2);
    const rightCp2y = lerp2(as.rightCp2y, bs.rightCp2y, ratio2);
    if (reversed) {
      path.cubicCurveTo(rightCp2x, rightCp2y, rightCp1x, rightCp1y, stepX, stepY1);
      path.lineTo(stepX, stepY0);
      path.cubicCurveTo(leftCp2x, leftCp2y, leftCp1x, leftCp1y, x0, y0);
    } else {
      path.cubicCurveTo(leftCp1x, leftCp1y, leftCp2x, leftCp2y, stepX, stepY0);
      path.lineTo(stepX, stepY1);
      path.cubicCurveTo(rightCp1x, rightCp1y, rightCp2x, rightCp2y, x1, y1);
    }
  }
}

// packages/ag-charts-community/src/chart/series/cartesian/lineInterpolationUtil.ts
var MAX_CATEGORIES = 1e3;
var CollapseMode = /* @__PURE__ */ ((CollapseMode3) => {
  CollapseMode3[CollapseMode3["Zero"] = 0] = "Zero";
  CollapseMode3[CollapseMode3["Split"] = 1] = "Split";
  return CollapseMode3;
})(CollapseMode || {});
function integratedCategoryMatch(a, b) {
  if (a == null || b == null)
    return false;
  if (typeof a !== "object" || typeof b !== "object")
    return false;
  if ("id" in a && "id" in b) {
    return a.id === b.id;
  }
  return a.toString() === b.toString();
}
function toAxisValue(value) {
  return transformIntegratedCategoryValue(value).valueOf();
}
function scale(val, scaling) {
  if (!scaling)
    return Number.NaN;
  if (val instanceof Date) {
    val = val.getTime();
  }
  if (scaling.type === "continuous" && typeof val === "number") {
    const domainRatio = (val - scaling.domain[0]) / (scaling.domain[1] - scaling.domain[0]);
    return domainRatio * (scaling.range[1] - scaling.range[0]) + scaling.range[0];
  }
  if (scaling.type === "log" && typeof val === "number") {
    return scaling.convert(val);
  }
  if (scaling.type !== "category")
    return Number.NaN;
  if (isUnitTimeCategoryScaling(scaling)) {
    if (typeof val === "number") {
      const { firstBandTime, intervalMs, bandCount, inset, step } = scaling;
      const matchingIndex2 = Math.round((val - firstBandTime) / intervalMs);
      if (matchingIndex2 >= 0 && matchingIndex2 < bandCount) {
        return inset + step * matchingIndex2;
      }
    }
    return Number.NaN;
  }
  const axisValue = toAxisValue(val);
  let matchingIndex = scaling.domain.findIndex((d) => toAxisValue(d) === axisValue);
  if (matchingIndex === -1) {
    matchingIndex = scaling.domain.findIndex((d) => integratedCategoryMatch(val, d));
  }
  if (matchingIndex >= 0) {
    return scaling.inset + scaling.step * matchingIndex;
  }
  return Number.NaN;
}
function getAxisIndices({ data }, values) {
  return data.map((datum, datumIndex) => ({
    xValue0Index: values.indexOf(toAxisValue(datum.xValue0)),
    xValue1Index: values.indexOf(toAxisValue(datum.xValue1)),
    datumIndex
  }));
}
function isValidScaling(data) {
  return Object.values(data.scales).every((s) => {
    if (s.type === "category") {
      if (isUnitTimeCategoryScaling(s)) {
        return s.bandCount < MAX_CATEGORIES;
      }
      return s.domain.length < MAX_CATEGORIES;
    }
    return true;
  });
}
function validateCategorySorting(newData, oldData) {
  const oldScale = oldData.scales.x;
  const newScale = newData.scales.x;
  if (oldScale?.type !== "category" || newScale?.type !== "category")
    return true;
  if (isUnitTimeCategoryScaling(oldScale) || isUnitTimeCategoryScaling(newScale)) {
    return true;
  }
  let x0 = -Infinity;
  for (const oldValue of oldScale.domain) {
    const x = scale(oldValue, newScale);
    if (!Number.isFinite(x))
      continue;
    if (x < x0) {
      return false;
    } else {
      x0 = x;
    }
  }
  return true;
}
function validateAxisEntriesOrder(axisValues, data) {
  let x0 = -Infinity;
  for (const axisValue of axisValues) {
    const x = scale(axisValue.value, data.scales.x);
    if (!Number.isFinite(x))
      continue;
    if (x < x0) {
      return false;
    } else {
      x0 = x;
    }
  }
  return true;
}
function spanAxisContext(newData, oldData) {
  const allAxisEntries = /* @__PURE__ */ new Map();
  for (const { xValue0, xValue1 } of newData.data) {
    const xValue0Value = toAxisValue(xValue0);
    const xValue1Value = toAxisValue(xValue1);
    allAxisEntries.set(xValue0Value, xValue0).set(xValue1Value, xValue1);
  }
  const newAxisEntries = Array.from(allAxisEntries, ([axisValue, value]) => ({ axisValue, value }));
  newAxisEntries.sort((a, b) => {
    return scale(a.value, newData.scales.x) - scale(b.value, newData.scales.x);
  });
  const exclusivelyOldAxisEntries = [];
  for (const { xValue0, xValue1 } of oldData.data) {
    const xValue0Value = toAxisValue(xValue0);
    const xValue1Value = toAxisValue(xValue1);
    if (!allAxisEntries.has(xValue0Value)) {
      allAxisEntries.set(xValue0Value, xValue0);
      exclusivelyOldAxisEntries.push({ axisValue: xValue0Value, value: xValue0 });
    }
    if (!allAxisEntries.has(xValue1Value)) {
      allAxisEntries.set(xValue1Value, xValue1);
      exclusivelyOldAxisEntries.push({ axisValue: xValue1Value, value: xValue1 });
    }
  }
  exclusivelyOldAxisEntries.sort((a, b) => {
    return scale(a.value, oldData.scales.x) - scale(b.value, oldData.scales.x);
  });
  const axisEntries = newAxisEntries;
  let insertionIndex = 0;
  for (const oldAxisEntry of exclusivelyOldAxisEntries) {
    for (let i = axisEntries.length - 1; i >= insertionIndex; i -= 1) {
      const oldValueX = scale(oldAxisEntry.value, oldData.scales.x);
      const newValueX = scale(axisEntries[i].value, oldData.scales.x);
      if (oldValueX > newValueX) {
        insertionIndex = i + 1;
        break;
      }
    }
    axisEntries.splice(insertionIndex, 0, oldAxisEntry);
    insertionIndex += 1;
  }
  if (!validateAxisEntriesOrder(axisEntries, oldData))
    return;
  const axisValues = axisEntries.map((axisEntry) => axisEntry.axisValue);
  const oldDataAxisIndices = getAxisIndices(oldData, axisValues);
  const newDataAxisIndices = getAxisIndices(newData, axisValues);
  return { axisValues, oldDataAxisIndices, newDataAxisIndices };
}
function clipSpan(span, data, axisValues, xValue0Index, xIndices) {
  if (xIndices.xValue1Index === xIndices.xValue0Index + 1)
    return span;
  const range3 = spanRange(span);
  let start2;
  let end3;
  if (data.scales.x?.type === "category") {
    const step = (range3[1].x - range3[0].x) / (xIndices.xValue1Index - xIndices.xValue0Index);
    start2 = range3[0].x + (xValue0Index - xIndices.xValue0Index) * step;
    end3 = start2 + step;
  } else {
    const xValue0 = axisValues[xValue0Index];
    const xValue1 = axisValues[xValue0Index + 1];
    start2 = scale(xValue0, data.scales.x);
    end3 = scale(xValue1, data.scales.x);
  }
  return clipSpanX(span, start2, end3);
}
function axisZeroSpan(span, data) {
  const [r0, r1] = spanRange(span);
  const y0 = scale(0, data.scales.y);
  return rescaleSpan(span, { x: r0.x, y: y0 }, { x: r1.x, y: y0 });
}
function collapseSpanToMidpoint(span) {
  const [r0, r1] = spanRange(span);
  return collapseSpanToPoint(span, {
    x: (r0.x + r1.x) / 2,
    y: (r0.y + r1.y) / 2
  });
}
function collapseSpan(span, collapseMode, data, axisIndices, indices, range3) {
  let xValue;
  let yValue;
  if (indices.xValue0Index >= range3.xValue1Index) {
    const datumIndex = axisIndices.findLast((i) => i.xValue1Index <= range3.xValue1Index)?.datumIndex;
    const datum = datumIndex == null ? void 0 : data.data[datumIndex];
    xValue = datum?.xValue1;
    yValue = datum?.yValue1;
  } else if (indices.xValue0Index <= range3.xValue0Index) {
    const datumIndex = axisIndices.find((i) => i.xValue0Index >= range3.xValue0Index)?.datumIndex;
    const datum = datumIndex == null ? void 0 : data.data[datumIndex];
    xValue = datum?.xValue0;
    yValue = datum?.yValue0;
  }
  if (xValue == null || yValue == null) {
    switch (collapseMode) {
      case 0 /* Zero */:
        return axisZeroSpan(span, data);
      case 1 /* Split */:
        return collapseSpanToMidpoint(span);
    }
  }
  const x = scale(xValue, data.scales.x);
  const y = scale(yValue, data.scales.y);
  const point = { x, y };
  return rescaleSpan(span, point, point);
}
function zeroDataSpan(spanDatum, zeroData) {
  if (zeroData == null)
    return;
  const newSpanXValue0 = toAxisValue(spanDatum.xValue0);
  const newSpanXValue1 = toAxisValue(spanDatum.xValue1);
  return zeroData.find(
    (zeroSpanDatum) => toAxisValue(zeroSpanDatum.xValue0) === newSpanXValue0 && toAxisValue(zeroSpanDatum.xValue1) === newSpanXValue1
  )?.span;
}
function addSpan(newData, collapseMode, newAxisIndices, newIndices, oldZeroData, range3, out) {
  const newSpanDatum = newData.data[newIndices.datumIndex];
  const newSpan = newSpanDatum.span;
  const zeroSpan = zeroDataSpan(newSpanDatum, oldZeroData);
  if (zeroSpan == null) {
    const oldSpan = collapseSpan(newSpan, collapseMode, newData, newAxisIndices, newIndices, range3);
    out.added.push({ from: oldSpan, to: newSpan });
  } else {
    out.removed.push({ from: zeroSpan, to: zeroSpan });
    out.moved.push({ from: zeroSpan, to: newSpan });
    out.added.push({ from: newSpan, to: newSpan });
  }
}
function removeSpan(oldData, collapseMode, oldAxisIndices, oldIndices, newZeroData, range3, out) {
  const oldSpanDatum = oldData.data[oldIndices.datumIndex];
  const oldSpan = oldSpanDatum.span;
  const zeroSpan = zeroDataSpan(oldSpanDatum, newZeroData);
  if (zeroSpan == null) {
    const newSpan = collapseSpan(oldSpan, collapseMode, oldData, oldAxisIndices, oldIndices, range3);
    out.removed.push({ from: oldSpan, to: newSpan });
  } else {
    out.removed.push({ from: oldSpan, to: oldSpan });
    out.moved.push({ from: oldSpan, to: zeroSpan });
    out.added.push({ from: zeroSpan, to: zeroSpan });
  }
}
function alignSpanToContainingSpan(span, axisValues, preData, postData, postSpanIndices) {
  const xScale = postData.scales.x;
  const startXValue0 = axisValues[postSpanIndices.xValue0Index];
  const endXValue1 = axisValues[postSpanIndices.xValue1Index];
  let startDatum;
  let endDatum;
  if (xScale?.type === "continuous" || xScale?.type === "log") {
    startDatum = preData.data.findLast((spanDatum) => toAxisValue(spanDatum.xValue0) <= startXValue0);
    endDatum = preData.data.find((spanDatum) => toAxisValue(spanDatum.xValue1) >= endXValue1);
  } else {
    startDatum = preData.data.find((spanDatum) => toAxisValue(spanDatum.xValue0) === startXValue0);
    endDatum = preData.data.find((spanDatum) => toAxisValue(spanDatum.xValue1) === endXValue1);
  }
  if (startDatum == null || endDatum == null)
    return;
  const [{ x: x0 }, { x: x1 }] = spanRange(span);
  const startX = scale(startDatum.xValue0, preData.scales.x);
  const startY = scale(startDatum.yValue0, preData.scales.y);
  const endX = scale(endDatum.xValue1, preData.scales.x);
  const endY = scale(endDatum.yValue1, preData.scales.y);
  let altSpan = postData.data[postSpanIndices.datumIndex].span;
  altSpan = rescaleSpan(altSpan, { x: startX, y: startY }, { x: endX, y: endY });
  altSpan = clipSpanX(altSpan, x0, x1);
  return altSpan;
}
function appendSpanPhases(newData, oldData, collapseMode, axisValues, xValue0Index, newAxisIndices, oldAxisIndices, range3, out) {
  const xValue1Index = xValue0Index + 1;
  const oldIndices = oldAxisIndices.find((i) => i.xValue0Index <= xValue0Index && i.xValue1Index >= xValue1Index);
  const newIndices = newAxisIndices.find((i) => i.xValue0Index <= xValue0Index && i.xValue1Index >= xValue1Index);
  const oldZeroData = oldData.zeroData;
  const newZeroData = newData.zeroData;
  if (oldIndices == null && newIndices != null) {
    addSpan(newData, collapseMode, newAxisIndices, newIndices, oldZeroData, range3, out);
    return;
  } else if (oldIndices != null && newIndices == null) {
    removeSpan(oldData, collapseMode, oldAxisIndices, oldIndices, newZeroData, range3, out);
    return;
  } else if (oldIndices == null || newIndices == null) {
    return;
  }
  let ordering;
  if (oldIndices.xValue0Index === newIndices.xValue0Index && oldIndices.xValue1Index === newIndices.xValue1Index) {
    ordering = 0;
  } else if (oldIndices.xValue0Index <= newIndices.xValue0Index && oldIndices.xValue1Index >= newIndices.xValue1Index) {
    ordering = -1;
  } else if (oldIndices.xValue0Index >= newIndices.xValue0Index && oldIndices.xValue1Index <= newIndices.xValue1Index) {
    ordering = 1;
  } else {
    ordering = 0;
  }
  const oldSpanDatum = oldData.data[oldIndices.datumIndex];
  const clippedOldSpanOldScale = clipSpan(oldSpanDatum.span, oldData, axisValues, xValue0Index, oldIndices);
  const newSpanDatum = newData.data[newIndices.datumIndex];
  const clippedNewSpanNewScale = clipSpan(newSpanDatum.span, newData, axisValues, xValue0Index, newIndices);
  if (ordering === 1) {
    const clippedPostRemoveOldSpanOldScale = alignSpanToContainingSpan(
      clippedOldSpanOldScale,
      axisValues,
      oldData,
      newData,
      newIndices
    );
    if (clippedPostRemoveOldSpanOldScale == null) {
      removeSpan(oldData, collapseMode, oldAxisIndices, oldIndices, newZeroData, range3, out);
    } else {
      out.removed.push({ from: clippedOldSpanOldScale, to: clippedPostRemoveOldSpanOldScale });
      out.moved.push({ from: clippedPostRemoveOldSpanOldScale, to: clippedNewSpanNewScale });
      out.added.push({ from: clippedNewSpanNewScale, to: clippedNewSpanNewScale });
    }
  } else if (ordering === -1) {
    const clippedPreAddedNewSpanNewScale = alignSpanToContainingSpan(
      clippedNewSpanNewScale,
      axisValues,
      newData,
      oldData,
      oldIndices
    );
    if (clippedPreAddedNewSpanNewScale == null) {
      addSpan(newData, collapseMode, newAxisIndices, newIndices, oldZeroData, range3, out);
    } else {
      out.removed.push({ from: clippedOldSpanOldScale, to: clippedOldSpanOldScale });
      out.moved.push({ from: clippedOldSpanOldScale, to: clippedPreAddedNewSpanNewScale });
      out.added.push({ from: clippedPreAddedNewSpanNewScale, to: clippedNewSpanNewScale });
    }
  } else {
    out.removed.push({ from: clippedOldSpanOldScale, to: clippedOldSpanOldScale });
    out.moved.push({ from: clippedOldSpanOldScale, to: clippedNewSpanNewScale });
    out.added.push({ from: clippedNewSpanNewScale, to: clippedNewSpanNewScale });
  }
}
function phaseAnimation(axisContext, newData, oldData, collapseMode) {
  const out = {
    removed: [],
    moved: [],
    added: []
  };
  const { axisValues, oldDataAxisIndices, newDataAxisIndices } = axisContext;
  const range3 = {
    xValue0Index: Math.max(
      oldDataAxisIndices.at(0)?.xValue0Index ?? -Infinity,
      newDataAxisIndices.at(0)?.xValue0Index ?? -Infinity
    ),
    xValue1Index: Math.min(
      oldDataAxisIndices.at(-1)?.xValue1Index ?? Infinity,
      newDataAxisIndices.at(-1)?.xValue1Index ?? Infinity
    )
  };
  for (let xValue0Index = 0; xValue0Index < axisValues.length - 1; xValue0Index += 1) {
    appendSpanPhases(
      newData,
      oldData,
      collapseMode,
      axisValues,
      xValue0Index,
      newDataAxisIndices,
      oldDataAxisIndices,
      range3,
      out
    );
  }
  return out;
}
function replotXAnimation(newData, oldData) {
  const removed = [];
  const moved = [];
  const added = [];
  for (let i = 0; i < oldData.data.length; i += 1) {
    const oldSpan = oldData.data[i].span;
    const newSpan = newData.data[i].span;
    removed.push({ from: oldSpan, to: oldSpan });
    moved.push({ from: oldSpan, to: newSpan });
    added.push({ from: newSpan, to: newSpan });
  }
  return {
    removed,
    moved,
    added
  };
}
function resetSpan(data, spanDatum, collapseMode) {
  const { span } = spanDatum;
  switch (collapseMode) {
    case 0 /* Zero */:
      return zeroDataSpan(spanDatum, data.zeroData) ?? axisZeroSpan(span, data);
    case 1 /* Split */:
      return collapseSpanToMidpoint(span);
  }
}
function resetAnimation(newData, oldData, collapseMode) {
  const added = [];
  const removed = [];
  for (const oldSpanDatum of oldData.data) {
    const oldSpan = oldSpanDatum.span;
    const collapsedSpan = resetSpan(oldData, oldSpanDatum, collapseMode);
    removed.push({ from: oldSpan, to: collapsedSpan });
  }
  for (const newSpanDatum of newData.data) {
    const newSpan = newSpanDatum.span;
    const collapsedSpan = resetSpan(newData, newSpanDatum, collapseMode);
    added.push({ from: collapsedSpan, to: newSpan });
  }
  return {
    removed,
    moved: [],
    added
  };
}
function pairUpSpans(newData, oldData, collapseMode) {
  if (!isValidScaling(newData) || !isValidScaling(oldData))
    return;
  if (!validateCategorySorting(newData, oldData))
    return;
  const axisContext = spanAxisContext(newData, oldData);
  if (axisContext == null) {
    return resetAnimation(newData, oldData, collapseMode);
  } else if (axisContext.axisValues.length === axisContext.oldDataAxisIndices.length + axisContext.newDataAxisIndices.length + 2) {
    return replotXAnimation(newData, oldData);
  } else {
    return phaseAnimation(axisContext, newData, oldData, collapseMode);
  }
}

// packages/ag-charts-community/src/chart/series/cartesian/lineUtil.ts
function interpolatePoints(points, interpolation) {
  const pointsIter = points.map((point) => point.point);
  let spans = linearPoints(pointsIter);
  switch (interpolation.type) {
    case "linear":
      break;
    case "smooth":
      spans = smoothPoints(pointsIter, interpolation.tension);
      break;
    case "step":
      spans = stepPoints(pointsIter, interpolation.position);
      break;
  }
  return spans.map(function spanToLinePathSpan(span, i) {
    return {
      span,
      xValue0: points[i].xDatum,
      yValue0: points[i].yDatum,
      xValue1: points[i + 1].xDatum,
      yValue1: points[i + 1].yDatum
    };
  });
}
function pointsEq(a, b, delta5 = 1e-3) {
  return Math.abs(a.x - b.x) < delta5 && Math.abs(a.y - b.y) < delta5;
}
function plotLinePathStroke({ path }, spans) {
  let lastPoint;
  for (const { span } of spans) {
    const [start2, end3] = spanRange(span);
    const join = lastPoint != null && pointsEq(lastPoint, start2) ? 2 /* Skip */ : 0 /* MoveTo */;
    plotSpan(path, span, join, false);
    lastPoint = end3;
  }
}
function plotInterpolatedLinePathStroke(ratio2, path, spans) {
  let lastPoint;
  for (const span of spans) {
    const [start2, end3] = interpolatedSpanRange(span.from, span.to, ratio2);
    const join = lastPoint != null && pointsEq(lastPoint, start2) ? 2 /* Skip */ : 0 /* MoveTo */;
    plotInterpolatedSpans(path.path, span.from, span.to, ratio2, join, false);
    lastPoint = end3;
  }
}
function prepareLinePathStrokeAnimationFns(status, spans, visibleToggleMode, targetOpacity = 1) {
  const removePhaseFn = (ratio2, path) => plotInterpolatedLinePathStroke(ratio2, path, spans.removed);
  const updatePhaseFn = (ratio2, path) => plotInterpolatedLinePathStroke(ratio2, path, spans.moved);
  const addPhaseFn = (ratio2, path) => plotInterpolatedLinePathStroke(ratio2, path, spans.added);
  const pathProperties = prepareLinePathPropertyAnimation(status, visibleToggleMode, targetOpacity);
  return { status, path: { addPhaseFn, updatePhaseFn, removePhaseFn }, pathProperties };
}
function prepareLinePathPropertyAnimation(status, visibleToggleMode, targetOpacity = 1) {
  const phase = visibleToggleMode === "none" ? "updated" : status;
  const result = {
    fromFn(path, datum) {
      const out = { phase: NODE_UPDATE_STATE_TO_PHASE_MAPPING[phase] };
      const segments = path.previousDatum ?? datum;
      if (segments != null) {
        out.segments = segments;
      }
      if (status === "removed") {
        out.finish = { visible: false };
      } else if (status === "added") {
        out.start = { visible: true };
      }
      return out;
    },
    toFn(_path, datum) {
      const out = { phase: NODE_UPDATE_STATE_TO_PHASE_MAPPING[phase] };
      const segments = datum;
      if (segments != null) {
        out.segments = segments;
      }
      return out;
    }
  };
  if (visibleToggleMode === "fade") {
    return {
      fromFn(path, datum) {
        const opacity = status === "added" ? 0 : targetOpacity;
        const segments = status === "removed" ? path.previousDatum ?? datum : datum;
        return { ...result.fromFn(path, datum), opacity, segments };
      },
      toFn(path, datum) {
        const opacity = status === "removed" ? 0 : targetOpacity;
        const segments = status === "removed" ? path.previousDatum ?? datum : datum;
        return { ...result.toFn(path, datum), opacity, segments };
      }
    };
  }
  return result;
}
function prepareLinePathAnimation(newData, oldData, diff9, targetOpacity = 1) {
  const isCategoryBased = newData.scales.x?.type === "category";
  const wasCategoryBased = oldData.scales.x?.type === "category";
  if (isCategoryBased !== wasCategoryBased || !isScaleValid(newData.scales.x) || !isScaleValid(oldData.scales.x)) {
    return;
  }
  if (newData.strokeData == null || oldData.strokeData == null) {
    return;
  }
  let status = "updated";
  if (oldData.visible && !newData.visible) {
    status = "removed";
  } else if (!oldData.visible && newData.visible) {
    status = "added";
  }
  const strokeSpans = pairUpSpans(
    { scales: newData.scales, data: newData.strokeData.spans },
    { scales: oldData.scales, data: oldData.strokeData.spans },
    1 /* Split */
  );
  if (strokeSpans == null)
    return;
  const stroke3 = prepareLinePathStrokeAnimationFns(status, strokeSpans, "fade", targetOpacity);
  const hasMotion = (diff9?.changed ?? true) || !areScalingEqual(newData.scales.x, oldData.scales.x) || !areScalingEqual(newData.scales.y, oldData.scales.y) || status !== "updated";
  return { status, stroke: stroke3, hasMotion };
}

// packages/ag-charts-community/src/chart/series/cartesian/barUtil.ts
function checkCrisp(scale2, visibleRange, smallestDataInterval, largestDataInterval) {
  if (visibleRange != null) {
    const [visibleMin, visibleMax] = visibleRange;
    const isZoomed = visibleMin !== 0 || visibleMax !== 1;
    if (isZoomed)
      return false;
  }
  if (ContinuousScale.is(scale2)) {
    const spacing = scale2.calcBandwidth(largestDataInterval) - scale2.calcBandwidth(smallestDataInterval);
    if (spacing > 0 && spacing < 1)
      return false;
  }
  if (BandScale.is(scale2)) {
    const { bandwidth, step } = scale2;
    if (bandwidth > 0 && bandwidth < 1)
      return false;
    const spacing = step - bandwidth;
    if (spacing > 0 && spacing < 1)
      return false;
  }
  return true;
}
var isDatumNegative = (datum) => {
  return isNegative(datum.yValue ?? 0);
};
function collapsedStartingBarPosition(isVertical, axes, mode) {
  const { startingX, startingY } = getStartingValues(isVertical, axes);
  const calculate = (datum, prevDatum) => {
    let x = isVertical ? datum.x : startingX;
    let y = isVertical ? startingY : datum.y;
    let width2 = isVertical ? datum.width : 0;
    let height2 = isVertical ? 0 : datum.height;
    const { opacity = 1 } = datum;
    if (prevDatum && (Number.isNaN(x) || Number.isNaN(y))) {
      ({ x, y } = prevDatum);
      width2 = isVertical ? prevDatum.width : 0;
      height2 = isVertical ? 0 : prevDatum.height;
      if (isVertical && !isDatumNegative(prevDatum)) {
        y += prevDatum.height;
      } else if (!isVertical && isDatumNegative(prevDatum)) {
        x += prevDatum.width;
      }
    }
    let clipBBox;
    if (datum.clipBBox == null) {
      clipBBox = void 0;
    } else if (isDatumNegative(datum)) {
      clipBBox = isVertical ? new BBox(x, y - height2, width2, height2) : new BBox(x - width2, y, width2, height2);
    } else {
      clipBBox = new BBox(x, y, width2, height2);
    }
    return { x, y, width: width2, height: height2, clipBBox, opacity };
  };
  return { isVertical, calculate, mode };
}
function midpointStartingBarPosition(isVertical, mode) {
  return {
    isVertical,
    calculate: (datum) => {
      return {
        x: isVertical ? datum.x : datum.x + datum.width / 2,
        y: isVertical ? datum.y + datum.height / 2 : datum.y,
        width: isVertical ? datum.width : 0,
        height: isVertical ? 0 : datum.height,
        clipBBox: datum.clipBBox,
        opacity: datum.opacity ?? 1
      };
    },
    mode
  };
}
function prepareBarAnimationFunctions(initPos, unknownStatus) {
  const isRemoved = (datum) => datum == null || Number.isNaN(datum.x) || Number.isNaN(datum.y);
  const fromFn = (rect2, datum, status) => {
    if (status === "updated" && isRemoved(datum)) {
      status = "removed";
    } else if (status === "updated" && isRemoved(rect2.previousDatum)) {
      status = "added";
    }
    let source;
    if (status === "unknown" || status === "added") {
      if (rect2.previousDatum == null && initPos.mode === "fade") {
        source = {
          ...resetBarSelectionsFn(rect2, datum),
          opacity: 0
        };
      } else {
        source = initPos.calculate(datum, rect2.previousDatum);
      }
      if (status === "unknown") {
        status = unknownStatus;
      }
    } else {
      source = {
        x: rect2.x,
        y: rect2.y,
        width: rect2.width,
        height: rect2.height,
        clipBBox: rect2.clipBBox,
        opacity: rect2.opacity ?? 1
      };
    }
    const phase = NODE_UPDATE_STATE_TO_PHASE_MAPPING[status];
    return { ...source, phase };
  };
  const toFn = (rect2, datum, status) => {
    if (status === "removed" && rect2.datum == null && initPos.mode === "fade") {
      return { ...resetBarSelectionsFn(rect2, datum), opacity: 0 };
    } else if (status === "removed" || isRemoved(datum)) {
      return initPos.calculate(datum, rect2.previousDatum);
    } else {
      return {
        x: datum.x,
        y: datum.y,
        width: datum.width,
        height: datum.height,
        clipBBox: datum.clipBBox,
        opacity: datum.opacity ?? 1
      };
    }
  };
  const applyFn = (rect2, datum, status) => {
    rect2.resetAnimationProperties(datum.x, datum.y, datum.width, datum.height, datum.opacity ?? 1, datum.clipBBox);
    rect2.crisp = status === "end" && (rect2.datum?.crisp ?? false);
  };
  return { toFn, fromFn, applyFn };
}
function getStartingValues(isVertical, axes) {
  const axis = axes[isVertical ? "y" /* Y */ : "x" /* X */];
  let startingX = Infinity;
  let startingY = 0;
  if (!axis) {
    return { startingX, startingY };
  }
  if (isVertical) {
    startingY = axis.scale.convert(ContinuousScale.is(axis.scale) ? 0 : Math.max(...axis.range));
  } else {
    startingX = axis.scale.convert(ContinuousScale.is(axis.scale) ? 0 : Math.min(...axis.range));
  }
  return { startingX, startingY };
}
function resetBarSelectionsFn(rect2, { x, y, width: width2, height: height2, clipBBox, opacity = 1 }) {
  return { x, y, width: width2, height: height2, clipBBox, opacity, crisp: rect2.datum?.crisp ?? false };
}
function resetBarSelectionsDirect(selections) {
  for (const selection of selections) {
    const nodes = selection.nodes();
    selection.batchedUpdate(function resetBarNodes() {
      for (const node of nodes) {
        const datum = node.datum;
        if (datum == null)
          continue;
        node.resetAnimationProperties(
          datum.x,
          datum.y,
          datum.width,
          datum.height,
          datum.opacity ?? 1,
          datum.clipBBox
        );
        node.crisp = datum.crisp ?? false;
      }
      selection.cleanup();
    });
  }
}
function computeBarFocusBounds(series, datum) {
  if (datum === void 0)
    return void 0;
  const { x, y, width: width2, height: height2 } = datum;
  return Transformable.toCanvas(series.contentGroup, new BBox(x, y, width2, height2));
}

// packages/ag-charts-community/src/chart/series/cartesian/cartesianSeriesUtil.ts
function upsertNodeDatum(ctx, params, createNode, updateNode) {
  const canReuseNode = ctx.canIncrementallyUpdate && ctx.nodeIndex < ctx.nodes.length;
  let node;
  if (canReuseNode) {
    node = ctx.nodes[ctx.nodeIndex];
    updateNode(ctx, node, params);
  } else {
    node = createNode(ctx, params);
    if (node != null) {
      ctx.nodes.push(node);
    }
  }
  ctx.nodeIndex++;
  return node;
}

// packages/ag-charts-community/src/chart/series/cartesian/areaUtil.ts
function plotAreaPathFill({ path }, { spans, phantomSpans }) {
  let phantomSpanIndex = 0;
  let sp = { x: Number.NaN, y: Number.NaN };
  let pp = { x: Number.NaN, y: Number.NaN };
  for (let i = 0; i < spans.length; i += 1) {
    const { span } = spans[i];
    const { span: phantomSpan } = phantomSpans[i];
    const { 0: sp0, 1: sp1 } = spanRange(span);
    const { 0: pp0, 1: pp1 } = spanRange(phantomSpan);
    if (pointsEq(sp, sp0) && pointsEq(pp, pp0)) {
      plotSpan(path, span, 2 /* Skip */, false);
    } else {
      for (let j = i - 1; j >= phantomSpanIndex; j -= 1) {
        plotSpan(path, phantomSpans[j].span, 1 /* LineTo */, true);
      }
      path.closePath();
      plotSpan(path, span, 0 /* MoveTo */, false);
      phantomSpanIndex = i;
    }
    sp = sp1;
    pp = pp1;
  }
  for (let j = spans.length - 1; j >= phantomSpanIndex; j -= 1) {
    plotSpan(path, phantomSpans[j].span, 1 /* LineTo */, true);
  }
  path.closePath();
}
function plotInterpolatedAreaSeriesFillSpans(ratio2, { path }, spans, fillPhantomSpans) {
  for (let i = 0; i < spans.length; i += 1) {
    const span = spans[i];
    const reversedPhantomSpan = fillPhantomSpans[i];
    plotInterpolatedSpans(path, span.from, span.to, ratio2, 0 /* MoveTo */, false);
    plotInterpolatedSpans(path, reversedPhantomSpan.from, reversedPhantomSpan.to, ratio2, 1 /* LineTo */, true);
    path.closePath();
  }
}
function prepareAreaFillAnimationFns(status, spans, fillPhantomSpans, visibleToggleMode) {
  const removePhaseFn = (ratio2, path) => plotInterpolatedAreaSeriesFillSpans(ratio2, path, spans.removed, fillPhantomSpans.removed);
  const updatePhaseFn = (ratio2, path) => plotInterpolatedAreaSeriesFillSpans(ratio2, path, spans.moved, fillPhantomSpans.moved);
  const addPhaseFn = (ratio2, path) => plotInterpolatedAreaSeriesFillSpans(ratio2, path, spans.added, fillPhantomSpans.added);
  const pathProperties = prepareLinePathPropertyAnimation(status, visibleToggleMode);
  return { status, path: { addPhaseFn, updatePhaseFn, removePhaseFn }, pathProperties };
}
function prepareAreaPathAnimation(newData, oldData) {
  const isCategoryBased = newData.scales.x?.type === "category";
  const wasCategoryBased = oldData.scales.x?.type === "category";
  if (isCategoryBased !== wasCategoryBased || !isScaleValid(newData.scales.x) || !isScaleValid(oldData.scales.x)) {
    return;
  }
  let status = "updated";
  if (oldData.visible && !newData.visible) {
    status = "removed";
  } else if (!oldData.visible && newData.visible) {
    status = "added";
  }
  const fillSpans = pairUpSpans(
    { scales: newData.scales, data: newData.fillData.spans },
    { scales: oldData.scales, data: oldData.fillData.spans },
    0 /* Zero */
  );
  if (fillSpans == null)
    return;
  const fillPhantomSpans = pairUpSpans(
    { scales: newData.scales, data: newData.fillData.phantomSpans },
    { scales: oldData.scales, data: oldData.fillData.phantomSpans },
    0 /* Zero */
  );
  if (fillPhantomSpans == null)
    return;
  const strokeSpans = pairUpSpans(
    {
      scales: newData.scales,
      data: newData.strokeData.spans,
      zeroData: newData.fillData.phantomSpans
    },
    {
      scales: oldData.scales,
      data: oldData.strokeData.spans,
      zeroData: oldData.fillData.phantomSpans
    },
    0 /* Zero */
  );
  if (strokeSpans == null)
    return;
  const fadeMode = "none";
  const fill = prepareAreaFillAnimationFns(status, fillSpans, fillPhantomSpans, fadeMode);
  const stroke3 = prepareLinePathStrokeAnimationFns(status, strokeSpans, fadeMode);
  return { status, fill, stroke: stroke3 };
}

// packages/ag-charts-community/src/chart/series/cartesian/diffUtil.ts
function calculateDataDiff(seriesId, datumSelection, getDatumId, contextNodeData, previousContextNodeData, processedData, processedDataUpdated) {
  let dataDiff = processedData?.reduced?.diff?.[seriesId];
  if (dataDiff?.changed) {
    return dataDiff;
  }
  if (!processedDataUpdated) {
    return {
      changed: false,
      added: /* @__PURE__ */ new Set(),
      updated: /* @__PURE__ */ new Set(),
      removed: /* @__PURE__ */ new Set(),
      moved: /* @__PURE__ */ new Set()
    };
  }
  const scalingChanged = hasScalingChanged(contextNodeData, previousContextNodeData);
  if (dataDiff == null && processedData?.reduced?.diff != null) {
    dataDiff = {
      changed: true,
      added: /* @__PURE__ */ new Set(),
      updated: /* @__PURE__ */ new Set(),
      removed: /* @__PURE__ */ new Set(),
      moved: /* @__PURE__ */ new Set()
    };
    if (scalingChanged) {
      dataDiff.updated = new Set(Array.from(datumSelection, ({ datum }) => getDatumId(datum)));
    } else {
      dataDiff.added = new Set(Array.from(datumSelection, ({ datum }) => getDatumId(datum)));
    }
  } else if (scalingChanged) {
    dataDiff = {
      changed: true,
      added: /* @__PURE__ */ new Set(),
      updated: new Set(Array.from(datumSelection, ({ datum }) => getDatumId(datum))),
      removed: /* @__PURE__ */ new Set(),
      moved: /* @__PURE__ */ new Set()
    };
  }
  return dataDiff;
}
function isGroupScaleContext(ctx) {
  return typeof ctx === "object" && ctx !== null && "groupScale" in ctx;
}
function hasScalingChanged(contextNodeData, previousContextNodeData) {
  if (!previousContextNodeData)
    return false;
  const scales = contextNodeData.scales;
  const prevScales = previousContextNodeData.scales;
  if (!areScalingEqual(scales.x, prevScales.x))
    return true;
  if (!areScalingEqual(scales.y, prevScales.y))
    return true;
  if (!isGroupScaleContext(contextNodeData) || !isGroupScaleContext(previousContextNodeData))
    return false;
  const groupScale = contextNodeData.groupScale;
  const prevGroupScale = previousContextNodeData.groupScale;
  return !areScalingEqual(groupScale, prevGroupScale);
}

// packages/ag-charts-community/src/chart/series/cartesian/markerUtil.ts
function markerFadeInAnimation({ id }, animationManager, status, options, ...markerSelections) {
  const params = {
    ...options,
    phase: options?.phase ?? (status ? NODE_UPDATE_STATE_TO_PHASE_MAPPING[status] : "trailing")
  };
  staticFromToMotion(id, "markers", animationManager, markerSelections, { opacity: 0 }, { opacity: 1 }, params);
  for (const s of markerSelections) {
    s.cleanup();
  }
}
function markerScaleInAnimation({ id }, animationManager, ...markerSelections) {
  staticFromToMotion(
    id,
    "markers",
    animationManager,
    markerSelections,
    { scalingX: 0, scalingY: 0 },
    { scalingX: 1, scalingY: 1 },
    { phase: "initial" }
  );
  for (const s of markerSelections) {
    s.cleanup();
  }
}
function markerSwipeScaleInAnimation({ id, nodeDataDependencies }, animationManager, options, ...markerSelections) {
  const seriesWidth = nodeDataDependencies.seriesRectWidth;
  const fromFn = (_, datum) => {
    const x = datum.midPoint?.x ?? seriesWidth;
    let delay = clamp(0, inverseEaseOut(x / seriesWidth), 1);
    if (Number.isNaN(delay)) {
      delay = 0;
    }
    return {
      scalingX: 0,
      scalingY: 0,
      delay: options?.delay ?? delay,
      duration: options?.duration ?? QUICK_TRANSITION,
      phase: options?.phase ?? "initial",
      start: options?.start,
      finish: options?.finish
    };
  };
  const toFn = () => {
    return { scalingX: 1, scalingY: 1 };
  };
  fromToMotion(id, "markers", animationManager, markerSelections, { fromFn, toFn });
}
function resetMarkerFn(_node) {
  return { opacity: 1, scalingX: 1, scalingY: 1 };
}
function resetMarkerSelectionsDirect(selections) {
  for (const selection of selections) {
    const nodes = selection.nodes();
    selection.batchedUpdate(function resetMarkerNodes() {
      for (const node of nodes) {
        const datum = node.datum;
        if (datum?.point == null)
          continue;
        const { x, y } = datum.point;
        if (!Number.isFinite(x) || !Number.isFinite(y))
          continue;
        node.resetAnimationProperties(x, y, node.size, 1, 1, 1);
      }
      selection.cleanup();
    });
  }
}
function resetMarkerPositionFn(_node, datum) {
  return {
    x: datum.point?.x ?? Number.NaN,
    y: datum.point?.y ?? Number.NaN,
    scalingCenterX: datum.point?.x ?? Number.NaN,
    scalingCenterY: datum.point?.y ?? Number.NaN
  };
}
function computeMarkerFocusBounds(series, { datumIndex }) {
  const nodeData = series.getNodeData();
  if (nodeData === void 0)
    return void 0;
  const datum = nodeData[datumIndex];
  const { point } = datum ?? {};
  if (datum == null || point == null)
    return void 0;
  const style2 = series.getFormattedMarkerStyle(datum);
  const anchor = Marker.anchor(style2.shape);
  const size = point.focusSize ?? style2.size;
  const paddedSize = 4 + size;
  const paddedRadius = paddedSize / 2;
  const anchorX = (anchor.x - 0.5) * size;
  const anchorY = (anchor.y - 0.5) * size;
  const x = datum.point.x - paddedRadius - anchorX;
  const y = datum.point.y - paddedRadius - anchorY;
  return Transformable.toCanvas(series.contentGroup, new BBox(x, y, paddedSize, paddedSize));
}
function markerEnabled(dataCount, scale2, marker, markerStyle = marker) {
  const enabled = markerStyle.enabled ?? marker.enabled;
  if (!enabled)
    return false;
  const minSpacing = 1;
  const step = scale2.step ?? findRangeExtent(scale2.range) / Math.max(1, dataCount);
  return step > minSpacing;
}
function getMarkerStyles(series, line, marker, inheritedStyle) {
  inheritedStyle ?? (inheritedStyle = {
    stroke: line.stroke,
    strokeOpacity: line.strokeOpacity,
    strokeWidth: line.strokeWidth
  });
  return highlightStates.reduce(
    (styles, state) => {
      styles[state] = series.getMarkerStyle(
        marker,
        {},
        void 0,
        { highlightState: state },
        void 0,
        inheritedStyle
      );
      return styles;
    },
    {}
  );
}

// packages/ag-charts-community/src/chart/series/cartesian/pathUtil.ts
function pathSwipeInAnimation({ id, visible, nodeDataDependencies }, animationManager, ...paths) {
  const { seriesRectWidth: width2, seriesRectHeight: height2 } = nodeDataDependencies;
  staticFromToMotion(
    id,
    "path_properties",
    animationManager,
    paths,
    { clipX: 0 },
    { clipX: width2 },
    {
      phase: "initial",
      start: { clip: true, clipY: height2, visible },
      finish: { clip: false, visible }
    }
  );
}
function pathFadeInAnimation({ id }, subId, animationManager, phase = "add", ...selection) {
  staticFromToMotion(id, subId, animationManager, selection, { opacity: 0 }, { opacity: 1 }, { phase });
}
function buildResetPathFn(opts) {
  return (_node) => ({
    visible: opts.getVisible(),
    opacity: opts.getOpacity(),
    clipScalingX: 1,
    clip: false
  });
}
function updateClipPath({ nodeDataDependencies }, path) {
  const toFinite = (value) => Number.isFinite(value) ? value : 0;
  path.clipX = toFinite(nodeDataDependencies.seriesRectWidth);
  path.clipY = toFinite(nodeDataDependencies.seriesRectHeight);
}

// packages/ag-charts-community/src/chart/series/polar/polarSeries.ts
var DEFAULT_POLAR_DIRECTION_KEYS = {
  ["angle" /* Angle */]: ["angleKey"],
  ["radius" /* Radius */]: ["radiusKey"]
};
var DEFAULT_POLAR_DIRECTION_NAMES = {
  ["angle" /* Angle */]: ["angleName"],
  ["radius" /* Radius */]: ["radiusName"]
};
var PolarSeries = class extends DataModelSeries {
  constructor({
    categoryKey,
    pickModes = [1 /* NEAREST_NODE */, 0 /* EXACT_SHAPE_MATCH */],
    canHaveAxes = false,
    animationResetFns,
    ...opts
  }) {
    super({
      ...opts,
      categoryKey,
      pickModes,
      canHaveAxes
    });
    this.directions = ["angle" /* Angle */, "radius" /* Radius */];
    this.itemGroup = this.contentGroup.appendChild(new Group({ name: "items" }));
    this.nodeData = [];
    this.itemSelection = Selection.select(
      this.itemGroup,
      () => this.nodeFactory(),
      false
    );
    this.labelSelection = Selection.select(
      this.labelGroup,
      () => this.labelFactory(),
      false
    );
    this.highlightSelection = Selection.select(
      this.highlightNodeGroup,
      () => this.nodeFactory()
    );
    this.highlightLabelSelection = Selection.select(
      this.highlightLabelGroup,
      () => this.labelFactory()
    );
    /**
     * The center of the polar series (for example, the center of a pie).
     * If the polar chart has multiple series, all of them will have their
     * center set to the same value as a result of the polar chart layout.
     * The center coordinates are not supposed to be set by the user.
     */
    this.centerX = 0;
    this.centerY = 0;
    /**
     * The maximum radius the series can use.
     * This value is set automatically as a result of the polar chart layout
     * and is not supposed to be set by the user.
     */
    this.radius = 0;
    /**
     * The largest marker size of any series in the same chart. Used to determine the extent of pointer interaction
     * with the series.
     */
    this.maxChartMarkerSize = 0;
    this.animationResetFns = animationResetFns;
    this.animationState = new StateMachine(
      "empty",
      {
        empty: {
          update: {
            target: "ready",
            action: (data) => this.animateEmptyUpdateReady(data)
          },
          reset: "empty",
          skip: "ready"
        },
        ready: {
          updateData: "waiting",
          clear: "clearing",
          highlight: (data) => this.animateReadyHighlight(data),
          highlightMarkers: (data) => this.animateReadyHighlightMarkers(data),
          resize: (data) => this.animateReadyResize(data),
          reset: "empty",
          skip: "ready"
        },
        waiting: {
          update: {
            target: "ready",
            action: (data) => this.animateWaitingUpdateReady(data)
          },
          reset: "empty",
          skip: "ready"
        },
        clearing: {
          update: {
            target: "empty",
            action: (data) => this.animateClearingUpdateEmpty(data)
          },
          reset: "empty",
          skip: "ready"
        }
      },
      () => this.checkProcessedDataAnimatable()
    );
    this.cleanup.register(
      this.ctx.eventsHub.on("legend:item-click", (event) => this.onLegendItemClick(event)),
      this.ctx.eventsHub.on("legend:item-double-click", (event) => this.onLegendItemDoubleClick(event))
    );
  }
  getItemNodes() {
    return [...this.itemGroup.children()];
  }
  getNodeData() {
    return this.nodeData;
  }
  getKeyAxis(direction) {
    if (direction === "angle" /* Angle */)
      return this.properties.angleKeyAxis;
    if (direction === "radius" /* Radius */)
      return this.properties.radiusKeyAxis;
  }
  setZIndex(zIndex) {
    super.setZIndex(zIndex);
    this.contentGroup.zIndex = [zIndex, 1 /* FOREGROUND */];
    this.highlightGroup.zIndex = [zIndex, 2 /* HIGHLIGHT */];
    this.labelGroup.zIndex = [zIndex, 3 /* LABEL */];
  }
  resetAnimation(phase) {
    if (phase === "initial") {
      this.animationState.transition("reset");
    } else if (phase === "ready") {
      this.animationState.transition("skip");
    }
  }
  labelFactory() {
    const text2 = new Text();
    text2.pointerEvents = 1 /* None */;
    return text2;
  }
  getInnerRadius() {
    return 0;
  }
  computeLabelsBBox(_options, _seriesRect) {
    return null;
  }
  getShapeFillBBox() {
    const outerRadius = this.radius;
    return {
      series: new BBox(-outerRadius, -outerRadius, outerRadius * 2, outerRadius * 2),
      axis: new BBox(-outerRadius, -outerRadius, outerRadius * 2, outerRadius * 2)
    };
  }
  resetAllAnimation() {
    const { item, label } = this.animationResetFns ?? {};
    this.ctx.animationManager.stopByAnimationGroupId(this.id);
    if (item) {
      resetMotion([this.itemSelection, this.highlightSelection], item);
    }
    if (label) {
      resetMotion([this.labelSelection, this.highlightLabelSelection], label);
    }
    this.itemSelection.cleanup();
    this.labelSelection.cleanup();
    this.highlightSelection.cleanup();
    this.highlightLabelSelection.cleanup();
  }
  animateEmptyUpdateReady(_data) {
    this.ctx.animationManager.skipCurrentBatch();
    this.resetAllAnimation();
  }
  animateWaitingUpdateReady(_data) {
    this.ctx.animationManager.skipCurrentBatch();
    this.resetAllAnimation();
  }
  animateReadyHighlight(_data) {
    const { item, label } = this.animationResetFns ?? {};
    if (item) {
      resetMotion([this.highlightSelection], item);
    }
    if (label) {
      resetMotion([this.highlightLabelSelection], label);
    }
  }
  animateReadyHighlightMarkers(_data) {
  }
  animateReadyResize(_data) {
    this.resetAllAnimation();
  }
  animateClearingUpdateEmpty(_data) {
    this.ctx.animationManager.skipCurrentBatch();
    this.resetAllAnimation();
  }
  computeFocusBounds(opts) {
    const datum = this.getNodeData()?.[opts.datumIndex];
    if (datum !== void 0) {
      return this.itemSelection.select((node) => node instanceof Path && node.datum === datum)[0];
    }
    return void 0;
  }
  getSeriesRange() {
    return [Number.NaN, Number.NaN];
  }
  isSeriesHighlighted(highlightedDatum, legendItemValues) {
    if (!this.properties.highlight.enabled) {
      return false;
    }
    const { series, legendItemName: activeLegendItemName, datumIndex } = highlightedDatum ?? {};
    const legendItemName = typeof datumIndex === "number" ? legendItemValues?.[datumIndex] : void 0;
    return series === this || legendItemName != null && legendItemName === activeLegendItemName;
  }
};

// packages/ag-charts-community/src/chart/series/hierarchy/hierarchySeriesProperties.ts
var HierarchyHighlightState = /* @__PURE__ */ ((HierarchyHighlightState3) => {
  HierarchyHighlightState3[HierarchyHighlightState3["None"] = 0] = "None";
  HierarchyHighlightState3[HierarchyHighlightState3["Item"] = 1] = "Item";
  HierarchyHighlightState3[HierarchyHighlightState3["OtherItem"] = 2] = "OtherItem";
  HierarchyHighlightState3[HierarchyHighlightState3["Branch"] = 3] = "Branch";
  HierarchyHighlightState3[HierarchyHighlightState3["OtherBranch"] = 4] = "OtherBranch";
  return HierarchyHighlightState3;
})(HierarchyHighlightState || {});
function toHierarchyHighlightString(state) {
  const unreachable = (a) => a;
  switch (state) {
    case 1 /* Item */:
      return "highlighted-item";
    case 2 /* OtherItem */:
      return "unhighlighted-item";
    case 3 /* Branch */:
      return "highlighted-branch";
    case 4 /* OtherBranch */:
      return "unhighlighted-branch";
    case 0 /* None */:
      return "none";
    default:
      return unreachable(state);
  }
}
var HierarchySeriesProperties = class extends SeriesProperties {
  constructor() {
    super(...arguments);
    this.childrenKey = "children";
    this.fills = Object.values(DEFAULT_FILLS);
    this.strokes = Object.values(DEFAULT_STROKES);
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], HierarchySeriesProperties.prototype, "childrenKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HierarchySeriesProperties.prototype, "sizeKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HierarchySeriesProperties.prototype, "colorKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HierarchySeriesProperties.prototype, "colorName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HierarchySeriesProperties.prototype, "fills", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HierarchySeriesProperties.prototype, "strokes", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HierarchySeriesProperties.prototype, "colorRange", 2);

// packages/ag-charts-community/src/chart/series/hierarchy/hierarchySeries.ts
var _HierarchyNode = class _HierarchyNode {
  constructor(series, itemId, datumIndex, datum, sizeValue, colorValue, sumSize, depth, parent, children, style2) {
    this.series = series;
    this.itemId = itemId;
    this.datumIndex = datumIndex;
    this.datum = datum;
    this.sizeValue = sizeValue;
    this.colorValue = colorValue;
    this.sumSize = sumSize;
    this.depth = depth;
    this.parent = parent;
    this.children = children;
    this.style = style2;
    this.midPoint = { x: 0, y: 0 };
  }
  get hasChildren() {
    return this.children.length > 0;
  }
  walk(callback2, order = _HierarchyNode.Walk.PreOrder) {
    if (order === _HierarchyNode.Walk.PreOrder) {
      callback2(this);
    }
    for (const child of this.children) {
      child.walk(callback2, order);
    }
    if (order === _HierarchyNode.Walk.PostOrder) {
      callback2(this);
    }
  }
  find(predicate) {
    if (predicate(this)) {
      return this;
    }
    for (const child of this.children) {
      const childResult = child.find(predicate);
      if (childResult != void 0) {
        return childResult;
      }
    }
    return void 0;
  }
  *[Symbol.iterator]() {
    yield this;
    for (const child of this.children) {
      yield* child;
    }
  }
};
_HierarchyNode.Walk = {
  PreOrder: 0,
  PostOrder: 1
};
var HierarchyNode = _HierarchyNode;
var HierarchySeries = class extends Series {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      pickModes: [1 /* NEAREST_NODE */, 0 /* EXACT_SHAPE_MATCH */]
    });
    this.colorDomain = [0, 0];
    this.maxDepth = 0;
    this.colorScale = new ColorScale();
    this.animationState = new StateMachine(
      "empty",
      {
        empty: {
          update: {
            target: "ready",
            action: (data) => this.animateEmptyUpdateReady(data)
          },
          reset: "empty",
          skip: "ready"
        },
        ready: {
          updateData: "waiting",
          clear: "clearing",
          highlight: (data) => this.animateReadyHighlight(data),
          resize: (data) => this.animateReadyResize(data),
          reset: "empty",
          skip: "ready"
        },
        waiting: {
          update: {
            target: "ready",
            action: (data) => this.animateWaitingUpdateReady(data)
          },
          reset: "empty",
          skip: "ready"
        },
        clearing: {
          update: {
            target: "empty",
            action: (data) => this.animateClearingUpdateEmpty(data)
          },
          reset: "empty",
          skip: "ready"
        }
      },
      () => this.checkProcessedDataAnimatable()
    );
  }
  resetAnimation(phase) {
    if (phase === "initial") {
      this.animationState.transition("reset");
    } else if (phase === "ready") {
      this.animationState.transition("skip");
    }
  }
  processData() {
    const { NodeClass } = this;
    const { childrenKey, sizeKey, colorKey, colorRange } = this.properties;
    let maxDepth = 0;
    let minColor = Infinity;
    let maxColor = -Infinity;
    const createNode = (datum, indexPath, parent) => {
      const depth = parent.depth == null ? 0 : parent.depth + 1;
      const children = childrenKey == null ? void 0 : datum[childrenKey];
      const isLeaf = children == null || children.length === 0;
      let sizeValue = sizeKey == null ? void 0 : datum[sizeKey];
      if (Number.isFinite(sizeValue)) {
        sizeValue = Math.max(sizeValue, 0);
      } else {
        sizeValue = isLeaf ? 1 : 0;
      }
      const sumSize = sizeValue;
      maxDepth = Math.max(maxDepth, depth);
      const colorValue = colorKey == null ? void 0 : datum[colorKey];
      if (typeof colorValue === "number") {
        minColor = Math.min(minColor, colorValue);
        maxColor = Math.max(maxColor, colorValue);
      }
      const style2 = this.getItemStyle({ datumIndex: indexPath, datum, depth, colorValue }, isLeaf, false);
      return appendChildren(
        new NodeClass(
          this,
          createDatumId(indexPath.join(";")),
          indexPath,
          datum,
          sizeValue,
          colorValue,
          sumSize,
          depth,
          parent,
          [],
          style2
        ),
        children
      );
    };
    const appendChildren = (node, data) => {
      const { datumIndex } = node;
      if (data) {
        for (const [childIndex, datum] of data.entries()) {
          const child = createNode(datum, datumIndex.concat(childIndex), node);
          node.children.push(child);
          node.sumSize += child.sumSize;
        }
      }
      return node;
    };
    const rootNode = appendChildren(
      new NodeClass(this, "root", [], void 0, 0, void 0, 0, void 0, void 0, [], {}),
      this.data?.data
    );
    const colorDomain = [minColor, maxColor];
    this.colorScale.domain = minColor < maxColor ? [minColor, maxColor] : [0, 1];
    this.colorScale.range = colorRange ?? ["black"];
    this.colorScale.update();
    this.rootNode = rootNode;
    this.maxDepth = maxDepth;
    this.colorDomain = colorDomain;
  }
  update({ seriesRect }) {
    this.updateSelections();
    this.updateNodes();
    const animationData = this.getAnimationData();
    const resize = this.checkResize(seriesRect);
    if (resize) {
      this.animationState.transition("resize", animationData);
    }
    this.animationState.transition("update", animationData);
  }
  resetAllAnimation(_data) {
    this.ctx.animationManager.stopByAnimationGroupId(this.id);
  }
  animateEmptyUpdateReady(data) {
    this.ctx.animationManager.skipCurrentBatch();
    this.resetAllAnimation(data);
  }
  animateWaitingUpdateReady(data) {
    this.ctx.animationManager.skipCurrentBatch();
    this.resetAllAnimation(data);
  }
  animateReadyHighlight(_data) {
  }
  animateReadyResize(data) {
    this.resetAllAnimation(data);
  }
  animateClearingUpdateEmpty(data) {
    this.ctx.animationManager.skipCurrentBatch();
    this.resetAllAnimation(data);
  }
  getAnimationData() {
    return {};
  }
  isProcessedDataAnimatable() {
    return true;
  }
  checkProcessedDataAnimatable() {
    if (!this.isProcessedDataAnimatable()) {
      this.ctx.animationManager.skipCurrentBatch();
    }
  }
  findNodeDatum(itemId) {
    return this.rootNode?.find((n) => n.itemId === itemId);
  }
  dataCount() {
    return Number.NaN;
  }
  getSeriesDomain() {
    return { domain: [Number.NaN, Number.NaN] };
  }
  getSeriesRange() {
    return [Number.NaN, Number.NaN];
  }
  getLegendData(legendType) {
    const { colorKey, colorRange } = this.properties;
    const {
      id: seriesId,
      ctx: { legendManager },
      visible
    } = this;
    return legendType === "gradient" && colorKey != null && colorRange != null ? [
      {
        legendType: "gradient",
        enabled: visible && legendManager.getItemEnabled({ seriesId }),
        seriesId,
        series: this.getFormatterContext("color"),
        colorRange,
        colorDomain: this.colorDomain
      }
    ] : [];
  }
  getDatumIdFromData(node) {
    return node.datumIndex.join(":");
  }
  getDatumId(node) {
    return this.getDatumIdFromData(node);
  }
  removeMeIndexPathForIndex(index) {
    return this.datumSelection.at(index + 1)?.datum.datumIndex ?? [];
  }
  removeMeIndexForIndexPath(indexPath) {
    for (const { index, datum } of this.datumSelection) {
      if (arraysEqual(datum.datumIndex, indexPath)) {
        return index - 1;
      }
    }
    return 0;
  }
  pickFocus(opts) {
    if (!this.rootNode?.children.length)
      return void 0;
    const index = clamp(0, opts.datumIndex - opts.datumIndexDelta, this.datumSelection.length - 1);
    const { datumIndexDelta: childDelta, otherIndexDelta: depthDelta } = opts;
    let path = this.removeMeIndexPathForIndex(index);
    const currentNode = path.reduce((n, childIndex) => n.children[childIndex], this.rootNode);
    if (depthDelta > 0 && currentNode.hasChildren) {
      path = [...path, 0];
    } else if (depthDelta < 0 && path.length > 1) {
      path = path.slice(0, -1);
    } else if (depthDelta === 0 && childDelta !== 0) {
      const maxIndex = currentNode.parent.children.length - 1;
      path = path.slice();
      path[path.length - 1] = clamp(0, path.at(-1) + childDelta, maxIndex);
    }
    const nextNode = path.reduce((n, childIndex) => n.children[childIndex], this.rootNode);
    const bounds = this.computeFocusBounds(this.datumSelection.at(index + 1));
    if (bounds == null)
      return;
    return {
      datum: nextNode,
      datumIndex: this.removeMeIndexForIndexPath(path),
      otherIndex: nextNode.depth,
      bounds,
      clipFocusBox: true
    };
  }
  getDatumAriaText(datum, description) {
    if (!(datum instanceof this.NodeClass)) {
      logger_exports.error(`datum is not HierarchyNode: ${JSON.stringify(datum)}`);
      return;
    }
    return this.ctx.localeManager.t("ariaAnnounceHierarchyDatum", {
      level: (datum.depth ?? -1) + 1,
      count: datum.children.length,
      description
    });
  }
  getCategoryValue(_datumIndex) {
    return;
  }
  datumIndexForCategoryValue(_categoryValue) {
    return;
  }
  getActiveHighlightNode() {
    if (!this.properties.highlight.enabled) {
      return void 0;
    }
    const highlightedNode = this.ctx.highlightManager?.getActiveHighlight();
    if (highlightedNode?.series !== this) {
      return void 0;
    }
    return highlightedNode;
  }
  getHierarchyHighlightState(isHighlight, highlightedNode, nodeDatum) {
    if (isHighlight) {
      return 1 /* Item */;
    }
    if (highlightedNode == null) {
      return 0 /* None */;
    }
    const nodeRoot = nodeDatum.datumIndex?.[0];
    const highlightRoot = highlightedNode.datumIndex?.[0];
    if (nodeRoot == null || highlightRoot == null) {
      return 0 /* None */;
    }
    return nodeRoot === highlightRoot ? 3 /* Branch */ : 4 /* OtherBranch */;
  }
  getHierarchyHighlightStyles(highlightState, highlight5) {
    switch (highlightState) {
      case 1 /* Item */:
        return mergeDefaults(highlight5.highlightedItem, highlight5.highlightedBranch);
      case 3 /* Branch */:
        return mergeDefaults(highlight5.unhighlightedItem, highlight5.highlightedBranch);
      case 4 /* OtherBranch */:
        return highlight5.unhighlightedBranch;
      default:
        return void 0;
    }
  }
  getHighlightStateString(_datum, isHighlight, datumIndex, _legendItemValues) {
    if (!this.properties.highlight.enabled) {
      return toHierarchyHighlightString(0 /* None */);
    }
    if (datumIndex == null) {
      return toHierarchyHighlightString(0 /* None */);
    }
    const nodeDatum = datumIndex.reduce((node, idx) => node?.children[idx], this.rootNode);
    const highlightedNode = this.getActiveHighlightNode();
    if (nodeDatum == null) {
      return toHierarchyHighlightString(0 /* None */);
    }
    const state = this.getHierarchyHighlightState(isHighlight ?? false, highlightedNode, nodeDatum);
    return toHierarchyHighlightString(state);
  }
};

// packages/ag-charts-community/src/chart/series/topology/mercatorScale.ts
var radsInDeg = Math.PI / 180;
var lonX = (lon) => lon * radsInDeg;
var latY = (lat) => -Math.log(Math.tan(Math.PI * 0.25 + lat * radsInDeg * 0.5));
var xLon = (x) => x / radsInDeg;
var yLat = (y) => (Math.atan(Math.exp(-y)) - Math.PI * 0.25) / (radsInDeg * 0.5);
var MercatorScale = class _MercatorScale extends AbstractScale {
  constructor(domain, range3) {
    super();
    this.domain = domain;
    this.range = range3;
    this.type = "mercator";
    this.defaultTickCount = 0;
    this.bounds = _MercatorScale.bounds(domain);
  }
  static bounds(domain) {
    const [[lon0, lat0], [lon1, lat1]] = domain;
    const x0 = lonX(lon0);
    const y0 = latY(lat0);
    const x1 = lonX(lon1);
    const y1 = latY(lat1);
    return new BBox(Math.min(x0, x1), Math.min(y0, y1), Math.abs(x1 - x0), Math.abs(y1 - y0));
  }
  static fixedScale() {
    return new _MercatorScale(
      [
        [xLon(0), yLat(0)],
        [xLon(1), yLat(1)]
      ],
      [
        [0, 0],
        [1, 1]
      ]
    );
  }
  toDomain() {
    return;
  }
  normalizeDomains(...domains) {
    let x0 = -Infinity;
    let x1 = Infinity;
    let y0 = -Infinity;
    let y1 = Infinity;
    for (const input of domains) {
      const domain = input.domain;
      for (const [x, y] of domain) {
        x0 = Math.min(x, x0);
        x1 = Math.max(x, x1);
        y0 = Math.min(y, y0);
        y1 = Math.max(y, y1);
      }
    }
    return {
      domain: [
        [x0, y0],
        [x1, y1]
      ],
      animatable: true
    };
  }
  convert([lon, lat]) {
    const [[x0, y0], [x1, y1]] = this.range;
    const xScale = (x1 - x0) / this.bounds.width;
    const yScale = (y1 - y0) / this.bounds.height;
    return [(lonX(lon) - this.bounds.x) * xScale + x0, (latY(lat) - this.bounds.y) * yScale + y0];
  }
  invert([x, y]) {
    const [[x0, y0], [x1, y1]] = this.range;
    const xScale = (x1 - x0) / this.bounds.width;
    const yScale = (y1 - y0) / this.bounds.height;
    return [xLon((x - x0) / xScale + this.bounds.x), yLat((y - y0) / yScale + this.bounds.y)];
  }
  getDomainMinMax() {
    return unpackDomainMinMax(this.domain);
  }
};

// packages/ag-charts-community/src/util/deferredExecutor.ts
var DeferredExecutor = class {
  constructor(options) {
    this.minimumDelay = options?.minimumDelay ?? 50;
    this.timeout = options?.timeout ?? 100;
  }
  /**
   * Schedule a computation for deferred execution.
   * If something is already pending, it will be cancelled first.
   */
  schedule(computation, onComplete) {
    this.cancel();
    this.pending = { computation, onComplete };
    if (this.minimumDelay > 0) {
      this.delayTimeoutId = setTimeout(() => {
        this.delayTimeoutId = void 0;
        this.scheduleIdleCallback();
      }, this.minimumDelay);
    } else {
      this.scheduleIdleCallback();
    }
  }
  /**
   * Force immediate execution if pending.
   * @returns The computation result, or undefined if nothing was pending.
   */
  demand() {
    if (!this.pending) {
      return void 0;
    }
    this.cancelScheduled();
    return this.execute();
  }
  /**
   * Cancel any pending execution without running it.
   */
  cancel() {
    this.cancelScheduled();
    this.pending = void 0;
  }
  /**
   * Check if there's pending work.
   */
  isPending() {
    return this.pending != null;
  }
  scheduleIdleCallback() {
    const window = getWindow();
    const remainingTimeout = Math.max(0, this.timeout - this.minimumDelay);
    if (typeof window.requestIdleCallback === "function") {
      this.idleCallbackId = window.requestIdleCallback(this.execute.bind(this), { timeout: remainingTimeout });
    } else {
      this.idleCallbackId = setTimeout(() => this.execute(), remainingTimeout);
    }
  }
  cancelScheduled() {
    if (this.delayTimeoutId != null) {
      clearTimeout(this.delayTimeoutId);
      this.delayTimeoutId = void 0;
    }
    if (this.idleCallbackId == null) {
      return;
    }
    const window = getWindow();
    if (typeof window.cancelIdleCallback === "function") {
      window.cancelIdleCallback(this.idleCallbackId);
    } else {
      clearTimeout(this.idleCallbackId);
    }
    this.idleCallbackId = void 0;
  }
  execute() {
    const pending = this.pending;
    if (!pending) {
      return void 0;
    }
    this.pending = void 0;
    this.delayTimeoutId = void 0;
    this.idleCallbackId = void 0;
    const result = pending.computation();
    pending.onComplete(result);
    return result;
  }
};

// packages/ag-charts-community/src/chart/series/aggregationManager.ts
var AggregationManager = class {
  constructor() {
    this._dataLength = 0;
    this.executor = new DeferredExecutor();
  }
  get filters() {
    return this._filters;
  }
  /**
   * Perform aggregation with deferred computation of coarser levels.
   * Returns immediate filters suitable for current zoom level.
   *
   * @param options.computePartial - Function to compute partial aggregation (receives existing filters for reuse)
   * @param options.computeFull - Function to compute full aggregation (receives existing filters for reuse)
   * @param options.targetRange - Current pixel range for determining which level to compute immediately
   * @returns The computed filters (immediate level for partial, or all levels for full)
   */
  aggregate(options) {
    this.executor.cancel();
    if (options.targetRange > 1 && options.computePartial) {
      const partialResult = options.computePartial(this._filters);
      if (partialResult) {
        const { immediate, computeRemaining } = partialResult;
        if (computeRemaining) {
          this.executor.schedule(computeRemaining, (remaining) => {
            this.mergeFilters(remaining);
          });
        }
        this._filters = immediate;
        return immediate;
      }
    }
    this._filters = options.computeFull(this._filters);
    return this._filters;
  }
  /**
   * Ensure we have an aggregation level suitable for the given range.
   * Forces deferred computation if needed.
   */
  ensureLevelForRange(range3) {
    const hasLevel = this._filters?.some((f) => f.maxRange > range3);
    if (!hasLevel && this.executor.isPending()) {
      const remaining = this.executor.demand();
      if (remaining) {
        this.mergeFilters(remaining);
      }
    }
  }
  /**
   * Get the best filter for a given range.
   */
  getFilterForRange(range3) {
    return this._filters?.find((f) => f.maxRange > range3);
  }
  /**
   * Cancel any pending deferred computation.
   */
  cancel() {
    this.executor.cancel();
  }
  /**
   * Mark filters as stale or discard them based on data size change.
   * When data size changes significantly (>10x), filters are discarded to prevent
   * incorrect array reuse.
   */
  markStale(dataLength) {
    const ratio2 = this._dataLength > 0 ? dataLength / this._dataLength : 0;
    if (ratio2 > 10 || ratio2 < 0.1 || this._dataLength === 0) {
      this._filters = void 0;
      this._dataLength = dataLength;
    } else if (this._filters) {
      for (const f of this._filters) {
        f.stale = true;
      }
    } else {
      this._dataLength = dataLength;
    }
    this.executor.cancel();
  }
  mergeFilters(deferredFilters) {
    if (!this._filters || deferredFilters.length === 0)
      return;
    const allFilters = [...this._filters, ...deferredFilters];
    allFilters.sort((a, b) => a.maxRange - b.maxRange);
    this._filters = allFilters;
  }
};

// packages/ag-charts-community/src/chart/axis/polarAxis.ts
var PolarAxis = class extends Axis {
  constructor() {
    super(...arguments);
    this.shape = "polygon";
    this.innerRadiusRatio = 0;
    this.defaultTickMinSpacing = 20;
  }
  update() {
    super.update();
    this.tickLineGroup.visible = this.tick.enabled;
    this.tickLabelGroup.visible = this.label.enabled;
  }
  layoutCrossLines() {
    const sideFlag = this.label.getSideFlag();
    const crosslinesVisible = this.hasDefinedDomain() || this.hasVisibleSeries();
    const { rotation, parallelFlipRotation, regularFlipRotation } = this.calculateRotations();
    for (const crossLine of this.crossLines) {
      crossLine.sideFlag = -sideFlag;
      crossLine.direction = rotation === -Math.PI / 2 ? "angle" /* Angle */ : "radius" /* Radius */;
      crossLine.parallelFlipRotation = parallelFlipRotation;
      crossLine.regularFlipRotation = regularFlipRotation;
      crossLine.calculateLayout?.(crosslinesVisible, this.reverse);
    }
  }
  updatePosition() {
    super.updatePosition();
    const translationX = Math.floor(this.translation.x);
    const translationY = Math.floor(this.translation.y);
    this.tickLineGroup.translationX = translationX;
    this.tickLineGroup.translationY = translationY;
    this.tickLabelGroup.translationX = translationX;
    this.tickLabelGroup.translationY = translationY;
    this.crossLineRangeGroup.translationX = translationX;
    this.crossLineRangeGroup.translationY = translationY;
    this.crossLineLineGroup.translationX = translationX;
    this.crossLineLineGroup.translationY = translationY;
    this.crossLineLabelGroup.translationX = translationX;
    this.crossLineLabelGroup.translationY = translationY;
    this.tickLabelGroupSelection.each(resetAxisLabelSelectionFn());
  }
  computeLabelsBBox(_options, _seriesRect) {
    return null;
  }
  computeRange() {
  }
  getAxisLinePoints() {
    return void 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], PolarAxis.prototype, "shape", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PolarAxis.prototype, "innerRadiusRatio", 2);

// packages/ag-charts-community/src/chart/axis/discreteTimeAxis.ts
var DiscreteTimeAxis = class extends CategoryAxis {
  calculateGridLine({ index: tickIndex, tickId, translation }, index, p1, p2, ticks) {
    const { gridLine, horizontal, interval, range: range3 } = this;
    if (interval.placement !== "between") {
      return super.calculateGridLine({ index: tickIndex, tickId, translation }, index, p1, p2, ticks);
    }
    const prevTick = ticks[index - 1];
    const offset = prevTick ? translation - (translation - prevTick.translation) / 2 : range3[0];
    const [x1, y1, x2, y2] = horizontal ? [offset, Math.max(p1, p2), offset, Math.min(p1, p2)] : [Math.min(p1, p2), offset, Math.max(p1, p2), offset];
    const { style: style2 } = gridLine;
    const { stroke: stroke3, strokeWidth = 0, lineDash } = style2[tickIndex % style2.length] ?? {};
    return { tickId, offset, x1, y1, x2, y2, stroke: stroke3, strokeWidth, lineDash };
  }
  calculateGridFills(ticks, p1, p2) {
    if (this.interval.placement !== "between") {
      return super.calculateGridFills(ticks, p1, p2);
    }
    return ticks.map((tick, index) => this.calculateGridFill(tick, index, tick.index, p1, p2, ticks));
  }
  calculateGridFill({ tickId, translation }, index, gridFillIndex, p1, p2, ticks) {
    const { gridLine, horizontal, interval, range: range3 } = this;
    if (interval.placement !== "between") {
      return super.calculateGridFill({ tickId, translation }, index, gridFillIndex, p1, p2, ticks);
    }
    const prevTick = ticks[index - 1];
    const nextTick = ticks[index + 1];
    const startOffset = prevTick ? translation - (translation - prevTick.translation) / 2 : range3[0];
    const endOffset = nextTick ? translation + (nextTick.translation - translation) / 2 : range3[1];
    const [x1, y1, x2, y2] = horizontal ? [startOffset, Math.max(p1, p2), endOffset, Math.min(p1, p2)] : [Math.min(p1, p2), startOffset, Math.max(p1, p2), endOffset];
    const { fill, fillOpacity } = gridLine.style[gridFillIndex % gridLine.style.length] ?? {};
    return { tickId, x1, y1, x2, y2, fill, fillOpacity };
  }
  calculateTickLine({ isPrimary, tickId, translation }, index, direction, ticks, scrollbarThickness = 0) {
    const { horizontal, interval, primaryTick, range: range3, tick } = this;
    if (interval.placement !== "between") {
      return super.calculateTickLine(
        { isPrimary, tickId, translation },
        index,
        direction,
        ticks,
        scrollbarThickness
      );
    }
    const datumTick = isPrimary && primaryTick?.enabled ? primaryTick : tick;
    const h = -direction * this.getTickSize(datumTick);
    const prevTick = ticks[index - 1];
    const offset = prevTick ? translation - (translation - prevTick.translation) / 2 : range3[0];
    const tickOffset = -direction * (scrollbarThickness + this.getTickSpacing(datumTick));
    const [x1, y1, x2, y2] = horizontal ? [offset, tickOffset, offset, tickOffset + h] : [tickOffset, offset, tickOffset + h, offset];
    const { stroke: stroke3, width: strokeWidth } = datumTick;
    const lineDash = void 0;
    return { tickId, offset, x1, y1, x2, y2, stroke: stroke3, strokeWidth, lineDash };
  }
};

// packages/ag-charts-community/src/chart/crossline/crossLineLabelPosition.ts
var horizontalCrosslineTranslationDirections = {
  top: { xTranslationDirection: 0, yTranslationDirection: -1 },
  bottom: { xTranslationDirection: 0, yTranslationDirection: 1 },
  left: { xTranslationDirection: -1, yTranslationDirection: 0 },
  right: { xTranslationDirection: 1, yTranslationDirection: 0 },
  "top-left": { xTranslationDirection: 1, yTranslationDirection: -1 },
  "top-right": { xTranslationDirection: -1, yTranslationDirection: -1 },
  "bottom-left": { xTranslationDirection: 1, yTranslationDirection: 1 },
  "bottom-right": { xTranslationDirection: -1, yTranslationDirection: 1 },
  inside: { xTranslationDirection: 0, yTranslationDirection: 0 },
  "inside-left": { xTranslationDirection: 1, yTranslationDirection: 0 },
  "inside-right": { xTranslationDirection: -1, yTranslationDirection: 0 },
  "inside-top": { xTranslationDirection: 0, yTranslationDirection: 1 },
  "inside-bottom": { xTranslationDirection: 0, yTranslationDirection: -1 },
  "inside-top-left": { xTranslationDirection: 1, yTranslationDirection: 1 },
  "inside-bottom-left": { xTranslationDirection: 1, yTranslationDirection: -1 },
  "inside-top-right": { xTranslationDirection: -1, yTranslationDirection: 1 },
  "inside-bottom-right": { xTranslationDirection: -1, yTranslationDirection: -1 }
};
var verticalCrossLineTranslationDirections = {
  top: { xTranslationDirection: 1, yTranslationDirection: 0 },
  bottom: { xTranslationDirection: -1, yTranslationDirection: 0 },
  left: { xTranslationDirection: 0, yTranslationDirection: -1 },
  right: { xTranslationDirection: 0, yTranslationDirection: 1 },
  "top-left": { xTranslationDirection: -1, yTranslationDirection: -1 },
  "top-right": { xTranslationDirection: -1, yTranslationDirection: 1 },
  "bottom-left": { xTranslationDirection: 1, yTranslationDirection: -1 },
  "bottom-right": { xTranslationDirection: 1, yTranslationDirection: 1 },
  inside: { xTranslationDirection: 0, yTranslationDirection: 0 },
  "inside-left": { xTranslationDirection: 0, yTranslationDirection: 1 },
  "inside-right": { xTranslationDirection: 0, yTranslationDirection: -1 },
  "inside-top": { xTranslationDirection: -1, yTranslationDirection: 0 },
  "inside-bottom": { xTranslationDirection: 1, yTranslationDirection: 0 },
  "inside-top-left": { xTranslationDirection: -1, yTranslationDirection: 1 },
  "inside-bottom-left": { xTranslationDirection: 1, yTranslationDirection: 1 },
  "inside-top-right": { xTranslationDirection: -1, yTranslationDirection: -1 },
  "inside-bottom-right": { xTranslationDirection: 1, yTranslationDirection: -1 }
};
function calculateLabelTranslation({
  yDirection,
  padding: padding2 = 0,
  position = "top",
  bbox
}) {
  const crossLineTranslationDirections = yDirection ? horizontalCrosslineTranslationDirections : verticalCrossLineTranslationDirections;
  const { xTranslationDirection, yTranslationDirection } = crossLineTranslationDirections[position];
  const xTranslation = xTranslationDirection * (padding2 + bbox.width / 2);
  const yTranslation = yTranslationDirection * (padding2 + bbox.height / 2);
  return {
    xTranslation,
    yTranslation
  };
}

// packages/ag-charts-community/src/motion/pathMotion.ts
function pathMotion(groupId, subId, animationManager, paths, fns) {
  const animate = (phase, path, collapsable, updateFn) => {
    animationManager.animate({
      id: `${groupId}_${subId}_${path.id}_${phase}`,
      groupId,
      from: collapsable ? 1 : 0,
      to: 1,
      ease: easeOut,
      collapsable,
      onUpdate(ratio2, preInit) {
        if (preInit && phase !== "removed")
          return;
        path.path.clear(true);
        updateFn(ratio2, path);
        path.checkPathDirty();
      },
      onStop() {
        if (phase !== "added")
          return;
        path.path.clear(true);
        updateFn(1, path);
        path.checkPathDirty();
      },
      phase: NODE_UPDATE_STATE_TO_PHASE_MAPPING[phase]
    });
  };
  const tempPath = new Path();
  const resultsChange = (updateFn) => {
    tempPath.resetPathDirty();
    updateFn(0, tempPath);
    tempPath.resetPathDirty();
    updateFn(1, tempPath);
    tempPath.checkPathDirty();
    return tempPath.isPathDirty();
  };
  const { addPhaseFn, updatePhaseFn, removePhaseFn } = fns;
  for (const path of paths) {
    if (!animationManager.isSkipped()) {
      animate("removed", path, !resultsChange(removePhaseFn), removePhaseFn);
      animate("updated", path, !resultsChange(updatePhaseFn), updatePhaseFn);
    }
    animate("added", path, !resultsChange(addPhaseFn), addPhaseFn);
  }
}

// packages/ag-charts-community/src/scene/dropShadow.ts
var DropShadow = class extends ChangeDetectableProperties {
  constructor() {
    super(...arguments);
    this.enabled = true;
    this.color = "rgba(0, 0, 0, 0.5)";
    this.xOffset = 0;
    this.yOffset = 0;
    this.blur = 5;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], DropShadow.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], DropShadow.prototype, "color", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], DropShadow.prototype, "xOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], DropShadow.prototype, "yOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], DropShadow.prototype, "blur", 2);

// packages/ag-charts-community/src/scene/util/sector.ts
function sectorBox({ startAngle, endAngle, innerRadius, outerRadius }) {
  let x0 = Infinity;
  let y0 = Infinity;
  let x1 = -Infinity;
  let y1 = -Infinity;
  const addPoint = (x, y) => {
    x0 = Math.min(x, x0);
    y0 = Math.min(y, y0);
    x1 = Math.max(x, x1);
    y1 = Math.max(y, y1);
  };
  addPoint(innerRadius * Math.cos(startAngle), innerRadius * Math.sin(startAngle));
  addPoint(innerRadius * Math.cos(endAngle), innerRadius * Math.sin(endAngle));
  addPoint(outerRadius * Math.cos(startAngle), outerRadius * Math.sin(startAngle));
  addPoint(outerRadius * Math.cos(endAngle), outerRadius * Math.sin(endAngle));
  if (isBetweenAngles(0, startAngle, endAngle)) {
    addPoint(outerRadius, 0);
  }
  if (isBetweenAngles(Math.PI * 0.5, startAngle, endAngle)) {
    addPoint(0, outerRadius);
  }
  if (isBetweenAngles(Math.PI, startAngle, endAngle)) {
    addPoint(-outerRadius, 0);
  }
  if (isBetweenAngles(Math.PI * 1.5, startAngle, endAngle)) {
    addPoint(0, -outerRadius);
  }
  return new BBox(x0, y0, x1 - x0, y1 - y0);
}
function isPointInSector(x, y, sector) {
  const radius = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
  const { innerRadius, outerRadius } = sector;
  if (sector.startAngle === sector.endAngle || radius < Math.min(innerRadius, outerRadius) || radius > Math.max(innerRadius, outerRadius)) {
    return false;
  }
  const startAngle = normalizeAngle180(sector.startAngle);
  const endAngle = normalizeAngle180(sector.endAngle);
  const angle2 = Math.atan2(y, x);
  return startAngle < endAngle ? angle2 <= endAngle && angle2 >= startAngle : angle2 <= endAngle && angle2 >= -Math.PI || angle2 >= startAngle && angle2 <= Math.PI;
}
function arcIntersections(cx, cy, r, startAngle, endAngle, counterClockwise, x1, y1, x2, y2) {
  if (Number.isNaN(cx) || Number.isNaN(cy)) {
    return 0;
  }
  if (counterClockwise) {
    [endAngle, startAngle] = [startAngle, endAngle];
  }
  const k = (y2 - y1) / (x2 - x1);
  const y0 = y1 - k * x1;
  const a = Math.pow(k, 2) + 1;
  const b = 2 * (k * (y0 - cy) - cx);
  const c = Math.pow(cx, 2) + Math.pow(y0 - cy, 2) - Math.pow(r, 2);
  const d = Math.pow(b, 2) - 4 * a * c;
  if (d < 0) {
    return 0;
  }
  const i1x = (-b + Math.sqrt(d)) / 2 / a;
  const i2x = (-b - Math.sqrt(d)) / 2 / a;
  let intersections = 0;
  for (const x of [i1x, i2x]) {
    const isXInsideLine = x >= Math.min(x1, x2) && x <= Math.max(x1, x2);
    if (!isXInsideLine) {
      continue;
    }
    const y = k * x + y0;
    const adjacent = x - cx;
    const opposite = y - cy;
    const angle2 = Math.atan2(opposite, adjacent);
    if (isBetweenAngles(angle2, startAngle, endAngle)) {
      intersections++;
    }
  }
  return intersections;
}
function lineCollidesSector(line, sector) {
  const { startAngle, endAngle, innerRadius, outerRadius } = sector;
  const outerStart = { x: outerRadius * Math.cos(startAngle), y: outerRadius * Math.sin(startAngle) };
  const outerEnd = { x: outerRadius * Math.cos(endAngle), y: outerRadius * Math.sin(endAngle) };
  const innerStart = innerRadius === 0 ? { x: 0, y: 0 } : { x: innerRadius * Math.cos(startAngle), y: innerRadius * Math.sin(startAngle) };
  const innerEnd = innerRadius === 0 ? { x: 0, y: 0 } : { x: innerRadius * Math.cos(endAngle), y: innerRadius * Math.sin(endAngle) };
  return segmentIntersection(
    line.start.x,
    line.start.y,
    line.end.x,
    line.end.y,
    outerStart.x,
    outerStart.y,
    innerStart.x,
    innerStart.y
  ) || segmentIntersection(
    line.start.x,
    line.start.y,
    line.end.x,
    line.end.y,
    outerEnd.x,
    outerEnd.y,
    innerEnd.x,
    innerEnd.y
  ) || arcIntersections(
    0,
    0,
    outerRadius,
    startAngle,
    endAngle,
    true,
    line.start.x,
    line.start.y,
    line.end.x,
    line.end.y
  );
}
function boxCollidesSector(box, sector) {
  const topLeft = { x: box.x, y: box.y };
  const topRight = { x: box.x + box.width, y: box.y };
  const bottomLeft = { x: box.x, y: box.y + box.height };
  const bottomRight = { x: box.x + box.width, y: box.y + box.height };
  return lineCollidesSector({ start: topLeft, end: topRight }, sector) || lineCollidesSector({ start: bottomLeft, end: bottomRight }, sector);
}
function radiiScalingFactor(r, sweep, a, b) {
  if (a === 0 && b === 0)
    return 0;
  const fs1 = Math.asin(Math.abs(1 * a) / (r + 1 * a)) + Math.asin(Math.abs(1 * b) / (r + 1 * b)) - sweep;
  if (fs1 < 0)
    return 1;
  let start2 = 0;
  let end3 = 1;
  for (let i = 0; i < 8; i += 1) {
    const s = (start2 + end3) / 2;
    const fs = Math.asin(Math.abs(s * a) / (r + s * a)) + Math.asin(Math.abs(s * b) / (r + s * b)) - sweep;
    if (fs < 0) {
      start2 = s;
    } else {
      end3 = s;
    }
  }
  return start2;
}
var delta2 = 1e-6;
function clockwiseAngle(angle2, relativeToStartAngle) {
  if (angleBetween(angle2, relativeToStartAngle) < delta2) {
    return relativeToStartAngle;
  } else {
    return normalizeAngle360(angle2 - relativeToStartAngle) + relativeToStartAngle;
  }
}
function clockwiseAngles(startAngle, endAngle, relativeToStartAngle = 0) {
  const fullPie = Math.abs(endAngle - startAngle) >= 2 * Math.PI;
  const sweepAngle = fullPie ? 2 * Math.PI : normalizeAngle360(endAngle - startAngle);
  startAngle = clockwiseAngle(startAngle, relativeToStartAngle);
  endAngle = startAngle + sweepAngle;
  return { startAngle, endAngle };
}
function arcRadialLineIntersectionAngle(cx, cy, r, startAngle, endAngle, clipAngle) {
  const sinA = Math.sin(clipAngle);
  const cosA = Math.cos(clipAngle);
  const c = cx ** 2 + cy ** 2 - r ** 2;
  let p0x;
  let p0y;
  let p1x;
  let p1y;
  if (cosA > 0.5) {
    const tanA = sinA / cosA;
    const a = 1 + tanA ** 2;
    const b = -2 * (cx + cy * tanA);
    const d = b ** 2 - 4 * a * c;
    if (d < 0)
      return;
    const x0 = (-b + Math.sqrt(d)) / (2 * a);
    const x1 = (-b - Math.sqrt(d)) / (2 * a);
    p0x = x0;
    p0y = x0 * tanA;
    p1x = x1;
    p1y = x1 * tanA;
  } else {
    const cotA = cosA / sinA;
    const a = 1 + cotA ** 2;
    const b = -2 * (cy + cx * cotA);
    const d = b ** 2 - 4 * a * c;
    if (d < 0)
      return;
    const y0 = (-b + Math.sqrt(d)) / (2 * a);
    const y1 = (-b - Math.sqrt(d)) / (2 * a);
    p0x = y0 * cotA;
    p0y = y0;
    p1x = y1 * cotA;
    p1y = y1;
  }
  const normalisedX = cosA;
  const normalisedY = sinA;
  const p0DotNormalized = p0x * normalisedX + p0y * normalisedY;
  const p1DotNormalized = p1x * normalisedX + p1y * normalisedY;
  const a0 = p0DotNormalized > 0 ? clockwiseAngle(Math.atan2(p0y - cy, p0x - cx), startAngle) : Number.NaN;
  const a1 = p1DotNormalized > 0 ? clockwiseAngle(Math.atan2(p1y - cy, p1x - cx), startAngle) : Number.NaN;
  if (a0 >= startAngle && a0 <= endAngle) {
    return a0;
  } else if (a1 >= startAngle && a1 <= endAngle) {
    return a1;
  }
}
function arcCircleIntersectionAngle(cx, cy, r, startAngle, endAngle, circleR) {
  const d = Math.hypot(cx, cy);
  const d1 = (d ** 2 - r ** 2 + circleR ** 2) / (2 * d);
  const d2 = d - d1;
  const theta = Math.atan2(cy, cx);
  const deltaTheta = Math.acos(-d2 / r);
  const a0 = clockwiseAngle(theta + deltaTheta, startAngle);
  const a1 = clockwiseAngle(theta - deltaTheta, startAngle);
  if (a0 >= startAngle && a0 <= endAngle) {
    return a0;
  } else if (a1 >= startAngle && a1 <= endAngle) {
    return a1;
  }
}

// packages/ag-charts-community/src/scene/shape/svgPath.ts
var SvgPath = class extends Path {
  constructor(d = "") {
    super();
    this._d = "";
    this.d = d;
  }
  get d() {
    return this._d;
  }
  set d(d) {
    if (d === this._d)
      return;
    this._d = d;
    this.path.clear();
    this.path.appendSvg(d);
    this.checkPathDirty();
  }
};
var TranslatableSvgPath = class extends Translatable(SvgPath) {
  isPointInPath(x, y) {
    return super.isPointInPath(x - this.translationX, y - this.translationY);
  }
};

// packages/ag-charts-community/src/scale/approximateOrdinalTimeScale.ts
var ApproximateOrdinalTimeScale = class _ApproximateOrdinalTimeScale extends OrdinalTimeScale {
  static is(value) {
    return value instanceof _ApproximateOrdinalTimeScale;
  }
  /**
   * Set the source scale that this approximate scale delegates to.
   * All property access (domain, range, etc.) will be delegated to the source.
   */
  setSourceScale(scale2) {
    this._sourceScale = scale2;
    const delegateProperty = (prop) => {
      Object.defineProperty(this, prop, {
        get: () => scale2[prop],
        set: (value) => {
          scale2[prop] = value;
        },
        configurable: true
      });
    };
    delegateProperty("domain");
    delegateProperty("range");
    delegateProperty("paddingInner");
    delegateProperty("paddingOuter");
    delegateProperty("round");
    const delegateReadOnly = (prop) => {
      Object.defineProperty(this, prop, {
        get: () => scale2[prop],
        configurable: true
      });
    };
    delegateReadOnly("bandwidth");
    delegateReadOnly("step");
    delegateReadOnly("inset");
    delegateReadOnly("rawBandwidth");
  }
  // Delegate bands to source scale (read-only)
  get bands() {
    return this._sourceScale?.bands ?? super.bands;
  }
  // Delegate refresh to ensure source scale is up-to-date
  refresh() {
    this._sourceScale?.["refresh"]?.();
  }
  // Delegate ordinalRange to use source scale's computed values
  ordinalRange(i) {
    if (this._sourceScale) {
      return this._sourceScale.ordinalRange(i);
    }
    return super.ordinalRange(i);
  }
  // Delegate convert to source scale but use our findIndex
  convert(d, options) {
    this.refresh();
    const i = this.findIndex(d, options?.alignment);
    if (i == null || i < 0 || i >= this.bands.length) {
      return Number.NaN;
    }
    return this.ordinalRange(i);
  }
  findIndex(value, alignment = 0 /* Leading */) {
    if (value == null) {
      return void 0;
    }
    const { bands, reversed } = this;
    const n = bands.length;
    if (n === 0)
      return void 0;
    if (n === 1)
      return 0;
    const firstBand = bands[0];
    const lastBand = bands[n - 1];
    if (firstBand == null || lastBand == null) {
      return this._sourceScale?.findIndex(value, alignment);
    }
    const target = value.valueOf();
    const first2 = firstBand.valueOf();
    const last = lastBand.valueOf();
    const ratio2 = (target - first2) / (last - first2);
    const rawIndex = reversed ? (1 - ratio2) * (n - 1) : ratio2 * (n - 1);
    if (alignment === 0 /* Leading */) {
      return Math.max(0, Math.min(n - 1, Math.floor(rawIndex)));
    } else {
      return Math.max(0, Math.min(n - 1, Math.ceil(rawIndex)));
    }
  }
};

// packages/ag-charts-community/src/scene/sectorBox.ts
var SectorBox = class _SectorBox {
  constructor(startAngle, endAngle, innerRadius, outerRadius) {
    this.startAngle = startAngle;
    this.endAngle = endAngle;
    this.innerRadius = innerRadius;
    this.outerRadius = outerRadius;
  }
  clone() {
    const { startAngle, endAngle, innerRadius, outerRadius } = this;
    return new _SectorBox(startAngle, endAngle, innerRadius, outerRadius);
  }
  equals(other) {
    return this.startAngle === other.startAngle && this.endAngle === other.endAngle && this.innerRadius === other.innerRadius && this.outerRadius === other.outerRadius;
  }
  [interpolate](other, d) {
    return new _SectorBox(
      this.startAngle * (1 - d) + other.startAngle * d,
      this.endAngle * (1 - d) + other.endAngle * d,
      this.innerRadius * (1 - d) + other.innerRadius * d,
      this.outerRadius * (1 - d) + other.outerRadius * d
    );
  }
};

// packages/ag-charts-community/src/scene/image.ts
var Image2 = class extends Node2 {
  constructor(sourceImage) {
    super();
    this.sourceImage = sourceImage;
    this.x = 0;
    this.y = 0;
    this.width = 0;
    this.height = 0;
    this.opacity = 1;
  }
  render(renderCtx) {
    const { ctx } = renderCtx;
    const image = this.sourceImage;
    if (image) {
      ctx.globalAlpha = this.opacity;
      ctx.drawImage(image, 0, 0, image.width, image.height, this.x, this.y, this.width, this.height);
    }
    super.render(renderCtx);
  }
};
__decorateClass([
  SceneChangeDetection()
], Image2.prototype, "x", 2);
__decorateClass([
  SceneChangeDetection()
], Image2.prototype, "y", 2);
__decorateClass([
  SceneChangeDetection()
], Image2.prototype, "width", 2);
__decorateClass([
  SceneChangeDetection()
], Image2.prototype, "height", 2);
__decorateClass([
  SceneChangeDetection()
], Image2.prototype, "opacity", 2);

// packages/ag-charts-community/src/scene/shape/arc.ts
var Arc = class extends Path {
  constructor() {
    super(...arguments);
    this.centerX = 0;
    this.centerY = 0;
    this.radius = 10;
    this.startAngle = 0;
    this.endAngle = Math.PI * 2;
    this.counterClockwise = false;
    this.type = 0 /* Open */;
  }
  get fullPie() {
    return isNumberEqual(normalizeAngle360(this.startAngle), normalizeAngle360(this.endAngle));
  }
  updatePath() {
    const path = this.path;
    path.clear();
    path.arc(this.centerX, this.centerY, this.radius, this.startAngle, this.endAngle, this.counterClockwise);
    if (this.type === 1 /* Chord */) {
      path.closePath();
    } else if (this.type === 2 /* Round */ && !this.fullPie) {
      path.lineTo(this.centerX, this.centerY);
      path.closePath();
    }
  }
  computeBBox() {
    return new BBox(this.centerX - this.radius, this.centerY - this.radius, this.radius * 2, this.radius * 2);
  }
  isPointInPath(x, y) {
    const bbox = this.getBBox();
    return this.type !== 0 /* Open */ && bbox.containsPoint(x, y) && this.path.isPointInPath(x, y);
  }
};
Arc.className = "Arc";
__decorateClass([
  SceneChangeDetection()
], Arc.prototype, "centerX", 2);
__decorateClass([
  SceneChangeDetection()
], Arc.prototype, "centerY", 2);
__decorateClass([
  SceneChangeDetection()
], Arc.prototype, "radius", 2);
__decorateClass([
  SceneChangeDetection()
], Arc.prototype, "startAngle", 2);
__decorateClass([
  SceneChangeDetection()
], Arc.prototype, "endAngle", 2);
__decorateClass([
  SceneChangeDetection()
], Arc.prototype, "counterClockwise", 2);
__decorateClass([
  SceneChangeDetection()
], Arc.prototype, "type", 2);

// packages/ag-charts-community/src/scene/shape/radialColumnShape.ts
function rotatePoint2(x, y, rotation) {
  const radius = Math.hypot(x, y);
  const angle2 = Math.atan2(y, x);
  const rotated = angle2 + rotation;
  return {
    x: Math.cos(rotated) * radius,
    y: Math.sin(rotated) * radius
  };
}
var RadialColumnShape = class extends Path {
  constructor() {
    super(...arguments);
    this.isBeveled = true;
    this.columnWidth = 0;
    this.startAngle = 0;
    this.endAngle = 0;
    this.outerRadius = 0;
    this.innerRadius = 0;
    this.axisInnerRadius = 0;
    this.axisOuterRadius = 0;
  }
  set cornerRadius(_value) {
  }
  computeBBox() {
    const { columnWidth } = this;
    const [innerRadius, outerRadius] = this.normalizeRadii(this.innerRadius, this.outerRadius);
    const rotation = this.getRotation();
    const left = -columnWidth / 2;
    const right = columnWidth / 2;
    const top = -outerRadius;
    const bottom = -innerRadius;
    let x0 = Infinity;
    let y0 = Infinity;
    let x1 = -Infinity;
    let y1 = -Infinity;
    for (let i = 0; i < 4; i += 1) {
      const { x, y } = rotatePoint2(i % 2 === 0 ? left : right, i < 2 ? top : bottom, rotation);
      x0 = Math.min(x, x0);
      y0 = Math.min(y, y0);
      x1 = Math.max(x, x1);
      y1 = Math.max(y, y1);
    }
    return new BBox(x0, y0, x1 - x0, y1 - y0);
  }
  getRotation() {
    const { startAngle, endAngle } = this;
    const midAngle = angleBetween(startAngle, endAngle);
    return normalizeAngle360(startAngle + midAngle / 2 + Math.PI / 2);
  }
  normalizeRadii(innerRadius, outerRadius) {
    if (innerRadius > outerRadius) {
      return [outerRadius, innerRadius];
    }
    return [innerRadius, outerRadius];
  }
  updatePath() {
    const { isBeveled } = this;
    if (isBeveled) {
      this.updateBeveledPath();
    } else {
      this.updateRectangularPath();
    }
    this.checkPathDirty();
  }
  updateRectangularPath() {
    const { columnWidth, path } = this;
    const [innerRadius, outerRadius] = this.normalizeRadii(this.innerRadius, this.outerRadius);
    const left = -columnWidth / 2;
    const right = columnWidth / 2;
    const top = -outerRadius;
    const bottom = -innerRadius;
    const rotation = this.getRotation();
    const points = [
      [left, bottom],
      [left, top],
      [right, top],
      [right, bottom]
    ].map(([x, y]) => rotatePoint2(x, y, rotation));
    path.clear(true);
    path.moveTo(points[0].x, points[0].y);
    path.lineTo(points[1].x, points[1].y);
    path.lineTo(points[2].x, points[2].y);
    path.lineTo(points[3].x, points[3].y);
    path.closePath();
  }
  calculateCircleIntersection(x, radiusSquared) {
    const xSquared = x * x;
    if (radiusSquared < xSquared) {
      return null;
    }
    const y = -Math.sqrt(radiusSquared - xSquared);
    const angle2 = Math.atan2(y, x);
    return { y, angle: angle2 };
  }
  calculateBothIntersections(left, right, radius) {
    const radiusSquared = radius * radius;
    const leftInt = this.calculateCircleIntersection(left, radiusSquared);
    const rightInt = this.calculateCircleIntersection(right, radiusSquared);
    if (!leftInt || !rightInt) {
      return null;
    }
    return { left: leftInt, right: rightInt };
  }
  calculateAxisOuterIntersections(left, right, axisOuterRadius) {
    const axisOuterRadiusSquared = axisOuterRadius * axisOuterRadius;
    const axisOuterLeft = this.calculateCircleIntersection(left, axisOuterRadiusSquared);
    const axisOuterRight = this.calculateCircleIntersection(right, axisOuterRadiusSquared);
    if (!axisOuterLeft || !axisOuterRight) {
      return null;
    }
    return {
      left: axisOuterLeft,
      right: axisOuterRight,
      radiusSquared: axisOuterRadiusSquared
    };
  }
  moveToRotated(x, y, rotation) {
    const point = rotatePoint2(x, y, rotation);
    this.path.moveTo(point.x, point.y);
  }
  lineToRotated(x, y, rotation) {
    const point = rotatePoint2(x, y, rotation);
    this.path.lineTo(point.x, point.y);
  }
  renderTopWithCornerClipping(axisOuterRadius, axisOuter, geometry) {
    const { path } = this;
    const { right, top, rotation } = geometry;
    const topSquared = top * top;
    const topIntersectionSquared = axisOuter.radiusSquared - topSquared;
    if (topIntersectionSquared <= 0) {
      this.lineToRotated(right, axisOuter.right.y, rotation);
      path.arc(0, 0, axisOuterRadius, rotation + axisOuter.right.angle, rotation + axisOuter.left.angle, true);
    } else {
      const topIntersectionX = Math.sqrt(topIntersectionSquared);
      const topRightAngle = Math.atan2(top, topIntersectionX);
      const topLeftAngle = Math.atan2(top, -topIntersectionX);
      this.lineToRotated(right, axisOuter.right.y, rotation);
      path.arc(0, 0, axisOuterRadius, rotation + axisOuter.right.angle, rotation + topRightAngle, true);
      this.lineToRotated(-topIntersectionX, top, rotation);
      path.arc(0, 0, axisOuterRadius, rotation + topLeftAngle, rotation + axisOuter.left.angle, true);
    }
  }
  updateBeveledPath() {
    const { columnWidth, path, axisInnerRadius, axisOuterRadius } = this;
    const [innerRadius, outerRadius] = this.normalizeRadii(this.innerRadius, this.outerRadius);
    const left = -columnWidth / 2;
    const right = columnWidth / 2;
    const top = -outerRadius;
    const bottom = -innerRadius;
    const rotation = this.getRotation();
    const isTouchingInner = isNumberEqual(innerRadius, axisInnerRadius);
    const isTouchingOuter = isNumberEqual(outerRadius, axisOuterRadius);
    const topCornersBreach = Math.hypot(left, top) > axisOuterRadius || Math.hypot(right, top) > axisOuterRadius;
    if (!isTouchingInner && !isTouchingOuter && !topCornersBreach) {
      this.updateRectangularPath();
      return;
    }
    const inner = isTouchingInner ? this.calculateBothIntersections(left, right, innerRadius) : null;
    const outer = isTouchingOuter ? this.calculateBothIntersections(left, right, outerRadius) : null;
    const axisOuter = topCornersBreach ? this.calculateAxisOuterIntersections(left, right, axisOuterRadius) : null;
    if (isTouchingInner && !inner || isTouchingOuter && !outer || topCornersBreach && !axisOuter) {
      this.updateRectangularPath();
      return;
    }
    path.clear(true);
    const geometry = { left, right, top, bottom, rotation };
    if (inner) {
      this.moveToRotated(left, inner.left.y, rotation);
    } else {
      this.moveToRotated(left, bottom, rotation);
    }
    if (inner) {
      path.arc(0, 0, innerRadius, rotation + inner.left.angle, rotation + inner.right.angle, false);
    } else {
      this.lineToRotated(right, bottom, rotation);
    }
    if (outer) {
      this.lineToRotated(right, outer.right.y, rotation);
      path.arc(0, 0, outerRadius, rotation + outer.right.angle, rotation + outer.left.angle, true);
    } else if (axisOuter) {
      this.renderTopWithCornerClipping(axisOuterRadius, axisOuter, geometry);
    } else {
      this.lineToRotated(right, top, rotation);
      this.lineToRotated(left, top, rotation);
    }
    path.closePath();
  }
};
RadialColumnShape.className = "RadialColumnShape";
__decorateClass([
  SceneChangeDetection()
], RadialColumnShape.prototype, "isBeveled", 2);
__decorateClass([
  SceneChangeDetection()
], RadialColumnShape.prototype, "columnWidth", 2);
__decorateClass([
  SceneChangeDetection()
], RadialColumnShape.prototype, "startAngle", 2);
__decorateClass([
  SceneChangeDetection()
], RadialColumnShape.prototype, "endAngle", 2);
__decorateClass([
  SceneChangeDetection()
], RadialColumnShape.prototype, "outerRadius", 2);
__decorateClass([
  SceneChangeDetection()
], RadialColumnShape.prototype, "innerRadius", 2);
__decorateClass([
  SceneChangeDetection()
], RadialColumnShape.prototype, "axisInnerRadius", 2);
__decorateClass([
  SceneChangeDetection()
], RadialColumnShape.prototype, "axisOuterRadius", 2);
function getRadialColumnWidth(startAngle, endAngle, axisOuterRadius, columnWidthRatio, maxColumnWidthRatio) {
  const rotation = angleBetween(startAngle, endAngle);
  const pad2 = rotation * (1 - columnWidthRatio) / 2;
  startAngle += pad2;
  endAngle -= pad2;
  if (rotation < 1e-3) {
    return 2 * axisOuterRadius * maxColumnWidthRatio;
  }
  if (rotation >= 2 * Math.PI) {
    const midAngle = startAngle + rotation / 2;
    startAngle = midAngle - Math.PI;
    endAngle = midAngle + Math.PI;
  }
  const startX = axisOuterRadius * Math.cos(startAngle);
  const startY = axisOuterRadius * Math.sin(startAngle);
  const endX = axisOuterRadius * Math.cos(endAngle);
  const endY = axisOuterRadius * Math.sin(endAngle);
  const colWidth = Math.floor(Math.hypot(startX - endX, startY - endY));
  const maxWidth = 2 * axisOuterRadius * maxColumnWidthRatio;
  return Math.max(1, Math.min(maxWidth, colWidth));
}

// packages/ag-charts-community/src/scene/shape/sector.ts
var Arc2 = class {
  constructor(cx, cy, r, a0, a1) {
    this.cx = cx;
    this.cy = cy;
    this.r = r;
    this.a0 = a0;
    this.a1 = a1;
    if (this.a0 >= this.a1) {
      this.a0 = Number.NaN;
      this.a1 = Number.NaN;
    }
  }
  isValid() {
    return Number.isFinite(this.a0) && Number.isFinite(this.a1);
  }
  pointAt(a) {
    return {
      x: this.cx + this.r * Math.cos(a),
      y: this.cy + this.r * Math.sin(a)
    };
  }
  clipStart(a) {
    if (a == null || !this.isValid() || a < this.a0)
      return;
    this.a0 = a;
    if (Number.isNaN(a) || this.a0 >= this.a1) {
      this.a0 = Number.NaN;
      this.a1 = Number.NaN;
    }
  }
  clipEnd(a) {
    if (a == null || !this.isValid() || a > this.a1)
      return;
    this.a1 = a;
    if (Number.isNaN(a) || this.a0 >= this.a1) {
      this.a0 = Number.NaN;
      this.a1 = Number.NaN;
    }
  }
};
var Sector = class extends Path {
  constructor() {
    super(...arguments);
    this.centerX = 0;
    this.centerY = 0;
    this.innerRadius = 10;
    this.outerRadius = 20;
    this.startAngle = 0;
    this.endAngle = Math.PI * 2;
    this.clipSector = void 0;
    this.concentricEdgeInset = 0;
    this.radialEdgeInset = 0;
    this.startOuterCornerRadius = 0;
    this.endOuterCornerRadius = 0;
    this.startInnerCornerRadius = 0;
    this.endInnerCornerRadius = 0;
  }
  set inset(value) {
    this.concentricEdgeInset = value;
    this.radialEdgeInset = value;
  }
  set cornerRadius(value) {
    this.startOuterCornerRadius = value;
    this.endOuterCornerRadius = value;
    this.startInnerCornerRadius = value;
    this.endInnerCornerRadius = value;
  }
  computeBBox() {
    return sectorBox(this).translate(this.centerX, this.centerY);
  }
  normalizedRadii() {
    const { concentricEdgeInset } = this;
    let { innerRadius, outerRadius } = this;
    innerRadius = innerRadius > 0 ? innerRadius + concentricEdgeInset : 0;
    outerRadius = Math.max(outerRadius - concentricEdgeInset, 0);
    return { innerRadius, outerRadius };
  }
  normalizedClipSector() {
    const { clipSector } = this;
    if (clipSector == null)
      return;
    const { startAngle, endAngle } = clockwiseAngles(this.startAngle, this.endAngle);
    const { innerRadius, outerRadius } = this.normalizedRadii();
    const clipAngles = clockwiseAngles(clipSector.startAngle, clipSector.endAngle, startAngle);
    return new SectorBox(
      Math.max(startAngle, clipAngles.startAngle),
      Math.min(endAngle, clipAngles.endAngle),
      Math.max(innerRadius, clipSector.innerRadius),
      Math.min(outerRadius, clipSector.outerRadius)
    );
  }
  getAngleOffset(radius) {
    return radius > 0 ? this.radialEdgeInset / radius : 0;
  }
  arc(r, angleSweep, a0, a1, outerArc, innerArc, start2, inner) {
    if (r <= 0)
      return;
    const { startAngle, endAngle } = clockwiseAngles(this.startAngle, this.endAngle);
    const { innerRadius, outerRadius } = this.normalizedRadii();
    const clipSector = this.normalizedClipSector();
    if (inner && innerRadius <= 0)
      return;
    const angleOffset = inner ? this.getAngleOffset(innerRadius + r) : this.getAngleOffset(outerRadius - r);
    const angle2 = start2 ? startAngle + angleOffset + angleSweep : endAngle - angleOffset - angleSweep;
    const radius = inner ? innerRadius + r : outerRadius - r;
    const cx = radius * Math.cos(angle2);
    const cy = radius * Math.sin(angle2);
    if (clipSector != null) {
      const delta5 = 1e-6;
      if (!start2 && !(angle2 >= startAngle - delta5 && angle2 <= clipSector.endAngle - delta5))
        return;
      if (start2 && !(angle2 >= clipSector.startAngle + delta5 && angle2 <= endAngle - delta5))
        return;
      if (inner && radius < clipSector.innerRadius - delta5)
        return;
      if (!inner && radius > clipSector.outerRadius + delta5)
        return;
    }
    const arc = new Arc2(cx, cy, r, a0, a1);
    if (clipSector != null) {
      if (inner) {
        arc.clipStart(arcRadialLineIntersectionAngle(cx, cy, r, a0, a1, clipSector.endAngle));
        arc.clipEnd(arcRadialLineIntersectionAngle(cx, cy, r, a0, a1, clipSector.startAngle));
      } else {
        arc.clipStart(arcRadialLineIntersectionAngle(cx, cy, r, a0, a1, clipSector.startAngle));
        arc.clipEnd(arcRadialLineIntersectionAngle(cx, cy, r, a0, a1, clipSector.endAngle));
      }
      let circleClipStart;
      let circleClipEnd;
      if (start2) {
        circleClipStart = arcCircleIntersectionAngle(cx, cy, r, a0, a1, clipSector.innerRadius);
        circleClipEnd = arcCircleIntersectionAngle(cx, cy, r, a0, a1, clipSector.outerRadius);
      } else {
        circleClipStart = arcCircleIntersectionAngle(cx, cy, r, a0, a1, clipSector.outerRadius);
        circleClipEnd = arcCircleIntersectionAngle(cx, cy, r, a0, a1, clipSector.innerRadius);
      }
      arc.clipStart(circleClipStart);
      arc.clipEnd(circleClipEnd);
      if (circleClipStart != null) {
        const { x: x2, y: y2 } = arc.pointAt(circleClipStart);
        const theta2 = clockwiseAngle(Math.atan2(y2, x2), startAngle);
        if (start2) {
          innerArc?.clipStart(theta2);
        } else {
          outerArc.clipEnd(theta2);
        }
      }
      if (circleClipEnd != null) {
        const { x: x2, y: y2 } = arc.pointAt(circleClipEnd);
        const theta2 = clockwiseAngle(Math.atan2(y2, x2), startAngle);
        if (start2) {
          outerArc.clipStart(theta2);
        } else {
          innerArc?.clipEnd(theta2);
        }
      }
    }
    if (clipSector != null) {
      const { x: x2, y: y2 } = arc.pointAt((arc.a0 + arc.a1) / 2);
      if (!isPointInSector(x2, y2, clipSector))
        return;
    }
    const { x, y } = arc.pointAt(start2 === inner ? arc.a0 : arc.a1);
    const theta = clockwiseAngle(Math.atan2(y, x), startAngle);
    const radialArc = inner ? innerArc : outerArc;
    if (start2) {
      radialArc?.clipStart(theta);
    } else {
      radialArc?.clipEnd(theta);
    }
    return arc;
  }
  updatePath() {
    const delta5 = 1e-6;
    const { path, centerX, centerY, concentricEdgeInset, radialEdgeInset } = this;
    let { startOuterCornerRadius, endOuterCornerRadius, startInnerCornerRadius, endInnerCornerRadius } = this;
    const { startAngle, endAngle } = clockwiseAngles(this.startAngle, this.endAngle);
    const { innerRadius, outerRadius } = this.normalizedRadii();
    const clipSector = this.normalizedClipSector();
    const sweepAngle = endAngle - startAngle;
    const fullPie = sweepAngle >= 2 * Math.PI - delta5;
    path.clear();
    const innerAngleOffset = this.getAngleOffset(innerRadius);
    const adjustedSweep = sweepAngle - 2 * innerAngleOffset;
    const radialLength = outerRadius - innerRadius;
    const innerCornerDistance = innerRadius > 0 && adjustedSweep > 0 ? 2 * innerRadius * Math.sin(adjustedSweep / 2) : 0;
    const outerCornerDistance = outerRadius > 0 && adjustedSweep > 0 ? 2 * outerRadius * Math.sin(adjustedSweep / 2) : 0;
    startOuterCornerRadius = Math.floor(
      Math.max(0, Math.min(startOuterCornerRadius, outerCornerDistance / 2, radialLength / 2))
    );
    endOuterCornerRadius = Math.floor(
      Math.max(0, Math.min(endOuterCornerRadius, outerCornerDistance / 2, radialLength / 2))
    );
    startInnerCornerRadius = Math.floor(
      Math.max(0, Math.min(startInnerCornerRadius, innerCornerDistance / 2, radialLength / 2))
    );
    endInnerCornerRadius = Math.floor(
      Math.max(0, Math.min(endInnerCornerRadius, innerCornerDistance / 2, radialLength / 2))
    );
    const isInvalid = innerRadius === 0 && outerRadius === 0 || innerRadius > outerRadius || innerCornerDistance < 0 || outerCornerDistance <= 0;
    if (isInvalid) {
      return;
    } else if ((clipSector?.startAngle ?? startAngle) === (clipSector?.endAngle ?? endAngle)) {
      return;
    } else if (fullPie && this.clipSector == null && startOuterCornerRadius === 0 && endOuterCornerRadius === 0 && startInnerCornerRadius === 0 && endInnerCornerRadius === 0) {
      path.moveTo(centerX + outerRadius * Math.cos(startAngle), centerY + outerRadius * Math.sin(startAngle));
      path.arc(centerX, centerY, outerRadius, startAngle, endAngle);
      if (innerRadius > concentricEdgeInset) {
        path.moveTo(centerX + innerRadius * Math.cos(endAngle), centerY + innerRadius * Math.sin(endAngle));
        path.arc(centerX, centerY, innerRadius, endAngle, startAngle, true);
      }
      path.closePath();
      return;
    } else if (this.clipSector == null && Math.abs(innerRadius - outerRadius) < 1e-6) {
      path.arc(centerX, centerY, outerRadius, startAngle, endAngle, false);
      path.arc(centerX, centerY, outerRadius, endAngle, startAngle, true);
      path.closePath();
      return;
    }
    const outerAngleOffset = this.getAngleOffset(outerRadius);
    const outerAngleExceeded = sweepAngle < 2 * outerAngleOffset;
    if (outerAngleExceeded)
      return;
    const hasInnerSweep = (clipSector?.innerRadius ?? innerRadius) > concentricEdgeInset;
    const innerAngleExceeded = innerRadius < concentricEdgeInset || sweepAngle < 2 * innerAngleOffset;
    const maxRadialLength = Math.max(
      startOuterCornerRadius,
      startInnerCornerRadius,
      endOuterCornerRadius,
      endInnerCornerRadius
    );
    const initialScalingFactor = maxRadialLength > 0 ? Math.min(radialLength / maxRadialLength, 1) : 1;
    startOuterCornerRadius *= initialScalingFactor;
    endOuterCornerRadius *= initialScalingFactor;
    startInnerCornerRadius *= initialScalingFactor;
    endInnerCornerRadius *= initialScalingFactor;
    const outerScalingFactor = radiiScalingFactor(
      outerRadius,
      sweepAngle - 2 * outerAngleOffset,
      -startOuterCornerRadius,
      -endOuterCornerRadius
    );
    startOuterCornerRadius *= outerScalingFactor;
    endOuterCornerRadius *= outerScalingFactor;
    if (!innerAngleExceeded && hasInnerSweep) {
      const innerScalingFactor = radiiScalingFactor(
        innerRadius,
        sweepAngle - 2 * innerAngleOffset,
        startInnerCornerRadius,
        endInnerCornerRadius
      );
      startInnerCornerRadius *= innerScalingFactor;
      endInnerCornerRadius *= innerScalingFactor;
    } else {
      startInnerCornerRadius = 0;
      endInnerCornerRadius = 0;
    }
    const maxCombinedRadialLength = Math.max(
      startOuterCornerRadius + startInnerCornerRadius,
      endOuterCornerRadius + endInnerCornerRadius
    );
    const edgesScalingFactor = maxCombinedRadialLength > 0 ? Math.min(radialLength / maxCombinedRadialLength, 1) : 1;
    startOuterCornerRadius *= edgesScalingFactor;
    endOuterCornerRadius *= edgesScalingFactor;
    startInnerCornerRadius *= edgesScalingFactor;
    endInnerCornerRadius *= edgesScalingFactor;
    let startOuterCornerRadiusAngleSweep = 0;
    let endOuterCornerRadiusAngleSweep = 0;
    const startOuterCornerRadiusSweep = startOuterCornerRadius / (outerRadius - startOuterCornerRadius);
    const endOuterCornerRadiusSweep = endOuterCornerRadius / (outerRadius - endOuterCornerRadius);
    if (startOuterCornerRadiusSweep >= 0 && startOuterCornerRadiusSweep < 1 - delta5) {
      startOuterCornerRadiusAngleSweep = Math.asin(startOuterCornerRadiusSweep);
    } else {
      startOuterCornerRadiusAngleSweep = sweepAngle / 2;
      const maxStartOuterCornerRadius = outerRadius / (1 / Math.sin(startOuterCornerRadiusAngleSweep) + 1);
      startOuterCornerRadius = Math.min(maxStartOuterCornerRadius, startOuterCornerRadius);
    }
    if (endOuterCornerRadiusSweep >= 0 && endOuterCornerRadiusSweep < 1 - delta5) {
      endOuterCornerRadiusAngleSweep = Math.asin(endOuterCornerRadiusSweep);
    } else {
      endOuterCornerRadiusAngleSweep = sweepAngle / 2;
      const maxEndOuterCornerRadius = outerRadius / (1 / Math.sin(endOuterCornerRadiusAngleSweep) + 1);
      endOuterCornerRadius = Math.min(maxEndOuterCornerRadius, endOuterCornerRadius);
    }
    const startInnerCornerRadiusAngleSweep = Math.asin(
      startInnerCornerRadius / (innerRadius + startInnerCornerRadius)
    );
    const endInnerCornerRadiusAngleSweep = Math.asin(endInnerCornerRadius / (innerRadius + endInnerCornerRadius));
    const outerArcRadius = clipSector?.outerRadius ?? outerRadius;
    const outerArcRadiusOffset = this.getAngleOffset(outerArcRadius);
    const outerArc = new Arc2(
      0,
      0,
      outerArcRadius,
      startAngle + outerArcRadiusOffset,
      endAngle - outerArcRadiusOffset
    );
    const innerArcRadius = clipSector?.innerRadius ?? innerRadius;
    const innerArcRadiusOffset = this.getAngleOffset(innerArcRadius);
    const innerArc = hasInnerSweep ? new Arc2(0, 0, innerArcRadius, startAngle + innerArcRadiusOffset, endAngle - innerArcRadiusOffset) : void 0;
    if (clipSector != null) {
      outerArc.clipStart(clipSector.startAngle);
      outerArc.clipEnd(clipSector.endAngle);
      innerArc?.clipStart(clipSector.startAngle);
      innerArc?.clipEnd(clipSector.endAngle);
    }
    const startOuterArc = this.arc(
      startOuterCornerRadius,
      startOuterCornerRadiusAngleSweep,
      startAngle - Math.PI * 0.5,
      startAngle + startOuterCornerRadiusAngleSweep,
      outerArc,
      innerArc,
      true,
      false
    );
    const endOuterArc = this.arc(
      endOuterCornerRadius,
      endOuterCornerRadiusAngleSweep,
      endAngle - endOuterCornerRadiusAngleSweep,
      endAngle + Math.PI * 0.5,
      outerArc,
      innerArc,
      false,
      false
    );
    const endInnerArc = this.arc(
      endInnerCornerRadius,
      endInnerCornerRadiusAngleSweep,
      endAngle + Math.PI * 0.5,
      endAngle + Math.PI - endInnerCornerRadiusAngleSweep,
      outerArc,
      innerArc,
      false,
      true
    );
    const startInnerArc = this.arc(
      startInnerCornerRadius,
      startInnerCornerRadiusAngleSweep,
      startAngle + Math.PI + startInnerCornerRadiusAngleSweep,
      startAngle + Math.PI * 1.5,
      outerArc,
      innerArc,
      true,
      true
    );
    if (innerAngleExceeded && hasInnerSweep) {
    } else if (innerAngleExceeded) {
      const x = sweepAngle < Math.PI * 0.5 ? radialEdgeInset * (1 + Math.cos(sweepAngle)) / Math.sin(sweepAngle) : Number.NaN;
      let r;
      if (x > 0 && x < outerRadius) {
        r = Math.max(Math.hypot(radialEdgeInset, x), innerRadius);
      } else {
        r = radialEdgeInset;
      }
      r = Math.max(r, innerRadius);
      const midAngle = startAngle + sweepAngle * 0.5;
      path.moveTo(centerX + r * Math.cos(midAngle), centerY + r * Math.sin(midAngle));
    } else if (startInnerArc?.isValid() === true || innerArc?.isValid() === true) {
    } else {
      const midAngle = startAngle + sweepAngle / 2;
      const cx = innerRadius * Math.cos(midAngle);
      const cy = innerRadius * Math.sin(midAngle);
      path.moveTo(centerX + cx, centerY + cy);
    }
    if (startOuterArc?.isValid() === true) {
      const { cx, cy, r, a0, a1 } = startOuterArc;
      path.arc(centerX + cx, centerY + cy, r, a0, a1);
    }
    if (outerArc.isValid()) {
      const { r, a0, a1 } = outerArc;
      path.arc(centerX, centerY, r, a0, a1);
    }
    if (endOuterArc?.isValid() === true) {
      const { cx, cy, r, a0, a1 } = endOuterArc;
      path.arc(centerX + cx, centerY + cy, r, a0, a1);
    }
    if (!innerAngleExceeded) {
      if (endInnerArc?.isValid() === true) {
        const { cx, cy, r, a0, a1 } = endInnerArc;
        path.arc(centerX + cx, centerY + cy, r, a0, a1);
      }
      if (innerArc?.isValid() === true) {
        const { r, a0, a1 } = innerArc;
        path.arc(centerX, centerY, r, a1, a0, true);
      }
      if (startInnerArc?.isValid() === true) {
        const { cx, cy, r, a0, a1 } = startInnerArc;
        path.arc(centerX + cx, centerY + cy, r, a0, a1);
      }
    }
    path.closePath();
  }
  isPointInPath(x, y) {
    const { startAngle, endAngle, innerRadius, outerRadius } = this.clipSector ?? this;
    return isPointInSector(x - this.centerX, y - this.centerY, {
      startAngle,
      endAngle,
      innerRadius: Math.min(innerRadius, outerRadius),
      outerRadius: Math.max(innerRadius, outerRadius)
    });
  }
};
Sector.className = "Sector";
__decorateClass([
  SceneChangeDetection()
], Sector.prototype, "centerX", 2);
__decorateClass([
  SceneChangeDetection()
], Sector.prototype, "centerY", 2);
__decorateClass([
  SceneChangeDetection()
], Sector.prototype, "innerRadius", 2);
__decorateClass([
  SceneChangeDetection()
], Sector.prototype, "outerRadius", 2);
__decorateClass([
  SceneChangeDetection()
], Sector.prototype, "startAngle", 2);
__decorateClass([
  SceneChangeDetection()
], Sector.prototype, "endAngle", 2);
__decorateClass([
  SceneObjectChangeDetection({ equals: (lhs, rhs) => lhs.equals(rhs) })
], Sector.prototype, "clipSector", 2);
__decorateClass([
  SceneChangeDetection()
], Sector.prototype, "concentricEdgeInset", 2);
__decorateClass([
  SceneChangeDetection()
], Sector.prototype, "radialEdgeInset", 2);
__decorateClass([
  SceneChangeDetection()
], Sector.prototype, "startOuterCornerRadius", 2);
__decorateClass([
  SceneChangeDetection()
], Sector.prototype, "endOuterCornerRadius", 2);
__decorateClass([
  SceneChangeDetection()
], Sector.prototype, "startInnerCornerRadius", 2);
__decorateClass([
  SceneChangeDetection()
], Sector.prototype, "endInnerCornerRadius", 2);

// packages/ag-charts-community/src/widget/menuItemWidget.ts
var MenuItemWidget = class extends AbstractButtonWidget {
  constructor() {
    super(createElement("div"), "menuitem");
  }
};
var MenuItemRadioWidget = class extends AbstractButtonWidget {
  constructor() {
    super(createElement("div"), "menuitemradio");
  }
  setChecked(checked) {
    setAttribute(this.elem, "aria-checked", checked);
  }
};

// packages/ag-charts-community/src/widget/menuWidget.ts
var closeKeys = ["Escape", "ArrowLeft"];
var MenuWidget = class _MenuWidget extends RovingTabContainerWidget {
  constructor(orientation = "vertical") {
    super(orientation, "menu");
    this.handleMouseEnter = (ev, current) => {
      if (!current.hasPopup()) {
        this.expandSubMenu(ev, void 0);
      }
    };
    this.handleMouseMove = (_ev, current) => {
      current.focus({ preventScroll: true });
    };
  }
  destructor() {
    this.collapse({ mode: "2" /* DESTROY */ });
  }
  addSeparator() {
    const sep = getDocument().createElement("div");
    setAttribute(sep, "role", "separator");
    this.elem.appendChild(sep);
    return sep;
  }
  onChildAdded(child) {
    super.onChildAdded(child);
    child.addListener("mouseenter", this.handleMouseEnter);
    child.addListener("mousemove", this.handleMouseMove);
  }
  onChildRemoved(child) {
    super.onChildRemoved(child);
    child.removeListener("mouseenter", this.handleMouseEnter);
    child.removeListener("mousemove", this.handleMouseMove);
  }
  addSubMenu() {
    const subMenuButton = new MenuItemWidget();
    const subMenu = new _MenuWidget(this.orientation);
    subMenu.id = createElementId();
    const expand = () => {
      this.collapseExpandedSubMenu(subMenu);
      subMenuButton.expandControlled();
    };
    const arrowRightOpener = (ev) => {
      if (hasNoModifiers(ev.sourceEvent) && ev.sourceEvent.code === "ArrowRight") {
        this.collapseExpandedSubMenu(subMenu);
        subMenuButton.expandControlled();
      }
    };
    subMenuButton.setControlled(subMenu);
    subMenuButton.setAriaHasPopup("menu");
    subMenuButton.addListener("click", expand);
    subMenuButton.addListener("mouseenter", expand);
    subMenuButton.addListener("keydown", arrowRightOpener);
    this.addChild(subMenuButton);
    return { subMenuButton, subMenu };
  }
  expandSubMenu(ev, subMenu) {
    const { expansionScope } = this;
    if (!expansionScope)
      return;
    this.collapseExpandedSubMenu(subMenu);
    subMenu?.expand(ev);
  }
  collapseExpandedSubMenu(newSubMenu) {
    const { expansionScope } = this;
    if (!expansionScope)
      return;
    expansionScope.expandedSubMenu?.collapse({ mode: "4" /* SIDLING_OPENED */ });
    expansionScope.expandedSubMenu = newSubMenu;
  }
  expand(opts) {
    if (this.expansionScope != null)
      return;
    this.expansionScope = {
      lastFocus: getLastFocus(opts.sourceEvent),
      expandedSubMenu: void 0,
      abort: () => this.collapse({ mode: "1" /* ABORT */ }),
      close: () => this.collapse({ mode: "0" /* CLOSE */ }),
      removers: new CleanupRegistry()
    };
    const scope = this.expansionScope;
    const buttons = this.children.map((value) => value.getElement());
    setAttribute(scope.lastFocus, "aria-expanded", true);
    scope.removers.register(
      addMouseCloseListener(this.elem, scope.abort),
      addTouchCloseListener(this.elem, scope.abort),
      ...this.children.map((child) => addEscapeEventListener(child.getElement(), scope.close, closeKeys)),
      opts?.overrideFocusVisible && addOverrideFocusVisibleEventListener(this.elem, buttons, opts.overrideFocusVisible)
    );
    this.internalListener?.dispatch("expand-widget", this, { type: "expand-widget" });
    this.children[0]?.focus({ preventScroll: true });
  }
  collapse(opts) {
    const { mode = "0" /* CLOSE */ } = opts ?? {};
    if (this.expansionScope === void 0)
      return;
    const { lastFocus, removers, expandedSubMenu } = this.expansionScope;
    this.expansionScope = void 0;
    expandedSubMenu?.collapse({ mode: "3" /* PARENT_CLOSED */ });
    setAttribute(lastFocus, "aria-expanded", false);
    if (mode === "0" /* CLOSE */) {
      lastFocus?.focus({ preventScroll: true });
    }
    removers.flush();
    this.internalListener?.dispatch("collapse-widget", this, { type: "collapse-widget", mode });
  }
};

// packages/ag-charts-community/src/components/popover/popover.ts
var canvasOverlay = "canvas-overlay";
var Popover = class extends AbstractModuleInstance {
  constructor(ctx, id, options) {
    super();
    this.ctx = ctx;
    this.hideFns = [];
    this.setOwnedWidget = /* @__PURE__ */ (() => {
      let ownedWidget;
      return (owns) => {
        ownedWidget?.destroy();
        ownedWidget = owns;
      };
    })();
    this.moduleId = `popover-${id}`;
    if (options?.detached) {
      this.element = createElement("div");
    } else {
      this.element = ctx.domManager.addChild(canvasOverlay, this.moduleId);
    }
    this.element.setAttribute("role", "presentation");
    this.hideFns.push(() => this.setOwnedWidget(void 0));
    this.cleanup.register(() => ctx.domManager.removeChild(canvasOverlay, this.moduleId));
  }
  attachTo(popover) {
    if (this.element.parentElement)
      return;
    popover.element.append(this.element);
  }
  hide(opts) {
    const { lastFocus = this.lastFocus } = opts ?? {};
    if (this.element.children.length === 0)
      return;
    for (const fn of this.hideFns) {
      fn();
    }
    lastFocus?.focus();
    this.lastFocus = void 0;
  }
  removeChildren() {
    this.element.replaceChildren();
  }
  initPopoverElement(popover, options) {
    if (!this.element.parentElement) {
      throw new Error("Can not show popover that has not been attached to a parent.");
    }
    popover ?? (popover = createElement("div", "ag-charts-popover"));
    popover.classList.toggle("ag-charts-popover", true);
    if (options.ariaLabel != null) {
      popover.setAttribute("aria-label", options.ariaLabel);
    }
    if (options.class != null) {
      popover.classList.add(options.class);
    }
    this.element.replaceChildren(popover);
    return popover;
  }
  showWidget(controller, owns, options) {
    this.setOwnedWidget(owns);
    this.initPopoverElement(owns.getElement(), options);
    owns.addListener("collapse-widget", () => {
      controller.setControlled(void 0);
      this.setOwnedWidget(void 0);
    });
    controller.setControlled(owns);
    controller.expandControlled();
  }
  showWithChildren(children, options) {
    const popover = this.initPopoverElement(void 0, options);
    popover.replaceChildren(...children);
    this.hideFns.push(() => this.removeChildren());
    if (options.onHide) {
      this.hideFns.push(options.onHide);
    }
    if (options.initialFocus && options.sourceEvent) {
      const lastFocus = getLastFocus(options.sourceEvent);
      if (lastFocus !== void 0) {
        this.lastFocus = lastFocus;
        this.initialFocus = options.initialFocus;
      }
    }
    return popover;
  }
  getPopoverElement() {
    return this.element.firstElementChild;
  }
  updatePosition(position) {
    const popover = this.getPopoverElement();
    if (!popover)
      return;
    popover.style.setProperty("right", "unset");
    popover.style.setProperty("bottom", "unset");
    if (position.x != null)
      popover.style.setProperty("left", `${Math.floor(position.x)}px`);
    if (position.y != null)
      popover.style.setProperty("top", `${Math.floor(position.y)}px`);
    this.initialFocus?.focus();
    this.initialFocus = void 0;
  }
};

// packages/ag-charts-community/src/components/popover/anchoredPopover.ts
var AnchoredPopover = class extends Popover {
  setAnchor(anchor, fallbackAnchor) {
    this.anchor = anchor;
    this.fallbackAnchor = fallbackAnchor;
    this.updatePosition(anchor);
    this.repositionWithinBounds();
  }
  updateAnchor(options) {
    const anchor = options.anchor ?? this.anchor;
    const fallbackAnchor = options.fallbackAnchor ?? this.fallbackAnchor;
    if (anchor) {
      this.setAnchor(anchor, fallbackAnchor);
    }
  }
  showWidget(controller, owns, options) {
    super.showWidget(controller, owns, options);
    this.updateAnchor(options);
  }
  showWithChildren(children, options) {
    const popover = super.showWithChildren(children, options);
    this.updateAnchor(options);
    getWindow().requestAnimationFrame(() => {
      this.repositionWithinBounds();
    });
    return popover;
  }
  repositionWithinBounds() {
    const { anchor, ctx, fallbackAnchor } = this;
    const popover = this.getPopoverElement();
    if (!anchor || !popover)
      return;
    const canvasRect = ctx.domManager.getBoundingClientRect();
    const { offsetWidth: width2, offsetHeight: height2 } = popover;
    let x = clamp(0, anchor.x, canvasRect.width - width2);
    let y = clamp(0, anchor.y, canvasRect.height - height2);
    if (x !== anchor.x && fallbackAnchor?.x != null) {
      x = clamp(0, fallbackAnchor.x - width2, canvasRect.width - width2);
    }
    if (y !== anchor.y && fallbackAnchor?.y != null) {
      y = clamp(0, fallbackAnchor.y - height2, canvasRect.height - height2);
    }
    this.updatePosition({ x, y });
  }
};

// packages/ag-charts-community/src/components/menu/menu.ts
var Menu = class extends AnchoredPopover {
  show(controller, options) {
    const menu = new MenuWidget("vertical");
    for (const item of options.items) {
      menu.addChild(this.createRow(options, item, menu));
    }
    menu.addClass("ag-charts-menu");
    this.showWidget(controller, menu, options);
  }
  allocRow(options, item) {
    if (options.menuItemRole == null || options.menuItemRole === "menuitem") {
      return new MenuItemWidget();
    } else {
      options.menuItemRole;
      const result = new MenuItemRadioWidget();
      result.setChecked(options.value === item.value);
      return result;
    }
  }
  createRow(options, item, menu) {
    const active = item.value === options.value;
    const row = this.allocRow(options, item);
    row.addClass("ag-charts-menu__row");
    row.toggleClass(`ag-charts-menu__row--active`, active);
    if (typeof item.value === "string") {
      row.getElement().dataset.popoverId = item.value;
    }
    if (item.icon != null) {
      const icon = createElement("span", `ag-charts-menu__icon ${getIconClassNames(item.icon)}`);
      row.getElement().appendChild(icon);
    }
    const strokeWidthVisible = item.strokeWidth != null;
    if (strokeWidthVisible) {
      row.toggleClass(`ag-charts-menu__row--stroke-width-visible`, strokeWidthVisible);
      row.setCSSVariable("--strokeWidth", strokeWidthVisible ? `${item.strokeWidth}px` : null);
    }
    if (item.label != null) {
      const label = createElement("span", "ag-charts-menu__label");
      label.textContent = this.ctx.localeManager.t(item.label);
      row.getElement().appendChild(label);
    }
    if ("altText" in item) {
      row.setAriaLabel(this.ctx.localeManager.t(item.altText));
    }
    row.addListener("click", ({ sourceEvent }) => {
      options.onPress?.(item);
      sourceEvent.preventDefault();
      sourceEvent.stopPropagation();
      menu.collapse();
    });
    return row;
  }
};

// packages/ag-charts-community/src/components/popover/draggablePopover.ts
var DraggablePopover = class extends Popover {
  constructor() {
    super(...arguments);
    this.dragged = false;
  }
  setDragHandle(dragHandle) {
    dragHandle.addListener("drag-start", (event) => {
      dragHandle.addClass(this.dragHandleDraggingClass);
      this.onDragStart(event);
    });
    dragHandle.addListener("drag-move", this.onDragMove.bind(this));
    dragHandle.addListener("drag-end", () => {
      dragHandle.removeClass(this.dragHandleDraggingClass);
      this.onDragEnd.bind(this);
    });
  }
  onDragStart(event) {
    const popover = this.getPopoverElement();
    if (!popover)
      return;
    event.sourceEvent.preventDefault();
    this.dragged = true;
    this.dragStartState = {
      client: vector_exports.from(event.clientX, event.clientY),
      position: vector_exports.from(
        Number(popover.style.getPropertyValue("left").replace("px", "")),
        Number(popover.style.getPropertyValue("top").replace("px", ""))
      )
    };
  }
  onDragMove(event) {
    const { dragStartState } = this;
    const popover = this.getPopoverElement();
    if (!dragStartState || !popover)
      return;
    const offset = vector_exports.sub(vector_exports.from(event.clientX, event.clientY), dragStartState.client);
    const position = vector_exports.add(dragStartState.position, offset);
    const bounds = this.ctx.domManager.getBoundingClientRect();
    const partialPosition = {};
    if (position.x >= 0 && position.x + popover.offsetWidth <= bounds.width) {
      partialPosition.x = position.x;
    }
    if (position.y >= 0 && position.y + popover.offsetHeight <= bounds.height) {
      partialPosition.y = position.y;
    }
    this.updatePosition(partialPosition);
  }
  onDragEnd() {
    this.dragStartState = void 0;
  }
};

// packages/ag-charts-community/src/components/toolbar/toolbarButtonWidget.ts
var ARIA_HASPOPUP = {
  "disjoint-channel": "false",
  "fibonacci-menu": "menu",
  "fibonacci-retracement": "false",
  "fibonacci-retracement-trend-based": "false",
  "fill-color": "dialog",
  "horizontal-line": "false",
  "line-color": "dialog",
  "line-menu": "menu",
  "line-stroke-width": "menu",
  "line-style-type": "menu",
  "measurer-menu": "menu",
  "pan-end": "false",
  "pan-left": "false",
  "pan-right": "false",
  "pan-start": "false",
  "parallel-channel": "false",
  "shape-menu": "menu",
  "text-color": "dialog",
  "text-menu": "menu",
  "text-size": "menu",
  "vertical-line": "false",
  "zoom-in": "false",
  "zoom-out": "false",
  callout: "false",
  clear: "false",
  comment: "false",
  delete: "false",
  line: "false",
  lock: "false",
  menu: "menu",
  note: "false",
  reset: "false",
  settings: "dialog",
  text: "false"
};
function getAriaHasPopupOfValue(value) {
  if (typeof value !== "string")
    return "false";
  return ARIA_HASPOPUP[value];
}
var ToolbarButtonWidget = class extends ButtonWidget {
  constructor(localeManager) {
    super();
    this.localeManager = localeManager;
  }
  update(options) {
    const { localeManager } = this;
    if (options.tooltip) {
      const tooltip = localeManager.t(options.tooltip);
      if (tooltip !== this.lastTooltip) {
        this.elem.title = tooltip;
        this.lastTooltip = tooltip;
      }
    }
    let innerHTML = "";
    if (options.icon != null) {
      innerHTML = `<span class="${getIconClassNames(options.icon)} ag-charts-toolbar__icon"></span>`;
    }
    if (options.label != null) {
      const label = localeManager.t(options.label);
      innerHTML = `${innerHTML}<span class="ag-charts-toolbar__label">${label}</span>`;
    }
    const haspopup = getAriaHasPopupOfValue(options.value);
    if (haspopup == "false") {
      this.setAriaHasPopup(void 0);
      this.setAriaExpanded(void 0);
    } else {
      this.setAriaHasPopup(haspopup);
      this.setAriaExpanded(false);
    }
    if (innerHTML !== this.lastInnerHTML) {
      this.elem.innerHTML = innerHTML;
      this.lastInnerHTML = innerHTML;
    }
  }
  setChecked(checked) {
    setAttribute(this.elem, "aria-checked", checked);
  }
};

// packages/ag-charts-community/src/components/toolbar/toolbar.ts
var BUTTON_ACTIVE_CLASS = "ag-charts-toolbar__button--active";
var BaseToolbar = class extends ToolbarWidget {
  constructor({ eventsHub, localeManager }, ariaLabelId, orientation) {
    super(orientation);
    this.ariaLabelId = ariaLabelId;
    this.horizontalSpacing = 10;
    this.verticalSpacing = 10;
    this.events = new Listeners();
    this.hasPrefix = false;
    this.buttonWidgets = [];
    this.updateAriaLabel = () => this.setAriaLabel(this.localeManager.t(this.ariaLabelId));
    this.eventsHub = eventsHub;
    this.localeManager = localeManager;
    this.addClass("ag-charts-toolbar");
    this.toggleClass("ag-charts-toolbar--horizontal", orientation === "horizontal");
    this.toggleClass("ag-charts-toolbar--vertical", orientation === "vertical");
    this.eventsHub.on("locale:change", this.updateAriaLabel);
    this.updateAriaLabel();
  }
  setAriaLabelId(ariaLabelId) {
    this.ariaLabelId = ariaLabelId;
    this.updateAriaLabel();
  }
  addToolbarListener(eventType, handler) {
    return this.events.addListener(eventType, handler);
  }
  clearButtons() {
    this.expanded?.collapse({ mode: "2" /* DESTROY */ });
    for (const button of this.buttonWidgets) {
      button.destroy();
    }
    this.buttonWidgets.splice(0);
  }
  updateButtons(buttons) {
    const { buttonWidgets } = this;
    for (const [index, button] of buttons.entries()) {
      const buttonWidget = this.buttonWidgets.at(index) ?? this.createButton(index, button);
      buttonWidget.update(button);
    }
    for (let index = buttons.length; index < buttonWidgets.length; index++) {
      const button = this.buttonWidgets.at(index);
      button?.destroy();
    }
    this.buttonWidgets.splice(buttons.length);
    this.refreshButtonClasses();
  }
  updateButtonByIndex(index, button) {
    this.buttonWidgets.at(index)?.update(button);
  }
  clearActiveButton() {
    for (const button of this.buttonWidgets) {
      button.toggleClass(BUTTON_ACTIVE_CLASS, false);
    }
  }
  toggleActiveButtonByIndex(index) {
    if (index === -1)
      return;
    for (const [buttonIndex, button] of this.buttonWidgets.entries()) {
      button.toggleClass(BUTTON_ACTIVE_CLASS, index != null && index === buttonIndex);
    }
  }
  toggleButtonEnabledByIndex(index, enabled) {
    if (index === -1)
      return;
    this.buttonWidgets.at(index)?.setEnabled(enabled);
  }
  toggleSwitchCheckedByIndex(index, checked) {
    if (index === -1)
      return;
    this.buttonWidgets.at(index)?.setChecked(checked);
  }
  getButtonBounds() {
    return this.buttonWidgets.map((buttonWidget) => this.getButtonWidgetBounds(buttonWidget));
  }
  setButtonHiddenByIndex(index, hidden) {
    this.buttonWidgets.at(index)?.setHidden(hidden);
  }
  getButtonWidgetBounds(buttonWidget) {
    const parent = this.getBounds();
    const bounds = buttonWidget.getBounds();
    return new BBox(bounds.x + parent.x, bounds.y + parent.y, bounds.width, bounds.height);
  }
  refreshButtonClasses() {
    const { buttonWidgets, hasPrefix } = this;
    let first2;
    let last;
    let section;
    for (const [index, buttonWidget] of buttonWidgets.entries()) {
      first2 = !hasPrefix && index === 0 || section != buttonWidget.section;
      last = index === buttonWidgets.length - 1 || buttonWidget.section != buttonWidgets.at(index + 1)?.section;
      buttonWidget.toggleClass("ag-charts-toolbar__button--first", first2);
      buttonWidget.toggleClass("ag-charts-toolbar__button--last", last);
      buttonWidget.toggleClass("ag-charts-toolbar__button--gap", index > 0 && first2);
      section = buttonWidget.section;
    }
  }
  createButton(index, button) {
    const buttonWidget = this.createButtonWidget();
    buttonWidget.addClass("ag-charts-toolbar__button");
    buttonWidget.addListener("click", (event) => {
      const buttonOptions = { index, ...button instanceof BaseProperties ? button.toJson() : button };
      const buttonBounds = this.getButtonWidgetBounds(buttonWidget);
      const params = {
        event,
        button: buttonOptions,
        buttonBounds,
        buttonWidget
      };
      this.events.dispatch("button-pressed", params);
    });
    buttonWidget.addListener("focus", () => {
      const params = { button: { index } };
      this.events.dispatch("button-focused", params);
    });
    buttonWidget.addListener("expand-controlled-widget", (e) => {
      this.expanded?.collapse({ mode: "4" /* SIDLING_OPENED */ });
      this.expanded = e.controlled;
      const removeListener = this.expanded.addListener("collapse-widget", () => {
        this.expanded = void 0;
        removeListener();
      });
    });
    if (button.section) {
      buttonWidget.section = button.section;
    }
    this.buttonWidgets.push(buttonWidget);
    this.addChild(buttonWidget);
    return buttonWidget;
  }
};
var Toolbar = class extends BaseToolbar {
  createButtonWidget() {
    return new ToolbarButtonWidget(this.localeManager);
  }
};

// packages/ag-charts-community/src/components/toolbar/floatingToolbar.ts
var FloatingToolbarPopover = class extends DraggablePopover {
  constructor(ctx, id, onPopoverMoved) {
    super(ctx, id);
    this.onPopoverMoved = onPopoverMoved;
    this.dragHandleDraggingClass = "ag-charts-floating-toolbar__drag-handle--dragging";
  }
  show(children, options = {}) {
    this.showWithChildren(children, {
      ...options,
      class: "ag-charts-floating-toolbar"
    });
  }
  hide() {
    this.dragged = false;
    super.hide();
  }
  getBounds() {
    const element2 = this.getPopoverElement();
    return new BBox(
      element2?.offsetLeft ?? 0,
      element2?.offsetTop ?? 0,
      element2?.offsetWidth ?? 0,
      element2?.offsetHeight ?? 0
    );
  }
  hasBeenDragged() {
    return this.dragged;
  }
  setAnchor(anchor, horizontalSpacing, verticalSpacing) {
    const element2 = this.getPopoverElement();
    if (!element2)
      return;
    const position = anchor.position ?? "above";
    const { offsetWidth: width2, offsetHeight: height2 } = element2;
    let top = anchor.y - height2 - verticalSpacing;
    let left = anchor.x - width2 / 2;
    if (position === "below") {
      top = anchor.y + verticalSpacing;
    } else if (position === "right") {
      top = anchor.y - height2 / 2;
      left = anchor.x + horizontalSpacing;
    } else if (position === "above-left") {
      left = anchor.x;
    }
    this.updatePosition({ x: left, y: top });
  }
  ignorePointerEvents() {
    const element2 = this.getPopoverElement();
    if (element2)
      element2.style.pointerEvents = "none";
  }
  capturePointerEvents() {
    const element2 = this.getPopoverElement();
    if (element2)
      element2.style.pointerEvents = "unset";
  }
  updatePosition(position) {
    const bounds = this.getBounds();
    const canvasRect = this.ctx.domManager.getBoundingClientRect();
    position.x = Math.floor(clamp(0, position.x, canvasRect.width - bounds.width));
    position.y = Math.floor(clamp(0, position.y, canvasRect.height - bounds.height));
    super.updatePosition(position);
    this.onPopoverMoved();
  }
};
var FloatingToolbar = class extends BaseToolbar {
  constructor(ctx, ariaLabelId, id) {
    super(ctx, ariaLabelId, "horizontal");
    this.hasPrefix = true;
    this.popover = new FloatingToolbarPopover(ctx, id, this.onPopoverMoved.bind(this));
    this.dragHandle = new DragHandleWidget(ctx.localeManager.t("toolbarAnnotationsDragHandle"));
    this.popover.setDragHandle(this.dragHandle);
  }
  destroy() {
    super.destroy();
    this.popover.destroy();
  }
  show(options = {}) {
    this.popover.show([this.dragHandle.getElement(), this.getElement()], options);
  }
  hide() {
    this.popover.hide();
  }
  setAnchor(anchor) {
    this.popover.setAnchor(anchor, this.horizontalSpacing, this.verticalSpacing);
  }
  hasBeenDragged() {
    return this.popover.hasBeenDragged();
  }
  ignorePointerEvents() {
    this.popover.ignorePointerEvents();
  }
  capturePointerEvents() {
    this.popover.capturePointerEvents();
  }
  onPopoverMoved() {
    const popoverBounds = this.popover.getBounds();
    if (this.popoverBounds?.equals(popoverBounds))
      return;
    this.popoverBounds = popoverBounds.clone();
    const buttonBounds = this.getButtonBounds();
    this.events.dispatch("toolbar-moved", { popoverBounds, buttonBounds });
  }
  getButtonWidgetBounds(buttonWidget) {
    const popoverBounds = this.popover.getBounds();
    const bounds = super.getButtonWidgetBounds(buttonWidget);
    const dragHandleBounds = this.dragHandle.getBounds();
    return new BBox(
      bounds.x + popoverBounds.x - dragHandleBounds.width,
      bounds.y + popoverBounds.y,
      bounds.width,
      bounds.height
    );
  }
};
var DragHandleWidget = class extends NativeWidget {
  constructor(title) {
    super(createElement("div", "ag-charts-floating-toolbar__drag-handle"));
    const icon = new NativeWidget(
      createElement("span", `${getIconClassNames("drag-handle")} ag-charts-toolbar__icon`)
    );
    icon.setAriaHidden(true);
    this.addChild(icon);
    this.elem.title = title;
  }
};

// packages/ag-charts-community/src/module-support.ts
var motion = { ...fromToMotion_exports, ...resetMotion_exports };

// packages/ag-charts-community/src/widget/exports.ts
var exports_exports = {};
__export(exports_exports, {
  ButtonWidget: () => ButtonWidget,
  MenuItemRadioWidget: () => MenuItemRadioWidget,
  MenuItemWidget: () => MenuItemWidget,
  MenuWidget: () => MenuWidget,
  NativeWidget: () => NativeWidget,
  SliderWidget: () => SliderWidget,
  ToolbarWidget: () => ToolbarWidget,
  WIDGET_HTML_EVENTS: () => WIDGET_HTML_EVENTS,
  Widget: () => Widget,
  WidgetEventUtil: () => WidgetEventUtil
});

// packages/ag-charts-community/src/api/preset/sparkline.ts
var commonAxisProperties = {
  title: {
    enabled: false
  },
  label: {
    enabled: false
  },
  line: {
    enabled: false
  },
  gridLine: {
    enabled: false
  },
  crosshair: {
    enabled: false,
    stroke: DEFAULT_SPARKLINE_CROSSHAIR_STROKE,
    lineDash: [0],
    label: {
      enabled: false
    }
  }
};
var numericAxisProperties = {
  ...commonAxisProperties,
  nice: false
};
var chartTooltipDefaults = {
  mode: "compact",
  position: {
    anchorTo: "node",
    placement: ["right", "left"]
  },
  showArrow: false
};
var barGridLineDefaults = {
  style: [{ stroke: { $ref: "gridLineColor" } }],
  width: 2
};
var barAxisDefaults = {
  number: {
    gridLine: barGridLineDefaults
  },
  time: {
    gridLine: barGridLineDefaults
  },
  category: {
    gridLine: barGridLineDefaults
  }
};
var SPARKLINE_THEME = {
  overrides: {
    common: {
      animation: { enabled: false },
      contextMenu: { enabled: false },
      keyboard: { enabled: false },
      background: { visible: false },
      navigator: { enabled: false },
      padding: {
        top: 0,
        right: 0,
        bottom: 0,
        left: 0
      },
      axes: {
        number: {
          ...numericAxisProperties,
          interval: {
            values: [0]
          }
        },
        log: {
          ...numericAxisProperties
        },
        time: {
          ...numericAxisProperties
        },
        category: {
          ...commonAxisProperties
        }
      }
    },
    bar: {
      series: {
        crisp: false,
        label: {
          placement: "inside-end",
          padding: 4
        },
        // @ts-expect-error undocumented option
        sparklineMode: true
      },
      tooltip: {
        ...chartTooltipDefaults,
        position: {
          ...chartTooltipDefaults.position,
          anchorTo: "pointer"
        },
        range: "nearest"
      },
      axes: barAxisDefaults
    },
    line: {
      seriesArea: {
        padding: {
          top: 2,
          right: 2,
          bottom: 2,
          left: 2
        }
      },
      series: {
        // @ts-expect-error undocumented option
        sparklineMode: true,
        strokeWidth: 1,
        marker: {
          enabled: false,
          size: 3
        }
      },
      tooltip: chartTooltipDefaults
    },
    area: {
      seriesArea: {
        padding: {
          top: 1,
          right: 0,
          bottom: 1,
          left: 0
        }
      },
      series: {
        strokeWidth: 1,
        fillOpacity: 0.4
      },
      tooltip: chartTooltipDefaults
    }
  }
};
var setInitialBaseTheme = simpleMemorize(createInitialBaseTheme);
function createInitialBaseTheme(baseTheme, initialBaseTheme) {
  if (typeof baseTheme === "string") {
    return {
      ...initialBaseTheme,
      baseTheme
    };
  }
  if (baseTheme != null) {
    return {
      ...baseTheme,
      // @ts-expect-error internal implementation
      baseTheme: setInitialBaseTheme(baseTheme.baseTheme, initialBaseTheme)
    };
  }
  return initialBaseTheme;
}
function sparklineDataPreset(data) {
  if (Array.isArray(data) && data.length !== 0) {
    const firstItem = data.find((v) => v != null);
    if (typeof firstItem === "number") {
      const mappedData = data.map((y, x) => ({ x, y }));
      return { data: mappedData, series: [{ xKey: "x", yKey: "y" }], datumKey: "y" };
    } else if (Array.isArray(firstItem)) {
      const mappedData = data.map((datum) => ({ x: datum?.[0], y: datum?.[1], datum }));
      return { data: mappedData, series: [{ xKey: "x", yKey: "y" }], datumKey: "datum" };
    }
  } else if (data?.length === 0) {
    return { data, series: [{ xKey: "x", yKey: "y" }], datumKey: "y" };
  }
  return { data };
}
function axisPreset(opts) {
  switch (opts?.type) {
    case "number": {
      const { reverse, min, max } = opts ?? {};
      return {
        type: "number",
        reverse,
        min,
        max
      };
    }
    case "time": {
      const { reverse, min, max } = opts ?? {};
      return {
        type: "time",
        reverse,
        min,
        max
      };
    }
    case "category":
    default: {
      if (opts == null) {
        return { type: "category" };
      }
      const { reverse, paddingInner, paddingOuter } = opts;
      return {
        type: "category",
        reverse,
        paddingInner,
        paddingOuter
      };
    }
  }
}
function gridLinePreset(opts, defaultEnabled, sparkOpts) {
  const gridLineOpts = {};
  if (opts?.stroke != null) {
    gridLineOpts.style = [{ stroke: opts?.stroke }];
    gridLineOpts.enabled ?? (gridLineOpts.enabled = true);
  }
  if (opts?.strokeWidth != null) {
    gridLineOpts.width = opts?.strokeWidth;
    gridLineOpts.enabled ?? (gridLineOpts.enabled = true);
  }
  if (sparkOpts.type === "bar" && sparkOpts.direction !== "horizontal") {
    gridLineOpts.enabled ?? (gridLineOpts.enabled = true);
  }
  if (opts?.visible != null) {
    gridLineOpts.enabled = opts.visible;
  }
  gridLineOpts.enabled ?? (gridLineOpts.enabled = defaultEnabled);
  return gridLineOpts;
}
var tooltipRendererFn = simpleMemorize((context, tooltip, datumKey) => {
  return (params) => {
    const xValue = params.datum[params.xKey];
    const yValue = params.datum[params.yKey];
    const datum = datumKey == null ? params.datum : params.datum[datumKey];
    const userContent = tooltip?.renderer?.({ context, datum, xValue, yValue });
    if (isString(userContent) || isNumber(userContent) || isDate(userContent)) {
      return toTextString(userContent);
    }
    const content = userContent?.content ?? yValue.toFixed(2);
    return userContent?.title ? {
      heading: void 0,
      title: void 0,
      data: [{ label: userContent.title, value: content }]
    } : {
      heading: void 0,
      title: content,
      data: []
    };
  };
});
function sparkline(opts) {
  const {
    background,
    container,
    foreground,
    height: height2,
    listeners,
    locale,
    minHeight,
    minWidth,
    overrideDevicePixelRatio,
    padding: padding2,
    width: width2,
    theme: baseTheme,
    data: baseData,
    crosshair,
    axis,
    min,
    max,
    tooltip,
    context,
    styleNonce,
    ...seriesOptions
  } = opts;
  const chartOpts = {
    background,
    container,
    foreground,
    height: height2,
    listeners,
    locale,
    minHeight,
    minWidth,
    overrideDevicePixelRatio,
    padding: padding2,
    width: width2,
    styleNonce
  };
  const { data, series: [seriesOverrides] = [], datumKey } = sparklineDataPreset(baseData);
  const seriesConfig = seriesOptions;
  if (seriesOverrides != null) {
    Object.assign(seriesConfig, seriesOverrides);
  }
  seriesConfig.tooltip = {
    ...tooltip,
    renderer: tooltipRendererFn(context, tooltip, datumKey)
  };
  chartOpts.theme = setInitialBaseTheme(baseTheme, SPARKLINE_THEME);
  chartOpts.data = data;
  chartOpts.series = [seriesConfig];
  const swapAxes = seriesConfig.type === "bar" && seriesConfig.direction === "horizontal";
  const [crossAxisPosition, numberAxisPosition] = swapAxes ? ["left", "bottom"] : ["bottom", "left"];
  const crossAxis = {
    ...axisPreset(axis),
    position: crossAxisPosition,
    ...crosshair == null ? {} : { crosshair }
  };
  const numberAxis = {
    type: "number",
    gridLine: gridLinePreset(axis, false, opts),
    position: numberAxisPosition,
    ...min == null ? {} : { min },
    ...max == null ? {} : { max }
  };
  chartOpts.axes = swapAxes ? { x: numberAxis, y: crossAxis } : { x: crossAxis, y: numberAxis };
  return chartOpts;
}

// packages/ag-charts-community/src/api/preset/presetModules.ts
var commonSparklineOmit = [
  "showInLegend",
  "showInMiniChart",
  "grouped",
  "stacked",
  "stackGroup",
  "tooltip",
  "listeners",
  "errorBar",
  "xKey",
  "yKey",
  "type"
];
var commonSparklineAxisOptionsDef = {
  visible: boolean,
  reverse: boolean,
  stroke: color,
  strokeWidth: positiveNumber
};
var commonSparklineOptionsDef = {
  context: () => true,
  tooltip: defined,
  theme: defined,
  background: defined,
  container: defined,
  width: defined,
  height: defined,
  minWidth: defined,
  minHeight: defined,
  padding: defined,
  listeners: defined,
  locale: defined,
  data: defined,
  styleNonce: string,
  axis: typeUnion(
    {
      number: {
        ...commonSparklineAxisOptionsDef,
        min: and(number, lessThan("max")),
        max: and(number, greaterThan("min"))
      },
      category: {
        ...commonSparklineAxisOptionsDef,
        paddingInner: ratio,
        paddingOuter: ratio
      },
      time: {
        ...commonSparklineAxisOptionsDef,
        min: and(or(number, date), lessThan("max")),
        max: and(or(number, date), greaterThan("min"))
      }
    },
    "axis options",
    "category"
  ),
  min: and(number, lessThan("max")),
  max: and(number, greaterThan("min")),
  crosshair: {
    enabled: boolean,
    snap: boolean,
    ...strokeOptionsDef,
    ...lineDashOptionsDef
  },
  xKey: string,
  yKey: string
};
commonSparklineOptionsDef.overrideDevicePixelRatio = undocumented(number);
commonSparklineOptionsDef.foreground = undocumented(defined);
var SparklinePresetModule = {
  type: "preset",
  name: "sparkline",
  version: VERSION,
  options: typeUnion(
    {
      area: {
        ...commonSparklineOptionsDef,
        ...without(areaSeriesOptionsDef, commonSparklineOmit)
      },
      bar: {
        ...commonSparklineOptionsDef,
        ...without(barSeriesOptionsDef, commonSparklineOmit)
      },
      line: {
        ...commonSparklineOptionsDef,
        ...without(lineSeriesOptionsDef, commonSparklineOmit)
      }
    },
    "sparkline options"
  ),
  create: sparkline,
  processData: sparklineDataPreset
};

// packages/ag-charts-community/src/chart/cartesianChart.ts
var directions = ["top", "right", "bottom", "left"];
var _CartesianChart = class _CartesianChart extends Chart {
  constructor(options, resources) {
    super(options, resources);
    // TODO should come from theme
    /** Integrated Charts feature state - not used in Standalone Charts. */
    this.paired = true;
    this.axes = this.createChartAxes();
    this.lastUpdateClipRect = void 0;
    this.lastLayoutWidth = Number.NaN;
    this.lastLayoutHeight = Number.NaN;
  }
  createChartAxes() {
    return new CartesianChartAxes();
  }
  onAxisChange(newValue, oldValue) {
    super.onAxisChange(newValue, oldValue);
    this.syncAxisChanges(newValue, oldValue);
    if (this.ctx != null) {
      this.ctx.zoomManager.setAxes(newValue);
    }
  }
  destroySeries(series) {
    super.destroySeries(series);
    this.lastLayoutWidth = Number.NaN;
    this.lastLayoutHeight = Number.NaN;
  }
  getChartType() {
    return "cartesian";
  }
  setRootClipRects(clipRect) {
    const { seriesRoot, annotationRoot } = this;
    seriesRoot.setClipRect(clipRect);
    annotationRoot.setClipRect(clipRect);
  }
  async processData() {
    await super.processData();
    if (this.syncStatus === "init") {
      this.syncStatus = "domains-calculated";
    }
    this.ctx.updateService.dispatchProcessData({ series: { shouldFlipXY: this.shouldFlipXY() } });
  }
  async processDomains() {
    await super.processDomains();
    for (const axis of this.axes) {
      const syncedDomain = await this.getSyncedDomain(axis);
      if (syncedDomain != null) {
        axis.setDomains({ domain: syncedDomain });
      }
    }
  }
  performLayout(ctx) {
    const { seriesRoot, annotationRoot } = this;
    const { clipSeries, seriesRect, visible } = this.updateAxes(ctx);
    this.seriesRoot.visible = visible;
    this.seriesRect = seriesRect;
    this.animationRect = ctx.layoutBox;
    const { x, y } = seriesRect;
    if (ctx.width !== this.lastLayoutWidth || ctx.height !== this.lastLayoutHeight) {
      for (const group of [seriesRoot, annotationRoot]) {
        group.translationX = Math.floor(x);
        group.translationY = Math.floor(y);
      }
    } else {
      const { translationX, translationY } = seriesRoot;
      staticFromToMotion(
        this.id,
        "seriesRect",
        this.ctx.animationManager,
        [seriesRoot, annotationRoot],
        { translationX, translationY },
        { translationX: Math.floor(x), translationY: Math.floor(y) },
        { phase: "update" }
      );
    }
    this.lastLayoutWidth = ctx.width;
    this.lastLayoutHeight = ctx.height;
    const seriesPaddedRect = seriesRect.clone().grow(this.seriesArea.getPadding());
    const alwaysClip = this.series.some((s) => s.alwaysClip);
    const enableClip = alwaysClip || (this.seriesArea.clip ?? false) || clipSeries;
    const clipRect = enableClip ? seriesPaddedRect : void 0;
    const { lastUpdateClipRect } = this;
    this.lastUpdateClipRect = clipRect;
    if (this.ctx.animationManager.isActive() && lastUpdateClipRect != null) {
      this.ctx.animationManager.animate({
        id: this.id,
        groupId: "clip-rect",
        phase: "update",
        from: lastUpdateClipRect,
        to: seriesPaddedRect,
        onUpdate: (interpolatedClipRect) => this.setRootClipRects(interpolatedClipRect),
        onStop: () => this.setRootClipRects(clipRect),
        onComplete: () => this.setRootClipRects(clipRect)
      });
    } else {
      this.setRootClipRects(clipRect);
    }
    this.ctx.layoutManager.emitLayoutComplete(ctx, {
      axes: fromPairs(this.axes.map((axis) => [axis.id, axis.getLayoutState()])),
      series: {
        visible,
        rect: seriesRect,
        paddedRect: seriesPaddedRect
      },
      clipSeries
    });
    stackCartesianSeries(this.series);
  }
  updateAxes(layoutContext) {
    const { layoutBox, scrollbars } = layoutContext;
    const { clipSeries, seriesRect, overflows } = this.resolveAxesLayout(layoutBox, scrollbars);
    for (const axis of this.axes) {
      axis.update();
      axis.setCrossLinesVisible(!overflows);
      this.clipAxis(axis, seriesRect, layoutBox);
    }
    return { clipSeries, seriesRect, visible: !overflows };
  }
  // Iteratively try to resolve axis widths - since X axis width affects Y axis range,
  // and vice-versa, we need to iteratively try and find a fit for the axes and their
  // ticks/labels.
  resolveAxesLayout(layoutBox, scrollbars) {
    let newState;
    let prevState;
    let iterations = 0;
    const maxIterations = 10;
    const crossAtAxes = this.axes.filter((axis) => axis.crossAt?.value != null);
    do {
      prevState = newState ?? this.getDefaultState();
      newState = this.updateAxesPass(
        new Map(prevState.axisAreaWidths),
        layoutBox.clone(),
        crossAtAxes,
        scrollbars
      );
      if (iterations++ > maxIterations) {
        logger_exports.warn("Max iterations reached. Unable to stabilize axes layout.");
        break;
      }
    } while (!this.isLayoutStable(newState, prevState));
    this.lastAreaWidths = newState.axisAreaWidths;
    return newState;
  }
  updateAxesPass(axisAreaWidths, axisAreaBound, crossAtAxes, scrollbars) {
    const axisWidths = /* @__PURE__ */ new Map();
    const primaryTickCounts = {};
    let overflows = false;
    let clipSeries = false;
    const seriesAreaPadding = this.seriesArea.getPadding();
    for (const dir of directions) {
      const padding2 = seriesAreaPadding[dir] ?? 0;
      const axis = this.axes.findLast((a) => a.position === dir);
      if (axis) {
        axis.seriesAreaPadding = padding2;
      } else {
        axisAreaBound.shrink(padding2, dir);
      }
    }
    const totalWidth = (axisAreaWidths.get("left") ?? 0) + (axisAreaWidths.get("right") ?? 0);
    const totalHeight = (axisAreaWidths.get("top") ?? 0) + (axisAreaWidths.get("bottom") ?? 0);
    const crossLinePadding = this.buildCrossLinePadding(axisAreaWidths);
    const crossLineHPadding = crossLinePadding.left + crossLinePadding.right;
    const crossLineVPadding = crossLinePadding.top + crossLinePadding.bottom;
    if (axisAreaBound.width <= totalWidth + crossLineHPadding || axisAreaBound.height <= totalHeight + crossLineVPadding) {
      overflows = true;
    } else {
      axisAreaBound.shrink(crossLinePadding);
    }
    const { scene } = this.ctx;
    const seriesRect = axisAreaBound.clone().shrink(Object.fromEntries(axisAreaWidths));
    for (const axis of this.axes) {
      const { position = "left", direction } = axis;
      const isVertical = direction === "y" /* Y */;
      let axisWidth;
      this.sizeAxis(axis, seriesRect, position);
      if (axis.thickness == null) {
        const availableSize = getSize(isVertical, scene);
        axisWidth = availableSize * (axis.maxThicknessRatio ?? 1);
      } else {
        axisWidth = axis.thickness;
      }
      const chartLayout = {
        sizeLimit: axisWidth - axis.label.spacing,
        padding: this.padding,
        scrollbars
      };
      const { primaryTickCount, bbox } = axis.calculateLayout(
        axis.nice ? primaryTickCounts[direction] : void 0,
        chartLayout
      );
      primaryTickCounts[direction] ?? (primaryTickCounts[direction] = primaryTickCount);
      clipSeries || (clipSeries = axis.dataDomain.clipped || axis.visibleRange[0] > 0 || axis.visibleRange[1] < 1);
      if (axis.thickness == null) {
        axisWidth = Math.min(getSize(isVertical, bbox) ?? 0, axisWidth);
      }
      axisWidths.set(axis.id, Math.ceil(axisWidth));
    }
    let crossPositions;
    if (crossAtAxes.length > 0) {
      crossPositions = this.calculateAxesCrossPositions(axisWidths, seriesRect, crossAtAxes);
    }
    const axisGroups = groupBy(this.axes, (axis) => axis.position ?? "left");
    const newAxisAreaWidths = /* @__PURE__ */ new Map();
    const axisOffsets = /* @__PURE__ */ new Map();
    for (const [position, axes] of entries(axisGroups)) {
      let currentOffset = getSize(position !== "left" && position !== "right", scene) % scene.pixelRatio;
      let totalAxisWidth = 0;
      for (const axis of axes ?? []) {
        axisOffsets.set(axis.id, currentOffset);
        const axisThickness = axisWidths.get(axis.id) ?? 0;
        totalAxisWidth = Math.max(totalAxisWidth, currentOffset + axisThickness);
        if (axis.layoutConstraints.stacked) {
          currentOffset += axisThickness + _CartesianChart.AxesPadding;
        }
      }
      newAxisAreaWidths.set(position, Math.ceil(totalAxisWidth));
    }
    for (const [position, axes] of entries(axisGroups)) {
      this.positionAxes({
        axes: axes ?? [],
        position,
        axisWidths,
        axisOffsets,
        axisAreaWidths: newAxisAreaWidths,
        axisBound: axisAreaBound,
        seriesRect
      });
    }
    if (crossPositions != null) {
      this.applyAxisCrossing(seriesRect, crossPositions);
    }
    return { clipSeries, seriesRect, axisAreaWidths: newAxisAreaWidths, overflows };
  }
  calculateAxesCrossPositions(axisWidths, seriesRect, crossAtAxes) {
    const crossPositions = /* @__PURE__ */ new Map();
    for (const axis of crossAtAxes) {
      const { crossPosition, visible } = this.calculateAxisCrossPosition(axis);
      axis.setAxisVisible(visible);
      this.adjustAxisWidth(axis, axisWidths, crossPosition, seriesRect, visible);
      if (crossPosition == void 0)
        continue;
      crossPositions.set(axis.id, crossPosition);
    }
    return crossPositions;
  }
  calculateAxisCrossPosition(axis) {
    const perpendicularAxis = this.axes.perpendicular(axis);
    const {
      scale: { domain, bandwidth },
      range: range3
    } = perpendicularAxis;
    const halfBandwidth = (bandwidth ?? 0) / 2;
    const crossPosition = perpendicularAxis.scale.convert(axis.crossAt?.value, { clamp: false }) + halfBandwidth;
    if (perpendicularAxis.inRange(crossPosition))
      return { crossPosition, visible: true };
    if (axis.crossAt?.sticky === false) {
      return { crossPosition: void 0, visible: false };
    }
    const clampedPosition = Number.isNaN(crossPosition) ? range3[domain[0]] : clampArray(crossPosition, range3);
    return { crossPosition: clampedPosition, visible: true };
  }
  adjustAxisWidth(axis, axisWidths, crossPosition, seriesRect, visible) {
    const crosshairModule = axis.getModuleMap().getModule("crosshair");
    if (crosshairModule?.enabled)
      return;
    const annotationsModule = this.modulesManager.getModule("annotations");
    const hasAnnotations = annotationsModule?.enabled === true || this.ctx.annotationManager.createMemento().some((annotation) => {
      switch (annotation.type) {
        case "vertical-line":
          return axis.direction === "x" /* X */;
        case "horizontal-line":
          return axis.direction === "y" /* Y */;
      }
    });
    if (hasAnnotations)
      return;
    const currentWidth = axisWidths.get(axis.id) ?? 0;
    const adjustedWidth = visible ? this.calculateAxisBleedingWidth(axis, currentWidth, crossPosition, seriesRect) : 0;
    axisWidths.set(axis.id, adjustedWidth);
  }
  calculateAxisBleedingWidth(axis, actualWidth, crossPosition, seriesRect) {
    if (crossPosition == null)
      return actualWidth;
    switch (axis.position) {
      case "left":
      case "top":
        return Math.max(0, actualWidth - crossPosition);
      case "right":
        return Math.max(0, crossPosition + actualWidth - seriesRect.width);
      case "bottom":
        return Math.max(0, crossPosition + actualWidth - seriesRect.height);
      default:
        return actualWidth;
    }
  }
  applyAxisCrossing(seriesRect, crossPositions) {
    for (const axis of this.axes) {
      const crossPosition = crossPositions.get(axis.id);
      if (crossPosition == null) {
        axis.crossAxisTranslation.x = 0;
        axis.crossAxisTranslation.y = 0;
        continue;
      }
      const isXDirection = axis.direction === "x" /* X */;
      axis.crossAxisTranslation.x = isXDirection ? 0 : seriesRect.x + crossPosition - axis.translation.x;
      axis.crossAxisTranslation.y = isXDirection ? seriesRect.y + crossPosition - axis.translation.y : 0;
    }
  }
  buildCrossLinePadding(axisAreaSize) {
    var _a;
    const crossLinePadding = { top: 0, right: 0, bottom: 0, left: 0 };
    for (const axis of this.axes) {
      const { position, label } = axis;
      if (axis.crossLines) {
        for (const crossLine of axis.crossLines) {
          if (crossLine instanceof CartesianCrossLine) {
            crossLine.position = position ?? "top";
            (_a = crossLine.label).parallel ?? (_a.parallel = label.parallel);
          }
          crossLine.calculatePadding?.(crossLinePadding);
        }
      }
    }
    for (const [side, padding2 = 0] of entries(crossLinePadding)) {
      crossLinePadding[side] = Math.max(padding2 - (axisAreaSize.get(side) ?? 0), 0);
    }
    return crossLinePadding;
  }
  clampToOutsideSeriesRect(seriesRect, value, dimension, direction) {
    const bound = dimension === "x" ? seriesRect.x : seriesRect.y;
    const size = dimension === "x" ? seriesRect.width : seriesRect.height;
    return direction === 1 ? Math.min(value, bound + size) : Math.max(value, bound);
  }
  async getSyncedDomain(axis) {
    const syncModule = this.modulesManager.getModule("sync");
    if (!syncModule?.enabled)
      return;
    return await syncModule.getSyncedDomain(axis);
  }
  syncAxisChanges(newValue, oldValue) {
    const syncModule = this.modulesManager.getModule("sync");
    if (!syncModule?.enabled)
      return;
    const removed = new Set(oldValue ?? []);
    for (const axis of newValue) {
      removed.delete(axis);
    }
    for (const removedAxis of removed) {
      syncModule.removeAxis(removedAxis);
    }
  }
  sizeAxis(axis, seriesRect, position) {
    const isNumberAxis = axis instanceof NumberAxis;
    const isLeftRight = position === "left" || position === "right";
    const { width: width2, height: height2 } = seriesRect;
    const maxEnd = isLeftRight ? height2 : width2;
    let start2 = 0;
    let end3 = maxEnd;
    let { min, max } = this.ctx.zoomManager.getAxisZoom(axis.id);
    const { width: axisWidth, unit, align: align2 } = axis.layoutConstraints;
    if (unit === "px") {
      end3 = start2 + axisWidth;
    } else {
      end3 = end3 * axisWidth / 100;
    }
    const size = end3 - start2;
    if (align2 === "end") {
      start2 = maxEnd - size;
      end3 = maxEnd;
    } else if (align2 === "center") {
      const center2 = start2 + (maxEnd - start2) / 2;
      start2 = center2 - size / 2;
      end3 = center2 + size / 2;
    } else if (align2 === "justify") {
      end3 = maxEnd;
    }
    if (isLeftRight) {
      if (isNumberAxis) {
        [start2, end3] = [end3, start2];
      } else {
        [min, max] = [1 - max, 1 - min];
      }
    }
    axis.range = [start2, end3];
    axis.visibleRange = [min, max];
    axis.gridLength = isLeftRight ? width2 : height2;
    axis.lineRange = isLeftRight ? [height2, 0] : [0, width2];
  }
  positionAxes(opts) {
    const { axes, axisBound, axisWidths, axisOffsets, axisAreaWidths, seriesRect, position } = opts;
    const axisAreaWidth = axisAreaWidths.get(position) ?? 0;
    let mainDimension = "x";
    let minorDimension = "y";
    let direction = 1;
    if (position === "top" || position === "bottom") {
      mainDimension = "y";
      minorDimension = "x";
    }
    let axisBoundMainOffset = axisBound[mainDimension];
    if (position === "right" || position === "bottom") {
      direction = -1;
      axisBoundMainOffset += mainDimension === "x" ? axisBound.width : axisBound.height;
    }
    for (const axis of axes) {
      const minorOffset = axisAreaWidths.get(minorDimension === "x" ? "left" : "top") ?? 0;
      const axisThickness = axisWidths.get(axis.id) ?? 0;
      const axisOffset = axisOffsets.get(axis.id) ?? 0;
      axis.gridPadding = axisAreaWidth - axisOffset - axisThickness;
      axis.translation[minorDimension] = axisBound[minorDimension] + minorOffset;
      axis.translation[mainDimension] = this.clampToOutsideSeriesRect(
        seriesRect,
        axisBoundMainOffset + direction * (axisOffset + axisThickness),
        mainDimension,
        direction
      );
    }
  }
  shouldFlipXY() {
    return this.series.every((series) => series instanceof CartesianSeries && series.shouldFlipXY());
  }
  getDefaultState() {
    const axisAreaWidths = /* @__PURE__ */ new Map();
    if (this.lastAreaWidths) {
      for (const { position = "left" } of this.axes) {
        const areaWidth = this.lastAreaWidths.get(position);
        if (areaWidth != null) {
          axisAreaWidths.set(position, areaWidth);
        }
      }
    }
    return { axisAreaWidths, clipSeries: false, overflows: false };
  }
  isLayoutStable(newState, prevState) {
    if (prevState.overflows !== newState.overflows || prevState.clipSeries !== newState.clipSeries) {
      return false;
    }
    for (const key of newState.axisAreaWidths.keys()) {
      if (!prevState.axisAreaWidths.has(key)) {
        return false;
      }
    }
    for (const [p, w] of prevState.axisAreaWidths.entries()) {
      const otherW = newState.axisAreaWidths.get(p);
      if ((w != null || otherW != null) && w !== otherW) {
        return false;
      }
    }
    return true;
  }
  clipAxis(axis, seriesRect, layoutBBox) {
    const gridLinePadding = Math.ceil(axis.gridLine?.width ?? 0);
    const axisLinePadding = Math.ceil(axis.line?.width ?? 0);
    let { width: width2, height: height2 } = seriesRect;
    width2 += axis.direction === "x" /* X */ ? gridLinePadding : axisLinePadding;
    height2 += axis.direction === "y" /* Y */ ? gridLinePadding : axisLinePadding;
    axis.clipGrid(seriesRect.x, seriesRect.y, width2, height2);
    switch (axis.position) {
      case "left":
      case "right":
        axis.clipTickLines(
          layoutBBox.x,
          seriesRect.y - gridLinePadding,
          layoutBBox.width + gridLinePadding,
          seriesRect.height + gridLinePadding * 2
        );
        break;
      case "top":
      case "bottom":
        axis.clipTickLines(
          seriesRect.x - gridLinePadding,
          layoutBBox.y,
          seriesRect.width + gridLinePadding * 2,
          layoutBBox.height + gridLinePadding
        );
        break;
    }
  }
};
_CartesianChart.className = "CartesianChart";
_CartesianChart.type = "cartesian";
_CartesianChart.AxesPadding = 15;
__decorateClass([
  ActionOnSet({
    changeValue(newValue, oldValue) {
      this.onAxisChange(newValue, oldValue);
    }
  })
], _CartesianChart.prototype, "axes", 2);
var CartesianChart = _CartesianChart;
function getSize(isVertical, bounds) {
  return isVertical ? bounds?.width : bounds?.height;
}

// packages/ag-charts-community/src/chart/cartesianChartModule.ts
var histogramAxisTypes = /* @__PURE__ */ new Set(["number", "log", "time"]);
var invalidHistogramAxis = (axis) => isObject(axis) && axis.type != null && !histogramAxisTypes.has(axis.type);
var CartesianChartModule = {
  type: "chart",
  name: "cartesian",
  version: VERSION,
  options: cartesianChartOptionsDefs,
  create(options, resources) {
    return new CartesianChart(options, resources);
  },
  validate(options, optionsDefs2, path) {
    const additionalErrors = [];
    if (options?.series?.[0]?.type === "histogram") {
      if (Object.values(options?.axes ?? {}).some(invalidHistogramAxis)) {
        additionalErrors.push(
          new ValidationError(
            "invalid",
            "only continuous axis types when histogram series is used",
            options.axes,
            path,
            "axes"
          )
        );
        options = without(options, ["axes"]);
      }
    }
    const result = validate(options, optionsDefs2, path);
    result.invalid.push(...additionalErrors);
    return result;
  }
};

// packages/ag-charts-community/src/chart/polarChart.ts
var PolarChart = class extends Chart {
  constructor(options, resources) {
    super(options, resources);
    this.axes = this.createChartAxes();
    this.padding = new Padding(40);
    this.ctx.axisManager.axisGroup.zIndex = 8 /* AXIS_FOREGROUND */;
  }
  createChartAxes() {
    return new PolarChartAxes();
  }
  getChartType() {
    return "polar";
  }
  isDataTransactionSupported() {
    return !this.series.some((s) => s.type === "pie" || s.type === "donut");
  }
  async performLayout(ctx) {
    const seriesRect = ctx.layoutBox.clone().shrink(this.seriesArea.getPadding());
    this.seriesRect = seriesRect;
    this.animationRect = seriesRect;
    this.seriesRoot.translationX = seriesRect.x;
    this.seriesRoot.translationY = seriesRect.y;
    await this.computeCircle(seriesRect);
    for (const axis of this.axes) {
      axis.update();
    }
    let maxMarkerSize = 0;
    for (const series of this.series) {
      maxMarkerSize = Math.max(maxMarkerSize, series.properties.marker?.size ?? 0);
    }
    for (const series of this.series.filter(isPolarSeries)) {
      series.maxChartMarkerSize = maxMarkerSize;
    }
    this.ctx.layoutManager.emitLayoutComplete(ctx, {
      series: { visible: true, rect: seriesRect, paddedRect: ctx.layoutBox }
    });
  }
  updateAxes(seriesBox, cx, cy, radius) {
    if (this.axes.length === 0)
      return;
    const angleAxis = this.axes["angle" /* Angle */];
    const radiusAxis = this.axes["radius" /* Radius */];
    const angleScale = angleAxis.scale;
    const innerRadiusRatio = radiusAxis.innerRadiusRatio;
    angleAxis.innerRadiusRatio = innerRadiusRatio;
    angleAxis.computeRange();
    angleAxis.gridLength = radius;
    radiusAxis.gridAngles = angleScale.ticks({
      nice: [angleAxis.nice, angleAxis.nice],
      interval: void 0,
      tickCount: void 0,
      minTickCount: 0,
      maxTickCount: Infinity
    })?.ticks?.map((value) => angleScale.convert(value));
    radiusAxis.gridRange = angleAxis.range;
    radiusAxis.range = [radius, radius * innerRadiusRatio];
    for (const axis of [angleAxis, radiusAxis]) {
      axis.translation.x = seriesBox.x + cx;
      axis.translation.y = seriesBox.y + cy;
      axis.calculateLayout();
    }
  }
  async computeCircle(seriesBox) {
    const polarSeries = this.series.filter(isPolarSeries);
    const setSeriesCircle = (cx, cy, r) => {
      this.updateAxes(seriesBox, cx, cy, r);
      for (const series of polarSeries) {
        series.centerX = cx;
        series.centerY = cy;
        series.radius = r;
      }
      const pieSeries = polarSeries.filter((s) => s.type === "donut" || s.type === "pie");
      if (pieSeries.length > 1) {
        const innerRadii = pieSeries.map((series) => {
          const innerRadius = series.getInnerRadius();
          return { series, innerRadius };
        }).sort((a, b) => a.innerRadius - b.innerRadius);
        innerRadii.at(-1).series.surroundingRadius = void 0;
        for (let i = 0; i < innerRadii.length - 1; i++) {
          innerRadii[i].series.surroundingRadius = innerRadii[i + 1].innerRadius;
        }
      }
    };
    const centerX = seriesBox.width / 2;
    const centerY = seriesBox.height / 2;
    const initialRadius = Math.max(0, Math.min(seriesBox.width, seriesBox.height) / 2);
    let radius = initialRadius;
    setSeriesCircle(centerX, centerY, radius);
    const shake = async ({ hideWhenNecessary = false } = {}) => {
      const labelBoxes = [];
      for (const series of iterate(this.axes, polarSeries)) {
        const box = await series.computeLabelsBBox({ hideWhenNecessary }, seriesBox);
        if (box) {
          labelBoxes.push(box);
        }
      }
      if (labelBoxes.length === 0) {
        setSeriesCircle(centerX, centerY, initialRadius);
        return;
      }
      const labelBox = BBox.merge(labelBoxes);
      const refined = this.refineCircle(labelBox, radius, seriesBox);
      setSeriesCircle(refined.centerX, refined.centerY, refined.radius);
      radius = refined.radius;
    };
    await shake();
    await shake();
    await shake();
    await shake({ hideWhenNecessary: true });
    await shake({ hideWhenNecessary: true });
    for (const series of iterate(this.axes, polarSeries)) {
      await series.computeLabelsBBox({ hideWhenNecessary: true }, seriesBox);
    }
    return { radius, centerX, centerY };
  }
  refineCircle(labelsBox, radius, seriesBox) {
    const minCircleRatio = 0.5;
    const circleLeft = -radius;
    const circleTop = -radius;
    const circleRight = radius;
    const circleBottom = radius;
    let padLeft = Math.max(0, circleLeft - labelsBox.x);
    let padTop = Math.max(0, circleTop - labelsBox.y);
    let padRight = Math.max(0, labelsBox.x + labelsBox.width - circleRight);
    let padBottom = Math.max(0, labelsBox.y + labelsBox.height - circleBottom);
    padLeft = padRight = Math.max(padLeft, padRight);
    padTop = padBottom = Math.max(padTop, padBottom);
    const availCircleWidth = seriesBox.width - padLeft - padRight;
    const availCircleHeight = seriesBox.height - padTop - padBottom;
    let newRadius = Math.min(availCircleWidth, availCircleHeight) / 2;
    const minHorizontalRadius = minCircleRatio * seriesBox.width / 2;
    const minVerticalRadius = minCircleRatio * seriesBox.height / 2;
    const minRadius = Math.min(minHorizontalRadius, minVerticalRadius);
    if (newRadius < minRadius) {
      newRadius = minRadius;
      const horizontalPadding = padLeft + padRight;
      const verticalPadding = padTop + padBottom;
      if (2 * newRadius + verticalPadding > seriesBox.height) {
        const padHeight = seriesBox.height - 2 * newRadius;
        if (Math.min(padTop, padBottom) * 2 > padHeight) {
          padTop = padHeight / 2;
          padBottom = padHeight / 2;
        } else if (padTop > padBottom) {
          padTop = padHeight - padBottom;
        } else {
          padBottom = padHeight - padTop;
        }
      }
      if (2 * newRadius + horizontalPadding > seriesBox.width) {
        const padWidth = seriesBox.width - 2 * newRadius;
        if (Math.min(padLeft, padRight) * 2 > padWidth) {
          padLeft = padWidth / 2;
          padRight = padWidth / 2;
        } else if (padLeft > padRight) {
          padLeft = padWidth - padRight;
        } else {
          padRight = padWidth - padLeft;
        }
      }
    }
    const newWidth = padLeft + 2 * newRadius + padRight;
    const newHeight = padTop + 2 * newRadius + padBottom;
    return {
      centerX: (seriesBox.width - newWidth) / 2 + padLeft + newRadius,
      centerY: (seriesBox.height - newHeight) / 2 + padTop + newRadius,
      radius: newRadius
    };
  }
};
PolarChart.className = "PolarChart";
PolarChart.type = "polar";
function isPolarSeries(series) {
  return series instanceof PolarSeries;
}

// packages/ag-charts-community/src/chart/polarChartModule.ts
var PolarChartModule = {
  type: "chart",
  name: "polar",
  version: VERSION,
  options: polarChartOptionsDefs,
  create(options, resources) {
    return new PolarChart(options, resources);
  },
  validate(options, optionsDefs2, path) {
    const additionalErrors = [];
    const baseType = options?.series?.[0]?.type;
    if (baseType === "pie" || baseType === "donut") {
      if (options?.axes) {
        additionalErrors.push(new UnknownError([], options.axes, path, "axes"));
        options = without(options, ["axes"]);
      }
    }
    const result = validate(options, optionsDefs2, path);
    result.invalid.push(...additionalErrors);
    return result;
  }
};

// packages/ag-charts-community/src/chart/gridLayout.ts
function gridLayout({
  orientation,
  bboxes,
  maxHeight,
  maxWidth,
  itemPaddingY = 0,
  itemPaddingX = 0,
  forceResult = false
}) {
  const horizontal = orientation === "horizontal";
  const primary = {
    max: horizontal ? maxWidth : maxHeight,
    fn: horizontal ? (b) => b.width : (b) => b.height,
    padding: horizontal ? itemPaddingX : itemPaddingY
  };
  const secondary = {
    max: horizontal ? maxHeight : maxWidth,
    fn: horizontal ? (b) => b.height : (b) => b.width,
    padding: horizontal ? itemPaddingY : itemPaddingX
  };
  let processedBBoxCount = 0;
  const rawPages = [];
  while (processedBBoxCount < bboxes.length) {
    const unprocessedBBoxes = bboxes.slice(processedBBoxCount);
    const result = processBBoxes(unprocessedBBoxes, processedBBoxCount, primary, secondary, forceResult);
    if (!result) {
      return;
    }
    processedBBoxCount += result.processedBBoxCount;
    rawPages.push(result.pageIndices);
  }
  return buildPages(rawPages, orientation, bboxes, itemPaddingY, itemPaddingX);
}
function processBBoxes(bboxes, indexOffset, primary, secondary, forceResult) {
  const minGuess = 1;
  let startingGuess = estimateStartingGuess(bboxes, primary);
  if (startingGuess < minGuess) {
    if (!forceResult) {
      return;
    }
    startingGuess = minGuess;
  }
  let guess = startingGuess;
  while (guess >= minGuess) {
    const pageIndices = calculatePage(bboxes, indexOffset, guess, primary, secondary, forceResult);
    if (pageIndices == null && guess <= minGuess) {
      return;
    }
    if (pageIndices == null) {
      guess--;
      continue;
    }
    if (typeof pageIndices === "number") {
      if (pageIndices <= minGuess) {
        return;
      }
      guess = pageIndices < guess && pageIndices > minGuess ? pageIndices : guess;
      guess--;
      continue;
    }
    const processedBBoxCount = pageIndices.length * pageIndices[0].length;
    return { processedBBoxCount, pageIndices };
  }
}
function calculatePage(bboxes, indexOffset, primaryCount, primary, secondary, forceResult) {
  const result = [];
  let sumSecondary = 0;
  let currentMaxSecondary = 0;
  let currentPrimaryIndices = [];
  const maxPrimaryValues = [];
  for (let bboxIndex = 0; bboxIndex < bboxes.length; bboxIndex++) {
    const primaryValueIdx = (bboxIndex + primaryCount) % primaryCount;
    if (primaryValueIdx === 0) {
      sumSecondary += currentMaxSecondary;
      currentMaxSecondary = 0;
      if (currentPrimaryIndices.length > 0) {
        result.push(currentPrimaryIndices);
      }
      currentPrimaryIndices = [];
    }
    const primaryValue = primary.fn(bboxes[bboxIndex]) + primary.padding;
    maxPrimaryValues[primaryValueIdx] = Math.max(maxPrimaryValues[primaryValueIdx] ?? 0, primaryValue);
    currentMaxSecondary = Math.max(currentMaxSecondary, secondary.fn(bboxes[bboxIndex]) + secondary.padding);
    const currentSecondaryDimension = sumSecondary + currentMaxSecondary;
    const returnResult = !forceResult || result.length > 0;
    if (currentSecondaryDimension > secondary.max && returnResult) {
      currentPrimaryIndices = [];
      break;
    }
    const sumPrimary = maxPrimaryValues.reduce((sum, next) => sum + next, 0);
    if (sumPrimary > primary.max && !forceResult) {
      if (maxPrimaryValues.length < primaryCount) {
        return maxPrimaryValues.length;
      }
      return;
    }
    currentPrimaryIndices.push(bboxIndex + indexOffset);
  }
  if (currentPrimaryIndices.length > 0) {
    result.push(currentPrimaryIndices);
  }
  return result.length > 0 ? result : void 0;
}
function buildPages(rawPages, orientation, bboxes, itemPaddingY, itemPaddingX) {
  let maxPageWidth = 0;
  let maxPageHeight = 0;
  const pages = rawPages.map((indices) => {
    if (orientation === "horizontal") {
      indices = transpose(indices);
    }
    let endIndex = 0;
    const columns = indices.map((colIndices) => {
      const colBBoxes = colIndices.map((bboxIndex) => {
        endIndex = Math.max(bboxIndex, endIndex);
        return bboxes[bboxIndex];
      });
      let columnHeight = 0;
      let columnWidth = 0;
      for (const bbox of colBBoxes) {
        columnHeight += bbox.height + itemPaddingY;
        columnWidth = Math.max(columnWidth, bbox.width + itemPaddingX);
      }
      return {
        indices: colIndices,
        bboxes: colBBoxes,
        columnHeight: Math.ceil(columnHeight),
        columnWidth: Math.ceil(columnWidth)
      };
    });
    let pageWidth = 0;
    let pageHeight = 0;
    for (const column of columns) {
      pageWidth += column.columnWidth;
      pageHeight = Math.max(pageHeight, column.columnHeight);
    }
    maxPageWidth = Math.max(pageWidth, maxPageWidth);
    maxPageHeight = Math.max(pageHeight, maxPageHeight);
    return {
      columns,
      startIndex: indices[0][0],
      endIndex,
      pageWidth,
      pageHeight
    };
  });
  return { pages, maxPageWidth, maxPageHeight };
}
function transpose(data) {
  const result = [];
  for (const _ of data[0]) {
    result.push([]);
  }
  for (const [dataIdx, innerData] of data.entries()) {
    for (const [itemIdx, item] of innerData.entries()) {
      result[itemIdx][dataIdx] = item;
    }
  }
  return result;
}
function estimateStartingGuess(bboxes, primary) {
  const n = bboxes.length;
  let primarySum = 0;
  for (let bboxIndex = 0; bboxIndex < n; bboxIndex++) {
    primarySum += primary.fn(bboxes[bboxIndex]) + primary.padding;
    if (primarySum > primary.max) {
      const ratio2 = n / bboxIndex;
      if (ratio2 < 2) {
        return Math.ceil(n / 2);
      }
      return bboxIndex;
    }
  }
  return n;
}

// packages/ag-charts-community/src/chart/pagination/pagination.ts
var PaginationLabel = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.color = "black";
    this.fontStyle = void 0;
    this.fontWeight = void 0;
    this.fontSize = 12 /* SMALL */;
    this.fontFamily = "Verdana, sans-serif";
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], PaginationLabel.prototype, "color", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PaginationLabel.prototype, "fontStyle", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PaginationLabel.prototype, "fontWeight", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PaginationLabel.prototype, "fontSize", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PaginationLabel.prototype, "fontFamily", 2);
var PaginationMarkerStyle = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.size = 15;
    this.fill = void 0;
    this.fillOpacity = void 0;
    this.stroke = void 0;
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], PaginationMarkerStyle.prototype, "size", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PaginationMarkerStyle.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PaginationMarkerStyle.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PaginationMarkerStyle.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PaginationMarkerStyle.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PaginationMarkerStyle.prototype, "strokeOpacity", 2);
var PaginationMarker = class extends BaseProperties {
  constructor(parent) {
    super();
    this.parent = parent;
    this.shape = "triangle";
    this.size = 15;
    this.padding = 8;
  }
};
__decorateClass([
  ActionOnSet({
    changeValue() {
      if (this.parent.marker === this) {
        this.parent.onMarkerShapeChange();
      }
    }
  })
], PaginationMarker.prototype, "shape", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PaginationMarker.prototype, "size", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PaginationMarker.prototype, "padding", 2);
var Pagination = class extends BaseProperties {
  constructor(chartUpdateCallback, pageUpdateCallback) {
    super();
    this.chartUpdateCallback = chartUpdateCallback;
    this.pageUpdateCallback = pageUpdateCallback;
    this.id = createId(this);
    this.marker = new PaginationMarker(this);
    this.activeStyle = new PaginationMarkerStyle();
    this.inactiveStyle = new PaginationMarkerStyle();
    this.highlightStyle = new PaginationMarkerStyle();
    this.label = new PaginationLabel();
    this.group = new TranslatableGroup({ name: "pagination" });
    this.labelNode = new Text();
    this.totalPages = 0;
    this.currentPage = 0;
    this.translationX = 0;
    this.translationY = 0;
    this.nextButtonDisabled = false;
    this.previousButtonDisabled = false;
    this._visible = true;
    this._enabled = true;
    this._orientation = "vertical";
    this.nextButton = new Marker();
    this.previousButton = new Marker();
    this.labelNode.setProperties({
      textBaseline: "middle",
      fontSize: 12 /* SMALL */,
      fontFamily: "Verdana, sans-serif",
      fill: "black",
      y: 1
    });
    this.group.append([this.nextButton, this.previousButton, this.labelNode]);
    this.update();
    this.updateMarkers();
  }
  set visible(value) {
    this._visible = value;
    this.updateGroupVisibility();
  }
  get visible() {
    return this._visible;
  }
  set enabled(value) {
    this._enabled = value;
    this.updateGroupVisibility();
  }
  get enabled() {
    return this._enabled;
  }
  updateGroupVisibility() {
    this.group.visible = this.enabled && this.visible;
  }
  set orientation(value) {
    this._orientation = value;
    switch (value) {
      case "horizontal": {
        this.previousButton.rotation = -Math.PI / 2;
        this.nextButton.rotation = Math.PI / 2;
        break;
      }
      case "vertical":
      default: {
        this.previousButton.rotation = 0;
        this.nextButton.rotation = Math.PI;
      }
    }
  }
  get orientation() {
    return this._orientation;
  }
  update() {
    this.updateLabel();
    this.updatePositions();
    this.enableOrDisableButtons();
  }
  updatePositions() {
    this.group.translationX = this.translationX;
    this.group.translationY = this.translationY;
    this.updateLabelPosition();
    this.updateNextButtonPosition();
  }
  updateLabelPosition() {
    const { size: markerSize, padding: markerPadding } = this.marker;
    this.nextButton.size = markerSize;
    this.previousButton.size = markerSize;
    this.labelNode.x = markerSize / 2 + markerPadding;
  }
  updateNextButtonPosition() {
    const labelBBox = this.labelNode.getBBox();
    this.nextButton.translationX = labelBBox.width + (this.marker.size / 2 + this.marker.padding) * 2;
  }
  updateLabel() {
    const {
      currentPage,
      totalPages: pages,
      labelNode,
      label: { color: color2, fontStyle, fontWeight: fontWeight2, fontSize, fontFamily }
    } = this;
    labelNode.text = `${currentPage + 1} / ${pages}`;
    labelNode.fill = color2;
    labelNode.fontStyle = fontStyle;
    labelNode.fontWeight = fontWeight2;
    labelNode.fontSize = fontSize;
    labelNode.fontFamily = fontFamily;
  }
  updateMarkers() {
    const {
      nextButton,
      previousButton,
      nextButtonDisabled,
      previousButtonDisabled,
      activeStyle,
      inactiveStyle,
      highlightStyle,
      highlightActive
    } = this;
    const buttonStyle = (button, disabled) => {
      if (disabled) {
        return inactiveStyle;
      } else if (button === highlightActive) {
        return highlightStyle;
      }
      return activeStyle;
    };
    this.updateMarker(nextButton, buttonStyle("next", nextButtonDisabled));
    this.updateMarker(previousButton, buttonStyle("previous", previousButtonDisabled));
  }
  updateMarker(marker, style2) {
    const { shape, size } = this.marker;
    marker.shape = shape;
    marker.size = size;
    marker.fill = style2.fill;
    marker.fillOpacity = style2.fillOpacity ?? 1;
    marker.stroke = style2.stroke;
    marker.strokeWidth = style2.strokeWidth;
    marker.strokeOpacity = style2.strokeOpacity;
  }
  enableOrDisableButtons() {
    const { currentPage, totalPages } = this;
    const zeroPagesToDisplay = totalPages === 0;
    const onLastPage = currentPage === totalPages - 1;
    const onFirstPage = currentPage === 0;
    this.nextButtonDisabled = onLastPage || zeroPagesToDisplay;
    this.previousButtonDisabled = onFirstPage || zeroPagesToDisplay;
  }
  setPage(pageNumber) {
    pageNumber = clamp(0, pageNumber, Math.max(0, this.totalPages - 1));
    if (this.currentPage !== pageNumber) {
      this.currentPage = pageNumber;
      this.onPaginationChanged();
    }
  }
  getCursor(node) {
    return { previous: this.previousButtonDisabled, next: this.nextButtonDisabled }[node] ? void 0 : "pointer";
  }
  onClick(event, node) {
    event.preventDefault();
    if (node === "next" && !this.nextButtonDisabled) {
      this.incrementPage();
      this.onPaginationChanged();
    } else if (node === "previous" && !this.previousButtonDisabled) {
      this.decrementPage();
      this.onPaginationChanged();
    }
  }
  onMouseHover(node) {
    this.highlightActive = node;
    this.updateMarkers();
    this.chartUpdateCallback(9 /* SCENE_RENDER */);
  }
  onPaginationChanged() {
    this.pageUpdateCallback(this.currentPage);
  }
  incrementPage() {
    this.currentPage = Math.min(this.currentPage + 1, this.totalPages - 1);
  }
  decrementPage() {
    this.currentPage = Math.max(this.currentPage - 1, 0);
  }
  onMarkerShapeChange() {
    this.updatePositions();
    this.updateMarkers();
    this.chartUpdateCallback(9 /* SCENE_RENDER */);
  }
  attachPagination(node) {
    node.append(this.group);
  }
  getBBox() {
    return this.group.getBBox();
  }
  computeCSSBounds() {
    const prev = Transformable.toCanvas(this.previousButton);
    const next = Transformable.toCanvas(this.nextButton);
    return { prev, next };
  }
};
Pagination.className = "Pagination";
__decorateClass([
  addFakeTransformToInstanceProperty
], Pagination.prototype, "marker", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Pagination.prototype, "activeStyle", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Pagination.prototype, "inactiveStyle", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Pagination.prototype, "highlightStyle", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Pagination.prototype, "label", 2);

// packages/ag-charts-community/src/chart/legend/legendDOMProxy.ts
var LegendDOMProxy = class {
  constructor(ctx, idPrefix) {
    this.dirty = true;
    this.itemList = ctx.proxyInteractionService.createProxyContainer({
      type: "list",
      domManagerId: `${idPrefix}-toolbar`,
      classList: ["ag-charts-proxy-legend-toolbar"],
      ariaLabel: { id: "ariaLabelLegend" }
    });
    this.paginationGroup = ctx.proxyInteractionService.createProxyContainer({
      type: "group",
      domManagerId: `${idPrefix}-pagination`,
      classList: ["ag-charts-proxy-legend-pagination"],
      ariaLabel: { id: "ariaLabelLegendPagination" }
    });
    this.itemDescription = createElement("p");
    this.itemDescription.style.display = "none";
    this.itemDescription.id = createElementId();
    this.itemDescription.textContent = this.getItemAriaDescription(ctx.localeManager);
    this.itemList.getElement().append(this.itemDescription);
  }
  initLegendList(params) {
    if (!this.dirty)
      return;
    const { ctx, itemSelection, datumReader, itemListener } = params;
    const lm = ctx.localeManager;
    const count = itemSelection.length;
    itemSelection.each((markerLabel, datum, index) => {
      markerLabel.proxyButton?.destroy();
      markerLabel.proxyButton = ctx.proxyInteractionService.createProxyElement({
        type: "listswitch",
        textContent: this.getItemAriaText(lm, toPlainText(datumReader.getItemLabel(datum)), index, count),
        ariaChecked: !!markerLabel.datum.enabled,
        ariaDescribedBy: this.itemDescription.id,
        parent: this.itemList
      });
      const button = markerLabel.proxyButton;
      button.addListener("click", (ev) => itemListener.onClick(ev.sourceEvent, markerLabel.datum, button));
      button.addListener("dblclick", (ev) => itemListener.onDoubleClick(ev.sourceEvent, markerLabel.datum));
      button.addListener("mouseenter", (ev) => itemListener.onHover(ev.sourceEvent, markerLabel));
      button.addListener("mouseleave", () => itemListener.onLeave());
      button.addListener("contextmenu", (ev) => itemListener.onContextClick(ev, markerLabel));
      button.addListener("blur", () => itemListener.onLeave());
      button.addListener("focus", (ev) => itemListener.onHover(ev.sourceEvent, markerLabel));
      button.addListener("drag-start", () => {
      });
    });
    this.dirty = false;
  }
  update(params) {
    if (params.visible) {
      this.initLegendList(params);
      this.updateItemProxyButtons(params);
      this.updatePaginationProxyButtons(params, true);
    }
    this.updateVisibility(params.visible);
  }
  updateVisibility(visible) {
    this.itemList.setHidden(!visible);
    this.paginationGroup.setHidden(!visible);
  }
  updateItemProxyButtons({ itemSelection, group, pagination, interactive }) {
    const groupBBox = Transformable.toCanvas(group);
    this.itemList.setBounds(groupBBox);
    const maxHeight = Math.max(...itemSelection.nodes().map((l) => l.getTextMeasureBBox().height));
    itemSelection.each((l, _datum) => {
      if (l.proxyButton) {
        const visible = l.pageIndex === pagination.currentPage;
        const { x, y, height: height2, width: width2 } = Transformable.toCanvas(l, l.getTextMeasureBBox());
        const margin = (maxHeight - height2) / 2;
        const bbox = { x: x - groupBBox.x, y: y - margin - groupBBox.y, height: maxHeight, width: width2 };
        const enabled = interactive && visible;
        l.proxyButton.setCursor("pointer");
        l.proxyButton.setEnabled(enabled);
        l.proxyButton.setPointerEvents(enabled ? void 0 : "none");
        l.proxyButton.setBounds(bbox);
      }
    });
  }
  updatePaginationProxyButtons(params, init) {
    const { pagination } = params;
    this.paginationGroup.setHidden(!pagination.visible);
    if (init && "ctx" in params) {
      const { oldPages, newPages } = params;
      const oldNeedsButtons = (oldPages?.length ?? newPages.length) > 1;
      const newNeedsButtons = newPages.length > 1;
      if (oldNeedsButtons !== newNeedsButtons) {
        if (newNeedsButtons) {
          this.createPaginationButtons(params);
        } else {
          this.destroyPaginationButtons();
        }
      }
      this.paginationGroup.setAriaHidden(newNeedsButtons ? void 0 : true);
    }
    if (this.prevButton && this.nextButton) {
      const { prev, next } = pagination.computeCSSBounds();
      const group = BBox.merge([prev, next]);
      prev.x -= group.x;
      prev.y -= group.y;
      next.x -= group.x;
      next.y -= group.y;
      this.paginationGroup.setBounds(group);
      this.prevButton.setBounds(prev);
      this.nextButton.setBounds(next);
      this.prevButton.setEnabled(pagination.currentPage !== 0);
      this.nextButton.setEnabled(pagination.currentPage !== pagination.totalPages - 1);
      this.nextButton.setCursor(pagination.getCursor("next"));
      this.prevButton.setCursor(pagination.getCursor("previous"));
    }
  }
  createPaginationButtons(params) {
    const { ctx, pagination } = params;
    if (!this.prevButton) {
      this.prevButton = ctx.proxyInteractionService.createProxyElement({
        type: "button",
        textContent: { id: "ariaLabelLegendPagePrevious" },
        tabIndex: 0,
        parent: this.paginationGroup
      });
      this.prevButton.addListener("click", (ev) => this.onPageButton(params, ev, "previous"));
      this.prevButton.addListener("mouseenter", () => pagination.onMouseHover("previous"));
      this.prevButton.addListener("mouseleave", () => pagination.onMouseHover(void 0));
    }
    if (!this.nextButton) {
      this.nextButton = ctx.proxyInteractionService.createProxyElement({
        type: "button",
        textContent: { id: "ariaLabelLegendPageNext" },
        tabIndex: 0,
        parent: this.paginationGroup
      });
      this.nextButton.addListener("click", (ev) => this.onPageButton(params, ev, "next"));
      this.nextButton.addListener("mouseenter", () => pagination.onMouseHover("next"));
      this.nextButton.addListener("mouseleave", () => pagination.onMouseHover(void 0));
    }
  }
  destroyPaginationButtons() {
    this.nextButton?.destroy();
    this.prevButton?.destroy();
    this.nextButton = void 0;
    this.prevButton = void 0;
  }
  onPageButton(params, ev, node) {
    params.pagination.onClick(ev.sourceEvent, node);
    this.updatePaginationProxyButtons(params, false);
  }
  onDataUpdate(oldData, newData) {
    this.dirty = oldData.length !== newData.length || oldData.some((_v, index, _a) => {
      const [newValue, oldValue] = [newData[index], oldData[index]];
      return newValue.id !== oldValue.id;
    });
  }
  onLocaleChanged(localeManager, itemSelection, datumReader) {
    const count = itemSelection.length;
    itemSelection.each(({ proxyButton }, datum, index) => {
      const button = proxyButton?.getElement();
      if (button != null) {
        const label = toPlainText(datumReader.getItemLabel(datum));
        button.textContent = this.getItemAriaText(localeManager, label, index, count);
      }
    });
    this.itemDescription.textContent = this.getItemAriaDescription(localeManager);
  }
  onPageChange(params) {
    this.updateItemProxyButtons(params);
    this.updatePaginationProxyButtons(params, false);
  }
  getItemAriaText(localeManager, label, index, count) {
    if (index >= 0 && label) {
      index++;
      return localeManager.t("ariaLabelLegendItem", { label, index, count });
    }
    return localeManager.t("ariaLabelLegendItemUnknown");
  }
  getItemAriaDescription(localeManager) {
    return localeManager.t("ariaDescriptionLegendItem");
  }
};

// packages/ag-charts-community/src/chart/legend/legendEvent.ts
function makeLegendItemEvent(type, { itemId, seriesId, label: { text: text2 } }, event) {
  const result = {
    defaultPrevented: false,
    apiEvent: {
      type,
      itemId,
      // FIXME: AG-16068
      seriesId,
      event,
      text: toPlainText(text2),
      preventDefault: () => result.defaultPrevented = true
    }
  };
  return result;
}

// packages/ag-charts-community/src/chart/legend/legendMarkerLabel.ts
var LegendMarkerLabel = class extends TranslatableGroup {
  constructor() {
    super({ name: "markerLabelGroup" });
    this.symbolsGroup = this.appendChild(
      new Group({
        name: "legend-markerLabel-symbols",
        renderToOffscreenCanvas: true,
        optimizeForInfrequentRedraws: true
      })
    );
    this.label = this.appendChild(new Text());
    this.enabled = true;
    this.pageIndex = Number.NaN;
    this.spacing = 0;
    this.length = 0;
    this.isCustomMarker = false;
    this.marker = this.symbolsGroup.appendChild(new Marker({ zIndex: 1 }));
    this.line = this.symbolsGroup.appendChild(new Line({ zIndex: 0 }));
    this.line.visible = false;
    this.label.textBaseline = "middle";
    this.label.y = 1;
  }
  destroy() {
    super.destroy();
    this.proxyButton?.destroy();
  }
  setEnabled(enabled) {
    this.enabled = enabled;
    this.refreshVisibilities();
  }
  getTextMeasureBBox() {
    this.layout();
    return BBox.merge([this.symbolsGroup.getBBox(), this.label.getTextMeasureBBox()]);
  }
  refreshVisibilities() {
    const opacity = this.enabled ? 1 : 0.5;
    this.label.opacity = opacity;
    this.opacity = opacity;
  }
  layout() {
    const { marker, line, length: length2, isCustomMarker } = this;
    let centerTranslateX = 0;
    let centerTranslateY = 0;
    if (marker.visible) {
      const { size } = marker;
      const anchor = Marker.anchor(marker.shape);
      centerTranslateX = (anchor.x - 0.5) * size + length2 / 2;
      centerTranslateY = (anchor.y - 0.5) * size;
      if (isCustomMarker) {
        marker.x = 0;
        marker.y = 0;
        marker.translationX = centerTranslateX;
        marker.translationY = centerTranslateY;
      } else {
        marker.x = centerTranslateX;
        marker.y = centerTranslateY;
        marker.translationX = 0;
        marker.translationY = 0;
      }
    }
    if (line.visible) {
      line.x1 = 0;
      line.x2 = length2;
      line.y1 = 0;
      line.y2 = 0;
    }
  }
  preRender(renderCtx) {
    const out = super.preRender(renderCtx);
    this.layout();
    return out;
  }
  layoutLabel() {
    const { length: length2, spacing } = this;
    this.label.x = length2 + spacing;
  }
  computeBBox() {
    this.layout();
    return super.computeBBox();
  }
};
LegendMarkerLabel.className = "MarkerLabel";
__decorateClass([
  ProxyPropertyOnWrite("label")
], LegendMarkerLabel.prototype, "text", 2);
__decorateClass([
  ProxyPropertyOnWrite("label")
], LegendMarkerLabel.prototype, "fontStyle", 2);
__decorateClass([
  ProxyPropertyOnWrite("label")
], LegendMarkerLabel.prototype, "fontWeight", 2);
__decorateClass([
  ProxyPropertyOnWrite("label")
], LegendMarkerLabel.prototype, "fontSize", 2);
__decorateClass([
  ProxyPropertyOnWrite("label")
], LegendMarkerLabel.prototype, "fontFamily", 2);
__decorateClass([
  ProxyPropertyOnWrite("label", "fill")
], LegendMarkerLabel.prototype, "color", 2);
__decorateClass([
  ObserveChanges((target) => target.layoutLabel())
], LegendMarkerLabel.prototype, "spacing", 2);
__decorateClass([
  ObserveChanges((target) => target.layoutLabel())
], LegendMarkerLabel.prototype, "length", 2);
__decorateClass([
  SceneChangeDetection()
], LegendMarkerLabel.prototype, "isCustomMarker", 2);

// packages/ag-charts-community/src/chart/legend/legend.ts
function toHighlightNodeDatum(series, legendDatum) {
  switch (typeof legendDatum.itemId) {
    case "number":
      return {
        series,
        itemId: void 0,
        datum: void 0,
        datumIndex: legendDatum.itemId,
        legendItemName: legendDatum.legendItemName
      };
    case "string":
      return {
        series,
        itemId: legendDatum.itemId,
        datum: void 0,
        datumIndex: void 0,
        legendItemName: legendDatum.legendItemName
      };
    default:
      return legendDatum.itemId;
  }
}
var LegendLabel = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.maxLength = void 0;
    this.color = "black";
    this.fontStyle = void 0;
    this.fontWeight = void 0;
    this.fontSize = 12 /* SMALL */;
    this.fontFamily = "Verdana, sans-serif";
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendLabel.prototype, "maxLength", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendLabel.prototype, "color", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendLabel.prototype, "fontStyle", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendLabel.prototype, "fontWeight", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendLabel.prototype, "fontSize", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendLabel.prototype, "fontFamily", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendLabel.prototype, "formatter", 2);
var LegendMarker = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.shape = void 0;
    this.size = 15;
    this.padding = 8;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendMarker.prototype, "shape", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendMarker.prototype, "size", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendMarker.prototype, "padding", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendMarker.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendMarker.prototype, "enabled", 2);
var LegendLine = class extends BaseProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendLine.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendLine.prototype, "length", 2);
var LegendItem = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.paddingX = 16;
    this.paddingY = 8;
    this.showSeriesStroke = false;
    this.marker = new LegendMarker();
    this.label = new LegendLabel();
    this.line = new LegendLine();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendItem.prototype, "maxWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendItem.prototype, "paddingX", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendItem.prototype, "paddingY", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendItem.prototype, "showSeriesStroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendItem.prototype, "marker", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendItem.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendItem.prototype, "line", 2);
var LegendListeners = class extends BaseProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendListeners.prototype, "legendItemClick", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LegendListeners.prototype, "legendItemDoubleClick", 2);
var fillGradientDefaults2 = {
  type: "gradient",
  bounds: "item",
  gradient: "linear",
  colorStops: [{ color: "black" }],
  rotation: 0,
  reverse: false,
  colorSpace: "rgb"
};
var fillPatternDefaults2 = {
  type: "pattern",
  pattern: "forward-slanted-lines",
  width: 8,
  height: 8,
  padding: 1,
  fill: "black",
  fillOpacity: 1,
  backgroundFill: "white",
  backgroundFillOpacity: 1,
  stroke: "black",
  strokeOpacity: 1,
  strokeWidth: 1,
  rotation: 0,
  scale: 1
};
var fillImageDefaults2 = {
  type: "image",
  backgroundFill: "black",
  backgroundFillOpacity: 1,
  rotation: 0,
  repeat: "no-repeat",
  fit: "contain",
  width: 8,
  height: 8
};
var Legend = class extends BaseProperties {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.id = createId(this);
    this.group = new TranslatableGroup({ name: "legend", zIndex: 16 /* LEGEND */ });
    this.itemSelection = Selection.select(
      this.group,
      LegendMarkerLabel
    );
    this.containerNode = this.group.appendChild(new Rect({ name: "legend-container" }));
    this.oldSize = [0, 0];
    this.pages = [];
    this.maxPageSize = [0, 0];
    /** Item index to track on re-pagination, so current page updates appropriately. */
    this.paginationTrackingIndex = 0;
    this.truncatedItems = /* @__PURE__ */ new Set();
    this._data = [];
    this.toggleSeries = true;
    this.item = new LegendItem();
    this.listeners = new LegendListeners();
    this.enabled = false;
    this.position = "bottom";
    this.border = new Border(this.containerNode);
    this.cornerRadius = 0;
    this.fillOpacity = 1;
    this.padding = 4;
    this.spacing = 0;
    this.cleanup = new CleanupRegistry();
    this.size = [0, 0];
    this._visible = true;
    this.pagination = new Pagination(
      (type) => ctx.updateService.update(type),
      (page) => this.updatePageNumber(page)
    );
    this.pagination.attachPagination(this.group);
    const { items } = ctx.contextMenuRegistry.builtins;
    items["toggle-series-visibility"].action = (params) => this.contextToggleVisibility(params);
    items["toggle-other-series"].action = (params) => this.contextToggleOtherSeries(params);
    this.cleanup.register(
      ctx.eventsHub.on("active:load-memento", (event) => this.onActiveLoadMemento(event)),
      ctx.eventsHub.on("active:update", (event) => this.onActiveUpdate(event)),
      ctx.eventsHub.on("legend:change", this.onLegendDataChange.bind(this)),
      ctx.eventsHub.on("legend:change-partial", this.onLegendDataChangePartial.bind(this)),
      ctx.layoutManager.registerElement(1 /* Legend */, (e) => this.positionLegend(e)),
      ctx.eventsHub.on("locale:change", () => this.onLocaleChanged()),
      () => delete items["toggle-series-visibility"].action,
      () => delete items["toggle-other-series"].action,
      () => this.group.remove()
    );
    this.domProxy = new LegendDOMProxy(this.ctx, this.id);
    this.ctx.historyManager.addMementoOriginator(ctx.legendManager);
  }
  set data(value) {
    if (objectsEqual(value, this._data))
      return;
    this.domProxy.onDataUpdate(this._data, value);
    this._data = value;
    this.updateGroupVisibility();
  }
  get data() {
    return this._data;
  }
  onLegendDataChange({ legendData = [] }) {
    if (!this.enabled)
      return;
    this.data = legendData.filter((datum) => !datum.hideInLegend);
  }
  onLegendDataChangePartial(event) {
    this.itemSelection.each(({ proxyButton }, { itemId }) => {
      if (proxyButton == null)
        return;
      for (const eventElem of event.legendData) {
        if (eventElem.itemId === itemId) {
          proxyButton.setChecked(eventElem.enabled);
        }
      }
    });
  }
  destroy() {
    this.ctx.domManager.removeChild("canvas-overlay", `${this.id}-toolbar`);
    this.ctx.domManager.removeChild("canvas-overlay", `${this.id}-pagination`);
    this.cleanup.flush();
    this.itemSelection.clear();
  }
  getOrientation() {
    return this.orientation ?? "horizontal";
  }
  set visible(value) {
    this._visible = value;
    this.updateGroupVisibility();
  }
  get visible() {
    return this._visible;
  }
  updateGroupVisibility() {
    this.group.visible = this.enabled && this.visible && this.data.length > 0;
  }
  updateItemSelection() {
    const data = [...this.data];
    if (this.reverseOrder) {
      data.reverse();
    }
    this.itemSelection.update(data);
  }
  isInteractive() {
    const {
      toggleSeries,
      listeners: { legendItemClick, legendItemDoubleClick }
    } = this;
    return toggleSeries || legendItemDoubleClick != null || legendItemClick != null;
  }
  checkInteractionState() {
    return this.ctx.interactionManager.isState(1 /* Frozen */);
  }
  attachLegend(scene) {
    scene.appendChild(this.group);
  }
  getItemLabel(datum) {
    const { formatter: formatter2 } = this.item.label;
    if (formatter2) {
      const seriesDatum = datum.datum;
      return this.cachedCallWithContext(formatter2, {
        itemId: datum.itemId,
        value: datum.label.text,
        seriesId: datum.seriesId,
        ...seriesDatum && { datum: seriesDatum }
      });
    }
    return datum.label.text;
  }
  /**
   * The method is given the desired size of the legend, which only serves as a hint.
   * The vertically oriented legend will take as much horizontal space as needed, but will
   * respect the height constraints, and the horizontal legend will take as much vertical
   * space as needed in an attempt not to exceed the given width.
   * After the layout is done, the {@link size} will contain the actual size of the legend.
   * If the actual size is not the same as the previous actual size, the legend will fire
   * the 'layoutChange' event to communicate that another layout is needed, and the above
   * process should be repeated.
   * @param width
   * @param height
   */
  calcLayout(width2, height2) {
    const {
      paddingX,
      paddingY,
      label,
      maxWidth,
      label: { maxLength = Infinity, fontStyle, fontWeight: fontWeight2, fontSize, fontFamily }
    } = this.item;
    this.updateItemSelection();
    const bboxes = [];
    const measurer3 = cachedTextMeasurer(label);
    const itemMaxWidthPercentage = 0.8;
    const maxItemWidth = maxWidth ?? width2 * itemMaxWidthPercentage;
    const { markerWidth, anyLineEnabled } = this.calculateMarkerWidth();
    this.itemSelection.each((markerLabel, datum) => {
      markerLabel.fontStyle = fontStyle;
      markerLabel.fontWeight = fontWeight2;
      markerLabel.fontSize = fontSize;
      markerLabel.fontFamily = fontFamily;
      const paddedSymbolWidth = this.updateMarkerLabel(markerLabel, datum, markerWidth, anyLineEnabled);
      const id = datum.itemId ?? datum.id;
      const labelText = this.getItemLabel(datum);
      const text2 = toPlainText(labelText, "<unknown>").replace(LineSplitter, " ");
      markerLabel.text = this.truncate(text2, maxLength, maxItemWidth, paddedSymbolWidth, measurer3, id);
      bboxes.push(markerLabel.getTextMeasureBBox());
    });
    width2 = Math.max(1, width2);
    height2 = Math.max(1, height2);
    if (!Number.isFinite(width2)) {
      return {};
    }
    [width2, height2] = this.updateContainer(width2, height2);
    const size = this.size;
    const oldSize = this.oldSize;
    size[0] = width2;
    size[1] = height2;
    if (size[0] !== oldSize[0] || size[1] !== oldSize[1]) {
      oldSize[0] = size[0];
      oldSize[1] = size[1];
    }
    const { pages, maxPageHeight, maxPageWidth } = this.updatePagination(bboxes, width2, height2);
    const oldPages = this.pages;
    this.pages = pages;
    this.maxPageSize = [maxPageWidth - paddingX, maxPageHeight - paddingY];
    const pageNumber = this.pagination.currentPage;
    const page = this.pages[pageNumber];
    if (this.pages.length < 1 || !page) {
      this.visible = false;
      return { oldPages };
    }
    this.visible = true;
    this.updatePositions(pageNumber);
    this.update();
    return { oldPages };
  }
  isCustomMarker(markerEnabled3, shape) {
    return markerEnabled3 && shape !== void 0 && typeof shape !== "string";
  }
  calcSymbolsEnabled(symbol) {
    const { showSeriesStroke, marker } = this.item;
    const markerEnabled3 = !!marker.enabled || !showSeriesStroke || (symbol.marker.enabled ?? true);
    const lineEnabled = !!(symbol.line && showSeriesStroke);
    const isCustomMarker = this.isCustomMarker(markerEnabled3, symbol.marker.shape);
    return { markerEnabled: markerEnabled3, lineEnabled, isCustomMarker };
  }
  calcSymbolsLengths(symbol, markerEnabled3, lineEnabled) {
    const { marker, line } = this.item;
    let customMarkerSize;
    const { shape } = symbol.marker;
    if (this.isCustomMarker(markerEnabled3, shape)) {
      const tmpShape = new Marker();
      tmpShape.shape = shape;
      tmpShape.updatePath();
      const bbox = tmpShape.getBBox();
      customMarkerSize = Math.max(bbox.width, bbox.height);
    }
    const markerLength = markerEnabled3 ? marker.size : 0;
    const lineLength = lineEnabled ? line.length ?? 25 : 0;
    return { markerLength, lineLength, customMarkerSize };
  }
  calculateMarkerWidth() {
    let markerWidth = 0;
    let anyLineEnabled = false;
    this.itemSelection.each((_, datum) => {
      const { symbol } = datum;
      const { lineEnabled, markerEnabled: markerEnabled3 } = this.calcSymbolsEnabled(symbol);
      const {
        markerLength,
        lineLength,
        customMarkerSize = -Infinity
      } = this.calcSymbolsLengths(symbol, markerEnabled3, lineEnabled);
      markerWidth = Math.max(markerWidth, lineLength, customMarkerSize, markerLength);
      anyLineEnabled || (anyLineEnabled = lineEnabled);
    });
    return { markerWidth, anyLineEnabled };
  }
  updateMarkerLabel(markerLabel, datum, markerWidth, anyLineEnabled) {
    const { marker: itemMarker, paddingX } = this.item;
    const { symbol } = datum;
    let paddedSymbolWidth = paddingX;
    const { markerEnabled: markerEnabled3, isCustomMarker } = this.calcSymbolsEnabled(symbol);
    const spacing = itemMarker.padding;
    if (markerEnabled3 || anyLineEnabled) {
      paddedSymbolWidth += spacing + markerWidth;
    }
    const { marker, line } = markerLabel;
    marker.visible = markerEnabled3;
    if (marker.visible) {
      marker.shape = itemMarker.shape ?? symbol.marker.shape ?? "square";
      marker.size = itemMarker.size;
      marker.setStyleProperties(this.getMarkerStyles(deepClone(symbol)));
    }
    line.visible = anyLineEnabled;
    if (line.visible) {
      line.setStyleProperties(this.getLineStyles(symbol));
    }
    markerLabel.length = markerWidth;
    markerLabel.spacing = spacing;
    markerLabel.isCustomMarker = isCustomMarker;
    return paddedSymbolWidth;
  }
  updateContainer(width2, height2) {
    const containerStyles = this.getContainerStyles();
    this.containerNode.width = 0;
    this.containerNode.height = 0;
    this.containerNode.setStyleProperties(containerStyles);
    this.containerNode.cornerRadius = containerStyles.cornerRadius;
    width2 -= containerStyles.strokeWidth * 2 + containerStyles.padding.left + containerStyles.padding.right;
    height2 -= containerStyles.strokeWidth * 2 + containerStyles.padding.top + containerStyles.padding.bottom;
    return [width2, height2];
  }
  truncate(text2, maxCharLength, maxItemWidth, paddedMarkerWidth, measurer3, id) {
    let addEllipsis = false;
    if (text2.length > maxCharLength) {
      text2 = text2.substring(0, maxCharLength);
      addEllipsis = true;
    }
    const result = truncateLine(text2, measurer3, maxItemWidth - paddedMarkerWidth, addEllipsis);
    if (isTextTruncated(result)) {
      this.truncatedItems.add(id);
    } else {
      this.truncatedItems.delete(id);
    }
    return result;
  }
  updatePagination(bboxes, width2, height2) {
    const orientation = this.getOrientation();
    const trackingIndex = Math.min(this.paginationTrackingIndex, bboxes.length);
    this.pagination.orientation = orientation;
    this.pagination.translationX = 0;
    this.pagination.translationY = 0;
    const { pages, maxPageHeight, maxPageWidth, paginationBBox, paginationVertical } = this.calculatePagination(
      bboxes,
      width2,
      height2
    );
    const newCurrentPage = pages.findIndex((p) => p.endIndex >= trackingIndex);
    this.pagination.currentPage = clamp(0, newCurrentPage, pages.length - 1);
    const { paddingX: itemPaddingX, paddingY: itemPaddingY } = this.item;
    const paginationComponentPadding = 8;
    const legendItemsWidth = maxPageWidth - itemPaddingX;
    const legendItemsHeight = maxPageHeight - itemPaddingY;
    let paginationX = 0;
    let paginationY = -paginationBBox.y - this.item.marker.size / 2;
    if (paginationVertical) {
      paginationY += legendItemsHeight + paginationComponentPadding;
    } else {
      paginationX += -paginationBBox.x + legendItemsWidth + paginationComponentPadding;
      paginationY += (legendItemsHeight - paginationBBox.height) / 2;
    }
    this.pagination.translationX = paginationX;
    this.pagination.translationY = paginationY;
    this.pagination.update();
    this.pagination.updateMarkers();
    let pageIndex = 0;
    this.itemSelection.each((markerLabel, _, nodeIndex) => {
      if (nodeIndex > (pages[pageIndex]?.endIndex ?? Infinity)) {
        pageIndex++;
      }
      markerLabel.pageIndex = pageIndex;
    });
    return {
      maxPageHeight,
      maxPageWidth,
      pages
    };
  }
  calculatePagination(bboxes, width2, height2) {
    const { paddingX: itemPaddingX, paddingY: itemPaddingY } = this.item;
    const vertPositions = [
      "left",
      "left-top",
      "left-bottom",
      "right",
      "right-top",
      "right-bottom"
    ];
    const { placement } = expandLegendPosition(this.position);
    const orientation = this.getOrientation();
    const paginationVertical = vertPositions.includes(placement);
    let paginationBBox = this.pagination.getBBox();
    let lastPassPaginationBBox = new BBox(0, 0, 0, 0);
    let pages = [];
    let maxPageWidth = 0;
    let maxPageHeight = 0;
    let count = 0;
    const stableOutput = (bbox) => {
      return bbox.width === paginationBBox.width && bbox.height === paginationBBox.height;
    };
    const forceResult = this.maxWidth !== void 0 && this.maxHeight !== void 0;
    do {
      if (count++ > 10) {
        logger_exports.warn("unable to find stable legend layout.");
        break;
      }
      paginationBBox = lastPassPaginationBBox;
      const maxWidth = width2 - (paginationVertical ? 0 : paginationBBox.width);
      const maxHeight = height2 - (paginationVertical ? paginationBBox.height : 0);
      const layout = gridLayout({
        orientation,
        bboxes,
        maxHeight,
        maxWidth,
        itemPaddingY,
        itemPaddingX,
        forceResult
      });
      pages = layout?.pages ?? [];
      maxPageWidth = layout?.maxPageWidth ?? 0;
      maxPageHeight = layout?.maxPageHeight ?? 0;
      const totalPages = pages.length;
      this.pagination.visible = totalPages > 1;
      this.pagination.totalPages = totalPages;
      this.pagination.update();
      this.pagination.updateMarkers();
      lastPassPaginationBBox = this.pagination.getBBox();
      if (!this.pagination.visible) {
        break;
      }
    } while (!stableOutput(lastPassPaginationBBox));
    return { maxPageWidth, maxPageHeight, pages, paginationBBox: lastPassPaginationBBox, paginationVertical };
  }
  updatePositions(pageNumber = 0) {
    const {
      item: { paddingY },
      itemSelection,
      pages
    } = this;
    if (pages.length < 1 || !pages[pageNumber]) {
      return;
    }
    const { columns, startIndex: visibleStart, endIndex: visibleEnd } = pages[pageNumber];
    let x = 0;
    let y = 0;
    const columnCount = columns.length;
    const rowCount = columns[0].indices.length;
    const horizontal = this.getOrientation() === "horizontal";
    const itemHeight = columns[0].bboxes[0].height + paddingY;
    const rowSumColumnWidths = [];
    itemSelection.each((markerLabel, _, i) => {
      if (i < visibleStart || i > visibleEnd) {
        markerLabel.visible = false;
        return;
      }
      const pageIndex = i - visibleStart;
      let columnIndex;
      let rowIndex;
      if (horizontal) {
        columnIndex = pageIndex % columnCount;
        rowIndex = Math.floor(pageIndex / columnCount);
      } else {
        columnIndex = Math.floor(pageIndex / rowCount);
        rowIndex = pageIndex % rowCount;
      }
      markerLabel.visible = true;
      const column = columns[columnIndex];
      if (!column) {
        return;
      }
      y = Math.floor(itemHeight * rowIndex);
      x = Math.floor(rowSumColumnWidths[rowIndex] ?? 0);
      rowSumColumnWidths[rowIndex] = (rowSumColumnWidths[rowIndex] ?? 0) + column.columnWidth;
      markerLabel.translationX = x;
      markerLabel.translationY = y;
    });
  }
  updatePageNumber(pageNumber) {
    const { itemSelection, group, pagination, pages } = this;
    const { startIndex, endIndex } = pages[pageNumber];
    if (startIndex === 0) {
      this.paginationTrackingIndex = 0;
    } else if (pageNumber === pages.length - 1) {
      this.paginationTrackingIndex = endIndex;
    } else {
      this.paginationTrackingIndex = Math.floor((startIndex + endIndex) / 2);
    }
    this.pagination.update();
    this.pagination.updateMarkers();
    this.updatePositions(pageNumber);
    this.domProxy.onPageChange({ itemSelection, group, pagination, interactive: this.isInteractive() });
    this.ctx.updateService.update(9 /* SCENE_RENDER */);
  }
  update() {
    const {
      label: { color: color2 }
    } = this.item;
    this.itemSelection.each((markerLabel, datum) => {
      markerLabel.setEnabled(datum.enabled);
      markerLabel.color = color2;
    });
    this.updateContextMenu();
  }
  updateContextMenu() {
    const action = this.toggleSeries ? "show" : "hide";
    this.ctx.contextMenuRegistry.toggle("toggle-series-visibility", action);
    this.ctx.contextMenuRegistry.toggle("toggle-other-series", action);
  }
  getLineStyles(datum) {
    const { stroke: stroke3, strokeOpacity = 1, strokeWidth, lineDash } = datum.line ?? {};
    const defaultLineStrokeWidth = Math.min(2, strokeWidth ?? 1);
    return {
      stroke: stroke3,
      strokeOpacity,
      strokeWidth: this.item.line.strokeWidth ?? defaultLineStrokeWidth,
      lineDash
    };
  }
  getMarkerStyles({ marker }) {
    const { fill, stroke: stroke3, strokeOpacity = 1, fillOpacity = 1, strokeWidth, lineDash, lineDashOffset } = marker;
    const defaultLineStrokeWidth = Math.min(2, strokeWidth ?? 1);
    if (isPatternFill(fill)) {
      fill.width = 8;
      fill.height = 8;
      fill.padding = 1;
      fill.strokeWidth = Math.min(2, fill.strokeWidth ?? 2);
    }
    if (isImageFill(fill)) {
      fill.fit = "contain";
      fill.width = void 0;
      fill.height = void 0;
      fill.repeat = "no-repeat";
    }
    return getShapeStyle(
      {
        fill,
        stroke: stroke3,
        strokeOpacity,
        fillOpacity,
        strokeWidth: this.item.marker.strokeWidth ?? defaultLineStrokeWidth,
        lineDash,
        lineDashOffset
      },
      fillGradientDefaults2,
      fillPatternDefaults2,
      fillImageDefaults2
    );
  }
  getContainerStyles() {
    const { stroke: stroke3, strokeOpacity, strokeWidth } = this.border;
    const { cornerRadius, fill, fillOpacity, padding: padding2 } = this;
    const isPaddingNumber = typeof padding2 === "number";
    return getShapeStyle(
      {
        cornerRadius,
        fill,
        fillOpacity,
        padding: {
          top: isPaddingNumber ? padding2 : padding2.top ?? 0,
          right: isPaddingNumber ? padding2 : padding2.right ?? 0,
          bottom: isPaddingNumber ? padding2 : padding2.bottom ?? 0,
          left: isPaddingNumber ? padding2 : padding2.left ?? 0
        },
        stroke: stroke3,
        strokeOpacity,
        strokeWidth: this.border.enabled ? strokeWidth : 0
      },
      fillGradientDefaults2,
      fillPatternDefaults2,
      fillImageDefaults2
    );
  }
  computePagedBBox() {
    const actualBBox = Group.computeChildrenBBox(this.group.excludeChildren({ name: "legend-container" }));
    if (this.pages.length > 1) {
      const [maxPageWidth, maxPageHeight] = this.maxPageSize;
      actualBBox.height = Math.max(maxPageHeight, actualBBox.height);
      actualBBox.width = Math.max(maxPageWidth, actualBBox.width);
    }
    const { strokeWidth, padding: padding2 } = this.getContainerStyles();
    actualBBox.grow(padding2).grow(strokeWidth);
    return actualBBox;
  }
  findNode(params) {
    const { datum, proxyButton } = this.itemSelection.select((ml) => ml.datum?.itemId === params.itemId)[0] ?? {};
    if (datum === void 0 || proxyButton === void 0) {
      throw new Error(
        `AG Charts - Missing required properties { datum: ${datum}, proxyButton: ${JSON.stringify(proxyButton)} }`
      );
    }
    return { datum, proxyButton };
  }
  contextToggleVisibility(params) {
    const { datum, proxyButton } = this.findNode(params);
    this.doClick(params.event, datum, proxyButton);
    this.clearHighlight();
  }
  contextToggleOtherSeries(params) {
    this.doDoubleClick(params.event, this.findNode(params).datum);
    this.clearHighlight();
  }
  onContextClick(widgetEvent, node) {
    if (this.checkInteractionState())
      return;
    const { sourceEvent } = widgetEvent;
    const legendItem = node.datum;
    this.clearHighlight();
    if (this.preventHidingAll && this.contextMenuDatum?.enabled && this.getVisibleItemCount() <= 1) {
      this.ctx.contextMenuRegistry.builtins.items["toggle-series-visibility"].enabled = false;
    } else {
      this.ctx.contextMenuRegistry.builtins.items["toggle-series-visibility"].enabled = true;
    }
    const toggleOtherSeriesVisible = this.ctx.chartService.series.length > 1 && this.ctx.chartService.series[0]?.getLegendData("category")[0]?.hideToggleOtherSeries !== true;
    const action = toggleOtherSeriesVisible ? "show" : "hide";
    this.ctx.contextMenuRegistry.toggle("toggle-other-series", action);
    const { offsetX, offsetY } = sourceEvent;
    const { x: canvasX, y: canvasY } = Transformable.toCanvasPoint(node, offsetX, offsetY);
    this.ctx.contextMenuRegistry.dispatchContext("legend-item", { widgetEvent, canvasX, canvasY }, { legendItem });
  }
  onClick(event, datum, proxyButton) {
    if (this.checkInteractionState())
      return;
    if (this.doClick(event, datum, proxyButton)) {
      event.preventDefault();
    }
  }
  getVisibleItemCount() {
    return this.ctx.chartService.series.flatMap((s) => s.getLegendData("category")).filter((d) => d.enabled).length;
  }
  doClick(event, datum, proxyButton) {
    const {
      listeners: { legendItemClick },
      ctx: { chartService },
      preventHidingAll,
      toggleSeries
    } = this;
    if (!datum) {
      return false;
    }
    const { legendType, seriesId, itemId, enabled, legendItemName } = datum;
    const series = chartService.series.find((s) => s.id === seriesId);
    if (!series) {
      return false;
    }
    let newEnabled = enabled;
    const clickEvent = makeLegendItemEvent("click", datum, event);
    if (legendItemClick) {
      callWithContext([series.properties, this.ctx.chartService], legendItemClick, clickEvent.apiEvent);
    }
    if (clickEvent.defaultPrevented)
      return true;
    if (toggleSeries) {
      newEnabled = !enabled;
      if (preventHidingAll && !newEnabled) {
        const numVisibleItems = this.getVisibleItemCount();
        if (numVisibleItems < 2) {
          newEnabled = true;
        }
      }
      proxyButton.setChecked(newEnabled);
      this.ctx.eventsHub.emit("legend:item-click", {
        legendType,
        series,
        itemId,
        enabled: newEnabled,
        legendItemName
      });
    }
    this.updateHighlight(newEnabled, datum, series);
    this.ctx.legendManager.update();
    this.ctx.updateService.update(2 /* PROCESS_DATA */, {
      forceNodeDataRefresh: true,
      skipAnimations: datum.skipAnimations ?? false
    });
    return true;
  }
  onDoubleClick(event, datum) {
    if (this.checkInteractionState())
      return;
    if (this.doDoubleClick(event, datum)) {
      event.preventDefault();
    }
  }
  doDoubleClick(event, datum) {
    const {
      listeners: { legendItemDoubleClick },
      ctx: { chartService },
      toggleSeries
    } = this;
    if (!datum) {
      return false;
    }
    const { legendType, id, itemId, seriesId } = datum;
    const series = chartService.series.find((s) => s.id === id);
    if (!series) {
      return false;
    }
    const doubleClickEvent = makeLegendItemEvent("dblclick", datum, event);
    if (legendItemDoubleClick) {
      callWithContext(
        [series.properties, this.ctx.chartService],
        legendItemDoubleClick,
        doubleClickEvent.apiEvent
      );
    }
    if (doubleClickEvent.defaultPrevented)
      return true;
    if (toggleSeries) {
      const legendData = chartService.series.flatMap((s) => s.getLegendData("category"));
      let numVisibleItems = 0;
      const visibleLegendItemNames = /* @__PURE__ */ new Set();
      for (const d of legendData) {
        if (!d.enabled)
          continue;
        numVisibleItems += 1;
        if (d.legendItemName != null) {
          visibleLegendItemNames.add(d.legendItemName);
        }
      }
      if (visibleLegendItemNames.size > 0) {
        numVisibleItems = visibleLegendItemNames.size;
      }
      const clickedItem = legendData.find((d) => d.itemId === itemId && d.seriesId === seriesId);
      this.ctx.eventsHub.emit("legend:item-double-click", {
        legendType,
        series,
        itemId,
        numVisibleItems,
        enabled: clickedItem?.enabled ?? false,
        legendItemName: clickedItem?.legendItemName
      });
    }
    this.ctx.legendManager.update();
    this.ctx.updateService.update(2 /* PROCESS_DATA */, { forceNodeDataRefresh: true });
    return true;
  }
  toTooltipMeta(event, node) {
    let point;
    if (event instanceof FocusEvent) {
      point = Transformable.toCanvas(node).computeCenter();
    } else {
      event.preventDefault();
      point = Transformable.toCanvasPoint(node, event.offsetX, event.offsetY);
    }
    return { canvasX: point.x, canvasY: point.y, showArrow: false };
  }
  onHover(event, node) {
    if (this.checkInteractionState())
      return;
    if (!this.enabled)
      throw new Error("AG Charts - onHover handler called on disabled legend");
    this.pagination.setPage(node.pageIndex);
    const datum = node.datum;
    const series = datum ? this.ctx.chartService.series.find((s) => s.id === datum?.id) : void 0;
    if (datum && this.truncatedItems.has(datum.itemId ?? datum.id)) {
      const meta = this.toTooltipMeta(event, node);
      this.ctx.tooltipManager.updateTooltip(this.id, meta, [
        { type: "structured", title: this.getItemLabel(datum) }
      ]);
    } else {
      this.ctx.tooltipManager.removeTooltip(this.id, void 0, true);
    }
    this.updateHighlight(datum?.enabled, datum, series);
  }
  onLeave() {
    if (this.checkInteractionState())
      return;
    this.ctx.tooltipManager.removeTooltip(this.id, void 0, true);
    this.clearHighlight();
  }
  clearHighlight() {
    this.updateHighlight(void 0, void 0, void 0);
  }
  updateHighlight(enabled, legendDatum, series, event) {
    const updateManagers = (opts) => {
      if (opts === void 0) {
        this.ctx.activeManager.clear();
      } else {
        const seriesId = opts.nodeDatum.series.id;
        const itemId = opts.itemId;
        this.ctx.activeManager.update({ type: "legend", seriesId, itemId }, void 0);
      }
      this.ctx.highlightManager.updateHighlight(this.id, opts?.nodeDatum);
    };
    const highlightNodeDatum = (opts) => {
      if (this.ctx.interactionManager.isState(64 /* Default */) || event?.initialState) {
        updateManagers(opts);
      } else if (this.ctx.interactionManager.isState(4 /* Animation */)) {
        this.ctx.animationManager.onBatchStop(() => {
          updateManagers(opts);
        });
      } else if (opts === void 0) {
        updateManagers(opts);
      }
    };
    if (enabled === true && series !== void 0 && legendDatum !== void 0) {
      const itemId = legendDatum.itemId;
      const nodeDatum = toHighlightNodeDatum(series, legendDatum);
      highlightNodeDatum({ itemId, nodeDatum });
    } else {
      highlightNodeDatum(void 0);
    }
  }
  onActiveUpdate(activeItem) {
    if (activeItem?.type === "series-node") {
      this.ctx.highlightManager.updateHighlight(this.id, void 0);
    }
  }
  onActiveLoadMemento(event) {
    const { activeItem } = event;
    if (activeItem?.type !== "legend") {
      return this.ctx.highlightManager.updateHighlight(this.id, void 0);
    }
    const datum = this.data.find((d) => d.seriesId === activeItem.seriesId && d.itemId === activeItem.itemId);
    const series = this.ctx.chartService.series.find((s) => s.id === activeItem.seriesId);
    if (series === void 0) {
      logger_exports.warn(`Cannot find seriesId: "${activeItem.seriesId}"`);
      event.reject();
    } else if (datum === void 0) {
      const json = JSON.stringify({ seriesId: activeItem.seriesId, itemId: activeItem.itemId });
      logger_exports.warn(`cannot find legend item: ${json}`);
      event.reject();
    } else {
      this.updateHighlight(datum.enabled, datum, series, event);
    }
  }
  onLocaleChanged() {
    this.updateItemSelection();
    this.domProxy.onLocaleChanged(this.ctx.localeManager, this.itemSelection, this);
  }
  positionLegend(ctx) {
    const oldPages = this.positionLegendScene(ctx);
    this.positionLegendDOM(oldPages);
  }
  positionLegendScene(ctx) {
    if (!this.enabled || !this.data.length)
      return;
    const { placement, floating, xOffset, yOffset } = expandLegendPosition(this.position);
    const layoutBox = floating ? new BBox(0, 0, ctx.width, ctx.height) : ctx.layoutBox;
    const { x, y, width: width2, height: height2 } = layoutBox;
    const [legendWidth, legendHeight] = this.calculateLegendDimensions(layoutBox);
    const { oldPages } = this.calcLayout(legendWidth, legendHeight);
    const legendBBox = this.computePagedBBox();
    if (this.visible) {
      let unreachable2 = function(_a) {
        return void 0;
      };
      var unreachable = unreachable2;
      const legendSpacing = this.spacing;
      let translationX;
      let translationY;
      switch (placement) {
        case "top":
          translationX = (width2 - legendBBox.width) / 2;
          translationY = 0;
          break;
        case "bottom":
          translationX = (width2 - legendBBox.width) / 2;
          translationY = height2 - legendBBox.height;
          break;
        case "right":
          translationX = width2 - legendBBox.width;
          translationY = (height2 - legendBBox.height) / 2;
          break;
        case "left":
          translationX = 0;
          translationY = (height2 - legendBBox.height) / 2;
          break;
        case "top-right":
        case "right-top":
          translationX = width2 - legendBBox.width;
          translationY = 0;
          break;
        case "top-left":
        case "left-top":
          translationX = 0;
          translationY = 0;
          break;
        case "bottom-right":
        case "right-bottom":
          translationX = width2 - legendBBox.width;
          translationY = height2 - legendBBox.height;
          break;
        case "bottom-left":
        case "left-bottom":
          translationX = 0;
          translationY = height2 - legendBBox.height;
          break;
        default:
          unreachable2(placement);
      }
      if (!floating) {
        let shrinkAmount;
        let shrinkDirection;
        switch (placement) {
          case "top":
          case "top-right":
          case "top-left":
            shrinkAmount = legendBBox.height + legendSpacing;
            shrinkDirection = "top";
            break;
          case "bottom":
          case "bottom-right":
          case "bottom-left":
            shrinkAmount = legendBBox.height + legendSpacing;
            shrinkDirection = "bottom";
            break;
          case "left":
          case "left-top":
          case "left-bottom":
            shrinkAmount = legendBBox.width + legendSpacing;
            shrinkDirection = "left";
            break;
          case "right":
          case "right-top":
          case "right-bottom":
            shrinkAmount = legendBBox.width + legendSpacing;
            shrinkDirection = "right";
            break;
          default:
            unreachable2(placement);
        }
        layoutBox.shrink(shrinkAmount, shrinkDirection);
      }
      translationX += xOffset;
      translationY += yOffset;
      this.group.translationX = Math.floor(x + translationX - legendBBox.x);
      this.group.translationY = Math.floor(y + translationY - legendBBox.y);
      this.containerNode.x = legendBBox.x;
      this.containerNode.y = legendBBox.y;
      this.containerNode.width = legendBBox.width;
      this.containerNode.height = legendBBox.height;
    }
    return oldPages;
  }
  positionLegendDOM(oldPages) {
    const { ctx, itemSelection, pagination, pages: newPages, group } = this;
    const visible = this.visible && this.enabled;
    const interactive = this.isInteractive();
    this.domProxy.update({
      visible,
      interactive,
      ctx,
      itemSelection,
      group,
      pagination,
      oldPages,
      newPages,
      datumReader: this,
      itemListener: this
    });
  }
  calculateLegendDimensions(shrinkRect) {
    const { width: width2, height: height2 } = shrinkRect;
    const { placement } = expandLegendPosition(this.position);
    const aspectRatio = width2 / height2;
    const maxCoefficient = 0.5;
    const minHeightCoefficient = 0.2;
    const minWidthCoefficient = 0.25;
    let legendWidth, legendHeight;
    function unreachable(_a) {
      return void 0;
    }
    switch (placement) {
      case "top":
      case "top-left":
      case "top-right":
      case "bottom":
      case "bottom-left":
      case "bottom-right": {
        const heightCoefficient = aspectRatio < 1 ? Math.min(maxCoefficient, minHeightCoefficient * (1 / aspectRatio)) : minHeightCoefficient;
        legendWidth = this.maxWidth ? Math.min(this.maxWidth, width2) : width2;
        legendHeight = this.maxHeight ? Math.min(this.maxHeight, height2) : Math.round(height2 * heightCoefficient);
        break;
      }
      case "left":
      case "left-top":
      case "left-bottom":
      case "right":
      case "right-top":
      case "right-bottom": {
        const widthCoefficient = aspectRatio > 1 ? Math.min(maxCoefficient, minWidthCoefficient * aspectRatio) : minWidthCoefficient;
        legendWidth = this.maxWidth ? Math.min(this.maxWidth, width2) : Math.round(width2 * widthCoefficient);
        legendHeight = this.maxHeight ? Math.min(this.maxHeight, height2) : height2;
        break;
      }
      default:
        unreachable(placement);
    }
    return [legendWidth, legendHeight];
  }
  cachedCallWithContext(fn, params) {
    const { callbackCache, chartService } = this.ctx;
    return callbackCache.call([this, chartService], fn, params);
  }
};
Legend.className = "Legend";
__decorateClass([
  addFakeTransformToInstanceProperty
], Legend.prototype, "toggleSeries", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Legend.prototype, "pagination", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Legend.prototype, "item", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Legend.prototype, "listeners", 2);
__decorateClass([
  ObserveChanges((target, newValue, oldValue) => {
    target.updateGroupVisibility();
    if (newValue === oldValue) {
      return;
    }
    const {
      ctx: { legendManager, stateManager }
    } = target;
    if (oldValue === false && newValue === true) {
      stateManager.restoreState(legendManager);
    }
  }),
  addFakeTransformToInstanceProperty
], Legend.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Legend.prototype, "position", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Legend.prototype, "maxWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Legend.prototype, "maxHeight", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Legend.prototype, "reverseOrder", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Legend.prototype, "orientation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Legend.prototype, "preventHidingAll", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Legend.prototype, "border", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Legend.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Legend.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Legend.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Legend.prototype, "padding", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Legend.prototype, "spacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Legend.prototype, "xOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Legend.prototype, "yOffset", 2);

// packages/ag-charts-community/src/chart/legend/legendModule.ts
var LegendModule = {
  type: "plugin",
  name: "legend",
  version: VERSION,
  // TODO fix missing behaviour
  // removable: 'standalone-only',
  options: {
    enabled: boolean,
    position: legendPositionValidator,
    orientation: union("horizontal", "vertical"),
    maxWidth: positiveNumber,
    maxHeight: positiveNumber,
    spacing: positiveNumber,
    border: borderOptionsDef,
    cornerRadius: number,
    padding,
    fill: colorUnion,
    fillOpacity: ratio,
    preventHidingAll: boolean,
    reverseOrder: boolean,
    toggleSeries: boolean,
    item: {
      marker: {
        size: positiveNumber,
        shape: shapeValidator,
        padding: positiveNumber,
        strokeWidth: positiveNumber
      },
      line: {
        length: positiveNumber,
        strokeWidth: positiveNumber
      },
      label: {
        maxLength: positiveNumber,
        formatter: callback,
        ...fontOptionsDef
      },
      maxWidth: positiveNumber,
      paddingX: positiveNumber,
      paddingY: positiveNumber,
      showSeriesStroke: boolean
    },
    pagination: {
      marker: {
        size: positiveNumber,
        shape: shapeValidator,
        padding: positiveNumber
      },
      activeStyle: {
        ...fillOptionsDef,
        ...strokeOptionsDef
      },
      inactiveStyle: {
        ...fillOptionsDef,
        ...strokeOptionsDef
      },
      highlightStyle: {
        ...fillOptionsDef,
        ...strokeOptionsDef
      },
      label: fontOptionsDef
    },
    listeners: {
      legendItemClick: callback,
      legendItemDoubleClick: callback
    }
  },
  themeTemplate: {
    ...LEGEND_CONTAINER_THEME,
    enabled: {
      $and: [
        { $greaterThan: [{ $size: { $path: "/series" } }, 1] },
        {
          $or: [
            { $isChartType: "cartesian" },
            { $isChartType: "standalone" },
            {
              $and: [
                { $isChartType: "polar" },
                { $not: { $isSeriesType: "pie" } },
                { $not: { $isSeriesType: "donut" } }
              ]
            }
          ]
        }
      ]
    },
    position: "bottom" /* BOTTOM */,
    orientation: {
      $if: [
        {
          $or: [
            { $eq: [{ $path: "./position" }, "left" /* LEFT */] },
            { $eq: [{ $path: "./position" }, "left-top" /* LEFT_TOP */] },
            { $eq: [{ $path: "./position" }, "left-bottom" /* LEFT_BOTTOM */] },
            { $eq: [{ $path: "./position" }, "right" /* RIGHT */] },
            { $eq: [{ $path: "./position" }, "right-top" /* RIGHT_TOP */] },
            { $eq: [{ $path: "./position" }, "right-bottom" /* RIGHT_BOTTOM */] },
            { $eq: [{ $path: "./position/placement" }, "left" /* LEFT */] },
            { $eq: [{ $path: "./position/placement" }, "left-top" /* LEFT_TOP */] },
            { $eq: [{ $path: "./position/placement" }, "left-bottom" /* LEFT_BOTTOM */] },
            { $eq: [{ $path: "./position/placement" }, "right" /* RIGHT */] },
            { $eq: [{ $path: "./position/placement" }, "right-top" /* RIGHT_TOP */] },
            { $eq: [{ $path: "./position/placement" }, "right-bottom" /* RIGHT_BOTTOM */] }
          ]
        },
        "vertical",
        "horizontal"
      ]
    },
    spacing: 30,
    listeners: {},
    toggleSeries: true,
    item: {
      paddingX: 16,
      paddingY: 8,
      marker: { size: 15, padding: 8 },
      showSeriesStroke: true,
      label: {
        color: { $ref: "textColor" },
        fontSize: { $rem: FONT_SIZE_RATIO.SMALL },
        fontFamily: { $ref: "fontFamily" },
        fontWeight: { $ref: "fontWeight" }
      }
    },
    reverseOrder: false,
    pagination: {
      marker: { size: 12 },
      activeStyle: { fill: { $ref: "foregroundColor" } },
      inactiveStyle: { fill: { $ref: "subtleTextColor" } },
      highlightStyle: { fill: { $ref: "foregroundColor" } },
      label: { color: { $ref: "textColor" } }
    },
    fill: {
      $if: [{ $path: ["./position/floating", false] }, { $ref: "chartBackgroundColor" }, "transparent"]
    }
  },
  create: (ctx) => {
    const moduleInstance = new Legend(ctx);
    moduleInstance.attachLegend(ctx.scene);
    return moduleInstance;
  }
};

// packages/ag-charts-community/src/chart/axis/logAxis.ts
var LogAxis = class extends NumberAxis {
  getVisibleDomain(domain) {
    const [d0, d1] = domain;
    const [r0, r1] = this.visibleRange;
    if (domain.length < 2) {
      return [d0, d1];
    }
    const min = Math.min(d0, d1);
    const max = Math.max(d0, d1);
    if (min >= 0) {
      const log0 = Math.log(d0);
      const log1 = Math.log(d1);
      const span = log1 - log0;
      return [Math.exp(log0 + r0 * span), Math.exp(log0 + r1 * span)];
    }
    if (max <= 0) {
      const log0 = -Math.log(-d0);
      const log1 = -Math.log(-d1);
      const span = log1 - log0;
      return [-Math.exp(-(log0 + r0 * span)), -Math.exp(-(log0 + r1 * span))];
    }
    return [Number.NaN, Number.NaN];
  }
  normaliseDataDomain(d) {
    const { min, max, preferredMin, preferredMax } = this;
    const { extent: extent2, clipped } = normalisedExtentWithMetadata(
      d.domain,
      min,
      max,
      preferredMin,
      preferredMax,
      void 0,
      d.sortMetadata?.sortOrder
    );
    if (extent2[0] < 0 && extent2[1] > 0 || d.domain[0] < 0 && d.domain[1] > 0) {
      logger_exports.warn(
        `The log axis domain crosses zero, the chart data cannot be rendered. See log axis documentation for more information.`
      );
      return { domain: [], clipped };
    } else if (extent2[0] === 0 || extent2[1] === 0 || d.domain[0] === 0 || d.domain[1] === 0) {
      logger_exports.warn(
        `The log axis domain contains a value of 0, the chart data cannot be rendered. See log axis documentation for more information.`
      );
      return { domain: [], clipped };
    }
    return { domain: extent2, clipped };
  }
  set base(value) {
    this.scale.base = value;
  }
  get base() {
    return this.scale.base;
  }
  constructor(moduleCtx) {
    super(moduleCtx, new LogScale());
  }
};
LogAxis.className = "LogAxis";
LogAxis.type = "log";

// packages/ag-charts-community/src/chart/series/cartesian/areaAggregation.ts
var MAX_POINTS = 10;
function aggregationIndexType(xValues, d0, d1, indexData, maxRange, datumIndex, xNeedsValueOf) {
  const xValue = xValues[datumIndex];
  if (xValue === void 0)
    return -1;
  const xRatio = Number.isFinite(d0) ? aggregationXRatioForXValue(xValue, d0, d1, xNeedsValueOf) : aggregationXRatioForDatumIndex(datumIndex, xValues.length);
  const aggIndex = aggregationIndexForXRatio(xRatio, maxRange);
  if (datumIndex === indexData[aggIndex + AGGREGATION_INDEX_X_MIN] || datumIndex === indexData[aggIndex + AGGREGATION_INDEX_X_MAX] || datumIndex === indexData[aggIndex + AGGREGATION_INDEX_Y_MIN] || datumIndex === indexData[aggIndex + AGGREGATION_INDEX_Y_MAX]) {
    return aggIndex;
  }
  return -1;
}
function buildIndicesFromAggregation(xValues, d0, d1, indexData, maxRange, xNeedsValueOf, xValuesLength, reuseIndices, reuseMetaIndices) {
  let indicesCount = 0;
  let metaIndicesCount = 0;
  let currentGroup = -1;
  for (let datumIndex = 0; datumIndex < xValuesLength; datumIndex++) {
    const group = aggregationIndexType(xValues, d0, d1, indexData, maxRange, datumIndex, xNeedsValueOf);
    if (group === -1)
      continue;
    indicesCount++;
    if (group !== currentGroup) {
      metaIndicesCount++;
      currentGroup = group;
    }
  }
  metaIndicesCount++;
  const indices = reuseIndices?.length === indicesCount ? reuseIndices : new Uint32Array(indicesCount);
  const metaIndices = reuseMetaIndices?.length === metaIndicesCount ? reuseMetaIndices : new Uint32Array(metaIndicesCount);
  let indicesIdx = 0;
  let metaIndicesIdx = 0;
  currentGroup = -1;
  for (let datumIndex = 0; datumIndex < xValuesLength; datumIndex++) {
    const group = aggregationIndexType(xValues, d0, d1, indexData, maxRange, datumIndex, xNeedsValueOf);
    if (group === -1)
      continue;
    if (group !== currentGroup) {
      metaIndices[metaIndicesIdx++] = indicesIdx;
      currentGroup = group;
    }
    indices[indicesIdx++] = datumIndex;
  }
  metaIndices[metaIndicesIdx] = indicesCount - 1;
  return { indices, metaIndices };
}
function computeAreaAggregation(domain, xValues, yValues, options) {
  const xValuesLength = xValues.length;
  if (xValuesLength < AGGREGATION_THRESHOLD)
    return;
  const [d0, d1] = domain;
  const { xNeedsValueOf, yNeedsValueOf, existingFilters } = options;
  let maxRange = aggregationRangeFittingPoints(xValues, d0, d1, { xNeedsValueOf });
  const existingFilter = existingFilters?.find((f) => f.maxRange === maxRange);
  let { indexData, valueData } = createAggregationIndices(xValues, yValues, yValues, d0, d1, maxRange, {
    xNeedsValueOf,
    yNeedsValueOf,
    reuseIndexData: existingFilter?.indexData,
    reuseValueData: existingFilter?.valueData
  });
  let { indices, metaIndices } = buildIndicesFromAggregation(
    xValues,
    d0,
    d1,
    indexData,
    maxRange,
    xNeedsValueOf,
    xValuesLength,
    existingFilter?.indices,
    existingFilter?.metaIndices
  );
  const filters = [{ maxRange, metaIndices, indices, indexData, valueData }];
  while (indices.length > MAX_POINTS && maxRange > AGGREGATION_MIN_RANGE) {
    const currentMaxRange = maxRange;
    const nextMaxRange = Math.trunc(currentMaxRange / 2);
    const nextExistingFilter = existingFilters?.find((f) => f.maxRange === nextMaxRange);
    const compacted = compactAggregationIndices(indexData, valueData, currentMaxRange, {
      reuseIndexData: nextExistingFilter?.indexData,
      reuseValueData: nextExistingFilter?.valueData
    });
    maxRange = compacted.maxRange;
    indexData = compacted.indexData;
    valueData = compacted.valueData;
    const previousIndices = indices;
    let indicesCount = 0;
    let metaIndicesCount = 0;
    let currentGroup = -1;
    for (const datumIndex of previousIndices) {
      const group = aggregationIndexType(xValues, d0, d1, indexData, maxRange, datumIndex, xNeedsValueOf);
      if (group === -1)
        continue;
      indicesCount++;
      if (group !== currentGroup) {
        metaIndicesCount++;
        currentGroup = group;
      }
    }
    metaIndicesCount++;
    const newIndices = nextExistingFilter?.indices?.length === indicesCount ? nextExistingFilter.indices : new Uint32Array(indicesCount);
    const newMetaIndices = nextExistingFilter?.metaIndices?.length === metaIndicesCount ? nextExistingFilter.metaIndices : new Uint32Array(metaIndicesCount);
    let indicesIdx = 0;
    let metaIndicesIdx = 0;
    currentGroup = -1;
    for (const datumIndex of previousIndices) {
      const group = aggregationIndexType(xValues, d0, d1, indexData, maxRange, datumIndex, xNeedsValueOf);
      if (group === -1)
        continue;
      if (group !== currentGroup) {
        newMetaIndices[metaIndicesIdx++] = indicesIdx;
        currentGroup = group;
      }
      newIndices[indicesIdx++] = datumIndex;
    }
    newMetaIndices[metaIndicesIdx] = indicesCount - 1;
    indices = newIndices;
    metaIndices = newMetaIndices;
    filters.push({ maxRange, metaIndices, indices, indexData, valueData });
  }
  filters.reverse();
  return filters;
}
function computeAreaAggregationPartial(domain, xValues, yValues, options) {
  const xValuesLength = xValues.length;
  if (xValuesLength < AGGREGATION_THRESHOLD)
    return;
  const [d0, d1] = domain;
  const { xNeedsValueOf, yNeedsValueOf, targetRange, existingFilters } = options;
  const finestMaxRange = aggregationRangeFittingPoints(xValues, d0, d1, { xNeedsValueOf });
  const targetMaxRange = Math.min(finestMaxRange, nextPowerOf2(Math.max(targetRange, AGGREGATION_MIN_RANGE)));
  const existingFilter = existingFilters?.find((f) => f.maxRange === targetMaxRange);
  const { indexData, valueData } = createAggregationIndices(xValues, yValues, yValues, d0, d1, targetMaxRange, {
    xNeedsValueOf,
    yNeedsValueOf,
    reuseIndexData: existingFilter?.indexData,
    reuseValueData: existingFilter?.valueData
  });
  const { indices, metaIndices } = buildIndicesFromAggregation(
    xValues,
    d0,
    d1,
    indexData,
    targetMaxRange,
    xNeedsValueOf,
    xValuesLength,
    existingFilter?.indices,
    existingFilter?.metaIndices
  );
  const immediateLevel = {
    maxRange: targetMaxRange,
    indices,
    metaIndices,
    indexData,
    valueData
  };
  function computeRemaining() {
    const allLevels = computeAreaAggregation([d0, d1], xValues, yValues, {
      xNeedsValueOf,
      yNeedsValueOf,
      existingFilters
    });
    return allLevels?.filter((level) => level.maxRange !== targetMaxRange) ?? [];
  }
  return { immediate: [immediateLevel], computeRemaining };
}
function aggregateAreaData(scale2, xValues, yValues, domainInput, xNeedsValueOf, yNeedsValueOf) {
  const [d0, d1] = aggregationDomain(scale2, domainInput);
  return computeAreaAggregation([d0, d1], xValues, yValues, { xNeedsValueOf, yNeedsValueOf });
}
var memoizedAggregateAreaData = simpleMemorize2(aggregateAreaData);
function aggregateAreaDataFromDataModel(scale2, dataModel, processedData, yKey, series, existingFilters) {
  const xValues = dataModel.resolveKeysById(series, "xValue", processedData);
  const yValues = dataModel.resolveColumnById(series, yKey, processedData);
  const domainInput = dataModel.getDomain(series, "xValue", "key", processedData);
  const xNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "xValue", processedData);
  const yNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, yKey, processedData);
  if (existingFilters) {
    const [d0, d1] = aggregationDomain(scale2, domainInput);
    return computeAreaAggregation([d0, d1], xValues, yValues, {
      xNeedsValueOf,
      yNeedsValueOf,
      existingFilters
    });
  }
  return memoizedAggregateAreaData(scale2, xValues, yValues, domainInput, xNeedsValueOf, yNeedsValueOf);
}
function aggregateAreaDataFromDataModelPartial(scale2, dataModel, processedData, yKey, series, targetRange, existingFilters) {
  const xValues = dataModel.resolveKeysById(series, "xValue", processedData);
  const yValues = dataModel.resolveColumnById(series, yKey, processedData);
  const domainInput = dataModel.getDomain(series, "xValue", "key", processedData);
  const xNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "xValue", processedData);
  const yNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, yKey, processedData);
  const [d0, d1] = aggregationDomain(scale2, domainInput);
  return computeAreaAggregationPartial([d0, d1], xValues, yValues, {
    xNeedsValueOf,
    yNeedsValueOf,
    targetRange,
    existingFilters
  });
}

// packages/ag-charts-community/src/chart/series/cartesian/areaSeriesProperties.ts
var AreaSeriesProperties = class extends CartesianSeriesProperties {
  constructor() {
    super(...arguments);
    this.xName = void 0;
    this.fill = "#c16068";
    this.fillOpacity = 1;
    this.stroke = "#874349";
    this.strokeWidth = 2;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.interpolation = new InterpolationProperties();
    this.shadow = new DropShadow();
    this.marker = new SeriesMarker();
    this.label = new Label();
    this.tooltip = makeSeriesTooltip();
    this.connectMissingData = false;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "xKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "xName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "yKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "yName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "yFilterKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "stackGroup", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "normalizedTo", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "interpolation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "styler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "shadow", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "marker", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "tooltip", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AreaSeriesProperties.prototype, "connectMissingData", 2);

// packages/ag-charts-community/src/chart/series/cartesian/areaSeries.ts
var CROSS_FILTER_AREA_FILL_OPACITY_FACTOR = 0.125;
var CROSS_FILTER_AREA_STROKE_OPACITY_FACTOR = 0.25;
var AreaSeries = class extends CartesianSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      propertyKeys: DEFAULT_CARTESIAN_DIRECTION_KEYS,
      propertyNames: DEFAULT_CARTESIAN_DIRECTION_NAMES,
      categoryKey: "xValue",
      pathsPerSeries: ["fill", "stroke"],
      pathsZIndexSubOrderOffset: [0, 1e3],
      datumSelectionGarbageCollection: false,
      segmentedDataNodes: false,
      pickModes: [2 /* AXIS_ALIGNED */, 0 /* EXACT_SHAPE_MATCH */],
      animationResetFns: {
        path: buildResetPathFn({ getVisible: () => this.visible, getOpacity: () => this.getOpacity() }),
        label: resetLabelFn,
        datum: (node, datum) => ({ ...resetMarkerFn(node), ...resetMarkerPositionFn(node, datum) })
      },
      clipFocusBox: false
    });
    this.properties = new AreaSeriesProperties();
    this.connectsToYAxis = true;
    this.aggregationManager = new AggregationManager();
    this.backgroundGroup = new Group({
      name: `${this.id}-background`,
      zIndex: 0 /* BACKGROUND */
    });
    this._isStacked = void 0;
    this.fillSpans = [];
    this.phantomSpans = [];
    this.strokeSpans = [];
  }
  get pickModeAxis() {
    return "main";
  }
  renderToOffscreenCanvas() {
    const hasMarkers = (this.contextNodeData?.nodeData?.length ?? 0) > 0;
    return super.renderToOffscreenCanvas() || hasMarkers && this.getDrawingMode(false) === "cutout" || this.contextNodeData != null && (this.contextNodeData.fillData.spans.length > RENDER_TO_OFFSCREEN_CANVAS_THRESHOLD || this.contextNodeData.strokeData.spans.length > RENDER_TO_OFFSCREEN_CANVAS_THRESHOLD);
  }
  attachSeries(seriesContentNode, seriesNode, annotationNode) {
    super.attachSeries(seriesContentNode, seriesNode, annotationNode);
    seriesContentNode.appendChild(this.backgroundGroup);
  }
  detachSeries(seriesContentNode, seriesNode, annotationNode) {
    super.detachSeries(seriesContentNode, seriesNode, annotationNode);
    this.backgroundGroup.remove();
  }
  attachPaths([fill, stroke3]) {
    this.backgroundGroup.appendChild(fill);
    this.contentGroup.appendChild(stroke3);
    stroke3.zIndex = -1;
  }
  detachPaths([fill, stroke3]) {
    fill.remove();
    stroke3.remove();
  }
  isStacked() {
    const stackCount = this.seriesGrouping?.stackCount ?? 1;
    return stackCount > 1;
  }
  isNormalized() {
    return this.properties.normalizedTo != null;
  }
  setSeriesIndex(index) {
    const isStacked = this.isStacked();
    const isStackedChanged = isStacked === this._isStacked;
    this._isStacked = isStackedChanged;
    return super.setSeriesIndex(index, isStackedChanged);
  }
  setZIndex(zIndex) {
    super.setZIndex(zIndex);
    if (this.isStacked()) {
      this.backgroundGroup.zIndex = [0 /* BACKGROUND */, zIndex];
      this.contentGroup.zIndex = [1 /* ANY_CONTENT */, zIndex, 0 /* FOREGROUND */];
    } else {
      this.backgroundGroup.zIndex = [1 /* ANY_CONTENT */, zIndex, 0 /* FOREGROUND */, 0];
      this.contentGroup.zIndex = [1 /* ANY_CONTENT */, zIndex, 0 /* FOREGROUND */, 1];
    }
  }
  async processData(dataController) {
    if (this.data == null)
      return;
    const { data, visible, seriesGrouping: { groupIndex = this.id, stackCount = 1 } = {} } = this;
    const { xKey, yKey, yFilterKey, connectMissingData, normalizedTo } = this.properties;
    const animationEnabled = !this.ctx.animationManager.isSkipped();
    const xScale = this.axes["x" /* X */]?.scale;
    const yScale = this.axes["y" /* Y */]?.scale;
    const { xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale });
    const stacked = stackCount > 1 || normalizedTo != null;
    const idMap = {
      value: `area-stack-${groupIndex}-yValue`,
      marker: `area-stack-${groupIndex}-yValues-marker`
    };
    const common = { invalidValue: null };
    if ((isDefined(normalizedTo) || connectMissingData) && stackCount > 1) {
      common.invalidValue = 0;
    }
    if (!visible) {
      common.forceValue = 0;
    }
    const allowNullKey = this.properties.allowNullKeys ?? false;
    const props = [
      keyProperty(xKey, xScaleType, { id: "xValue", allowNullKey }),
      valueProperty(yKey, yScaleType, { id: `yValueRaw`, ...common }),
      ...yFilterKey == null ? [] : [valueProperty(yFilterKey, yScaleType, { id: "yFilterRaw" })]
    ];
    if (stacked) {
      props.push(
        ...groupAccumulativeValueProperty(
          yKey,
          "normal",
          { id: `yValueCumulative`, ...common, groupId: idMap.marker },
          yScaleType
        )
      );
    }
    if (isDefined(normalizedTo)) {
      props.push(
        valueProperty(yKey, yScaleType, { id: `yValue`, ...common, groupId: idMap.value }),
        normaliseGroupTo(Object.values(idMap), normalizedTo)
      );
    }
    if (animationEnabled) {
      props.push(animationValidation());
    }
    const { dataModel, processedData } = await this.requestDataModel(dataController, data, {
      props,
      groupByKeys: stacked,
      groupByData: !stacked
    });
    this.aggregateData(dataModel, processedData);
    this.animationState.transition("updateData");
  }
  xCoordinateRange(xValue, pixelSize) {
    const { marker } = this.properties;
    const x = this.axes["x" /* X */].scale.convert(xValue);
    const r = marker.enabled ? 0.5 * marker.size * pixelSize : 0;
    return [x - r, x + r];
  }
  yCoordinateRange(yValues, pixelSize) {
    const { marker } = this.properties;
    const y = this.axes["y" /* Y */].scale.convert(yValues[0]);
    const r = marker.enabled ? 0.5 * marker.size * pixelSize : 0;
    return [y - r, y + r];
  }
  yValueKey() {
    return this.isNormalized() ? "yValue" : "yValueRaw";
  }
  yCumulativeKey(processData) {
    return processData.type === "grouped" ? "yValueCumulative" : this.yValueKey();
  }
  getSeriesDomain(direction) {
    const { dataModel, processedData, axes } = this;
    if (!dataModel || !processedData)
      return { domain: [] };
    const yAxis = axes["y" /* Y */];
    if (direction === "x" /* X */) {
      const keyDef = dataModel.resolveProcessedDataDefById(this, `xValue`);
      const keys = dataModel.getDomain(this, `xValue`, "key", processedData);
      if (keyDef?.def.type === "key" && keyDef.def.valueType === "category") {
        return keys;
      }
      return { domain: fixNumericExtent(extent(keys.domain)) };
    }
    const yExtent = this.domainForClippedRange(
      "y" /* Y */,
      [this.yCumulativeKey(processedData)],
      "xValue"
    );
    if (yAxis instanceof NumberAxis && !(yAxis instanceof LogAxis)) {
      const fixedYExtent = Number.isFinite(yExtent[1] - yExtent[0]) ? [Math.min(yExtent[0], 0), Math.max(yExtent[1], 0)] : [];
      return { domain: fixNumericExtent(fixedYExtent) };
    } else {
      return { domain: fixNumericExtent(yExtent) };
    }
  }
  getSeriesRange(_direction, visibleRange) {
    const [y0, y1] = this.domainForVisibleRange(
      "y" /* Y */,
      [this.yCumulativeKey(this.processedData)],
      "xValue",
      visibleRange
    );
    return [Math.min(y0, 0), Math.max(y1, 0)];
  }
  getZoomRangeFittingItems(xVisibleRange, yVisibleRange, minVisibleItems) {
    return this.zoomFittingVisibleItems(
      "xValue",
      [this.yCumulativeKey(this.processedData)],
      xVisibleRange,
      yVisibleRange,
      minVisibleItems
    );
  }
  getVisibleItems(xVisibleRange, yVisibleRange, minVisibleItems) {
    return this.countVisibleItems(
      "xValue",
      [this.yCumulativeKey(this.processedData)],
      xVisibleRange,
      yVisibleRange,
      minVisibleItems
    );
  }
  aggregateData(dataModel, processedData) {
    this.aggregationManager.markStale(processedData.input.count);
    if (processedDataIsAnimatable(processedData))
      return;
    const xAxis = this.axes["x" /* X */];
    if (xAxis == null)
      return;
    const targetRange = this.estimateTargetRange();
    this.aggregationManager.aggregate({
      computePartial: (existingFilters) => aggregateAreaDataFromDataModelPartial(
        xAxis.scale.type,
        dataModel,
        processedData,
        this.yCumulativeKey(processedData),
        this,
        targetRange,
        existingFilters
      ),
      computeFull: (existingFilters) => aggregateAreaDataFromDataModel(
        xAxis.scale.type,
        dataModel,
        processedData,
        this.yCumulativeKey(processedData),
        this,
        existingFilters
      ),
      targetRange
    });
    const filters = this.aggregationManager.filters;
    if (filters && filters.length > 0) {
      debugMetrics_exports.record(
        `${this.type}:aggregation`,
        filters.map((f) => f.maxRange)
      );
    }
  }
  estimateTargetRange() {
    const xAxis = this.axes["x" /* X */];
    if (xAxis?.scale?.range) {
      const [r0, r1] = xAxis.scale.range;
      return Math.abs(r1 - r0);
    }
    return this.ctx.scene?.canvas?.width ?? 800;
  }
  stackAggregatedData(aggregation) {
    const { indices, metaIndices } = aggregation;
    const { visible, axes, dataModel, processedData, seriesBelowStackContext } = this;
    const xAxis = axes["x" /* X */];
    const yAxis = axes["y" /* Y */];
    if (!visible) {
      this.phantomSpans = [];
      this.fillSpans = [];
      this.strokeSpans = [];
      return seriesBelowStackContext;
    }
    if (xAxis == null || yAxis == null || dataModel == null || processedData == null)
      return;
    const { scale: xScale } = xAxis;
    const { scale: yScale } = yAxis;
    const xOffset = (xScale.bandwidth ?? 0) / 2;
    const connectMissingData = !this.isStacked() && this.properties.connectMissingData;
    const invalidData = processedData.invalidData?.get(this.id);
    const xValues = dataModel.resolveKeysById(this, "xValue", processedData);
    const yValues = dataModel.resolveColumnById(this, this.yCumulativeKey(processedData), processedData);
    let [m0, m1] = visibleRangeIndices(1, metaIndices.length - 1, xAxis.range, (metaIndex) => {
      const startIndex = metaIndices[metaIndex];
      const endIndex = metaIndices[metaIndex + 1];
      const startDatumIndex = indices[startIndex];
      const endDatumIndex = indices[endIndex];
      const xValue0 = xValues[startDatumIndex];
      const xValue1 = xValues[endDatumIndex];
      const { 0: x0 } = this.xCoordinateRange(xValue0, 0);
      const { 1: x1 } = this.xCoordinateRange(xValue1, 0);
      return [x0, x1];
    });
    m0 = Math.max(m0 - 1, 0);
    m1 = Math.min(m1 + 1, metaIndices.length - 1);
    let phantomSpans = [];
    if (seriesBelowStackContext?.fillSpans) {
      phantomSpans = seriesBelowStackContext?.fillSpans;
    } else {
      for (let metaIndex = m0; metaIndex < m1; metaIndex += 1) {
        const startIndex = metaIndices[metaIndex];
        const endIndex = metaIndices[metaIndex + 1];
        const startDatumIndex = indices[startIndex];
        const endDatumIndex = indices[endIndex];
        const xValue0 = xValues[startDatumIndex];
        const xValue1 = xValues[endDatumIndex];
        const span = {
          type: "linear",
          moveTo: false,
          x0: xScale.convert(xValue0) + xOffset,
          y0: yScale.convert(0),
          x1: xScale.convert(xValue1) + xOffset,
          y1: yScale.convert(0)
        };
        phantomSpans.push({
          span,
          xValue0,
          xValue1,
          yValue0: 0,
          yValue1: 0
        });
      }
    }
    this.phantomSpans = phantomSpans;
    const fillSpans = [];
    const strokeSpans = [];
    let phantomIndex = 0;
    for (let metaIndex = m0; metaIndex < m1; metaIndex += 1) {
      const startIndex = metaIndices[metaIndex];
      const endIndex = metaIndices[metaIndex + 1];
      const startDatumIndex = indices[startIndex];
      const endDatumIndex = indices[endIndex];
      const spanInvalid = !connectMissingData && this.hasInvalidDatumsInRange(invalidData, yValues, startDatumIndex, endDatumIndex);
      const phantomSpanDatum = phantomSpans[phantomIndex++];
      if (spanInvalid) {
        fillSpans.push(phantomSpanDatum);
        strokeSpans.push(phantomSpanDatum);
        continue;
      }
      const bucketPoints = [];
      for (let i = startIndex; i <= endIndex; i++) {
        const datumIndex = indices[i];
        if (invalidData?.[datumIndex])
          continue;
        const yValue = yValues[datumIndex];
        if (!Number.isFinite(yValue))
          continue;
        const xDatum = xValues[datumIndex];
        bucketPoints.push({
          point: {
            x: xScale.convert(xDatum) + xOffset,
            y: yScale.convert(yValue)
          },
          xDatum,
          yDatum: yValue
        });
      }
      if (bucketPoints.length < 2) {
        fillSpans.push(phantomSpanDatum);
        strokeSpans.push(phantomSpanDatum);
        continue;
      }
      const startPoint = bucketPoints[0];
      const endPoint = bucketPoints.at(-1);
      const midPoints = bucketPoints.slice(1, -1).map((p) => p.point);
      const span = {
        type: "multi-line",
        moveTo: false,
        x0: startPoint.point.x,
        y0: startPoint.point.y,
        x1: endPoint.point.x,
        y1: endPoint.point.y,
        midPoints
      };
      const spanDatum = {
        span,
        xValue0: startPoint.xDatum,
        xValue1: endPoint.xDatum,
        yValue0: startPoint.yDatum,
        yValue1: endPoint.yDatum
      };
      fillSpans.push(spanDatum);
      strokeSpans.push(spanDatum);
    }
    this.fillSpans = fillSpans;
    this.strokeSpans = strokeSpans;
    return {
      stack: [],
      fillSpans,
      strokeSpans
    };
  }
  hasInvalidDatumsInRange(invalidData, yValues, startIndex, endIndex) {
    const rangeStart = Math.min(startIndex, endIndex);
    const rangeEnd = Math.max(startIndex, endIndex);
    for (let datumIndex = rangeStart; datumIndex <= rangeEnd; datumIndex++) {
      if (invalidData?.[datumIndex]) {
        return true;
      }
      const yValue = yValues[datumIndex];
      if (!Number.isFinite(yValue)) {
        return true;
      }
    }
    return false;
  }
  stackYValueData() {
    const { visible, axes, dataModel, processedData, seriesBelowStackContext, properties } = this;
    const xAxis = axes["x" /* X */];
    const yAxis = axes["y" /* Y */];
    if (xAxis == null || yAxis == null || dataModel == null || processedData == null)
      return;
    const { interpolation } = properties;
    const { scale: xScale } = xAxis;
    const { scale: yScale } = yAxis;
    const xOffset = (xScale.bandwidth ?? 0) / 2;
    let xValues = dataModel.resolveKeysById(this, "xValue", processedData);
    let yValues = dataModel.resolveColumnById(this, this.yValueKey(), processedData);
    const connectMissingData = !this.isStacked() && this.properties.connectMissingData;
    const invalidKeys = processedData.invalidKeys?.get(this.id);
    const invalidData = connectMissingData ? processedData.invalidData?.get(this.id) : void 0;
    const indexFilter = invalidData ?? invalidKeys;
    if (indexFilter != null) {
      xValues = xValues.filter((_, datumIndex) => indexFilter[datumIndex] === false);
      yValues = yValues.filter((_, datumIndex) => indexFilter[datumIndex] === false);
    }
    let [startIndex, endIndex] = visibleRangeIndices(
      1,
      xValues.length,
      xAxis.range,
      (datumIndex) => this.xCoordinateRange(xValues[datumIndex], 0)
    );
    startIndex = Math.max(startIndex - 2, 0);
    endIndex = Math.min(endIndex + 2, xValues.length);
    let phantomSpans;
    if (seriesBelowStackContext?.fillSpans) {
      phantomSpans = seriesBelowStackContext?.fillSpans;
    } else {
      const phantomSpanPoints = [];
      for (let datumIndex = startIndex; datumIndex < endIndex; datumIndex += 1) {
        const xDatum = xValues[datumIndex];
        phantomSpanPoints.push({
          point: {
            x: xScale.convert(xDatum) + xOffset,
            y: yScale.convert(0)
          },
          xDatum,
          yDatum: 0
        });
      }
      phantomSpans = interpolatePoints(phantomSpanPoints, { type: "linear" });
    }
    this.phantomSpans = phantomSpans;
    if (!visible) {
      this.fillSpans = phantomSpans;
      this.strokeSpans = [];
      return seriesBelowStackContext;
    }
    let bottomStack = seriesBelowStackContext?.stack;
    if (bottomStack == null) {
      bottomStack = [];
      for (let datumIndex = startIndex; datumIndex < endIndex - 1; datumIndex += 1) {
        bottomStack.push({ leading: 0, trailing: 0, dataValid: true, breakBefore: false });
      }
    }
    const topStack = bottomStack.slice();
    let trackingValidData = false;
    for (let stackIndex = 0; stackIndex < topStack.length; stackIndex += 1) {
      const leadingIndex = startIndex + stackIndex;
      const trailingIndex = startIndex + stackIndex + 1;
      let { leading, trailing, breakBefore } = bottomStack[stackIndex];
      const leadingValue = yValues[leadingIndex];
      const trailingValue = yValues[trailingIndex];
      const missingLeading = !Number.isFinite(leadingValue);
      const missingTrailing = !Number.isFinite(trailingValue);
      const dataValid = !missingLeading && !missingTrailing;
      if (dataValid) {
        leading += leadingValue;
        trailing += trailingValue;
      }
      if (stackIndex !== 0 && dataValid !== trackingValidData) {
        breakBefore = true;
      }
      trackingValidData = dataValid;
      topStack[stackIndex] = { leading, trailing, dataValid, breakBefore };
    }
    const fillSpans = [];
    const strokeSpans = [];
    const topSpanPoints = [];
    for (let stackIndex = 0; stackIndex < topStack.length; stackIndex += 1) {
      const { leading, dataValid, breakBefore } = topStack[stackIndex];
      const leadingIndex = startIndex + stackIndex;
      if (breakBefore) {
        if (topSpanPoints.length !== 0) {
          const previousStack = topStack[stackIndex - 1];
          const previousPoint = {
            point: {
              x: xScale.convert(xValues[leadingIndex]) + xOffset,
              y: yScale.convert(previousStack.trailing)
            },
            xDatum: xValues[leadingIndex],
            yDatum: previousStack.trailing
          };
          topSpanPoints.push(previousPoint);
          const spans = interpolatePoints(topSpanPoints, interpolation);
          fillSpans.push(...spans);
          strokeSpans.push(...spans);
        }
        topSpanPoints.length = 0;
      }
      if (dataValid) {
        const leadingPoint = {
          point: {
            x: xScale.convert(xValues[leadingIndex]) + xOffset,
            y: yScale.convert(leading)
          },
          xDatum: xValues[leadingIndex],
          yDatum: leading
        };
        topSpanPoints.push(leadingPoint);
      } else {
        fillSpans.push(phantomSpans[stackIndex]);
      }
    }
    if (topSpanPoints.length !== 0) {
      const previousStack = topStack.at(-1);
      const trailingIndex = startIndex + topStack.length;
      const trailingPoint = {
        point: {
          x: xScale.convert(xValues[trailingIndex]) + xOffset,
          y: yScale.convert(previousStack.trailing)
        },
        xDatum: xValues[trailingIndex],
        yDatum: previousStack.trailing
      };
      topSpanPoints.push(trailingPoint);
      const spans = interpolatePoints(topSpanPoints, interpolation);
      fillSpans.push(...spans);
      strokeSpans.push(...spans);
      topSpanPoints.length = 0;
    }
    this.fillSpans = fillSpans;
    this.strokeSpans = strokeSpans;
    return {
      stack: topStack,
      fillSpans,
      strokeSpans
    };
  }
  createStackContext() {
    const xAxis = this.axes["x" /* X */];
    if (xAxis == null)
      return;
    const { scale: xScale } = xAxis;
    const [r0, r1] = xScale.range;
    const range3 = Math.abs(r1 - r0);
    this.aggregationManager.ensureLevelForRange(range3);
    const dataAggregationFilter = this.aggregationManager.getFilterForRange(range3);
    if (dataAggregationFilter) {
      return this.stackAggregatedData(dataAggregationFilter);
    } else {
      return this.stackYValueData();
    }
  }
  /**
   * Creates the context object with cached lookups for createNodeData().
   * All expensive operations (data resolution, scale lookups) are performed once here.
   */
  createNodeDatumContext(xAxis, yAxis) {
    const { dataModel, processedData } = this;
    if (!dataModel || !processedData)
      return void 0;
    const {
      xKey,
      xName,
      yFilterKey,
      yKey,
      yName,
      legendItemName,
      marker,
      label,
      fill: seriesFill,
      stroke: seriesStroke,
      normalizedTo
    } = this.properties;
    const xScale = xAxis.scale;
    const yScale = yAxis.scale;
    const { isContinuousY } = this.getScaleInformation({ xScale, yScale });
    const stacked = processedData.type === "grouped";
    const [r0, r1] = xScale.range;
    const range3 = Math.abs(r1 - r0);
    this.aggregationManager.ensureLevelForRange(range3);
    const dataAggregationFilter = this.aggregationManager.getFilterForRange(range3);
    const existingNodeData = this.contextNodeData?.nodeData;
    const canIncrementallyUpdate = existingNodeData != null && this.canIncrementallyUpdateNodes(dataAggregationFilter != null);
    return {
      // Axes (from template method parameters)
      xAxis,
      yAxis,
      // Data arrays (resolved once)
      rawData: processedData.dataSources.get(this.id)?.data ?? [],
      xValues: dataModel.resolveKeysById(this, "xValue", processedData),
      yRawValues: dataModel.resolveColumnById(this, "yValueRaw", processedData),
      yCumulativeValues: stacked ? dataModel.resolveColumnById(this, "yValueCumulative", processedData) : dataModel.resolveColumnById(this, "yValueRaw", processedData),
      yFilterValues: yFilterKey == null ? void 0 : dataModel.resolveColumnById(this, "yFilterRaw", processedData),
      invalidData: processedData.invalidData?.get(this.id),
      // Scales (cached)
      xScale,
      yScale,
      xOffset: (xScale.bandwidth ?? 0) / 2,
      yOffset: 0,
      // Aggregation
      indices: dataAggregationFilter?.indices,
      // Pre-computed flags
      isContinuousY,
      labelsEnabled: label.enabled,
      normalizedTo,
      canIncrementallyUpdate,
      animationEnabled: !this.ctx.animationManager.isSkipped(),
      // Property caches
      xKey,
      yKey,
      xName,
      yName,
      legendItemName,
      markerSize: marker.size,
      markerFill: marker.fill ?? seriesFill,
      markerStroke: marker.stroke ?? seriesStroke,
      markerStrokeWidth: marker.strokeWidth ?? this.properties.strokeWidth,
      yDomain: this.getSeriesDomain("y" /* Y */).domain,
      // Mutable state (nodes instead of markerData to match base interface)
      nodes: canIncrementallyUpdate ? existingNodeData : [],
      labelData: [],
      nodeIndex: 0,
      crossFiltering: false
    };
  }
  /**
   * Computes the marker coordinate for a datum.
   * Uses cached context values to avoid repeated lookups.
   */
  computeMarkerCoordinate(ctx, scratch) {
    let currY;
    if (isDefined(ctx.normalizedTo) ? ctx.isContinuousY && isContinuous(scratch.yDatum) : !Number.isNaN(scratch.yDatum)) {
      currY = scratch.yCumulative;
    }
    scratch.x = ctx.xScale.convert(scratch.xDatum) + ctx.xOffset;
    scratch.y = ctx.yScale.convert(currY);
    if (!Number.isFinite(scratch.x)) {
      scratch.validPoint = false;
    }
  }
  /**
   * Processes a single datum and updates the context's marker/label data.
   * Uses scratch object to avoid allocations in tight loops.
   */
  handleDatum(ctx, scratch, datumIndex) {
    scratch.xDatum = ctx.xValues[datumIndex];
    if (scratch.xDatum === void 0 && !this.properties.allowNullKeys)
      return;
    scratch.datum = ctx.rawData[datumIndex];
    scratch.yDatum = ctx.yRawValues[datumIndex];
    scratch.yCumulative = +ctx.yCumulativeValues[datumIndex];
    scratch.validPoint = Number.isFinite(scratch.yDatum) && ctx.invalidData?.[datumIndex] !== true;
    this.computeMarkerCoordinate(ctx, scratch);
    scratch.selected = ctx.yFilterValues == null ? void 0 : ctx.yFilterValues[datumIndex] === scratch.yDatum;
    if (scratch.selected === false) {
      ctx.crossFiltering = true;
    }
    if (scratch.validPoint) {
      const canReuseNode = ctx.canIncrementallyUpdate && ctx.nodeIndex < ctx.nodes.length;
      if (canReuseNode) {
        const existingNode = ctx.nodes[ctx.nodeIndex];
        existingNode.datum = scratch.datum;
        existingNode.datumIndex = datumIndex;
        existingNode.midPoint = { x: scratch.x, y: scratch.y };
        existingNode.cumulativeValue = scratch.yCumulative;
        existingNode.yValue = scratch.yDatum;
        existingNode.xValue = scratch.xDatum;
        existingNode.point = { x: scratch.x, y: scratch.y, size: ctx.markerSize };
        existingNode.selected = scratch.selected;
      } else {
        ctx.nodes.push({
          series: this,
          datum: scratch.datum,
          datumIndex,
          midPoint: { x: scratch.x, y: scratch.y },
          cumulativeValue: scratch.yCumulative,
          yValue: scratch.yDatum,
          xValue: scratch.xDatum,
          yKey: ctx.yKey,
          xKey: ctx.xKey,
          point: { x: scratch.x, y: scratch.y, size: ctx.markerSize },
          fill: ctx.markerFill,
          stroke: ctx.markerStroke,
          strokeWidth: ctx.markerStrokeWidth,
          selected: scratch.selected
        });
      }
      ctx.nodeIndex++;
    }
    if (ctx.labelsEnabled && scratch.validPoint) {
      const labelText = this.getLabelText(
        scratch.yDatum,
        scratch.datum,
        ctx.yKey,
        "y",
        ctx.yDomain,
        this.properties.label,
        {
          value: scratch.yDatum,
          datum: scratch.datum,
          xKey: ctx.xKey,
          yKey: ctx.yKey,
          xName: ctx.xName,
          yName: ctx.yName,
          legendItemName: ctx.legendItemName
        }
      );
      ctx.labelData.push({
        series: this,
        datum: scratch.datum,
        datumIndex,
        x: scratch.x,
        y: scratch.y,
        labelText
      });
    }
  }
  // ============================================================================
  // Template Method Hooks
  // ============================================================================
  /**
   * Populates the node data array by iterating over visible data.
   */
  populateNodeData(ctx) {
    const scratch = {
      datum: void 0,
      xDatum: void 0,
      yDatum: void 0,
      yCumulative: 0,
      selected: void 0,
      x: 0,
      y: 0,
      validPoint: false
    };
    let [startIndex, endIndex] = this.visibleRangeIndices("xValue", ctx.xAxis.range, ctx.indices);
    startIndex = Math.max(startIndex - 2, 0);
    endIndex = Math.min(endIndex + 2, ctx.indices?.length ?? ctx.xValues.length);
    if (this.processedData.input.count < 1e3) {
      startIndex = 0;
      endIndex = this.processedData.input.count;
    }
    for (let i = startIndex; i < endIndex; i += 1) {
      const datumIndex = ctx.indices?.[i] ?? i;
      this.handleDatum(ctx, scratch, datumIndex);
    }
  }
  /**
   * Initializes the result context object with default values.
   * Called before populate phase to allow early return for invisible series.
   *
   * Note: We use the actual fillSpans/strokeSpans/phantomSpans because createStackContext()
   * runs BEFORE createNodeData() and populates these instance fields. They are valid
   * even in the early return case when !visible.
   */
  initializeResult(ctx) {
    const { visibleSameStackCount } = this.ctx.seriesStateManager.getVisiblePeerGroupIndex(this);
    return {
      itemId: ctx.yKey,
      // Use actual spans from createStackContext() - valid even for early return
      fillData: { spans: this.fillSpans, phantomSpans: this.phantomSpans },
      strokeData: { spans: this.strokeSpans },
      labelData: ctx.labelData,
      nodeData: ctx.nodes,
      scales: this.calculateScaling(),
      visible: this.visible,
      stackVisible: visibleSameStackCount > 0,
      crossFiltering: ctx.crossFiltering,
      styles: getMarkerStyles(this, this.properties, this.properties.marker),
      segments: void 0
    };
  }
  /**
   * Assembles the final result with computed fields.
   * Note: fillData/strokeData are already set in initializeResult() from instance fields.
   */
  assembleResult(ctx, result) {
    result.segments = calculateSegments(
      this.properties.segmentation,
      ctx.xAxis,
      ctx.yAxis,
      this.chart.seriesRect,
      this.ctx.scene,
      false
    );
    return result;
  }
  isPathOrSelectionDirty() {
    return this.properties.marker.isDirty();
  }
  updatePathNodes(opts) {
    const {
      paths: [fillPaths, strokePaths],
      visible,
      animationEnabled
    } = opts;
    const crossFiltering = this.contextNodeData?.crossFiltering === true;
    const segments = this.contextNodeData?.segments;
    const merged = mergeDefaults(this.getHighlightStyle(), this.getStyle());
    const { strokeWidth, stroke: stroke3, strokeOpacity, lineDash, lineDashOffset, fill, fillOpacity, opacity } = merged;
    strokePaths.setProperties({
      segments,
      fill: void 0,
      lineCap: "round",
      lineJoin: "round",
      pointerEvents: 1 /* None */,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity: strokeOpacity * (crossFiltering ? CROSS_FILTER_AREA_STROKE_OPACITY_FACTOR : 1),
      lineDash,
      lineDashOffset,
      opacity,
      visible: visible || animationEnabled
    });
    strokePaths.datum = segments;
    fillPaths.setStyleProperties(
      {
        fill,
        stroke: void 0,
        fillOpacity: fillOpacity * (crossFiltering ? CROSS_FILTER_AREA_FILL_OPACITY_FACTOR : 1)
      },
      this.getShapeFillBBox()
    );
    fillPaths.setProperties({
      segments,
      lineJoin: "round",
      pointerEvents: 1 /* None */,
      fillShadow: this.properties.shadow,
      opacity,
      visible: visible || animationEnabled
    });
    fillPaths.datum = segments;
    updateClipPath(this, strokePaths);
    updateClipPath(this, fillPaths);
  }
  updatePaths(opts) {
    this.updateAreaPaths(opts.paths, opts.contextData);
  }
  updateAreaPaths(paths, contextData) {
    for (const path of paths) {
      path.visible = contextData.visible;
    }
    if (contextData.visible) {
      this.updateFillPath(paths, contextData);
      this.updateStrokePath(paths, contextData);
    } else {
      for (const path of paths) {
        path.path.clear();
        path.markDirty("AreaSeries");
      }
    }
  }
  updateFillPath(paths, contextData) {
    const [fill] = paths;
    fill.path.clear();
    plotAreaPathFill(fill, contextData.fillData);
    fill.markDirty("AreaSeries");
  }
  updateStrokePath(paths, contextData) {
    const { spans } = contextData.strokeData;
    const [, stroke3] = paths;
    stroke3.path.clear();
    plotLinePathStroke(stroke3, spans);
    stroke3.markDirty("AreaSeries");
  }
  updateDatumSelection(opts) {
    const { nodeData, datumSelection } = opts;
    const { contextNodeData, processedData, axes, properties } = this;
    const { marker, styler } = properties;
    const markerStyle = styler ? this.getStyle().marker : void 0;
    const markersEnabled = contextNodeData?.crossFiltering === true || markerEnabled(processedData.input.count, axes["x" /* X */].scale, marker, markerStyle);
    if (marker.isDirty()) {
      datumSelection.clear();
      datumSelection.cleanup();
    }
    const data = markersEnabled ? nodeData : [];
    if (!processedDataIsAnimatable(this.processedData)) {
      return datumSelection.update(data);
    }
    return datumSelection.update(data, void 0, (datum) => createDatumId(datum.xValue));
  }
  updateDatumStyles(opts) {
    const { datumSelection, isHighlight } = opts;
    const { marker } = this.properties;
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    datumSelection.each((node, datum) => {
      if (!datumSelection.isGarbage(node)) {
        const highlightState = this.getHighlightState(highlightedDatum, opts.isHighlight, datum.datumIndex);
        const stylerStyle = this.getStyle(highlightState);
        const { stroke: stroke3, strokeWidth, strokeOpacity } = stylerStyle;
        const params = this.makeItemStylerParams(
          this.dataModel,
          this.processedData,
          datum.datumIndex,
          stylerStyle.marker
        );
        datum.style = this.getMarkerStyle(
          marker,
          datum,
          params,
          { isHighlight, highlightState },
          stylerStyle.marker,
          {
            stroke: stroke3,
            strokeWidth,
            strokeOpacity
          }
        );
      }
    });
  }
  updateDatumNodes(opts) {
    const { contextNodeData } = this;
    if (!contextNodeData) {
      return;
    }
    const { datumSelection, isHighlight } = opts;
    const fillBBox = this.getShapeFillBBox();
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    const drawingMode = this.getDrawingMode(isHighlight, opts.drawingMode);
    datumSelection.each((node, datum) => {
      const state = this.getHighlightState(highlightedDatum, isHighlight, datum.datumIndex);
      const style2 = datum.style ?? contextNodeData.styles[state];
      this.applyMarkerStyle(style2, node, datum.point, fillBBox, { selected: datum.selected });
      node.drawingMode = this.resolveMarkerDrawingModeForState(drawingMode, style2);
    });
    if (!isHighlight) {
      this.properties.marker.markClean();
    }
  }
  updateLabelSelection(opts) {
    return opts.labelSelection.update(this.isLabelEnabled() ? opts.labelData : []);
  }
  updateLabelNodes(opts) {
    const { isHighlight = false } = opts;
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const params = this.makeLabelFormatterParams();
    opts.labelSelection.each((text2, datum) => {
      const style2 = getLabelStyles(this, datum, params, this.properties.label, isHighlight, activeHighlight);
      const { enabled, fontStyle, fontWeight: fontWeight2, fontSize, fontFamily, color: color2 } = style2;
      if (enabled && datum?.labelText) {
        text2.fontStyle = fontStyle;
        text2.fontWeight = fontWeight2;
        text2.fontSize = fontSize;
        text2.fontFamily = fontFamily;
        text2.textAlign = "center";
        text2.textBaseline = "bottom";
        text2.text = datum.labelText;
        text2.x = datum.x;
        text2.y = datum.y - 10;
        text2.fill = color2;
        text2.visible = true;
        text2.fillOpacity = this.getHighlightStyle(isHighlight, datum.datumIndex).opacity ?? 1;
        text2.setBoxing(style2);
      } else {
        text2.visible = false;
      }
    });
  }
  makeStylerParams(highlightStateEnum) {
    const { id: seriesId } = this;
    const { marker, fill, fillOpacity, lineDash, lineDashOffset, stroke: stroke3, strokeOpacity, strokeWidth, xKey, yKey } = this.properties;
    const highlightState = toHighlightString(highlightStateEnum ?? 0 /* None */);
    return {
      marker: {
        fill: marker.fill,
        fillOpacity: marker.fillOpacity,
        size: marker.size,
        shape: marker.shape,
        stroke: marker.stroke,
        strokeOpacity: marker.strokeOpacity,
        strokeWidth: marker.strokeWidth,
        lineDash: marker.lineDash,
        lineDashOffset: marker.lineDashOffset
      },
      highlightState,
      fill,
      fillOpacity,
      lineDash,
      lineDashOffset,
      seriesId,
      stroke: stroke3,
      strokeOpacity,
      strokeWidth,
      xKey,
      yKey
    };
  }
  makeItemStylerParams(dataModel, processedData, datumIndex, style2) {
    const { xKey, yKey } = this.properties;
    const xValue = dataModel.resolveKeysById(this, `xValue`, processedData)[datumIndex];
    const yValue = dataModel.resolveColumnById(this, `yValueRaw`, processedData)[datumIndex];
    const xDomain = dataModel.getDomain(this, `xValue`, "key", processedData).domain;
    const yDomain = dataModel.getDomain(this, this.yCumulativeKey(processedData), "value", processedData).domain;
    const fill = this.filterItemStylerFillParams(style2.fill) ?? style2.fill;
    return {
      ...datumStylerProperties(xValue, yValue, xKey, yKey, xDomain, yDomain),
      xValue,
      yValue,
      ...style2,
      fill
    };
  }
  makeLabelFormatterParams() {
    const { xKey, xName, yKey, yName, legendItemName } = this.properties;
    return { xKey, xName, yKey, yName, legendItemName };
  }
  getTooltipContent(datumIndex) {
    const { id: seriesId, dataModel, processedData, axes, properties } = this;
    const { xKey, xName, yKey, yName, tooltip, legendItemName } = properties;
    const allowNullKeys = properties.allowNullKeys ?? false;
    const xAxis = axes["x" /* X */];
    const yAxis = axes["y" /* Y */];
    if (!dataModel || !processedData || !xAxis || !yAxis)
      return;
    const datum = processedData.dataSources.get(this.id)?.data?.[datumIndex];
    const xValue = dataModel.resolveKeysById(this, `xValue`, processedData)[datumIndex];
    const yValue = dataModel.resolveColumnById(this, `yValueRaw`, processedData)[datumIndex];
    if (xValue === void 0 && !allowNullKeys)
      return;
    const stylerStyle = this.getStyle();
    const params = this.makeItemStylerParams(dataModel, processedData, datumIndex, stylerStyle.marker);
    const format = this.getMarkerStyle(
      this.properties.marker,
      { datumIndex, datum },
      params,
      { isHighlight: false },
      stylerStyle.marker
    );
    return this.formatTooltipWithContext(
      tooltip,
      {
        heading: this.getAxisValueText(xAxis, "tooltip", xValue, datum, xKey, legendItemName, allowNullKeys),
        symbol: this.legendItemSymbol(),
        data: [
          {
            label: yName,
            fallbackLabel: yKey,
            value: this.getAxisValueText(yAxis, "tooltip", yValue, datum, yKey, legendItemName),
            missing: isTooltipValueMissing(yValue)
          }
        ]
      },
      {
        seriesId,
        datum,
        title: yName,
        xKey,
        xName,
        yKey,
        yName,
        ...format,
        ...this.getModuleTooltipParams()
      }
    );
  }
  legendItemSymbol() {
    const { fill, stroke: stroke3, fillOpacity, strokeOpacity, strokeWidth, lineDash, marker } = this.getStyle();
    const useAreaFill = !marker.enabled || marker.fill == null;
    const legendMarkerFill = useAreaFill ? fill : marker.fill;
    const markerStyle = this.getMarkerStyle(
      this.properties.marker,
      {},
      void 0,
      { isHighlight: false, checkForHighlight: false },
      {
        size: marker.size,
        shape: marker.shape,
        fill: legendMarkerFill,
        fillOpacity: useAreaFill ? fillOpacity : marker.fillOpacity,
        stroke: marker.stroke
      }
    );
    return {
      marker: {
        ...markerStyle,
        enabled: marker.enabled || strokeWidth <= 0
      },
      line: {
        enabled: true,
        stroke: stroke3,
        strokeOpacity,
        strokeWidth,
        lineDash
      }
    };
  }
  getLegendData(legendType) {
    if (legendType !== "category") {
      return [];
    }
    const {
      id: seriesId,
      ctx: { legendManager },
      visible
    } = this;
    const { yKey: itemId, yName, legendItemName, showInLegend } = this.properties;
    return [
      {
        legendType,
        id: seriesId,
        itemId,
        legendItemName,
        seriesId,
        enabled: visible && legendManager.getItemEnabled({ seriesId, itemId }),
        label: {
          text: legendItemName ?? yName ?? itemId
        },
        symbol: this.legendItemSymbol(),
        hideInLegend: !showInLegend
      }
    ];
  }
  resetDatumAnimation(data) {
    resetMarkerSelectionsDirect([data.datumSelection]);
  }
  animateEmptyUpdateReady(animationData) {
    const { datumSelection, labelSelection, contextData, paths } = animationData;
    const { animationManager } = this.ctx;
    this.updateAreaPaths(paths, contextData);
    pathSwipeInAnimation(this, animationManager, ...paths);
    resetMotion([datumSelection], resetMarkerPositionFn);
    markerSwipeScaleInAnimation(
      this,
      animationManager,
      { ...this.getAnimationDrawingModes(), phase: "initial" },
      datumSelection
    );
    seriesLabelFadeInAnimation(this, "labels", animationManager, labelSelection);
  }
  animateReadyResize(animationData) {
    const { contextData, paths } = animationData;
    this.updateAreaPaths(paths, contextData);
    super.animateReadyResize(animationData);
  }
  animateWaitingUpdateReady(animationData) {
    const { animationManager } = this.ctx;
    const { datumSelection, labelSelection, contextData, paths, previousContextData } = animationData;
    const [fill, stroke3] = paths;
    if (contextData.visible === false && previousContextData?.visible === false)
      return;
    if (fill == null && stroke3 == null)
      return;
    this.resetDatumAnimation(animationData);
    this.resetLabelAnimation(animationData);
    const update = () => {
      this.resetPathAnimation(animationData);
      this.updateAreaPaths(paths, contextData);
    };
    const skip = () => {
      animationManager.skipCurrentBatch();
      update();
    };
    if (contextData == null || previousContextData == null) {
      update();
      markerFadeInAnimation(this, animationManager, "added", this.getAnimationDrawingModes(), datumSelection);
      pathFadeInAnimation(this, "fill_path_properties", animationManager, "add", fill);
      pathFadeInAnimation(this, "stroke_path_properties", animationManager, "add", stroke3);
      seriesLabelFadeInAnimation(this, "labels", animationManager, labelSelection);
      return;
    }
    if (contextData.crossFiltering !== previousContextData.crossFiltering) {
      skip();
      return;
    }
    const fns = prepareAreaPathAnimation(contextData, previousContextData);
    if (fns === void 0) {
      skip();
      return;
    } else if (fns.status === "no-op") {
      return;
    }
    markerFadeInAnimation(this, animationManager, void 0, this.getAnimationDrawingModes(), datumSelection);
    fromToMotion(this.id, "fill_path_properties", animationManager, [fill], fns.fill.pathProperties);
    pathMotion(this.id, "fill_path_update", animationManager, [fill], fns.fill.path);
    fromToMotion(this.id, "stroke_path_properties", animationManager, [stroke3], fns.stroke.pathProperties);
    pathMotion(this.id, "stroke_path_update", animationManager, [stroke3], fns.stroke.path);
    seriesLabelFadeInAnimation(this, "labels", animationManager, labelSelection);
    this.ctx.animationManager.animate({
      id: this.id,
      groupId: "reset_after_animation",
      phase: "trailing",
      from: {},
      to: {},
      onComplete: () => this.updateAreaPaths(paths, contextData)
    });
  }
  isLabelEnabled() {
    return this.properties.label.enabled;
  }
  nodeFactory() {
    return new Marker();
  }
  getStyle(highlightState) {
    const { styler, marker, fill, fillOpacity, lineDash, lineDashOffset, stroke: stroke3, strokeOpacity, strokeWidth } = this.properties;
    const { size, shape, fill: markerFill = "transparent", fillOpacity: markerFillOpacity } = marker;
    let stylerResult = {};
    if (styler) {
      const stylerParams = this.makeStylerParams(highlightState);
      const cbResult = this.cachedCallWithContext(styler, stylerParams) ?? {};
      const resolved = this.ctx.optionsGraphService.resolvePartial(
        ["series", `${this.declarationOrder}`],
        cbResult,
        { pick: false }
      );
      stylerResult = resolved ?? {};
    }
    stylerResult.marker ?? (stylerResult.marker = {});
    return {
      fill: stylerResult.fill ?? fill,
      fillOpacity: stylerResult.fillOpacity ?? fillOpacity,
      lineDash: stylerResult.lineDash ?? lineDash,
      lineDashOffset: stylerResult.lineDashOffset ?? lineDashOffset,
      stroke: stylerResult.stroke ?? stroke3,
      strokeOpacity: stylerResult.strokeOpacity ?? strokeOpacity,
      strokeWidth: stylerResult.strokeWidth ?? strokeWidth,
      marker: {
        enabled: stylerResult.marker.enabled ?? marker.enabled,
        fill: stylerResult.marker.fill ?? markerFill,
        fillOpacity: stylerResult.marker.fillOpacity ?? markerFillOpacity,
        shape: stylerResult.marker.shape ?? shape,
        size: stylerResult.marker.size ?? size,
        lineDash: stylerResult.marker.lineDash ?? marker.lineDash ?? lineDash,
        lineDashOffset: stylerResult.marker.lineDashOffset ?? marker.lineDashOffset ?? lineDashOffset,
        stroke: stylerResult.marker.stroke ?? marker.stroke ?? stroke3,
        strokeOpacity: stylerResult.marker.strokeOpacity ?? marker.strokeOpacity ?? strokeOpacity,
        strokeWidth: stylerResult.marker.strokeWidth ?? marker.strokeWidth ?? strokeWidth
      }
    };
  }
  getFormattedMarkerStyle(datum) {
    const stylerStyle = this.getStyle();
    const params = this.makeItemStylerParams(
      this.dataModel,
      this.processedData,
      datum.datumIndex,
      stylerStyle.marker
    );
    return this.getMarkerStyle(
      this.properties.marker,
      datum,
      params,
      { isHighlight: true },
      void 0,
      stylerStyle
    );
  }
  isPointInArea(x, y) {
    let fillPath;
    for (const child of this.backgroundGroup.children()) {
      if (child instanceof Path) {
        fillPath = child;
        break;
      }
    }
    if (!fillPath?.getBBox().containsPoint(x, y)) {
      return false;
    }
    return fillPath.isPointInPath(x, y);
  }
  computeFocusBounds(opts) {
    return computeMarkerFocusBounds(this, opts);
  }
  hasItemStylers() {
    return this.properties.styler != null || this.properties.marker.itemStyler != null || this.properties.label.itemStyler != null;
  }
};
AreaSeries.className = "AreaSeries";
AreaSeries.type = "area";

// packages/ag-charts-community/src/chart/series/cartesian/areaSeriesModule.ts
var themeTemplate = {
  series: {
    nodeClickRange: "nearest",
    fill: {
      $applySwitch: [
        { $path: "type" },
        { $palette: "fill" },
        ["gradient", FILL_GRADIENT_LINEAR_DEFAULTS],
        ["image", FILL_IMAGE_DEFAULTS],
        ["pattern", FILL_PATTERN_DEFAULTS]
      ]
    },
    stroke: { $palette: "stroke" },
    fillOpacity: 0.8,
    strokeOpacity: 1,
    strokeWidth: { $isUserOption: ["./stroke", 2, 0] },
    lineDash: [0],
    lineDashOffset: 0,
    shadow: {
      enabled: false,
      color: DEFAULT_SHADOW_COLOUR,
      xOffset: 3,
      yOffset: 3,
      blur: 5
    },
    interpolation: {
      type: "linear"
    },
    marker: {
      enabled: false,
      shape: "circle",
      size: 7,
      strokeWidth: { $isUserOption: ["./stroke", 1, 0] },
      fill: {
        $applySwitch: [
          { $path: "type" },
          { $palette: "fill" },
          ["gradient", FILL_GRADIENT_RADIAL_REVERSED_DEFAULTS],
          ["pattern", FILL_PATTERN_DEFAULTS]
        ]
      },
      stroke: { $palette: "stroke" }
    },
    label: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: false,
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      fontWeight: { $ref: "fontWeight" },
      color: { $ref: "textColor" }
    },
    tooltip: {
      range: { $path: ["/tooltip/range", "nearest"] },
      position: {
        anchorTo: { $path: ["/tooltip/position/anchorTo", "node"] }
      }
    },
    highlight: MARKER_SERIES_HIGHLIGHT_STYLE,
    segmentation: SEGMENTATION_DEFAULTS
  }
};
var AreaSeriesModule = {
  type: "series",
  name: "area",
  chartType: "cartesian",
  stackable: true,
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: areaSeriesOptionsDef,
  predictAxis: predictCartesianNonPrimitiveAxis,
  defaultAxes: {
    y: {
      type: "number" /* NUMBER */,
      position: "left" /* LEFT */
    },
    x: {
      type: "category" /* CATEGORY */,
      position: "bottom" /* BOTTOM */
    }
  },
  axisKeys: { ["x" /* X */]: "xKeyAxis", ["y" /* Y */]: "yKeyAxis" },
  themeTemplate,
  create: (ctx) => new AreaSeries(ctx)
};

// packages/ag-charts-community/src/scene/shape/barShape.ts
var FEATHERED_THRESHOLD = 1e-3;
var BarShape = class extends Rect {
  constructor() {
    super(...arguments);
    this.direction = "x";
    this.featherRatio = 0;
  }
  // optimised field accessor
  /**
   * High-performance static property setter that bypasses the decorator system entirely.
   * Writes directly to backing fields (__propertyName) to avoid:
   * - Decorator setter chains and equality checks
   * - Multiple onChangeDetection calls per property
   * - Object.keys() iteration in assignIfNotStrictlyEqual
   * - Object allocation overhead
   *
   * A single markDirty() call at the end ensures the scene graph is properly invalidated.
   * WARNING: Only use for hot paths where performance is critical and properties don't need
   * individual change detection (e.g., when updating many nodes in a loop).
   */
  setStaticProperties(drawingMode, topLeftCornerRadius, topRightCornerRadius, bottomRightCornerRadius, bottomLeftCornerRadius, visible, crisp, fillShadow, direction, featherRatio) {
    this.__direction = direction ?? "x";
    this.__featherRatio = featherRatio ?? 0;
    super.setStaticProperties(
      drawingMode,
      topLeftCornerRadius,
      topRightCornerRadius,
      bottomRightCornerRadius,
      bottomLeftCornerRadius,
      visible,
      crisp,
      fillShadow
    );
  }
  get feathered() {
    return Math.abs(this.featherRatio) > FEATHERED_THRESHOLD;
  }
  isPointInPath(x, y) {
    if (!this.feathered) {
      return super.isPointInPath(x, y);
    }
    const bbox = this.getBBox();
    return bbox.containsPoint(x, y);
  }
  updatePath() {
    if (!this.feathered) {
      super.updatePath();
      return;
    }
    const {
      path,
      borderPath,
      __direction: direction,
      __featherRatio: featherRatio,
      __x: x,
      __y: y,
      __width: width2,
      __height: height2
    } = this;
    path.clear();
    borderPath.clear();
    if (direction === "x") {
      const featherInsetX = Math.abs(featherRatio) * width2;
      if (featherRatio > 0) {
        path.moveTo(x, y);
        path.lineTo(x + width2 - featherInsetX, y);
        path.lineTo(x + width2, y + height2 / 2);
        path.lineTo(x + width2 - featherInsetX, y + height2);
        path.lineTo(x, y + height2);
        path.closePath();
      } else {
        path.moveTo(x + featherInsetX, y);
        path.lineTo(x + width2, y);
        path.lineTo(x + width2, y + height2);
        path.lineTo(x + featherInsetX, y + height2);
        path.lineTo(x, y + height2 / 2);
        path.closePath();
      }
    } else {
      const featherInsetY = Math.abs(featherRatio) * height2;
      if (featherRatio > 0) {
        path.moveTo(x, y + featherInsetY);
        path.lineTo(x + width2 / 2, y);
        path.lineTo(x + width2, y + featherInsetY);
        path.lineTo(x + width2, y + height2);
        path.lineTo(x, y + height2);
        path.closePath();
      } else {
        path.moveTo(x, y);
        path.lineTo(x + width2, y);
        path.lineTo(x + width2, y + height2 - featherInsetY);
        path.lineTo(x + width2 / 2, y + height2);
        path.lineTo(x, y + height2 - featherInsetY);
        path.closePath();
      }
    }
  }
  renderStroke(ctx) {
    if (!this.feathered) {
      super.renderStroke(ctx);
      return;
    }
    const {
      __stroke: stroke3,
      __strokeWidth: strokeWidth,
      __lineDash: lineDash,
      __lineDashOffset: lineDashOffset,
      __lineCap: lineCap,
      __lineJoin: lineJoin,
      path
    } = this;
    if (stroke3 && strokeWidth) {
      const { globalAlpha } = ctx;
      this.applyStrokeAndAlpha(ctx);
      ctx.lineWidth = strokeWidth;
      if (lineDash) {
        ctx.setLineDash(lineDash);
      }
      if (lineDashOffset) {
        ctx.lineDashOffset = lineDashOffset;
      }
      if (lineCap) {
        ctx.lineCap = lineCap;
      }
      if (lineJoin) {
        ctx.lineJoin = lineJoin;
      }
      ctx.stroke(path.getPath2D());
      ctx.globalAlpha = globalAlpha;
    }
  }
};
__decorateClass([
  DeclaredSceneChangeDetection()
], BarShape.prototype, "direction", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], BarShape.prototype, "featherRatio", 2);

// packages/ag-charts-community/src/chart/series/cartesian/barAggregation.ts
function computeBarAggregation(domain, xValues, yStartValues, yEndValues, options) {
  if (xValues.length < AGGREGATION_THRESHOLD)
    return;
  const [d0, d1] = domain;
  const { smallestKeyInterval, xNeedsValueOf, yNeedsValueOf, existingFilters } = options;
  let maxRange = aggregationRangeFittingPoints(xValues, d0, d1, { smallestKeyInterval, xNeedsValueOf });
  const existingFilter = existingFilters?.find((f) => f.maxRange === maxRange);
  let {
    indexData: positiveIndexData,
    valueData: positiveValueData,
    negativeIndexData,
    negativeValueData
  } = createAggregationIndices(xValues, yEndValues, yStartValues ?? yEndValues, d0, d1, maxRange, {
    split: true,
    xNeedsValueOf,
    yNeedsValueOf,
    reuseIndexData: existingFilter?.positiveIndexData,
    reuseValueData: existingFilter?.positiveValueData,
    reuseNegativeIndexData: existingFilter?.negativeIndexData,
    reuseNegativeValueData: existingFilter?.negativeValueData
  });
  if (!negativeIndexData || !negativeValueData) {
    throw new Error("Negative aggregation data missing in split mode");
  }
  let positiveIndices = getMidpointsForIndices(maxRange, positiveIndexData, existingFilter?.positiveIndices);
  let negativeIndices = getMidpointsForIndices(maxRange, negativeIndexData, existingFilter?.negativeIndices);
  const filters = [
    {
      maxRange,
      positiveIndices,
      positiveIndexData,
      positiveValueData,
      negativeIndices,
      negativeIndexData,
      negativeValueData
    }
  ];
  while (maxRange > 64) {
    const currentMaxRange = maxRange;
    const nextMaxRange = Math.trunc(currentMaxRange / 2);
    const nextExistingFilter = existingFilters?.find((f) => f.maxRange === nextMaxRange);
    const positiveCompacted = compactAggregationIndices(positiveIndexData, positiveValueData, currentMaxRange, {
      reuseIndexData: nextExistingFilter?.positiveIndexData,
      reuseValueData: nextExistingFilter?.positiveValueData
    });
    const negativeCompacted = compactAggregationIndices(negativeIndexData, negativeValueData, currentMaxRange, {
      reuseIndexData: nextExistingFilter?.negativeIndexData,
      reuseValueData: nextExistingFilter?.negativeValueData
    });
    maxRange = positiveCompacted.maxRange;
    positiveIndexData = positiveCompacted.indexData;
    positiveValueData = positiveCompacted.valueData;
    positiveIndices = positiveCompacted.midpointData ?? getMidpointsForIndices(maxRange, positiveIndexData, nextExistingFilter?.positiveIndices);
    negativeIndexData = negativeCompacted.indexData;
    negativeValueData = negativeCompacted.valueData;
    negativeIndices = negativeCompacted.midpointData ?? getMidpointsForIndices(maxRange, negativeIndexData, nextExistingFilter?.negativeIndices);
    filters.push({
      maxRange,
      positiveIndices,
      positiveIndexData,
      positiveValueData,
      negativeIndices,
      negativeIndexData,
      negativeValueData
    });
  }
  filters.reverse();
  return filters;
}
function computeBarAggregationPartial(domain, xValues, yStartValues, yEndValues, options) {
  if (xValues.length < AGGREGATION_THRESHOLD)
    return;
  const [d0, d1] = domain;
  const { smallestKeyInterval, xNeedsValueOf, yNeedsValueOf, targetRange, existingFilters } = options;
  const finestMaxRange = aggregationRangeFittingPoints(xValues, d0, d1, { smallestKeyInterval, xNeedsValueOf });
  const targetMaxRange = Math.min(finestMaxRange, nextPowerOf2(Math.max(targetRange, AGGREGATION_MIN_RANGE)));
  const existingFilter = existingFilters?.find((f) => f.maxRange === targetMaxRange);
  const {
    indexData: positiveIndexData,
    valueData: positiveValueData,
    negativeIndexData,
    negativeValueData
  } = createAggregationIndices(xValues, yEndValues, yStartValues ?? yEndValues, d0, d1, targetMaxRange, {
    split: true,
    xNeedsValueOf,
    yNeedsValueOf,
    reuseIndexData: existingFilter?.positiveIndexData,
    reuseValueData: existingFilter?.positiveValueData,
    reuseNegativeIndexData: existingFilter?.negativeIndexData,
    reuseNegativeValueData: existingFilter?.negativeValueData
  });
  if (!negativeIndexData || !negativeValueData) {
    throw new Error("Negative aggregation data missing in split mode");
  }
  const immediateLevel = {
    maxRange: targetMaxRange,
    positiveIndices: getMidpointsForIndices(targetMaxRange, positiveIndexData, existingFilter?.positiveIndices),
    positiveIndexData,
    positiveValueData,
    negativeIndices: getMidpointsForIndices(targetMaxRange, negativeIndexData, existingFilter?.negativeIndices),
    negativeIndexData,
    negativeValueData
  };
  function computeRemaining() {
    const allLevels = computeBarAggregation([d0, d1], xValues, yStartValues, yEndValues, {
      smallestKeyInterval,
      xNeedsValueOf,
      yNeedsValueOf,
      existingFilters
    });
    return allLevels?.filter((level) => level.maxRange !== targetMaxRange) ?? [];
  }
  return { immediate: [immediateLevel], computeRemaining };
}
function aggregateBarData(scale2, xValues, yStartValues, yEndValues, domainInput, smallestKeyInterval, xNeedsValueOf, yNeedsValueOf) {
  const [d0, d1] = aggregationDomain(scale2, domainInput);
  return computeBarAggregation([d0, d1], xValues, yStartValues, yEndValues, {
    smallestKeyInterval,
    xNeedsValueOf,
    yNeedsValueOf
  });
}
var memoizedAggregateBarData = simpleMemorize2(aggregateBarData);
function aggregateBarDataFromDataModel(scale2, dataModel, processedData, series, existingFilters) {
  const xValues = dataModel.resolveKeysById(series, "xValue", processedData);
  const isStacked = dataModel.hasColumnById(series, "yValue-start");
  const yStartValues = isStacked ? dataModel.resolveColumnById(series, "yValue-start", processedData) : void 0;
  const yEndValues = isStacked ? dataModel.resolveColumnById(series, "yValue-end", processedData) : dataModel.resolveColumnById(series, "yValue-raw", processedData);
  const domainInput = dataModel.getDomain(series, "xValue", "key", processedData);
  const xNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "xValue", processedData);
  const yNeedsValueOf = dataModel.resolveColumnNeedsValueOf(
    series,
    isStacked ? "yValue-end" : "yValue-raw",
    processedData
  );
  if (existingFilters) {
    const [d0, d1] = aggregationDomain(scale2, domainInput);
    return computeBarAggregation([d0, d1], xValues, yStartValues, yEndValues, {
      smallestKeyInterval: processedData.reduced?.smallestKeyInterval,
      xNeedsValueOf,
      yNeedsValueOf,
      existingFilters
    });
  }
  return memoizedAggregateBarData(
    scale2,
    xValues,
    yStartValues,
    yEndValues,
    domainInput,
    processedData.reduced?.smallestKeyInterval,
    xNeedsValueOf,
    yNeedsValueOf
  );
}
function aggregateBarDataFromDataModelPartial(scale2, dataModel, processedData, series, targetRange, existingFilters) {
  const xValues = dataModel.resolveKeysById(series, "xValue", processedData);
  const isStacked = dataModel.hasColumnById(series, "yValue-start");
  const yStartValues = isStacked ? dataModel.resolveColumnById(series, "yValue-start", processedData) : void 0;
  const yEndValues = isStacked ? dataModel.resolveColumnById(series, "yValue-end", processedData) : dataModel.resolveColumnById(series, "yValue-raw", processedData);
  const domainInput = dataModel.getDomain(series, "xValue", "key", processedData);
  const xNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "xValue", processedData);
  const yNeedsValueOf = dataModel.resolveColumnNeedsValueOf(
    series,
    isStacked ? "yValue-end" : "yValue-raw",
    processedData
  );
  const [d0, d1] = aggregationDomain(scale2, domainInput);
  return computeBarAggregationPartial([d0, d1], xValues, yStartValues, yEndValues, {
    smallestKeyInterval: processedData.reduced?.smallestKeyInterval,
    xNeedsValueOf,
    yNeedsValueOf,
    targetRange,
    existingFilters
  });
}

// packages/ag-charts-community/src/chart/series/cartesian/barSeriesProperties.ts
var BarSeriesLabel = class extends Label {
  constructor() {
    super(...arguments);
    this.placement = "inside-center";
    this.spacing = 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesLabel.prototype, "placement", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesLabel.prototype, "spacing", 2);
var BarSeriesProperties = class extends AbstractBarSeriesProperties {
  constructor() {
    super(...arguments);
    this.fill = "#c16068";
    this.fillOpacity = 1;
    this.stroke = "#874349";
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.cornerRadius = 0;
    this.crisp = void 0;
    this.shadow = new DropShadow();
    this.label = new BarSeriesLabel();
    this.tooltip = makeSeriesTooltip();
    this.sparklineMode = false;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "xKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "xName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "yKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "yName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "yFilterKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "stackGroup", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "normalizedTo", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "crisp", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "styler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "itemStyler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "simpleItemStyler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "shadow", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "tooltip", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BarSeriesProperties.prototype, "sparklineMode", 2);

// packages/ag-charts-community/src/chart/series/cartesian/barSeries.ts
var BarSeries = class extends AbstractBarSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      propertyKeys: DEFAULT_CARTESIAN_DIRECTION_KEYS,
      propertyNames: DEFAULT_CARTESIAN_DIRECTION_NAMES,
      categoryKey: "xValue",
      pickModes: [
        2 /* AXIS_ALIGNED */,
        // Only used in sparklineMode
        1 /* NEAREST_NODE */,
        0 /* EXACT_SHAPE_MATCH */
      ],
      pathsPerSeries: [],
      datumSelectionGarbageCollection: false,
      animationAlwaysUpdateSelections: true,
      animationResetFns: {
        datum: resetBarSelectionsFn,
        label: resetLabelFn
      }
    });
    this.properties = new BarSeriesProperties();
    this.connectsToYAxis = true;
    this.aggregationManager = new AggregationManager();
    this.phantomGroup = this.contentGroup.appendChild(new Group({ name: "phantom", zIndex: -1 }));
    this.phantomSelection = Selection.select(
      this.phantomGroup,
      () => this.nodeFactory(),
      false
    );
    this.phantomHighlightGroup = this.highlightGroup.appendChild(
      new Group({ name: `${this.internalId}-highlight-node` })
    );
    this.phantomHighlightSelection = Selection.select(
      this.phantomHighlightGroup,
      () => this.nodeFactory(),
      false
    );
    this.phantomGroup.opacity = 0.2;
    this.phantomHighlightGroup.opacity = 0.2;
  }
  get pickModeAxis() {
    return this.properties.sparklineMode ? "main" : void 0;
  }
  crossFilteringEnabled() {
    return this.properties.yFilterKey != null && (this.seriesGrouping == null || this.seriesGrouping.stackIndex === 0);
  }
  async processData(dataController) {
    if (!this.data)
      return;
    const { xKey, yKey, yFilterKey, normalizedTo } = this.properties;
    const { seriesGrouping: { groupIndex = this.id } = {}, data } = this;
    const stackCount = this.seriesGrouping?.stackCount ?? 0;
    const stacked = stackCount > 1 || normalizedTo != null;
    const grouped = stacked;
    const animationEnabled = !this.ctx.animationManager.isSkipped();
    const xScale = this.getCategoryAxis()?.scale;
    const yScale = this.getValueAxis()?.scale;
    const { isContinuousX, xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale });
    const stackGroupName = `bar-stack-${groupIndex}-yValues`;
    const stackGroupTrailingName = `${stackGroupName}-trailing`;
    const visibleProps = this.visible ? {} : { forceValue: 0 };
    const allowNullKey = this.properties.allowNullKeys ?? false;
    const props = [
      keyProperty(xKey, xScaleType, { id: "xValue", allowNullKey }),
      valueProperty(yKey, yScaleType, { id: `yValue-raw`, invalidValue: null, ...visibleProps })
    ];
    if (this.crossFilteringEnabled()) {
      props.push(
        valueProperty(yFilterKey, yScaleType, {
          id: `yFilterValue`,
          invalidValue: null,
          ...visibleProps
        })
      );
    }
    if (stacked) {
      props.push(
        ...groupAccumulativeValueProperty(
          yKey,
          "normal",
          {
            id: `yValue-end`,
            rangeId: `yValue-range`,
            invalidValue: null,
            missingValue: 0,
            groupId: stackGroupName,
            separateNegative: true,
            ...visibleProps
          },
          yScaleType
        ),
        ...groupAccumulativeValueProperty(
          yKey,
          "trailing",
          {
            id: `yValue-start`,
            invalidValue: null,
            missingValue: 0,
            groupId: stackGroupTrailingName,
            separateNegative: true,
            ...visibleProps
          },
          yScaleType
        )
      );
    }
    if (isContinuousX) {
      props.push(SMALLEST_KEY_INTERVAL, LARGEST_KEY_INTERVAL);
    }
    if (isFiniteNumber(normalizedTo)) {
      props.push(normaliseGroupTo([stackGroupName, stackGroupTrailingName], Math.abs(normalizedTo)));
    }
    if (this.needsDataModelDiff() && this.processedData) {
      props.push(diff(this.id, this.processedData));
    }
    if (animationEnabled || !grouped) {
      props.push(animationValidation());
    }
    const { dataModel, processedData } = await this.requestDataModel(dataController, data, {
      props,
      groupByKeys: grouped,
      groupByData: !grouped
    });
    this.aggregateData(dataModel, processedData);
    this.smallestDataInterval = processedData.reduced?.smallestKeyInterval;
    this.largestDataInterval = processedData.reduced?.largestKeyInterval;
    this.animationState.transition("updateData");
  }
  yCumulativeKey(dataModel) {
    return dataModel.hasColumnById(this, `yValue-end`) ? "yValue-end" : "yValue-raw";
  }
  getSeriesDomain(direction) {
    const { processedData, dataModel } = this;
    if (dataModel == null || processedData == null)
      return { domain: [] };
    if (direction === this.getCategoryDirection()) {
      const keyDef = dataModel.resolveProcessedDataDefById(this, `xValue`);
      const keys = dataModel.getDomain(this, `xValue`, "key", processedData);
      if (keyDef?.def.type === "key" && keyDef.def.valueType === "category") {
        return keys;
      }
      return { domain: this.padBandExtent(keys.domain) };
    }
    const yKey = this.yCumulativeKey(dataModel);
    let yExtent = this.domainForClippedRange(direction, [yKey], "xValue");
    const yFilterExtent = this.crossFilteringEnabled() ? dataModel.getDomain(this, `yFilterValue`, "value", processedData).domain : void 0;
    if (yFilterExtent != null) {
      yExtent = [Math.min(yExtent[0], yFilterExtent[0]), Math.max(yExtent[1], yFilterExtent[1])];
    }
    const yAxis = this.getValueAxis();
    if (yAxis instanceof NumberAxis && !(yAxis instanceof LogAxis)) {
      const fixedYExtent = Number.isFinite(yExtent[1] - yExtent[0]) ? [Math.min(0, yExtent[0]), Math.max(0, yExtent[1])] : [];
      return { domain: fixNumericExtent(fixedYExtent) };
    } else {
      return { domain: fixNumericExtent(yExtent) };
    }
  }
  getSeriesRange(direction, visibleRange) {
    const selfDirection = this.properties.direction === "horizontal" ? "x" /* X */ : "y" /* Y */;
    if (selfDirection !== direction)
      return [];
    const yKey = this.yCumulativeKey(this.dataModel);
    const [y0, y1] = this.domainForVisibleRange("y" /* Y */, [yKey], "xValue", visibleRange);
    return [Math.min(y0, 0), Math.max(y1, 0)];
  }
  getZoomRangeFittingItems(xVisibleRange, yVisibleRange, minVisibleItems) {
    const yKey = this.yCumulativeKey(this.dataModel);
    return this.zoomFittingVisibleItems("xValue", [yKey], xVisibleRange, yVisibleRange, minVisibleItems);
  }
  getVisibleItems(xVisibleRange, yVisibleRange, minVisibleItems) {
    const yKey = this.yCumulativeKey(this.dataModel);
    return this.countVisibleItems("xValue", [yKey], xVisibleRange, yVisibleRange, minVisibleItems);
  }
  aggregateData(dataModel, processedData) {
    this.aggregationManager.markStale(processedData.input.count);
    if (processedDataIsAnimatable(processedData))
      return;
    const xAxis = this.axes["x" /* X */];
    if (xAxis == null)
      return;
    const targetRange = this.estimateTargetRange();
    this.aggregationManager.aggregate({
      computePartial: (existingFilters) => aggregateBarDataFromDataModelPartial(
        xAxis.scale.type,
        dataModel,
        processedData,
        this,
        targetRange,
        existingFilters
      ),
      computeFull: (existingFilters) => aggregateBarDataFromDataModel(xAxis.scale.type, dataModel, processedData, this, existingFilters),
      targetRange
    });
    const filters = this.aggregationManager.filters;
    if (filters && filters.length > 0) {
      debugMetrics_exports.record(
        `${this.type}:aggregation`,
        filters.map((f) => f.maxRange)
      );
    }
  }
  estimateTargetRange() {
    const xAxis = this.axes["x" /* X */];
    if (xAxis?.scale?.range) {
      const [r0, r1] = xAxis.scale.range;
      return Math.abs(r1 - r0);
    }
    return this.ctx.scene?.canvas?.width ?? 800;
  }
  /**
   * Creates shared context for node datum creation/update operations.
   * This context is instantiated once and reused across all datum operations
   * to minimize memory allocations. Only caches values that are expensive to
   * compute - cheap property lookups use `this` directly.
   */
  createNodeDatumContext(xAxis, yAxis) {
    const { dataModel, processedData } = this;
    if (!dataModel || !processedData)
      return void 0;
    const rawData = processedData.dataSources?.get(this.id);
    if (rawData == null)
      return void 0;
    const xScale = xAxis.scale;
    const yScale = yAxis.scale;
    const range3 = Math.abs(xScale.range[1] - xScale.range[0]);
    this.aggregationManager.ensureLevelForRange(range3);
    const dataAggregationFilter = this.aggregationManager.getFilterForRange(range3);
    const isStacked = dataModel.hasColumnById(this, `yValue-start`);
    const { label } = this.properties;
    const canIncrementallyUpdate = this.canIncrementallyUpdateNodes(dataAggregationFilter != null);
    const { groupOffset, barOffset, barWidth } = this.getBarDimensions();
    return {
      dataSource: rawData,
      rawData: rawData.data,
      xValues: dataModel.resolveKeysById(this, `xValue`, processedData),
      yRawValues: dataModel.resolveColumnById(this, `yValue-raw`, processedData),
      yFilterValues: this.crossFilteringEnabled() ? dataModel.resolveColumnById(this, `yFilterValue`, processedData) : void 0,
      yStartValues: isStacked ? dataModel.resolveColumnById(this, `yValue-start`, processedData) : void 0,
      yEndValues: isStacked ? dataModel.resolveColumnById(this, `yValue-end`, processedData) : void 0,
      xScale,
      yScale,
      xAxis,
      yAxis,
      groupOffset,
      barOffset,
      barWidth,
      range: range3,
      yReversed: yAxis.isReversed(),
      bboxBottom: yScale.convert(0),
      labelSpacing: label.spacing + (typeof label.padding === "number" ? label.padding : 0),
      crisp: dataAggregationFilter == null && (this.properties.crisp ?? checkCrisp(xAxis?.scale, xAxis?.visibleRange, this.smallestDataInterval, this.largestDataInterval)),
      isStacked,
      animationEnabled: !this.ctx.animationManager.isSkipped(),
      dataAggregationFilter,
      canIncrementallyUpdate,
      phantomNodes: canIncrementallyUpdate ? this.contextNodeData.phantomNodeData ?? [] : [],
      nodes: canIncrementallyUpdate ? this.contextNodeData.nodeData : [],
      labels: canIncrementallyUpdate ? this.contextNodeData.labelData : [],
      nodeIndex: 0,
      phantomIndex: 0,
      barAlongX: this.getBarDirection() === "x" /* X */,
      shouldFlipXY: this.shouldFlipXY(),
      xKey: this.properties.xKey,
      yKey: this.properties.yKey,
      xName: this.properties.xName,
      yName: this.properties.yName,
      legendItemName: this.properties.legendItemName,
      label,
      yDomain: this.getSeriesDomain("y" /* Y */).domain
    };
  }
  /**
   * Computes the x position for a datum at the given index.
   */
  computeXPosition(ctx, datumIndex) {
    const x = ctx.xScale.convert(ctx.xValues[datumIndex]);
    if (!Number.isFinite(x))
      return Number.NaN;
    return x + ctx.groupOffset + ctx.barOffset;
  }
  prepareNodeDatumState(ctx, nodeDatumScratch, datumIndex, yStart, yEnd) {
    if (!Number.isFinite(yEnd)) {
      return void 0;
    }
    const xValue = ctx.xValues[datumIndex];
    if (xValue === void 0 && !this.properties.allowNullKeys) {
      return void 0;
    }
    const datum = ctx.dataSource?.data[datumIndex];
    const yRawValue = ctx.yRawValues[datumIndex];
    const yFilterValue = ctx.yFilterValues == null ? void 0 : Number(ctx.yFilterValues[datumIndex]);
    if (yFilterValue != null && !Number.isFinite(yFilterValue)) {
      return void 0;
    }
    const labelText = ctx.label.enabled && yRawValue != null ? this.getLabelText(
      yFilterValue ?? yRawValue,
      datum,
      ctx.yKey,
      "y",
      ctx.yDomain,
      ctx.label,
      {
        datum,
        value: yFilterValue ?? yRawValue,
        xKey: ctx.xKey,
        yKey: ctx.yKey,
        xName: ctx.xName,
        yName: ctx.yName,
        legendItemName: ctx.legendItemName
      }
    ) : void 0;
    const isPositive = yRawValue >= 0 && !Object.is(yRawValue, -0);
    nodeDatumScratch.datum = datum;
    nodeDatumScratch.xValue = xValue;
    nodeDatumScratch.yRawValue = yRawValue;
    nodeDatumScratch.yFilterValue = yFilterValue;
    nodeDatumScratch.labelText = labelText;
    nodeDatumScratch.inset = yFilterValue != null && yFilterValue > yRawValue;
    nodeDatumScratch.isPositive = isPositive;
    nodeDatumScratch.precomputedBottomY = yFilterValue == null ? void 0 : ctx.yScale.convert(yStart);
    nodeDatumScratch.precomputedIsUpward = yFilterValue == null ? void 0 : isPositive !== ctx.yReversed;
    return nodeDatumScratch;
  }
  /**
   * Creates a skeleton BarNodeDatum with minimal required fields.
   * The node will be populated by updateNodeDatum.
   */
  createSkeletonNodeDatum(ctx, params, phantom) {
    const scratch = params.nodeDatumScratch;
    return {
      series: this,
      datum: scratch.datum,
      datumIndex: params.datumIndex,
      cumulativeValue: 0,
      // Will be updated by updateNodeDatum
      phantom,
      xValue: scratch.xValue ?? "",
      yValue: 0,
      // Will be updated by updateNodeDatum
      yKey: ctx.yKey,
      xKey: ctx.xKey,
      capDefaults: {
        lengthRatioMultiplier: 0,
        // Will be updated by updateNodeDatum
        lengthMax: 0
        // Will be updated by updateNodeDatum
      },
      x: 0,
      // Will be updated by updateNodeDatum
      y: 0,
      // Will be updated by updateNodeDatum
      width: 0,
      // Will be updated by updateNodeDatum
      height: 0,
      // Will be updated by updateNodeDatum
      midPoint: { x: 0, y: 0 },
      // Required - updated in place by updateNodeDatum
      opacity: params.opacity,
      featherRatio: params.featherRatio,
      topLeftCornerRadius: false,
      // Will be updated by updateNodeDatum
      topRightCornerRadius: false,
      // Will be updated by updateNodeDatum
      bottomRightCornerRadius: false,
      // Will be updated by updateNodeDatum
      bottomLeftCornerRadius: false,
      // Will be updated by updateNodeDatum
      clipBBox: void 0,
      // Will be created/updated by updateNodeDatum
      crisp: ctx.crisp,
      label: void 0,
      // Will be created/updated by updateNodeDatum
      missing: false,
      // Will be updated by updateNodeDatum
      focusable: !phantom
    };
  }
  /**
   * Creates a BarNodeDatum (and optionally a phantom node) for a single data point.
   * Creates skeleton nodes and uses updateNodeDatum to populate them with calculated values.
   */
  createNodeDatum(ctx, params) {
    const prepared = this.prepareNodeDatumState(
      ctx,
      params.nodeDatumScratch,
      params.datumIndex,
      params.yStart,
      params.yEnd
    );
    if (!prepared) {
      return { nodeData: void 0, phantomNodeData: void 0 };
    }
    const nodeData = this.createSkeletonNodeDatum(ctx, params, false);
    this.updateNodeDatum(ctx, nodeData, params, prepared);
    let phantomNodeData;
    if (prepared.yFilterValue != null) {
      phantomNodeData = this.createSkeletonNodeDatum(ctx, params, true);
      this.updateNodeDatum(ctx, phantomNodeData, params);
    }
    return { nodeData, phantomNodeData };
  }
  /**
   * Updates an existing BarNodeDatum in-place for value-only changes.
   * This is more efficient than recreating the entire node when only data values change
   * but the structure (insertions/removals) remains the same.
   */
  updateNodeDatum(ctx, node, params, prepared) {
    prepared ?? (prepared = this.prepareNodeDatumState(
      ctx,
      params.nodeDatumScratch,
      params.datumIndex,
      params.yStart,
      params.yEnd
    ));
    if (!prepared) {
      return;
    }
    const mutableNode = node;
    const phantom = node.phantom;
    const prevY = params.yStart;
    const yValue = phantom ? prepared.yFilterValue : prepared.yFilterValue ?? prepared.yRawValue;
    const cumulativeValue = phantom ? prepared.yFilterValue : prepared.yFilterValue ?? params.yEnd;
    const nodeLabelText = phantom ? void 0 : prepared.labelText;
    let currY;
    if (phantom) {
      currY = params.yEnd;
    } else if (prepared.yFilterValue == null) {
      currY = params.yEnd;
    } else {
      currY = params.yStart + prepared.yFilterValue;
    }
    let nodeYRange;
    if (phantom) {
      nodeYRange = params.yRange;
    } else {
      nodeYRange = Math.max(params.yStart + (prepared.yFilterValue ?? -Infinity), params.yRange);
    }
    let crossScale;
    if (phantom) {
      crossScale = void 0;
    } else if (prepared.inset) {
      crossScale = 0.6;
    } else {
      crossScale = void 0;
    }
    const isUpward = prepared.precomputedIsUpward ?? prepared.isPositive !== ctx.yReversed;
    const y = ctx.yScale.convert(currY);
    const bottomY = prepared.precomputedBottomY ?? ctx.yScale.convert(prevY);
    const bboxHeight = ctx.yScale.convert(nodeYRange);
    const xOffset = params.width * 0.5 * (1 - (crossScale ?? 1));
    const rectX = ctx.barAlongX ? Math.min(y, bottomY) : params.x + xOffset;
    const rectY = ctx.barAlongX ? params.x + xOffset : Math.min(y, bottomY);
    const rectWidth = ctx.barAlongX ? Math.abs(bottomY - y) : params.width * (crossScale ?? 1);
    const rectHeight = ctx.barAlongX ? params.width * (crossScale ?? 1) : Math.abs(bottomY - y);
    const barRectX = ctx.barAlongX ? Math.min(ctx.bboxBottom, bboxHeight) : params.x + xOffset;
    const barRectY = ctx.barAlongX ? params.x + xOffset : Math.min(ctx.bboxBottom, bboxHeight);
    const barRectWidth = ctx.barAlongX ? Math.abs(ctx.bboxBottom - bboxHeight) : params.width * (crossScale ?? 1);
    const barRectHeight = ctx.barAlongX ? params.width * (crossScale ?? 1) : Math.abs(ctx.bboxBottom - bboxHeight);
    mutableNode.datum = prepared.datum;
    mutableNode.datumIndex = params.datumIndex;
    mutableNode.cumulativeValue = cumulativeValue;
    mutableNode.xValue = prepared.xValue;
    mutableNode.yValue = yValue;
    mutableNode.x = barRectX;
    mutableNode.y = barRectY;
    mutableNode.width = barRectWidth;
    mutableNode.height = barRectHeight;
    const mutableMidPoint = mutableNode.midPoint;
    mutableMidPoint.x = rectX + rectWidth / 2;
    mutableMidPoint.y = rectY + rectHeight / 2;
    const lengthRatioMultiplier = ctx.shouldFlipXY ? rectHeight : rectWidth;
    mutableNode.capDefaults.lengthRatioMultiplier = lengthRatioMultiplier;
    mutableNode.capDefaults.lengthMax = lengthRatioMultiplier;
    mutableNode.opacity = params.opacity;
    mutableNode.featherRatio = params.featherRatio;
    mutableNode.topLeftCornerRadius = ctx.barAlongX !== isUpward;
    mutableNode.topRightCornerRadius = isUpward;
    mutableNode.bottomRightCornerRadius = ctx.barAlongX === isUpward;
    mutableNode.bottomLeftCornerRadius = !isUpward;
    const existingClipBBox = mutableNode.clipBBox;
    if (existingClipBBox) {
      existingClipBBox.x = rectX;
      existingClipBBox.y = rectY;
      existingClipBBox.width = rectWidth;
      existingClipBBox.height = rectHeight;
    } else {
      mutableNode.clipBBox = new BBox(rectX, rectY, rectWidth, rectHeight);
    }
    mutableNode.crisp = ctx.crisp;
    if (nodeLabelText == null) {
      mutableNode.label = void 0;
    } else {
      const labelPlacement = adjustLabelPlacement({
        isUpward,
        isVertical: !ctx.barAlongX,
        placement: ctx.label.placement,
        spacing: ctx.labelSpacing,
        rect: { x: rectX, y: rectY, width: rectWidth, height: rectHeight }
      });
      const existingLabel = mutableNode.label;
      if (existingLabel) {
        existingLabel.text = nodeLabelText;
        existingLabel.x = labelPlacement.x;
        existingLabel.y = labelPlacement.y;
        existingLabel.textAlign = labelPlacement.textAlign;
        existingLabel.textBaseline = labelPlacement.textBaseline;
      } else {
        mutableNode.label = {
          text: nodeLabelText,
          ...labelPlacement
        };
      }
    }
    mutableNode.missing = isTooltipValueMissing(yValue);
  }
  /**
   * Creates node data using aggregation filters for large datasets.
   */
  createNodeDataWithAggregation(ctx, xPosition, nodeDatumParamsScratch) {
    const sign = ctx.yReversed ? -1 : 1;
    for (let p = 0; p < 2; p += 1) {
      const positive = p === 0;
      const indices = positive ? ctx.dataAggregationFilter.positiveIndices : ctx.dataAggregationFilter.negativeIndices;
      const indexData = positive ? ctx.dataAggregationFilter.positiveIndexData : ctx.dataAggregationFilter.negativeIndexData;
      const Y_MIN = positive ? AGGREGATION_INDEX_Y_MIN : AGGREGATION_INDEX_Y_MAX;
      const Y_MAX = positive ? AGGREGATION_INDEX_Y_MAX : AGGREGATION_INDEX_Y_MIN;
      const visibleRange = this.visibleRangeIndices("xValue", ctx.xAxis.range, indices);
      const start2 = visibleRange[0];
      const end3 = visibleRange[1];
      for (let i = start2; i < end3; i += 1) {
        const aggIndex = i * AGGREGATION_SPAN;
        const xMinIndex = indexData[aggIndex + AGGREGATION_INDEX_X_MIN];
        const xMaxIndex = indexData[aggIndex + AGGREGATION_INDEX_X_MAX];
        const yMinIndex = indexData[aggIndex + Y_MIN];
        const yMaxIndex = indexData[aggIndex + Y_MAX];
        if (xMinIndex === AGGREGATION_INDEX_UNSET)
          continue;
        if (ctx.xValues[yMaxIndex] == null || ctx.xValues[yMinIndex] == null)
          continue;
        const x = xPosition(Math.trunc((xMinIndex + xMaxIndex) / 2));
        const width2 = Math.abs(xPosition(xMaxIndex) - xPosition(xMinIndex)) + ctx.barWidth;
        if (x - width2 < 0 || x > ctx.range)
          continue;
        const bandCount = Math.abs(xMaxIndex - xMinIndex) + 1;
        const opacity = BandScale.is(ctx.xScale) ? Math.min(ctx.xScale.bandwidth * Math.max(bandCount - 1, 1) / (ctx.xScale.step * bandCount), 1) : 1;
        nodeDatumParamsScratch.datumIndex = yMaxIndex;
        nodeDatumParamsScratch.x = x;
        nodeDatumParamsScratch.width = width2;
        nodeDatumParamsScratch.opacity = opacity;
        if (ctx.isStacked) {
          nodeDatumParamsScratch.yStart = Number(ctx.yStartValues[yMinIndex]);
          nodeDatumParamsScratch.yEnd = Number(ctx.yEndValues[yMaxIndex]);
          nodeDatumParamsScratch.featherRatio = 0;
        } else {
          const yEndMax = Number(ctx.yRawValues[yMaxIndex]);
          const yEndMin = Number(ctx.yRawValues[yMinIndex]);
          nodeDatumParamsScratch.yStart = 0;
          nodeDatumParamsScratch.yEnd = yEndMax;
          nodeDatumParamsScratch.featherRatio = (positive ? 1 : -1) * sign * (1 - yEndMin / yEndMax);
        }
        nodeDatumParamsScratch.yRange = nodeDatumParamsScratch.yEnd;
        this.upsertNodeDatum(ctx, nodeDatumParamsScratch);
      }
    }
  }
  /**
   * Creates node data for grouped data processing.
   */
  createNodeDataGrouped(ctx, xPosition, nodeDatumParamsScratch) {
    const processedData = this.processedData;
    const invalidData = processedData.invalidData?.get(this.id);
    const width2 = ctx.barWidth;
    const yRangeIndex = ctx.isStacked ? this.dataModel.resolveProcessedDataIndexById(this, `yValue-range`) : -1;
    const columnIndex = processedData.columnScopes.findIndex((s) => s.has(this.id));
    const groups = processedData.groups;
    const visibleRange = visibleRangeIndices(1, groups.length, ctx.xAxis.range, (groupIndex) => {
      const group = groups[groupIndex];
      const xValue = group.keys[0];
      return this.xCoordinateRange(xValue);
    });
    const start2 = visibleRange[0];
    const end3 = visibleRange[1];
    for (let groupIndex = start2; groupIndex < end3; groupIndex += 1) {
      const group = groups[groupIndex];
      const aggregation = group.aggregation;
      const datumIndices = group.datumIndices[columnIndex];
      if (datumIndices == null)
        continue;
      for (const relativeDatumIndex of datumIndices) {
        const datumIndex = groupIndex + relativeDatumIndex;
        const x = xPosition(datumIndex);
        if (invalidData?.[datumIndex] === true)
          continue;
        const yRawValue = ctx.yRawValues[datumIndex];
        if (yRawValue == null)
          continue;
        const isPositive = yRawValue >= 0 && !Object.is(yRawValue, -0);
        const yStart = ctx.isStacked ? Number(ctx.yStartValues?.[datumIndex]) : 0;
        const yEnd = ctx.isStacked ? Number(ctx.yEndValues?.[datumIndex]) : yRawValue;
        let yRange = yEnd;
        if (ctx.isStacked) {
          yRange = aggregation[yRangeIndex][isPositive ? 1 : 0];
        }
        nodeDatumParamsScratch.datumIndex = datumIndex;
        nodeDatumParamsScratch.x = x;
        nodeDatumParamsScratch.width = width2;
        nodeDatumParamsScratch.yStart = yStart;
        nodeDatumParamsScratch.yEnd = yEnd;
        nodeDatumParamsScratch.yRange = yRange;
        nodeDatumParamsScratch.featherRatio = 0;
        nodeDatumParamsScratch.opacity = 1;
        this.upsertNodeDatum(ctx, nodeDatumParamsScratch);
      }
    }
  }
  /**
   * Creates node data for simple (non-grouped) data processing.
   */
  createNodeDataSimple(ctx, xPosition, nodeDatumParamsScratch) {
    const invalidData = this.processedData.invalidData?.get(this.id);
    const width2 = ctx.barWidth;
    const visibleRange = this.visibleRangeIndices("xValue", ctx.xAxis.range);
    let start2 = visibleRange[0];
    let end3 = visibleRange[1];
    if (this.processedData.input.count < 1e3) {
      start2 = 0;
      end3 = this.processedData.input.count;
    }
    for (let datumIndex = start2; datumIndex < end3; datumIndex += 1) {
      if (invalidData?.[datumIndex] === true)
        continue;
      const yRawValue = ctx.yRawValues[datumIndex];
      if (yRawValue == null)
        continue;
      const x = xPosition(datumIndex);
      const yEnd = Number(yRawValue);
      nodeDatumParamsScratch.datumIndex = datumIndex;
      nodeDatumParamsScratch.x = x;
      nodeDatumParamsScratch.width = width2;
      nodeDatumParamsScratch.yStart = 0;
      nodeDatumParamsScratch.yEnd = yEnd;
      nodeDatumParamsScratch.yRange = yEnd;
      nodeDatumParamsScratch.featherRatio = 0;
      nodeDatumParamsScratch.opacity = 1;
      this.upsertNodeDatum(ctx, nodeDatumParamsScratch);
    }
  }
  /**
   * Handles node creation/update - reuses existing nodes when possible for incremental updates.
   * This method decides whether to update existing nodes in-place or create new ones.
   */
  upsertNodeDatum(ctx, params) {
    const canReuseNode = ctx.canIncrementallyUpdate && ctx.nodeIndex < ctx.nodes.length;
    const needsPhantom = ctx.yFilterValues != null;
    const canReusePhantom = needsPhantom && ctx.canIncrementallyUpdate && ctx.phantomIndex < ctx.phantomNodes.length;
    let nodeData;
    let phantomNodeData;
    if (canReuseNode) {
      nodeData = ctx.nodes[ctx.nodeIndex];
      this.updateNodeDatum(ctx, nodeData, params);
      if (ctx.nodeIndex >= ctx.labels.length) {
        ctx.labels.push(nodeData);
      }
    } else {
      const result = this.createNodeDatum(ctx, params);
      if (result.nodeData) {
        ctx.nodes.push(result.nodeData);
        ctx.labels.push(result.nodeData);
      }
      phantomNodeData = result.phantomNodeData;
    }
    ctx.nodeIndex++;
    if (!needsPhantom) {
      return { nodeData: ctx.nodes[ctx.nodeIndex] };
    }
    if (canReusePhantom) {
      phantomNodeData = ctx.phantomNodes[ctx.phantomIndex];
      this.updateNodeDatum(ctx, phantomNodeData, params);
    } else if (phantomNodeData) {
      ctx.phantomNodes.push(phantomNodeData);
    } else {
      const result = this.createNodeDatum(ctx, params);
      if (result.phantomNodeData) {
        ctx.phantomNodes.push(result.phantomNodeData);
      }
    }
    ctx.phantomIndex++;
    return { nodeData, phantomNodeData };
  }
  // ============================================================================
  // Template Method Hooks (createNodeData flow)
  // ============================================================================
  /**
   * Populates node data by selecting the appropriate strategy based on data type.
   * Creates scratch objects and delegates to strategy-specific methods.
   */
  populateNodeData(ctx) {
    const xPosition = (index) => this.computeXPosition(ctx, index);
    const nodeDatumParamsScratch = {
      nodeDatumScratch: {
        datum: void 0,
        xValue: void 0,
        yRawValue: 0,
        yFilterValue: void 0,
        labelText: void 0,
        inset: false,
        isPositive: false,
        precomputedBottomY: void 0,
        precomputedIsUpward: void 0
      },
      datumIndex: 0,
      x: 0,
      width: 0,
      yStart: 0,
      yEnd: 0,
      yRange: 0,
      featherRatio: 0,
      opacity: 1
    };
    if (ctx.dataAggregationFilter != null) {
      this.createNodeDataWithAggregation(ctx, xPosition, nodeDatumParamsScratch);
    } else if (this.processedData.type === "grouped") {
      this.createNodeDataGrouped(ctx, xPosition, nodeDatumParamsScratch);
    } else {
      this.createNodeDataSimple(ctx, xPosition, nodeDatumParamsScratch);
    }
  }
  /**
   * Creates the initial result context object.
   * Note: segments is undefined here - it's computed in assembleResult.
   */
  initializeResult(ctx) {
    return {
      itemId: this.properties.yKey,
      nodeData: ctx.nodes,
      phantomNodeData: ctx.phantomNodes,
      labelData: ctx.labels,
      scales: this.calculateScaling(),
      visible: this.visible || ctx.animationEnabled,
      groupScale: this.getScaling(this.ctx.seriesStateManager.getGroupScale(this)),
      styles: getItemStyles(this.getItemStyle.bind(this)),
      segments: void 0
    };
  }
  /**
   * Finalizes node data by trimming incremental arrays.
   * BarSeries has multiple arrays: nodes, phantomNodes, and labels.
   */
  finalizeNodeData(ctx) {
    if (ctx.canIncrementallyUpdate) {
      this.trimIncrementalNodeArray(ctx.nodes, ctx.nodeIndex);
      this.trimIncrementalNodeArray(ctx.phantomNodes, ctx.phantomIndex);
      this.trimIncrementalNodeArray(ctx.labels, ctx.nodes.length);
    }
  }
  /**
   * Assembles the final result by computing segments.
   */
  assembleResult(ctx, result) {
    result.segments = calculateSegments(
      this.properties.segmentation,
      ctx.xAxis,
      ctx.yAxis,
      this.chart.seriesRect,
      this.ctx.scene
    );
    return result;
  }
  nodeFactory() {
    return new BarShape();
  }
  updateSeriesSelections() {
    super.updateSeriesSelections();
    this.phantomSelection = this.updateDatumSelection({
      nodeData: this.contextNodeData?.phantomNodeData ?? [],
      datumSelection: this.phantomSelection
    });
  }
  updateHighlightSelectionItem(opts) {
    const out = super.updateHighlightSelectionItem(opts);
    const highlightedDatum = this.ctx.highlightManager?.getActiveHighlight();
    const seriesHighlighted = this.isSeriesHighlighted(highlightedDatum);
    const item = seriesHighlighted && highlightedDatum?.datum ? highlightedDatum : void 0;
    this.phantomHighlightSelection = this.updateDatumSelection({
      nodeData: item ? this.getHighlightData(this.contextNodeData?.phantomNodeData ?? [], item) ?? [] : [],
      datumSelection: this.phantomHighlightSelection
    });
    return out;
  }
  updateNodes(itemHighlighted, nodeRefresh) {
    super.updateNodes(itemHighlighted, nodeRefresh);
    this.updateDatumNodes({
      datumSelection: this.phantomSelection,
      isHighlight: false,
      drawingMode: "overlay"
    });
    this.updateDatumNodes({
      datumSelection: this.phantomHighlightSelection,
      isHighlight: true,
      drawingMode: "overlay"
    });
  }
  getHighlightData(nodeData, highlightedItem) {
    const highlightItem = nodeData.find((nodeDatum) => nodeDatum.datum === highlightedItem.datum);
    return highlightItem == null ? void 0 : [{ ...highlightItem }];
  }
  updateDatumSelection(opts) {
    if (!processedDataIsAnimatable(this.processedData)) {
      return opts.datumSelection.update(opts.nodeData);
    }
    return opts.datumSelection.update(opts.nodeData, void 0, this.getDatumId.bind(this));
  }
  makeStylerParams(highlightStateEnum) {
    const { id: seriesId } = this;
    const {
      cornerRadius,
      fill,
      fillOpacity,
      lineDash,
      lineDashOffset,
      stackGroup,
      stroke: stroke3,
      strokeOpacity,
      strokeWidth,
      xKey,
      yKey
    } = this.properties;
    const highlightState = toHighlightString(highlightStateEnum ?? 0 /* None */);
    return {
      cornerRadius,
      fill,
      fillOpacity,
      highlightState,
      lineDash,
      lineDashOffset,
      seriesId,
      stackGroup,
      stroke: stroke3,
      strokeOpacity,
      strokeWidth,
      xKey,
      yKey
    };
  }
  makeItemStylerParams(dataModel, processedData, datumIndex, xValue, isHighlight, style2) {
    const { id: seriesId } = this;
    const { xKey, yKey, stackGroup } = this.properties;
    const datum = processedData.dataSources.get(seriesId)?.data?.[datumIndex];
    const yValue = dataModel.resolveColumnById(this, `yValue-raw`, processedData)[datumIndex];
    const xDomain = dataModel.getDomain(this, `xValue`, "key", processedData).domain;
    const yDomain = dataModel.getDomain(this, this.yCumulativeKey(dataModel), "value", processedData).domain;
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const highlightStateString = this.getHighlightStateString(activeHighlight, isHighlight, datumIndex);
    const fill = this.filterItemStylerFillParams(style2.fill) ?? style2.fill;
    return {
      seriesId,
      ...datumStylerProperties(xValue, yValue, xKey, yKey, xDomain, yDomain),
      datum,
      xValue,
      yValue,
      stackGroup,
      highlightState: highlightStateString,
      ...style2,
      fill
    };
  }
  getStyle(ignoreStylerCallback, highlightState) {
    const {
      cornerRadius,
      fill,
      fillOpacity,
      lineDash,
      lineDashOffset,
      stroke: stroke3,
      strokeOpacity,
      strokeWidth,
      styler
    } = this.properties;
    let stylerResult = {};
    if (!ignoreStylerCallback && styler) {
      const stylerParams = this.makeStylerParams(highlightState);
      stylerResult = this.ctx.optionsGraphService.resolvePartial(
        ["series", `${this.declarationOrder}`],
        this.cachedCallWithContext(styler, stylerParams) ?? {},
        { pick: false }
      ) ?? {};
    }
    return {
      cornerRadius: stylerResult.cornerRadius ?? cornerRadius,
      fill: stylerResult.fill ?? fill,
      fillOpacity: stylerResult.fillOpacity ?? fillOpacity,
      lineDash: stylerResult.lineDash ?? lineDash,
      lineDashOffset: stylerResult.lineDashOffset ?? lineDashOffset,
      opacity: 1,
      stroke: stylerResult.stroke ?? stroke3,
      strokeOpacity: stylerResult.strokeOpacity ?? strokeOpacity,
      strokeWidth: stylerResult.strokeWidth ?? strokeWidth
    };
  }
  getItemStyle(datumIndex, isHighlight, highlightState) {
    const { properties, dataModel, processedData } = this;
    const { itemStyler, simpleItemStyler } = properties;
    const highlightStyle = this.getHighlightStyle(isHighlight, datumIndex, highlightState);
    if (simpleItemStyler && processedData != null && datumIndex != null) {
      const datum = processedData.dataSources.get(this.id)?.data?.[datumIndex];
      const overrides = simpleItemStyler(datum);
      return mergeDefaults(
        overrides,
        highlightStyle,
        this.getStyle(false, highlightState)
      );
    }
    let style2 = mergeDefaults(highlightStyle, this.getStyle(datumIndex === void 0, highlightState));
    if (itemStyler && dataModel != null && processedData != null && datumIndex != null) {
      const xValue = dataModel.resolveKeysById(this, `xValue`, processedData)[datumIndex];
      const overrides = this.cachedDatumCallback(
        createDatumId(this.getDatumId({ xValue, phantom: false }), isHighlight ? "highlight" : "node"),
        () => {
          const params = this.makeItemStylerParams(
            dataModel,
            processedData,
            datumIndex,
            xValue,
            isHighlight,
            style2
          );
          return this.ctx.optionsGraphService.resolvePartial(
            ["series", `${this.declarationOrder}`],
            this.callWithContext(itemStyler, params)
          );
        }
      );
      if (overrides) {
        style2 = mergeDefaults(overrides, style2);
      }
    }
    return style2;
  }
  updateDatumStyles(opts) {
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    const series = this;
    function applyDatumStyle(node, datum) {
      if (!opts.datumSelection.isGarbage(node)) {
        const highlightState = series.getHighlightState(highlightedDatum, opts.isHighlight, datum.datumIndex);
        datum.style = series.getItemStyle(datum.datumIndex, opts.isHighlight, highlightState);
      }
    }
    opts.datumSelection.each(applyDatumStyle);
  }
  updateDatumNodes(opts) {
    const { contextNodeData } = this;
    if (!contextNodeData) {
      return;
    }
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    const { shadow } = this.properties;
    const categoryAlongX = this.getCategoryDirection() === "x" /* X */;
    const fillBBox = this.getShapeFillBBox();
    const direction = this.getBarDirection();
    const { drawingMode, isHighlight } = opts;
    const series = this;
    const contextStyles = contextNodeData.styles;
    function updateDatumNode(rect2, datum) {
      const style2 = datum.style ?? contextStyles[series.getHighlightState(highlightedDatum, isHighlight, datum.datumIndex)];
      rect2.setStyleProperties(style2, fillBBox);
      const cornerRadius = style2.cornerRadius ?? 0;
      const visible = categoryAlongX ? (datum.clipBBox?.width ?? datum.width) > 0 : (datum.clipBBox?.height ?? datum.height) > 0;
      rect2.setStaticProperties(
        drawingMode,
        datum.topLeftCornerRadius ? cornerRadius : 0,
        datum.topRightCornerRadius ? cornerRadius : 0,
        datum.bottomRightCornerRadius ? cornerRadius : 0,
        datum.bottomLeftCornerRadius ? cornerRadius : 0,
        visible,
        datum.crisp,
        shadow,
        direction,
        datum.featherRatio
      );
    }
    opts.datumSelection.each(updateDatumNode);
  }
  updateLabelSelection(opts) {
    const data = this.isLabelEnabled() ? opts.labelData : [];
    return opts.labelSelection.update(data, (text2) => {
      text2.pointerEvents = 1 /* None */;
    });
  }
  updateLabelNodes(opts) {
    const { isHighlight = false } = opts;
    const params = {
      xKey: this.properties.xKey,
      xName: this.properties.xName ?? this.properties.xKey,
      yKey: this.properties.yKey,
      yName: this.properties.yName ?? this.properties.yKey,
      legendItemName: this.properties.legendItemName ?? this.properties.xName ?? this.properties.xKey
    };
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    opts.labelSelection.each((textNode, datum) => {
      textNode.fillOpacity = this.getHighlightStyle(isHighlight, datum?.datumIndex).opacity ?? 1;
      updateLabelNode(this, textNode, params, this.properties.label, datum.label, isHighlight, activeHighlight);
    });
  }
  getTooltipContent(datumIndex) {
    const { id: seriesId, dataModel, processedData, properties } = this;
    const { xKey, xName, yKey, yName, legendItemName, stackGroup, tooltip } = properties;
    const allowNullKeys = properties.allowNullKeys ?? false;
    const xAxis = this.getCategoryAxis();
    const yAxis = this.getValueAxis();
    if (!dataModel || !processedData || !xAxis || !yAxis)
      return;
    const datum = processedData.dataSources.get(this.id)?.data?.[datumIndex];
    const xValue = dataModel.resolveKeysById(this, `xValue`, processedData)[datumIndex];
    const yValue = dataModel.resolveColumnById(this, `yValue-raw`, processedData)[datumIndex];
    if (xValue === void 0 && !allowNullKeys)
      return;
    const format = this.getItemStyle(datumIndex, false);
    return this.formatTooltipWithContext(
      tooltip,
      {
        heading: this.getAxisValueText(xAxis, "tooltip", xValue, datum, xKey, legendItemName, allowNullKeys),
        symbol: this.legendItemSymbol(),
        data: [
          {
            label: yName,
            fallbackLabel: yKey,
            value: this.getAxisValueText(yAxis, "tooltip", yValue, datum, yKey, legendItemName),
            missing: isTooltipValueMissing(yValue)
          }
        ]
      },
      {
        seriesId,
        datum,
        title: yName,
        xKey,
        xName,
        yKey,
        yName,
        legendItemName,
        stackGroup,
        ...format,
        ...this.getModuleTooltipParams()
      }
    );
  }
  legendItemSymbol() {
    const { fill, stroke: stroke3, strokeWidth, fillOpacity, strokeOpacity, lineDash, lineDashOffset } = this.getStyle(
      false,
      0 /* None */
    );
    return {
      marker: {
        fill: fill ?? "rgba(0, 0, 0, 0)",
        stroke: stroke3 ?? "rgba(0, 0, 0, 0)",
        fillOpacity,
        strokeOpacity,
        strokeWidth,
        lineDash,
        lineDashOffset
      }
    };
  }
  getLegendData(legendType) {
    const { showInLegend } = this.properties;
    if (legendType !== "category") {
      return [];
    }
    const {
      id: seriesId,
      ctx: { legendManager },
      visible
    } = this;
    const { yKey: itemId, yName, legendItemName } = this.properties;
    return [
      {
        legendType: "category",
        id: seriesId,
        itemId,
        seriesId,
        enabled: visible && legendManager.getItemEnabled({ seriesId, itemId }),
        label: { text: legendItemName ?? yName ?? itemId },
        symbol: this.legendItemSymbol(),
        legendItemName,
        hideInLegend: !showInLegend
      }
    ];
  }
  resetDatumAnimation(data) {
    resetBarSelectionsDirect([data.datumSelection, this.phantomSelection]);
  }
  animateReadyHighlight(data) {
    resetBarSelectionsDirect([data, this.phantomHighlightSelection]);
  }
  animateEmptyUpdateReady({ datumSelection, labelSelection, annotationSelections }) {
    const { phantomSelection } = this;
    const fns = prepareBarAnimationFunctions(
      collapsedStartingBarPosition(this.isVertical(), this.axes, "normal"),
      "unknown"
    );
    fromToMotion(this.id, "nodes", this.ctx.animationManager, [datumSelection, phantomSelection], fns);
    seriesLabelFadeInAnimation(this, "labels", this.ctx.animationManager, labelSelection);
    seriesLabelFadeInAnimation(this, "annotations", this.ctx.animationManager, ...annotationSelections);
  }
  animateWaitingUpdateReady(data) {
    const { phantomSelection } = this;
    const { datumSelection, labelSelection, annotationSelections, contextData, previousContextData } = data;
    this.ctx.animationManager.stopByAnimationGroupId(this.id);
    const dataDiff = calculateDataDiff(
      this.id,
      datumSelection,
      this.getDatumId.bind(this),
      data.contextData,
      previousContextData,
      this.processedData,
      this.processedDataUpdated
    );
    const mode = previousContextData == null ? "fade" : "normal";
    const fns = prepareBarAnimationFunctions(
      collapsedStartingBarPosition(this.isVertical(), this.axes, mode),
      "added"
    );
    fromToMotion(
      this.id,
      "nodes",
      this.ctx.animationManager,
      [datumSelection, phantomSelection],
      fns,
      (_, datum) => this.getDatumId(datum),
      dataDiff
    );
    if (!dataDiff || dataDiff?.changed || !areScalingEqual(contextData.groupScale, previousContextData?.groupScale)) {
      seriesLabelFadeInAnimation(this, "labels", this.ctx.animationManager, labelSelection);
      seriesLabelFadeInAnimation(this, "annotations", this.ctx.animationManager, ...annotationSelections);
    }
  }
  getDatumId(datum) {
    return createDatumId(datum.xValue, datum.phantom);
  }
  isLabelEnabled() {
    return this.properties.label.enabled;
  }
  computeFocusBounds({ datumIndex }) {
    const datumBox = this.contextNodeData?.nodeData[datumIndex].clipBBox;
    return computeBarFocusBounds(this, datumBox);
  }
  hasItemStylers() {
    return this.properties.styler != null || this.properties.itemStyler != null || this.properties.simpleItemStyler != null || this.properties.label.itemStyler != null;
  }
};
BarSeries.className = "BarSeries";
BarSeries.type = "bar";

// packages/ag-charts-community/src/chart/series/cartesian/barSeriesModule.ts
var themeTemplate2 = {
  series: {
    direction: "vertical",
    fill: {
      $applySwitch: [
        { $path: "type" },
        { $palette: "fill" },
        ["gradient", FILL_GRADIENT_LINEAR_DEFAULTS],
        ["image", FILL_IMAGE_DEFAULTS],
        ["pattern", FILL_PATTERN_DEFAULTS]
      ]
    },
    stroke: { $palette: "stroke" },
    fillOpacity: 1,
    strokeWidth: { $isUserOption: ["./stroke", 2, 0] },
    lineDash: [0],
    lineDashOffset: 0,
    label: {
      ...LABEL_BOXING_DEFAULTS,
      padding: { $isUserOption: ["./spacing", 0, 8] },
      // compatibility with old `padding` property (now named `spacing`).
      enabled: false,
      fontWeight: { $ref: "fontWeight" },
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      color: {
        $if: [
          {
            $or: [
              { $eq: [{ $path: "./placement" }, "outside-start"] },
              { $eq: [{ $path: "./placement" }, "outside-end"] }
            ]
          },
          { $ref: "textColor" },
          { $ref: "chartBackgroundColor" }
        ]
      },
      placement: "inside-center"
    },
    shadow: {
      enabled: false,
      color: DEFAULT_SHADOW_COLOUR,
      xOffset: 3,
      yOffset: 3,
      blur: 5
    },
    highlight: MULTI_SERIES_HIGHLIGHT_STYLE,
    segmentation: SEGMENTATION_DEFAULTS
  }
};
var BarSeriesModule = {
  type: "series",
  name: "bar",
  chartType: "cartesian",
  stackable: true,
  groupable: true,
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: barSeriesOptionsDef,
  predictAxis: predictCartesianNonPrimitiveAxis,
  defaultAxes: DIRECTION_SWAP_AXES,
  axisKeys: { ["x" /* X */]: "xKeyAxis", ["y" /* Y */]: "yKeyAxis" },
  axisKeysFlipped: { ["x" /* X */]: "yKeyAxis", ["y" /* Y */]: "xKeyAxis" },
  themeTemplate: themeTemplate2,
  create: (ctx) => new BarSeries(ctx)
};

// packages/ag-charts-community/src/chart/series/cartesian/bubbleAggregation.ts
var SIZE_QUANTIZATION = 3;
var FILTER_DATUM_THRESHOLD = 5;
var FILTER_RANGE_THRESHOLD = 0.05;
function getPrimaryDatumIndex(context, indices, bounds) {
  const { xValues, yValues, xDomain, yDomain, xNeedsValueOf, yNeedsValueOf } = context;
  const { x0, y0, x1, y1 } = bounds;
  let currentIndex = 0;
  let currentDistanceSquared = Infinity;
  const midX = (x0 + x1) / 2;
  const midY = (y0 + y1) / 2;
  for (const datumIndex of indices) {
    const xValue = xValues[datumIndex];
    const yValue = yValues[datumIndex];
    if (xValue == null || yValue == null)
      continue;
    const xRatio = aggregationXRatioForXValue(xValue, xDomain.min, xDomain.max, xNeedsValueOf);
    const yRatio = aggregationXRatioForXValue(yValue, yDomain.min, yDomain.max, yNeedsValueOf);
    const distanceSquared2 = (xRatio - midX) ** 2 + (yRatio - midY) ** 2;
    if (distanceSquared2 < currentDistanceSquared) {
      currentDistanceSquared = distanceSquared2;
      currentIndex = datumIndex;
    }
  }
  return currentIndex;
}
function countVisibleItems(context, indices, bounds) {
  const { xValues, yValues, xDomain, yDomain, xNeedsValueOf, yNeedsValueOf } = context;
  const { x0, y0, x1, y1 } = bounds;
  let count = 0;
  for (const datumIndex of indices) {
    const xValue = xValues[datumIndex];
    const yValue = yValues[datumIndex];
    if (xValue == null || yValue == null)
      continue;
    const xRatio = aggregationXRatioForXValue(xValue, xDomain.min, xDomain.max, xNeedsValueOf);
    const yRatio = aggregationXRatioForXValue(yValue, yDomain.min, yDomain.max, yNeedsValueOf);
    if (xRatio >= x0 && xRatio <= x1 && yRatio >= y0 && yRatio <= y1) {
      count += 1;
    }
  }
  return count;
}
function quadChildren(context, indices, bounds) {
  const { xValues, yValues, xDomain, yDomain, xNeedsValueOf, yNeedsValueOf } = context;
  const { x0, y0, x1, y1 } = bounds;
  const childBuckets = [
    { x0: 1, y0: 1, x1: 0, y1: 0, indices: [] },
    { x0: 1, y0: 1, x1: 0, y1: 0, indices: [] },
    { x0: 1, y0: 1, x1: 0, y1: 0, indices: [] },
    { x0: 1, y0: 1, x1: 0, y1: 0, indices: [] }
  ];
  const midX = (x0 + x1) / 2;
  const midY = (y0 + y1) / 2;
  for (const datumIndex of indices) {
    const xValue = xValues[datumIndex];
    const yValue = yValues[datumIndex];
    if (xValue == null || yValue == null)
      continue;
    const xRatio = aggregationXRatioForXValue(xValue, xDomain.min, xDomain.max, xNeedsValueOf);
    const yRatio = aggregationXRatioForXValue(yValue, yDomain.min, yDomain.max, yNeedsValueOf);
    const childIndex = (xRatio > midX ? 1 : 0) + (yRatio > midY ? 2 : 0);
    const childBucket = childBuckets[childIndex];
    childBucket.indices.push(datumIndex);
    childBucket.x0 = Math.min(childBucket.x0, xRatio);
    childBucket.y0 = Math.min(childBucket.y0, yRatio);
    childBucket.x1 = Math.max(childBucket.x1, xRatio);
    childBucket.y1 = Math.max(childBucket.y1, yRatio);
  }
  const children = [];
  for (const childBucket of childBuckets) {
    const { indices: childIndices, x0: cx0, x1: cx1, y0: cy0, y1: cy1 } = childBucket;
    if (childIndices.length === 0)
      continue;
    const child = aggregateQuad(context, childIndices, { x0: cx0, y0: cy0, x1: cx1, y1: cy1 });
    children.push(child);
  }
  return children;
}
function aggregateQuad(context, indices, bounds) {
  const { x0, y0, x1, y1 } = bounds;
  const terminate = indices.length < FILTER_DATUM_THRESHOLD && x1 - x0 < FILTER_RANGE_THRESHOLD && y1 - y0 < FILTER_RANGE_THRESHOLD || x0 === x1 && y0 === y1;
  let children = terminate ? null : quadChildren(context, indices, bounds);
  if (children?.length === 1) {
    return children[0];
  } else if (children?.length === 0) {
    children = null;
  }
  const scale2 = Math.hypot(x1 - x0, y1 - y0);
  const primaryDatumIndex = getPrimaryDatumIndex(context, indices, bounds);
  return { scale: scale2, x0, y0, x1, y1, indices, primaryDatumIndex, children };
}
function computeBubbleAggregation(xDomain, yDomain, xValues, yValues, sizeValues, sizeDomain, options) {
  const [xd0, xd1] = xDomain;
  const [yd0, yd1] = yDomain;
  const [sd0, sd1] = sizeDomain;
  const { xNeedsValueOf, yNeedsValueOf } = options;
  const context = {
    xValues,
    yValues,
    xDomain: { min: xd0, max: xd1 },
    yDomain: { min: yd0, max: yd1 },
    xNeedsValueOf,
    yNeedsValueOf
  };
  const filters = [];
  if (sizeValues != null && sd1 > sd0) {
    const sizeIndices = Array.from({ length: SIZE_QUANTIZATION }, () => []);
    for (let datumIndex = 0; datumIndex < sizeValues.length; datumIndex += 1) {
      const sizeValue = sizeValues[datumIndex];
      const sizeRatio = (sizeValue - sd0) / (sd1 - sd0);
      const sizeIndex = Math.trunc(sizeRatio * SIZE_QUANTIZATION);
      if (sizeIndex >= 0 && sizeIndex < SIZE_QUANTIZATION) {
        sizeIndices[sizeIndex].push(datumIndex);
      }
    }
    for (let i = 0; i < sizeIndices.length; i += 1) {
      const indices = sizeIndices[i];
      const node = aggregateQuad(context, indices, { x0: 0, y0: 0, x1: 1, y1: 1 });
      if (node != null) {
        const sizeRatio = i / SIZE_QUANTIZATION;
        filters.push({ sizeRatio, node });
      }
    }
  } else {
    const indices = xValues.map((_, i) => i);
    const node = aggregateQuad(context, indices, { x0: 0, y0: 0, x1: 1, y1: 1 });
    if (node != null) {
      filters.push({ sizeRatio: 0, node });
    }
  }
  return filters.length > 0 ? { xValues, yValues, xd0, xd1, yd0, yd1, filters, xNeedsValueOf, yNeedsValueOf } : void 0;
}
function aggregateBubbleData(xScale, yScale, xValues, yValues, sizeValues, xDomainInput, yDomainInput, sizeDomain, xNeedsValueOf, yNeedsValueOf) {
  const [xd0, xd1] = aggregationDomain(xScale, xDomainInput);
  const [yd0, yd1] = aggregationDomain(yScale, yDomainInput);
  return computeBubbleAggregation(
    [xd0, xd1],
    [yd0, yd1],
    xValues,
    yValues,
    sizeValues,
    [sizeDomain[0], sizeDomain[1]],
    { xNeedsValueOf, yNeedsValueOf }
  );
}
function aggregateBubbleDataFromDataModel(xScale, yScale, dataModel, processedData, sizeScale, hasSizeKey, series) {
  const xValues = dataModel.resolveColumnById(series, "xValue", processedData);
  const yValues = dataModel.resolveColumnById(series, "yValue", processedData);
  const sizeValues = hasSizeKey ? dataModel.resolveColumnById(series, "sizeValue", processedData) : void 0;
  const xDomain = dataModel.getDomain(series, "xValue", "value", processedData);
  const yDomain = dataModel.getDomain(series, "yValue", "value", processedData);
  const sizeDomain = hasSizeKey ? sizeScale.domain : [0, 0];
  const xNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "xValue", processedData);
  const yNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "yValue", processedData);
  return aggregateBubbleData(
    xScale,
    yScale,
    xValues,
    yValues,
    sizeValues,
    xDomain,
    yDomain,
    sizeDomain,
    xNeedsValueOf,
    yNeedsValueOf
  );
}
function computeBubbleAggregationCountIndices(dilation, dataAggregation, options, counter, groupedAggregation, singleDatumIndices) {
  const {
    xRange,
    yRange,
    xVisibleRange: [xvr0, xvr1],
    yVisibleRange: [yvr0, yvr1],
    minSize,
    maxSize
  } = options;
  const { xValues, yValues, xd0, xd1, yd0, yd1, xNeedsValueOf, yNeedsValueOf } = dataAggregation;
  const baseScalingFactor = 1 / Math.min(xRange / (xvr1 - xvr0), yRange / (yvr1 - yvr0));
  const context = {
    xValues,
    yValues,
    xDomain: { min: xd0, max: xd1 },
    yDomain: { min: yd0, max: yd1 },
    xNeedsValueOf,
    yNeedsValueOf
  };
  for (const { sizeRatio, node } of dataAggregation.filters) {
    const radius = 0.5 * (minSize + sizeRatio * (maxSize - minSize));
    const baseMinScale = radius * baseScalingFactor;
    const minScale = dilation * baseMinScale;
    const x0 = xvr0 - radius / xRange;
    const x1 = xvr1 + radius / xRange;
    const y0 = yvr0 - radius / yRange;
    const y1 = yvr1 + radius / yRange;
    const queue = [node];
    while (queue.length > 0) {
      const item = queue.pop();
      if (item.x1 < x0 || item.x0 > x1 || item.y1 < y0 || item.y0 > y1) {
        continue;
      }
      if (dilation !== 1 && item.scale <= minScale) {
        if (counter != null) {
          counter.count += 1;
        }
        groupedAggregation?.push({
          datumIndex: item.primaryDatumIndex,
          count: item.indices.length,
          area: (item.x1 - item.x0) * (item.y1 - item.y0),
          dilation: clamp(1, item.scale / baseMinScale, dilation)
        });
      } else if (item.children == null) {
        const { indices } = item;
        if (counter != null) {
          const fullyVisible = item.x0 >= xvr0 && item.x1 <= xvr1 && item.y0 >= yvr0 && item.y1 <= yvr1;
          const itemCount = fullyVisible ? indices.length : countVisibleItems(context, indices, { x0: xvr0, y0: yvr0, x1: xvr1, y1: yvr1 });
          counter.count += itemCount;
        }
        singleDatumIndices?.push(...indices);
      } else {
        queue.push(...item.children);
      }
    }
  }
}
function computeBubbleAggregationCount(dilation, dataAggregation, options) {
  const counter = { count: 0 };
  computeBubbleAggregationCountIndices(dilation, dataAggregation, options, counter, void 0, void 0);
  return counter.count;
}
var MAX_AGGREGATION_DILATION = 100;
var DILATION_ITERATIONS = 12;
function computeBubbleAggregationDilation(dataAggregation, aggregationOptions, maxRenderedItems) {
  if (computeBubbleAggregationCount(1, dataAggregation, aggregationOptions) <= maxRenderedItems) {
    return 1;
  }
  let minDilation = 1;
  let maxDilation = 2;
  while (computeBubbleAggregationCount(maxDilation, dataAggregation, aggregationOptions) > maxRenderedItems && maxDilation < MAX_AGGREGATION_DILATION) {
    minDilation *= 2;
    maxDilation *= 2;
  }
  for (let i = 0; i < DILATION_ITERATIONS; i += 1) {
    const dilation = (maxDilation + minDilation) / 2;
    const count = computeBubbleAggregationCount(dilation, dataAggregation, aggregationOptions);
    if (count > maxRenderedItems) {
      minDilation = dilation;
    } else {
      maxDilation = dilation;
    }
  }
  return (minDilation + maxDilation) / 2;
}
function computeBubbleAggregationData(dilation, dataAggregation, options) {
  const groupedAggregation = [];
  const singleDatumIndices = [];
  computeBubbleAggregationCountIndices(
    dilation,
    dataAggregation,
    options,
    void 0,
    groupedAggregation,
    singleDatumIndices
  );
  return { groupedAggregation, singleDatumIndices };
}

// packages/ag-charts-community/src/chart/series/cartesian/bubbleSeriesProperties.ts
var BubbleSeriesMarker = class extends SeriesMarker {
  constructor() {
    super(...arguments);
    this.maxSize = 30;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], BubbleSeriesMarker.prototype, "maxSize", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneArrayChangeDetection()
], BubbleSeriesMarker.prototype, "domain", 2);
var BubbleSeriesLabel = class extends Label {
  constructor() {
    super(...arguments);
    this.placement = "top";
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], BubbleSeriesLabel.prototype, "placement", 2);
var BubbleSeriesProperties = class extends CartesianSeriesProperties {
  constructor() {
    super(...arguments);
    this.label = new BubbleSeriesLabel();
    this.tooltip = makeSeriesTooltip();
    this.maxRenderedItems = Infinity;
    // No validation. Not a part of the options contract.
    this.marker = new BubbleSeriesMarker();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], BubbleSeriesProperties.prototype, "xKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BubbleSeriesProperties.prototype, "yKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BubbleSeriesProperties.prototype, "sizeKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BubbleSeriesProperties.prototype, "labelKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BubbleSeriesProperties.prototype, "xFilterKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BubbleSeriesProperties.prototype, "yFilterKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BubbleSeriesProperties.prototype, "sizeFilterKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BubbleSeriesProperties.prototype, "xName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BubbleSeriesProperties.prototype, "yName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BubbleSeriesProperties.prototype, "sizeName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BubbleSeriesProperties.prototype, "labelName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BubbleSeriesProperties.prototype, "title", 2);
__decorateClass([
  ProxyProperty("marker.shape")
], BubbleSeriesProperties.prototype, "shape", 2);
__decorateClass([
  ProxyProperty("marker.size")
], BubbleSeriesProperties.prototype, "size", 2);
__decorateClass([
  ProxyProperty("marker.maxSize")
], BubbleSeriesProperties.prototype, "maxSize", 2);
__decorateClass([
  ProxyProperty("marker.domain")
], BubbleSeriesProperties.prototype, "domain", 2);
__decorateClass([
  ProxyProperty("marker.fill")
], BubbleSeriesProperties.prototype, "fill", 2);
__decorateClass([
  ProxyProperty("marker.fillOpacity")
], BubbleSeriesProperties.prototype, "fillOpacity", 2);
__decorateClass([
  ProxyProperty("marker.stroke")
], BubbleSeriesProperties.prototype, "stroke", 2);
__decorateClass([
  ProxyProperty("marker.strokeWidth")
], BubbleSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  ProxyProperty("marker.strokeOpacity")
], BubbleSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  ProxyProperty("marker.lineDash")
], BubbleSeriesProperties.prototype, "lineDash", 2);
__decorateClass([
  ProxyProperty("marker.lineDashOffset")
], BubbleSeriesProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  ProxyProperty("marker.itemStyler")
], BubbleSeriesProperties.prototype, "itemStyler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BubbleSeriesProperties.prototype, "styler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BubbleSeriesProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BubbleSeriesProperties.prototype, "tooltip", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BubbleSeriesProperties.prototype, "maxRenderedItems", 2);

// packages/ag-charts-community/src/chart/series/cartesian/bubbleSeries.ts
var BubbleScatterSeriesNodeEvent = class extends CartesianSeriesNodeEvent {
  constructor(type, nativeEvent, datum, series) {
    super(type, nativeEvent, datum, series);
    this.sizeKey = series.properties.sizeKey;
  }
};
var BubbleSeries = class extends CartesianSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      propertyKeys: {
        ...DEFAULT_CARTESIAN_DIRECTION_KEYS,
        label: ["labelKey"],
        size: ["sizeKey"]
      },
      propertyNames: {
        ...DEFAULT_CARTESIAN_DIRECTION_NAMES,
        label: ["labelName"],
        size: ["sizeName"]
      },
      categoryKey: void 0,
      pickModes: [
        2 /* AXIS_ALIGNED */,
        1 /* NEAREST_NODE */,
        0 /* EXACT_SHAPE_MATCH */
      ],
      pathsPerSeries: [],
      datumSelectionGarbageCollection: false,
      animationResetFns: {
        label: resetLabelFn,
        datum: resetMarkerFn
      },
      usesPlacedLabels: true,
      clipFocusBox: false
    });
    this.NodeEvent = BubbleScatterSeriesNodeEvent;
    this.properties = new BubbleSeriesProperties();
    this.dataAggregation = void 0;
    this.sizeScale = new LinearScale();
    this.placedLabelData = [];
  }
  get pickModeAxis() {
    return "main-category";
  }
  get type() {
    return super.type;
  }
  async processData(dataController) {
    if (this.data == null || !this.visible)
      return;
    const xScale = this.axes["x" /* X */]?.scale;
    const yScale = this.axes["y" /* Y */]?.scale;
    const { xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale });
    const sizeScaleType = this.sizeScale.type;
    const { xKey, yKey, sizeKey, xFilterKey, yFilterKey, sizeFilterKey, labelKey, marker } = this.properties;
    const allowNullKey = this.properties.allowNullKeys ?? false;
    const { dataModel, processedData } = await this.requestDataModel(dataController, this.data, {
      props: [
        valueProperty(xKey, xScaleType, { id: `xValue`, allowNullKey }),
        valueProperty(yKey, yScaleType, { id: `yValue`, allowNullKey }),
        ...xFilterKey == null ? [] : [valueProperty(xFilterKey, xScaleType, { id: `xFilterValue` })],
        ...yFilterKey == null ? [] : [valueProperty(yFilterKey, yScaleType, { id: `yFilterValue` })],
        ...sizeFilterKey == null ? [] : [valueProperty(sizeFilterKey, sizeScaleType, { id: `sizeFilterValue` })],
        ...sizeKey ? [valueProperty(sizeKey, sizeScaleType, { id: `sizeValue` })] : [],
        ...labelKey ? [valueProperty(labelKey, "category", { id: `labelValue` })] : []
      ]
    });
    const sizeKeyIdx = sizeKey ? dataModel.resolveProcessedDataIndexById(this, `sizeValue`) : void 0;
    const mutableMarkerDomain = marker.domain ? [marker.domain[0], marker.domain[1]] : void 0;
    this.sizeScale.domain = mutableMarkerDomain ?? (sizeKeyIdx == null ? void 0 : processedData.domain.values[sizeKeyIdx]) ?? [];
    this.dataAggregation = this.aggregateData(dataModel, processedData);
    this.animationState.transition("updateData");
  }
  xCoordinateRange(xValue, pixelSize, index) {
    const { properties, sizeScale } = this;
    const { size, sizeKey } = properties;
    const x = this.axes["x" /* X */].scale.convert(xValue);
    const sizeValues = sizeKey == null ? void 0 : this.dataModel.resolveColumnById(this, `sizeValue`, this.processedData);
    const sizeValue = sizeValues == null ? size : sizeScale.convert(sizeValues[index]);
    const r = 0.5 * sizeValue * pixelSize;
    return [x - r, x + r];
  }
  yCoordinateRange(yValues, pixelSize, index) {
    const { properties, sizeScale } = this;
    const { size, sizeKey } = properties;
    const y = this.axes["y" /* Y */].scale.convert(yValues[0]);
    const sizeValues = sizeKey == null ? void 0 : this.dataModel.resolveColumnById(this, `sizeValue`, this.processedData);
    const sizeValue = sizeValues == null ? size : sizeScale.convert(sizeValues[index]);
    const r = 0.5 * sizeValue * pixelSize;
    return [y - r, y + r];
  }
  getSeriesDomain(direction) {
    const { dataModel, processedData } = this;
    if (!processedData || !dataModel)
      return { domain: [] };
    const dataValues = {
      ["x" /* X */]: "xValue",
      ["y" /* Y */]: "yValue"
    };
    const id = dataValues[direction];
    const dataDef = dataModel.resolveProcessedDataDefById(this, id);
    const domainData = dataModel.getDomain(this, id, "value", processedData);
    if (dataDef?.def.type === "value" && dataDef?.def.valueType === "category") {
      return { domain: domainData.domain };
    }
    const crossDirection = direction === "x" /* X */ ? "y" /* Y */ : "x" /* X */;
    const crossId = dataValues[crossDirection];
    const ext = this.domainForClippedRange(direction, [id], crossId);
    return { domain: fixNumericExtent(extent(ext)) };
  }
  getSeriesRange(_direction, visibleRange) {
    return this.domainForVisibleRange("y" /* Y */, ["yValue"], "xValue", visibleRange);
  }
  getVisibleItems(xVisibleRange, yVisibleRange, minVisibleItems) {
    const { dataAggregation, axes } = this;
    const xAxis = axes["x" /* X */];
    const yAxis = axes["y" /* Y */];
    if (dataAggregation == null || xAxis == null || yAxis == null) {
      return this.countVisibleItems("xValue", ["yValue"], xVisibleRange, yVisibleRange, minVisibleItems);
    }
    const aggregationOptions = this.aggregationOptions(xAxis, yAxis, xVisibleRange, yVisibleRange ?? [0, 1]);
    return computeBubbleAggregationCount(0, dataAggregation, aggregationOptions);
  }
  aggregateData(dataModel, processedData) {
    if (processedData.type === "grouped")
      return;
    if (processedData.input.count <= this.properties.maxRenderedItems)
      return;
    const xAxis = this.axes["x" /* X */];
    const yAxis = this.axes["y" /* Y */];
    if (xAxis == null || yAxis == null)
      return;
    const xScale = xAxis.scale;
    const yScale = yAxis.scale;
    if (!ContinuousScale.is(xScale) || !ContinuousScale.is(yScale))
      return;
    return aggregateBubbleDataFromDataModel(
      xScale.type,
      yScale.type,
      dataModel,
      processedData,
      this.sizeScale,
      this.properties.sizeKey != null,
      this
    );
  }
  aggregationOptions(xAxis, yAxis, xVisibleRange = xAxis.visibleRange, yVisibleRange = yAxis.visibleRange) {
    const { processedData, dataModel } = this;
    const { sizeKey } = this.properties;
    const [markerSize, markerMaxSize] = this.getSizeRange();
    const xRange = Math.abs(xAxis.range[1] - xAxis.range[0]);
    const yRange = Math.abs(yAxis.range[1] - yAxis.range[0]);
    const minSize = Math.max(markerSize, 1);
    const maxSize = sizeKey ? Math.max(markerMaxSize, 1) : minSize;
    const xScale = xAxis.scale;
    const yScale = yAxis.scale;
    if (processedData != null && dataModel != null) {
      if (ContinuousScale.is(xScale)) {
        xVisibleRange = rescaleVisibleRange(
          xVisibleRange,
          xScale.domain.map(dateToNumber),
          dataModel.getDomain(this, `xValue`, "value", processedData).domain.map(dateToNumber)
        );
      }
      if (ContinuousScale.is(yScale)) {
        yVisibleRange = rescaleVisibleRange(
          yVisibleRange,
          yScale.domain.map(dateToNumber),
          dataModel.getDomain(this, `yValue`, "value", processedData).domain.map(dateToNumber)
        );
      }
    }
    return { xRange, yRange, minSize, maxSize, xVisibleRange, yVisibleRange };
  }
  /**
   * Creates and returns a context object that caches expensive property lookups
   * and scale conversions. Called once per createNodeData() invocation.
   */
  createNodeDatumContext(xAxis, yAxis) {
    const { dataModel, processedData, sizeScale, visible } = this;
    if (!dataModel || !processedData)
      return void 0;
    const rawData = processedData.dataSources.get(this.id)?.data;
    if (rawData == null)
      return void 0;
    const {
      xKey,
      yKey,
      sizeKey,
      xFilterKey,
      yFilterKey,
      sizeFilterKey,
      labelKey,
      xName,
      yName,
      sizeName,
      labelName,
      label,
      legendItemName,
      marker
    } = this.properties;
    const xScale = xAxis.scale;
    const yScale = yAxis.scale;
    const canIncrementallyUpdate = processedData.changeDescription != null && this.contextNodeData?.nodeData != null;
    let labelTextDomain;
    if (labelKey) {
      labelTextDomain = [];
    } else if (sizeKey) {
      labelTextDomain = dataModel.getDomain(this, `sizeValue`, "value", processedData).domain;
    } else {
      labelTextDomain = [];
    }
    const xDataValues = dataModel.resolveColumnById(this, `xValue`, processedData);
    return {
      // Axes (from template method parameters)
      xAxis,
      yAxis,
      // Data arrays
      rawData,
      xValues: xDataValues,
      // Base interface field
      xDataValues,
      // BubbleSeries-specific alias
      yDataValues: dataModel.resolveColumnById(this, `yValue`, processedData),
      sizeDataValues: sizeKey == null ? void 0 : dataModel.resolveColumnById(this, `sizeValue`, processedData),
      labelDataValues: labelKey == null ? void 0 : dataModel.resolveColumnById(this, `labelValue`, processedData),
      xFilterDataValues: xFilterKey == null ? void 0 : dataModel.resolveColumnById(this, `xFilterValue`, processedData),
      yFilterDataValues: yFilterKey == null ? void 0 : dataModel.resolveColumnById(this, `yFilterValue`, processedData),
      sizeFilterDataValues: sizeFilterKey == null ? void 0 : dataModel.resolveColumnById(this, `sizeFilterValue`, processedData),
      // Scales
      xScale,
      yScale,
      sizeScale,
      // Computed positioning
      xOffset: (xScale.bandwidth ?? 0) / 2,
      yOffset: (yScale.bandwidth ?? 0) / 2,
      // Property lookups
      xKey,
      yKey,
      sizeKey,
      labelKey,
      xName,
      yName,
      sizeName,
      labelName,
      legendItemName,
      // Label properties
      labelsEnabled: label.enabled,
      labelPlacement: label.placement,
      labelAnchor: Marker.anchor(marker.shape),
      labelTextDomain,
      labelPadding: expandLabelPadding(label),
      labelTextMeasurer: cachedTextMeasurer(label),
      label,
      // Other state
      animationEnabled: !this.ctx.animationManager.isSkipped(),
      visible,
      // Incremental update support
      canIncrementallyUpdate,
      nodes: canIncrementallyUpdate ? this.contextNodeData.nodeData : [],
      nodeIndex: 0
    };
  }
  // ============================================================================
  // Template Method Hooks
  // ============================================================================
  /**
   * Populates the node data array by iterating over visible data.
   * Strategy selection happens inside: simple or aggregation path.
   */
  populateNodeData(ctx) {
    this.sizeScale.range = this.getSizeRange();
    const scratch = {
      datum: void 0,
      xDatum: void 0,
      yDatum: void 0,
      sizeValue: void 0,
      x: 0,
      y: 0,
      selected: void 0,
      nodeLabel: { text: "", width: 0, height: 0 },
      markerSize: 0,
      count: 1,
      dilation: 1,
      area: 0
    };
    const { dataAggregation } = this;
    if (dataAggregation == null) {
      this.createNodeDataSimple(ctx, scratch);
    } else {
      this.createNodeDataWithAggregation(ctx, scratch, ctx.xAxis, ctx.yAxis, dataAggregation);
    }
  }
  /**
   * Initializes the result context object with default values.
   * Called before populate phase to allow early return for invisible series.
   */
  initializeResult(ctx) {
    const { marker } = this.properties;
    return {
      itemId: ctx.yKey,
      nodeData: ctx.nodes,
      labelData: ctx.labelsEnabled ? ctx.nodes : [],
      scales: this.calculateScaling(),
      visible: this.visible || ctx.animationEnabled,
      styles: getMarkerStyles(this, this.properties, marker)
    };
  }
  /**
   * Validates datum state and upserts node - centralizes duplicated upsert pattern.
   */
  upsertBubbleNodeDatum(ctx, scratch, datumIndex) {
    if (!this.prepareNodeDatumState(ctx, scratch, datumIndex))
      return;
    upsertNodeDatum(
      ctx,
      { scratch, datumIndex },
      (c, p) => {
        const node = this.createSkeletonNodeDatum(c, p.scratch, p.datumIndex);
        this.updateNodeDatum(c, node, p.scratch, p.datumIndex);
        return node;
      },
      (c, n, p) => this.updateNodeDatum(c, n, p.scratch, p.datumIndex)
    );
  }
  /**
   * Simple iteration path for ungrouped data without aggregation.
   */
  createNodeDataSimple(ctx, scratch) {
    const dataLength = ctx.rawData.length;
    for (let datumIndex = 0; datumIndex < dataLength; datumIndex++) {
      scratch.count = 1;
      scratch.dilation = 1;
      scratch.area = 0;
      this.upsertBubbleNodeDatum(ctx, scratch, datumIndex);
    }
  }
  /**
   * Aggregation path for large datasets using quadtree-based 2D spatial aggregation.
   */
  createNodeDataWithAggregation(ctx, scratch, xAxis, yAxis, dataAggregation) {
    const { maxRenderedItems } = this.properties;
    const aggregationOptions = this.aggregationOptions(xAxis, yAxis);
    const aggregationDilation = computeBubbleAggregationDilation(
      dataAggregation,
      aggregationOptions,
      maxRenderedItems
    );
    const { groupedAggregation, singleDatumIndices } = computeBubbleAggregationData(
      aggregationDilation,
      dataAggregation,
      aggregationOptions
    );
    for (const { datumIndex, count, dilation, area: area2 } of groupedAggregation) {
      scratch.count = count;
      scratch.dilation = dilation;
      scratch.area = area2;
      this.upsertBubbleNodeDatum(ctx, scratch, datumIndex);
    }
    for (const datumIndex of singleDatumIndices) {
      scratch.count = 1;
      scratch.dilation = 1;
      scratch.area = 0;
      this.upsertBubbleNodeDatum(ctx, scratch, datumIndex);
    }
  }
  /**
   * Validates and prepares state needed for node creation/update.
   * Returns undefined if datum should be skipped (invalid data).
   */
  prepareNodeDatumState(ctx, scratch, datumIndex) {
    const datum = ctx.rawData[datumIndex];
    const xDatum = ctx.xDataValues[datumIndex];
    const yDatum = ctx.yDataValues[datumIndex];
    const allowNullKeys = this.properties.allowNullKeys ?? false;
    if ((xDatum === void 0 || yDatum === void 0) && !allowNullKeys)
      return void 0;
    const sizeValue = ctx.sizeDataValues?.[datumIndex];
    const x = ctx.xScale.convert(xDatum) + ctx.xOffset;
    const y = ctx.yScale.convert(yDatum) + ctx.yOffset;
    if (!Number.isFinite(x) || !Number.isFinite(y))
      return void 0;
    let selected;
    if (ctx.xFilterDataValues != null && ctx.yFilterDataValues != null) {
      selected = ctx.xFilterDataValues[datumIndex] === xDatum && ctx.yFilterDataValues[datumIndex] === yDatum;
      if (ctx.sizeFilterDataValues != null) {
        selected && (selected = ctx.sizeFilterDataValues[datumIndex] === sizeValue);
      }
    }
    let nodeLabel;
    if (ctx.labelsEnabled) {
      nodeLabel = this.computeLabel(ctx, datum, yDatum, sizeValue, datumIndex);
    } else {
      nodeLabel = { text: "", width: 0, height: 0 };
    }
    const markerSize = sizeValue == null ? ctx.sizeScale.range[0] : ctx.sizeScale.convert(sizeValue);
    scratch.datum = datum;
    scratch.xDatum = xDatum;
    scratch.yDatum = yDatum;
    scratch.sizeValue = sizeValue;
    scratch.x = x;
    scratch.y = y;
    scratch.selected = selected;
    scratch.nodeLabel = nodeLabel;
    scratch.markerSize = markerSize;
    return scratch;
  }
  /**
   * Computes label text and measurements for a datum.
   * Separated to enable skipping when labels are disabled.
   */
  computeLabel(ctx, datum, yDatum, sizeValue, datumIndex) {
    let labelTextValue;
    let labelTextKey;
    let labelTextProperty;
    if (ctx.labelKey && ctx.labelDataValues) {
      labelTextValue = ctx.labelDataValues[datumIndex];
      labelTextKey = ctx.labelKey;
      labelTextProperty = "label";
    } else if (ctx.sizeKey) {
      labelTextValue = sizeValue;
      labelTextKey = ctx.sizeKey;
      labelTextProperty = "size";
    } else {
      labelTextValue = yDatum;
      labelTextKey = ctx.yKey;
      labelTextProperty = "y";
    }
    const labelText = this.getLabelText(
      labelTextValue,
      datum,
      labelTextKey,
      labelTextProperty,
      ctx.labelTextDomain,
      ctx.label,
      {
        value: labelTextValue,
        datum,
        xKey: ctx.xKey,
        yKey: ctx.yKey,
        // sizeKey may be undefined for ScatterSeries (which extends BubbleSeries)
        sizeKey: ctx.sizeKey,
        labelKey: ctx.labelKey,
        xName: ctx.xName,
        yName: ctx.yName,
        sizeName: ctx.sizeName,
        labelName: ctx.labelName,
        legendItemName: ctx.legendItemName
      }
    );
    let { width: width2, height: height2 } = isArray(labelText) ? measureTextSegments(labelText, ctx.label) : ctx.labelTextMeasurer.measureLines(String(labelText));
    width2 += ctx.labelPadding.left + ctx.labelPadding.right;
    height2 += ctx.labelPadding.bottom + ctx.labelPadding.top;
    return { text: labelText, width: width2, height: height2 };
  }
  /**
   * Creates a minimal skeleton node - actual values set by updateNodeDatum.
   */
  createSkeletonNodeDatum(ctx, _scratch, _datumIndex) {
    return {
      series: this,
      yKey: ctx.yKey,
      xKey: ctx.xKey,
      datum: void 0,
      datumIndex: 0,
      xValue: void 0,
      yValue: void 0,
      sizeValue: void 0,
      capDefaults: { lengthRatioMultiplier: this.properties.marker.getDiameter(), lengthMax: Infinity },
      point: { x: 0, y: 0, size: 0 },
      midPoint: { x: 0, y: 0 },
      label: { text: "", width: 0, height: 0 },
      anchor: ctx.labelAnchor,
      placement: ctx.labelPlacement,
      count: 1,
      dilation: 1,
      area: 0,
      selected: void 0
    };
  }
  /**
   * Updates node properties in-place.
   * Shared by both create (skeleton + update) and incremental update paths.
   */
  updateNodeDatum(ctx, node, scratch, datumIndex) {
    const mutableNode = node;
    const { x, y, markerSize, dilation } = scratch;
    mutableNode.datum = scratch.datum;
    mutableNode.datumIndex = datumIndex;
    mutableNode.xValue = scratch.xDatum;
    mutableNode.yValue = scratch.yDatum;
    mutableNode.sizeValue = scratch.sizeValue;
    mutableNode.selected = scratch.selected;
    mutableNode.count = scratch.count;
    mutableNode.dilation = scratch.dilation;
    mutableNode.area = scratch.area;
    mutableNode.label = scratch.nodeLabel;
    mutableNode.anchor = ctx.labelAnchor;
    mutableNode.placement = ctx.labelPlacement;
    const mutablePoint = mutableNode.point;
    mutablePoint.x = x;
    mutablePoint.y = y;
    mutablePoint.size = Math.sqrt(dilation) * markerSize;
    const mutableMidPoint = mutableNode.midPoint;
    mutableMidPoint.x = x;
    mutableMidPoint.y = y;
  }
  isPathOrSelectionDirty() {
    return this.properties.marker.isDirty();
  }
  getLabelData() {
    if (!this.isLabelEnabled())
      return [];
    return this.contextNodeData?.labelData ?? [];
  }
  updateDatumSelection(opts) {
    const { nodeData, datumSelection } = opts;
    if (this.properties.marker.isDirty()) {
      datumSelection.clear();
      datumSelection.cleanup();
    }
    if (!processedDataIsAnimatable(this.processedData)) {
      return datumSelection.update(nodeData);
    }
    const { sizeKey } = this.properties;
    let getId;
    if (sizeKey) {
      getId = (datum) => createDatumId(datum.xValue, datum.yValue, datum.sizeValue, toPlainText(datum.label.text));
    }
    return datumSelection.update(nodeData, void 0, getId);
  }
  updateDatumStyles(opts) {
    const { datumSelection, isHighlight } = opts;
    const { xKey, yKey, sizeKey, labelKey, marker } = this.properties;
    const params = { xKey, yKey, sizeKey, labelKey };
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    datumSelection.each((node, datum) => {
      if (!datumSelection.isGarbage(node)) {
        const highlightState = this.getHighlightState(highlightedDatum, opts.isHighlight, datum.datumIndex);
        const stylerStyle = this.getStyle(highlightState);
        datum.style = this.getMarkerStyle(
          marker,
          datum,
          params,
          {
            isHighlight,
            highlightState,
            resolveMarkerSubPath: []
          },
          stylerStyle
        );
      }
    });
  }
  updateDatumNodes(opts) {
    const { contextNodeData } = this;
    if (!contextNodeData)
      return;
    const { datumSelection, isHighlight, drawingMode } = opts;
    this.sizeScale.range = this.getSizeRange();
    const fillBBox = this.getShapeFillBBox();
    const aggregated = this.dataAggregation != null;
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    datumSelection.each((node, datum, index) => {
      const {
        point: { size },
        count,
        area: area2,
        dilation
      } = datum;
      const state = this.getHighlightState(highlightedDatum, isHighlight, datum.datumIndex);
      const style2 = { ...datum.style ?? contextNodeData.styles[state] };
      style2.size = size;
      if (dilation > 1) {
        const fillOpacity = style2.fillOpacity ?? 0;
        const opacityScale = 0.269669 + 683e-6 * count + -37.534348 * area2 + 4449e-6 * count * area2 + -0 * count ** 2 + 44.428603 * area2 ** 2;
        style2.fillOpacity = clamp(fillOpacity / dilation, fillOpacity / 0.1 * opacityScale, 1);
      }
      this.applyMarkerStyle(style2, node, datum.point, fillBBox, { selected: datum.selected });
      node.drawingMode = this.resolveMarkerDrawingModeForState(drawingMode, style2);
      node.zIndex = aggregated ? [-count, index] : 0;
    });
    if (!isHighlight) {
      this.properties.marker.markClean();
    }
  }
  updatePlacedLabelData(labelData) {
    this.placedLabelData = labelData;
    this.labelSelection.update(
      labelData.map((v) => ({
        ...v.datum,
        point: {
          x: v.x,
          y: v.y,
          size: v.datum.point.size
        }
      })),
      (text2) => {
        text2.pointerEvents = 1 /* None */;
      }
    );
    this.updateLabelNodes({ labelSelection: this.labelSelection });
    this.updateHighlightLabelSelection();
  }
  updateHighlightLabelSelection() {
    const highlightedDatum = this.ctx.highlightManager?.getActiveHighlight();
    const highlightItem = this.isSeriesHighlighted(highlightedDatum) && highlightedDatum?.datum ? highlightedDatum : void 0;
    const highlightLabelData = highlightItem == null ? [] : this.placedLabelData.filter((label) => label.datum.datumIndex === highlightItem.datumIndex).map((label) => ({
      ...label.datum,
      point: {
        x: label.x,
        y: label.y,
        size: label.datum.point.size
      }
    }));
    this.highlightLabelSelection = this.updateLabelSelection({
      labelData: highlightLabelData,
      labelSelection: this.highlightLabelSelection
    }) ?? this.highlightLabelSelection;
    this.highlightLabelGroup.visible = highlightLabelData.length > 0;
    this.highlightLabelGroup.batchedUpdate(() => {
      this.updateLabelNodes({ labelSelection: this.highlightLabelSelection, isHighlight: true });
    });
  }
  updateLabelNodes(opts) {
    const { isHighlight = false } = opts;
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const params = this.makeLabelFormatterParams();
    opts.labelSelection.each((text2, datum) => {
      const style2 = getLabelStyles(this, datum, params, this.properties.label, isHighlight, activeHighlight);
      text2.text = datum.label.text;
      text2.fill = style2.color;
      text2.x = datum.point?.x ?? 0;
      text2.y = datum.point?.y ?? 0;
      text2.fontStyle = style2.fontStyle;
      text2.fontWeight = style2.fontWeight;
      text2.fontSize = style2.fontSize;
      text2.fontFamily = style2.fontFamily;
      text2.textBaseline = "top";
      text2.fillOpacity = this.getHighlightStyle(isHighlight, datum.datumIndex).opacity ?? 1;
      text2.setBoxing(style2);
    });
  }
  updateLabelSelection(opts) {
    const { labelData, labelSelection } = opts;
    return labelSelection.update(labelData, (text2) => {
      text2.pointerEvents = 1 /* None */;
    });
  }
  makeStylerParams(highlightStateEnum) {
    const {
      id: seriesId,
      properties: {
        size,
        maxSize,
        shape,
        fill,
        fillOpacity,
        lineDash,
        lineDashOffset,
        stroke: stroke3,
        strokeOpacity,
        strokeWidth,
        xKey,
        yKey,
        sizeKey,
        labelKey
      }
    } = this;
    const highlightState = toHighlightString(highlightStateEnum ?? 0 /* None */);
    if (this.type === "bubble") {
      return {
        highlightState,
        size,
        maxSize,
        shape,
        fill,
        fillOpacity,
        lineDash,
        lineDashOffset,
        seriesId,
        sizeKey,
        stroke: stroke3,
        strokeOpacity,
        strokeWidth,
        xKey,
        yKey,
        labelKey
      };
    } else if (this.type === "scatter") {
      return {
        highlightState,
        size,
        shape,
        fill,
        fillOpacity,
        lineDash,
        lineDashOffset,
        seriesId,
        stroke: stroke3,
        strokeOpacity,
        strokeWidth,
        xKey,
        yKey,
        labelKey
      };
    } else {
      return this.type;
    }
  }
  makeLabelFormatterParams() {
    const { xKey, xName, yKey, yName, sizeKey, sizeName, labelKey, labelName, legendItemName } = this.properties;
    return {
      xKey,
      xName,
      yKey,
      yName,
      sizeKey,
      sizeName,
      labelKey,
      labelName,
      legendItemName
    };
  }
  getTooltipContent(datumIndex) {
    const { id: seriesId, dataModel, processedData, axes, properties, ctx } = this;
    const { formatManager } = ctx;
    const {
      xKey,
      xName,
      yKey,
      yName,
      sizeKey,
      sizeName,
      labelKey,
      labelName,
      title,
      tooltip,
      marker,
      legendItemName
    } = properties;
    const xAxis = axes["x" /* X */];
    const yAxis = axes["y" /* Y */];
    if (!dataModel || !processedData || !xAxis || !yAxis)
      return;
    const datum = processedData.dataSources.get(this.id)?.data?.[datumIndex];
    const xValue = dataModel.resolveColumnById(this, `xValue`, processedData)[datumIndex];
    const yValue = dataModel.resolveColumnById(this, `yValue`, processedData)[datumIndex];
    const allowNullKeys = this.properties.allowNullKeys ?? false;
    if (xValue === void 0 && !allowNullKeys)
      return;
    const data = [];
    if (this.isLabelEnabled() && labelKey != null) {
      const value = dataModel.resolveColumnById(this, `labelValue`, processedData)[datumIndex];
      const content = formatManager.format(this.callWithContext.bind(this), {
        type: "category",
        value,
        datum,
        seriesId,
        legendItemName,
        key: labelKey,
        source: "tooltip",
        property: "label",
        domain: [],
        boundSeries: this.getFormatterContext("label")
      });
      data.push({ label: labelName, fallbackLabel: labelKey, value: content ?? formatValue(value) });
    }
    data.push(
      {
        label: xName,
        fallbackLabel: xKey,
        value: this.getAxisValueText(xAxis, "tooltip", xValue, datum, xKey, legendItemName, allowNullKeys),
        missing: isTooltipValueMissing(xValue, allowNullKeys)
      },
      {
        label: yName,
        fallbackLabel: yKey,
        value: this.getAxisValueText(yAxis, "tooltip", yValue, datum, yKey, legendItemName, allowNullKeys),
        missing: isTooltipValueMissing(yValue, allowNullKeys)
      }
    );
    if (sizeKey != null) {
      const value = dataModel.resolveColumnById(this, `sizeValue`, processedData)[datumIndex];
      if (value != null) {
        const domain = dataModel.getDomain(this, `sizeValue`, "value", processedData).domain;
        const content = formatManager.format(this.callWithContext.bind(this), {
          type: "number",
          value,
          datum,
          seriesId,
          legendItemName,
          key: sizeKey,
          source: "tooltip",
          property: "size",
          boundSeries: this.getFormatterContext("size"),
          domain,
          fractionDigits: void 0,
          visibleDomain: void 0
        });
        data.push({ label: sizeName, fallbackLabel: sizeKey, value: content ?? formatValue(value) });
      }
    }
    const activeStyle = this.getMarkerStyle(
      marker,
      { datum, datumIndex },
      { xKey, yKey, sizeKey, labelKey },
      { resolveMarkerSubPath: [] }
    );
    return this.formatTooltipWithContext(
      tooltip,
      {
        title,
        symbol: this.legendItemSymbol(),
        data
      },
      {
        seriesId,
        datum,
        title: yKey,
        xKey,
        xName,
        yKey,
        yName,
        sizeKey,
        sizeName,
        labelKey,
        labelName,
        legendItemName,
        ...activeStyle,
        ...this.getModuleTooltipParams()
      }
    );
  }
  legendItemSymbol() {
    const style2 = this.getStyle();
    const marker = this.getMarkerStyle(
      this.properties.marker,
      {},
      void 0,
      {
        isHighlight: false,
        checkForHighlight: false,
        resolveMarkerSubPath: []
      },
      style2
    );
    return {
      marker
    };
  }
  getLegendData() {
    const {
      id: seriesId,
      ctx: { legendManager },
      visible
    } = this;
    const { yKey: itemId, yName, legendItemName, title, showInLegend } = this.properties;
    return [
      {
        legendType: "category",
        id: seriesId,
        itemId,
        seriesId,
        enabled: visible && legendManager.getItemEnabled({ seriesId, itemId }),
        label: {
          text: legendItemName ?? title ?? yName ?? itemId
        },
        symbol: this.legendItemSymbol(),
        legendItemName,
        hideInLegend: !showInLegend
      }
    ];
  }
  animateEmptyUpdateReady({ datumSelection, labelSelection }) {
    markerScaleInAnimation(this, this.ctx.animationManager, datumSelection);
    seriesLabelFadeInAnimation(this, "labels", this.ctx.animationManager, labelSelection);
  }
  resetDatumAnimation(data) {
    resetMarkerSelectionsDirect([data.datumSelection]);
  }
  isLabelEnabled() {
    return this.properties.label.enabled;
  }
  nodeFactory() {
    return new Marker();
  }
  getStyle(highlightState) {
    const { properties } = this;
    let stylerResult = {};
    if (properties.styler) {
      const stylerParams = this.makeStylerParams(highlightState);
      const cbResult = this.cachedCallWithContext(properties.styler, stylerParams) ?? {};
      const resolved = this.ctx.optionsGraphService.resolvePartial(
        ["series", `${this.declarationOrder}`],
        cbResult,
        { pick: false }
      );
      stylerResult = resolved ?? {};
    }
    return {
      fill: stylerResult.fill ?? properties.fill,
      fillOpacity: stylerResult.fillOpacity ?? properties.fillOpacity,
      lineDash: stylerResult.lineDash ?? properties.lineDash,
      lineDashOffset: stylerResult.lineDashOffset ?? properties.lineDashOffset,
      shape: stylerResult.shape ?? properties.shape,
      size: stylerResult.size ?? properties.size,
      maxSize: stylerResult.maxSize ?? properties.maxSize,
      stroke: stylerResult.stroke ?? properties.stroke,
      strokeOpacity: stylerResult.strokeOpacity ?? properties.strokeOpacity,
      strokeWidth: stylerResult.strokeWidth ?? properties.strokeWidth
    };
  }
  getSizeRange() {
    const { size, maxSize } = this.getStyle();
    return [size, maxSize];
  }
  getFormattedMarkerStyle(datum) {
    const { xKey, yKey, sizeKey, labelKey, marker } = this.properties;
    return this.getMarkerStyle(marker, datum, { xKey, yKey, sizeKey, labelKey }, { resolveMarkerSubPath: [] });
  }
  computeFocusBounds(opts) {
    return computeMarkerFocusBounds(this, opts);
  }
  hasItemStylers() {
    const { styler, itemStyler, marker, label } = this.properties;
    return !!(styler ?? itemStyler ?? marker.itemStyler ?? label.itemStyler);
  }
  initQuadTree(quadtree) {
    addHitTestersToQuadtree(quadtree, this.datumNodesIter());
  }
  pickNodeDataClosestDatum(point) {
    return findQuadtreeMatch(this, point);
  }
};
BubbleSeries.className = "BubbleSeries";
BubbleSeries.type = "bubble";

// packages/ag-charts-community/src/chart/series/cartesian/bubbleSeriesModule.ts
var themeTemplate3 = {
  series: {
    shape: "circle",
    size: 7,
    maxSize: 30,
    fill: {
      $applySwitch: [
        { $path: "type" },
        { $palette: "fill" },
        ["gradient", FILL_GRADIENT_RADIAL_REVERSED_DEFAULTS],
        ["image", FILL_IMAGE_DEFAULTS],
        ["pattern", FILL_PATTERN_DEFAULTS]
      ]
    },
    stroke: { $palette: "stroke" },
    fillOpacity: 0.8,
    maxRenderedItems: 2e3,
    label: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: false,
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      fontWeight: { $ref: "fontWeight" },
      color: { $ref: "textColor" }
    },
    tooltip: {
      range: {
        $if: [
          { $eq: [{ $path: ["/tooltip/range", "nearest"] }, "area"] },
          "nearest",
          { $path: ["/tooltip/range", "nearest"] }
        ]
      },
      position: {
        anchorTo: { $path: ["/tooltip/position/anchorTo", "node"] }
      }
    },
    highlight: MULTI_SERIES_HIGHLIGHT_STYLE
  }
};
var BubbleSeriesModule = {
  type: "series",
  name: "bubble",
  chartType: "cartesian",
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: bubbleSeriesOptionsDef,
  predictAxis: predictCartesianAxis,
  defaultAxes: {
    x: {
      type: "number" /* NUMBER */,
      position: "bottom" /* BOTTOM */
    },
    y: {
      type: "number" /* NUMBER */,
      position: "left" /* LEFT */
    }
  },
  axisKeys: { ["x" /* X */]: "xKeyAxis", ["y" /* Y */]: "yKeyAxis" },
  themeTemplate: themeTemplate3,
  create: (ctx) => new BubbleSeries(ctx)
};

// packages/ag-charts-community/src/chart/series/cartesian/histogramSeriesProperties.ts
var HistogramSeriesProperties = class extends CartesianSeriesProperties {
  constructor() {
    super(...arguments);
    this.fillOpacity = 1;
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.cornerRadius = 0;
    this.areaPlot = false;
    this.aggregation = "sum";
    this.shadow = new DropShadow();
    this.label = new Label();
    this.tooltip = makeSeriesTooltip();
  }
  getStyle() {
    const { fill, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset, cornerRadius } = this;
    return {
      fill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset,
      cornerRadius,
      opacity: 1
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], HistogramSeriesProperties.prototype, "xKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HistogramSeriesProperties.prototype, "yKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HistogramSeriesProperties.prototype, "xName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HistogramSeriesProperties.prototype, "yName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HistogramSeriesProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HistogramSeriesProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HistogramSeriesProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HistogramSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HistogramSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HistogramSeriesProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HistogramSeriesProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HistogramSeriesProperties.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HistogramSeriesProperties.prototype, "areaPlot", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HistogramSeriesProperties.prototype, "bins", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HistogramSeriesProperties.prototype, "aggregation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HistogramSeriesProperties.prototype, "binCount", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HistogramSeriesProperties.prototype, "shadow", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HistogramSeriesProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HistogramSeriesProperties.prototype, "tooltip", 2);

// packages/ag-charts-community/src/chart/series/cartesian/histogramSeries.ts
var defaultBinCount = 10;
var HistogramSeries = class extends CartesianSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      propertyKeys: DEFAULT_CARTESIAN_DIRECTION_KEYS,
      propertyNames: DEFAULT_CARTESIAN_DIRECTION_NAMES,
      categoryKey: void 0,
      pickModes: [1 /* NEAREST_NODE */, 0 /* EXACT_SHAPE_MATCH */],
      datumSelectionGarbageCollection: true,
      animationAlwaysPopulateNodeData: true,
      alwaysClip: true,
      animationResetFns: {
        datum: resetBarSelectionsFn,
        label: resetLabelFn
      }
    });
    this.properties = new HistogramSeriesProperties();
    this.calculatedBins = [];
  }
  get hasData() {
    return this.calculatedBins.length > 0;
  }
  // During processData phase, used to unify different ways of the user specifying
  // the bins. Returns bins in format[[min1, max1], [min2, max2], ... ].
  deriveBins(xDomain) {
    const binStarts = createTicks(xDomain[0], xDomain[1], defaultBinCount).ticks;
    const binSize = tickStep(xDomain[0], xDomain[1], defaultBinCount);
    const [firstBinEnd] = binStarts;
    const expandStartToBin = (n) => [n, n + binSize];
    return [[firstBinEnd - binSize, firstBinEnd], ...binStarts.map(expandStartToBin)];
  }
  calculateNiceBins(domain, binCount) {
    const startGuess = Math.floor(domain[0]);
    const stop = domain[1];
    const segments = binCount || 1;
    const { start: start2, binSize } = this.calculateNiceStart(startGuess, stop, segments);
    return this.getBins(start2, stop, binSize, segments);
  }
  getBins(start2, stop, step, count) {
    const bins = [];
    const precision = this.calculatePrecision(step);
    for (let i = 0; i < count; i++) {
      const a = Math.round((start2 + i * step) * precision) / precision;
      let b = Math.round((start2 + (i + 1) * step) * precision) / precision;
      if (i === count - 1) {
        b = Math.max(b, stop);
      }
      bins[i] = [a, b];
    }
    return bins;
  }
  calculatePrecision(step) {
    let precision = 10;
    if (Number.isFinite(step) && step > 0) {
      while (step < 1) {
        precision *= 10;
        step *= 10;
      }
    }
    return precision;
  }
  calculateNiceStart(a, b, segments) {
    const binSize = Math.abs(b - a) / segments;
    const order = Math.floor(Math.log10(binSize));
    const magnitude = Math.pow(10, order);
    const start2 = Math.floor(a / magnitude) * magnitude;
    return {
      start: start2,
      binSize
    };
  }
  async processData(dataController) {
    const { visible } = this;
    const { xKey, yKey, areaPlot, aggregation } = this.properties;
    const xScale = this.axes["x" /* X */]?.scale;
    const yScale = this.axes["y" /* Y */]?.scale;
    const { xScaleType, yScaleType } = this.getScaleInformation({ yScale, xScale });
    const visibleProps = visible ? {} : { forceValue: 0 };
    const props = [keyProperty(xKey, xScaleType), SORT_DOMAIN_GROUPS];
    if (yKey) {
      let aggProp = groupCount("groupAgg", { visible });
      if (aggregation === "count") {
      } else if (aggregation === "sum") {
        aggProp = groupSum("groupAgg", { visible });
      } else if (aggregation === "mean") {
        aggProp = groupAverage("groupAgg", { visible });
      }
      if (areaPlot) {
        aggProp = area("groupAgg", aggProp);
      }
      props.push(valueProperty(yKey, yScaleType, { invalidValue: void 0, ...visibleProps }), aggProp);
    } else {
      props.push(rowCountProperty("count"));
      let aggProp = groupCount("groupAgg", { visible });
      if (areaPlot) {
        aggProp = area("groupAgg", aggProp);
      }
      props.push(aggProp);
    }
    let calculatedBinDomains = [];
    const groupByFn = (dataSet) => {
      const xExtent = fixNumericExtent(dataSet.domain.keys[0]);
      if (xExtent.length === 0) {
        dataSet.domain.groups = [];
        return () => [];
      }
      const bins = isNumber(this.properties.binCount) ? this.calculateNiceBins(xExtent, this.properties.binCount) : this.properties.bins ?? this.deriveBins(xExtent);
      const binCount = bins.length;
      calculatedBinDomains = [...bins];
      return (keys) => {
        let xValue = keys[0];
        if (isDate(xValue)) {
          xValue = xValue.getTime();
        }
        if (!isNumber(xValue))
          return [];
        for (let i = 0; i < binCount; i++) {
          const nextBin = bins[i];
          if (xValue >= nextBin[0] && xValue < nextBin[1]) {
            return nextBin;
          }
          if (i === binCount - 1 && xValue <= nextBin[1]) {
            return nextBin;
          }
        }
        return [];
      };
    };
    const { dataModel, processedData: p } = await this.requestDataModel(dataController, this.data, {
      props,
      groupByFn
    });
    const processedData = p;
    const groups = /* @__PURE__ */ new Map();
    for (const [groupIndex, group] of processedData.groups.entries()) {
      const domain = group.keys;
      groups.set(createDatumId(...domain), { group, groupIndex });
    }
    this.calculatedBins = calculatedBinDomains.map((domain) => {
      const g = groups.get(createDatumId(...domain));
      if (g) {
        const { group, groupIndex } = g;
        const [[negativeAgg, positiveAgg] = [0, 0]] = group.aggregation;
        const datum = [...dataModel.forEachDatum(this, processedData, group, groupIndex)];
        const frequency = this.frequency(group);
        const total = negativeAgg + positiveAgg;
        return { domain, datum, groupIndex, frequency, total };
      } else {
        return { domain, datum: [], groupIndex: -1, frequency: 0, total: 0 };
      }
    });
    this.animationState.transition("updateData");
  }
  xCoordinateRange() {
    return [Number.NaN, Number.NaN];
  }
  yCoordinateRange() {
    return [Number.NaN, Number.NaN];
  }
  getSeriesDomain(direction) {
    const { processedData, dataModel } = this;
    if (!processedData || !dataModel || !this.calculatedBins.length)
      return { domain: [] };
    const yDomain = dataModel.getDomain(this, `groupAgg`, "aggregate", processedData).domain;
    const xDomainMin = this.calculatedBins[0].domain[0];
    const xDomainMax = this.calculatedBins[(this.calculatedBins?.length ?? 0) - 1].domain[1];
    if (direction === "x" /* X */) {
      return { domain: fixNumericExtent([xDomainMin, xDomainMax]) };
    }
    return { domain: fixNumericExtent(yDomain) };
  }
  getSeriesRange(_direction, [r0, r1]) {
    const { dataModel, processedData } = this;
    if (!dataModel || processedData?.type !== "grouped")
      return [Number.NaN, Number.NaN];
    const xScale = this.axes["x" /* X */].scale;
    const yMin = 0;
    let yMax = -Infinity;
    for (const { keys, aggregation } of processedData.groups) {
      const [[negativeAgg, positiveAgg] = [0, 0]] = aggregation;
      const [xDomainMin, xDomainMax] = keys;
      const [x0, x1] = findMinMax([xScale.convert(xDomainMin), xScale.convert(xDomainMax)]);
      if (x1 >= r0 && x0 <= r1) {
        const total = negativeAgg + positiveAgg;
        yMax = Math.max(yMax, total);
      }
    }
    if (yMin > yMax)
      return [Number.NaN, Number.NaN];
    return [yMin, yMax];
  }
  frequency(group) {
    return group.datumIndices.reduce((acc, datumIndices) => acc + datumIndices.length, 0);
  }
  /**
   * Creates the shared context for datum creation.
   * Caches expensive lookups and computations that are constant across all datums.
   *
   * Note: rawData and xValues are empty arrays because HistogramSeries
   * iterates over calculatedBins rather than raw data.
   */
  createNodeDatumContext(xAxis, yAxis) {
    const { xKey, yKey, xName, yName, label } = this.properties;
    const { contextNodeData, processedData } = this;
    const canIncrementallyUpdate = contextNodeData?.nodeData != null && processedData?.changeDescription != null;
    return {
      // Axes (from template method parameters)
      xAxis,
      yAxis,
      // Scales
      xScale: xAxis.scale,
      yScale: yAxis.scale,
      yAxisReversed: yAxis.isReversed(),
      // Data source (empty arrays - histogram uses calculatedBins instead)
      rawData: [],
      xValues: [],
      // Property lookups
      xKey,
      yKey,
      xName,
      yName,
      label,
      // Animation flag
      animationEnabled: !this.ctx.animationManager.isSkipped(),
      // Incremental update support
      canIncrementallyUpdate,
      nodes: canIncrementallyUpdate ? contextNodeData.nodeData : [],
      nodeIndex: 0
    };
  }
  /**
   * Creates label data for a histogram bin if labels are enabled.
   */
  createLabelData(ctx, bin, x, y, w, h) {
    const { label, yKey, xKey, xName, yName } = ctx;
    const { total, datum } = bin;
    if (!label.enabled || total === 0) {
      return void 0;
    }
    return {
      x: x + w / 2,
      y: y + h / 2,
      text: this.getLabelText(total, datum, yKey, "y", [], label, {
        value: total,
        datum,
        xKey,
        yKey,
        xName,
        yName
      })
    };
  }
  /**
   * Creates a skeleton HistogramNodeDatum with minimal required fields.
   * The node will be populated by updateNodeDatum.
   */
  createSkeletonNodeDatum(ctx, bin) {
    const { xKey, yKey } = ctx;
    const { domain, datum, groupIndex, frequency, total } = bin;
    return {
      series: this,
      datumIndex: groupIndex,
      datum,
      aggregatedValue: total,
      frequency,
      domain,
      yKey,
      xKey,
      x: 0,
      y: 0,
      xValue: 0,
      yValue: 0,
      width: 0,
      height: 0,
      midPoint: { x: 0, y: 0 },
      topLeftCornerRadius: false,
      topRightCornerRadius: false,
      bottomRightCornerRadius: false,
      bottomLeftCornerRadius: false,
      label: void 0,
      crisp: true
    };
  }
  /**
   * Updates an existing HistogramNodeDatum in-place.
   * This is more efficient than recreating the entire node when only data values change.
   */
  updateNodeDatum(ctx, node, bin) {
    const { xScale, yScale, yAxisReversed } = ctx;
    const { domain, datum, groupIndex, frequency, total } = bin;
    const mutableNode = node;
    const [xDomainMin, xDomainMax] = domain;
    const xMinPx = xScale.convert(xDomainMin);
    const xMaxPx = xScale.convert(xDomainMax);
    const yZeroPx = yScale.convert(0);
    const yMaxPx = yScale.convert(total);
    const w = Math.abs(xMaxPx - xMinPx);
    const h = Math.abs(yMaxPx - yZeroPx);
    const x = Math.min(xMinPx, xMaxPx);
    const y = Math.min(yZeroPx, yMaxPx);
    mutableNode.datumIndex = groupIndex;
    mutableNode.datum = datum;
    mutableNode.aggregatedValue = total;
    mutableNode.frequency = frequency;
    mutableNode.domain = domain;
    mutableNode.x = x;
    mutableNode.y = y;
    mutableNode.xValue = xMinPx;
    mutableNode.yValue = yMaxPx;
    mutableNode.width = w;
    mutableNode.height = h;
    if (mutableNode.midPoint) {
      mutableNode.midPoint.x = x + w / 2;
      mutableNode.midPoint.y = y + h / 2;
    } else {
      mutableNode.midPoint = { x: x + w / 2, y: y + h / 2 };
    }
    mutableNode.topLeftCornerRadius = !yAxisReversed;
    mutableNode.topRightCornerRadius = !yAxisReversed;
    mutableNode.bottomRightCornerRadius = yAxisReversed;
    mutableNode.bottomLeftCornerRadius = yAxisReversed;
    mutableNode.label = this.createLabelData(ctx, bin, x, y, w, h);
  }
  /**
   * Creates a HistogramNodeDatum for a single bin.
   * Creates a skeleton node and uses updateNodeDatum to populate it.
   */
  createNodeDatum(ctx, bin) {
    const node = this.createSkeletonNodeDatum(ctx, bin);
    this.updateNodeDatum(ctx, node, bin);
    return node;
  }
  /**
   * Template method hook: Iterates over calculated bins and creates/updates node datums.
   */
  populateNodeData(ctx) {
    const { processedData } = this;
    if (processedData?.type !== "grouped") {
      return;
    }
    for (const bin of this.calculatedBins) {
      upsertNodeDatum(
        ctx,
        bin,
        (c, b) => this.createNodeDatum(c, b),
        (c, n, b) => this.updateNodeDatum(c, n, b)
      );
    }
  }
  /**
   * Template method hook: Creates the result object shell.
   */
  initializeResult(ctx) {
    return {
      itemId: this.properties.yKey ?? this.id,
      nodeData: ctx.nodes,
      labelData: ctx.nodes,
      scales: this.calculateScaling(),
      animationValid: true,
      visible: this.visible || ctx.animationEnabled,
      styles: getItemStyles(this.getItemStyle.bind(this))
    };
  }
  /**
   * Template method hook: Trims arrays and sorts nodes for keyboard navigation.
   */
  finalizeNodeData(ctx) {
    super.finalizeNodeData(ctx);
    ctx.nodes.sort((a, b) => a.x - b.x);
  }
  nodeFactory() {
    return new Rect();
  }
  updateDatumSelection(opts) {
    const { nodeData, datumSelection } = opts;
    if (!processedDataIsAnimatable(this.processedData)) {
      return datumSelection.update(nodeData);
    }
    return datumSelection.update(
      nodeData,
      void 0,
      (datum) => createDatumId(...datum.domain)
    );
  }
  getItemStyle(datumIndex, isHighlight, highlightState) {
    const { properties } = this;
    const highlightStyle = this.getHighlightStyle(isHighlight, datumIndex, highlightState);
    return mergeDefaults(highlightStyle, properties.getStyle());
  }
  updateDatumStyles(opts) {
    const { datumSelection, isHighlight } = opts;
    datumSelection.each((node, datum) => {
      if (!datumSelection.isGarbage(node)) {
        datum.style = this.getItemStyle(datum.datumIndex, isHighlight);
      }
    });
  }
  updateDatumNodes(opts) {
    const { contextNodeData } = this;
    if (!contextNodeData) {
      return;
    }
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    const { shadow } = this.properties;
    const fillBBox = this.getShapeFillBBox();
    opts.datumSelection.each((rect2, datum) => {
      const style2 = datum.style ?? contextNodeData.styles[this.getHighlightState(highlightedDatum, opts.isHighlight, datum.datumIndex)];
      const { cornerRadius = 0 } = style2;
      const { topLeftCornerRadius, topRightCornerRadius, bottomRightCornerRadius, bottomLeftCornerRadius } = datum;
      rect2.setStyleProperties(style2, fillBBox);
      rect2.topLeftCornerRadius = topLeftCornerRadius ? cornerRadius : 0;
      rect2.topRightCornerRadius = topRightCornerRadius ? cornerRadius : 0;
      rect2.bottomRightCornerRadius = bottomRightCornerRadius ? cornerRadius : 0;
      rect2.bottomLeftCornerRadius = bottomLeftCornerRadius ? cornerRadius : 0;
      rect2.crisp = datum.crisp;
      rect2.fillShadow = shadow;
    });
  }
  updateLabelSelection(opts) {
    const { labelData, labelSelection } = opts;
    return labelSelection.update(labelData, (text2) => {
      text2.pointerEvents = 1 /* None */;
      text2.textAlign = "center";
      text2.textBaseline = "middle";
    });
  }
  updateLabelNodes(opts) {
    const labelEnabled = this.isLabelEnabled();
    const { isHighlight = false } = opts;
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    opts.labelSelection.each((text2, datum) => {
      const style2 = getLabelStyles(
        this,
        datum,
        this.properties,
        this.properties.label,
        isHighlight,
        activeHighlight
      );
      const { enabled, fontStyle, fontWeight: fontWeight2, fontSize, fontFamily, color: color2 } = style2;
      if (enabled && labelEnabled && datum?.label) {
        text2.text = datum.label.text;
        text2.x = datum.label.x;
        text2.y = datum.label.y;
        text2.fontStyle = fontStyle;
        text2.fontWeight = fontWeight2;
        text2.fontFamily = fontFamily;
        text2.fontSize = fontSize;
        text2.fill = color2;
        text2.visible = true;
        text2.fillOpacity = this.getHighlightStyle(isHighlight, datum.datumIndex).opacity ?? 1;
        text2.setBoxing(style2);
      } else {
        text2.visible = false;
      }
    });
  }
  initQuadTree(quadtree) {
    const { value: childNode } = this.contentGroup.children().next();
    if (childNode instanceof Group) {
      addHitTestersToQuadtree(quadtree, childNode.children());
    }
  }
  pickNodeClosestDatum(point) {
    return findQuadtreeMatch(this, point);
  }
  getTooltipContent(datumIndex) {
    const {
      id: seriesId,
      dataModel,
      processedData,
      axes,
      properties,
      ctx: { localeManager }
    } = this;
    const { xKey, xName, yKey, yName, tooltip, legendItemName } = properties;
    const xAxis = axes["x" /* X */];
    const yAxis = axes["y" /* Y */];
    if (!dataModel || processedData?.type !== "grouped" || !xAxis || !yAxis) {
      return;
    }
    const group = processedData.groups[datumIndex];
    const { aggregation, keys } = group;
    const [[negativeAgg, positiveAgg] = [0, 0]] = aggregation;
    const frequency = this.frequency(group);
    const domain = keys;
    const [rangeMin, rangeMax] = domain;
    const aggregatedValue = negativeAgg + positiveAgg;
    const datum = {
      data: [...dataModel.forEachDatum(this, processedData, group, datumIndex)],
      aggregatedValue,
      frequency,
      domain
    };
    const data = [
      {
        label: xName,
        fallbackLabel: xKey,
        value: `${this.getAxisValueText(xAxis, "tooltip", rangeMin, datum, xKey, legendItemName)} - ${this.getAxisValueText(xAxis, "tooltip", rangeMax, datum, xKey, legendItemName)}`
      },
      {
        label: localeManager.t("seriesHistogramTooltipFrequency"),
        value: this.getAxisValueText(yAxis, "tooltip", frequency, datum, yKey, legendItemName)
      }
    ];
    if (yKey != null) {
      let label;
      switch (properties.aggregation) {
        case "sum":
          label = localeManager.t("seriesHistogramTooltipSum", { yName: yName ?? yKey });
          break;
        case "mean":
          label = localeManager.t("seriesHistogramTooltipMean", { yName: yName ?? yKey });
          break;
        case "count":
          label = localeManager.t("seriesHistogramTooltipCount", { yName: yName ?? yKey });
          break;
      }
      data.push({
        label,
        value: this.getAxisValueText(yAxis, "tooltip", aggregatedValue, datum, yKey, legendItemName)
      });
    }
    return this.formatTooltipWithContext(
      tooltip,
      {
        symbol: this.legendItemSymbol(),
        data
      },
      {
        seriesId,
        datum,
        title: yName,
        xKey,
        // HistogramSeries is an outlier since it's callbacks don't use TDatum.
        xName,
        yKey,
        // HistogramSeries is an outlier since it's callbacks don't use TDatum.
        yName,
        xRange: [rangeMin, rangeMax],
        frequency,
        ...this.getItemStyle(datumIndex, false)
      }
    );
  }
  legendItemSymbol() {
    const { fill, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this.properties;
    return {
      marker: {
        fill: deepClone(fill) ?? "rgba(0, 0, 0, 0)",
        stroke: stroke3 ?? "rgba(0, 0, 0, 0)",
        fillOpacity,
        strokeOpacity,
        strokeWidth,
        lineDash,
        lineDashOffset
      }
    };
  }
  getLegendData(legendType) {
    if (legendType !== "category") {
      return [];
    }
    const {
      id: seriesId,
      ctx: { legendManager },
      visible
    } = this;
    const { xKey: itemId, yName, showInLegend } = this.properties;
    return [
      {
        legendType: "category",
        id: seriesId,
        itemId,
        seriesId,
        enabled: visible && legendManager.getItemEnabled({ seriesId, itemId }),
        label: {
          text: yName ?? itemId ?? "Frequency"
        },
        symbol: this.legendItemSymbol(),
        hideInLegend: !showInLegend
      }
    ];
  }
  resetDatumAnimation(data) {
    resetBarSelectionsDirect([data.datumSelection]);
  }
  animateEmptyUpdateReady({ datumSelection, labelSelection }) {
    const fns = prepareBarAnimationFunctions(collapsedStartingBarPosition(true, this.axes, "normal"), "unknown");
    fromToMotion(this.id, "datums", this.ctx.animationManager, [datumSelection], fns);
    seriesLabelFadeInAnimation(this, "labels", this.ctx.animationManager, labelSelection);
  }
  animateWaitingUpdateReady(data) {
    const fns = prepareBarAnimationFunctions(collapsedStartingBarPosition(true, this.axes, "normal"), "added");
    const dataDiff = {
      changed: true,
      added: /* @__PURE__ */ new Set(),
      updated: /* @__PURE__ */ new Set(),
      removed: /* @__PURE__ */ new Set(),
      moved: /* @__PURE__ */ new Set()
    };
    fromToMotion(
      this.id,
      "datums",
      this.ctx.animationManager,
      [data.datumSelection],
      fns,
      (_, datum) => createDatumId(...datum.domain),
      dataDiff
    );
    if (dataDiff?.changed) {
      seriesLabelFadeInAnimation(this, "labels", this.ctx.animationManager, data.labelSelection);
    }
  }
  isLabelEnabled() {
    return this.properties.label.enabled;
  }
  computeFocusBounds({ datumIndex }) {
    return computeBarFocusBounds(this, this.contextNodeData?.nodeData[datumIndex]);
  }
  hasItemStylers() {
    return this.properties.label.itemStyler != null;
  }
};
HistogramSeries.className = "HistogramSeries";
HistogramSeries.type = "histogram";

// packages/ag-charts-community/src/chart/series/cartesian/histogramSeriesModule.ts
var themeTemplate4 = {
  series: {
    fill: {
      $applySwitch: [
        { $path: "type" },
        { $palette: "fill" },
        ["gradient", FILL_GRADIENT_LINEAR_DEFAULTS],
        ["image", FILL_IMAGE_DEFAULTS],
        ["pattern", FILL_PATTERN_DEFAULTS]
      ]
    },
    stroke: { $palette: "stroke" },
    strokeWidth: 1,
    fillOpacity: 1,
    strokeOpacity: 1,
    lineDash: [0],
    lineDashOffset: 0,
    label: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: false,
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      fontWeight: { $ref: "fontWeight" },
      color: { $ref: "chartBackgroundColor" }
    },
    shadow: {
      enabled: false,
      color: DEFAULT_SHADOW_COLOUR,
      xOffset: 3,
      yOffset: 3,
      blur: 5
    },
    highlight: MULTI_SERIES_HIGHLIGHT_STYLE
  }
};
var HistogramSeriesModule = {
  type: "series",
  name: "histogram",
  chartType: "cartesian",
  // enterprise: true,
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: histogramSeriesOptionsDef,
  predictAxis: predictCartesianNonPrimitiveAxis,
  defaultAxes: {
    x: {
      type: "number" /* NUMBER */,
      position: "bottom" /* BOTTOM */
    },
    y: {
      type: "number" /* NUMBER */,
      position: "left" /* LEFT */
    }
  },
  axisKeys: { ["x" /* X */]: "xKeyAxis", ["y" /* Y */]: "yKeyAxis" },
  themeTemplate: themeTemplate4,
  create: (ctx) => new HistogramSeries(ctx)
};

// packages/ag-charts-community/src/chart/series/cartesian/lineAggregation.ts
var MAX_POINTS2 = 10;
function isIndexInAggregation(xValues, d0, d1, indexData, maxRange, datumIndex, xNeedsValueOf, xValuesLength) {
  const xValue = xValues[datumIndex];
  if (xValue === void 0)
    return false;
  const xRatio = Number.isFinite(d0) ? aggregationXRatioForXValue(xValue, d0, d1, xNeedsValueOf) : aggregationXRatioForDatumIndex(datumIndex, xValuesLength);
  const aggIndex = aggregationIndexForXRatio(xRatio, maxRange);
  return datumIndex === indexData[aggIndex + AGGREGATION_INDEX_X_MIN] || datumIndex === indexData[aggIndex + AGGREGATION_INDEX_X_MAX] || datumIndex === indexData[aggIndex + AGGREGATION_INDEX_Y_MIN] || datumIndex === indexData[aggIndex + AGGREGATION_INDEX_Y_MAX];
}
function buildIndicesFromAggregation2(xValues, d0, d1, indexData, maxRange, xNeedsValueOf, xValuesLength, reuseArray) {
  let count = 0;
  for (let datumIndex = 0; datumIndex < xValuesLength; datumIndex++) {
    if (isIndexInAggregation(xValues, d0, d1, indexData, maxRange, datumIndex, xNeedsValueOf, xValuesLength)) {
      count++;
    }
  }
  const indices = reuseArray?.length === count ? reuseArray : new Uint32Array(count);
  let idx = 0;
  for (let datumIndex = 0; datumIndex < xValuesLength; datumIndex++) {
    if (isIndexInAggregation(xValues, d0, d1, indexData, maxRange, datumIndex, xNeedsValueOf, xValuesLength)) {
      indices[idx++] = datumIndex;
    }
  }
  return indices;
}
function filterIndicesFromPrevious(prevIndices, xValues, d0, d1, indexData, maxRange, xNeedsValueOf, xValuesLength, reuseArray) {
  let count = 0;
  for (const datumIndex of prevIndices) {
    if (isIndexInAggregation(xValues, d0, d1, indexData, maxRange, datumIndex, xNeedsValueOf, xValuesLength)) {
      count++;
    }
  }
  const indices = reuseArray?.length === count ? reuseArray : new Uint32Array(count);
  let idx = 0;
  for (const datumIndex of prevIndices) {
    if (isIndexInAggregation(xValues, d0, d1, indexData, maxRange, datumIndex, xNeedsValueOf, xValuesLength)) {
      indices[idx++] = datumIndex;
    }
  }
  return indices;
}
function computeLineAggregation(domain, xValues, yValues, options) {
  const xValuesLength = xValues.length;
  if (xValuesLength < AGGREGATION_THRESHOLD)
    return;
  const [d0, d1] = domain;
  const { xNeedsValueOf, yNeedsValueOf, existingFilters } = options;
  let maxRange = aggregationRangeFittingPoints(xValues, d0, d1, { xNeedsValueOf });
  const existingFilter = existingFilters?.find((f) => f.maxRange === maxRange);
  let { indexData, valueData } = createAggregationIndices(xValues, yValues, yValues, d0, d1, maxRange, {
    xNeedsValueOf,
    yNeedsValueOf,
    reuseIndexData: existingFilter?.indexData,
    reuseValueData: existingFilter?.valueData
  });
  let indices = buildIndicesFromAggregation2(
    xValues,
    d0,
    d1,
    indexData,
    maxRange,
    xNeedsValueOf,
    xValuesLength,
    existingFilter?.indices
  );
  const filters = [{ maxRange, indices, indexData, valueData }];
  while (indices.length > MAX_POINTS2 && maxRange > 64) {
    const currentMaxRange = maxRange;
    const nextMaxRange = Math.trunc(currentMaxRange / 2);
    const nextExistingFilter = existingFilters?.find((f) => f.maxRange === nextMaxRange);
    const compacted = compactAggregationIndices(indexData, valueData, currentMaxRange, {
      reuseIndexData: nextExistingFilter?.indexData,
      reuseValueData: nextExistingFilter?.valueData
    });
    maxRange = compacted.maxRange;
    indexData = compacted.indexData;
    valueData = compacted.valueData;
    indices = filterIndicesFromPrevious(
      indices,
      xValues,
      d0,
      d1,
      indexData,
      maxRange,
      xNeedsValueOf,
      xValuesLength,
      nextExistingFilter?.indices
    );
    filters.push({ maxRange, indices, indexData, valueData });
  }
  filters.reverse();
  return filters;
}
function computeLineAggregationPartial(domain, xValues, yValues, options) {
  const xValuesLength = xValues.length;
  if (xValuesLength < AGGREGATION_THRESHOLD)
    return;
  const [d0, d1] = domain;
  const { xNeedsValueOf, yNeedsValueOf, targetRange, existingFilters } = options;
  const finestMaxRange = aggregationRangeFittingPoints(xValues, d0, d1, { xNeedsValueOf });
  const targetMaxRange = Math.min(finestMaxRange, nextPowerOf2(Math.max(targetRange, AGGREGATION_MIN_RANGE)));
  const existingFilter = existingFilters?.find((f) => f.maxRange === targetMaxRange);
  const { indexData, valueData } = createAggregationIndices(xValues, yValues, yValues, d0, d1, targetMaxRange, {
    xNeedsValueOf,
    yNeedsValueOf,
    reuseIndexData: existingFilter?.indexData,
    reuseValueData: existingFilter?.valueData
  });
  const indices = buildIndicesFromAggregation2(
    xValues,
    d0,
    d1,
    indexData,
    targetMaxRange,
    xNeedsValueOf,
    xValuesLength,
    existingFilter?.indices
  );
  const immediateLevel = {
    maxRange: targetMaxRange,
    indices,
    indexData,
    valueData
  };
  function computeRemaining() {
    const allLevels = computeLineAggregation([d0, d1], xValues, yValues, {
      xNeedsValueOf,
      yNeedsValueOf,
      existingFilters
    });
    return allLevels?.filter((level) => level.maxRange !== targetMaxRange) ?? [];
  }
  return { immediate: [immediateLevel], computeRemaining };
}
function aggregateLineData(scale2, xValues, yValues, domainInput, xNeedsValueOf, yNeedsValueOf) {
  const [d0, d1] = aggregationDomain(scale2, domainInput);
  return computeLineAggregation([d0, d1], xValues, yValues, { xNeedsValueOf, yNeedsValueOf });
}
var memoizedAggregateLineData = simpleMemorize2(aggregateLineData);
function aggregateLineDataFromDataModel(scale2, dataModel, processedData, yKey, series, existingFilters) {
  const xValues = dataModel.resolveColumnById(series, "xValue", processedData);
  const yValues = dataModel.resolveColumnById(series, yKey, processedData);
  const domainInput = dataModel.getDomain(series, "xValue", "value", processedData);
  const xNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "xValue", processedData);
  const yNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, yKey, processedData);
  if (existingFilters) {
    const [d0, d1] = aggregationDomain(scale2, domainInput);
    return computeLineAggregation([d0, d1], xValues, yValues, {
      xNeedsValueOf,
      yNeedsValueOf,
      existingFilters
    });
  }
  return memoizedAggregateLineData(scale2, xValues, yValues, domainInput, xNeedsValueOf, yNeedsValueOf);
}
function aggregateLineDataFromDataModelPartial(scale2, dataModel, processedData, yKey, series, targetRange, existingFilters) {
  const xValues = dataModel.resolveColumnById(series, "xValue", processedData);
  const yValues = dataModel.resolveColumnById(series, yKey, processedData);
  const domainInput = dataModel.getDomain(series, "xValue", "value", processedData);
  const xNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "xValue", processedData);
  const yNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, yKey, processedData);
  const [d0, d1] = aggregationDomain(scale2, domainInput);
  return computeLineAggregationPartial([d0, d1], xValues, yValues, {
    xNeedsValueOf,
    yNeedsValueOf,
    targetRange,
    existingFilters
  });
}

// packages/ag-charts-community/src/chart/series/cartesian/lineSeriesProperties.ts
var LineSeriesProperties = class extends CartesianSeriesProperties {
  constructor() {
    super(...arguments);
    this.stroke = "#874349";
    this.strokeWidth = 2;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.interpolation = new InterpolationProperties();
    this.marker = new SeriesMarker();
    this.label = new Label();
    this.tooltip = makeSeriesTooltip();
    this.connectMissingData = false;
    this.sparklineMode = false;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "xKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "yKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "xName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "yName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "yFilterKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "stackGroup", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "normalizedTo", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "title", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "interpolation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "styler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "marker", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "tooltip", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "connectMissingData", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineSeriesProperties.prototype, "sparklineMode", 2);

// packages/ag-charts-community/src/chart/series/cartesian/lineSeries.ts
var CROSS_FILTER_LINE_STROKE_OPACITY_FACTOR = 0.25;
var LineSeries = class extends CartesianSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      propertyKeys: DEFAULT_CARTESIAN_DIRECTION_KEYS,
      propertyNames: DEFAULT_CARTESIAN_DIRECTION_NAMES,
      categoryKey: "xValue",
      pickModes: [
        2 /* AXIS_ALIGNED */,
        1 /* NEAREST_NODE */,
        0 /* EXACT_SHAPE_MATCH */
      ],
      datumSelectionGarbageCollection: false,
      segmentedDataNodes: false,
      animationResetFns: {
        path: buildResetPathFn({ getVisible: () => this.visible, getOpacity: () => this.getOpacity() }),
        label: resetLabelFn,
        datum: (node, datum) => ({ ...resetMarkerFn(node), ...resetMarkerPositionFn(node, datum) })
      },
      clipFocusBox: false
    });
    this.properties = new LineSeriesProperties();
    this.aggregationManager = new AggregationManager();
  }
  get pickModeAxis() {
    return this.properties.sparklineMode ? "main" : "main-category";
  }
  isNormalized() {
    return this.properties.normalizedTo != null;
  }
  renderToOffscreenCanvas() {
    const hasMarkers = (this.contextNodeData?.nodeData?.length ?? 0) > 0;
    return hasMarkers && this.getDrawingMode(false) === "cutout" || super.renderToOffscreenCanvas();
  }
  async processData(dataController) {
    if (this.data == null)
      return;
    const { data, visible, seriesGrouping: { groupIndex = this.id, stackCount = 0 } = {} } = this;
    const { xKey, yKey, yFilterKey, connectMissingData, normalizedTo } = this.properties;
    const xScale = this.axes["x" /* X */]?.scale;
    const yScale = this.axes["y" /* Y */]?.scale;
    const { isContinuousX, xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale });
    const stacked = stackCount > 1 || normalizedTo != null;
    const common = { invalidValue: null };
    if (connectMissingData && stacked) {
      common.invalidValue = 0;
    }
    if (stacked && !visible) {
      common.forceValue = 0;
    }
    const idMap = {
      value: `area-stack-${groupIndex}-yValue`,
      marker: `area-stack-${groupIndex}-yValues-marker`
    };
    const props = [];
    const allowNullKey = this.properties.allowNullKeys ?? false;
    if (!isContinuousX || stacked) {
      props.push(keyProperty(xKey, xScaleType, { id: "xKey", allowNullKey }));
    }
    props.push(
      valueProperty(xKey, xScaleType, { id: "xValue", allowNullKey }),
      valueProperty(yKey, yScaleType, {
        id: `yValueRaw`,
        ...common,
        invalidValue: void 0
      })
    );
    if (yFilterKey != null) {
      props.push(valueProperty(yFilterKey, yScaleType, { id: "yFilterRaw" }));
    }
    if (stacked) {
      props.push(
        ...groupAccumulativeValueProperty(
          yKey,
          "normal",
          { id: `yValueCumulative`, ...common, groupId: idMap.marker },
          yScaleType
        )
      );
    }
    if (isDefined(normalizedTo)) {
      props.push(
        valueProperty(yKey, yScaleType, { id: `yValue`, ...common, groupId: idMap.value }),
        normaliseGroupTo(Object.values(idMap), normalizedTo)
      );
    }
    if (this.needsDataModelDiff()) {
      props.push(animationValidation(isContinuousX ? ["xValue"] : void 0));
      if (this.processedData) {
        props.push(diff(this.id, this.processedData));
      }
    }
    const { dataModel, processedData } = await this.requestDataModel(dataController, data, {
      props,
      groupByKeys: stacked,
      groupByData: !stacked
    });
    this.aggregateData(dataModel, processedData);
    this.animationState.transition("updateData");
  }
  yValueKey() {
    return this.isNormalized() ? "yValue" : "yValueRaw";
  }
  yCumulativeKey(processData) {
    return processData.type === "grouped" ? "yValueCumulative" : this.yValueKey();
  }
  xCoordinateRange(xValue, pixelSize) {
    const { marker } = this.properties;
    const x = this.axes["x" /* X */].scale.convert(xValue);
    const r = marker.enabled ? 0.5 * marker.size * pixelSize : 0;
    return [x - r, x + r];
  }
  yCoordinateRange(yValues, pixelSize) {
    const { marker } = this.properties;
    const y = this.axes["y" /* Y */].scale.convert(yValues[0]);
    const r = marker.enabled ? 0.5 * marker.size * pixelSize : 0;
    return [y - r, y + r];
  }
  getSeriesDomain(direction) {
    const { dataModel, processedData, axes } = this;
    if (!dataModel || !processedData)
      return { domain: [] };
    const yAxis = axes["y" /* Y */];
    if (direction === "x" /* X */) {
      const xDef = dataModel.resolveProcessedDataDefById(this, `xValue`);
      const xDomain = dataModel.getDomain(this, `xValue`, "value", processedData);
      if (xDef?.def.type === "value" && xDef.def.valueType === "category") {
        const sortMetadata = dataModel.getKeySortMetadata(this, "xValue", processedData);
        return { domain: xDomain.domain, sortMetadata };
      }
      return { domain: fixNumericExtent(extent(xDomain.domain)) };
    }
    const yExtent = this.domainForClippedRange(
      "y" /* Y */,
      [this.yCumulativeKey(processedData)],
      "xValue"
    );
    if (this.isNormalized() && yAxis instanceof NumberAxis && !(yAxis instanceof LogAxis)) {
      const fixedYExtent = Number.isFinite(yExtent[1] - yExtent[0]) ? [Math.min(yExtent[0], 0), Math.max(yExtent[1], 0)] : [];
      return { domain: fixNumericExtent(fixedYExtent) };
    } else {
      return { domain: fixNumericExtent(yExtent) };
    }
  }
  getSeriesRange(_direction, visibleRange) {
    return this.domainForVisibleRange(
      "y" /* Y */,
      [this.yCumulativeKey(this.processedData)],
      "xValue",
      visibleRange
    );
  }
  getZoomRangeFittingItems(xVisibleRange, yVisibleRange, minVisibleItems) {
    return this.zoomFittingVisibleItems(
      "xValue",
      [this.yCumulativeKey(this.processedData)],
      xVisibleRange,
      yVisibleRange,
      minVisibleItems
    );
  }
  getVisibleItems(xVisibleRange, yVisibleRange, minVisibleItems) {
    return this.countVisibleItems(
      "xValue",
      [this.yCumulativeKey(this.processedData)],
      xVisibleRange,
      yVisibleRange,
      minVisibleItems
    );
  }
  aggregateData(dataModel, processedData) {
    this.aggregationManager.markStale(processedData.input.count);
    if (processedData.type !== "ungrouped")
      return;
    if (processedDataIsAnimatable(processedData))
      return;
    const xAxis = this.axes["x" /* X */];
    if (xAxis == null)
      return;
    const targetRange = this.estimateTargetRange();
    this.aggregationManager.aggregate({
      computePartial: (existingFilters) => aggregateLineDataFromDataModelPartial(
        xAxis.scale.type,
        dataModel,
        processedData,
        this.yCumulativeKey(processedData),
        this,
        targetRange,
        existingFilters
      ),
      computeFull: (existingFilters) => aggregateLineDataFromDataModel(
        xAxis.scale.type,
        dataModel,
        processedData,
        this.yCumulativeKey(processedData),
        this,
        existingFilters
      ),
      targetRange
    });
    const filters = this.aggregationManager.filters;
    if (filters && filters.length > 0) {
      debugMetrics_exports.record(
        `${this.type}:aggregation`,
        filters.map((f) => f.maxRange)
      );
    }
  }
  estimateTargetRange() {
    const xAxis = this.axes["x" /* X */];
    if (xAxis?.scale?.range) {
      const [r0, r1] = xAxis.scale.range;
      return Math.abs(r1 - r0);
    }
    return this.ctx.scene?.canvas?.width ?? 800;
  }
  /**
   * Creates the context object for efficient node datum creation.
   * Caches expensive-to-compute values that are reused across all datum iterations
   * to minimize memory allocations. Only caches values that are expensive to
   * compute - cheap property lookups use `this` directly.
   */
  createNodeDatumContext(xAxis, yAxis) {
    const { dataModel, processedData } = this;
    if (!dataModel || !processedData)
      return void 0;
    const xScale = xAxis.scale;
    const yScale = yAxis.scale;
    const rawData = processedData.dataSources.get(this.id)?.data ?? [];
    const [r0, r1] = xScale.range;
    const range3 = Math.abs(r1 - r0);
    this.aggregationManager.ensureLevelForRange(range3);
    const dataAggregationFilter = this.aggregationManager.getFilterForRange(range3);
    const canIncrementallyUpdate = this.canIncrementallyUpdateNodes(dataAggregationFilter != null);
    return {
      xAxis,
      yAxis,
      rawData,
      xValues: dataModel.resolveColumnById(this, "xValue", processedData),
      yRawValues: dataModel.resolveColumnById(this, "yValueRaw", processedData),
      yCumulativeValues: dataModel.resolveColumnById(this, this.yCumulativeKey(processedData), processedData),
      selectionValues: this.properties.yFilterKey ? dataModel.resolveColumnById(this, "yFilterRaw", processedData) : void 0,
      xScale,
      yScale,
      xOffset: (xScale.bandwidth ?? 0) / 2,
      yOffset: (yScale.bandwidth ?? 0) / 2,
      size: this.properties.marker.enabled ? this.properties.marker.size : 0,
      yDomain: this.getSeriesDomain("y" /* Y */).domain,
      labelsEnabled: this.properties.label.enabled,
      animationEnabled: !this.ctx.animationManager.isSkipped(),
      canIncrementallyUpdate,
      dataAggregationFilter,
      range: range3,
      xKey: this.properties.xKey,
      yKey: this.properties.yKey,
      xName: this.properties.xName,
      yName: this.properties.yName,
      legendItemName: this.properties.legendItemName,
      connectMissingData: this.properties.connectMissingData,
      capDefaults: {
        lengthRatioMultiplier: this.properties.marker.getDiameter(),
        lengthMax: Infinity
      },
      nodes: canIncrementallyUpdate ? this.contextNodeData.nodeData : [],
      spanPoints: [],
      nodeIndex: 0
    };
  }
  /**
   * Processes a single datum and updates the context's nodes and spanPoints arrays.
   * Uses the scratch object to avoid per-iteration allocations.
   */
  handleDatum(ctx, scratch, datumIndex) {
    scratch.datum = ctx.rawData[datumIndex];
    scratch.xDatum = ctx.xValues[datumIndex];
    scratch.yDatum = ctx.yRawValues[datumIndex];
    scratch.yCumulative = ctx.yCumulativeValues[datumIndex];
    scratch.selected = ctx.selectionValues?.[datumIndex];
    scratch.x = ctx.xScale.convert(scratch.xDatum) + ctx.xOffset;
    scratch.y = ctx.yScale.convert(scratch.yCumulative) + ctx.yOffset;
    if (!Number.isFinite(scratch.x))
      return;
    if (scratch.yDatum != null) {
      const labelText = ctx.labelsEnabled ? this.getLabelText(
        scratch.yDatum,
        scratch.datum,
        ctx.yKey,
        "y",
        ctx.yDomain,
        this.properties.label,
        {
          value: scratch.yDatum,
          datum: scratch.datum,
          xKey: ctx.xKey,
          yKey: ctx.yKey,
          xName: ctx.xName,
          yName: ctx.yName,
          legendItemName: ctx.legendItemName
        }
      ) : void 0;
      const canReuseNode = ctx.canIncrementallyUpdate && ctx.nodeIndex < ctx.nodes.length;
      if (canReuseNode) {
        const existingNode = ctx.nodes[ctx.nodeIndex];
        existingNode.datum = scratch.datum;
        existingNode.datumIndex = datumIndex;
        existingNode.point = { x: scratch.x, y: scratch.y, size: ctx.size };
        existingNode.midPoint = { x: scratch.x, y: scratch.y };
        existingNode.cumulativeValue = scratch.yCumulative;
        existingNode.yValue = scratch.yDatum;
        existingNode.xValue = scratch.xDatum;
        existingNode.labelText = labelText;
        existingNode.selected = scratch.selected;
      } else {
        ctx.nodes.push({
          series: this,
          datum: scratch.datum,
          datumIndex,
          yKey: ctx.yKey,
          xKey: ctx.xKey,
          point: { x: scratch.x, y: scratch.y, size: ctx.size },
          midPoint: { x: scratch.x, y: scratch.y },
          cumulativeValue: scratch.yCumulative,
          yValue: scratch.yDatum,
          xValue: scratch.xDatum,
          capDefaults: ctx.capDefaults,
          labelText,
          selected: scratch.selected
        });
      }
      ctx.nodeIndex++;
    }
    this.updateSpanPoints(ctx, scratch);
  }
  /**
   * Updates span points array based on current scratch values.
   */
  updateSpanPoints(ctx, scratch) {
    const currentSpanPoints = ctx.spanPoints.at(-1);
    if (scratch.yDatum != null) {
      const spanPoint = {
        point: { x: scratch.x, y: scratch.y },
        xDatum: scratch.xDatum,
        yDatum: scratch.yCumulative
      };
      if (Array.isArray(currentSpanPoints)) {
        currentSpanPoints.push(spanPoint);
      } else if (currentSpanPoints == null) {
        ctx.spanPoints.push([spanPoint]);
      } else {
        currentSpanPoints.skip += 1;
        ctx.spanPoints.push([spanPoint]);
      }
    } else if (!ctx.connectMissingData) {
      if (Array.isArray(currentSpanPoints) || currentSpanPoints == null) {
        ctx.spanPoints.push({ skip: 0 });
      } else {
        currentSpanPoints.skip += 1;
      }
    }
  }
  /**
   * Populates node data by iterating over the visible range.
   */
  populateNodeData(ctx) {
    const scratch = {
      datum: void 0,
      xDatum: void 0,
      yDatum: void 0,
      yCumulative: 0,
      selected: void 0,
      x: 0,
      y: 0
    };
    const indices = ctx.dataAggregationFilter?.indices;
    let [start2, end3] = this.visibleRangeIndices("xValue", ctx.xAxis.range, indices);
    start2 = Math.max(start2 - 1, 0);
    end3 = Math.min(end3 + 1, indices?.length ?? ctx.xValues.length);
    if (this.processedData.input.count < 1e3) {
      start2 = 0;
      end3 = this.processedData.input.count;
    }
    for (let i = start2; i < end3; i += 1) {
      this.handleDatum(ctx, scratch, indices?.[i] ?? i);
    }
  }
  /**
   * Creates the initial result context object.
   * Note: strokeData and segments are computed in assembleResult, but we need valid defaults
   * for the early return case (when !this.visible).
   */
  initializeResult(ctx) {
    return {
      itemId: ctx.yKey,
      nodeData: ctx.nodes,
      labelData: ctx.nodes,
      strokeData: { itemId: ctx.yKey, spans: [] },
      // Default for early return
      scales: this.calculateScaling(),
      visible: this.visible,
      crossFiltering: false,
      styles: getMarkerStyles(this, this.properties, this.properties.marker),
      segments: void 0
    };
  }
  /**
   * Assembles the final result by computing strokeData, crossFiltering, and segments.
   */
  assembleResult(ctx, result) {
    const strokeSpans = ctx.spanPoints.flatMap((p) => {
      return Array.isArray(p) ? interpolatePoints(p, this.properties.interpolation) : [];
    });
    result.strokeData = { itemId: ctx.yKey, spans: strokeSpans };
    result.crossFiltering = ctx.selectionValues?.some((selectionValue, index) => selectionValue === ctx.yRawValues[index]) ?? false;
    result.segments = calculateSegments(
      this.properties.segmentation,
      ctx.xAxis,
      ctx.yAxis,
      this.chart.seriesRect,
      this.ctx.scene,
      false
    );
    return result;
  }
  isPathOrSelectionDirty() {
    return this.properties.marker.isDirty();
  }
  updatePathNodes(opts) {
    const {
      paths: [lineNode],
      visible,
      animationEnabled
    } = opts;
    const crossFiltering = this.contextNodeData?.crossFiltering === true;
    const merged = mergeDefaults(this.getHighlightStyle(), this.getStyle());
    const { strokeWidth, stroke: stroke3, strokeOpacity, lineDash, lineDashOffset, opacity } = merged;
    const segments = this.contextNodeData?.segments;
    lineNode.setProperties({
      segments,
      fill: void 0,
      lineJoin: "round",
      pointerEvents: 1 /* None */,
      opacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity: strokeOpacity * (crossFiltering ? CROSS_FILTER_LINE_STROKE_OPACITY_FACTOR : 1),
      lineDash,
      lineDashOffset
    });
    lineNode.datum = segments;
    if (!animationEnabled) {
      lineNode.visible = visible;
    }
    updateClipPath(this, lineNode);
  }
  updateDatumSelection(opts) {
    let { nodeData } = opts;
    const { datumSelection } = opts;
    const { contextNodeData, processedData, axes, properties } = this;
    const { marker } = properties;
    const markersEnabled = contextNodeData?.crossFiltering === true || markerEnabled(processedData.input.count, axes["x" /* X */].scale, marker);
    nodeData = markersEnabled ? nodeData : [];
    if (marker.isDirty()) {
      datumSelection.clear();
      datumSelection.cleanup();
    }
    if (!processedDataIsAnimatable(this.processedData)) {
      return datumSelection.update(nodeData);
    }
    return datumSelection.update(nodeData, void 0, (datum) => createDatumId(datum.xValue));
  }
  updateDatumStyles(opts) {
    const { datumSelection, isHighlight } = opts;
    const { marker } = this.properties;
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    datumSelection.each((node, datum) => {
      if (!datumSelection.isGarbage(node)) {
        const highlightState = this.getHighlightState(highlightedDatum, opts.isHighlight, datum.datumIndex);
        const stylerStyle = this.getStyle(highlightState);
        const { stroke: stroke3, strokeWidth, strokeOpacity } = stylerStyle;
        const params = this.makeItemStylerParams(
          this.dataModel,
          this.processedData,
          datum.datumIndex,
          stylerStyle.marker
        );
        datum.style = this.getMarkerStyle(
          marker,
          datum,
          params,
          { isHighlight, highlightState },
          stylerStyle.marker,
          {
            stroke: stroke3,
            strokeWidth,
            strokeOpacity
          }
        );
      }
    });
  }
  updateDatumNodes(opts) {
    const { contextNodeData } = this;
    if (!contextNodeData) {
      return;
    }
    const { datumSelection, isHighlight } = opts;
    const applyTranslation = this.ctx.animationManager.isSkipped();
    const fillBBox = this.getShapeFillBBox();
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    const drawingMode = this.getDrawingMode(isHighlight, opts.drawingMode);
    datumSelection.each((node, datum) => {
      const state = this.getHighlightState(highlightedDatum, isHighlight, datum.datumIndex);
      const style2 = datum.style ?? contextNodeData.styles[state];
      this.applyMarkerStyle(style2, node, datum.point, fillBBox, {
        applyTranslation,
        selected: datum.selected
      });
      node.drawingMode = this.resolveMarkerDrawingModeForState(drawingMode, style2);
    });
    if (!isHighlight) {
      this.properties.marker.markClean();
    }
  }
  updateLabelSelection(opts) {
    return opts.labelSelection.update(this.isLabelEnabled() ? opts.labelData : []);
  }
  updateLabelNodes(opts) {
    const { isHighlight = false } = opts;
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const params = this.makeLabelFormatterParams();
    opts.labelSelection.each((text2, datum) => {
      const style2 = getLabelStyles(this, datum, params, this.properties.label, isHighlight, activeHighlight);
      const { enabled, fontStyle, fontWeight: fontWeight2, fontSize, fontFamily, color: color2 } = style2;
      if (enabled && datum?.labelText) {
        text2.fontStyle = fontStyle;
        text2.fontWeight = fontWeight2;
        text2.fontSize = fontSize;
        text2.fontFamily = fontFamily;
        text2.textAlign = "center";
        text2.textBaseline = "bottom";
        text2.text = datum.labelText;
        text2.x = datum.point.x;
        text2.y = datum.point.y - 10;
        text2.fill = color2;
        text2.visible = true;
        text2.fillOpacity = this.getHighlightStyle(isHighlight, datum.datumIndex).opacity ?? 1;
        text2.setBoxing(style2);
      } else {
        text2.visible = false;
      }
    });
  }
  makeStylerParams(highlightStateEnum) {
    const { id: seriesId } = this;
    const { marker, lineDash, lineDashOffset, stroke: stroke3, strokeOpacity, strokeWidth, xKey, yKey } = this.properties;
    const highlightState = toHighlightString(highlightStateEnum ?? 0 /* None */);
    return {
      marker: {
        fill: marker.fill,
        fillOpacity: marker.fillOpacity,
        size: marker.size,
        shape: marker.shape,
        stroke: marker.stroke,
        strokeOpacity: marker.strokeOpacity,
        strokeWidth: marker.strokeWidth,
        lineDash: marker.lineDash,
        lineDashOffset: marker.lineDashOffset
      },
      highlightState,
      lineDash,
      lineDashOffset,
      seriesId,
      stroke: stroke3,
      strokeOpacity,
      strokeWidth,
      xKey,
      yKey
    };
  }
  makeItemStylerParams(dataModel, processedData, datumIndex, style2) {
    const { xKey, yKey } = this.properties;
    const xValue = dataModel.resolveColumnById(this, `xValue`, processedData)[datumIndex];
    const yValue = dataModel.resolveColumnById(this, `yValueRaw`, processedData)[datumIndex];
    const xDomain = dataModel.getDomain(this, `xValue`, "key", processedData).domain;
    const yDomain = dataModel.getDomain(this, this.yCumulativeKey(processedData), "value", processedData).domain;
    const fill = this.filterItemStylerFillParams(style2.fill) ?? style2.fill;
    return {
      ...datumStylerProperties(xValue, yValue, xKey, yKey, xDomain, yDomain),
      xValue,
      yValue,
      ...style2,
      fill
    };
  }
  makeLabelFormatterParams() {
    const { xKey, xName, yKey, yName, legendItemName } = this.properties;
    return { xKey, xName, yKey, yName, legendItemName };
  }
  getTooltipContent(datumIndex) {
    const { id: seriesId, dataModel, processedData, axes, properties } = this;
    const { xKey, xName, yKey, yName, tooltip, legendItemName } = properties;
    const allowNullKeys = properties.allowNullKeys ?? false;
    const xAxis = axes["x" /* X */];
    const yAxis = axes["y" /* Y */];
    if (!dataModel || !processedData || !xAxis || !yAxis)
      return;
    const datum = processedData.dataSources.get(this.id)?.data?.[datumIndex];
    const xValue = dataModel.resolveColumnById(this, `xValue`, processedData)[datumIndex];
    const yValue = dataModel.resolveColumnById(this, `yValueRaw`, processedData)[datumIndex];
    if (xValue === void 0 && !allowNullKeys)
      return;
    const stylerStyle = this.getStyle();
    const params = this.makeItemStylerParams(dataModel, processedData, datumIndex, stylerStyle.marker);
    const format = this.getMarkerStyle(
      this.properties.marker,
      { datumIndex, datum },
      params,
      { isHighlight: false },
      stylerStyle.marker
    );
    return this.formatTooltipWithContext(
      tooltip,
      {
        heading: this.getAxisValueText(xAxis, "tooltip", xValue, datum, xKey, legendItemName, allowNullKeys),
        symbol: this.legendItemSymbol(),
        data: [
          {
            label: yName,
            fallbackLabel: yKey,
            value: this.getAxisValueText(yAxis, "tooltip", yValue, datum, yKey, legendItemName),
            missing: isTooltipValueMissing(yValue)
          }
        ]
      },
      {
        seriesId,
        datum,
        title: yName,
        xKey,
        xName,
        yKey,
        yName,
        ...format,
        ...this.getModuleTooltipParams()
      }
    );
  }
  legendItemSymbol() {
    const { stroke: stroke3, strokeOpacity, strokeWidth, lineDash, marker } = this.getStyle();
    const markerStyle = this.getMarkerStyle(
      this.properties.marker,
      {},
      void 0,
      {
        isHighlight: false,
        checkForHighlight: false
      },
      {
        size: marker.size,
        shape: marker.shape,
        fill: marker.fill,
        fillOpacity: marker.fillOpacity,
        stroke: marker.stroke,
        strokeOpacity: marker.strokeOpacity,
        strokeWidth: marker.strokeWidth,
        lineDash: marker.lineDash,
        lineDashOffset: marker.lineDashOffset
      }
    );
    return {
      marker: {
        ...markerStyle,
        enabled: this.properties.marker.enabled
      },
      line: {
        enabled: true,
        stroke: stroke3,
        strokeOpacity,
        strokeWidth,
        lineDash
      }
    };
  }
  getLegendData(legendType) {
    if (legendType !== "category") {
      return [];
    }
    const {
      id: seriesId,
      ctx: { legendManager },
      visible
    } = this;
    const { yKey: itemId, yName, title, legendItemName, showInLegend } = this.properties;
    return [
      {
        legendType,
        id: seriesId,
        itemId,
        legendItemName,
        seriesId,
        enabled: visible && legendManager.getItemEnabled({ seriesId, itemId }),
        label: {
          text: legendItemName ?? title ?? yName ?? itemId
        },
        symbol: this.legendItemSymbol(),
        hideInLegend: !showInLegend
      }
    ];
  }
  updatePaths(opts) {
    this.updateLinePaths(opts.paths, opts.contextData);
  }
  updateLinePaths(paths, contextData) {
    const spans = contextData.strokeData.spans;
    const [lineNode] = paths;
    lineNode.path.clear();
    plotLinePathStroke(lineNode, spans);
    lineNode.markDirty("LineSeries");
  }
  resetDatumAnimation(data) {
    resetMarkerSelectionsDirect([data.datumSelection]);
  }
  animateEmptyUpdateReady(animationData) {
    const { datumSelection, labelSelection, annotationSelections, contextData, paths } = animationData;
    const { animationManager } = this.ctx;
    this.updateLinePaths(paths, contextData);
    pathSwipeInAnimation(this, animationManager, ...paths);
    resetMotion([datumSelection], resetMarkerPositionFn);
    markerSwipeScaleInAnimation(
      this,
      animationManager,
      { ...this.getAnimationDrawingModes(), phase: "initial" },
      datumSelection
    );
    seriesLabelFadeInAnimation(this, "labels", animationManager, labelSelection);
    seriesLabelFadeInAnimation(this, "annotations", animationManager, ...annotationSelections);
  }
  animateReadyResize(animationData) {
    const { contextData, paths } = animationData;
    this.updateLinePaths(paths, contextData);
    super.animateReadyResize(animationData);
  }
  animateWaitingUpdateReady(animationData) {
    const { animationManager } = this.ctx;
    const {
      datumSelection,
      labelSelection: labelSelections,
      annotationSelections,
      contextData,
      paths,
      previousContextData
    } = animationData;
    const [path] = paths;
    if (contextData.visible === false && previousContextData?.visible === false)
      return;
    this.resetDatumAnimation(animationData);
    this.resetLabelAnimation(animationData);
    const update = () => {
      this.resetPathAnimation(animationData);
      this.updateLinePaths(paths, contextData);
    };
    const skip = () => {
      animationManager.skipCurrentBatch();
      update();
    };
    if (contextData == null || previousContextData == null) {
      update();
      markerFadeInAnimation(this, animationManager, "added", this.getAnimationDrawingModes(), datumSelection);
      staticFromToMotion(
        this.id,
        "path_properties",
        animationManager,
        [path],
        { opacity: 0 },
        { opacity: this.getOpacity() },
        { phase: "add" }
      );
      seriesLabelFadeInAnimation(this, "labels", animationManager, labelSelections);
      seriesLabelFadeInAnimation(this, "annotations", animationManager, ...annotationSelections);
      return;
    }
    if (contextData.crossFiltering !== previousContextData.crossFiltering) {
      skip();
      return;
    }
    const fns = prepareLinePathAnimation(
      contextData,
      previousContextData,
      this.processedData?.reduced?.diff?.[this.id],
      this.getOpacity()
    );
    if (fns === void 0) {
      skip();
      return;
    } else if (fns.status === "no-op") {
      return;
    }
    fromToMotion(this.id, "path_properties", animationManager, [path], fns.stroke.pathProperties);
    if (fns.status === "added") {
      this.updateLinePaths(paths, contextData);
    } else if (fns.status === "removed") {
      this.updateLinePaths(paths, previousContextData);
    } else {
      pathMotion(this.id, "path_update", animationManager, [path], fns.stroke.path);
    }
    if (fns.hasMotion) {
      markerFadeInAnimation(this, animationManager, void 0, this.getAnimationDrawingModes(), datumSelection);
      seriesLabelFadeInAnimation(this, "labels", animationManager, labelSelections);
      seriesLabelFadeInAnimation(this, "annotations", animationManager, ...annotationSelections);
    }
    this.ctx.animationManager.animate({
      id: this.id,
      groupId: "reset_after_animation",
      phase: "trailing",
      from: {},
      to: {},
      onComplete: () => this.updateLinePaths(paths, contextData)
    });
  }
  isLabelEnabled() {
    return this.properties.label.enabled;
  }
  getBandScalePadding() {
    return { inner: 1, outer: 0.1 };
  }
  nodeFactory() {
    return new Marker();
  }
  getStyle(highlightState) {
    const { styler, marker, lineDash, lineDashOffset, stroke: stroke3, strokeOpacity, strokeWidth } = this.properties;
    const { size, shape, fill = "transparent", fillOpacity } = marker;
    let stylerResult = {};
    if (styler) {
      const stylerParams = this.makeStylerParams(highlightState);
      const cbResult = this.cachedCallWithContext(styler, stylerParams) ?? {};
      const resolved = this.ctx.optionsGraphService.resolvePartial(
        ["series", `${this.declarationOrder}`],
        cbResult,
        { pick: false }
      );
      stylerResult = resolved ?? {};
    }
    stylerResult.marker ?? (stylerResult.marker = {});
    return {
      lineDash: stylerResult.lineDash ?? lineDash,
      lineDashOffset: stylerResult.lineDashOffset ?? lineDashOffset,
      stroke: stylerResult.stroke ?? stroke3,
      strokeOpacity: stylerResult.strokeOpacity ?? strokeOpacity,
      strokeWidth: stylerResult.strokeWidth ?? strokeWidth,
      marker: {
        fill: stylerResult.marker.fill ?? fill,
        fillOpacity: stylerResult.marker.fillOpacity ?? fillOpacity,
        shape: stylerResult.marker.shape ?? shape,
        size: stylerResult.marker.size ?? size,
        lineDash: stylerResult.marker.lineDash ?? marker.lineDash ?? lineDash,
        lineDashOffset: stylerResult.marker.lineDashOffset ?? marker.lineDashOffset ?? lineDashOffset,
        stroke: stylerResult.marker.stroke ?? marker.stroke ?? stroke3,
        strokeOpacity: stylerResult.marker.strokeOpacity ?? marker.strokeOpacity ?? strokeOpacity,
        strokeWidth: stylerResult.marker.strokeWidth ?? marker.strokeWidth ?? strokeWidth
      }
    };
  }
  getFormattedMarkerStyle(datum) {
    const stylerStyle = this.getStyle();
    const params = this.makeItemStylerParams(
      this.dataModel,
      this.processedData,
      datum.datumIndex,
      stylerStyle.marker
    );
    return this.getMarkerStyle(
      this.properties.marker,
      datum,
      params,
      { isHighlight: true },
      void 0,
      stylerStyle
    );
  }
  computeFocusBounds(opts) {
    return computeMarkerFocusBounds(this, opts);
  }
  hasItemStylers() {
    return this.properties.styler != null || this.properties.marker.itemStyler != null || this.properties.label.itemStyler != null;
  }
};
LineSeries.className = "LineSeries";
LineSeries.type = "line";

// packages/ag-charts-community/src/chart/series/cartesian/lineSeriesModule.ts
var themeTemplate5 = {
  series: {
    stroke: SAFE_STROKE_FILL_OPERATION,
    strokeWidth: 2,
    strokeOpacity: 1,
    lineDash: [0],
    lineDashOffset: 0,
    interpolation: {
      type: "linear"
    },
    marker: {
      shape: "circle",
      size: 7,
      strokeWidth: { $isUserOption: ["./stroke", 1, 0] },
      fill: {
        $applySwitch: [
          { $path: "type" },
          { $palette: "fill" },
          ["gradient", FILL_GRADIENT_RADIAL_REVERSED_DEFAULTS],
          ["image", FILL_IMAGE_DEFAULTS],
          ["pattern", FILL_PATTERN_DEFAULTS]
        ]
      },
      stroke: { $palette: "stroke" }
    },
    label: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: false,
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      fontWeight: { $ref: "fontWeight" },
      color: { $ref: "textColor" }
    },
    tooltip: {
      range: {
        $if: [
          { $eq: [{ $path: ["/tooltip/range", "nearest"] }, "area"] },
          "nearest",
          { $path: ["/tooltip/range", "nearest"] }
        ]
      },
      position: {
        anchorTo: { $path: ["/tooltip/position/anchorTo", "node"] }
      }
    },
    highlight: MARKER_SERIES_HIGHLIGHT_STYLE,
    segmentation: SEGMENTATION_DEFAULTS
  }
};
var LineSeriesModule = {
  type: "series",
  name: "line",
  chartType: "cartesian",
  stackable: true,
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: lineSeriesOptionsDef,
  predictAxis: predictCartesianNonPrimitiveAxis,
  defaultAxes: {
    y: {
      type: "number" /* NUMBER */,
      position: "left" /* LEFT */
    },
    x: {
      type: "category" /* CATEGORY */,
      position: "bottom" /* BOTTOM */
    }
  },
  axisKeys: { ["x" /* X */]: "xKeyAxis", ["y" /* Y */]: "yKeyAxis" },
  themeTemplate: themeTemplate5,
  create: (ctx) => new LineSeries(ctx)
};

// packages/ag-charts-community/src/chart/series/cartesian/scatterSeries.ts
var ScatterSeries = class extends BubbleSeries {
};
ScatterSeries.className = "ScatterSeries";
ScatterSeries.type = "scatter";

// packages/ag-charts-community/src/chart/series/cartesian/scatterSeriesModule.ts
var themeTemplate6 = {
  series: {
    shape: "circle",
    size: 7,
    fill: {
      $applySwitch: [
        { $path: "type" },
        { $palette: "fill" },
        ["gradient", FILL_GRADIENT_RADIAL_REVERSED_DEFAULTS],
        ["image", FILL_IMAGE_DEFAULTS],
        ["pattern", FILL_PATTERN_DEFAULTS]
      ]
    },
    stroke: { $palette: "stroke" },
    fillOpacity: 0.8,
    maxRenderedItems: 2e3,
    label: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: false,
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      fontWeight: { $ref: "fontWeight" },
      color: { $ref: "textColor" }
    },
    tooltip: {
      range: {
        $if: [
          { $eq: [{ $path: ["/tooltip/range", "nearest"] }, "area"] },
          "nearest",
          { $path: ["/tooltip/range", "nearest"] }
        ]
      },
      position: {
        anchorTo: { $path: ["/tooltip/position/anchorTo", "node"] }
      }
    },
    highlight: MULTI_SERIES_HIGHLIGHT_STYLE
  }
};
var ScatterSeriesModule = {
  type: "series",
  name: "scatter",
  chartType: "cartesian",
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: scatterSeriesOptionsDef,
  predictAxis: predictCartesianAxis,
  defaultAxes: {
    x: {
      type: "number" /* NUMBER */,
      position: "bottom" /* BOTTOM */
    },
    y: {
      type: "number" /* NUMBER */,
      position: "left" /* LEFT */
    }
  },
  axisKeys: { ["x" /* X */]: "xKeyAxis", ["y" /* Y */]: "yKeyAxis" },
  themeTemplate: themeTemplate6,
  create: (ctx) => new ScatterSeries(ctx)
};

// packages/ag-charts-community/src/chart/series/polar/donutSeriesProperties.ts
var DonutTitle = class extends Caption {
  constructor() {
    super(...arguments);
    this.showInLegend = false;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutTitle.prototype, "showInLegend", 2);
var DonutInnerLabel = class extends Label {
  constructor() {
    super(...arguments);
    this.spacing = 2;
  }
  set(properties, _reset) {
    return super.set(properties);
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutInnerLabel.prototype, "text", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutInnerLabel.prototype, "spacing", 2);
var DonutInnerCircle = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.fill = "transparent";
    this.fillOpacity = 1;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutInnerCircle.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutInnerCircle.prototype, "fillOpacity", 2);
var DonutSeriesCalloutLabel = class extends Label {
  constructor() {
    super(...arguments);
    this.offset = 3;
    this.minAngle = 0;
    this.minSpacing = 4;
    this.maxCollisionOffset = 50;
    this.avoidCollisions = true;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesCalloutLabel.prototype, "offset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesCalloutLabel.prototype, "minAngle", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesCalloutLabel.prototype, "minSpacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesCalloutLabel.prototype, "maxCollisionOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesCalloutLabel.prototype, "avoidCollisions", 2);
var DonutSeriesSectorLabel = class extends Label {
  constructor() {
    super(...arguments);
    this.positionOffset = 0;
    this.positionRatio = 0.5;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesSectorLabel.prototype, "positionOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesSectorLabel.prototype, "positionRatio", 2);
var DonutSeriesCalloutLine = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.length = 10;
    this.strokeWidth = 1;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesCalloutLine.prototype, "colors", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesCalloutLine.prototype, "length", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesCalloutLine.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesCalloutLine.prototype, "itemStyler", 2);
var DonutSeriesProperties = class extends SeriesProperties {
  constructor() {
    super(...arguments);
    this.defaultColorRange = [];
    this.defaultPatternFills = [];
    this.fills = Object.values(DEFAULT_FILLS);
    this.strokes = Object.values(DEFAULT_STROKES);
    this.fillOpacity = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.cornerRadius = 0;
    this.rotation = 0;
    this.outerRadiusOffset = 0;
    this.outerRadiusRatio = 1;
    this.strokeWidth = 1;
    this.sectorSpacing = 0;
    this.hideZeroValueSectorsInLegend = false;
    this.innerLabels = new PropertiesArray(DonutInnerLabel);
    this.title = new DonutTitle();
    this.innerCircle = new DonutInnerCircle();
    this.shadow = new DropShadow();
    this.calloutLabel = new DonutSeriesCalloutLabel();
    this.sectorLabel = new DonutSeriesSectorLabel();
    this.calloutLine = new DonutSeriesCalloutLine();
    this.tooltip = makeSeriesTooltip();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "angleKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "angleName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "angleFilterKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "radiusKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "radiusName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "radiusMin", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "radiusMax", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "calloutLabelKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "calloutLabelName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "sectorLabelKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "sectorLabelName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "legendItemKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "defaultColorRange", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "defaultPatternFills", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "fills", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "strokes", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "itemStyler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "rotation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "outerRadiusOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "outerRadiusRatio", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "innerRadiusOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "innerRadiusRatio", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "sectorSpacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "hideZeroValueSectorsInLegend", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "innerLabels", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "title", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "innerCircle", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "shadow", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "calloutLabel", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "sectorLabel", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "calloutLine", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DonutSeriesProperties.prototype, "tooltip", 2);

// packages/ag-charts-community/src/chart/series/polar/pieUtil.ts
function preparePieSeriesAnimationFunctions(initialLoad, rotationDegrees, scaleFn, oldScaleFn) {
  const scale2 = [scaleFn.convert(0), scaleFn.convert(1)];
  const oldScale = [oldScaleFn.convert(0), oldScaleFn.convert(1)];
  const rotation = Math.PI / -2 + toRadians(rotationDegrees);
  const phase = initialLoad ? "initial" : "update";
  const scaleToNewRadius = ({ radius }) => {
    return { innerRadius: scale2[0], outerRadius: scale2[0] + (scale2[1] - scale2[0]) * radius };
  };
  const scaleToOldRadius = ({ radius }) => {
    return { innerRadius: oldScale[0], outerRadius: oldScale[0] + (oldScale[1] - oldScale[0]) * radius };
  };
  const fromFn = (sect, datum, status, { prevFromProps }) => {
    let { startAngle, endAngle, innerRadius, outerRadius } = sect;
    let { fill, stroke: stroke3 } = datum.sectorFormat;
    if (status === "updated" && sect.previousDatum == null) {
      status = "added";
    }
    if (status === "unknown" || status === "added" && !prevFromProps) {
      startAngle = rotation;
      endAngle = rotation;
      innerRadius = datum.innerRadius;
      outerRadius = datum.outerRadius;
    } else if (status === "added" && prevFromProps) {
      startAngle = prevFromProps.endAngle ?? rotation;
      endAngle = prevFromProps.endAngle ?? rotation;
      innerRadius = prevFromProps.innerRadius ?? datum.innerRadius;
      outerRadius = prevFromProps.outerRadius ?? datum.outerRadius;
    }
    if (status === "added" && !initialLoad) {
      const radii = scaleToOldRadius(datum);
      innerRadius = radii.innerRadius;
      outerRadius = radii.outerRadius;
    }
    if (status === "updated") {
      fill = sect.fill ?? fill;
      stroke3 = (typeof sect.stroke === "string" ? sect.stroke : void 0) ?? stroke3;
    }
    const animatableFill = typeof fill === "string" ? { fill } : {};
    return { startAngle, endAngle, innerRadius, outerRadius, stroke: stroke3, phase, ...animatableFill };
  };
  const toFn = (_sect, datum, status, { prevLive }) => {
    let { startAngle, endAngle, innerRadius, outerRadius } = datum;
    const { stroke: stroke3, fill } = datum.sectorFormat;
    if (status === "removed" && prevLive) {
      startAngle = prevLive.datum?.endAngle;
      endAngle = prevLive.datum?.endAngle;
    } else if (status === "removed" && !prevLive) {
      startAngle = rotation;
      endAngle = rotation;
    }
    if (status === "removed") {
      const radii = scaleToNewRadius(datum);
      innerRadius = radii.innerRadius;
      outerRadius = radii.outerRadius;
    }
    const animatableFill = typeof fill === "string" ? { fill } : {};
    return { startAngle, endAngle, outerRadius, innerRadius, stroke: stroke3, ...animatableFill };
  };
  const innerCircleFromFn = (node, _) => {
    return { size: node.previousDatum?.radius ?? node.size ?? 0, phase };
  };
  const innerCircleToFn = (_, datum) => {
    return { size: datum.radius ?? 0 };
  };
  return { nodes: { toFn, fromFn }, innerCircle: { fromFn: innerCircleFromFn, toFn: innerCircleToFn } };
}
function resetPieSelectionsFn(_node, datum) {
  return {
    startAngle: datum.startAngle,
    endAngle: datum.endAngle,
    innerRadius: datum.innerRadius,
    outerRadius: datum.outerRadius,
    stroke: datum.sectorFormat.stroke
  };
}
function pickByMatchingAngle(series, point) {
  const dy2 = point.y - series.centerY;
  const dx2 = point.x - series.centerX;
  const angle2 = Math.atan2(dy2, dx2);
  const sectors = series.getItemNodes();
  for (const sector of sectors) {
    if (sector.datum.missing === true)
      continue;
    if (isBetweenAngles(angle2, sector.startAngle, sector.endAngle)) {
      const radius = Math.hypot(dx2, dy2);
      let distance2 = 0;
      if (radius < sector.innerRadius) {
        distance2 = sector.innerRadius - radius;
      } else if (radius > sector.outerRadius) {
        distance2 = radius - sector.outerRadius;
      }
      return { datum: sector.datum, distance: distance2 };
    }
  }
  return void 0;
}

// packages/ag-charts-community/src/chart/series/polar/donutSeries.ts
var PieDonutSeriesNodeEvent = class extends SeriesNodeEvent {
  constructor(type, nativeEvent, datum, series) {
    super(type, nativeEvent, datum, series);
    this.angleKey = series.properties.angleKey;
    this.radiusKey = series.properties.radiusKey;
    this.calloutLabelKey = series.properties.calloutLabelKey;
    this.sectorLabelKey = series.properties.sectorLabelKey;
  }
};
var DonutSeries = class extends PolarSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      categoryKey: void 0,
      propertyKeys: {
        ...DEFAULT_POLAR_DIRECTION_KEYS,
        sectorLabel: ["sectorLabelKey"],
        calloutLabel: ["calloutLabelKey"]
      },
      propertyNames: {
        ...DEFAULT_POLAR_DIRECTION_NAMES,
        sectorLabel: ["sectorLabelName"],
        calloutLabel: ["calloutLabelName"]
      },
      pickModes: [1 /* NEAREST_NODE */, 0 /* EXACT_SHAPE_MATCH */],
      animationResetFns: { item: resetPieSelectionsFn, label: resetLabelFn }
    });
    this.properties = new DonutSeriesProperties();
    this.phantomNodeData = void 0;
    this.backgroundGroup = new TranslatableGroup({
      name: `${this.id}-background`,
      zIndex: 0 /* BACKGROUND */
    });
    this.noVisibleData = false;
    this.previousRadiusScale = new LinearScale();
    this.radiusScale = new LinearScale();
    this.phantomGroup = this.contentGroup.appendChild(new Group({ name: "phantom", zIndex: -1 }));
    this.phantomSelection = Selection.select(
      this.phantomGroup,
      () => this.nodeFactory(),
      false
    );
    this.phantomHighlightGroup = this.highlightGroup.appendChild(new Group({ name: "phantom", zIndex: -1 }));
    this.phantomHighlightSelection = Selection.select(
      this.phantomHighlightGroup,
      () => this.nodeFactory(),
      false
    );
    this.calloutLabelGroup = this.contentGroup.appendChild(new Group({ name: "pieCalloutLabels" }));
    this.calloutLabelSelection = new Selection(
      this.calloutLabelGroup,
      Group
    );
    // AG-6193 If the sum of all datums is 0, then we'll draw 1 or 2 rings to represent the empty series.
    this.zerosumRingsGroup = this.backgroundGroup.appendChild(new Group({ name: `${this.id}-zerosumRings` }));
    this.zerosumOuterRing = this.zerosumRingsGroup.appendChild(new Marker({ shape: "circle" }));
    this.zerosumInnerRing = this.zerosumRingsGroup.appendChild(new Marker({ shape: "circle" }));
    this.innerLabelsGroup = this.contentGroup.appendChild(new Group({ name: "innerLabels" }));
    this.innerCircleGroup = this.backgroundGroup.appendChild(new Group({ name: `${this.id}-innerCircle` }));
    this.innerLabelsSelection = Selection.select(this.innerLabelsGroup, Text);
    this.innerCircleSelection = Selection.select(
      this.innerCircleGroup,
      () => new Marker({ shape: "circle" })
    );
    this.surroundingRadius = void 0;
    this.NodeEvent = PieDonutSeriesNodeEvent;
    this.angleScale = new LinearScale();
    this.angleScale.domain = [0, 1];
    this.angleScale.range = [-Math.PI, Math.PI].map((angle2) => angle2 + Math.PI / 2);
    this.phantomGroup.opacity = 0.2;
    this.phantomHighlightGroup.opacity = 0.2;
    this.innerLabelsGroup.pointerEvents = 1 /* None */;
  }
  get calloutNodeData() {
    return this.phantomNodeData ?? this.nodeData;
  }
  attachSeries(seriesContentNode, seriesNode, annotationNode) {
    super.attachSeries(seriesContentNode, seriesNode, annotationNode);
    seriesContentNode?.appendChild(this.backgroundGroup);
  }
  detachSeries(seriesContentNode, seriesNode, annotationNode) {
    super.detachSeries(seriesContentNode, seriesNode, annotationNode);
    this.backgroundGroup.remove();
  }
  setZIndex(zIndex) {
    super.setZIndex(zIndex);
    this.backgroundGroup.zIndex = [0 /* BACKGROUND */, zIndex];
  }
  nodeFactory() {
    const sector = new Sector();
    sector.miterLimit = 1e9;
    return sector;
  }
  getSeriesDomain(direction) {
    if (direction === "angle" /* Angle */) {
      return { domain: this.angleScale.domain };
    } else {
      return { domain: this.radiusScale.domain };
    }
  }
  async processData(dataController) {
    if (this.data == null)
      return;
    const {
      visible,
      id: seriesId,
      ctx: { legendManager }
    } = this;
    const { angleKey, angleFilterKey, radiusKey, calloutLabelKey, sectorLabelKey, legendItemKey } = this.properties;
    const processor = () => (value, index) => {
      if (visible && legendManager.getItemEnabled({ seriesId, itemId: index })) {
        return value;
      }
      return 0;
    };
    const animationEnabled = !this.ctx.animationManager.isSkipped();
    const allowNullKey = this.properties.allowNullKeys ?? false;
    const extraKeyProps = [];
    const extraProps = [];
    if (legendItemKey) {
      extraKeyProps.push(keyProperty(legendItemKey, "category", { id: `legendItemKey`, allowNullKey }));
    } else if (calloutLabelKey) {
      extraKeyProps.push(keyProperty(calloutLabelKey, "category", { id: `calloutLabelKey`, allowNullKey }));
    } else if (sectorLabelKey) {
      extraKeyProps.push(keyProperty(sectorLabelKey, "category", { id: `sectorLabelKey`, allowNullKey }));
    }
    const radiusScaleType = this.radiusScale.type;
    const angleScaleType = this.angleScale.type;
    if (radiusKey) {
      extraProps.push(
        rangedValueProperty(radiusKey, {
          id: "radiusValue",
          min: this.properties.radiusMin ?? 0,
          max: this.properties.radiusMax,
          missingValue: this.properties.radiusMax ?? 1,
          processor
        }),
        valueProperty(radiusKey, radiusScaleType, { id: `radiusRaw`, processor }),
        // Raw value pass-through.
        normalisePropertyTo("radiusValue", [0, 1], 1, this.properties.radiusMin ?? 0, this.properties.radiusMax)
      );
    }
    if (calloutLabelKey) {
      extraProps.push(valueProperty(calloutLabelKey, "category", { id: `calloutLabelValue`, allowNullKey }));
    }
    if (sectorLabelKey) {
      extraProps.push(valueProperty(sectorLabelKey, "category", { id: `sectorLabelValue`, allowNullKey }));
    }
    if (legendItemKey) {
      extraProps.push(valueProperty(legendItemKey, "category", { id: `legendItemValue`, allowNullKey }));
    }
    if (angleFilterKey) {
      extraProps.push(
        accumulativeValueProperty(angleFilterKey, angleScaleType, {
          id: `angleFilterValue`,
          onlyPositive: true,
          invalidValue: 0,
          processor
        }),
        valueProperty(angleFilterKey, angleScaleType, { id: `angleFilterRaw` }),
        normalisePropertyTo("angleFilterValue", [0, 1], 0, 0)
      );
    }
    if (animationEnabled && this.processedData?.reduced?.animationValidation?.uniqueKeys && extraKeyProps.length > 0) {
      extraProps.push(diff(this.id, this.processedData));
    }
    extraProps.push(animationValidation());
    await this.requestDataModel(dataController, this.data, {
      props: [
        ...extraKeyProps,
        accumulativeValueProperty(angleKey, angleScaleType, {
          id: `angleValue`,
          onlyPositive: true,
          invalidValue: 0,
          processor
        }),
        valueProperty(angleKey, angleScaleType, { id: `angleRaw` }),
        // Raw value pass-through.
        normalisePropertyTo("angleValue", [0, 1], 0, 0),
        ...extraProps
      ]
    });
    for (const valueDef of this.processedData?.defs?.values ?? []) {
      const { id, missing, property } = valueDef;
      const missCount = getMissCount(this, missing);
      if (id !== "angleRaw" && missCount > 0) {
        logger_exports.warnOnce(
          `no value was found for the key '${String(property)}' on ${missCount} data element${missCount > 1 ? "s" : ""}`
        );
      }
    }
    this.animationState.transition("updateData");
  }
  maybeRefreshNodeData() {
    if (!this.nodeDataRefresh)
      return;
    const { nodeData = [], phantomNodeData } = this.createNodeData() ?? {};
    this.nodeData = nodeData;
    this.phantomNodeData = phantomNodeData;
    if (nodeData.length > 0) {
      debugMetrics_exports.record(`${this.type}:nodeData`, nodeData.length);
    }
    this.nodeDataRefresh = false;
  }
  getProcessedDataValues(dataModel, processedData) {
    const angleValues = dataModel.resolveColumnById(this, `angleValue`, processedData);
    const angleRawValues = dataModel.resolveColumnById(this, `angleRaw`, processedData);
    const angleFilterValues = this.properties.angleFilterKey == null ? void 0 : dataModel.resolveColumnById(this, `angleFilterValue`, processedData);
    const angleFilterRawValues = this.properties.angleFilterKey == null ? void 0 : dataModel.resolveColumnById(this, `angleFilterRaw`, processedData);
    const radiusValues = this.properties.radiusKey ? dataModel.resolveColumnById(this, `radiusValue`, processedData) : void 0;
    const radiusRawValues = this.properties.radiusKey ? dataModel.resolveColumnById(this, `radiusRaw`, processedData) : void 0;
    const calloutLabelValues = this.properties.calloutLabelKey ? dataModel.resolveColumnById(this, `calloutLabelValue`, processedData) : void 0;
    const sectorLabelValues = this.properties.sectorLabelKey ? dataModel.resolveColumnById(this, `sectorLabelValue`, processedData) : void 0;
    const legendItemValues = this.properties.legendItemKey ? dataModel.resolveColumnById(this, `legendItemValue`, processedData) : void 0;
    return {
      angleValues,
      angleRawValues,
      angleFilterValues,
      angleFilterRawValues,
      radiusValues,
      radiusRawValues,
      calloutLabelValues,
      sectorLabelValues,
      legendItemValues
    };
  }
  createNodeData() {
    const {
      id: seriesId,
      processedData,
      dataModel,
      angleScale,
      ctx: { legendManager },
      visible
    } = this;
    const { rotation, innerRadiusRatio } = this.properties;
    if (!dataModel || processedData?.type !== "ungrouped")
      return;
    const processedDataValues = this.getProcessedDataValues(dataModel, processedData);
    const {
      angleValues,
      angleRawValues,
      angleFilterValues,
      angleFilterRawValues,
      radiusValues,
      radiusRawValues,
      legendItemValues
    } = processedDataValues;
    const useFilterAngles = angleFilterRawValues?.some((filterRawValue, index) => {
      return filterRawValue > angleRawValues[index];
    }) ?? false;
    let currentStart = 0;
    let sum = 0;
    const nodes = [];
    const phantomNodes = angleFilterRawValues == null ? void 0 : [];
    const rawData = processedData.dataSources.get(this.id)?.data ?? [];
    const invalidData = processedData.invalidData?.get(this.id);
    for (const [datumIndex, datum] of rawData.entries()) {
      if (invalidData?.[datumIndex] === true)
        continue;
      const currentValue = useFilterAngles ? angleFilterValues[datumIndex] : angleValues[datumIndex];
      const crossFilterScale = angleFilterRawValues != null && !useFilterAngles ? Math.sqrt(angleFilterRawValues[datumIndex] / angleRawValues[datumIndex]) : 1;
      const startAngle = angleScale.convert(currentStart) + toRadians(rotation);
      currentStart = currentValue;
      sum += currentValue;
      const endAngle = angleScale.convert(currentStart) + toRadians(rotation);
      const span = Math.abs(endAngle - startAngle);
      const midAngle = startAngle + span / 2;
      const angleValue = angleRawValues[datumIndex];
      const radiusRaw = radiusValues?.[datumIndex] ?? 1;
      const radius = radiusRaw * crossFilterScale;
      const radiusValue = radiusRawValues?.[datumIndex];
      const legendItemValue = legendItemValues?.[datumIndex];
      const nodeLabels = this.getLabels(datumIndex, datum, midAngle, span, processedDataValues);
      const sectorFormat = this.getItemStyle({ datum, datumIndex }, false);
      const node = {
        series: this,
        datum,
        datumIndex,
        angleValue,
        midAngle,
        midCos: Math.cos(midAngle),
        midSin: Math.sin(midAngle),
        startAngle,
        endAngle,
        radius,
        innerRadius: Math.max(this.radiusScale.convert(0), 0),
        outerRadius: Math.max(this.radiusScale.convert(radius), 0),
        sectorFormat,
        radiusValue,
        legendItemValue,
        enabled: visible && legendManager.getItemEnabled({ seriesId, itemId: datumIndex }),
        focusable: true,
        ...nodeLabels
      };
      nodes.push(node);
      if (phantomNodes != null) {
        phantomNodes.push({
          ...node,
          radius: 1,
          innerRadius: Math.max(this.radiusScale.convert(0), 0),
          outerRadius: Math.max(this.radiusScale.convert(1), 0),
          focusable: false
        });
      }
    }
    this.zerosumOuterRing.visible = sum === 0;
    this.zerosumInnerRing.visible = sum === 0 && innerRadiusRatio != null && innerRadiusRatio !== 1 && innerRadiusRatio > 0;
    return {
      itemId: seriesId,
      nodeData: nodes,
      labelData: nodes,
      phantomNodeData: phantomNodes
    };
  }
  getLabelContent(datumIndex, datum, values) {
    const { id: seriesId, ctx, properties } = this;
    const { formatManager } = ctx;
    const { calloutLabel, sectorLabel, calloutLabelKey, sectorLabelKey, legendItemKey } = properties;
    const allowNullKeys = properties.allowNullKeys ?? false;
    const calloutLabelValue = values.calloutLabelValues?.[datumIndex];
    const sectorLabelValue = values.sectorLabelValues?.[datumIndex];
    const legendItemValue = values.legendItemValues?.[datumIndex];
    const labelFormatterParams = {
      datum,
      angleKey: this.properties.angleKey,
      angleName: this.properties.angleName,
      radiusKey: this.properties.radiusKey,
      radiusName: this.properties.radiusName,
      calloutLabelKey: this.properties.calloutLabelKey,
      calloutLabelName: this.properties.calloutLabelName,
      sectorLabelKey: this.properties.sectorLabelKey,
      sectorLabelName: this.properties.sectorLabelName,
      legendItemKey: this.properties.legendItemKey
    };
    const result = {
      callout: void 0,
      sector: void 0,
      legendItem: void 0
    };
    if (calloutLabelKey) {
      result.callout = this.getLabelText(
        calloutLabelValue,
        datum,
        calloutLabelKey,
        "calloutLabel",
        [],
        calloutLabel,
        { ...labelFormatterParams, value: calloutLabelValue },
        allowNullKeys
      );
    }
    if (sectorLabelKey) {
      result.sector = this.getLabelText(
        sectorLabelValue,
        datum,
        sectorLabelKey,
        "sectorLabel",
        [],
        sectorLabel,
        { ...labelFormatterParams, value: sectorLabelValue },
        allowNullKeys
      );
    }
    if (legendItemKey != null && (legendItemValue != null || allowNullKeys)) {
      const legendItemDisplay = legendItemValue ?? "";
      result.legendItem = formatManager.format(this.callWithContext.bind(this), {
        type: "category",
        value: allowNullKeys ? legendItemValue : legendItemDisplay,
        datum,
        seriesId,
        legendItemName: void 0,
        key: legendItemKey,
        source: "legend-label",
        property: "legendItem",
        domain: [],
        boundSeries: this.getFormatterContext("legendItem")
      }) ?? legendItemDisplay;
    }
    return result;
  }
  getLabels(datumIndex, datum, midAngle, span, values) {
    const { properties } = this;
    const { calloutLabel, sectorLabel, legendItemKey } = properties;
    const formats = this.getLabelContent(datumIndex, datum, values);
    const result = {};
    if (calloutLabel.enabled && formats.callout && span >= toRadians(calloutLabel.minAngle)) {
      result.calloutLabel = {
        ...this.getTextAlignment(midAngle),
        text: formats.callout,
        hidden: false,
        collisionTextAlign: void 0,
        collisionOffsetY: 0,
        box: void 0
      };
    }
    if (sectorLabel.enabled && formats.sector) {
      result.sectorLabel = { text: formats.sector };
    }
    if (legendItemKey && formats.legendItem) {
      result.legendItem = { key: legendItemKey, text: formats.legendItem };
    }
    return result;
  }
  getTextAlignment(midAngle) {
    const quadrantTextOpts = [
      { textAlign: "center", textBaseline: "bottom" },
      { textAlign: "left", textBaseline: "middle" },
      { textAlign: "center", textBaseline: "top" },
      { textAlign: "right", textBaseline: "middle" }
    ];
    const midAngle180 = normalizeAngle180(midAngle);
    const quadrantStart = -0.75 * Math.PI;
    const quadrantOffset = midAngle180 - quadrantStart;
    const quadrant = Math.floor(quadrantOffset / (Math.PI / 2));
    const quadrantIndex = modulus(quadrant, quadrantTextOpts.length);
    return quadrantTextOpts[quadrantIndex];
  }
  getFillParams(fill, innerRadius, outerRadius) {
    if (!isGradientFill(fill) || fill.bounds === "item")
      return;
    return {
      centerX: 0,
      centerY: 0,
      innerRadius,
      outerRadius
    };
  }
  getItemStyle({ datum, datumIndex }, isHighlight, highlightState, legendItemValues) {
    const { fills, strokes, itemStyler } = this.properties;
    const defaultStroke = strokes[datumIndex];
    const defaultFill = fills[datumIndex];
    const {
      fill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset,
      cornerRadius,
      opacity
    } = mergeDefaults(
      this.getHighlightStyle(isHighlight, datumIndex, highlightState, legendItemValues),
      { fill: defaultFill, stroke: defaultStroke },
      this.properties
    );
    let overrides;
    if (itemStyler) {
      overrides = this.cachedDatumCallback(
        this.getDatumId(datumIndex) + (isHighlight ? "-highlight" : "-hide"),
        () => {
          const params = this.makeItemStylerParams(datum, datumIndex, isHighlight, {
            fill,
            fillOpacity,
            stroke: stroke3,
            strokeWidth,
            strokeOpacity,
            lineDash,
            lineDashOffset,
            cornerRadius
          });
          return this.ctx.optionsGraphService.resolvePartial(
            ["series", `${this.declarationOrder}`],
            this.callWithContext(itemStyler, params),
            { proxyPaths: { fill: ["fills", `${datumIndex}`], stroke: ["strokes", `${datumIndex}`] } }
          );
        }
      );
    }
    return {
      fill: overrides?.fill ?? fill,
      fillOpacity: overrides?.fillOpacity ?? fillOpacity,
      stroke: overrides?.stroke ?? stroke3,
      strokeWidth: overrides?.strokeWidth ?? strokeWidth,
      strokeOpacity: overrides?.strokeOpacity ?? strokeOpacity,
      lineDash: overrides?.lineDash ?? lineDash,
      lineDashOffset: overrides?.lineDashOffset ?? lineDashOffset,
      cornerRadius: overrides?.cornerRadius ?? cornerRadius,
      opacity
    };
  }
  makeItemStylerParams(datum, datumIndex, isHighlight, style2) {
    const { angleKey, radiusKey, calloutLabelKey, sectorLabelKey, legendItemKey } = this.properties;
    const fill = this.filterItemStylerFillParams(style2.fill) ?? style2.fill;
    return {
      datum,
      angleKey,
      radiusKey,
      calloutLabelKey,
      sectorLabelKey,
      legendItemKey,
      ...style2,
      fill,
      highlightState: this.getHighlightStateString(
        this.ctx.highlightManager?.getActiveHighlight(),
        isHighlight,
        datumIndex
      ),
      seriesId: this.id
    };
  }
  getCalloutLineStyle(nodeDatum, highlighted) {
    const { properties } = this;
    let itemStylerResult = {};
    if (properties.calloutLine.itemStyler) {
      const highlightState = this.getHighlightStateString(
        this.ctx.highlightManager?.getActiveHighlight(),
        highlighted,
        nodeDatum.datumIndex
      );
      const params = {
        angleKey: properties.angleKey,
        angleName: properties.angleName ?? properties.angleKey,
        calloutLabelKey: properties.calloutLabelKey,
        calloutLabelName: properties.calloutLabelName ?? properties.calloutLabelKey,
        datum: nodeDatum.datum,
        highlightState,
        legendItemKey: properties.legendItemKey,
        radiusKey: properties.radiusKey,
        radiusName: properties.radiusName ?? properties.radiusKey,
        sectorLabelKey: properties.sectorLabelKey,
        sectorLabelName: properties.sectorLabelName ?? properties.sectorLabelKey,
        seriesId: this.id
      };
      itemStylerResult = this.cachedCallWithContext(properties.calloutLine.itemStyler, params) ?? {};
    }
    return {
      length: itemStylerResult.length ?? properties.calloutLine.length,
      strokeWidth: itemStylerResult.strokeWidth ?? properties.calloutLine.strokeWidth,
      color: itemStylerResult.color,
      colors: properties.calloutLine.colors
    };
  }
  getInnerRadius() {
    const { radius } = this;
    const { innerRadiusRatio = 1, innerRadiusOffset = 0 } = this.properties;
    const innerRadius = radius * innerRadiusRatio + innerRadiusOffset;
    if (innerRadius === radius || innerRadius < 0) {
      return 0;
    }
    return innerRadius;
  }
  getOuterRadius() {
    const { outerRadiusRatio, outerRadiusOffset } = this.properties;
    return Math.max(this.radius * outerRadiusRatio + outerRadiusOffset, 0);
  }
  updateRadiusScale(resize) {
    const newRange = [this.getInnerRadius(), this.getOuterRadius()];
    this.radiusScale.range = newRange;
    if (resize) {
      this.previousRadiusScale.range = newRange;
    }
    const setRadii = (d) => ({
      ...d,
      innerRadius: Math.max(this.radiusScale.convert(0), 0),
      outerRadius: Math.max(this.radiusScale.convert(d.radius), 0)
    });
    this.nodeData = this.nodeData.map(setRadii);
    this.phantomNodeData = this.phantomNodeData?.map(setRadii);
  }
  getTitleTranslationY() {
    const outerRadius = Math.max(0, this.radiusScale.range[1]);
    if (outerRadius === 0) {
      return Number.NaN;
    }
    const spacing = this.properties.title?.spacing ?? 0;
    const titleOffset = 2 + spacing;
    const dy2 = Math.max(0, -outerRadius);
    return -outerRadius - titleOffset - dy2;
  }
  update({ seriesRect }) {
    const { title } = this.properties;
    const newNodeDataDependencies = {
      seriesRectWidth: seriesRect?.width,
      seriesRectHeight: seriesRect?.height
    };
    const resize = jsonDiff(this.nodeDataDependencies, newNodeDataDependencies) != null;
    if (resize) {
      this._nodeDataDependencies = newNodeDataDependencies;
    }
    this.maybeRefreshNodeData();
    this.updateTitleNodes();
    this.updateRadiusScale(resize);
    this.contentGroup.translationX = this.centerX;
    this.contentGroup.translationY = this.centerY;
    this.highlightGroup.translationX = this.centerX;
    this.highlightGroup.translationY = this.centerY;
    this.backgroundGroup.translationX = this.centerX;
    this.backgroundGroup.translationY = this.centerY;
    if (this.labelGroup) {
      this.labelGroup.translationX = this.centerX;
      this.labelGroup.translationY = this.centerY;
    }
    if (title) {
      const dy2 = this.getTitleTranslationY();
      title.node.y = Number.isFinite(dy2) ? dy2 : 0;
      const titleBox = title.node.getBBox();
      title.node.visible = title.enabled && Number.isFinite(dy2) && !this.bboxIntersectsSurroundingSeries(titleBox);
    }
    for (const circle of [this.zerosumInnerRing, this.zerosumOuterRing]) {
      circle.fillOpacity = 0;
      circle.stroke = this.properties.calloutLabel.color;
      circle.strokeWidth = 1;
      circle.strokeOpacity = 1;
    }
    this.updateNodeMidPoint();
    this.updateSelections();
    this.updateNodes(seriesRect);
  }
  updateTitleNodes() {
    const { oldTitle } = this;
    const { title } = this.properties;
    if (oldTitle !== title) {
      if (oldTitle) {
        oldTitle.node.remove();
      }
      if (title) {
        title.node.textBaseline = "bottom";
        this.labelGroup?.appendChild(title.node);
      }
      this.oldTitle = title;
    }
  }
  updateNodeMidPoint() {
    const setMidPoint = (d) => {
      const radius = d.innerRadius + (d.outerRadius - d.innerRadius) / 2;
      d.midPoint = {
        x: d.midCos * Math.max(0, radius),
        y: d.midSin * Math.max(0, radius)
      };
    };
    for (const datum of this.nodeData) {
      setMidPoint(datum);
    }
    if (this.phantomNodeData) {
      for (const datum of this.phantomNodeData) {
        setMidPoint(datum);
      }
    }
  }
  updateSelections() {
    this.updateGroupSelection();
    this.updateInnerCircleSelection();
  }
  updateGroupSelection() {
    const {
      itemSelection,
      highlightSelection,
      phantomSelection,
      phantomHighlightSelection,
      calloutLabelSelection,
      labelSelection,
      highlightLabelSelection,
      innerLabelsSelection
    } = this;
    const highlightedNodeData = this.nodeData.map((datum) => ({
      ...datum,
      // Allow mutable sectorFormat, so formatted sector styles can be updated and varied
      // between normal and highlighted cases.
      sectorFormat: { ...datum.sectorFormat }
    }));
    const phantomHighlightedNodeData = this.phantomNodeData?.map((datum) => ({
      ...datum,
      // Allow mutable sectorFormat, so formatted sector styles can be updated and varied
      // between normal and highlighted cases.
      sectorFormat: { ...datum.sectorFormat }
    }));
    const update = (selection, nodeData) => {
      selection.update(nodeData, void 0, (datum) => this.getDatumId(datum.datumIndex));
      if (this.ctx.animationManager.isSkipped()) {
        selection.cleanup();
      }
    };
    update(itemSelection, this.nodeData);
    update(highlightSelection, highlightedNodeData);
    update(phantomSelection, this.phantomNodeData ?? []);
    update(phantomHighlightSelection, phantomHighlightedNodeData ?? []);
    calloutLabelSelection.update(this.calloutNodeData, (group) => {
      const line = new Line();
      line.tag = 0 /* CalloutLine */;
      line.pointerEvents = 1 /* None */;
      group.appendChild(line);
      const text2 = new Text();
      text2.tag = 1 /* CalloutLabel */;
      text2.pointerEvents = 1 /* None */;
      group.appendChild(text2);
    });
    labelSelection.update(this.nodeData);
    highlightLabelSelection.update(highlightedNodeData);
    innerLabelsSelection.update(this.properties.innerLabels, (node) => {
      node.pointerEvents = 1 /* None */;
    });
  }
  updateInnerCircleSelection() {
    const { innerCircle } = this.properties;
    let radius = 0;
    const innerRadius = this.getInnerRadius();
    if (innerRadius > 0) {
      const circleRadius = Math.min(innerRadius, this.getOuterRadius());
      const antiAliasingPadding = 1;
      radius = Math.ceil(circleRadius * 2 + antiAliasingPadding);
    }
    const datums = innerCircle ? [{ radius }] : [];
    this.innerCircleSelection.update(datums);
  }
  updateNodes(seriesRect) {
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    const { visible, dataModel, processedData } = this;
    this.backgroundGroup.visible = visible;
    this.contentGroup.visible = visible;
    if (!dataModel || !processedData)
      return;
    const { legendItemValues } = this.getProcessedDataValues(dataModel, processedData);
    const seriesHighlighted = this.isSeriesHighlighted(highlightedDatum, legendItemValues);
    const drawingMode = this.ctx.chartService.highlight?.drawingMode ?? "overlay";
    this.highlightGroup.visible = visible && seriesHighlighted;
    this.labelGroup.visible = visible;
    this.innerCircleSelection.each((node, { radius }) => {
      node.setProperties({
        fill: this.properties.innerCircle?.fill,
        opacity: this.properties.innerCircle?.fillOpacity,
        size: radius
      });
    });
    const innerRadius = this.radiusScale.range[0];
    const outerRadius = this.radiusScale.range[1];
    const fillBBox = this.getShapeFillBBox();
    const animationDisabled = this.ctx.animationManager.isSkipped();
    const updateSectorFn = (sector, datum, _index, isDatumHighlighted, mode) => {
      const format = this.getItemStyle(datum, isDatumHighlighted, void 0, legendItemValues);
      datum.sectorFormat.fill = format.fill;
      datum.sectorFormat.stroke = format.stroke;
      if (animationDisabled) {
        sector.startAngle = datum.startAngle;
        sector.endAngle = datum.endAngle;
        sector.innerRadius = datum.innerRadius;
        sector.outerRadius = datum.outerRadius;
      }
      if (isDatumHighlighted || animationDisabled) {
        sector.fill = format.fill;
        sector.stroke = format.stroke;
      }
      const fillParams = this.getFillParams(format.fill, innerRadius, outerRadius);
      sector.setStyleProperties(format, fillBBox, fillParams);
      sector.drawingMode = mode;
      sector.cornerRadius = format.cornerRadius;
      sector.fillShadow = this.properties.shadow;
      const inset = Math.max(
        (this.properties.sectorSpacing + (format.stroke == null ? 0 : format.strokeWidth)) / 2,
        0
      );
      sector.inset = inset;
      sector.lineJoin = this.properties.sectorSpacing >= 0 || inset > 0 ? "miter" : "round";
    };
    this.itemSelection.each((node, datum, index) => updateSectorFn(node, datum, index, false, "overlay"));
    this.phantomSelection.each((node, datum, index) => updateSectorFn(node, datum, index, false, "overlay"));
    this.highlightSelection.each((node, datum, index) => {
      updateSectorFn(node, datum, index, true, drawingMode);
      node.visible = datum.datumIndex === highlightedDatum?.datumIndex;
    });
    this.phantomHighlightSelection.each((node, datum, index) => {
      updateSectorFn(node, datum, index, true, drawingMode);
      node.visible = datum.datumIndex === highlightedDatum?.datumIndex;
    });
    this.updateCalloutLineNodes();
    this.updateCalloutLabelNodes(seriesRect);
    this.updateSectorLabelNodes();
    this.updateInnerLabelNodes();
    this.updateZerosumRings();
    this.animationState.transition("update");
  }
  updateCalloutLineNodes() {
    const { strokes } = this.properties;
    const { offset } = this.properties.calloutLabel;
    const highlightedDatum = this.ctx.highlightManager?.getActiveHighlight();
    const seriesHighlighted = this.isSeriesHighlighted(highlightedDatum);
    for (const line of this.calloutLabelSelection.selectByTag(0 /* CalloutLine */)) {
      const datum = line.closestDatum();
      const isDatumHighlighted = seriesHighlighted && this.isItemHighlighted(highlightedDatum, datum.datumIndex) === true;
      const { length: calloutLength, strokeWidth, color: color2, colors } = this.getCalloutLineStyle(datum, false);
      const calloutStrokeWidth = strokeWidth;
      const calloutColors = isStringFillArray(colors) ? colors : strokes;
      const { calloutLabel: label, outerRadius, datumIndex } = datum;
      if (label?.text && !label.hidden && outerRadius !== 0) {
        line.visible = true;
        line.strokeWidth = calloutStrokeWidth;
        line.stroke = color2 ?? calloutColors[datumIndex % calloutColors.length];
        line.strokeOpacity = this.getHighlightStyle(isDatumHighlighted, datum.datumIndex).opacity ?? 1;
        line.fill = void 0;
        const x1 = datum.midCos * outerRadius;
        const y1 = datum.midSin * outerRadius;
        let x2 = datum.midCos * (outerRadius + calloutLength);
        let y2 = datum.midSin * (outerRadius + calloutLength);
        const isMoved = label.collisionTextAlign ?? label.collisionOffsetY !== 0;
        if (isMoved && label.box != null) {
          const box = label.box;
          let cx = x2;
          let cy = y2;
          if (x2 < box.x) {
            cx = box.x;
          } else if (x2 > box.x + box.width) {
            cx = box.x + box.width;
          }
          if (y2 < box.y) {
            cy = box.y;
          } else if (y2 > box.y + box.height) {
            cy = box.y + box.height;
          }
          const dx2 = cx - x2;
          const dy2 = cy - y2;
          const length2 = Math.sqrt(Math.pow(dx2, 2) + Math.pow(dy2, 2));
          const paddedLength = length2 - offset;
          if (paddedLength > 0) {
            x2 = x2 + dx2 * paddedLength / length2;
            y2 = y2 + dy2 * paddedLength / length2;
          }
        }
        line.x1 = x1;
        line.y1 = y1;
        line.x2 = x2;
        line.y2 = y2;
      } else {
        line.visible = false;
      }
    }
  }
  getLabelOverflow(box, seriesRect) {
    const seriesLeft = -this.centerX;
    const seriesRight = seriesLeft + seriesRect.width;
    const seriesTop = -this.centerY;
    const seriesBottom = seriesTop + seriesRect.height;
    const errPx = 1;
    let maxWidth = box.width;
    if (box.x + errPx < seriesLeft) {
      maxWidth = (box.x + box.width - seriesLeft) / box.width;
    } else if (box.x + box.width - errPx > seriesRight) {
      maxWidth = (seriesRight - box.x) / box.width;
    }
    const hasVerticalOverflow = box.y + errPx < seriesTop || box.y + box.height - errPx > seriesBottom;
    const hasSurroundingSeriesOverflow = this.bboxIntersectsSurroundingSeries(box);
    return { maxWidth, hasVerticalOverflow, hasSurroundingSeriesOverflow };
  }
  bboxIntersectsSurroundingSeries(box) {
    const { surroundingRadius } = this;
    if (surroundingRadius == null) {
      return false;
    }
    const corners = [
      { x: box.x, y: box.y },
      { x: box.x + box.width, y: box.y },
      { x: box.x + box.width, y: box.y + box.height },
      { x: box.x, y: box.y + box.height }
    ];
    const sur2 = surroundingRadius ** 2;
    return corners.some((corner) => corner.x ** 2 + corner.y ** 2 > sur2);
  }
  computeCalloutLabelCollisionOffsets() {
    const { radiusScale } = this;
    const { calloutLabel } = this.properties;
    const { offset, minSpacing } = calloutLabel;
    const innerRadius = radiusScale.convert(0);
    const shouldSkip = (datum) => {
      const label = datum.calloutLabel;
      return !label || datum.outerRadius === 0;
    };
    const fullData = this.calloutNodeData;
    const data = fullData.filter((t) => !shouldSkip(t));
    for (const datum of data) {
      const label = datum.calloutLabel;
      if (label == null)
        continue;
      label.hidden = false;
      label.collisionTextAlign = void 0;
      label.collisionOffsetY = 0;
    }
    if (data.length <= 1) {
      return;
    }
    const leftLabels = data.filter((d) => d.midCos < 0).sort((a, b) => a.midSin - b.midSin);
    const rightLabels = data.filter((d) => d.midCos >= 0).sort((a, b) => a.midSin - b.midSin);
    const topLabels = data.filter((d) => d.midSin < 0 && d.calloutLabel?.textAlign === "center").sort((a, b) => a.midCos - b.midCos);
    const bottomLabels = data.filter((d) => d.midSin >= 0 && d.calloutLabel?.textAlign === "center").sort((a, b) => a.midCos - b.midCos);
    const getTextBBox = (datum) => {
      const label = datum.calloutLabel;
      if (label == null)
        return BBox.zero.clone();
      const style2 = this.getLabelStyle(datum, calloutLabel, "calloutLabel");
      const padding2 = expandLabelPadding(style2);
      const calloutLength = this.getCalloutLineStyle(datum, false).length;
      const labelRadius = datum.outerRadius + calloutLength + offset;
      const x = datum.midCos * labelRadius;
      const y = datum.midSin * labelRadius + label.collisionOffsetY;
      const textAlign = label.collisionTextAlign ?? label.textAlign;
      const textBaseline = label.textBaseline;
      return Text.measureBBox(label.text, x, y, {
        font: this.properties.calloutLabel,
        textAlign,
        textBaseline
      }).grow(padding2);
    };
    const avoidNeighbourYCollision = (label, next, direction) => {
      const box = getTextBBox(label).grow(minSpacing / 2);
      const other = getTextBBox(next).grow(minSpacing / 2);
      const collidesOrBehind = box.x < other.x + other.width && box.x + box.width > other.x && (direction === "to-top" ? box.y < other.y + other.height : box.y + box.height > other.y);
      if (collidesOrBehind) {
        next.calloutLabel.collisionOffsetY = direction === "to-top" ? box.y - other.y - other.height : box.y + box.height - other.y;
      }
    };
    const avoidYCollisions = (labels) => {
      const midLabel = labels.slice().sort((a, b) => Math.abs(a.midSin) - Math.abs(b.midSin))[0];
      const midIndex = labels.indexOf(midLabel);
      for (let i = midIndex - 1; i >= 0; i--) {
        const prev = labels[i + 1];
        const next = labels[i];
        avoidNeighbourYCollision(prev, next, "to-top");
      }
      for (let i = midIndex + 1; i < labels.length; i++) {
        const prev = labels[i - 1];
        const next = labels[i];
        avoidNeighbourYCollision(prev, next, "to-bottom");
      }
    };
    const avoidXCollisions = (labels) => {
      const labelsCollideLabelsByY = data.some((datum) => datum.calloutLabel.collisionOffsetY !== 0);
      const boxes = labels.map((label) => getTextBBox(label));
      const paddedBoxes = boxes.map((box) => box.clone().grow(minSpacing / 2));
      let labelsCollideLabelsByX = false;
      for (let i = 0; i < paddedBoxes.length && !labelsCollideLabelsByX; i++) {
        const box = paddedBoxes[i];
        for (let j = i + 1; j < labels.length; j++) {
          const other = paddedBoxes[j];
          if (box.collidesBBox(other)) {
            labelsCollideLabelsByX = true;
            break;
          }
        }
      }
      const sectors = fullData.map((datum) => {
        const { startAngle, endAngle, outerRadius } = datum;
        return { startAngle, endAngle, innerRadius, outerRadius };
      });
      const labelsCollideSectors = boxes.some((box) => sectors.some((sector) => boxCollidesSector(box, sector)));
      if (!labelsCollideLabelsByX && !labelsCollideLabelsByY && !labelsCollideSectors)
        return;
      for (const d of labels) {
        if (d.calloutLabel.textAlign !== "center")
          continue;
        const label = d.calloutLabel;
        if (d.midCos < 0) {
          label.collisionTextAlign = "right";
        } else if (d.midCos > 0) {
          label.collisionTextAlign = "left";
        } else {
          label.collisionTextAlign = "center";
        }
      }
    };
    avoidYCollisions(leftLabels);
    avoidYCollisions(rightLabels);
    avoidXCollisions(topLabels);
    avoidXCollisions(bottomLabels);
  }
  getLabelStyle(datum, label, labelPath, isHighlight = false) {
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    return getLabelStyles(this, datum, this.properties, label, isHighlight, activeHighlight, [
      "series",
      `${this.declarationOrder}`,
      labelPath
    ]);
  }
  updateCalloutLabelNodes(seriesRect) {
    const { radiusScale } = this;
    const { calloutLabel } = this.properties;
    const tempTextNode = new Text();
    const highlightedDatum = this.ctx.highlightManager?.getActiveHighlight();
    const seriesHighlighted = this.isSeriesHighlighted(highlightedDatum);
    for (const text2 of this.calloutLabelSelection.selectByTag(1 /* CalloutLabel */)) {
      const datum = text2.closestDatum();
      const label = datum.calloutLabel;
      const radius = radiusScale.convert(datum.radius);
      const outerRadius = Math.max(0, radius);
      if (!label?.text || outerRadius === 0 || label.hidden) {
        text2.visible = false;
        continue;
      }
      const isDatumHighlighted = seriesHighlighted && this.isItemHighlighted(highlightedDatum, datum.datumIndex) === true;
      const style2 = this.getLabelStyle(datum, calloutLabel, "calloutLabel", isDatumHighlighted);
      const calloutLength = this.getCalloutLineStyle(datum, false).length;
      const labelRadius = outerRadius + calloutLength + calloutLabel.offset;
      const x = datum.midCos * labelRadius;
      const y = datum.midSin * labelRadius + label.collisionOffsetY;
      const align2 = {
        textAlign: label.collisionTextAlign ?? label.textAlign,
        textBaseline: label.textBaseline
      };
      tempTextNode.text = label.text;
      tempTextNode.x = x;
      tempTextNode.y = y;
      tempTextNode.setFont(style2);
      tempTextNode.setAlign(align2);
      tempTextNode.setBoxing(style2);
      const box = tempTextNode.getBBox();
      let displayText = label.text;
      let visible = true;
      if (calloutLabel.avoidCollisions) {
        const { maxWidth, hasVerticalOverflow } = this.getLabelOverflow(box, seriesRect);
        if (box.width > maxWidth) {
          const options = {
            font: this.properties.calloutLabel,
            textWrap: "on-space",
            overflow: "hide",
            maxWidth
          };
          displayText = wrapTextOrSegments(label.text, options);
        }
        visible = !hasVerticalOverflow;
      }
      text2.text = displayText;
      text2.x = x;
      text2.y = y;
      text2.setFont(style2);
      text2.setAlign(align2);
      text2.setBoxing(style2);
      text2.fill = style2.color;
      text2.fillOpacity = this.getHighlightStyle(isDatumHighlighted, datum.datumIndex).opacity ?? 1;
      text2.visible = visible;
    }
  }
  computeLabelsBBox(options, seriesRect) {
    const { calloutLabel } = this.properties;
    const { offset, maxCollisionOffset, minSpacing } = calloutLabel;
    if (!calloutLabel.avoidCollisions) {
      return null;
    }
    this.maybeRefreshNodeData();
    this.updateRadiusScale(false);
    this.computeCalloutLabelCollisionOffsets();
    const textBoxes = [];
    const text2 = new Text();
    let titleBox = void 0;
    const { title } = this.properties;
    if (title?.text && title.enabled) {
      const dy2 = this.getTitleTranslationY();
      if (Number.isFinite(dy2)) {
        text2.text = title.text;
        text2.x = 0;
        text2.y = dy2;
        text2.setFont(title);
        text2.setAlign({
          textBaseline: "bottom",
          textAlign: "center"
        });
        titleBox = text2.getBBox();
        textBoxes.push(titleBox);
      }
    }
    for (const datum of this.calloutNodeData) {
      const label = datum.calloutLabel;
      if (!label || datum.outerRadius === 0) {
        continue;
      }
      const style2 = this.getLabelStyle(datum, calloutLabel, "calloutLabel");
      const calloutLength = this.getCalloutLineStyle(datum, false).length;
      const labelRadius = datum.outerRadius + calloutLength + offset;
      const x = datum.midCos * labelRadius;
      const y = datum.midSin * labelRadius + label.collisionOffsetY;
      text2.text = label.text;
      text2.x = x;
      text2.y = y;
      text2.setFont(style2);
      text2.setAlign({
        textAlign: label.collisionTextAlign ?? label.textAlign,
        textBaseline: label.textBaseline
      });
      text2.setBoxing(style2);
      const box = text2.getBBox();
      label.box = box;
      if (Math.abs(label.collisionOffsetY) > maxCollisionOffset) {
        label.hidden = true;
        continue;
      }
      if (titleBox) {
        const seriesTop = -this.centerY;
        const titleCleanArea = new BBox(
          titleBox.x - minSpacing,
          seriesTop,
          titleBox.width + 2 * minSpacing,
          titleBox.y + titleBox.height + minSpacing - seriesTop
        );
        if (box.collidesBBox(titleCleanArea)) {
          label.hidden = true;
          continue;
        }
      }
      if (options.hideWhenNecessary) {
        const { maxWidth, hasVerticalOverflow, hasSurroundingSeriesOverflow } = this.getLabelOverflow(
          box,
          seriesRect
        );
        const isTooShort = box.width > maxWidth;
        if (hasVerticalOverflow || isTooShort || hasSurroundingSeriesOverflow) {
          label.hidden = true;
          continue;
        }
      }
      label.hidden = false;
      textBoxes.push(box);
    }
    if (textBoxes.length === 0) {
      return null;
    }
    return BBox.merge(textBoxes);
  }
  updateSectorLabelNodes() {
    const { properties } = this;
    const { positionOffset, positionRatio } = this.properties.sectorLabel;
    const highlightedDatum = this.ctx.highlightManager?.getActiveHighlight();
    const seriesHighlighted = this.isSeriesHighlighted(highlightedDatum);
    const innerRadius = this.radiusScale.convert(0);
    const shouldPutTextInCenter = innerRadius <= 0 && // is donut?
    this.ctx.legendManager.getData(this.id)?.filter((d) => d.enabled).length === 1;
    const align2 = { textAlign: "center", textBaseline: "middle" };
    const updateSelection = (selection) => selection.each((text2, datum) => {
      const { outerRadius, startAngle, endAngle } = datum;
      const isDatumHighlighted = seriesHighlighted && this.isItemHighlighted(highlightedDatum, datum.datumIndex) === true;
      let isTextVisible = false;
      if (datum.sectorLabel && outerRadius !== 0) {
        const style2 = this.getLabelStyle(datum, properties.sectorLabel, "sectorLabel", isDatumHighlighted);
        const labelRadius = innerRadius * (1 - positionRatio) + outerRadius * positionRatio + positionOffset;
        text2.fill = style2.color;
        text2.fillOpacity = this.getHighlightStyle(isDatumHighlighted, datum.datumIndex).opacity ?? 1;
        text2.text = datum.sectorLabel.text;
        if (shouldPutTextInCenter) {
          text2.x = 0;
          text2.y = 0;
        } else {
          text2.x = datum.midCos * labelRadius;
          text2.y = datum.midSin * labelRadius;
        }
        text2.setFont(style2);
        text2.setAlign(align2);
        text2.setBoxing(style2);
        const bbox = text2.getBBox();
        const corners = [
          [bbox.x, bbox.y],
          [bbox.x + bbox.width, bbox.y],
          [bbox.x + bbox.width, bbox.y + bbox.height],
          [bbox.x, bbox.y + bbox.height]
        ];
        const sectorBounds = { startAngle, endAngle, innerRadius, outerRadius };
        if (corners.every(([x, y]) => isPointInSector(x, y, sectorBounds))) {
          isTextVisible = true;
        }
      }
      text2.visible = isTextVisible;
    });
    updateSelection(this.labelSelection);
    updateSelection(this.highlightLabelSelection);
  }
  updateInnerLabelNodes() {
    const textBBoxes = [];
    const margins = [];
    this.innerLabelsSelection.each((text2, datum) => {
      const { fontStyle, fontWeight: fontWeight2, fontSize, fontFamily, color: color2 } = datum;
      text2.fontStyle = fontStyle;
      text2.fontWeight = fontWeight2;
      text2.fontSize = fontSize;
      text2.fontFamily = fontFamily;
      text2.text = datum.text;
      text2.x = 0;
      text2.y = 0;
      text2.fill = color2;
      text2.textAlign = "center";
      textBBoxes.push(text2.getBBox());
      margins.push(datum.spacing);
    });
    const getMarginTop = (index) => index === 0 ? 0 : margins[index];
    const getMarginBottom = (index) => index === margins.length - 1 ? 0 : margins[index];
    const totalWidth = textBBoxes.reduce((max, bbox) => Math.max(max, bbox.width), 0);
    const totalHeight = textBBoxes.reduce(
      (sum, bbox, i) => sum + bbox.height + getMarginTop(i) + getMarginBottom(i),
      0
    );
    const innerRadius = this.getInnerRadius();
    const labelRadius = Math.sqrt(Math.pow(totalWidth / 2, 2) + Math.pow(totalHeight / 2, 2));
    const labelsVisible = labelRadius <= (innerRadius > 0 ? innerRadius : this.getOuterRadius());
    const textBottoms = [];
    for (let i = 0, prev = -totalHeight / 2; i < textBBoxes.length; i++) {
      const bbox = textBBoxes[i];
      const bottom = bbox.height + prev + getMarginTop(i);
      textBottoms.push(bottom);
      prev = bottom + getMarginBottom(i);
    }
    this.innerLabelsSelection.each((text2, _datum, index) => {
      text2.visible = labelsVisible;
      if (Array.isArray(text2.text)) {
        text2.y = textBottoms[index] - textBBoxes[index].height;
      } else {
        text2.y = textBottoms[index];
      }
    });
  }
  updateZerosumRings() {
    this.zerosumOuterRing.size = this.getOuterRadius() * 2;
    this.zerosumInnerRing.size = this.getInnerRadius() * 2;
  }
  pickNodeClosestDatum(point) {
    return pickByMatchingAngle(this, point);
  }
  getTooltipContent(datumIndex) {
    const {
      id: seriesId,
      dataModel,
      processedData,
      properties,
      ctx: { formatManager }
    } = this;
    const {
      legendItemKey,
      calloutLabelKey,
      calloutLabelName,
      sectorLabelKey,
      sectorLabelName,
      angleKey,
      angleName,
      radiusKey,
      radiusName,
      tooltip
    } = properties;
    const title = this.properties.title.node.getPlainText();
    if (!dataModel || !processedData)
      return;
    const datum = processedData.dataSources.get(this.id)?.data?.[datumIndex];
    const processedDataValues = this.getProcessedDataValues(dataModel, processedData);
    const { angleRawValues } = processedDataValues;
    const angleRawValue = angleRawValues[datumIndex];
    const labelValues = this.getLabelContent(datumIndex, datum, processedDataValues);
    const label = labelValues.legendItem ?? labelValues.callout ?? labelValues.sector ?? angleName;
    const domain = extractDomain(dataModel.getDomain(this, `angleRaw`, "value", processedData));
    const angleContent = formatManager.format(this.callWithContext.bind(this), {
      type: "number",
      value: angleRawValue,
      datum,
      seriesId,
      legendItemName: void 0,
      key: angleKey,
      source: "tooltip",
      property: "angle",
      domain,
      boundSeries: this.getFormatterContext("angle"),
      fractionDigits: void 0,
      visibleDomain: void 0
    }) ?? formatValue(angleRawValue, 3);
    return this.formatTooltipWithContext(
      tooltip,
      {
        title,
        symbol: this.legendItemSymbol(datumIndex),
        data: [{ label: toPlainText(label), fallbackLabel: angleKey, value: angleContent }]
      },
      {
        seriesId,
        datum,
        title: angleName,
        legendItemKey,
        calloutLabelKey,
        calloutLabelName,
        sectorLabelKey,
        sectorLabelName,
        angleKey,
        angleName,
        radiusKey,
        radiusName,
        ...this.getItemStyle({ datum, datumIndex }, false)
      }
    );
  }
  legendItemSymbol(datumIndex) {
    const datum = this.processedData?.dataSources.get(this.id)?.data?.[datumIndex];
    const sectorFormat = this.getItemStyle({ datum, datumIndex }, false);
    const { fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.properties;
    let { fill } = sectorFormat;
    const { stroke: stroke3 } = sectorFormat;
    if (isGradientFill(fill)) {
      fill = { ...fill, gradient: "linear", rotation: 0, reverse: false };
    }
    return {
      marker: {
        fill,
        stroke: stroke3,
        fillOpacity,
        strokeOpacity,
        strokeWidth,
        lineDash,
        lineDashOffset
      }
    };
  }
  getLegendData(legendType) {
    const {
      visible,
      processedData,
      dataModel,
      id: seriesId,
      ctx: { legendManager }
    } = this;
    if (!dataModel || !processedData || legendType !== "category") {
      return [];
    }
    const { angleKey, calloutLabelKey, sectorLabelKey, legendItemKey, showInLegend } = this.properties;
    if (!legendItemKey && (!calloutLabelKey || calloutLabelKey === angleKey) && (!sectorLabelKey || sectorLabelKey === angleKey)) {
      return [];
    }
    const processedDataValues = this.getProcessedDataValues(dataModel, processedData);
    const { angleRawValues } = processedDataValues;
    const titleText = this.properties.title?.showInLegend && this.properties.title.text;
    const legendData = [];
    const hideZeros = this.properties.hideZeroValueSectorsInLegend;
    const rawData = processedData.dataSources.get(this.id)?.data;
    const invalidData = processedData.invalidData?.get(this.id);
    for (let datumIndex = 0; datumIndex < processedData.input.count; datumIndex++) {
      const datum = rawData?.[datumIndex];
      const angleRawValue = angleRawValues[datumIndex];
      if (invalidData?.[datumIndex] === true || hideZeros && angleRawValue === 0) {
        continue;
      }
      const labelParts = [];
      if (titleText) {
        labelParts.push(titleText);
      }
      const labels = this.getLabelContent(datumIndex, datum, processedDataValues);
      if (legendItemKey && labels.legendItem !== void 0) {
        labelParts.push(labels.legendItem);
      } else if (calloutLabelKey && calloutLabelKey !== angleKey && labels.callout !== void 0) {
        labelParts.push(labels.callout);
      } else if (sectorLabelKey && sectorLabelKey !== angleKey && labels.sector !== void 0) {
        labelParts.push(labels.sector);
      }
      if (labelParts.length === 0)
        continue;
      legendData.push({
        legendType: "category",
        id: seriesId,
        datum,
        itemId: datumIndex,
        seriesId,
        hideToggleOtherSeries: true,
        enabled: visible && legendManager.getItemEnabled({ seriesId, itemId: datumIndex }),
        label: {
          text: labelParts.map((s) => toPlainText(s)).join(" - ")
        },
        symbol: this.legendItemSymbol(datumIndex),
        legendItemName: legendItemKey == null ? void 0 : datum[legendItemKey],
        hideInLegend: !showInLegend
      });
    }
    return legendData;
  }
  // Used for grid
  setLegendState(enabledItems) {
    const {
      id: seriesId,
      ctx: { legendManager, updateService }
    } = this;
    for (const [itemId, enabled] of enabledItems.entries()) {
      legendManager.toggleItem(enabled, seriesId, itemId);
    }
    legendManager.update();
    updateService.update(7 /* SERIES_UPDATE */);
  }
  animateEmptyUpdateReady(_data) {
    const { animationManager } = this.ctx;
    const fns = preparePieSeriesAnimationFunctions(
      true,
      this.properties.rotation,
      this.radiusScale,
      this.previousRadiusScale
    );
    fromToMotion(
      this.id,
      "nodes",
      animationManager,
      [this.itemSelection, this.highlightSelection, this.phantomSelection, this.phantomHighlightSelection],
      fns.nodes,
      (_, datum) => this.getDatumId(datum.datumIndex)
    );
    fromToMotion(this.id, `innerCircle`, animationManager, [this.innerCircleSelection], fns.innerCircle);
    seriesLabelFadeInAnimation(this, "callout", animationManager, this.calloutLabelSelection);
    seriesLabelFadeInAnimation(this, "sector", animationManager, this.labelSelection, this.highlightLabelSelection);
    seriesLabelFadeInAnimation(this, "inner", animationManager, this.innerLabelsSelection);
    this.previousRadiusScale.range = this.radiusScale.range;
  }
  animateWaitingUpdateReady() {
    const {
      itemSelection,
      highlightSelection,
      phantomSelection,
      phantomHighlightSelection,
      processedData,
      radiusScale,
      previousRadiusScale
    } = this;
    const { animationManager } = this.ctx;
    const dataDiff = processedData?.reduced?.diff?.[this.id];
    this.ctx.animationManager.stopByAnimationGroupId(this.id);
    const supportedDiff = (dataDiff?.moved.size ?? 0) === 0;
    const hasKeys = (processedData?.defs.keys.length ?? 0) > 0;
    const hasUniqueKeys = processedData?.reduced?.animationValidation?.uniqueKeys ?? true;
    if (!supportedDiff || !hasKeys || !hasUniqueKeys) {
      this.ctx.animationManager.skipCurrentBatch();
    }
    const noVisibleData = !this.nodeData.some((n) => n.enabled);
    const fns = preparePieSeriesAnimationFunctions(
      false,
      this.properties.rotation,
      radiusScale,
      previousRadiusScale
    );
    fromToMotion(
      this.id,
      "nodes",
      animationManager,
      [itemSelection, highlightSelection, phantomSelection, phantomHighlightSelection],
      fns.nodes,
      (_, datum) => this.getDatumId(datum.datumIndex),
      dataDiff
    );
    fromToMotion(this.id, `innerCircle`, animationManager, [this.innerCircleSelection], fns.innerCircle);
    seriesLabelFadeInAnimation(this, "callout", this.ctx.animationManager, this.calloutLabelSelection);
    seriesLabelFadeInAnimation(
      this,
      "sector",
      this.ctx.animationManager,
      this.labelSelection,
      this.highlightLabelSelection
    );
    if (this.noVisibleData !== noVisibleData) {
      this.noVisibleData = noVisibleData;
      seriesLabelFadeInAnimation(this, "inner", this.ctx.animationManager, this.innerLabelsSelection);
    }
    this.previousRadiusScale.range = this.radiusScale.range;
  }
  animateClearingUpdateEmpty() {
    const {
      itemSelection,
      highlightSelection,
      phantomSelection,
      phantomHighlightSelection,
      radiusScale,
      previousRadiusScale
    } = this;
    const { animationManager } = this.ctx;
    const fns = preparePieSeriesAnimationFunctions(
      false,
      this.properties.rotation,
      radiusScale,
      previousRadiusScale
    );
    fromToMotion(
      this.id,
      "nodes",
      animationManager,
      [itemSelection, highlightSelection, phantomSelection, phantomHighlightSelection],
      fns.nodes,
      (_, datum) => this.getDatumId(datum.datumIndex)
    );
    fromToMotion(this.id, `innerCircle`, animationManager, [this.innerCircleSelection], fns.innerCircle);
    seriesLabelFadeOutAnimation(this, "callout", this.ctx.animationManager, this.calloutLabelSelection);
    seriesLabelFadeOutAnimation(
      this,
      "sector",
      this.ctx.animationManager,
      this.labelSelection,
      this.highlightLabelSelection
    );
    seriesLabelFadeOutAnimation(this, "inner", this.ctx.animationManager, this.innerLabelsSelection);
    this.previousRadiusScale.range = this.radiusScale.range;
  }
  getDatumId(datumIndex) {
    const { dataModel, processedData } = this;
    if (!dataModel || !processedData) {
      return `${datumIndex}`;
    }
    const { calloutLabelKey, sectorLabelKey, legendItemKey } = this.properties;
    if (!processedData.reduced?.animationValidation?.uniqueKeys) {
      return `${datumIndex}`;
    }
    if (legendItemKey) {
      const legendItemKeys = dataModel.resolveKeysById(this, "legendItemKey", processedData);
      return createDatumId(legendItemKeys[datumIndex]);
    } else if (calloutLabelKey) {
      const calloutLabelKeys = dataModel.resolveKeysById(this, "calloutLabelKey", processedData);
      return createDatumId(calloutLabelKeys[datumIndex]);
    } else if (sectorLabelKey) {
      const sectorLabelKeys = dataModel.resolveKeysById(this, "sectorLabelKey", processedData);
      return createDatumId(sectorLabelKeys[datumIndex]);
    }
    return `${datumIndex}`;
  }
  hasItemStylers() {
    return !(this.properties.itemStyler == null && this.properties.calloutLabel.itemStyler == null && this.properties.sectorLabel.itemStyler == null && this.properties.innerLabels.every((innerLabel) => innerLabel.itemStyler == null));
  }
};
DonutSeries.className = "DonutSeries";
DonutSeries.type = "donut";

// packages/ag-charts-community/src/chart/series/polar/pieTheme.ts
var pieTheme = {
  series: {
    title: {
      enabled: true,
      fontWeight: { $ref: "fontWeight" },
      fontSize: { $rem: FONT_SIZE_RATIO.LARGE },
      fontFamily: { $ref: "fontFamily" },
      color: { $ref: "subtleTextColor" },
      spacing: 5
    },
    calloutLabel: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: true,
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      fontWeight: { $ref: "fontWeight" },
      color: { $ref: "textColor" },
      offset: 3,
      minAngle: 1e-3
    },
    sectorLabel: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: true,
      fontWeight: { $ref: "fontWeight" },
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      color: { $ref: "chartBackgroundColor" },
      positionOffset: 0,
      positionRatio: 0.5
    },
    calloutLine: {
      length: 10,
      strokeWidth: 2,
      colors: {
        $map: [
          {
            $if: [
              {
                $or: [
                  { $isGradient: { $value: "$1" } },
                  { $isPattern: { $value: "$1" } },
                  { $isImage: { $value: "$1" } }
                ]
              },
              { $path: ["../../strokes/$index", { $ref: "foregroundColor" }] },
              { $value: "$1" }
            ]
          },
          {
            $if: [
              { $eq: [{ $path: "../strokeWidth" }, 0] },
              { $path: "../fills" },
              { $path: "../strokes" }
            ]
          }
        ]
      }
    },
    fills: {
      $applyCycle: [
        { $cacheMax: { $size: { $path: ["./data", { $path: "/data" }] } } },
        { $palette: "fills" },
        {
          $applySwitch: [
            { $path: ["/type", void 0, { $value: "$1" }] },
            { $value: "$1" },
            ["gradient", FILL_GRADIENT_RADIAL_REVERSED_SERIES_DEFAULTS],
            ["pattern", FILL_PATTERN_DEFAULTS],
            ["image", FILL_IMAGE_DEFAULTS]
          ]
        }
      ]
    },
    strokes: {
      $applyCycle: [{ $cacheMax: { $size: { $path: ["./data", { $path: "/data" }] } } }, { $palette: "strokes" }]
    },
    fillOpacity: 1,
    strokeOpacity: 1,
    strokeWidth: { $isUserOption: ["./strokes/0", 2, 0] },
    lineDash: [0],
    lineDashOffset: 0,
    rotation: 0,
    sectorSpacing: 1,
    shadow: {
      enabled: false,
      color: DEFAULT_SHADOW_COLOUR,
      xOffset: 3,
      yOffset: 3,
      blur: 5
    },
    highlight: PART_WHOLE_HIGHLIGHT_STYLE
  },
  legend: { enabled: true }
};

// packages/ag-charts-community/src/chart/series/polar/donutTheme.ts
var donutTheme = {
  ...pieTheme,
  series: {
    ...pieTheme.series,
    innerRadiusRatio: {
      $if: [{ $eq: [{ $path: ["./innerRadiusOffset", void 0] }, void 0] }, 0.7, void 0]
    },
    innerLabels: {
      $apply: {
        ...LABEL_BOXING_DEFAULTS,
        fontSize: { $ref: "fontSize" },
        fontFamily: { $ref: "fontFamily" },
        fontWeight: { $ref: "fontWeight" },
        color: { $ref: "textColor" },
        spacing: 2
      }
    },
    highlight: PART_WHOLE_HIGHLIGHT_STYLE
  }
};

// packages/ag-charts-community/src/chart/series/polar/donutSeriesModule.ts
var DonutSeriesModule = {
  type: "series",
  name: "donut",
  chartType: "polar",
  version: VERSION,
  dependencies: [PolarChartModule],
  options: donutSeriesOptionsDef,
  themeTemplate: donutTheme,
  create: (ctx) => new DonutSeries(ctx)
};

// packages/ag-charts-community/src/chart/series/polar/pieSeries.ts
var PieSeries = class extends DonutSeries {
};
PieSeries.className = "PieSeries";
PieSeries.type = "pie";

// packages/ag-charts-community/src/chart/series/polar/pieSeriesModule.ts
var PieSeriesModule = {
  type: "series",
  name: "pie",
  chartType: "polar",
  version: VERSION,
  dependencies: [PolarChartModule],
  options: pieSeriesOptionsDef,
  themeTemplate: pieTheme,
  create: (ctx) => new PieSeries(ctx)
};

// packages/ag-charts-community/src/locale/locale.ts
var Locale = class extends AbstractModuleInstance {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.localeText = void 0;
  }
};
__decorateClass([
  ObserveChanges((target) => {
    target.ctx.localeManager.setLocaleText(target.localeText);
  }),
  addFakeTransformToInstanceProperty
], Locale.prototype, "localeText", 2);
__decorateClass([
  ObserveChanges((target) => {
    target.ctx.localeManager.setLocaleTextFormatter(target.getLocaleText);
  }),
  addFakeTransformToInstanceProperty
], Locale.prototype, "getLocaleText", 2);

// packages/ag-charts-community/src/locale/localeModule.ts
var LocaleModule = {
  type: "plugin",
  name: "locale",
  version: VERSION,
  options: {
    localeText: object,
    getLocaleText: callbackOf(string)
  },
  create: (ctx) => new Locale(ctx)
};

// packages/ag-charts-community/src/module/axis-modules/numberAxisModule.ts
var NumberAxisModule = {
  type: "axis",
  name: "number",
  chartType: "cartesian",
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: numberAxisOptionsDefs,
  themeTemplate: {
    line: { enabled: false }
  },
  create: (ctx) => new NumberAxis(ctx)
};

// packages/ag-charts-community/src/module/axis-modules/logAxisModule.ts
var LogAxisModule = {
  type: "axis",
  name: "log",
  chartType: "cartesian",
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: logAxisOptionsDefs,
  themeTemplate: {
    base: 10,
    line: { enabled: false }
  },
  create: (ctx) => new LogAxis(ctx)
};

// packages/ag-charts-community/src/module/axis-modules/timeAxisModule.ts
var TimeAxisModule = {
  type: "axis",
  name: "time",
  chartType: "cartesian",
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: timeAxisOptionsDefs,
  themeTemplate: {
    gridLine: { enabled: false }
  },
  create: (ctx) => new TimeAxis(ctx)
};

// packages/ag-charts-community/src/module/axis-modules/categoryAxisModule.ts
var CategoryAxisModule = {
  type: "axis",
  name: "category",
  chartType: "cartesian",
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: categoryAxisOptionsDefs,
  themeTemplate: {
    groupPaddingInner: 0.1,
    label: { autoRotate: true, wrapping: "on-space" },
    gridLine: { enabled: false },
    interval: { placement: "between" }
  },
  create: (ctx) => new CategoryAxis(ctx)
};

// packages/ag-charts-community/src/module/axis-modules/groupedCategoryAxisModule.ts
var GroupedCategoryAxisModule = {
  type: "axis",
  name: "grouped-category",
  chartType: "cartesian",
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: groupedCategoryAxisOptionsDefs,
  themeTemplate: {
    tick: { enabled: true, stroke: { $ref: "separationLinesColor" } },
    label: { spacing: 10, rotation: 270, wrapping: "on-space" },
    maxThicknessRatio: 0.5,
    paddingInner: 0.4,
    groupPaddingInner: 0.2
  },
  create: (ctx) => new GroupedCategoryAxis(ctx)
};

// packages/ag-charts-community/src/chart/axis/unitTimeAxis.ts
var UnitTimeAxis = class extends DiscreteTimeAxis {
  constructor(moduleCtx) {
    super(moduleCtx, new UnitTimeScale(), false);
    this.parentLevel = new TimeAxisParentLevel();
    this.min = void 0;
    this.max = void 0;
    this.preferredMin = void 0;
    this.preferredMax = void 0;
    // eslint-disable-next-line sonarjs/use-type-alias
    this.unit = void 0;
    this.defaultUnit = void 0;
  }
  get primaryLabel() {
    return this.parentLevel.enabled ? this.parentLevel.label : void 0;
  }
  get primaryTick() {
    return this.parentLevel.enabled ? this.parentLevel.tick : void 0;
  }
  hasDefinedDomain() {
    const { min, max } = this;
    return min != null && max != null && min < max;
  }
  isCategoryLike() {
    return true;
  }
  processData() {
    super.processData();
    let defaultUnit;
    const { domain } = this.dataDomain;
    if (domain.length === 2 && domain[0].valueOf() === domain[1].valueOf()) {
      defaultUnit = lowestGranularityUnitForValue(domain[0]);
    } else {
      const { boundSeries, direction, min, max } = this;
      defaultUnit = calculateDefaultUnit(boundSeries, direction, min, max);
    }
    if (!objectsEqual(this.defaultUnit, defaultUnit)) {
      this.defaultUnit = defaultUnit;
    }
  }
  updateScale() {
    super.updateScale();
    this.scale.interval = this.unit ?? this.defaultUnit;
  }
  normaliseDataDomain(d) {
    const { extent: extent2, clipped } = normalisedTimeExtentWithMetadata(
      d,
      this.min,
      this.max,
      this.preferredMin,
      this.preferredMax
    );
    return { domain: extent2, clipped };
  }
  tickFormatParams(domain, ticks, _fractionDigits, timeInterval3) {
    timeInterval3 ?? (timeInterval3 = lowestGranularityUnitForTicks(ticks));
    const truncateDate = dateTruncationForDomain(domain);
    const unit = intervalUnit(timeInterval3);
    const step = intervalStep(timeInterval3);
    const epoch = intervalEpoch(timeInterval3);
    return { type: "date", unit, step, epoch, truncateDate };
  }
  datumFormatParams(value, params, _fractionDigits, timeInterval3, style2) {
    const interval = this.unit ?? this.defaultUnit ?? "millisecond";
    timeInterval3 ?? (timeInterval3 = interval);
    const { datum, seriesId, legendItemName, key, source, property, domain, boundSeries } = params;
    const unit = intervalUnit(timeInterval3);
    const step = intervalStep(timeInterval3);
    const epoch = intervalEpoch(timeInterval3);
    return {
      type: "date",
      value: intervalFloor(interval, value),
      datum,
      seriesId,
      legendItemName,
      key,
      source,
      property,
      domain,
      boundSeries,
      unit,
      step,
      epoch,
      style: style2
    };
  }
};
UnitTimeAxis.className = "UnitTimeAxis";
UnitTimeAxis.type = "unit-time";
__decorateClass([
  addFakeTransformToInstanceProperty
], UnitTimeAxis.prototype, "parentLevel", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], UnitTimeAxis.prototype, "min", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], UnitTimeAxis.prototype, "max", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], UnitTimeAxis.prototype, "preferredMin", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], UnitTimeAxis.prototype, "preferredMax", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], UnitTimeAxis.prototype, "unit", 2);

// packages/ag-charts-community/src/module/axis-modules/unitTimeAxisModule.ts
var UnitTimeAxisModule = {
  type: "axis",
  name: "unit-time",
  chartType: "cartesian",
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: unitTimeAxisOptionsDefs,
  themeTemplate: {
    groupPaddingInner: 0.1,
    label: { autoRotate: false },
    gridLine: { enabled: false },
    parentLevel: { enabled: true },
    interval: { placement: "between" }
  },
  create: (ctx) => new UnitTimeAxis(ctx)
};

// packages/ag-charts-community/src/module-bundles/cartesian-axes.ts
var AllCartesianAxesModule = [
  NumberAxisModule,
  LogAxisModule,
  TimeAxisModule,
  CategoryAxisModule,
  GroupedCategoryAxisModule,
  UnitTimeAxisModule
];

// packages/ag-charts-community/src/module-bundles/cartesian-series.ts
var AllCartesianSeriesModule = [
  AreaSeriesModule,
  BarSeriesModule,
  BubbleSeriesModule,
  HistogramSeriesModule,
  LineSeriesModule,
  ScatterSeriesModule
];

// packages/ag-charts-community/src/module-bundles/cartesian.ts
var AllCartesianModule = [
  AllCartesianAxesModule,
  AllCartesianSeriesModule,
  LegendModule,
  LocaleModule
].flat();

// packages/ag-charts-community/src/module-bundles/polar.ts
var AllPolarModule = [
  PolarChartModule,
  DonutSeriesModule,
  PieSeriesModule,
  LegendModule,
  LocaleModule
];

// packages/ag-charts-community/src/module-bundles/all.ts
var AllCommunityModule = [
  AllCartesianModule,
  AllPolarModule,
  // Presets
  SparklinePresetModule
].flat();

// packages/ag-charts-community/src/integrated-charts-scene.ts
var integrated_charts_scene_exports = {};
__export(integrated_charts_scene_exports, {
  Arc: () => Arc,
  BBox: () => BBox,
  Caption: () => Caption,
  CategoryScale: () => CategoryScale,
  Group: () => Group,
  Line: () => Line,
  LinearScale: () => LinearScale,
  Marker: () => Marker,
  Path: () => Path,
  RadialColumnShape: () => RadialColumnShape,
  Rect: () => Rect,
  Scene: () => Scene,
  Sector: () => Sector,
  Shape: () => Shape,
  TranslatableGroup: () => TranslatableGroup,
  getRadialColumnWidth: () => getRadialColumnWidth,
  toRadians: () => toRadians
});

// packages/ag-charts-community/src/integrated-charts-theme.ts
var integrated_charts_theme_exports = {};
__export(integrated_charts_theme_exports, {
  AGGREGATION_INDEX_UNSET: () => AGGREGATION_INDEX_UNSET,
  AGGREGATION_INDEX_X_MAX: () => AGGREGATION_INDEX_X_MAX,
  AGGREGATION_INDEX_X_MIN: () => AGGREGATION_INDEX_X_MIN,
  AGGREGATION_INDEX_Y_MAX: () => AGGREGATION_INDEX_Y_MAX,
  AGGREGATION_INDEX_Y_MIN: () => AGGREGATION_INDEX_Y_MIN,
  AGGREGATION_MAX_POINTS: () => AGGREGATION_MAX_POINTS,
  AGGREGATION_MIN_RANGE: () => AGGREGATION_MIN_RANGE,
  AGGREGATION_SPAN: () => AGGREGATION_SPAN,
  AGGREGATION_THRESHOLD: () => AGGREGATION_THRESHOLD,
  AbstractModuleInstance: () => AbstractModuleInstance,
  ActionOnSet: () => ActionOnSet,
  AdjacencyListGraph: () => AdjacencyListGraph,
  AsyncAwaitQueue: () => AsyncAwaitQueue,
  BASE_FONT_SIZE: () => BASE_FONT_SIZE,
  BREAK_TRANSFORM_CHAIN: () => BREAK_TRANSFORM_CHAIN,
  BaseProperties: () => BaseProperties,
  Border: () => Border,
  CANVAS_HEIGHT: () => CANVAS_HEIGHT,
  CANVAS_TO_BUFFER_DEFAULTS: () => CANVAS_TO_BUFFER_DEFAULTS,
  CANVAS_WIDTH: () => CANVAS_WIDTH,
  CARTESIAN_AXIS_TYPE: () => CARTESIAN_AXIS_TYPE,
  CARTESIAN_POSITION: () => CARTESIAN_POSITION,
  CallbackCache: () => CallbackCache,
  ChangeDetectableProperties: () => ChangeDetectableProperties,
  ChartAxisDirection: () => ChartAxisDirection,
  ChartTheme: () => ChartTheme,
  ChartUpdateType: () => ChartUpdateType,
  CleanupRegistry: () => CleanupRegistry,
  Color: () => Color,
  ConfiguredCanvasMixin: () => ConfiguredCanvasMixin,
  DEFAULT_ANNOTATION_HANDLE_FILL: () => DEFAULT_ANNOTATION_HANDLE_FILL,
  DEFAULT_ANNOTATION_STATISTICS_COLOR: () => DEFAULT_ANNOTATION_STATISTICS_COLOR,
  DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE: () => DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE,
  DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL: () => DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL,
  DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE: () => DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE,
  DEFAULT_ANNOTATION_STATISTICS_FILL: () => DEFAULT_ANNOTATION_STATISTICS_FILL,
  DEFAULT_ANNOTATION_STATISTICS_STROKE: () => DEFAULT_ANNOTATION_STATISTICS_STROKE,
  DEFAULT_CAPTION_ALIGNMENT: () => DEFAULT_CAPTION_ALIGNMENT,
  DEFAULT_CAPTION_LAYOUT_STYLE: () => DEFAULT_CAPTION_LAYOUT_STYLE,
  DEFAULT_FIBONACCI_STROKES: () => DEFAULT_FIBONACCI_STROKES,
  DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL: () => DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL,
  DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR: () => DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR,
  DEFAULT_POLAR_SERIES_STROKE: () => DEFAULT_POLAR_SERIES_STROKE,
  DEFAULT_SHADOW_COLOUR: () => DEFAULT_SHADOW_COLOUR,
  DEFAULT_SPARKLINE_CROSSHAIR_STROKE: () => DEFAULT_SPARKLINE_CROSSHAIR_STROKE,
  DEFAULT_TEXTBOX_COLOR: () => DEFAULT_TEXTBOX_COLOR,
  DEFAULT_TEXTBOX_FILL: () => DEFAULT_TEXTBOX_FILL,
  DEFAULT_TEXTBOX_STROKE: () => DEFAULT_TEXTBOX_STROKE,
  DEFAULT_TEXT_ANNOTATION_COLOR: () => DEFAULT_TEXT_ANNOTATION_COLOR,
  DEFAULT_TOOLBAR_POSITION: () => DEFAULT_TOOLBAR_POSITION,
  DIRECTION_SWAP_AXES: () => DIRECTION_SWAP_AXES,
  Debug: () => debugLogger_exports,
  DebugMetrics: () => debugMetrics_exports,
  DeclaredSceneChangeDetection: () => DeclaredSceneChangeDetection,
  DeclaredSceneObjectChangeDetection: () => DeclaredSceneObjectChangeDetection,
  Deprecated: () => Deprecated,
  DeprecatedAndRenamedTo: () => DeprecatedAndRenamedTo,
  EllipsisChar: () => EllipsisChar,
  ErrorType: () => ErrorType,
  EventEmitter: () => EventEmitter,
  FILL_GRADIENT_BLANK_DEFAULTS: () => FILL_GRADIENT_BLANK_DEFAULTS,
  FILL_GRADIENT_CONIC_SERIES_DEFAULTS: () => FILL_GRADIENT_CONIC_SERIES_DEFAULTS,
  FILL_GRADIENT_LINEAR_DEFAULTS: () => FILL_GRADIENT_LINEAR_DEFAULTS,
  FILL_GRADIENT_LINEAR_HIERARCHY_DEFAULTS: () => FILL_GRADIENT_LINEAR_HIERARCHY_DEFAULTS,
  FILL_GRADIENT_LINEAR_KEYED_DEFAULTS: () => FILL_GRADIENT_LINEAR_KEYED_DEFAULTS,
  FILL_GRADIENT_LINEAR_SINGLE_DEFAULTS: () => FILL_GRADIENT_LINEAR_SINGLE_DEFAULTS,
  FILL_GRADIENT_RADIAL_DEFAULTS: () => FILL_GRADIENT_RADIAL_DEFAULTS,
  FILL_GRADIENT_RADIAL_REVERSED_DEFAULTS: () => FILL_GRADIENT_RADIAL_REVERSED_DEFAULTS,
  FILL_GRADIENT_RADIAL_REVERSED_SERIES_DEFAULTS: () => FILL_GRADIENT_RADIAL_REVERSED_SERIES_DEFAULTS,
  FILL_GRADIENT_RADIAL_SERIES_DEFAULTS: () => FILL_GRADIENT_RADIAL_SERIES_DEFAULTS,
  FILL_IMAGE_BLANK_DEFAULTS: () => FILL_IMAGE_BLANK_DEFAULTS,
  FILL_IMAGE_DEFAULTS: () => FILL_IMAGE_DEFAULTS,
  FILL_PATTERN_BLANK_DEFAULTS: () => FILL_PATTERN_BLANK_DEFAULTS,
  FILL_PATTERN_DEFAULTS: () => FILL_PATTERN_DEFAULTS,
  FILL_PATTERN_HIERARCHY_DEFAULTS: () => FILL_PATTERN_HIERARCHY_DEFAULTS,
  FILL_PATTERN_KEYED_DEFAULTS: () => FILL_PATTERN_KEYED_DEFAULTS,
  FILL_PATTERN_SINGLE_DEFAULTS: () => FILL_PATTERN_SINGLE_DEFAULTS,
  FONT_SIZE: () => FONT_SIZE,
  FONT_SIZE_RATIO: () => FONT_SIZE_RATIO,
  IS_DARK_THEME: () => IS_DARK_THEME,
  InterpolationProperties: () => InterpolationProperties,
  LABEL_BOXING_DEFAULTS: () => LABEL_BOXING_DEFAULTS,
  LEGEND_CONTAINER_THEME: () => LEGEND_CONTAINER_THEME,
  LRUCache: () => LRUCache,
  LineSplitter: () => LineSplitter,
  Logger: () => logger_exports,
  MARKER_SERIES_HIGHLIGHT_STYLE: () => MARKER_SERIES_HIGHLIGHT_STYLE,
  MULTI_SERIES_HIGHLIGHT_STYLE: () => MULTI_SERIES_HIGHLIGHT_STYLE,
  MementoCaretaker: () => MementoCaretaker,
  ModuleRegistry: () => moduleRegistry_exports,
  ModuleType: () => ModuleType,
  ObserveChanges: () => ObserveChanges,
  PALETTE_ALT_DOWN_FILL: () => PALETTE_ALT_DOWN_FILL,
  PALETTE_ALT_DOWN_STROKE: () => PALETTE_ALT_DOWN_STROKE,
  PALETTE_ALT_NEUTRAL_FILL: () => PALETTE_ALT_NEUTRAL_FILL,
  PALETTE_ALT_NEUTRAL_STROKE: () => PALETTE_ALT_NEUTRAL_STROKE,
  PALETTE_ALT_UP_FILL: () => PALETTE_ALT_UP_FILL,
  PALETTE_ALT_UP_STROKE: () => PALETTE_ALT_UP_STROKE,
  PALETTE_DOWN_FILL: () => PALETTE_DOWN_FILL,
  PALETTE_DOWN_STROKE: () => PALETTE_DOWN_STROKE,
  PALETTE_NEUTRAL_FILL: () => PALETTE_NEUTRAL_FILL,
  PALETTE_NEUTRAL_STROKE: () => PALETTE_NEUTRAL_STROKE,
  PALETTE_UP_FILL: () => PALETTE_UP_FILL,
  PALETTE_UP_STROKE: () => PALETTE_UP_STROKE,
  PART_WHOLE_HIGHLIGHT_STYLE: () => PART_WHOLE_HIGHLIGHT_STYLE,
  POLAR_AXIS_SHAPE: () => POLAR_AXIS_SHAPE,
  POLAR_AXIS_TYPE: () => POLAR_AXIS_TYPE,
  PREV_NEXT_KEYS: () => PREV_NEXT_KEYS,
  Padding: () => Padding,
  ParallelStateMachine: () => ParallelStateMachine,
  PolarZIndexMap: () => PolarZIndexMap,
  PropertiesArray: () => PropertiesArray,
  Property: () => addFakeTransformToInstanceProperty,
  ProxyOnWrite: () => ProxyOnWrite,
  ProxyProperty: () => ProxyProperty,
  ProxyPropertyOnWrite: () => ProxyPropertyOnWrite,
  SAFE_FILLS_OPERATION: () => SAFE_FILLS_OPERATION,
  SAFE_FILL_OPERATION: () => SAFE_FILL_OPERATION,
  SAFE_RANGE2_OPERATION: () => SAFE_RANGE2_OPERATION,
  SAFE_STROKE_FILL_OPERATION: () => SAFE_STROKE_FILL_OPERATION,
  SEGMENTATION_DEFAULTS: () => SEGMENTATION_DEFAULTS,
  SINGLE_SERIES_HIGHLIGHT_STYLE: () => SINGLE_SERIES_HIGHLIGHT_STYLE,
  SKIP_JS_BUILTINS: () => SKIP_JS_BUILTINS,
  ScaleAlignment: () => ScaleAlignment,
  SceneArrayChangeDetection: () => SceneArrayChangeDetection,
  SceneChangeDetection: () => SceneChangeDetection,
  SceneObjectChangeDetection: () => SceneObjectChangeDetection,
  SceneRefChangeDetection: () => SceneRefChangeDetection,
  SeriesContentZIndexMap: () => SeriesContentZIndexMap,
  SeriesZIndexMap: () => SeriesZIndexMap,
  SimpleCache: () => SimpleCache,
  SpanJoin: () => SpanJoin,
  StateMachine: () => StateMachine,
  StateMachineProperty: () => StateMachineProperty,
  TRIPLE_EQ: () => TRIPLE_EQ,
  TextMeasurer: () => TextMeasurer,
  TickIntervals: () => TickIntervals,
  TrimCharsRegex: () => TrimCharsRegex,
  TrimEdgeGuard: () => TrimEdgeGuard,
  UNIT_MAX: () => UNIT_MAX,
  UNIT_MIN: () => UNIT_MIN,
  UnknownError: () => UnknownError,
  ValidationError: () => ValidationError,
  Vec2: () => vector_exports,
  Vec4: () => vector4_exports,
  Vertex: () => Vertex,
  WeakCache: () => WeakCache,
  ZIndexMap: () => ZIndexMap,
  addEscapeEventListener: () => addEscapeEventListener,
  addFakeTransformToInstanceProperty: () => addFakeTransformToInstanceProperty,
  addMouseCloseListener: () => addMouseCloseListener,
  addObserverToInstanceProperty: () => addObserverToInstanceProperty,
  addOverrideFocusVisibleEventListener: () => addOverrideFocusVisibleEventListener,
  addTouchCloseListener: () => addTouchCloseListener,
  addTransformToInstanceProperty: () => addTransformToInstanceProperty,
  aggregationBucketForDatum: () => aggregationBucketForDatum,
  aggregationDatumMatchesIndex: () => aggregationDatumMatchesIndex,
  aggregationDomain: () => aggregationDomain,
  aggregationIndexForXRatio: () => aggregationIndexForXRatio,
  aggregationRangeFittingPoints: () => aggregationRangeFittingPoints,
  aggregationXRatioForDatumIndex: () => aggregationXRatioForDatumIndex,
  aggregationXRatioForXValue: () => aggregationXRatioForXValue,
  and: () => and,
  angleBetween: () => angleBetween,
  angularPadding: () => angularPadding,
  appendEllipsis: () => appendEllipsis,
  applySkiaPatches: () => applySkiaPatches,
  arcDistanceSquared: () => arcDistanceSquared,
  areScalingEqual: () => areScalingEqual,
  array: () => array,
  arrayLength: () => arrayLength,
  arrayOf: () => arrayOf,
  arrayOfDefs: () => arrayOfDefs,
  arraysEqual: () => arraysEqual,
  assignIfNotStrictlyEqual: () => assignIfNotStrictlyEqual,
  attachDescription: () => attachDescription,
  attachListener: () => attachListener,
  autoSizedLabelOptionsDefs: () => autoSizedLabelOptionsDefs,
  barHighlightOptionsDef: () => barHighlightOptionsDef,
  bezier2DDistance: () => bezier2DDistance,
  bezier2DExtrema: () => bezier2DExtrema,
  boolean: () => boolean,
  borderOptionsDef: () => borderOptionsDef,
  boxCollides: () => boxCollides,
  boxContains: () => boxContains,
  boxEmpty: () => boxEmpty,
  boxesEqual: () => boxesEqual,
  buildDateFormatter: () => buildDateFormatter,
  cachedTextMeasurer: () => cachedTextMeasurer,
  calcLineHeight: () => calcLineHeight,
  calculatePlacement: () => calculatePlacement,
  callWithContext: () => callWithContext,
  callback: () => callback,
  callbackDefs: () => callbackDefs,
  callbackOf: () => callbackOf,
  ceilTo: () => ceilTo,
  checkDatum: () => checkDatum,
  circularSliceArray: () => circularSliceArray,
  clamp: () => clamp,
  clampArray: () => clampArray,
  clipLines: () => clipLines,
  clipSpanX: () => clipSpanX,
  collapseSpanToPoint: () => collapseSpanToPoint,
  collectAggregationLevels: () => collectAggregationLevels,
  color: () => color,
  colorStopsOrderValidator: () => colorStopsOrderValidator,
  colorUnion: () => colorUnion,
  commonChartOptionsDefs: () => commonChartOptionsDefs,
  commonSeriesOptionsDefs: () => commonSeriesOptionsDefs,
  commonSeriesThemeableOptionsDefs: () => commonSeriesThemeableOptionsDefs,
  compactAggregationIndices: () => compactAggregationIndices,
  compareDates: () => compareDates,
  computeExtremesAggregation: () => computeExtremesAggregation,
  computeExtremesAggregationPartial: () => computeExtremesAggregationPartial,
  constant: () => constant,
  contextMenuItemsArray: () => contextMenuItemsArray,
  countFractionDigits: () => countFractionDigits,
  countLines: () => countLines,
  createAggregationIndices: () => createAggregationIndices,
  createButton: () => createButton,
  createCanvasContext: () => createCanvasContext,
  createCheckbox: () => createCheckbox,
  createDeprecationWarning: () => createDeprecationWarning,
  createElement: () => createElement,
  createElementId: () => createElementId,
  createIcon: () => createIcon,
  createId: () => createId,
  createIdsGenerator: () => createIdsGenerator,
  createNumberFormatter: () => createNumberFormatter,
  createSelect: () => createSelect,
  createSvgElement: () => createSvgElement,
  createTextArea: () => createTextArea,
  createTicks: () => createTicks,
  date: () => date,
  dateToNumber: () => dateToNumber,
  dateTruncationForDomain: () => dateTruncationForDomain,
  datesSortOrder: () => datesSortOrder,
  debounce: () => debounce,
  decodeIntervalValue: () => decodeIntervalValue,
  deepClone: () => deepClone,
  deepFreeze: () => deepFreeze,
  defaultEpoch: () => defaultEpoch,
  defined: () => defined,
  definedZoomState: () => definedZoomState,
  diffArrays: () => diffArrays,
  distribute: () => distribute,
  downloadUrl: () => downloadUrl,
  dropFirstWhile: () => dropFirstWhile,
  dropLastWhile: () => dropLastWhile,
  durationDay: () => durationDay,
  durationHour: () => durationHour,
  durationMinute: () => durationMinute,
  durationMonth: () => durationMonth,
  durationSecond: () => durationSecond,
  durationWeek: () => durationWeek,
  durationYear: () => durationYear,
  easeIn: () => easeIn,
  easeInOut: () => easeInOut,
  easeInOutQuad: () => easeInOutQuad,
  easeInQuad: () => easeInQuad,
  easeOut: () => easeOut,
  easeOutQuad: () => easeOutQuad,
  encodedToTimestamp: () => encodedToTimestamp,
  enterpriseRegistry: () => enterpriseRegistry,
  entries: () => entries,
  errorBarOptionsDefs: () => errorBarOptionsDefs,
  errorBarThemeableOptionsDefs: () => errorBarThemeableOptionsDefs,
  estimateTickCount: () => estimateTickCount,
  evaluateBezier: () => evaluateBezier,
  every: () => every,
  expandLegendPosition: () => expandLegendPosition,
  extent: () => extent,
  extractDecoratedProperties: () => extractDecoratedProperties,
  extractDomain: () => extractDomain,
  fillGradientDefaults: () => fillGradientDefaults,
  fillImageDefaults: () => fillImageDefaults,
  fillOptionsDef: () => fillOptionsDef,
  fillPatternDefaults: () => fillPatternDefaults,
  findMaxIndex: () => findMaxIndex,
  findMaxValue: () => findMaxValue,
  findMinIndex: () => findMinIndex,
  findMinMax: () => findMinMax,
  findMinValue: () => findMinValue,
  findRangeExtent: () => findRangeExtent,
  first: () => first,
  flush: () => flush,
  focusCursorAtEnd: () => focusCursorAtEnd,
  fontFamilyFull: () => fontFamilyFull,
  fontOptionsDef: () => fontOptionsDef,
  fontWeight: () => fontWeight,
  formatNumber: () => formatNumber,
  formatObjectValidator: () => formatObjectValidator,
  formatPercent: () => formatPercent,
  formatValue: () => formatValue,
  fromPairs: () => fromPairs,
  generateUUID: () => generateUUID,
  geoJson: () => geoJson,
  getAngleRatioRadians: () => getAngleRatioRadians,
  getAttribute: () => getAttribute,
  getChartTheme: () => getChartTheme,
  getDOMMatrix: () => getDOMMatrix,
  getDocument: () => getDocument,
  getElementBBox: () => getElementBBox,
  getIconClassNames: () => getIconClassNames,
  getImage: () => getImage,
  getLastFocus: () => getLastFocus,
  getMaxInnerRectSize: () => getMaxInnerRectSize,
  getMidpointsForIndices: () => getMidpointsForIndices,
  getMinOuterRectSize: () => getMinOuterRectSize,
  getOffscreenCanvas: () => getOffscreenCanvas,
  getPath: () => getPath,
  getPath2D: () => getPath2D,
  getResizeObserver: () => getResizeObserver,
  getSequentialColors: () => getSequentialColors,
  getTickTimeInterval: () => getTickTimeInterval,
  getWindow: () => getWindow,
  googleFont: () => googleFont,
  gradientColorStops: () => gradientColorStops,
  gradientStrict: () => gradientStrict,
  greaterThan: () => greaterThan,
  groupBy: () => groupBy,
  guardTextEdges: () => guardTextEdges,
  hasNoModifiers: () => hasNoModifiers,
  hasRequiredInPath: () => hasRequiredInPath,
  highlightOptionsDef: () => highlightOptionsDef,
  htmlElement: () => htmlElement,
  inRange: () => inRange,
  initRovingTabIndex: () => initRovingTabIndex,
  insertListItemsSorted: () => insertListItemsSorted,
  instanceOf: () => instanceOf,
  interpolationOptionsDefs: () => interpolationOptionsDefs,
  intervalCeil: () => intervalCeil,
  intervalEpoch: () => intervalEpoch,
  intervalExtent: () => intervalExtent,
  intervalFloor: () => intervalFloor,
  intervalHierarchy: () => intervalHierarchy,
  intervalMilliseconds: () => intervalMilliseconds,
  intervalNext: () => intervalNext,
  intervalPrevious: () => intervalPrevious,
  intervalRange: () => intervalRange,
  intervalRangeCount: () => intervalRangeCount,
  intervalRangeNumeric: () => intervalRangeNumeric,
  intervalRangeStartIndex: () => intervalRangeStartIndex,
  intervalStep: () => intervalStep,
  intervalUnit: () => intervalUnit,
  inverseEaseOut: () => inverseEaseOut,
  isArray: () => isArray,
  isBetweenAngles: () => isBetweenAngles,
  isBoolean: () => isBoolean,
  isButtonClickEvent: () => isButtonClickEvent,
  isColor: () => isColor,
  isContinuous: () => isContinuous,
  isDate: () => isDate,
  isDecoratedObject: () => isDecoratedObject,
  isDefined: () => isDefined,
  isDenseInterval: () => isDenseInterval,
  isDocumentFragment: () => isDocumentFragment,
  isElement: () => isElement,
  isEmptyObject: () => isEmptyObject,
  isEnumKey: () => isEnumKey,
  isEnumValue: () => isEnumValue,
  isFiniteNumber: () => isFiniteNumber,
  isFunction: () => isFunction,
  isGradientFill: () => isGradientFill,
  isGradientFillArray: () => isGradientFillArray,
  isGradientOrPatternFill: () => isGradientOrPatternFill,
  isHTMLElement: () => isHTMLElement,
  isHtmlElement: () => isHtmlElement,
  isImageFill: () => isImageFill,
  isInputPending: () => isInputPending,
  isInteger: () => isInteger,
  isKeyOf: () => isKeyOf,
  isNegative: () => isNegative,
  isNode: () => isNode,
  isNumber: () => isNumber,
  isNumberEqual: () => isNumberEqual,
  isNumberObject: () => isNumberObject,
  isObject: () => isObject,
  isObjectLike: () => isObjectLike,
  isObjectWithProperty: () => isObjectWithProperty,
  isObjectWithStringProperty: () => isObjectWithStringProperty,
  isPatternFill: () => isPatternFill,
  isPlainObject: () => isPlainObject,
  isPointLabelDatum: () => isPointLabelDatum,
  isProperties: () => isProperties,
  isRegExp: () => isRegExp,
  isScaleValid: () => isScaleValid,
  isSegmentTruncated: () => isSegmentTruncated,
  isString: () => isString,
  isStringFillArray: () => isStringFillArray,
  isStringObject: () => isStringObject,
  isSymbol: () => isSymbol,
  isTextTruncated: () => isTextTruncated,
  isTruncated: () => isTruncated,
  isUnitTimeCategoryScaling: () => isUnitTimeCategoryScaling,
  isValidDate: () => isValidDate,
  isValidNumberFormat: () => isValidNumberFormat,
  iterate: () => iterate,
  joinFormatted: () => joinFormatted,
  jsonApply: () => jsonApply,
  jsonDiff: () => jsonDiff,
  jsonPropertyCompare: () => jsonPropertyCompare,
  jsonWalk: () => jsonWalk,
  kebabCase: () => kebabCase,
  labelBoxOptionsDef: () => labelBoxOptionsDef,
  legendPositionValidator: () => legendPositionValidator,
  lessThan: () => lessThan,
  lessThanOrEqual: () => lessThanOrEqual,
  levenshteinDistance: () => levenshteinDistance,
  lineDashOptionsDef: () => lineDashOptionsDef,
  lineDistanceSquared: () => lineDistanceSquared,
  lineHighlightOptionsDef: () => lineHighlightOptionsDef,
  lineSegmentOptions: () => lineSegmentOptions,
  lineSegmentation: () => lineSegmentation,
  linear: () => linear,
  linearGaugeSeriesOptionsDef: () => linearGaugeSeriesOptionsDef,
  linearGaugeSeriesThemeableOptionsDef: () => linearGaugeSeriesThemeableOptionsDef,
  linearGaugeTargetOptionsDef: () => linearGaugeTargetOptionsDef,
  linearPoints: () => linearPoints,
  listDecoratedProperties: () => listDecoratedProperties,
  lowestGranularityForInterval: () => lowestGranularityForInterval,
  lowestGranularityUnitForTicks: () => lowestGranularityUnitForTicks,
  lowestGranularityUnitForValue: () => lowestGranularityUnitForValue,
  makeAccessibleClickListener: () => makeAccessibleClickListener,
  mapValues: () => mapValues,
  markerOptionsDefs: () => markerOptionsDefs,
  markerStyleOptionsDefs: () => markerStyleOptionsDefs,
  measureTextSegments: () => measureTextSegments,
  memo: () => memo,
  merge: () => merge,
  mergeArrayDefaults: () => mergeArrayDefaults,
  mergeDefaults: () => mergeDefaults,
  modulus: () => modulus,
  multiSeriesHighlightOptionsDef: () => multiSeriesHighlightOptionsDef,
  nearestSquared: () => nearestSquared,
  nearestSquaredInContainer: () => nearestSquaredInContainer,
  nextPowerOf2: () => nextPowerOf2,
  niceTicksDomain: () => niceTicksDomain,
  normalisedExtentWithMetadata: () => normalisedExtentWithMetadata,
  normalisedTimeExtentWithMetadata: () => normalisedTimeExtentWithMetadata,
  normalizeAngle180: () => normalizeAngle180,
  normalizeAngle360: () => normalizeAngle360,
  normalizeAngle360FromDegrees: () => normalizeAngle360FromDegrees,
  normalizeAngle360Inclusive: () => normalizeAngle360Inclusive,
  number: () => number,
  numberFormatValidator: () => numberFormatValidator,
  numberMin: () => numberMin,
  numberRange: () => numberRange,
  object: () => object,
  objectsEqual: () => objectsEqual,
  objectsEqualWith: () => objectsEqualWith,
  optionsDefs: () => optionsDefs,
  or: () => or,
  padding: () => padding,
  paddingOptions: () => paddingOptions,
  parseNumberFormat: () => parseNumberFormat,
  partialAssign: () => partialAssign,
  pause: () => pause,
  pick: () => pick,
  placeLabels: () => placeLabels,
  positiveNumber: () => positiveNumber,
  positiveNumberNonZero: () => positiveNumberNonZero,
  previousPowerOf2: () => previousPowerOf2,
  radialGaugeSeriesOptionsDef: () => radialGaugeSeriesOptionsDef,
  radialGaugeSeriesThemeableOptionsDef: () => radialGaugeSeriesThemeableOptionsDef,
  radialGaugeTargetOptionsDef: () => radialGaugeTargetOptionsDef,
  range: () => range,
  rangeValidator: () => rangeValidator,
  ratio: () => ratio,
  readIntegratedWrappedValue: () => readIntegratedWrappedValue,
  record: () => record,
  required: () => required,
  rescaleSpan: () => rescaleSpan,
  rescaleVisibleRange: () => rescaleVisibleRange,
  resetIds: () => resetIds,
  resolveOperation: () => resolveOperation,
  rotatePoint: () => rotatePoint,
  roundTo: () => roundTo,
  safeCall: () => safeCall,
  seriesLabelOptionsDefs: () => seriesLabelOptionsDefs,
  seriesTooltipRangeValidator: () => seriesTooltipRangeValidator,
  setAttribute: () => setAttribute,
  setAttributes: () => setAttributes,
  setDocument: () => setDocument,
  setElementBBox: () => setElementBBox,
  setElementStyle: () => setElementStyle,
  setElementStyles: () => setElementStyles,
  setPath: () => setPath,
  setWindow: () => setWindow,
  shadowOptionsDefs: () => shadowOptionsDefs,
  shallowClone: () => shallowClone,
  shapeHighlightOptionsDef: () => shapeHighlightOptionsDef,
  shapeSegmentOptions: () => shapeSegmentOptions,
  shapeSegmentation: () => shapeSegmentation,
  shapeValidator: () => shapeValidator,
  simpleMemorize: () => simpleMemorize,
  simpleMemorize2: () => simpleMemorize2,
  smoothPoints: () => smoothPoints,
  solveBezier: () => solveBezier,
  sortAndUniqueDates: () => sortAndUniqueDates,
  sortBasedOnArray: () => sortBasedOnArray,
  spanRange: () => spanRange,
  splitBezier2D: () => splitBezier2D,
  stepPoints: () => stepPoints,
  stopPageScrolling: () => stopPageScrolling,
  strictObjectKeys: () => strictObjectKeys,
  strictUnion: () => strictUnion,
  string: () => string,
  stringLength: () => stringLength,
  stringifyValue: () => stringifyValue,
  strokeOptionsDef: () => strokeOptionsDef,
  textOrSegments: () => textOrSegments,
  themeNames: () => themeNames,
  themeOperator: () => themeOperator,
  themeSymbols: () => themeSymbols,
  themes: () => themes,
  throttle: () => throttle,
  tickFormat: () => tickFormat,
  tickStep: () => tickStep,
  toArray: () => toArray,
  toDegrees: () => toDegrees,
  toFontString: () => toFontString,
  toIterable: () => toIterable,
  toPlainText: () => toPlainText,
  toRadians: () => toRadians,
  toTextString: () => toTextString,
  toolbarButtonOptionsDefs: () => toolbarButtonOptionsDefs,
  tooltipOptionsDefs: () => tooltipOptionsDefs,
  tooltipOptionsDefsWithArea: () => tooltipOptionsDefsWithArea,
  transformIntegratedCategoryValue: () => transformIntegratedCategoryValue,
  truncateLine: () => truncateLine,
  typeUnion: () => typeUnion,
  undocumented: () => undocumented,
  unguardTextEdges: () => unguardTextEdges,
  union: () => union,
  unionSymbol: () => unionSymbol,
  unique: () => unique,
  validate: () => validate,
  withTimeout: () => withTimeout,
  without: () => without,
  wrapLines: () => wrapLines,
  wrapText: () => wrapText,
  wrapTextOrSegments: () => wrapTextOrSegments,
  wrapTextSegments: () => wrapTextSegments
});
var themeSymbols = {
  DEFAULT_ANNOTATION_HANDLE_FILL,
  DEFAULT_ANNOTATION_STATISTICS_COLOR,
  DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE,
  DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL,
  DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE,
  DEFAULT_ANNOTATION_STATISTICS_FILL,
  DEFAULT_ANNOTATION_STATISTICS_STROKE,
  DEFAULT_CAPTION_ALIGNMENT,
  DEFAULT_CAPTION_LAYOUT_STYLE,
  DEFAULT_FIBONACCI_STROKES,
  DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL,
  DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR,
  DEFAULT_POLAR_SERIES_STROKE,
  DEFAULT_SHADOW_COLOUR,
  DEFAULT_SPARKLINE_CROSSHAIR_STROKE,
  DEFAULT_TEXTBOX_COLOR,
  DEFAULT_TEXTBOX_FILL,
  DEFAULT_TEXTBOX_STROKE,
  DEFAULT_TEXT_ANNOTATION_COLOR,
  DEFAULT_TOOLBAR_POSITION,
  IS_DARK_THEME,
  PALETTE_ALT_DOWN_FILL,
  PALETTE_ALT_DOWN_STROKE,
  PALETTE_ALT_NEUTRAL_FILL,
  PALETTE_ALT_NEUTRAL_STROKE,
  PALETTE_ALT_UP_FILL,
  PALETTE_ALT_UP_STROKE,
  PALETTE_DOWN_FILL,
  PALETTE_DOWN_STROKE,
  PALETTE_NEUTRAL_FILL,
  PALETTE_NEUTRAL_STROKE,
  PALETTE_UP_FILL,
  PALETTE_UP_STROKE
};
var themeNames = Object.keys(themes);
function resolveOperation(operation) {
  const params = ChartTheme.getDefaultPublicParameters();
  const palette = ChartTheme.getDefaultColors();
  const graph = new OptionsGraph({ line: { operation } }, { series: [{ type: "line" }] }, params, palette);
  const resolved = graph.resolve();
  return resolved.operation;
}

// packages/ag-charts-community/src/integrated-charts-util.ts
var integrated_charts_util_exports = {};
__export(integrated_charts_util_exports, {
  Color: () => Color,
  interpolateColor: () => interpolateColor
});

// packages/ag-charts-community/src/module-bundles/integrated.ts
var AgChartsCommunityModule = {
  VERSION,
  _Scene: integrated_charts_scene_exports,
  _Theme: integrated_charts_theme_exports,
  _Util: integrated_charts_util_exports,
  create: AgCharts.create.bind(AgCharts),
  createSparkline: AgCharts.__createSparkline.bind(AgCharts),
  setup: () => {
    moduleRegistry_exports.setRegistryMode(moduleRegistry_exports.RegistryMode.Integrated);
    moduleRegistry_exports.registerModules(AllCommunityModule);
  },
  isEnterprise: false
};

// packages/ag-charts-enterprise/src/charts/standaloneChart.ts
var { Chart: Chart2 } = module_support_exports;
var StandaloneChart = class extends Chart2 {
  getChartType() {
    return "standalone";
  }
  performLayout(ctx) {
    const { seriesRoot, annotationRoot } = this;
    const seriesRect = ctx.layoutBox.clone().shrink(this.seriesArea.getPadding());
    this.seriesRect = seriesRect;
    this.animationRect = seriesRect;
    for (const group of [seriesRoot, annotationRoot]) {
      group.translationX = Math.floor(seriesRect.x);
      group.translationY = Math.floor(seriesRect.y);
    }
    seriesRoot.visible = this.series[0].visible;
    this.ctx.layoutManager.emitLayoutComplete(ctx, {
      series: { visible: true, rect: seriesRect, paddedRect: ctx.layoutBox }
    });
  }
  getAriaLabel() {
    const seriesType = this.series[0]?.type;
    if (seriesType == null)
      return "";
    const caption = this.getCaptionText();
    switch (seriesType) {
      case "radial-gauge":
      case "linear-gauge": {
        const captions = [];
        if (caption.length !== 0) {
          captions.push(caption);
        }
        for (const series of this.series) {
          captions.push(series.getCaptionText());
        }
        return this.ctx.localeManager.t("ariaAnnounceGaugeChart", { caption: captions.join(". ") });
      }
      case "treemap":
      case "sunburst":
        return this.ctx.localeManager.t("ariaAnnounceHierarchyChart", { caption });
      default: {
        return this.ctx.localeManager.t("ariaAnnounceStandaloneChart", { caption });
      }
    }
  }
};
StandaloneChart.className = "StandaloneChart";
StandaloneChart.type = "standalone";

// packages/ag-charts-enterprise/src/charts/standaloneChartModule.ts
var { standaloneChartOptionsDefs: standaloneChartOptionsDefs2 } = module_support_exports;
var StandaloneChartModule = {
  type: "chart",
  name: "standalone",
  enterprise: true,
  version: VERSION,
  options: standaloneChartOptionsDefs2,
  create(options, resources) {
    return new StandaloneChart(options, resources);
  }
};

// packages/ag-charts-enterprise/src/series/flow-proportion/flowProportionUtil.ts
function computeNodeGraph(nodes, links, includeCircularReferences) {
  if (!includeCircularReferences) {
    links = removeCircularLinks(links);
  }
  const nodeGraph = /* @__PURE__ */ new Map();
  for (const datum of nodes) {
    const itemId = datum.datumIndex.type === 0 /* Link */ ? `link-${datum.datumIndex.index}` : `node-${datum.datumIndex.index}`;
    nodeGraph.set(datum.id, {
      itemId,
      datum,
      linksBefore: [],
      linksAfter: [],
      maxPathLengthBefore: -1,
      maxPathLengthAfter: -1
    });
  }
  let maxPathLength = 0;
  for (const [id, node] of nodeGraph.entries()) {
    maxPathLength = Math.max(
      maxPathLength,
      computePathLength(nodeGraph, links, node, id, -1, []) + computePathLength(nodeGraph, links, node, id, 1, []) + 1
    );
  }
  return { links, nodeGraph, maxPathLength };
}
function findCircularLinks(links, link, into, stack) {
  const stackIndex = stack.indexOf(link);
  if (stackIndex !== -1) {
    for (let i = stackIndex; i < stack.length; i += 1) {
      into.add(stack[i]);
    }
    return;
  }
  stack.push(link);
  const { toNode } = link;
  for (const next of links) {
    if (next.fromNode === toNode) {
      findCircularLinks(links, next, into, stack);
    }
  }
  stack.pop();
}
function removeCircularLinks(links) {
  const circularLinks = /* @__PURE__ */ new Set();
  for (const link of links) {
    findCircularLinks(links, link, circularLinks, []);
  }
  if (circularLinks.size !== 0) {
    logger_exports.warnOnce("Some links formed circular references. These will be removed from the output.");
  }
  return circularLinks.size === 0 ? links : links.filter((link) => !circularLinks.has(link));
}
function computePathLength(nodeGraph, links, node, id, direction, stack) {
  if (stack.includes(id)) {
    return Infinity;
  }
  let maxPathLength = direction === -1 ? node.maxPathLengthBefore : node.maxPathLengthAfter;
  if (maxPathLength === -1) {
    maxPathLength = 0;
    const connectedLinks = direction === -1 ? node.linksBefore : node.linksAfter;
    for (const link of links) {
      const { fromNode, toNode } = link;
      const linkId = direction === -1 ? toNode.id : fromNode.id;
      const nextNodeId = direction === -1 ? fromNode.id : toNode.id;
      const nextNode = id === linkId ? nodeGraph.get(nextNodeId) : void 0;
      if (nextNode == null)
        continue;
      connectedLinks.push({ node: nextNode, link });
      stack?.push(id);
      maxPathLength = Math.max(
        maxPathLength,
        computePathLength(nodeGraph, links, nextNode, nextNodeId, direction, stack) + 1
      );
      stack?.pop();
    }
    if (direction === -1) {
      node.maxPathLengthBefore = maxPathLength;
    } else {
      node.maxPathLengthAfter = maxPathLength;
    }
  }
  return maxPathLength;
}

// packages/ag-charts-enterprise/src/series/flow-proportion/flowProportionSeries.ts
var {
  findNodeDatumInArray: findNodeDatumInArray2,
  keyProperty: keyProperty2,
  valueProperty: valueProperty2,
  DataController: DataController2,
  Group: Group4,
  HighlightState: HighlightState3,
  Selection: Selection2,
  Series: Series3,
  TransformableText: TransformableText2
} = module_support_exports;
var FlowProportionSeriesNodeEvent = class extends module_support_exports.SeriesNodeEvent {
  constructor(type, nativeEvent, datum, series) {
    super(type, nativeEvent, datum, series);
    const { datumIndex } = datum;
    const nodeDatum = series.contextNodeData?.nodeData.find(
      (d) => d.datumIndex.type === datumIndex.type && d.datumIndex.index === datumIndex.index
    );
    this.size = nodeDatum?.size;
    this.label = nodeDatum?.type === 1 /* Node */ ? nodeDatum?.label : void 0;
  }
};
var FlowProportionSeries = class extends Series3 {
  constructor() {
    super(...arguments);
    this.NodeEvent = FlowProportionSeriesNodeEvent;
    this.nodeCount = 0;
    this.linkCount = 0;
    this.linksDataModel = void 0;
    this.linksProcessedData = void 0;
    this.nodesDataModel = void 0;
    this.nodesProcessedData = void 0;
    this.processedNodes = /* @__PURE__ */ new Map();
    this.linkGroup = this.contentGroup.appendChild(new Group4({ name: "linkGroup" }));
    this.nodeGroup = this.contentGroup.appendChild(new Group4({ name: "nodeGroup" }));
    this.focusLinkGroup = this.highlightGroup.appendChild(new Group4({ name: "linkGroup" }));
    this.focusNodeGroup = this.highlightGroup.appendChild(new Group4({ name: "nodeGroup" }));
    this.highlightLinkGroup = this.highlightGroup.appendChild(new Group4({ name: "linkGroup" }));
    this.labelSelection = Selection2.select(
      this.labelGroup,
      TransformableText2
    );
    this.linkSelection = Selection2.select(
      this.linkGroup,
      () => this.linkFactory()
    );
    this.nodeSelection = Selection2.select(
      this.nodeGroup,
      () => this.nodeFactory()
    );
    this.focusLinkSelection = Selection2.select(
      this.focusLinkGroup,
      () => this.linkFactory()
    );
    this.focusNodeSelection = Selection2.select(
      this.focusNodeGroup,
      () => this.nodeFactory()
    );
    this.highlightLinkSelection = Selection2.select(
      this.highlightLinkGroup,
      () => this.linkFactory()
    );
    this.highlightNodeSelection = Selection2.select(
      this.highlightNodeGroup,
      () => this.nodeFactory()
    );
  }
  get nodes() {
    return this.properties.nodes;
  }
  async processData(dataController) {
    const { data, nodes } = this;
    if (data == null)
      return;
    const { fromKey, toKey, sizeKey, idKey, labelKey } = this.properties;
    const nodesDataController = new DataController2(
      "standalone",
      dataController.suppressFieldDotNotation,
      this.ctx.eventsHub
    );
    const nodesDataModelPromise = nodes == null ? null : nodesDataController.request(
      this.id,
      module_support_exports.DataSet.wrap(nodes) ?? module_support_exports.DataSet.empty(),
      {
        props: [
          keyProperty2(idKey, void 0, { id: "idValue", includeProperty: false }),
          ...labelKey == null ? [] : [valueProperty2(labelKey, void 0, { id: "labelValue", includeProperty: false })]
        ],
        groupByKeys: true
      }
    );
    const linksDataModelPromise = dataController.request(this.id, data, {
      props: [
        valueProperty2(fromKey, void 0, { id: "fromValue", includeProperty: false }),
        valueProperty2(toKey, void 0, { id: "toValue", includeProperty: false }),
        ...sizeKey == null ? [] : [
          valueProperty2(sizeKey, void 0, {
            id: "sizeValue",
            includeProperty: false,
            missingValue: 0
          })
        ]
      ],
      groupByKeys: false
    });
    if (nodes != null) {
      nodesDataController.execute();
    }
    const [nodesDataModel, linksDataModel] = await Promise.all([
      nodesDataModelPromise ?? Promise.resolve(null),
      linksDataModelPromise
    ]);
    this.nodesDataModel = nodesDataModel?.dataModel;
    this.nodesProcessedData = nodesDataModel?.processedData;
    this.linksDataModel = linksDataModel?.dataModel;
    this.linksProcessedData = linksDataModel?.processedData;
    const processedNodes = /* @__PURE__ */ new Map();
    if (nodesDataModel == null) {
      const fromIdValues = linksDataModel.dataModel.resolveColumnById(
        this,
        "fromValue",
        linksDataModel.processedData
      );
      const toIdValues = linksDataModel.dataModel.resolveColumnById(
        this,
        "toValue",
        linksDataModel.processedData
      );
      const createImplicitNode = (id) => {
        const datumIndex = processedNodes.size;
        const label = id;
        return {
          series: this,
          itemId: `node-${datumIndex}`,
          datum: {},
          // Must be a referential object for tooltips
          datumIndex: { type: 1 /* Node */, index: datumIndex },
          type: 1 /* Node */,
          index: datumIndex,
          linksBefore: [],
          linksAfter: [],
          id,
          size: 0,
          label,
          style: this.getNodeStyle(
            {
              datumIndex: { type: 1 /* Node */, index: datumIndex },
              datum: {},
              size: 0,
              label
            },
            datumIndex,
            false
          )
        };
      };
      const linkData = linksDataModel.processedData.dataSources.get(this.id)?.data;
      if (linkData) {
        for (const [datumIndex] of linkData.entries()) {
          const fromId = fromIdValues[datumIndex];
          const toId = toIdValues[datumIndex];
          if (fromId == null || toId == null)
            continue;
          if (!processedNodes.has(fromId)) {
            processedNodes.set(fromId, createImplicitNode(fromId));
          }
          if (!processedNodes.has(toId)) {
            processedNodes.set(toId, createImplicitNode(toId));
          }
        }
      }
    } else {
      const nodeIdValues = nodesDataModel.dataModel.resolveColumnById(
        this,
        "idValue",
        nodesDataModel.processedData
      );
      const labelValues = labelKey == null ? void 0 : nodesDataModel.dataModel.resolveColumnById(
        this,
        "labelValue",
        nodesDataModel.processedData
      );
      const nodeData = nodesDataModel.processedData.dataSources.get(this.id)?.data;
      if (nodeData) {
        for (const [datumIndex, datum] of nodeData.entries()) {
          const id = nodeIdValues[datumIndex];
          const label = labelValues?.[datumIndex];
          const nodeDatumIndex = { type: 1 /* Node */, index: datumIndex };
          processedNodes.set(id, {
            series: this,
            itemId: `node-${datumIndex}`,
            datum,
            datumIndex: nodeDatumIndex,
            type: 1 /* Node */,
            index: datumIndex,
            linksBefore: [],
            linksAfter: [],
            id,
            size: 0,
            label,
            style: this.getNodeStyle(
              { datumIndex: nodeDatumIndex, datum, size: 0, label },
              datumIndex,
              false
            )
          });
        }
      }
    }
    this.processedNodes = processedNodes;
  }
  findNodeDatum(itemId) {
    return findNodeDatumInArray2(itemId, this.contextNodeData?.nodeData);
  }
  getNodeGraph(createNode, createLink, { includeCircularReferences }) {
    const { linksDataModel, linksProcessedData } = this;
    if (linksDataModel == null || linksProcessedData == null) {
      const { links: links2, nodeGraph: nodeGraph2, maxPathLength: maxPathLength2 } = computeNodeGraph(
        (/* @__PURE__ */ new Map()).values(),
        [],
        includeCircularReferences
      );
      this.nodeCount = 0;
      this.linkCount = 0;
      return { nodeGraph: nodeGraph2, links: links2, maxPathLength: maxPathLength2 };
    }
    const { sizeKey } = this.properties;
    const fromIdValues = linksDataModel.resolveColumnById(this, "fromValue", linksProcessedData);
    const toIdValues = linksDataModel.resolveColumnById(this, "toValue", linksProcessedData);
    const sizeValues = sizeKey == null ? void 0 : linksDataModel.resolveColumnById(this, "sizeValue", linksProcessedData);
    const nodesById = /* @__PURE__ */ new Map();
    for (const datum of this.processedNodes.values()) {
      const node = createNode(datum);
      nodesById.set(datum.id, node);
    }
    const baseLinks = [];
    const linkData = linksProcessedData.dataSources.get(this.id)?.data;
    if (linkData) {
      for (const [datumIndex, datum] of linkData.entries()) {
        const fromId = fromIdValues[datumIndex];
        const toId = toIdValues[datumIndex];
        const size = sizeValues == null ? 1 : sizeValues[datumIndex];
        const fromNode = nodesById.get(fromId);
        const toNode = nodesById.get(toId);
        if (size <= 0 || fromNode == null || toNode == null)
          continue;
        const linkNodeDatumIndex = { type: 0 /* Link */, index: datumIndex };
        const link = createLink({
          series: this,
          itemId: `link-${datumIndex}`,
          datum,
          datumIndex: linkNodeDatumIndex,
          type: 0 /* Link */,
          index: datumIndex,
          fromNode,
          toNode,
          size,
          style: this.getLinkStyle(
            { datum, datumIndex: linkNodeDatumIndex },
            fromNode.datumIndex,
            false
          )
        });
        baseLinks.push(link);
      }
    }
    const { links, nodeGraph, maxPathLength } = computeNodeGraph(
      nodesById.values(),
      baseLinks,
      includeCircularReferences
    );
    for (const node of nodeGraph.values()) {
      node.datum.linksBefore = node.linksBefore.map((linkedNode) => linkedNode.link);
      node.datum.linksAfter = node.linksAfter.map((linkedNode) => linkedNode.link);
    }
    this.nodeCount = nodeGraph.size;
    this.linkCount = links.length;
    return { nodeGraph, links, maxPathLength };
  }
  updateSelections() {
    if (this.nodeDataRefresh) {
      this.contextNodeData = this.createNodeData();
      this.nodeDataRefresh = false;
    }
  }
  update(opts) {
    const { seriesRect } = opts;
    const newNodeDataDependencies = {
      seriesRectWidth: seriesRect?.width ?? 0,
      seriesRectHeight: seriesRect?.height ?? 0
    };
    if (this._nodeDataDependencies == null || this._nodeDataDependencies.seriesRectWidth !== newNodeDataDependencies.seriesRectWidth || this._nodeDataDependencies.seriesRectHeight !== newNodeDataDependencies.seriesRectHeight) {
      this._nodeDataDependencies = newNodeDataDependencies;
    }
    this.updateSelections();
    const nodeData = this.contextNodeData?.nodeData ?? [];
    const labelData = this.contextNodeData?.labelData ?? [];
    const highlightedDatum = this.getHighlightedDatum();
    this.contentGroup.visible = this.visible;
    const highlightState = highlightedDatum == null ? HighlightState3.None : HighlightState3.OtherItem;
    this.contentGroup.opacity = this.properties.highlight.getStyle(highlightState).opacity ?? 1;
    this.labelSelection = this.updateLabelSelection({ labelData, labelSelection: this.labelSelection });
    this.updateLabelNodes({ labelSelection: this.labelSelection });
    this.linkSelection = this.updateLinkSelection({
      nodeData: nodeData.filter((d) => d.type === 0 /* Link */),
      datumSelection: this.linkSelection
    });
    this.updateLinkNodes({ datumSelection: this.linkSelection, isHighlight: false });
    this.nodeSelection = this.updateNodeSelection({
      nodeData: nodeData.filter((d) => d.type === 1 /* Node */),
      datumSelection: this.nodeSelection
    });
    this.updateNodeNodes({ datumSelection: this.nodeSelection, isHighlight: false });
    let focusLinkSelection;
    let focusNodeSelection;
    let highlightLinkSelection;
    let highlightNodeSelection;
    if (highlightedDatum?.type === 1 /* Node */) {
      focusLinkSelection = nodeData.filter((node) => {
        return node.type === 0 /* Link */ && (node.toNode === highlightedDatum || node.fromNode === highlightedDatum);
      });
      focusNodeSelection = focusLinkSelection.map((link) => {
        return link.fromNode === highlightedDatum ? link.toNode : link.fromNode;
      });
      focusNodeSelection.push(highlightedDatum);
      highlightLinkSelection = [];
      highlightNodeSelection = [highlightedDatum];
    } else if (highlightedDatum?.type === 0 /* Link */) {
      focusLinkSelection = [highlightedDatum];
      focusNodeSelection = [highlightedDatum.fromNode, highlightedDatum.toNode];
      highlightLinkSelection = [highlightedDatum];
      highlightNodeSelection = [];
    } else {
      focusLinkSelection = [];
      focusNodeSelection = [];
      highlightLinkSelection = [];
      highlightNodeSelection = [];
    }
    this.focusLinkSelection = this.updateLinkSelection({
      nodeData: focusLinkSelection,
      datumSelection: this.focusLinkSelection
    });
    this.updateLinkNodes({ datumSelection: this.focusLinkSelection, isHighlight: false });
    this.focusNodeSelection = this.updateNodeSelection({
      nodeData: focusNodeSelection,
      datumSelection: this.focusNodeSelection
    });
    this.updateNodeNodes({ datumSelection: this.focusNodeSelection, isHighlight: false });
    this.highlightLinkSelection = this.updateLinkSelection({
      nodeData: highlightLinkSelection,
      datumSelection: this.highlightLinkSelection
    });
    this.updateLinkNodes({ datumSelection: this.highlightLinkSelection, isHighlight: true });
    this.highlightNodeSelection = this.updateNodeSelection({
      nodeData: highlightNodeSelection,
      datumSelection: this.highlightNodeSelection
    });
    this.updateNodeNodes({ datumSelection: this.highlightNodeSelection, isHighlight: true });
  }
  getHighlightedDatum() {
    let highlightedDatum = this.ctx.highlightManager?.getActiveHighlight();
    if (highlightedDatum?.series === this && highlightedDatum.type == null) {
      const { itemId } = highlightedDatum;
      const nodeData = this.contextNodeData?.nodeData ?? [];
      highlightedDatum = itemId == null ? void 0 : nodeData.find((node) => node.type === 1 /* Node */ && node.id === itemId);
    } else if (highlightedDatum?.series !== this) {
      highlightedDatum = void 0;
    }
    return highlightedDatum;
  }
  isLabelHighlighted(datum, activeHighlight) {
    if (activeHighlight == null)
      return false;
    if (activeHighlight.type === 1 /* Node */) {
      return activeHighlight === datum;
    }
    if (activeHighlight.type === 0 /* Link */) {
      return activeHighlight.fromNode === datum || activeHighlight.toNode === datum;
    }
    return false;
  }
  resetAnimation(_chartAnimationPhase) {
  }
  dataCount() {
    return Number.NaN;
  }
  getSeriesDomain(_direction) {
    return { domain: [] };
  }
  getSeriesRange(_direction, _visibleRange) {
    return [Number.NaN, Number.NaN];
  }
  legendItemSymbol(_type, nodeIndex, format = {}) {
    const { fills, strokes } = this.properties;
    const {
      fill = fills[nodeIndex % fills.length],
      fillOpacity = 1,
      stroke: stroke3 = strokes[nodeIndex % strokes.length],
      strokeWidth = 0,
      strokeOpacity = 1,
      lineDash = [0],
      lineDashOffset = 0
    } = format;
    return {
      marker: {
        fill,
        fillOpacity,
        stroke: stroke3,
        strokeWidth,
        strokeOpacity,
        lineDash,
        lineDashOffset
      }
    };
  }
  getLegendData(legendType) {
    if (legendType !== "category")
      return [];
    const { showInLegend } = this.properties;
    return Array.from(
      this.processedNodes.values(),
      ({ id, label }, nodeIndex) => ({
        legendType: "category",
        id: this.id,
        itemId: id,
        seriesId: this.id,
        enabled: true,
        label: { text: label ?? id },
        symbol: this.legendItemSymbol(1 /* Node */, nodeIndex),
        hideInLegend: !showInLegend,
        isFixed: true
      })
    );
  }
  pickNodeClosestDatum({ x, y }) {
    let minDistanceSquared = Infinity;
    let minDatum;
    this.linkSelection.each((node, datum) => {
      const distanceSquared2 = node.distanceSquared(x, y);
      if (distanceSquared2 < minDistanceSquared) {
        minDistanceSquared = distanceSquared2;
        minDatum = datum;
      }
    });
    this.nodeSelection.each((node, datum) => {
      const distanceSquared2 = node.distanceSquared(x, y);
      if (distanceSquared2 < minDistanceSquared) {
        minDistanceSquared = distanceSquared2;
        minDatum = datum;
      }
    });
    return minDatum == null ? void 0 : { datum: minDatum, distance: Math.sqrt(minDistanceSquared) };
  }
  getDatumAriaText(datum, description) {
    if (datum.type === 0 /* Link */) {
      return this.ctx.localeManager.t("ariaAnnounceFlowProportionLink", {
        index: datum.index + 1,
        count: this.linkCount,
        from: datum.fromNode.id,
        to: datum.toNode.id,
        size: datum.size,
        sizeName: this.properties.sizeName ?? this.properties.sizeKey
      });
    } else if (datum.type === 1 /* Node */) {
      return this.ctx.localeManager.t("ariaAnnounceFlowProportionNode", {
        index: datum.index + 1,
        count: this.nodeCount,
        description
      });
    }
  }
  pickFocus(opts) {
    const { datumIndexDelta: childDelta, otherIndexDelta: depthDelta } = opts;
    const currentNodeDatum = this.contextNodeData?.nodeData[opts.datumIndex - opts.datumIndexDelta];
    let nextNodeDatum = currentNodeDatum;
    if (depthDelta !== 0 || childDelta === 0)
      return;
    if (currentNodeDatum?.type === 0 /* Link */) {
      const allLinks = Array.from(this.linkSelection, (link) => link.datum);
      const selfIndex = allLinks.indexOf(currentNodeDatum);
      const nextIndex = selfIndex + childDelta;
      if (nextIndex >= 0 && nextIndex < allLinks.length) {
        nextNodeDatum = allLinks[nextIndex];
      } else if (nextIndex > 0) {
        nextNodeDatum = allLinks.at(-1);
      } else {
        const allNodes = Array.from(this.nodeSelection, (node) => node.datum);
        nextNodeDatum = allNodes.at(-1);
      }
    } else if (currentNodeDatum?.type === 1 /* Node */) {
      const allNodes = Array.from(this.nodeSelection, (node) => node.datum);
      const selfIndex = allNodes.indexOf(currentNodeDatum);
      const nextIndex = selfIndex + childDelta;
      if (nextIndex >= 0 && nextIndex < allNodes.length) {
        nextNodeDatum = allNodes[nextIndex];
      } else if (nextIndex < 0) {
        nextNodeDatum = allNodes[0];
      } else {
        const allLinks = Array.from(this.linkSelection, (link) => link.datum);
        nextNodeDatum = allLinks[0];
      }
    }
    if (nextNodeDatum == null)
      return;
    const nodeDatum = nextNodeDatum.type === 1 /* Node */ ? Array.from(this.nodeSelection).find((n) => n.datum === nextNodeDatum) : Array.from(this.linkSelection).find((n) => n.datum === nextNodeDatum);
    if (nodeDatum == null)
      return;
    const bounds = this.computeFocusBounds(nodeDatum.node);
    if (bounds == null)
      return;
    return {
      datum: nodeDatum.datum,
      datumIndex: this.contextNodeData?.nodeData.indexOf(nodeDatum.datum) ?? 0,
      otherIndex: 0,
      bounds,
      clipFocusBox: true
    };
  }
  getCategoryValue(_datumIndex) {
    return;
  }
  datumIndexForCategoryValue(_categoryValue) {
    return;
  }
};

// packages/ag-charts-enterprise/src/series/chord/chordLink.ts
var { Path: Path2 } = module_support_exports;
function bezierControlPoints({
  radius,
  startAngle,
  endAngle,
  tension
}) {
  const cp0x = radius * Math.cos(startAngle);
  const cp0y = radius * Math.sin(startAngle);
  const cp3x = radius * Math.cos(endAngle);
  const cp3y = radius * Math.sin(endAngle);
  const cp1x = cp0x * tension;
  const cp1y = cp0y * tension;
  const cp2x = cp3x * tension;
  const cp2y = cp3y * tension;
  return {
    x: [cp0x, cp1x, cp2x, cp3x],
    y: [cp0y, cp1y, cp2y, cp3y]
  };
}
var ChordLink = class extends Path2 {
  constructor() {
    super(...arguments);
    this.centerX = 0;
    this.centerY = 0;
    this.radius = 0;
    this.startAngle1 = 0;
    this.endAngle1 = 0;
    this.startAngle2 = 0;
    this.endAngle2 = 0;
    this.tension = 1;
  }
  tensionedCurveTo(cp0x, cp0y, cp1x, cp1y, cp2x, cp2y, cp3x, cp3y) {
    const { path, tension } = this;
    const scale2 = 1 - tension;
    path.cubicCurveTo(
      (cp1x - cp0x) * scale2 + cp0x,
      (cp1y - cp0y) * scale2 + cp0y,
      (cp2x - cp3x) * scale2 + cp3x,
      (cp2y - cp3y) * scale2 + cp3y,
      cp3x,
      cp3y
    );
  }
  updatePath() {
    const { path, centerX, centerY, radius } = this;
    let { startAngle1, endAngle1, startAngle2, endAngle2 } = this;
    if (startAngle1 > startAngle2) {
      [startAngle1, startAngle2] = [startAngle2, startAngle1];
      [endAngle1, endAngle2] = [endAngle2, endAngle1];
    }
    path.clear();
    const startX = centerX + radius * Math.cos(startAngle1);
    const startY = centerY + radius * Math.sin(startAngle1);
    path.moveTo(startX, startY);
    this.tensionedCurveTo(
      startX,
      startY,
      centerX,
      centerY,
      centerX,
      centerY,
      centerX + radius * Math.cos(endAngle2),
      centerY + radius * Math.sin(endAngle2)
    );
    path.arc(centerX, centerY, radius, endAngle2, startAngle2, true);
    this.tensionedCurveTo(
      centerX + radius * Math.cos(startAngle2),
      centerY + radius * Math.sin(startAngle2),
      centerX,
      centerY,
      centerX,
      centerY,
      centerX + radius * Math.cos(endAngle1),
      centerY + radius * Math.sin(endAngle1)
    );
    path.arc(centerX, centerY, radius, endAngle1, startAngle1, true);
    path.closePath();
  }
};
__decorateClass([
  SceneChangeDetection()
], ChordLink.prototype, "centerX", 2);
__decorateClass([
  SceneChangeDetection()
], ChordLink.prototype, "centerY", 2);
__decorateClass([
  SceneChangeDetection()
], ChordLink.prototype, "radius", 2);
__decorateClass([
  SceneChangeDetection()
], ChordLink.prototype, "startAngle1", 2);
__decorateClass([
  SceneChangeDetection()
], ChordLink.prototype, "endAngle1", 2);
__decorateClass([
  SceneChangeDetection()
], ChordLink.prototype, "startAngle2", 2);
__decorateClass([
  SceneChangeDetection()
], ChordLink.prototype, "endAngle2", 2);
__decorateClass([
  SceneChangeDetection()
], ChordLink.prototype, "tension", 2);

// packages/ag-charts-enterprise/src/series/chord/chordSeriesProperties.ts
var { FillGradientDefaults: FillGradientDefaults2, FillPatternDefaults: FillPatternDefaults2, FillImageDefaults: FillImageDefaults2, makeSeriesTooltip: makeSeriesTooltip2, SeriesProperties: SeriesProperties2, Label: Label3 } = module_support_exports;
var ChordSeriesLabelProperties = class extends Label3 {
  constructor() {
    super(...arguments);
    this.spacing = 1;
    this.maxWidth = 1;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesLabelProperties.prototype, "spacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesLabelProperties.prototype, "maxWidth", 2);
var ChordSeriesLinkProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.fill = void 0;
    this.fillOpacity = 1;
    this.stroke = void 0;
    this.strokeOpacity = 1;
    this.strokeWidth = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.tension = 0;
  }
  getStyle(fills, strokes, index) {
    const { fillOpacity, strokeWidth, strokeOpacity, lineDash, lineDashOffset, tension } = this;
    const fill = this.fill ?? fills[index % fills.length];
    const stroke3 = this.stroke ?? strokes[index % fills.length];
    return {
      fill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset,
      tension
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesLinkProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesLinkProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesLinkProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesLinkProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesLinkProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesLinkProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesLinkProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesLinkProperties.prototype, "tension", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesLinkProperties.prototype, "itemStyler", 2);
var ChordSeriesNodeProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.spacing = 1;
    this.width = 1;
    this.fill = void 0;
    this.fillOpacity = 1;
    this.stroke = void 0;
    this.strokeOpacity = 1;
    this.strokeWidth = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
  }
  getStyle(fills, strokes, index) {
    const { fillOpacity, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this;
    const fill = this.fill ?? fills[index % fills.length];
    const stroke3 = this.stroke ?? strokes[index % fills.length];
    return {
      fill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesNodeProperties.prototype, "spacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesNodeProperties.prototype, "width", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesNodeProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesNodeProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesNodeProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesNodeProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesNodeProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesNodeProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesNodeProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesNodeProperties.prototype, "itemStyler", 2);
var ChordSeriesProperties = class extends SeriesProperties2 {
  constructor() {
    super(...arguments);
    this.idKey = "";
    this.idName = void 0;
    this.labelKey = void 0;
    this.labelName = void 0;
    this.sizeKey = void 0;
    this.sizeName = void 0;
    this.nodes = void 0;
    this.fillGradientDefaults = new FillGradientDefaults2();
    this.fillPatternDefaults = new FillPatternDefaults2();
    this.fillImageDefaults = new FillImageDefaults2();
    this.fills = [];
    this.strokes = [];
    this.label = new ChordSeriesLabelProperties();
    this.link = new ChordSeriesLinkProperties();
    this.node = new ChordSeriesNodeProperties();
    this.tooltip = makeSeriesTooltip2();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesProperties.prototype, "fromKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesProperties.prototype, "toKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesProperties.prototype, "idKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesProperties.prototype, "idName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesProperties.prototype, "labelKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesProperties.prototype, "labelName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesProperties.prototype, "sizeKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesProperties.prototype, "sizeName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesProperties.prototype, "nodes", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesProperties.prototype, "fillGradientDefaults", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesProperties.prototype, "fillPatternDefaults", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesProperties.prototype, "fillImageDefaults", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesProperties.prototype, "fills", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesProperties.prototype, "strokes", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesProperties.prototype, "link", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesProperties.prototype, "node", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChordSeriesProperties.prototype, "tooltip", 2);

// packages/ag-charts-enterprise/src/series/chord/chordSeries.ts
var { SeriesNodePickMode: SeriesNodePickMode2, createDatumId: createDatumId2, Sector: Sector2, getShapeStyle: getShapeStyle2, getLabelStyles: getLabelStyles2, BBox: BBox2 } = module_support_exports;
var nodeMidAngle = (node) => node.startAngle + angleBetween(node.startAngle, node.endAngle) / 2;
var ChordSeries = class extends FlowProportionSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      pickModes: [SeriesNodePickMode2.NEAREST_NODE, SeriesNodePickMode2.EXACT_SHAPE_MATCH]
    });
    this.properties = new ChordSeriesProperties();
  }
  isLabelEnabled() {
    return (this.properties.labelKey != null || this.nodes == null) && this.properties.label.enabled;
  }
  linkFactory() {
    return new ChordLink();
  }
  nodeFactory() {
    return new Sector2();
  }
  createNodeData() {
    const {
      id: seriesId,
      _nodeDataDependencies: { seriesRectWidth, seriesRectHeight } = { seriesRectWidth: 0, seriesRectHeight: 0 },
      properties
    } = this;
    const {
      fromKey,
      toKey,
      sizeKey,
      labelKey,
      label: { spacing: labelSpacing, maxWidth: labelMaxWidth, fontSize },
      node: { width: nodeWidth, spacing: nodeSpacing }
    } = properties;
    const centerX = seriesRectWidth / 2;
    const centerY = seriesRectHeight / 2;
    let labelData = [];
    const { nodeGraph, links } = this.getNodeGraph(
      (node) => ({
        ...node,
        centerX,
        centerY,
        innerRadius: Number.NaN,
        outerRadius: Number.NaN,
        startAngle: Number.NaN,
        endAngle: Number.NaN
      }),
      (link) => ({
        ...link,
        centerX,
        centerY,
        radius: Number.NaN,
        startAngle1: Number.NaN,
        endAngle1: Number.NaN,
        startAngle2: Number.NaN,
        endAngle2: Number.NaN
      }),
      { includeCircularReferences: true }
    );
    let totalSize = 0;
    for (const [id, { datum: node, linksBefore, linksAfter }] of nodeGraph.entries()) {
      const size = linksBefore.reduce((acc, { link }) => acc + link.size, 0) + linksAfter.reduce((acc, { link }) => acc + link.size, 0);
      if (size === 0) {
        nodeGraph.delete(id);
      } else {
        const { label } = properties;
        node.size = size;
        totalSize += node.size;
        const labelText = label.enabled ? this.getLabelText(
          node.label,
          node.datum,
          labelKey,
          "label",
          [],
          label,
          { datum: node.datum, value: node.label, fromKey, toKey, sizeKey, size: node.size }
        ) : void 0;
        node.label = toPlainText(labelText);
      }
    }
    let labelInset = 0;
    if (this.isLabelEnabled()) {
      const measurer3 = cachedTextMeasurer(this.properties.label);
      let maxMeasuredLabelWidth = 0;
      for (const { datum: node } of nodeGraph.values()) {
        const { id, label } = node;
        if (label == null)
          continue;
        const text2 = wrapText(label, {
          maxWidth: labelMaxWidth,
          font: this.properties.label,
          textWrap: "never"
        });
        const { width: width2 } = measurer3.measureLines(text2);
        maxMeasuredLabelWidth = Math.max(width2, maxMeasuredLabelWidth);
        labelData.push({
          id,
          text: text2,
          centerX,
          centerY,
          angle: Number.NaN,
          radius: Number.NaN,
          size: node.size,
          datumIndex: node.datumIndex,
          nodeDatum: node
        });
      }
      labelInset = maxMeasuredLabelWidth + labelSpacing;
    }
    const nodeCount = nodeGraph.size;
    let radius = Math.min(seriesRectWidth, seriesRectHeight) / 2 - nodeWidth - labelInset;
    let spacingSweep = nodeSpacing / radius;
    if (labelInset !== 0 && (nodeCount * spacingSweep >= 1.5 * Math.PI || radius <= 0)) {
      labelData = [];
      radius = Math.min(seriesRectWidth, seriesRectHeight) / 2 - nodeWidth;
      spacingSweep = nodeSpacing / radius;
    }
    if (nodeCount * spacingSweep >= 2 * Math.PI || radius <= 0) {
      logger_exports.warnOnce("There was insufficient space to display the Chord Series.");
      return;
    }
    const innerRadius = radius;
    const outerRadius = radius + nodeWidth;
    const sizeScale = Math.max((2 * Math.PI - nodeCount * spacingSweep) / totalSize, 0);
    let nodeAngle = 0;
    for (const { datum: node } of nodeGraph.values()) {
      node.innerRadius = innerRadius;
      node.outerRadius = outerRadius;
      node.startAngle = nodeAngle;
      node.endAngle = nodeAngle + node.size * sizeScale;
      nodeAngle = node.endAngle + spacingSweep;
      const midR = (node.innerRadius + node.outerRadius) / 2;
      const midAngle = nodeMidAngle(node);
      node.midPoint = {
        x: node.centerX + midR * Math.cos(midAngle),
        y: node.centerY + midR * Math.sin(midAngle)
      };
    }
    const nodeData = [];
    for (const { datum: node, linksBefore, linksAfter } of nodeGraph.values()) {
      const midAngle = nodeMidAngle(node);
      const combinedLinks = [
        ...linksBefore.map((l) => ({
          link: l.link,
          distance: angleBetween(nodeMidAngle(l.node.datum), midAngle),
          after: false
        })),
        ...linksAfter.map((l) => ({
          link: l.link,
          distance: angleBetween(nodeMidAngle(l.node.datum), midAngle),
          after: true
        }))
      ];
      let linkAngle = node.startAngle;
      for (const { link, after } of combinedLinks.toSorted((a, b) => a.distance - b.distance)) {
        const linkSweep = link.size * sizeScale;
        if (after) {
          link.startAngle1 = linkAngle;
          link.endAngle1 = linkAngle + linkSweep;
        } else {
          link.startAngle2 = linkAngle;
          link.endAngle2 = linkAngle + linkSweep;
        }
        linkAngle += link.size * sizeScale;
      }
      nodeData.push(node);
    }
    const { tension } = this.properties.link;
    for (const link of links) {
      link.radius = radius;
      const outer = bezierControlPoints({
        radius,
        startAngle: link.startAngle1,
        endAngle: link.endAngle2,
        tension
      });
      const inner = bezierControlPoints({
        radius,
        startAngle: link.startAngle2,
        endAngle: link.endAngle1,
        tension
      });
      const outerX = evaluateBezier(...outer.x, 0.5);
      const outerY = evaluateBezier(...outer.y, 0.5);
      const innerX = evaluateBezier(...inner.x, 0.5);
      const innerY = evaluateBezier(...inner.y, 0.5);
      link.midPoint = {
        x: link.centerX + (outerX + innerX) / 2,
        y: link.centerY + (outerY + innerY) / 2
      };
      nodeData.push(link);
    }
    for (const label of labelData) {
      const node = nodeGraph.get(label.id)?.datum;
      if (node == null)
        continue;
      label.radius = outerRadius + labelSpacing;
      label.angle = normalizeAngle360(node.startAngle + angleBetween(node.startAngle, node.endAngle) / 2);
      label.datumIndex = node.datumIndex;
      label.nodeDatum = node;
    }
    labelData.sort((a, b) => a.angle - b.angle);
    let minAngle = Infinity;
    let maxAngle = -Infinity;
    labelData = labelData.filter((label) => {
      const labelHeight = calcLineHeight(fontSize);
      const da = Math.atan2(labelHeight / 2, label.radius);
      const a0 = label.angle - da;
      const a1 = label.angle + da;
      if (isBetweenAngles(minAngle, a0, a1))
        return false;
      if (isBetweenAngles(maxAngle, a0, a1))
        return false;
      minAngle = Math.min(a0, minAngle);
      maxAngle = Math.max(a1, maxAngle);
      return true;
    });
    return {
      itemId: seriesId,
      nodeData,
      labelData
    };
  }
  updateLabelSelection(opts) {
    const labels = this.isLabelEnabled() ? opts.labelData : [];
    return opts.labelSelection.update(labels);
  }
  updateLabelNodes(opts) {
    const params = {
      toKey: this.properties.toKey,
      fromKey: this.properties.fromKey,
      sizeKey: this.properties.sizeKey,
      size: Number.NaN
    };
    const activeHighlightDatum = this.getHighlightedDatum();
    opts.labelSelection.each((label, labelNodeDatum) => {
      const { size, text: text2, centerX, centerY, radius, angle: angle2, datumIndex, nodeDatum } = labelNodeDatum;
      params.size = size;
      const isHighlight = this.isLabelHighlighted(nodeDatum, activeHighlightDatum);
      const highlightStyle = this.getHighlightStyle(isHighlight, datumIndex);
      const style2 = getLabelStyles2(
        this,
        void 0,
        params,
        this.properties.label,
        isHighlight,
        activeHighlightDatum
      );
      const { fontStyle, fontWeight: fontWeight2, fontSize, fontFamily, color: fill } = style2;
      label.visible = true;
      label.translationX = centerX + radius * Math.cos(angle2);
      label.translationY = centerY + radius * Math.sin(angle2);
      label.text = text2;
      label.fill = fill;
      label.fontStyle = fontStyle;
      label.fontWeight = fontWeight2;
      label.fontSize = fontSize;
      label.fontFamily = fontFamily;
      label.textBaseline = "middle";
      if (Math.cos(angle2) >= 0) {
        label.textAlign = "left";
        label.rotation = angle2;
      } else {
        label.textAlign = "right";
        label.rotation = angle2 - Math.PI;
      }
      const opacity = highlightStyle.opacity ?? 1;
      label.opacity = opacity;
      label.fillOpacity = opacity;
      label.setBoxing(style2);
    });
  }
  updateNodeSelection(opts) {
    return opts.datumSelection.update(opts.nodeData, void 0, (datum) => createDatumId2(datum.type, datum.id));
  }
  getNodeStyle(nodeDatum, fromNodeDatumIndex, isHighlight) {
    const { properties } = this;
    const { fills, strokes, fillGradientDefaults: fillGradientDefaults3, fillPatternDefaults: fillPatternDefaults3, fillImageDefaults: fillImageDefaults3 } = properties;
    const { itemStyler } = properties.node;
    const highlightStyle = this.getHighlightStyle(isHighlight, nodeDatum.datumIndex);
    const baseStyle = mergeDefaults(highlightStyle, properties.node.getStyle(fills, strokes, fromNodeDatumIndex));
    let style2 = getShapeStyle2(baseStyle, fillGradientDefaults3, fillPatternDefaults3, fillImageDefaults3);
    if (itemStyler != null && nodeDatum.datumIndex != null) {
      const overrides = this.cachedDatumCallback(
        createDatumId2(nodeDatum.datumIndex.index, "node", isHighlight ? "highlight" : "node"),
        () => {
          const params = this.makeItemStylerParams(nodeDatum, isHighlight, style2);
          return this.callWithContext(itemStyler, params);
        }
      );
      if (overrides) {
        style2 = getShapeStyle2(
          mergeDefaults(overrides, style2),
          fillGradientDefaults3,
          fillPatternDefaults3,
          fillImageDefaults3
        );
      }
    }
    style2.opacity = 1;
    return style2;
  }
  makeItemStylerParams({ datum, datumIndex, size = 0, label }, isHighlight, style2) {
    const { id: seriesId } = this;
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const highlightState = this.getHighlightStateString(activeHighlight, isHighlight, datumIndex);
    const fill = this.filterItemStylerFillParams(style2.fill) ?? style2.fill;
    return {
      seriesId,
      datum,
      highlightState,
      ...style2,
      size,
      label,
      fill
    };
  }
  updateNodeNodes(opts) {
    const { datumSelection, isHighlight } = opts;
    const fillBBox = this.getShapeFillBBox();
    datumSelection.each((sector, datum) => {
      const { datumIndex } = datum;
      const style2 = this.getNodeStyle(datum, datumIndex.index, isHighlight);
      sector.setStyleProperties(style2, fillBBox);
      sector.centerX = datum.centerX;
      sector.centerY = datum.centerY;
      sector.innerRadius = datum.innerRadius;
      sector.outerRadius = datum.outerRadius;
      sector.startAngle = datum.startAngle;
      sector.endAngle = datum.endAngle;
      sector.inset = sector.strokeWidth / 2;
    });
  }
  updateLinkSelection(opts) {
    return opts.datumSelection.update(
      opts.nodeData,
      void 0,
      (datum) => createDatumId2(datum.type, datum.index, datum.fromNode.id, datum.toNode.id)
    );
  }
  getLinkStyle({ datumIndex, datum }, fromNodeDatumIndex, isHighlight) {
    const { id: seriesId, properties } = this;
    const { fills, strokes, fillGradientDefaults: fillGradientDefaults3, fillPatternDefaults: fillPatternDefaults3, fillImageDefaults: fillImageDefaults3 } = properties;
    const { itemStyler } = properties.link;
    const highlightStyle = this.getHighlightStyle(isHighlight, datumIndex);
    const baseStyle = mergeDefaults(
      highlightStyle,
      properties.link.getStyle(fills, strokes, fromNodeDatumIndex.index)
    );
    let style2 = getShapeStyle2(baseStyle, fillGradientDefaults3, fillPatternDefaults3, fillImageDefaults3);
    if (itemStyler != null && datumIndex != null) {
      const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
      const overrides = this.cachedDatumCallback(
        createDatumId2(datumIndex.index, "link", isHighlight ? "highlight" : "node"),
        () => {
          const highlightState = this.getHighlightStateString(
            activeHighlight,
            isHighlight,
            fromNodeDatumIndex
          );
          return this.callWithContext(itemStyler, {
            seriesId,
            datum,
            highlightState,
            ...style2
          });
        }
      );
      if (overrides) {
        style2 = getShapeStyle2(
          mergeDefaults(overrides, style2),
          fillGradientDefaults3,
          fillPatternDefaults3,
          fillImageDefaults3
        );
      }
    }
    style2.opacity = 1;
    return style2;
  }
  updateLinkNodes(opts) {
    const { datumSelection, isHighlight } = opts;
    const fillBBox = this.getShapeFillBBox();
    datumSelection.each((link, datum) => {
      const fromNodeDatumIndex = datum.fromNode.datumIndex;
      const style2 = this.getLinkStyle(datum, fromNodeDatumIndex, isHighlight);
      link.centerX = datum.centerX;
      link.centerY = datum.centerY;
      link.radius = datum.radius;
      link.startAngle1 = datum.startAngle1;
      link.endAngle1 = datum.endAngle1;
      link.startAngle2 = datum.startAngle2;
      link.endAngle2 = datum.endAngle2;
      link.tension = style2.tension;
      link.setStyleProperties(style2, fillBBox);
    });
  }
  getShapeFillBBox() {
    const width2 = this._nodeDataDependencies?.seriesRectWidth ?? 0;
    const height2 = this._nodeDataDependencies?.seriesRectHeight ?? 0;
    const size = Math.min(width2, height2);
    const x = (width2 - size) / 2;
    const y = (height2 - size) / 2;
    const bbox = new BBox2(x, y, width2, height2);
    return { series: bbox, axis: bbox };
  }
  getTooltipContent(datumIndex) {
    const {
      id: seriesId,
      linksProcessedData,
      nodesProcessedData,
      properties,
      ctx: { formatManager }
    } = this;
    const { fromKey, toKey, sizeKey, sizeName, tooltip } = properties;
    const seriesDatum = this.contextNodeData?.nodeData.find(
      (d) => d.datumIndex.type === datumIndex.type && d.datumIndex.index === datumIndex.index
    );
    if (seriesDatum == null)
      return;
    const nodeIndex = seriesDatum.type === 0 /* Link */ ? seriesDatum.fromNode.index : seriesDatum.index;
    const title = seriesDatum.type === 0 /* Link */ ? `${seriesDatum.fromNode.label} - ${seriesDatum.toNode.label}` : seriesDatum.label;
    const datum = datumIndex.type === 0 /* Link */ ? linksProcessedData?.dataSources.get(this.id)?.data[datumIndex.index] : nodesProcessedData?.dataSources.get(this.id)?.data[datumIndex.index];
    const size = seriesDatum.size;
    let format;
    if (seriesDatum.type === 0 /* Link */) {
      const fromNodeDatumIndex = seriesDatum.fromNode.datumIndex;
      format = this.getLinkStyle({ datumIndex, datum }, fromNodeDatumIndex, false);
    } else {
      const label = seriesDatum.label;
      format = this.getNodeStyle({ datumIndex, datum, size, label }, datumIndex.index, false);
    }
    const data = [];
    if (sizeKey != null) {
      const content = formatManager.format(this.callWithContext.bind(this), {
        type: "number",
        value: size,
        datum,
        seriesId,
        legendItemName: void 0,
        key: sizeKey,
        source: "tooltip",
        property: "size",
        domain: [],
        boundSeries: this.getFormatterContext("size"),
        fractionDigits: void 0,
        visibleDomain: void 0
      });
      data.push({ label: sizeName, fallbackLabel: sizeKey, value: content ?? String(size) });
    }
    return this.formatTooltipWithContext(
      tooltip,
      {
        title,
        symbol: this.legendItemSymbol(seriesDatum.type, nodeIndex, format),
        data
      },
      {
        seriesId,
        datum,
        title,
        fromKey,
        toKey,
        sizeKey,
        sizeName,
        size,
        ...format
      }
    );
  }
  computeFocusBounds(node) {
    return node;
  }
  hasItemStylers() {
    return this.properties.node.itemStyler != null || this.properties.link.itemStyler != null || this.properties.label.itemStyler != null;
  }
};
ChordSeries.className = "ChordSeries";
ChordSeries.type = "chord";

// packages/ag-charts-enterprise/src/series/chord/chordSeriesOptionsDef.ts
var { chordSeriesThemeableOptionsDef: chordSeriesThemeableOptionsDef2 } = module_support_exports;
var chordSeriesOptionsDef = {
  ...chordSeriesThemeableOptionsDef2,
  ...commonSeriesOptionsDefs,
  type: required(constant("chord")),
  fromKey: required(string),
  toKey: required(string),
  sizeKey: string,
  sizeName: string
};
chordSeriesOptionsDef.fillGradientDefaults = undocumented(fillGradientDefaults);
chordSeriesOptionsDef.fillPatternDefaults = undocumented(fillPatternDefaults);
chordSeriesOptionsDef.fillImageDefaults = undocumented(fillImageDefaults);

// packages/ag-charts-enterprise/src/series/chord/chordModule.ts
var ChordSeriesModule = {
  type: "series",
  name: "chord",
  chartType: "standalone",
  enterprise: true,
  solo: true,
  version: VERSION,
  dependencies: [StandaloneChartModule],
  options: chordSeriesOptionsDef,
  themeTemplate: {
    series: {
      fills: { $palette: "fills" },
      strokes: { $palette: "strokes" },
      fillGradientDefaults: FILL_GRADIENT_LINEAR_DEFAULTS,
      fillPatternDefaults: FILL_PATTERN_DEFAULTS,
      fillImageDefaults: FILL_IMAGE_DEFAULTS,
      highlight: SINGLE_SERIES_HIGHLIGHT_STYLE,
      label: {
        ...LABEL_BOXING_DEFAULTS,
        enabled: true,
        fontFamily: { $ref: "fontFamily" },
        fontSize: { $ref: "fontSize" },
        fontWeight: { $ref: "fontWeight" },
        color: { $ref: "textColor" },
        spacing: 5,
        maxWidth: 100
      },
      node: {
        spacing: 8,
        width: 10,
        strokeWidth: { $isUserOption: ["./stroke", 2, 0] }
      },
      link: {
        fillOpacity: 0.5,
        strokeWidth: { $isUserOption: ["./stroke", 2, 0] },
        tension: 0.4
      }
    },
    legend: {
      enabled: false,
      toggleSeries: false
    }
  },
  create: (ctx) => new ChordSeries(ctx)
};

// packages/ag-charts-enterprise/src/series/funnel/funnelConnector.ts
var { BBox: BBox3, Path: Path3 } = module_support_exports;
var delta3 = 1e-6;
function pointsEq2([ax, ay], [bx, by]) {
  return Math.abs(ax - bx) <= delta3 && Math.abs(ay - by) <= delta3;
}
var FunnelConnector = class extends Path3 {
  constructor() {
    super(...arguments);
    this.x0 = 0;
    this.y0 = 0;
    this.x1 = 0;
    this.y1 = 0;
    this.x2 = 0;
    this.y2 = 0;
    this.x3 = 0;
    this.y3 = 0;
  }
  get midPoint() {
    const { x0, y0, x1, y1, x2, y2, x3, y3 } = this;
    return {
      x: (x0 + x1 + x2 + x3) / 4,
      y: (y0 + y1 + y2 + y3) / 4
    };
  }
  distanceSquared(x, y) {
    if (this.containsPoint(x, y))
      return 0;
    const { x0, y0, x1, y1, x2, y2, x3, y3 } = this;
    return Math.min(
      lineDistanceSquared(x, y, x0, y0, x1, y1, Infinity),
      lineDistanceSquared(x, y, x1, y1, x2, y2, Infinity),
      lineDistanceSquared(x, y, x2, y2, x3, y3, Infinity),
      lineDistanceSquared(x, y, x3, y3, x0, y0, Infinity)
    );
  }
  computeBBox() {
    const { x0, y0, x1, y1, x2, y2, x3, y3 } = this;
    const x = Math.min(x0, x1, x2, x3);
    const width2 = Math.max(x0, x1, x2, x3) - x;
    const y = Math.min(y0, y1, y2, y3);
    const height2 = Math.max(y0, y1, y2, y3) - y;
    return new BBox3(x, y, width2, height2);
  }
  updatePath() {
    const { path, x0, y0, x1, y1, x2, y2, x3, y3 } = this;
    const points = [
      [x0, y0],
      [x1, y1],
      [x2, y2],
      [x3, y3]
    ];
    path.clear();
    let start2;
    let current;
    for (const p of points) {
      if (start2 != null && pointsEq2(start2, p) || current != null && pointsEq2(current, p)) {
        continue;
      }
      const [x, y] = p;
      if (start2 == null) {
        path.moveTo(x, y);
      } else {
        path.lineTo(x, y);
      }
      start2 ?? (start2 = p);
      current = p;
    }
    path.closePath();
  }
};
__decorateClass([
  SceneChangeDetection()
], FunnelConnector.prototype, "x0", 2);
__decorateClass([
  SceneChangeDetection()
], FunnelConnector.prototype, "y0", 2);
__decorateClass([
  SceneChangeDetection()
], FunnelConnector.prototype, "x1", 2);
__decorateClass([
  SceneChangeDetection()
], FunnelConnector.prototype, "y1", 2);
__decorateClass([
  SceneChangeDetection()
], FunnelConnector.prototype, "x2", 2);
__decorateClass([
  SceneChangeDetection()
], FunnelConnector.prototype, "y2", 2);
__decorateClass([
  SceneChangeDetection()
], FunnelConnector.prototype, "x3", 2);
__decorateClass([
  SceneChangeDetection()
], FunnelConnector.prototype, "y3", 2);

// packages/ag-charts-enterprise/src/series/pyramid/pyramidProperties.ts
var { SeriesProperties: SeriesProperties3, makeSeriesTooltip: makeSeriesTooltip3, Label: Label4, DropShadow: DropShadow2 } = module_support_exports;
var PyramidSeriesLabel = class extends Label4 {
};
var PyramidSeriesStageLabel = class extends Label4 {
  constructor() {
    super(...arguments);
    this.spacing = 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidSeriesStageLabel.prototype, "spacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidSeriesStageLabel.prototype, "placement", 2);
var PyramidProperties = class extends SeriesProperties3 {
  constructor() {
    super(...arguments);
    this.fills = [];
    this.fillOpacity = 1;
    this.strokes = [];
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.direction = "vertical";
    this.reverse = void 0;
    this.spacing = 0;
    this.aspectRatio = void 0;
    this.shadow = new DropShadow2().set({ enabled: false });
    this.label = new PyramidSeriesLabel();
    this.stageLabel = new PyramidSeriesStageLabel();
    this.tooltip = makeSeriesTooltip3();
  }
  getStyle(index = 0) {
    const { fills, strokes, fillOpacity, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this;
    return {
      fill: fills[index % fills.length],
      fillOpacity,
      stroke: strokes[index % strokes.length],
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset,
      opacity: 1
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidProperties.prototype, "stageKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidProperties.prototype, "valueKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidProperties.prototype, "fills", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidProperties.prototype, "strokes", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidProperties.prototype, "direction", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidProperties.prototype, "reverse", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidProperties.prototype, "spacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidProperties.prototype, "aspectRatio", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidProperties.prototype, "itemStyler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidProperties.prototype, "shadow", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidProperties.prototype, "stageLabel", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PyramidProperties.prototype, "tooltip", 2);

// packages/ag-charts-enterprise/src/series/pyramid/pyramidUtil.ts
function applyPyramidDatum(connector, { x, y, top, right, bottom, left }) {
  connector.x0 = x - top / 2;
  connector.x1 = x + top / 2;
  connector.x2 = x + bottom / 2;
  connector.x3 = x - bottom / 2;
  connector.y0 = y - left / 2;
  connector.y1 = y - right / 2;
  connector.y2 = y + right / 2;
  connector.y3 = y + left / 2;
}
function preparePyramidAnimationFunctions(direction) {
  const fromFn = (_connector, datum) => {
    const { x, y } = datum;
    let { top, right, bottom, left } = datum;
    if (direction === "vertical") {
      top = 0;
      bottom = 0;
    } else {
      left = 0;
      right = 0;
    }
    return { x, y, top, right, bottom, left };
  };
  const toFn = (_connector, datum) => {
    const { x, y, top, right, bottom, left } = datum;
    return { x, y, top, right, bottom, left };
  };
  const applyFn = applyPyramidDatum;
  return { fromFn, toFn, applyFn };
}

// packages/ag-charts-enterprise/src/series/pyramid/pyramidSeries.ts
var {
  valueProperty: valueProperty3,
  SeriesNodePickMode: SeriesNodePickMode3,
  createDatumId: createDatumId3,
  BBox: BBox4,
  Group: Group5,
  Selection: Selection3,
  Text: Text2,
  PointerEvents: PointerEvents2,
  fromToMotion: fromToMotion2,
  seriesLabelFadeInAnimation: seriesLabelFadeInAnimation2,
  getLabelStyles: getLabelStyles3
} = module_support_exports;
var PyramidSeries = class extends module_support_exports.DataModelSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      categoryKey: void 0,
      pickModes: [SeriesNodePickMode3.EXACT_SHAPE_MATCH, SeriesNodePickMode3.NEAREST_NODE]
    });
    this.properties = new PyramidProperties();
    this.itemGroup = this.contentGroup.appendChild(new Group5({ name: "itemGroup" }));
    this.itemLabelGroup = this.contentGroup.appendChild(new Group5({ name: "itemLabelGroup" }));
    this.stageLabelGroup = this.contentGroup.appendChild(new Group5({ name: "stageLabelGroup" }));
    this.datumSelection = Selection3.select(
      this.itemGroup,
      () => this.nodeFactory()
    );
    this.labelSelection = Selection3.select(
      this.itemLabelGroup,
      Text2
    );
    this.stageLabelSelection = Selection3.select(this.stageLabelGroup, Text2);
    this.highlightLabelSelection = Selection3.select(this.highlightLabelGroup, Text2);
    this.highlightDatumSelection = Selection3.select(
      this.highlightNodeGroup,
      () => this.nodeFactory()
    );
    this.animationState = new StateMachine(
      "empty",
      {
        empty: {
          update: {
            target: "ready",
            action: () => this.animateEmptyUpdateReady()
          },
          reset: "empty",
          skip: "ready"
        },
        ready: {
          clear: "empty",
          reset: "empty",
          skip: "ready"
        }
      },
      () => this.checkProcessedDataAnimatable()
    );
    this.itemLabelGroup.pointerEvents = PointerEvents2.None;
    this.stageLabelGroup.pointerEvents = PointerEvents2.None;
    this.cleanup.register(this.ctx.eventsHub.on("legend:item-click", (event) => this.onLegendItemClick(event)));
  }
  nodeFactory() {
    return new FunnelConnector();
  }
  getNodeData() {
    return this.contextNodeData?.nodeData;
  }
  resetAnimation(phase) {
    if (phase === "initial") {
      this.animationState.transition("reset");
    } else if (phase === "ready") {
      this.animationState.transition("skip");
    }
  }
  async processData(dataController) {
    if (this.data == null)
      return;
    const {
      id: seriesId,
      visible,
      ctx: { legendManager }
    } = this;
    const { stageKey, valueKey } = this.properties;
    const xScaleType = "category";
    const yScaleType = "number";
    const validation = (_value, _datum, index) => visible && legendManager.getItemEnabled({ seriesId, itemId: index });
    const visibleProps = this.visible ? {} : { forceValue: 0 };
    const allowNullKey = this.properties.allowNullKeys ?? false;
    await this.requestDataModel(dataController, this.data, {
      props: [
        valueProperty3(stageKey, xScaleType, { id: "xValue", allowNullKey }),
        valueProperty3(valueKey, yScaleType, { id: `yValue`, ...visibleProps, validation, invalidValue: 0 })
      ]
    });
  }
  createNodeData() {
    const {
      id: seriesId,
      dataModel,
      processedData,
      properties,
      visible,
      ctx: { legendManager }
    } = this;
    const {
      stageKey,
      valueKey,
      direction,
      reverse = direction === "horizontal",
      spacing,
      aspectRatio,
      label,
      stageLabel
    } = properties;
    if (dataModel == null || processedData == null)
      return;
    const horizontal = direction === "horizontal";
    const xValues = dataModel.resolveColumnById(this, `xValue`, processedData);
    const yValues = dataModel.resolveColumnById(this, `yValue`, processedData);
    const xDomain = dataModel.getDomain(this, "xValue", "value", processedData).domain;
    const yDomain = dataModel.getDomain(this, "yValue", "value", processedData).domain;
    const textMeasurer = cachedTextMeasurer(stageLabel);
    let textAlign;
    let textBaseline;
    if (horizontal) {
      textAlign = "center";
      textBaseline = stageLabel.placement === "before" ? "bottom" : "top";
    } else {
      textAlign = stageLabel.placement === "after" ? "left" : "right";
      textBaseline = "middle";
    }
    const stageLabelData = stageLabel.enabled ? [] : void 0;
    let maxLabelWidth = 0;
    let maxLabelHeight = 0;
    let yTotal = 0;
    const rawData = processedData.dataSources.get(this.id)?.data ?? [];
    for (const [datumIndex, datum] of rawData.entries()) {
      const xValue = xValues[datumIndex];
      if (xValue === void 0 && !this.properties.allowNullKeys)
        continue;
      const yValue = yValues[datumIndex];
      const enabled = visible && legendManager.getItemEnabled({ seriesId, itemId: datumIndex });
      yTotal += yValue;
      if (stageLabelData == null)
        continue;
      const text2 = this.getLabelText(
        xValue,
        datum,
        stageKey,
        "x",
        xDomain,
        this.properties.stageLabel,
        { datum, value: yValue, stageKey, valueKey },
        this.properties.allowNullKeys ?? false
      );
      const { width: width2, height: height2 } = isArray(text2) ? measureTextSegments(text2, label) : textMeasurer.measureLines(toTextString(text2));
      maxLabelWidth = Math.max(maxLabelWidth, width2);
      maxLabelHeight = Math.max(maxLabelHeight, height2);
      stageLabelData.push({
        x: Number.NaN,
        y: Number.NaN,
        text: text2,
        textAlign,
        textBaseline,
        visible: enabled
      });
    }
    const seriesRectWidth = this._nodeDataDependencies?.seriesRectWidth ?? 0;
    const seriesRectHeight = this._nodeDataDependencies?.seriesRectHeight ?? 0;
    const totalSpacing = spacing * (processedData.input.count - 1);
    let bounds;
    if (horizontal) {
      const verticalInset = maxLabelHeight + stageLabel.spacing;
      bounds = new BBox4(
        0,
        stageLabel.placement === "before" ? verticalInset : 0,
        seriesRectWidth,
        seriesRectHeight - verticalInset
      );
    } else {
      const horizontalInset = maxLabelWidth + stageLabel.spacing;
      bounds = new BBox4(
        stageLabel.placement === "after" ? 0 : horizontalInset,
        0,
        seriesRectWidth - horizontalInset,
        seriesRectHeight
      );
    }
    if (aspectRatio != null && aspectRatio !== 0) {
      const directionalAspectRatio = direction === "horizontal" ? 1 / aspectRatio : aspectRatio;
      const constrainedWidth = Math.min(bounds.width, bounds.height * directionalAspectRatio);
      const constrainedHeight = constrainedWidth / directionalAspectRatio;
      bounds = new BBox4(
        bounds.x + (bounds.width - constrainedWidth) / 2,
        bounds.y + (bounds.height - constrainedHeight) / 2,
        constrainedWidth,
        constrainedHeight
      );
    }
    let labelX;
    let labelY;
    if (horizontal) {
      labelY = stageLabel.placement === "before" ? bounds.y - stageLabel.spacing : bounds.y + bounds.height + stageLabel.spacing;
    } else {
      labelX = stageLabel.placement === "after" ? bounds.x + bounds.width + stageLabel.spacing : bounds.x - stageLabel.spacing;
    }
    const availableWidth = bounds.width - (horizontal ? totalSpacing : 0);
    const availableHeight = bounds.height - (horizontal ? 0 : totalSpacing);
    if (availableWidth < 0 || availableHeight < 0)
      return;
    const nodeData = [];
    const labelData = [];
    let yStart = 0;
    let stageLabelIndex = 0;
    for (const [datumIndex, datum] of rawData.entries()) {
      const xValue = xValues[datumIndex];
      if (xValue === void 0 && !this.properties.allowNullKeys)
        continue;
      const yValue = yValues[datumIndex];
      const enabled = visible && legendManager.getItemEnabled({ seriesId, itemId: datumIndex });
      const yEnd = yStart + yValue;
      const yMidRatio = (yStart + yEnd) / (2 * yTotal);
      const yRangeRatio = (yEnd - yStart) / yTotal;
      const xOffset = horizontal ? availableWidth * yMidRatio + spacing * datumIndex : availableWidth * 0.5;
      const yOffset = horizontal ? availableHeight * 0.5 : availableHeight * yMidRatio + spacing * datumIndex;
      const x = bounds.x + xOffset;
      const y = bounds.y + yOffset;
      if (stageLabelData != null) {
        const stageLabelDatum = stageLabelData[stageLabelIndex++];
        stageLabelDatum.x = labelX ?? x;
        stageLabelDatum.y = labelY ?? y;
      }
      let top;
      let right;
      let bottom;
      let left;
      if (horizontal) {
        const barWidth = availableWidth * yRangeRatio;
        top = barWidth;
        bottom = barWidth;
        const y0 = (xOffset + barWidth / 2) * (availableHeight / bounds.width);
        const y1 = (xOffset - barWidth / 2) * (availableHeight / bounds.width);
        right = reverse ? bounds.height - y0 : y0;
        left = reverse ? bounds.height - y1 : y1;
      } else {
        const barHeight = availableHeight * yRangeRatio;
        right = barHeight;
        left = barHeight;
        const x0 = (yOffset - barHeight / 2) * (availableWidth / bounds.height);
        const x1 = (yOffset + barHeight / 2) * (availableWidth / bounds.height);
        top = reverse ? bounds.width - x0 : x0;
        bottom = reverse ? bounds.width - x1 : x1;
      }
      const text2 = this.getLabelText(
        yValue,
        datum,
        valueKey,
        "y",
        yDomain,
        label,
        {
          datum,
          value: yValue,
          stageKey,
          valueKey
        }
      );
      const labelDatum = {
        x,
        y,
        text: text2,
        textAlign: "center",
        textBaseline: "middle",
        visible: enabled
      };
      labelData.push(labelDatum);
      nodeData.push({
        series: this,
        datum,
        datumIndex,
        index: datumIndex,
        xValue,
        yValue,
        x,
        y,
        top,
        right,
        bottom,
        left,
        label: labelDatum,
        enabled,
        midPoint: {
          x,
          y
        },
        style: this.getItemStyle({ datumIndex, datum }, false)
      });
      yStart = yEnd;
    }
    return {
      itemId: seriesId,
      nodeData,
      labelData,
      stageLabelData,
      bounds
    };
  }
  updateSelections() {
    if (this.nodeDataRefresh) {
      this.contextNodeData = this.createNodeData();
      this.nodeDataRefresh = false;
    }
  }
  update({ seriesRect }) {
    this.checkResize(seriesRect);
    const {
      datumSelection,
      labelSelection,
      stageLabelSelection,
      highlightDatumSelection,
      highlightLabelSelection
    } = this;
    this.updateSelections();
    this.contentGroup.visible = this.visible;
    this.contentGroup.opacity = this.getOpacity();
    let highlightedDatum = this.ctx.highlightManager?.getActiveHighlight();
    if (highlightedDatum != null && (highlightedDatum.series !== this || highlightedDatum.datum == null)) {
      highlightedDatum = void 0;
    }
    const nodeData = this.contextNodeData?.nodeData ?? [];
    const labelData = this.contextNodeData?.labelData ?? [];
    const stageLabelData = this.contextNodeData?.stageLabelData ?? [];
    this.datumSelection = this.updateDatumSelection({ nodeData, datumSelection });
    this.updateDatumStyles({ datumSelection, isHighlight: false });
    this.updateDatumNodes({ datumSelection, isHighlight: false });
    this.labelSelection = this.updateLabelSelection({ labelData, labelSelection });
    this.updateLabelNodes({ labelSelection, labelProperties: this.properties.label });
    this.stageLabelSelection = this.updateStageLabelSelection({ stageLabelData, stageLabelSelection });
    this.updateLabelNodes({
      labelSelection: stageLabelSelection,
      labelProperties: this.properties.stageLabel,
      checkActiveHighlight: true
    });
    const highlightLabelData = this.getHighlightLabelData(labelData, highlightedDatum) ?? [];
    this.highlightLabelSelection = highlightLabelSelection.update(highlightLabelData);
    this.updateLabelNodes({
      labelSelection: this.highlightLabelSelection,
      labelProperties: this.properties.label,
      isHighlight: true
    });
    this.highlightDatumSelection = this.updateDatumSelection({
      nodeData: highlightedDatum == null ? [] : [highlightedDatum],
      datumSelection: highlightDatumSelection
    });
    this.updateDatumStyles({ datumSelection: highlightDatumSelection, isHighlight: true });
    this.updateDatumNodes({ datumSelection: highlightDatumSelection, isHighlight: true });
    this.animationState.transition("update");
  }
  updateDatumSelection(opts) {
    return opts.datumSelection.update(opts.nodeData);
  }
  getItemStyle({ datumIndex, datum }, isHighlight) {
    const { properties } = this;
    const { itemStyler } = properties;
    const highlightStyle = this.getHighlightStyle(isHighlight, datumIndex);
    const baseStyle = mergeDefaults(highlightStyle, properties.getStyle(datumIndex));
    let style2 = baseStyle;
    if (itemStyler != null && datumIndex != null) {
      const overrides = this.cachedDatumCallback(
        createDatumId3(datumIndex, isHighlight ? "highlight" : "node"),
        () => {
          const params = this.makeItemStylerParams(datum, datumIndex, isHighlight, style2);
          return this.callWithContext(itemStyler, params);
        }
      );
      if (overrides) {
        style2 = mergeDefaults(overrides, style2);
      }
    }
    return style2;
  }
  makeItemStylerParams(datum, datumIndex, isHighlight, style2) {
    const { id: seriesId, properties } = this;
    const { stageKey, valueKey } = properties;
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const highlightState = this.getHighlightStateString(activeHighlight, isHighlight, datumIndex);
    const fill = this.filterItemStylerFillParams(style2.fill) ?? style2.fill;
    return {
      seriesId,
      datum,
      stageKey,
      valueKey,
      highlightState,
      ...style2,
      fill
    };
  }
  updateDatumStyles({
    datumSelection,
    isHighlight
  }) {
    datumSelection.each((_, nodeDatum) => {
      nodeDatum.style = this.getItemStyle(nodeDatum, isHighlight);
    });
  }
  updateDatumNodes({
    datumSelection
  }) {
    const { properties } = this;
    const { shadow } = properties;
    const bounds = this.contextNodeData?.bounds;
    const fillBBox = bounds ? { series: bounds, axis: bounds } : void 0;
    datumSelection.each((connector, nodeDatum) => {
      connector.setStyleProperties(nodeDatum.style, fillBBox);
      applyPyramidDatum(connector, nodeDatum);
      connector.fillShadow = shadow;
    });
  }
  updateLabelSelection(opts) {
    return opts.labelSelection.update(this.properties.label.enabled ? opts.labelData : []);
  }
  updateStageLabelSelection(opts) {
    return opts.stageLabelSelection.update(opts.stageLabelData);
  }
  updateLabelNodes(opts) {
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const { labelSelection, labelProperties, isHighlight = false, checkActiveHighlight = false } = opts;
    labelSelection.each((label, nodeDatum, datumIndex) => {
      const { visible, x, y, text: text2, textAlign, textBaseline } = nodeDatum;
      const datumIsHighlighted = isHighlight || checkActiveHighlight && activeHighlight?.datumIndex === datumIndex;
      const highlightStyle = this.getHighlightStyle(datumIsHighlighted, datumIndex);
      const style2 = getLabelStyles3(
        this,
        void 0,
        this.properties,
        labelProperties,
        datumIsHighlighted,
        activeHighlight
      );
      const { color: fill, fontSize, fontStyle, fontWeight: fontWeight2, fontFamily } = style2;
      label.visible = visible;
      label.x = x;
      label.y = y;
      label.text = text2;
      label.fill = fill;
      label.opacity = (highlightStyle.opacity ?? 1) * (style2.fillOpacity ?? 1);
      label.fillOpacity = (highlightStyle.opacity ?? 1) * (style2.fillOpacity ?? 1);
      label.fontStyle = fontStyle;
      label.fontWeight = fontWeight2;
      label.fontSize = fontSize;
      label.fontFamily = fontFamily;
      label.textAlign = textAlign;
      label.textBaseline = textBaseline;
      label.setBoxing(style2);
    });
  }
  getHighlightLabelData(_labelData, highlightedItem) {
    if (highlightedItem?.label) {
      return [{ ...highlightedItem.label }];
    }
    return void 0;
  }
  computeFocusBounds(opts) {
    const datum = this.getNodeData()?.[opts.datumIndex];
    if (datum === void 0)
      return;
    for (const node of this.datumSelection) {
      if (node.datum === datum) {
        return node.node;
      }
    }
  }
  getTooltipContent(datumIndex) {
    const { id: seriesId, dataModel, processedData, properties } = this;
    const { stageKey, valueKey, tooltip } = properties;
    if (!dataModel || !processedData)
      return;
    const datum = processedData.dataSources.get(this.id)?.data[datumIndex];
    const xValue = dataModel.resolveColumnById(this, "xValue", processedData)[datumIndex];
    const yValue = dataModel.resolveColumnById(this, `yValue`, processedData)[datumIndex];
    const allowNullKeys = this.properties.allowNullKeys ?? false;
    if (xValue === void 0 && !allowNullKeys)
      return;
    const label = this.getLabelText(
      xValue,
      datum,
      stageKey,
      "x",
      dataModel.getDomain(this, "xValue", "value", processedData).domain,
      this.properties.stageLabel,
      { datum, value: xValue, stageKey, valueKey }
    );
    const format = this.getItemStyle({ datumIndex, datum }, false);
    return this.formatTooltipWithContext(
      tooltip,
      {
        symbol: this.legendItemSymbol(datumIndex),
        data: [{ label: toPlainText(label), value: toPlainText(yValue) }]
      },
      {
        seriesId,
        datum,
        title: void 0,
        stageKey,
        valueKey,
        ...format
      }
    );
  }
  getSeriesDomain() {
    return { domain: [Number.NaN, Number.NaN] };
  }
  getSeriesRange() {
    return [Number.NaN, Number.NaN];
  }
  pickNodeClosestDatum({ x, y }) {
    let minDistanceSquared = Infinity;
    let minDatum;
    this.datumSelection.each((node, datum) => {
      const distanceSquared2 = node.distanceSquared(x, y);
      if (distanceSquared2 < minDistanceSquared) {
        minDistanceSquared = distanceSquared2;
        minDatum = datum;
      }
    });
    return minDatum == null ? void 0 : { datum: minDatum, distance: Math.sqrt(minDistanceSquared) };
  }
  legendItemSymbol(datumIndex) {
    const { fills, strokes, strokeWidth, fillOpacity, strokeOpacity, lineDash, lineDashOffset } = this.properties;
    const fill = fills[datumIndex] ?? "black";
    const stroke3 = strokes[datumIndex] ?? "black";
    return {
      marker: {
        fill,
        fillOpacity,
        stroke: stroke3,
        strokeWidth,
        strokeOpacity,
        lineDash,
        lineDashOffset
      }
    };
  }
  getLegendData(legendType) {
    const {
      processedData,
      dataModel,
      id: seriesId,
      ctx: { legendManager },
      visible
    } = this;
    if (!dataModel || !processedData || legendType !== "category") {
      return [];
    }
    const { showInLegend } = this.properties;
    const stageValues = dataModel.resolveColumnById(this, `xValue`, processedData);
    return (processedData.dataSources.get(this.id)?.data ?? []).map((datum, datumIndex) => {
      const stageValue = stageValues[datumIndex];
      const allowNullKeys = this.properties.allowNullKeys ?? false;
      if (stageValue == null && !allowNullKeys)
        return;
      return {
        legendType: "category",
        id: seriesId,
        datum,
        itemId: datumIndex,
        seriesId,
        enabled: visible && legendManager.getItemEnabled({ seriesId, itemId: datumIndex }),
        label: { text: String(stageValue) },
        symbol: this.legendItemSymbol(datumIndex),
        hideInLegend: !showInLegend
      };
    }).filter((datum) => datum != null);
  }
  animateReset() {
    this.ctx.animationManager.skipCurrentBatch();
    this.ctx.animationManager.stopByAnimationGroupId(this.id);
  }
  animateEmptyUpdateReady() {
    const { datumSelection, labelSelection, properties } = this;
    const fns = preparePyramidAnimationFunctions(properties.direction);
    fromToMotion2(this.id, "nodes", this.ctx.animationManager, [datumSelection], fns);
    seriesLabelFadeInAnimation2(this, "labels", this.ctx.animationManager, labelSelection);
  }
  hasItemStylers() {
    return this.properties.itemStyler != null || this.properties.label.itemStyler != null;
  }
};
PyramidSeries.className = "PyramidSeries";
PyramidSeries.type = "pyramid";

// packages/ag-charts-enterprise/src/series/pyramid/pyramidSeriesOptionsDef.ts
var { pyramidSeriesThemeableOptionsDef: pyramidSeriesThemeableOptionsDef2 } = module_support_exports;
var pyramidSeriesOptionsDef = {
  ...pyramidSeriesThemeableOptionsDef2,
  ...commonSeriesOptionsDefs,
  type: required(constant("pyramid")),
  stageKey: required(string),
  valueKey: required(string)
};

// packages/ag-charts-enterprise/src/series/pyramid/pyramidThemes.ts
var PYRAMID_SERIES_THEME = {
  series: {
    direction: "vertical",
    strokeWidth: { $isUserOption: ["./strokes/0", 2, 0] },
    spacing: 2,
    fills: {
      $applyCycle: [
        { $size: { $path: ["./data", { $path: "/data" }] } },
        { $palette: "fills" },
        {
          $applySwitch: [
            { $path: ["/type", void 0, { $value: "$1" }] },
            { $value: "$1" },
            ["gradient", FILL_GRADIENT_LINEAR_DEFAULTS],
            ["pattern", FILL_PATTERN_DEFAULTS],
            ["image", FILL_IMAGE_DEFAULTS]
          ]
        }
      ]
    },
    strokes: {
      $applyCycle: [{ $size: { $path: ["./data", { $path: "/data" }] } }, { $palette: "strokes" }]
    },
    label: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: true,
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      fontWeight: { $ref: "fontWeight" },
      color: { $ref: "chartBackgroundColor" }
    },
    stageLabel: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: true,
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      fontWeight: { $ref: "fontWeight" },
      color: { $ref: "textColor" },
      spacing: 12
    },
    shadow: {
      enabled: false,
      color: DEFAULT_SHADOW_COLOUR,
      xOffset: 3,
      yOffset: 3,
      blur: 5
    },
    highlight: {
      unhighlightedItem: {
        opacity: 0.4
      }
    }
  }
};

// packages/ag-charts-enterprise/src/series/pyramid/pyramidModule.ts
var PyramidSeriesModule = {
  type: "series",
  name: "pyramid",
  chartType: "standalone",
  enterprise: true,
  solo: true,
  version: VERSION,
  dependencies: [StandaloneChartModule],
  options: pyramidSeriesOptionsDef,
  themeTemplate: PYRAMID_SERIES_THEME,
  create: (ctx) => new PyramidSeries(ctx)
};

// packages/ag-charts-enterprise/src/series/sankey/sankeyLink.ts
var { BBox: BBox5, Path: Path4 } = module_support_exports;
var SankeyLink = class extends Path4 {
  constructor() {
    super(...arguments);
    this.x1 = 0;
    this.x2 = 0;
    this.y1 = 0;
    this.y2 = 0;
    this.height = 0;
    this.inset = 0;
    this.elbows = [];
  }
  computeBBox() {
    const x = Math.min(this.x1, this.x2);
    const width2 = Math.max(this.x1, this.x2) - x;
    const y = Math.min(this.y1, this.y2);
    const height2 = Math.max(this.y1, this.y2) - y + this.height;
    return new BBox5(x, y, width2, height2);
  }
  updatePath() {
    const { path, inset } = this;
    path.clear();
    const height2 = this.height - 2 * this.inset;
    const offset = height2 / 2;
    let x1 = this.x1 + inset;
    let y1 = this.y1 + inset;
    path.moveTo(x1, y1);
    for (const elbow of this.elbows) {
      this.updatePathSection(x1, y1, elbow.x, elbow.y, height2, -offset);
      x1 = elbow.x;
      y1 = elbow.y;
    }
    const x2 = this.x2 - inset;
    const y2 = this.y2 + inset;
    this.updatePathSection(x1, y1, x2, y2, height2, -offset);
    path.lineTo(x2, y2 + height2);
    x1 = x2;
    y1 = y2;
    for (const elbow of this.elbows.toReversed()) {
      this.updatePathSection(x1, y1, elbow.x, elbow.y, height2, offset);
      x1 = elbow.x;
      y1 = elbow.y;
    }
    this.updatePathSection(x1, y1, this.x1 + inset, this.y1 + inset, height2, offset);
    path.closePath();
  }
  updatePathSection(x1, y1, x2, y2, height2, yOffset) {
    const { path } = this;
    const start2 = vector_exports.from(x1, y1 + yOffset + height2 / 2);
    const end3 = vector_exports.from(x2, y2 + yOffset + height2 / 2);
    if (Math.abs(end3.y - start2.y) < 2) {
      path.lineTo(end3.x, end3.y);
      return;
    }
    let angle2 = vector_exports.angle(vector_exports.sub(end3, start2));
    if (angle2 < 0)
      angle2 = 2 * Math.PI + angle2;
    const right = 0;
    const down = Math.PI / 2;
    const left = Math.PI;
    const up = Math.PI * 1.5;
    const innerArc = getArcValues(start2, end3, 0);
    const outerArc = getArcValues(start2, end3, height2);
    if (innerArc.radius < height2) {
      path.cubicCurveTo((start2.x + end3.x) / 2, start2.y, (start2.x + end3.x) / 2, end3.y, end3.x, end3.y);
      return;
    }
    if (angle2 >= up) {
      path.arc(start2.x, y1 - innerArc.radius, innerArc.radius, down, down + outerArc.angle, true);
      path.arc(end3.x, y2 + outerArc.radius, outerArc.radius, up + outerArc.angle, up);
      path.lineTo(end3.x, end3.y);
    } else if (angle2 > right && angle2 <= down) {
      path.arc(start2.x, y1 + outerArc.radius, outerArc.radius, up, up + outerArc.angle);
      path.arc(end3.x, y2 - innerArc.radius, innerArc.radius, down + innerArc.angle, down, true);
      path.lineTo(end3.x, end3.y);
    } else if (angle2 > down && angle2 <= left) {
      path.arc(start2.x, y1 + outerArc.radius, outerArc.radius - height2, up, up + outerArc.angle, true);
      path.arc(end3.x, y2 - innerArc.radius, innerArc.radius + height2, down + innerArc.angle, down);
      path.lineTo(end3.x, end3.y);
    } else {
      path.arc(start2.x, y1 - innerArc.radius, innerArc.radius + height2, down, down + innerArc.angle);
      path.arc(end3.x, y2 + outerArc.radius, outerArc.radius - height2, up + outerArc.angle, up, true);
      path.lineTo(end3.x, end3.y);
    }
  }
};
__decorateClass([
  SceneChangeDetection()
], SankeyLink.prototype, "x1", 2);
__decorateClass([
  SceneChangeDetection()
], SankeyLink.prototype, "x2", 2);
__decorateClass([
  SceneChangeDetection()
], SankeyLink.prototype, "y1", 2);
__decorateClass([
  SceneChangeDetection()
], SankeyLink.prototype, "y2", 2);
__decorateClass([
  SceneChangeDetection()
], SankeyLink.prototype, "height", 2);
__decorateClass([
  SceneChangeDetection()
], SankeyLink.prototype, "inset", 2);
function getArcValues(start2, end3, minRadius) {
  const lineAngle = vector_exports.angle(vector_exports.sub(end3, start2));
  const chordLength = vector_exports.distance(start2, end3);
  const bisect = vector_exports.add(start2, vector_exports.rotate(vector_exports.from(chordLength / 2, 0), lineAngle));
  const gradient2 = -1 / vector_exports.gradient(start2, end3);
  const intercept2 = vector_exports.intercept(bisect, gradient2);
  const offset = lerpClamp(0.1, 0.5, Math.PI / 2 - Math.abs(vector_exports.gradient(start2, end3)));
  const center2 = vector_exports.intersectAtX(gradient2, intercept2, start2.x);
  const radius = Math.max(minRadius, vector_exports.distance(start2, center2) * offset);
  const angle2 = vector_exports.angle(vector_exports.sub(center2, start2), vector_exports.sub(center2, bisect)) / -(1.1 - offset);
  return { angle: angle2, radius };
}
function lerpClamp(a, b, ratio2) {
  return clamp(a, (b - a) * ratio2 + a, b);
}

// packages/ag-charts-enterprise/src/series/sankey/sankeySeriesProperties.ts
var { FillGradientDefaults: FillGradientDefaults3, FillPatternDefaults: FillPatternDefaults3, FillImageDefaults: FillImageDefaults3, makeSeriesTooltip: makeSeriesTooltip4, SeriesProperties: SeriesProperties4, Label: Label5 } = module_support_exports;
var SankeySeriesLabelProperties = class extends Label5 {
  constructor() {
    super(...arguments);
    this.spacing = 1;
    this.placement = void 0;
    this.edgePlacement = void 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesLabelProperties.prototype, "spacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesLabelProperties.prototype, "placement", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesLabelProperties.prototype, "edgePlacement", 2);
var SankeySeriesLinkProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.fill = void 0;
    this.fillOpacity = 1;
    this.stroke = void 0;
    this.strokeOpacity = 1;
    this.strokeWidth = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesLinkProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesLinkProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesLinkProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesLinkProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesLinkProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesLinkProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesLinkProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesLinkProperties.prototype, "itemStyler", 2);
var SankeySeriesNodeProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.spacing = 1;
    this.minSpacing = 0;
    this.width = 1;
    this.alignment = "justify";
    this.verticalAlignment = "center";
    this.sort = "auto";
    this.fill = void 0;
    this.fillOpacity = 1;
    this.stroke = void 0;
    this.strokeOpacity = 1;
    this.strokeWidth = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesNodeProperties.prototype, "spacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesNodeProperties.prototype, "minSpacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesNodeProperties.prototype, "width", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesNodeProperties.prototype, "alignment", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesNodeProperties.prototype, "verticalAlignment", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesNodeProperties.prototype, "sort", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesNodeProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesNodeProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesNodeProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesNodeProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesNodeProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesNodeProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesNodeProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesNodeProperties.prototype, "itemStyler", 2);
var SankeySeriesProperties = class extends SeriesProperties4 {
  constructor() {
    super(...arguments);
    this.nodes = void 0;
    this.idKey = "";
    this.idName = void 0;
    this.labelKey = void 0;
    this.labelName = void 0;
    this.sizeKey = void 0;
    this.sizeName = void 0;
    this.fillGradientDefaults = new FillGradientDefaults3();
    this.fillPatternDefaults = new FillPatternDefaults3();
    this.fillImageDefaults = new FillImageDefaults3();
    this.defaultColorRange = [];
    this.defaultPatternFills = [];
    this.fills = [];
    this.strokes = [];
    this.label = new SankeySeriesLabelProperties();
    this.link = new SankeySeriesLinkProperties();
    this.node = new SankeySeriesNodeProperties();
    this.tooltip = makeSeriesTooltip4();
  }
  getStyle(isLink, fills, strokes, index) {
    const {
      fillOpacity,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset,
      fill = fills[index % fills.length],
      stroke: stroke3 = strokes[index % fills.length]
    } = isLink ? this.link : this.node;
    return {
      fill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "nodes", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "fromKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "toKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "idKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "idName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "labelKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "labelName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "sizeKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "sizeName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "fillGradientDefaults", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "fillPatternDefaults", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "fillImageDefaults", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "defaultColorRange", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "defaultPatternFills", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "fills", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "strokes", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "link", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "node", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SankeySeriesProperties.prototype, "tooltip", 2);

// packages/ag-charts-enterprise/src/series/sankey/sankeySeries.ts
var { Transformable: Transformable2, SeriesNodePickMode: SeriesNodePickMode4, createDatumId: createDatumId4, getShapeStyle: getShapeStyle3, getLabelStyles: getLabelStyles4, Rect: Rect2, BBox: BBox6 } = module_support_exports;
var SankeySeries = class extends FlowProportionSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      pickModes: [SeriesNodePickMode4.NEAREST_NODE, SeriesNodePickMode4.EXACT_SHAPE_MATCH]
    });
    this.properties = new SankeySeriesProperties();
  }
  isLabelEnabled() {
    return (this.properties.labelKey != null || this.nodes == null) && this.properties.label.enabled;
  }
  linkFactory() {
    return new SankeyLink();
  }
  nodeFactory() {
    return new Rect2();
  }
  createNodeData() {
    const seriesRectWidth = this._nodeDataDependencies?.seriesRectWidth ?? 0;
    const nodeWidth = this.properties.node.width;
    const {
      nodeGraph: baseNodeGraph,
      links,
      maxPathLength
    } = this.getNodeGraph(this.createNode.bind(this, nodeWidth), this.createLink, {
      includeCircularReferences: false
    });
    const nodeGraph = baseNodeGraph;
    if (nodeGraph.size === 0)
      return;
    const columns = this.initialiseColumns(maxPathLength);
    this.assignNodesToColumns(nodeGraph, columns, maxPathLength);
    const measurer3 = cachedTextMeasurer(this.properties.label);
    const { columnLabelInsetBefore, columnLabelInsetAfter } = this.getColumnLabelInsets(
      columns,
      measurer3,
      maxPathLength
    );
    const columnWidth = (seriesRectWidth - nodeWidth - columnLabelInsetBefore - columnLabelInsetAfter) / (maxPathLength - 1);
    this.positionNodesInColumnsX(columns, columnWidth, columnLabelInsetBefore);
    this.createGhostNodesAndColumnDiffs(nodeGraph, columns);
    this.weightNodes(columns);
    const minSize = 1;
    const { sizeScale, nodeSpacing } = this.getScaleAndSpacing(columns, minSize);
    if (sizeScale < 0) {
      logger_exports.warnOnce(
        "There was insufficient space to display the Sankey Series. Reduce [node.spacing], [node.minSpacing], or provide a larger container."
      );
      return;
    }
    this.positionNodesInColumnsY(columns, minSize, sizeScale, nodeSpacing);
    this.sortAndPositionLinks(nodeGraph, sizeScale);
    const nodeData = [];
    const labelData = [];
    this.createNodesNodeData(nodeData, nodeGraph, columns, columnWidth, measurer3, labelData);
    this.createLinksNodeData(nodeData, links, minSize, sizeScale);
    return {
      itemId: this.id,
      nodeData,
      labelData
    };
  }
  createNode(nodeWidth, node) {
    return {
      ...node,
      x: Number.NaN,
      y: Number.NaN,
      width: nodeWidth,
      height: Number.NaN
    };
  }
  createLink(link) {
    return {
      ...link,
      x1: Number.NaN,
      x2: Number.NaN,
      y1: Number.NaN,
      y2: Number.NaN,
      height: Number.NaN,
      elbows: []
    };
  }
  initialiseColumns(maxPathLength) {
    const columns = [];
    for (let index = 0; index < maxPathLength; index += 1) {
      columns.push({ index, size: 0, nodes: [], x: 0 });
    }
    return columns;
  }
  assignNodesToColumns(nodeGraph, columns, maxPathLength) {
    const { fromKey, toKey, sizeKey, labelKey } = this.properties;
    for (const graphNode of nodeGraph.values()) {
      const { datum: node, linksBefore, linksAfter } = graphNode;
      const size = Math.max(
        linksBefore.reduce((acc, { link }) => acc + link.size, 0),
        linksAfter.reduce((acc, { link }) => acc + link.size, 0)
      );
      if (linksBefore.length === 0 && linksAfter.length === 0 || size === 0) {
        graphNode.columnIndex = -1;
        continue;
      }
      const column = this.getNodeColumn(columns, graphNode, maxPathLength);
      node.size = size;
      const { label } = this.properties;
      const labelText = label.enabled ? this.getLabelText(
        node.label,
        node.datum,
        labelKey,
        "label",
        [],
        this.properties.label,
        { datum: node.datum, value: node.label, fromKey, toKey, sizeKey, size }
      ) : void 0;
      node.label = toPlainText(labelText);
      column.nodes.push(graphNode);
      column.size += size;
      graphNode.columnIndex = column.index;
    }
  }
  getNodeColumn(columns, graphNode, maxPathLength) {
    const {
      node: { alignment }
    } = this.properties;
    const { linksBefore, linksAfter, maxPathLengthBefore, maxPathLengthAfter } = graphNode;
    let column;
    switch (alignment) {
      case "left":
        column = columns[maxPathLengthBefore];
        break;
      case "right":
        column = columns[maxPathLength - 1 - maxPathLengthAfter];
        break;
      case "center": {
        if (linksBefore.length !== 0) {
          column = columns[maxPathLengthBefore];
        } else if (linksAfter.length === 0) {
          column = columns[0];
        } else {
          const columnIndex = linksAfter.reduce((acc, link) => Math.min(acc, link.node.maxPathLengthBefore), maxPathLength) - 1;
          column = columns[columnIndex];
        }
        break;
      }
      case "justify": {
        column = linksAfter.length === 0 ? columns[maxPathLength - 1] : columns[maxPathLengthBefore];
        break;
      }
    }
    return column;
  }
  getColumnLabelInsets(columns, measurer3, maxPathLength) {
    const {
      label: { spacing: labelSpacing, placement: labelPlacement, edgePlacement: edgeLabelPlacement },
      node: { width: nodeWidth }
    } = this.properties;
    const seriesRectWidth = this._nodeDataDependencies?.seriesRectWidth ?? 0;
    let columnLabelInsetBefore = 0;
    let columnLabelInsetAfter = 0;
    if (this.isLabelEnabled() && (edgeLabelPlacement === "outside" || edgeLabelPlacement == null)) {
      const reduceLabelWidthFn = (acc, n) => {
        const node = n;
        if (node.datum.label == null || node.datum.label === "")
          return acc;
        let maxWidth = (seriesRectWidth - nodeWidth) / (maxPathLength - 1) - labelSpacing;
        if (labelPlacement === "center" && edgeLabelPlacement == null)
          maxWidth /= 2;
        const text2 = wrapText(node.datum.label, {
          maxWidth,
          maxHeight: node.datum.height,
          font: this.properties.label,
          textWrap: "never"
        });
        let { width: width2 } = measurer3.measureLines(text2);
        if (labelPlacement === "center" && edgeLabelPlacement == null)
          width2 /= 2;
        return Math.max(acc, width2);
      };
      if (labelPlacement !== "right" || edgeLabelPlacement === "outside") {
        columnLabelInsetBefore = nodeWidth + columns[0].nodes.reduce(reduceLabelWidthFn, 0);
      }
      if (labelPlacement !== "left" || edgeLabelPlacement === "outside") {
        columnLabelInsetAfter = nodeWidth + columns.at(-1).nodes.reduce(reduceLabelWidthFn, 0);
      }
    }
    return { columnLabelInsetBefore, columnLabelInsetAfter };
  }
  positionNodesInColumnsX(columns, columnWidth, columnLabelInsetBefore) {
    for (let index = 0; index < columns.length; index++) {
      const column = columns[index];
      column.x = columnLabelInsetBefore + index * columnWidth;
      for (const graphNode of column.nodes) {
        graphNode.datum.x = column.x;
      }
    }
  }
  createGhostNodesAndColumnDiffs(nodeGraph, columns) {
    for (const graphNode of nodeGraph.values()) {
      graphNode.weight = 0;
      let closestColumnDiff = Infinity;
      for (const link of graphNode.linksAfter) {
        const node = link.node;
        closestColumnDiff = Math.min(closestColumnDiff, node.columnIndex - graphNode.columnIndex);
      }
      if (closestColumnDiff === Infinity) {
        for (const link of graphNode.linksBefore) {
          const node = link.node;
          closestColumnDiff = Math.min(closestColumnDiff, graphNode.columnIndex - node.columnIndex);
        }
      }
      graphNode.closestColumnDiff = closestColumnDiff;
      this.createNodeGhostNodes(graphNode, columns, closestColumnDiff);
    }
  }
  createNodeGhostNodes(graphNode, columns, closestColumnDiff) {
    for (const link of graphNode.linksAfter) {
      const node = link.node;
      if (node.columnIndex <= graphNode.columnIndex)
        continue;
      for (let i = node.columnIndex - 1; i > graphNode.columnIndex; i--) {
        const size = link.link.size;
        const ghostNode = {
          ghost: true,
          datum: { ...graphNode.datum, size, y: 0, height: 0 },
          weight: 0,
          linksBefore: [{ node: { columnIndex: i - 1, datum: { size } } }],
          linksAfter: [{ node: { columnIndex: i + 1, datum: { size } } }],
          link: link.link,
          columnIndex: graphNode.columnIndex,
          size: graphNode.datum.size,
          closestColumnDiff,
          fromNode: { y: node.datum.y },
          toNode: { y: 0 }
        };
        columns[i].size += size;
        columns[i].nodes.push(ghostNode);
      }
    }
  }
  weightNodes(columns) {
    const { properties } = this;
    if (properties.node.sort === "data")
      return;
    if (properties.node.sort !== "auto") {
      for (const column of columns) {
        column.nodes.sort((a, b) => this.sortNodes(a, b));
      }
      return;
    }
    const sortedColumns = columns.toSorted((a, b) => {
      const aMax = a.nodes.reduce((acc, n) => Math.max(acc, n.datum.size), 0);
      const bMax = b.nodes.reduce((acc, n) => Math.max(acc, n.datum.size), 0);
      return bMax - aMax;
    });
    const columnWeights = {};
    for (let i = 0; i < sortedColumns.length; i++) {
      columnWeights[sortedColumns[i].index] = Math.pow(10, sortedColumns.length - i - 1);
    }
    for (const column of columns) {
      for (const node of column.nodes) {
        if ("ghost" in node && node.ghost) {
          node.weight = node.size / column.size * columnWeights[column.index];
          continue;
        }
        node.weight = node.datum.size / column.size * columnWeights[column.index];
      }
      column.nodes.sort((a, b) => a.weight - b.weight);
    }
    for (const column of columns) {
      for (const node of column.nodes) {
        if ("ghost" in node && node.ghost) {
          continue;
        }
        node.weight += node.linksBefore.reduce((acc, before) => {
          if (before.node.columnIndex !== column.index - 1)
            return acc;
          const weight = columns[before.node.columnIndex].nodes.indexOf(before.node) * columnWeights[before.node.columnIndex];
          return Math.max(acc, weight);
        }, 0);
        node.weight += node.linksAfter.reduce((acc, after) => {
          if (after.node.columnIndex !== column.index + 1)
            return acc;
          const weight = columns[after.node.columnIndex].nodes.indexOf(after.node) * columnWeights[after.node.columnIndex];
          return Math.max(acc, weight);
        }, 0);
      }
      column.nodes.sort((a, b) => this.sortNodes(a, b));
    }
  }
  getScaleAndSpacing(columns, minSize) {
    const seriesRectHeight = this._nodeDataDependencies?.seriesRectHeight ?? 0;
    const getSizeScale = (spacing) => {
      return columns.reduce((acc, { size, nodes }) => {
        const spacingAccomodation = seriesRectHeight - nodes.length * minSize;
        const spacingOccupation = (nodes.length - 1) * spacing / spacingAccomodation;
        const columnSizeScale = (1 - spacingOccupation) / size;
        return Math.min(acc, columnSizeScale);
      }, Infinity);
    };
    let nodeSpacing = this.properties.node.spacing;
    let sizeScale = getSizeScale(nodeSpacing);
    while (sizeScale < 0 && nodeSpacing > this.properties.node.minSpacing) {
      nodeSpacing -= 1;
      sizeScale = getSizeScale(nodeSpacing);
    }
    return { nodeSpacing, sizeScale };
  }
  positionNodesInColumnsY(columns, minSize, sizeScale, nodeSpacing) {
    const seriesRectHeight = this._nodeDataDependencies?.seriesRectHeight ?? 0;
    for (const column of columns) {
      let columnNodesHeight = 0;
      for (const node of column.nodes) {
        const height2 = seriesRectHeight * node.datum.size * sizeScale;
        node.datum.height = Math.max(minSize, height2);
        columnNodesHeight += height2;
      }
      const spacingOccupation = nodeSpacing * (column.nodes.length - 1);
      let y = 0;
      if (this.properties.node.verticalAlignment === "bottom") {
        y = seriesRectHeight - columnNodesHeight - spacingOccupation;
      } else if (this.properties.node.verticalAlignment === "center") {
        y = (seriesRectHeight - columnNodesHeight - spacingOccupation) / 2;
      }
      for (const node of column.nodes) {
        node.datum.y = y;
        y += seriesRectHeight * node.datum.size * sizeScale + nodeSpacing;
        if ("ghost" in node && node.ghost) {
          node.link.elbows.push({ x: column.x, y: node.datum.y });
        }
      }
    }
  }
  sortAndPositionLinks(nodeGraph, sizeScale) {
    const seriesRectHeight = this._nodeDataDependencies?.seriesRectHeight ?? 0;
    for (const { datum, linksBefore, linksAfter } of nodeGraph.values()) {
      let y2 = datum.y;
      linksBefore.sort(
        (a, b) => this.sortNodes(a.node, b.node)
      );
      for (const { link } of linksBefore) {
        link.y2 = y2;
        y2 += link.size * seriesRectHeight * sizeScale;
      }
      let y1 = datum.y;
      linksAfter.sort(
        (a, b) => this.sortNodes(a.node, b.node, {
          invertColumnSort: true
        })
      );
      for (const { link } of linksAfter) {
        link.y1 = y1;
        y1 += link.size * seriesRectHeight * sizeScale;
      }
    }
  }
  createNodesNodeData(nodeData, nodeGraph, columns, columnWidth, measurer3, labelData) {
    for (const [index, column] of columns.entries()) {
      const leading = index === 0;
      const trailing = index === columns.length - 1;
      let bottom = -Infinity;
      column.nodes.sort((a, b) => a.datum.y - b.datum.y);
      for (const n of column.nodes) {
        if ("ghost" in n && n.ghost)
          continue;
        const { datum: node } = n;
        node.midPoint = {
          x: node.x + node.width / 2,
          y: node.y + node.height / 2
        };
        nodeData.push(node);
        bottom = this.createNodeLabelData(
          nodeGraph,
          columnWidth,
          measurer3,
          labelData,
          node,
          leading,
          trailing,
          bottom
        );
      }
    }
  }
  createNodeLabelData(nodeGraph, columnWidth, measurer3, labelData, node, leading, trailing, bottom) {
    if (node.label == null)
      return bottom;
    const {
      label: { spacing: labelSpacing, edgePlacement: edgeLabelPlacement, fontSize }
    } = this.properties;
    const seriesRectWidth = this._nodeDataDependencies?.seriesRectWidth ?? 0;
    const y = node.y + node.height / 2;
    let text2;
    if (!leading && !trailing) {
      const lineHeight = calcLineHeight(fontSize);
      const y12 = y - lineHeight;
      const y2 = y + lineHeight;
      let maxX = seriesRectWidth;
      for (const { datum } of nodeGraph.values()) {
        const intersectsLabel = datum.x > node.x && Math.max(datum.y, y12) <= Math.min(datum.y + datum.height, y2);
        if (intersectsLabel) {
          maxX = Math.min(maxX, datum.x - labelSpacing);
        }
      }
      const maxWidth = maxX - node.x - 2 * labelSpacing;
      text2 = wrapText(node.label, {
        maxWidth,
        maxHeight: node.height,
        font: this.properties.label,
        textWrap: "never",
        overflow: "hide"
      });
    }
    if (text2 == null || text2 === "") {
      const labelInset = edgeLabelPlacement == null && (leading || trailing) ? labelSpacing : labelSpacing * 2;
      text2 = wrapText(node.label, {
        maxWidth: columnWidth - labelInset,
        maxHeight: node.height,
        font: this.properties.label,
        textWrap: "never"
      });
    }
    if (text2 === "")
      return bottom;
    const { height: height2 } = measurer3.measureLines(text2);
    const y0 = y - height2 / 2;
    const y1 = y + height2 / 2;
    const { x, textAlign } = this.getNodeLabelPlacement(node, leading, trailing);
    if (y0 >= bottom) {
      labelData.push({
        x,
        y,
        textAlign,
        text: text2,
        size: node.size,
        nodeDatum: node,
        datumIndex: node.datumIndex
      });
      bottom = y1;
    }
    return bottom;
  }
  getNodeLabelPlacement(node, leading, trailing) {
    const {
      label: { spacing: labelSpacing, placement: labelPlacement, edgePlacement: edgeLabelPlacement }
    } = this.properties;
    let x = node.x + node.width + labelSpacing;
    let textAlign = "left";
    let placement = labelPlacement;
    if (leading && edgeLabelPlacement == null && labelPlacement == null) {
      placement = "left";
    }
    if (edgeLabelPlacement === "outside") {
      if (leading)
        placement = "left";
      if (trailing)
        placement = "right";
    } else if (edgeLabelPlacement === "inside") {
      if (leading)
        placement = "right";
      if (trailing)
        placement = "left";
    }
    if (placement === "left") {
      x = node.x - labelSpacing;
      textAlign = "right";
    } else if (placement === "center") {
      x = node.x + node.width / 2;
      textAlign = "center";
    }
    return { x, textAlign };
  }
  createLinksNodeData(nodeData, links, minSize, sizeScale) {
    const seriesRectHeight = this._nodeDataDependencies?.seriesRectHeight ?? 0;
    const nodeWidth = this.properties.node.width;
    for (const link of links) {
      const { fromNode, toNode, size } = link;
      link.height = Math.max(minSize, seriesRectHeight * size * sizeScale);
      link.x1 = fromNode.x + nodeWidth;
      link.x2 = toNode.x;
      link.midPoint = {
        x: (link.x1 + link.x2) / 2,
        y: (link.y1 + link.y2) / 2 + link.height / 2
      };
      nodeData.push(link);
    }
  }
  sortNodes(a, b, opts) {
    const { properties } = this;
    if (properties.node.sort === "ascending") {
      return (a.datum.label ?? "").localeCompare(b.datum.label ?? "");
    } else if (properties.node.sort === "descending") {
      return (b.datum.label ?? "").localeCompare(a.datum.label ?? "");
    } else if (properties.node.sort === "data") {
      return 0;
    }
    if (a.columnIndex < b.columnIndex)
      return opts?.invertColumnSort ? 1 : -1;
    if (a.columnIndex > b.columnIndex)
      return opts?.invertColumnSort ? -1 : 1;
    if (a.weight === b.weight) {
      return a.datum.size - b.datum.size;
    }
    if (a.closestColumnDiff < b.closestColumnDiff)
      return 1;
    if (a.closestColumnDiff > b.closestColumnDiff)
      return -1;
    return a.weight - b.weight;
  }
  updateLabelSelection(opts) {
    const labels = this.isLabelEnabled() ? opts.labelData : [];
    return opts.labelSelection.update(labels);
  }
  updateLabelNodes(opts) {
    const activeHighlightDatum = this.getHighlightedDatum();
    opts.labelSelection.each((label, datum) => {
      const { x, y, textAlign, text: text2, datumIndex, nodeDatum } = datum;
      const params = {
        fromKey: this.properties.fromKey,
        size: datum.size,
        sizeKey: this.properties.sizeKey,
        toKey: this.properties.toKey
      };
      const isHighlight = this.isLabelHighlighted(nodeDatum, activeHighlightDatum);
      const highlightStyle = this.getHighlightStyle(isHighlight, datumIndex);
      const style2 = getLabelStyles4(
        this,
        void 0,
        params,
        this.properties.label,
        isHighlight,
        activeHighlightDatum
      );
      const { color: fill, fontStyle, fontWeight: fontWeight2, fontSize, fontFamily } = style2;
      label.visible = true;
      label.x = x;
      label.y = y;
      label.text = text2;
      label.fill = fill;
      label.fontStyle = fontStyle;
      label.fontWeight = fontWeight2;
      label.fontSize = fontSize;
      label.fontFamily = fontFamily;
      label.textAlign = textAlign;
      label.textBaseline = "middle";
      const opacity = highlightStyle.opacity ?? 1;
      label.opacity = opacity;
      label.fillOpacity = opacity;
      label.setBoxing(style2);
    });
  }
  updateNodeSelection(opts) {
    return opts.datumSelection.update(opts.nodeData, void 0, (datum) => createDatumId4(datum.type, datum.id));
  }
  getNodeStyle(nodeDatum, fromNodeDatumIndex, isHighlight) {
    const { properties } = this;
    const {
      fills,
      strokes,
      defaultColorRange,
      defaultPatternFills,
      fillGradientDefaults: fillGradientDefaults3,
      fillPatternDefaults: fillPatternDefaults3,
      fillImageDefaults: fillImageDefaults3
    } = properties;
    const { itemStyler } = properties.node;
    const defaultColorStops = defaultColorRange[fromNodeDatumIndex % defaultColorRange.length].map((color2) => ({
      color: color2
    }));
    const defaultPatternFill = defaultPatternFills[fromNodeDatumIndex % defaultPatternFills.length];
    const highlightStyle = this.getHighlightStyle(isHighlight, nodeDatum.datumIndex);
    const baseStyle = mergeDefaults(highlightStyle, properties.getStyle(false, fills, strokes, fromNodeDatumIndex));
    const hasNodeFill = properties.node.fill != null;
    let style2 = getShapeStyle3(
      baseStyle,
      hasNodeFill ? fillGradientDefaults3 : { ...fillGradientDefaults3.toJson(), colorStops: defaultColorStops },
      hasNodeFill ? fillPatternDefaults3 : { ...fillPatternDefaults3.toJson(), fill: defaultPatternFill, stroke: defaultPatternFill },
      fillImageDefaults3
    );
    if (itemStyler != null && nodeDatum.datumIndex != null) {
      const overrides = this.cachedDatumCallback(
        createDatumId4(nodeDatum.datumIndex.index, "node", isHighlight ? "highlight" : "node"),
        () => {
          const params = this.makeItemStylerParams(nodeDatum, isHighlight, style2);
          return this.callWithContext(itemStyler, params);
        }
      );
      if (overrides) {
        style2 = mergeDefaults(
          overrides,
          style2,
          { ...fillGradientDefaults3.toJson(), colorStops: defaultColorStops },
          { ...fillPatternDefaults3.toJson(), fill: defaultPatternFill, stroke: defaultPatternFill },
          fillImageDefaults3
        );
      }
    }
    style2.opacity = 1;
    return style2;
  }
  makeItemStylerParams({ datum, datumIndex, size = 0, label }, isHighlight, style2) {
    const { id: seriesId } = this;
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const highlightState = this.getHighlightStateString(activeHighlight, isHighlight, datumIndex);
    const fill = this.filterItemStylerFillParams(style2.fill) ?? style2.fill;
    return {
      seriesId,
      datum,
      highlightState,
      ...style2,
      size,
      label,
      fill
    };
  }
  updateNodeNodes(opts) {
    const { datumSelection, isHighlight } = opts;
    const fillBBox = this.getShapeFillBBox();
    datumSelection.each((rect2, datum) => {
      const { datumIndex } = datum;
      const style2 = this.getNodeStyle(datum, datumIndex.index, isHighlight);
      rect2.x = datum.x;
      rect2.y = datum.y;
      rect2.width = Math.max(datum.width, 0);
      rect2.height = Math.max(datum.height, 0);
      rect2.setStyleProperties(style2, fillBBox);
    });
  }
  getShapeFillBBox() {
    const width2 = this._nodeDataDependencies?.seriesRectWidth ?? 0;
    const height2 = this._nodeDataDependencies?.seriesRectHeight ?? 0;
    const bbox = new BBox6(0, 0, width2, height2);
    return { series: bbox, axis: bbox };
  }
  updateLinkSelection(opts) {
    return opts.datumSelection.update(
      opts.nodeData,
      void 0,
      (datum) => createDatumId4(datum.type, datum.index, datum.fromNode.id, datum.toNode.id)
    );
  }
  getLinkStyle({ datumIndex, datum }, fromNodeDatumIndex, isHighlight) {
    const { id: seriesId, properties } = this;
    const {
      fills,
      strokes,
      defaultColorRange,
      defaultPatternFills,
      fillGradientDefaults: fillGradientDefaults3,
      fillPatternDefaults: fillPatternDefaults3,
      fillImageDefaults: fillImageDefaults3
    } = properties;
    const { itemStyler } = properties.link;
    const defaultColorStops = defaultColorRange[fromNodeDatumIndex.index % defaultColorRange.length].map(
      (color2) => ({
        color: color2
      })
    );
    const defaultPatternFill = defaultPatternFills[fromNodeDatumIndex.index % defaultPatternFills.length];
    const highlightStyle = this.getHighlightStyle(isHighlight, datumIndex);
    const baseStyle = mergeDefaults(
      highlightStyle,
      properties.getStyle(true, fills, strokes, fromNodeDatumIndex.index)
    );
    const hasLinkFill = properties.link.fill != null;
    let style2 = getShapeStyle3(
      baseStyle,
      hasLinkFill ? fillGradientDefaults3 : { ...fillGradientDefaults3.toJson(), colorStops: defaultColorStops },
      hasLinkFill ? fillPatternDefaults3 : { ...fillPatternDefaults3.toJson(), fill: defaultPatternFill, stroke: defaultPatternFill },
      fillImageDefaults3
    );
    if (itemStyler != null && datumIndex != null) {
      const overrides = this.cachedDatumCallback(
        createDatumId4(datumIndex.index, "link", isHighlight ? "highlight" : "node"),
        () => {
          const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
          const highlightState = this.getHighlightStateString(activeHighlight, isHighlight, datumIndex);
          return this.callWithContext(itemStyler, {
            seriesId,
            datum,
            highlightState,
            ...style2
          });
        }
      );
      if (overrides) {
        style2 = mergeDefaults(
          overrides,
          style2,
          { ...fillGradientDefaults3.toJson(), colorStops: defaultColorStops },
          { ...fillPatternDefaults3.toJson(), fill: defaultPatternFill, stroke: defaultPatternFill },
          fillImageDefaults3
        );
      }
    }
    style2.opacity = 1;
    return style2;
  }
  updateLinkNodes(opts) {
    const { datumSelection, isHighlight } = opts;
    const fillBBox = this.getShapeFillBBox();
    datumSelection.each((link, datum) => {
      const fromNodeDatumIndex = datum.fromNode.datumIndex;
      const style2 = this.getLinkStyle(datum, fromNodeDatumIndex, isHighlight);
      link.x1 = datum.x1;
      link.y1 = datum.y1;
      link.x2 = datum.x2;
      link.y2 = datum.y2;
      link.height = datum.height;
      link.elbows = datum.elbows;
      link.setStyleProperties(style2, fillBBox);
      link.inset = link.strokeWidth / 2;
    });
  }
  getTooltipContent(datumIndex) {
    const {
      id: seriesId,
      linksProcessedData,
      nodesProcessedData,
      properties,
      ctx: { formatManager }
    } = this;
    const { fromKey, toKey, sizeKey, sizeName, tooltip } = properties;
    const seriesDatum = this.contextNodeData?.nodeData.find(
      (d) => d.datumIndex.type === datumIndex.type && d.datumIndex.index === datumIndex.index
    );
    if (seriesDatum == null)
      return;
    const nodeIndex = seriesDatum.type === 0 /* Link */ ? seriesDatum.fromNode.index : seriesDatum.index;
    const title = seriesDatum.type === 0 /* Link */ ? `${seriesDatum.fromNode.label} - ${seriesDatum.toNode.label}` : seriesDatum.label;
    const datum = datumIndex.type === 0 /* Link */ ? linksProcessedData?.dataSources.get(this.id)?.data[datumIndex.index] : nodesProcessedData?.dataSources.get(this.id)?.data[datumIndex.index];
    const size = seriesDatum.size;
    let format;
    if (seriesDatum.type === 0 /* Link */) {
      const fromNodeDatumIndex = seriesDatum.fromNode.datumIndex;
      format = this.getLinkStyle({ datumIndex, datum }, fromNodeDatumIndex, false);
    } else {
      format = this.getNodeStyle({ datumIndex, datum }, datumIndex.index, false);
    }
    const data = [];
    if (sizeKey != null) {
      const content = formatManager.format(this.callWithContext.bind(this), {
        type: "number",
        value: size,
        datum,
        seriesId,
        legendItemName: void 0,
        key: sizeKey,
        source: "tooltip",
        property: "size",
        domain: [],
        boundSeries: this.getFormatterContext("size"),
        fractionDigits: void 0,
        visibleDomain: void 0
      });
      data.push({ label: sizeName, fallbackLabel: sizeKey, value: content ?? String(size) });
    }
    return this.formatTooltipWithContext(
      tooltip,
      {
        title,
        symbol: this.legendItemSymbol(seriesDatum.type, nodeIndex, format),
        data
      },
      {
        seriesId,
        datum,
        title,
        fromKey,
        toKey,
        sizeKey,
        sizeName,
        size,
        ...format
      }
    );
  }
  computeFocusBounds(node) {
    if (node instanceof Rect2) {
      const { x, y, width: width2, height: height2 } = node;
      const bbox = new BBox6(x, y, width2, height2);
      return Transformable2.toCanvas(this.contentGroup, bbox);
    }
    return node;
  }
  hasItemStylers() {
    return this.properties.node.itemStyler != null || this.properties.link.itemStyler != null || this.properties.label.itemStyler != null;
  }
};
SankeySeries.className = "SankeySeries";
SankeySeries.type = "sankey";

// packages/ag-charts-enterprise/src/series/sankey/sankeySeriesOptionsDef.ts
var { sankeySeriesThemeableOptionsDef: sankeySeriesThemeableOptionsDef2 } = module_support_exports;
var sankeySeriesOptionsDef = {
  ...sankeySeriesThemeableOptionsDef2,
  ...commonSeriesOptionsDefs,
  type: required(constant("sankey")),
  fromKey: required(string),
  toKey: required(string),
  sizeKey: string,
  sizeName: string
};
sankeySeriesOptionsDef.fillGradientDefaults = undocumented(fillGradientDefaults);
sankeySeriesOptionsDef.fillPatternDefaults = undocumented(fillPatternDefaults);
sankeySeriesOptionsDef.fillImageDefaults = undocumented(fillImageDefaults);
sankeySeriesOptionsDef.defaultColorRange = undocumented(arrayOf(arrayOf(color)));
sankeySeriesOptionsDef.defaultPatternFills = undocumented(arrayOf(color));

// packages/ag-charts-enterprise/src/series/sankey/sankeyModule.ts
var SankeySeriesModule = {
  type: "series",
  name: "sankey",
  chartType: "standalone",
  enterprise: true,
  solo: true,
  version: VERSION,
  dependencies: [StandaloneChartModule],
  options: sankeySeriesOptionsDef,
  themeTemplate: {
    seriesArea: {
      padding: {
        top: 10,
        bottom: 10
      }
    },
    series: {
      fills: { $palette: "fills" },
      strokes: { $palette: "strokes" },
      fillGradientDefaults: FILL_GRADIENT_LINEAR_DEFAULTS,
      fillPatternDefaults: FILL_PATTERN_DEFAULTS,
      fillImageDefaults: FILL_IMAGE_DEFAULTS,
      defaultColorRange: { $palette: "gradients" },
      defaultPatternFills: SAFE_FILLS_OPERATION,
      highlight: {
        unhighlightedItem: {
          opacity: 0.5
        }
      },
      label: {
        ...LABEL_BOXING_DEFAULTS,
        enabled: true,
        fontFamily: { $ref: "fontFamily" },
        fontSize: { $ref: "fontSize" },
        fontWeight: { $ref: "fontWeight" },
        color: { $ref: "textColor" },
        spacing: 10
      },
      node: {
        spacing: { $if: [{ $greaterThan: [{ $path: "./minSpacing" }, 20] }, { $path: "./minSpacing" }, 20] },
        minSpacing: 0,
        width: 10,
        strokeWidth: { $isUserOption: ["./stroke", 2, 0] }
      },
      link: {
        fillOpacity: 0.5,
        strokeWidth: { $isUserOption: ["./stroke", 2, 0] }
      }
    },
    legend: {
      enabled: false,
      toggleSeries: false
    }
  },
  create: (ctx) => new SankeySeries(ctx)
};

// packages/ag-charts-enterprise/src/series/util/labelFormatter.ts
function generateLabelSecondaryLabelFontSizeCandidates(label, secondaryLabel) {
  const { fontSize: labelFontSize, minimumFontSize: labelMinimumFontSize = labelFontSize } = label;
  const {
    fontSize: secondaryLabelFontSize,
    minimumFontSize: secondaryLabelMinimumFontSize = secondaryLabelFontSize
  } = secondaryLabel;
  const labelTracks = labelFontSize - labelMinimumFontSize;
  const secondaryLabelTracks = secondaryLabelFontSize - secondaryLabelMinimumFontSize;
  let currentLabelFontSize = label.fontSize;
  let currentSecondaryLabelFontSize = secondaryLabel.fontSize;
  const out = [{ labelFontSize, secondaryLabelFontSize }];
  while (currentLabelFontSize > labelMinimumFontSize || currentSecondaryLabelFontSize > secondaryLabelMinimumFontSize) {
    const labelProgress = labelTracks > 0 ? (currentLabelFontSize - labelMinimumFontSize) / labelTracks : -1;
    const secondaryLabelProgress = secondaryLabelTracks > 0 ? (currentSecondaryLabelFontSize - secondaryLabelMinimumFontSize) / secondaryLabelTracks : -1;
    if (labelProgress > secondaryLabelProgress) {
      currentLabelFontSize--;
    } else {
      currentSecondaryLabelFontSize--;
    }
    out.push({
      labelFontSize: currentLabelFontSize,
      secondaryLabelFontSize: currentSecondaryLabelFontSize
    });
  }
  out.reverse();
  return out;
}
function formatStackedLabels(labelValue, labelProps, secondaryLabelValue, secondaryLabelProps, { padding: padding2 }, sizeFittingHeight) {
  const { spacing = 0 } = labelProps;
  const widthAdjust = 2 * padding2;
  const heightAdjust = 2 * padding2 + spacing;
  const minimumHeight = (labelProps.minimumFontSize ?? labelProps.fontSize) + (secondaryLabelProps.minimumFontSize ?? secondaryLabelProps.fontSize);
  if (minimumHeight > sizeFittingHeight(minimumHeight + heightAdjust, false).height - heightAdjust)
    return;
  const fontSizeCandidates = generateLabelSecondaryLabelFontSizeCandidates(labelProps, secondaryLabelProps);
  const labelTextSizeProps = {
    fontFamily: labelProps.fontFamily,
    fontStyle: labelProps.fontStyle,
    fontWeight: labelProps.fontWeight
  };
  const secondaryLabelTextSizeProps = {
    fontFamily: secondaryLabelProps.fontFamily,
    fontStyle: secondaryLabelProps.fontStyle,
    fontWeight: secondaryLabelProps.fontWeight
  };
  let label;
  let secondaryLabel;
  return findMaxValue(0, fontSizeCandidates.length - 1, (index) => {
    const { labelFontSize, secondaryLabelFontSize } = fontSizeCandidates[index];
    const allowTruncation = index === 0;
    const labelFont = { ...labelTextSizeProps, fontSize: labelFontSize };
    const secondaryLabelFont = { ...secondaryLabelTextSizeProps, fontSize: secondaryLabelFontSize };
    const labelLineHeight = cachedTextMeasurer(labelFont).lineHeight();
    const secondaryLabelLineHeight = cachedTextMeasurer(secondaryLabelFont).lineHeight();
    const sizeFitting = sizeFittingHeight(
      labelLineHeight + secondaryLabelLineHeight + heightAdjust,
      allowTruncation
    );
    const availableWidth = sizeFitting.width - widthAdjust;
    const availableHeight = sizeFitting.height - heightAdjust;
    if (labelLineHeight + secondaryLabelLineHeight > availableHeight)
      return;
    if (label?.fontSize !== labelFontSize) {
      label = wrapLabel(
        labelProps,
        labelValue,
        availableWidth,
        availableHeight,
        labelFont,
        labelProps.wrapping,
        allowTruncation ? labelProps.overflowStrategy : "hide"
      );
    }
    if (label == null || label.width > availableWidth || label.height > availableHeight)
      return;
    if (secondaryLabel?.fontSize !== secondaryLabelFontSize) {
      secondaryLabel = wrapLabel(
        secondaryLabelProps,
        secondaryLabelValue,
        availableWidth,
        availableHeight,
        secondaryLabelFont,
        secondaryLabelProps.wrapping,
        allowTruncation ? secondaryLabelProps.overflowStrategy : "hide"
      );
    }
    if (secondaryLabel == null)
      return;
    const totalLabelHeight = label.height + secondaryLabel.height;
    if (secondaryLabel.width > availableWidth || totalLabelHeight > availableHeight)
      return;
    return {
      width: Math.max(label.width, secondaryLabel.width),
      height: totalLabelHeight + spacing,
      meta: sizeFitting.meta,
      label,
      secondaryLabel
    };
  });
}
function formatSingleLabel(value, props, { padding: padding2 }, sizeFittingHeight) {
  const sizeAdjust = 2 * padding2;
  const minimumFontSize = Math.min(props.minimumFontSize ?? props.fontSize, props.fontSize);
  const textSizeProps = {
    fontFamily: props.fontFamily,
    fontStyle: props.fontStyle,
    fontWeight: props.fontWeight
  };
  return findMaxValue(minimumFontSize, props.fontSize, (fontSize) => {
    const currentFont = { ...textSizeProps, fontSize };
    const measurer3 = cachedTextMeasurer(currentFont);
    const allowTruncation = fontSize === minimumFontSize;
    const lineHeight = props.lineHeight ?? measurer3.lineHeight();
    const sizeFitting = sizeFittingHeight(lineHeight + sizeAdjust, allowTruncation);
    const availableWidth = sizeFitting.width - sizeAdjust;
    const availableHeight = sizeFitting.height - sizeAdjust;
    if (lineHeight > availableHeight || availableWidth < 0)
      return;
    const lines = wrapLines(value, {
      maxWidth: availableWidth,
      maxHeight: availableHeight,
      font: currentFont,
      textWrap: props.wrapping,
      overflow: (allowTruncation ? props.overflowStrategy : null) ?? "hide"
    });
    if (!lines.length)
      return;
    const { width: width2, height: height2 } = measurer3.measureLines(lines);
    const text2 = lines.join("\n");
    return [{ width: width2, height: height2, text: text2, fontSize, lineHeight }, sizeFitting.meta];
  });
}
function hasInvalidFontSize(label) {
  return label?.minimumFontSize != null && label?.fontSize != null && label?.minimumFontSize > label?.fontSize;
}
function formatLabels(baseLabelValue, labelProps, baseSecondaryLabelValue, secondaryLabelProps, layoutParams, sizeFittingHeight) {
  const labelValue = labelProps.enabled ? baseLabelValue : void 0;
  const secondaryLabelValue = secondaryLabelProps.enabled ? baseSecondaryLabelValue : void 0;
  if (hasInvalidFontSize(labelProps) || hasInvalidFontSize(secondaryLabelProps)) {
    logger_exports.warnOnce(`minimumFontSize should be set to a value less than or equal to the font size`);
  }
  let value;
  if (labelValue != null && secondaryLabelValue != null) {
    value = formatStackedLabels(
      labelValue,
      labelProps,
      secondaryLabelValue,
      secondaryLabelProps,
      layoutParams,
      sizeFittingHeight
    );
  }
  let labelMeta;
  if (value == null && labelValue != null) {
    labelMeta = formatSingleLabel(labelValue, labelProps, layoutParams, sizeFittingHeight);
  }
  if (labelMeta != null) {
    const [label, meta] = labelMeta;
    value = {
      width: label.width,
      height: label.height,
      meta,
      label,
      secondaryLabel: void 0
    };
  }
  let secondaryLabelMeta;
  if (value == null && labelValue == null && secondaryLabelValue != null) {
    secondaryLabelMeta = formatSingleLabel(
      secondaryLabelValue,
      secondaryLabelProps,
      layoutParams,
      sizeFittingHeight
    );
  }
  if (secondaryLabelMeta != null) {
    const [secondaryLabel, meta] = secondaryLabelMeta;
    value = {
      width: secondaryLabel.width,
      height: secondaryLabel.height,
      meta,
      label: void 0,
      secondaryLabel
    };
  }
  return value;
}
function wrapLabel(props, text2, maxWidth, maxHeight, font3, textWrap2, overflow) {
  const lines = wrapLines(text2, { maxWidth, maxHeight, font: font3, textWrap: textWrap2, overflow });
  if (!lines.length)
    return;
  const measurer3 = cachedTextMeasurer(font3);
  const lineHeight = props.lineHeight ?? measurer3.lineHeight();
  const { width: width2 } = measurer3.measureLines(lines);
  return {
    width: width2,
    lineHeight,
    text: lines.join("\n"),
    height: lines.length * lineHeight,
    fontSize: font3.fontSize
  };
}

// packages/ag-charts-enterprise/src/series/util/autoSizedLabel.ts
var BaseAutoSizedLabel = class extends module_support_exports.Label {
  constructor() {
    super(...arguments);
    this.wrapping = "on-space";
    this.overflowStrategy = "ellipsis";
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], BaseAutoSizedLabel.prototype, "wrapping", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BaseAutoSizedLabel.prototype, "overflowStrategy", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BaseAutoSizedLabel.prototype, "lineHeight", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BaseAutoSizedLabel.prototype, "minimumFontSize", 2);
var AutoSizedLabel = class extends BaseAutoSizedLabel {
  constructor() {
    super(...arguments);
    this.spacing = 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], AutoSizedLabel.prototype, "spacing", 2);
var AutoSizedSecondaryLabel = class extends BaseAutoSizedLabel {
};

// packages/ag-charts-enterprise/src/series/sunburst/sunburstSeriesProperties.ts
var { HierarchySeriesProperties: HierarchySeriesProperties2, makeSeriesTooltip: makeSeriesTooltip5, HighlightProperties: HighlightProperties2 } = module_support_exports;
var SunburstSeriesHighlightStyle = class extends BaseProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesHighlightStyle.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesHighlightStyle.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesHighlightStyle.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesHighlightStyle.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesHighlightStyle.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesHighlightStyle.prototype, "opacity", 2);
var SunburstSeriesHighlight = class extends HighlightProperties2 {
  constructor() {
    super(...arguments);
    this.highlightedBranch = new SunburstSeriesHighlightStyle();
    this.unhighlightedBranch = new SunburstSeriesHighlightStyle();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesHighlight.prototype, "highlightedBranch", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesHighlight.prototype, "unhighlightedBranch", 2);
var SunburstSeriesProperties = class extends HierarchySeriesProperties2 {
  constructor() {
    super(...arguments);
    this.fillOpacity = 1;
    this.strokeWidth = 0;
    this.strokeOpacity = 1;
    this.cornerRadius = 0;
    this.highlight = new SunburstSeriesHighlight();
    this.label = new AutoSizedLabel();
    this.secondaryLabel = new AutoSizedSecondaryLabel();
    this.tooltip = makeSeriesTooltip5();
  }
  getStyle(index) {
    const { fills, strokes, fillOpacity, strokeWidth, strokeOpacity } = this;
    return {
      fill: fills[index % fills.length],
      fillOpacity,
      stroke: strokes[index % strokes.length],
      strokeWidth,
      strokeOpacity,
      opacity: 1
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesProperties.prototype, "sizeName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesProperties.prototype, "labelKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesProperties.prototype, "secondaryLabelKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesProperties.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesProperties.prototype, "sectorSpacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesProperties.prototype, "padding", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesProperties.prototype, "itemStyler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesProperties.prototype, "highlight", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesProperties.prototype, "secondaryLabel", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SunburstSeriesProperties.prototype, "tooltip", 2);

// packages/ag-charts-enterprise/src/series/sunburst/sunburstSeries.ts
var {
  fromToMotion: fromToMotion3,
  createDatumId: createDatumId5,
  PointerEvents: PointerEvents3,
  Sector: Sector3,
  Group: Group6,
  ScalableGroup: ScalableGroup2,
  Selection: Selection4,
  TransformableText: TransformableText3,
  BBox: BBox7,
  getLabelStyles: getLabelStyles5,
  toHierarchyHighlightString: toHierarchyHighlightString2
} = module_support_exports;
var SunburstNode = class extends module_support_exports.HierarchyNode {
  constructor() {
    super(...arguments);
    this.label = void 0;
    this.secondaryLabel = void 0;
    this.contentHeight = 0;
    this.bbox = void 0;
    // cspell:ignore bbox
    this.startAngle = 0;
    this.endAngle = 0;
  }
};
function setAngleData(node, startAngle = 0, angleScale = 2 * Math.PI / node.sumSize) {
  for (const child of node.children) {
    const endAngle = startAngle + child.sumSize * angleScale;
    child.startAngle = startAngle;
    child.endAngle = endAngle;
    setAngleData(child, startAngle, angleScale);
    startAngle = endAngle;
  }
}
var SunburstSeries = class extends module_support_exports.HierarchySeries {
  constructor(moduleCtx) {
    super(moduleCtx);
    this.NodeClass = SunburstNode;
    this.properties = new SunburstSeriesProperties();
    this.scalingGroup = this.contentGroup.appendChild(new ScalableGroup2());
    this.sectorGroup = this.scalingGroup.appendChild(new Group6());
    this.highlightSectorGroup = this.scalingGroup.appendChild(new Group6());
    this.sectorLabelGroup = this.scalingGroup.appendChild(new Group6());
    this.datumSelection = Selection4.select(this.sectorGroup, Sector3);
    this.labelSelection = Selection4.select(
      this.sectorLabelGroup,
      Group6
    );
    this.highlightSelection = Selection4.select(
      this.highlightSectorGroup,
      Sector3
    );
    this.sectorLabelGroup.pointerEvents = PointerEvents3.None;
  }
  processData() {
    super.processData();
    setAngleData(this.rootNode);
  }
  updateSelections() {
    const highlightedNode = this.getActiveHighlightNode();
    this.highlightSelection.update(
      highlightedNode == null ? [] : [highlightedNode],
      void 0,
      (node) => this.getDatumId(node)
    );
    if (!this.nodeDataRefresh)
      return;
    this.nodeDataRefresh = false;
    const { chart } = this;
    if (chart == null)
      return;
    const seriesRect = chart.seriesRect;
    if (seriesRect == null)
      return;
    const descendants = Array.from(this.rootNode);
    const updateLabelGroup = (group) => {
      group.append([
        new TransformableText3({ tag: 0 /* Primary */ }),
        new TransformableText3({ tag: 1 /* Secondary */ })
      ]);
    };
    this.datumSelection.update(descendants, void 0, (node) => this.getDatumId(node));
    this.labelSelection.update(descendants, updateLabelGroup, (node) => this.getDatumId(node));
  }
  getItemStyle(nodeDatum, isHighlight) {
    const { properties, colorScale } = this;
    const { itemStyler } = properties;
    const rootIndex = nodeDatum.datumIndex?.[0] ?? 0;
    const highlightedNode = this.getActiveHighlightNode();
    const highlightState = this.getHierarchyHighlightState(isHighlight, highlightedNode, nodeDatum);
    const highlightStyles = this.getHierarchyHighlightStyles(highlightState, this.properties.highlight);
    const baseStyle = mergeDefaults(highlightStyles, properties.getStyle(rootIndex));
    if (nodeDatum.colorValue != null && highlightStyles?.fill == null) {
      baseStyle.fill = colorScale.convert(nodeDatum.colorValue);
    }
    let style2 = baseStyle;
    if (itemStyler != null && nodeDatum != null) {
      const overrides = this.cachedDatumCallback(
        createDatumId5(this.getDatumId(nodeDatum), isHighlight ? "highlight" : "node"),
        () => {
          const params = this.makeItemStylerParams(
            nodeDatum,
            style2,
            toHierarchyHighlightString2(highlightState)
          );
          return this.callWithContext(itemStyler, params);
        }
      );
      if (overrides) {
        style2 = mergeDefaults(overrides, style2);
      }
    }
    return style2;
  }
  makeItemStylerParams(nodeDatum, style2, highlightState) {
    const { id: seriesId } = this;
    const fill = this.filterItemStylerFillParams(style2.fill) ?? style2.fill;
    return {
      seriesId,
      datum: nodeDatum.datum,
      depth: nodeDatum.depth ?? 0,
      highlightState,
      ...style2,
      fill
    };
  }
  updateNodes() {
    const { chart, data, maxDepth } = this;
    if (chart == null || data == null) {
      return;
    }
    const { width: width2, height: height2 } = chart.seriesRect;
    const {
      sectorSpacing = 0,
      padding: padding2 = 0,
      cornerRadius,
      childrenKey,
      colorKey,
      colorName,
      labelKey,
      secondaryLabelKey,
      sizeKey,
      sizeName
    } = this.properties;
    this.contentGroup.translationX = width2 / 2;
    this.contentGroup.translationY = height2 / 2;
    const baseInset = sectorSpacing * 0.5;
    const radius = Math.min(width2, height2) / 2;
    const radiusScale = radius / (maxDepth + 1);
    const angleOffset = -Math.PI / 2;
    const seriesFillBBox = {
      series: new BBox7(-radius, -radius, 2 * radius, 2 * radius),
      axis: new BBox7(-radius, -radius, 2 * radius, 2 * radius)
    };
    this.rootNode?.walk((node) => {
      const { startAngle, endAngle } = node;
      if (node.depth != null) {
        const midAngle = (startAngle + endAngle) / 2 + angleOffset;
        const midRadius = (node.depth + 0.5) * radiusScale;
        node.midPoint.x = Math.cos(midAngle) * midRadius;
        node.midPoint.y = Math.sin(midAngle) * midRadius;
      }
    });
    this.rootNode?.walk((node) => {
      const { datum, depth, startAngle, endAngle, parent, sumSize } = node;
      node.label = void 0;
      node.secondaryLabel = void 0;
      node.contentHeight = 0;
      let labelValue;
      if (datum != null && depth != null && labelKey != null) {
        const value = datum[labelKey];
        labelValue = this.getLabelText(
          value,
          datum,
          labelKey,
          "label",
          [],
          this.properties.label,
          {
            depth,
            datum,
            childrenKey,
            colorKey,
            colorName,
            labelKey,
            secondaryLabelKey,
            sizeKey,
            sizeName,
            value
          }
        );
      }
      if (labelValue === "") {
        labelValue = void 0;
      }
      let secondaryLabelValue;
      if (datum != null && depth != null && secondaryLabelKey != null) {
        const value = datum[secondaryLabelKey];
        secondaryLabelValue = this.getLabelText(
          value,
          datum,
          secondaryLabelKey,
          "secondaryLabel",
          [],
          this.properties.secondaryLabel,
          {
            depth,
            datum,
            childrenKey,
            colorKey,
            colorName,
            labelKey,
            secondaryLabelKey,
            sizeKey,
            sizeName,
            value
          }
        );
      }
      if (secondaryLabelValue === "") {
        secondaryLabelValue = void 0;
      }
      if (depth == null)
        return;
      const innerRadius = depth * radiusScale + baseInset;
      const outerRadius = (depth + 1) * radiusScale - baseInset;
      const innerAngleOffset = innerRadius > baseInset ? baseInset / innerRadius : baseInset;
      const outerAngleOffset = outerRadius > baseInset ? baseInset / outerRadius : baseInset;
      const innerStartAngle = startAngle + innerAngleOffset;
      const innerEndAngle = endAngle + innerAngleOffset;
      const deltaInnerAngle = innerEndAngle - innerStartAngle;
      const outerStartAngle = startAngle + outerAngleOffset;
      const outerEndAngle = endAngle + outerAngleOffset;
      const deltaOuterAngle = outerEndAngle - outerStartAngle;
      const sizeFittingHeight = (labelHeight2) => {
        const isCenterCircle = depth === 0 && parent?.sumSize === sumSize;
        if (isCenterCircle) {
          const labelWidth2 = 2 * Math.sqrt(outerRadius ** 2 - (labelHeight2 * 0.5) ** 2);
          return { width: labelWidth2, height: labelHeight2, meta: 0 /* CenterCircle */ };
        }
        const parallelHeight = labelHeight2;
        const availableWidthUntilItHitsTheOuterRadius = 2 * Math.sqrt(outerRadius ** 2 - (innerRadius + parallelHeight) ** 2);
        const availableWidthUntilItHitsTheStraightEdges = deltaInnerAngle < Math.PI ? 2 * innerRadius * Math.tan(deltaInnerAngle * 0.5) : Infinity;
        const parallelWidth = Math.min(
          availableWidthUntilItHitsTheOuterRadius,
          availableWidthUntilItHitsTheStraightEdges
        );
        const maxPerpendicularAngle = Math.PI / 4;
        let perpendicularHeight;
        let perpendicularWidth;
        if (depth === 0) {
          perpendicularHeight = labelHeight2;
          perpendicularWidth = Math.sqrt(outerRadius ** 2 - (perpendicularHeight / 2) ** 2) - labelHeight2 / (2 * Math.tan(deltaOuterAngle * 0.5));
        } else if (normalizeAngle360(deltaInnerAngle) < maxPerpendicularAngle) {
          perpendicularHeight = 2 * innerRadius * Math.tan(deltaInnerAngle * 0.5);
          perpendicularWidth = Math.sqrt(outerRadius ** 2 - (perpendicularHeight / 2) ** 2) - innerRadius;
        } else {
          perpendicularWidth = 0;
          perpendicularHeight = 0;
        }
        return parallelWidth >= perpendicularWidth ? { width: parallelWidth, height: parallelHeight, meta: 1 /* Parallel */ } : { width: perpendicularWidth, height: perpendicularHeight, meta: 2 /* Perpendicular */ };
      };
      const formatting = formatLabels(
        toPlainText(labelValue),
        this.properties.label,
        toPlainText(secondaryLabelValue),
        this.properties.secondaryLabel,
        { padding: padding2 },
        sizeFittingHeight
      );
      if (formatting == null)
        return;
      const { width: labelWidth, height: labelHeight, meta: labelPlacement, label, secondaryLabel } = formatting;
      const theta = angleOffset + (startAngle + endAngle) / 2;
      const top = Math.sin(theta) >= 0;
      const right = Math.cos(theta) >= 0;
      const circleQuarter = (top ? 3 /* Top */ : 12 /* Bottom */) & (right ? 6 /* Right */ : 9 /* Left */);
      let labelRadius;
      switch (labelPlacement) {
        case 0 /* CenterCircle */:
          labelRadius = 0;
          break;
        case 1 /* Parallel */: {
          const opticalCentering = 0.58;
          const idealRadius = outerRadius - (radiusScale - labelHeight) * opticalCentering;
          const maximumRadius = Math.sqrt((outerRadius - padding2) ** 2 - (labelWidth / 2) ** 2);
          labelRadius = Math.min(idealRadius, maximumRadius);
          break;
        }
        case 2 /* Perpendicular */:
          if (depth === 0) {
            const minimumRadius = labelHeight / (2 * Math.tan(deltaInnerAngle * 0.5)) + labelWidth * 0.5;
            const maximumRadius = Math.sqrt(outerRadius ** 2 - (labelHeight * 0.5) ** 2) - labelWidth * 0.5;
            labelRadius = (minimumRadius + maximumRadius) * 0.5;
          } else {
            labelRadius = (innerRadius + outerRadius) * 0.5;
          }
          break;
      }
      if (label != null) {
        const {
          fontStyle = "normal",
          fontFamily,
          fontWeight: fontWeight2 = "normal",
          color: color2 = "black"
        } = this.properties.label;
        node.label = {
          ...label,
          fontStyle,
          fontFamily,
          fontWeight: fontWeight2,
          color: color2,
          labelPlacement,
          circleQuarter,
          radius: labelRadius,
          theta
        };
      }
      if (secondaryLabel != null) {
        const {
          fontStyle = "normal",
          fontFamily,
          fontWeight: fontWeight2 = "normal",
          color: color2 = "black"
        } = this.properties.secondaryLabel;
        node.secondaryLabel = {
          ...secondaryLabel,
          fontStyle,
          fontFamily,
          fontWeight: fontWeight2,
          color: color2,
          labelPlacement,
          circleQuarter,
          radius: labelRadius,
          theta
        };
      }
      node.contentHeight = formatting.height;
    });
    const updateSector = (nodeDatum, sector, highlighted) => {
      const { depth, startAngle, endAngle } = nodeDatum;
      if (depth == null) {
        sector.visible = false;
        return;
      }
      sector.visible = true;
      const style2 = this.getItemStyle(nodeDatum, highlighted);
      const fill = style2.fill;
      const strokeWidth = style2.strokeWidth;
      const fillBBox = isGradientFill(fill) && fill.bounds !== "item" ? seriesFillBBox : void 0;
      sector.setStyleProperties(style2, fillBBox);
      sector.centerX = 0;
      sector.centerY = 0;
      sector.innerRadius = depth * radiusScale;
      sector.outerRadius = (depth + 1) * radiusScale;
      sector.startAngle = startAngle + angleOffset;
      sector.endAngle = endAngle + angleOffset;
      sector.inset = baseInset + strokeWidth * 0.5;
      sector.cornerRadius = cornerRadius;
    };
    this.datumSelection.each((sector, datum) => {
      updateSector(datum, sector, false);
    });
    this.highlightSelection.each((rect2, datum) => {
      updateSector(datum, rect2, true);
    });
    const highlightedNode = this.getActiveHighlightNode();
    const updateText = (node, text2, tag, highlighted) => {
      const { depth, contentHeight } = node;
      const primary = tag === 0 /* Primary */;
      const label = primary ? node.label : node.secondaryLabel;
      if (depth == null || label == null) {
        text2.visible = false;
        return;
      }
      const { labelPlacement, circleQuarter, radius: textRadius, theta } = label;
      const highlightState = this.getHierarchyHighlightState(highlighted, highlightedNode, node);
      const { opacity: highlightOpacity } = this.getHierarchyHighlightStyles(highlightState, this.properties.highlight) ?? {};
      const params = {
        childrenKey: this.properties.childrenKey,
        colorKey: this.properties.colorKey,
        colorName: this.properties.colorName ?? this.properties.colorKey,
        depth: node.depth ?? Number.NaN,
        labelKey: this.properties.labelKey,
        secondaryLabelKey: this.properties.secondaryLabelKey,
        sizeKey: this.properties.sizeKey,
        sizeName: this.properties.sizeName ?? this.properties.sizeKey
      };
      const baseLabelStyle = primary ? this.properties.label : this.properties.secondaryLabel;
      const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
      const style2 = getLabelStyles5(this, node, params, baseLabelStyle, highlighted, activeHighlight);
      text2.text = label.text;
      text2.fontSize = label.fontSize;
      text2.lineHeight = label.lineHeight;
      text2.fontStyle = label.fontStyle;
      text2.fontFamily = label.fontFamily;
      text2.fontWeight = label.fontWeight;
      text2.fillOpacity = highlightOpacity ?? 1;
      text2.fill = style2.color;
      text2.setBoxing(style2);
      switch (labelPlacement) {
        case 0 /* CenterCircle */:
          text2.textAlign = "center";
          text2.textBaseline = "top";
          text2.translationX = 0;
          text2.translationY = (primary ? 0 : contentHeight - label.height) - contentHeight * 0.5;
          text2.rotation = 0;
          break;
        case 1 /* Parallel */: {
          const topHalf = (circleQuarter & 3 /* Top */) !== 0;
          const translationRadius = primary === !topHalf ? textRadius : textRadius - (contentHeight - label.height);
          text2.textAlign = "center";
          text2.textBaseline = topHalf ? "bottom" : "top";
          text2.translationX = Math.cos(theta) * translationRadius;
          text2.translationY = Math.sin(theta) * translationRadius;
          text2.rotation = topHalf ? theta - Math.PI * 0.5 : theta + Math.PI * 0.5;
          break;
        }
        case 2 /* Perpendicular */: {
          const rightHalf = (circleQuarter & 6 /* Right */) !== 0;
          const translation = primary === !rightHalf ? (contentHeight - label.height) * 0.5 : (label.height - contentHeight) * 0.5;
          text2.textAlign = "center";
          text2.textBaseline = "middle";
          text2.translationX = Math.cos(theta) * textRadius + Math.cos(theta + Math.PI / 2) * translation;
          text2.translationY = Math.sin(theta) * textRadius + Math.sin(theta + Math.PI / 2) * translation;
          text2.rotation = rightHalf ? theta : theta + Math.PI;
          break;
        }
      }
      text2.visible = true;
    };
    const highlightedDatum = this.getActiveHighlightNode();
    for (const text2 of this.labelSelection.selectByClass(TransformableText3)) {
      const datum = text2.closestDatum();
      updateText(datum, text2, text2.tag, datum === highlightedDatum);
    }
  }
  getTooltipContent(datumIndex) {
    const { id: seriesId, properties, ctx } = this;
    const { labelKey, secondaryLabelKey, childrenKey, sizeKey, sizeName, colorKey, colorName, tooltip } = properties;
    const { formatManager } = ctx;
    const nodeDatum = datumIndex.reduce((n, i) => n?.children[i], this.rootNode);
    if (nodeDatum == null)
      return;
    const { datum, depth } = nodeDatum;
    if (datum == null || depth == null)
      return;
    const data = [];
    const datumSize = sizeKey == null ? void 0 : datum[sizeKey];
    if (datumSize != null) {
      const sizeDomain = [0, this.rootNode?.sumSize ?? 0];
      const content = formatManager.format(this.callWithContext.bind(this), {
        type: "number",
        value: datumSize,
        datum,
        seriesId,
        legendItemName: void 0,
        key: sizeKey,
        source: "tooltip",
        property: "size",
        boundSeries: this.getFormatterContext("size"),
        domain: sizeDomain,
        fractionDigits: void 0,
        visibleDomain: void 0
      });
      data.push({ label: sizeName, fallbackLabel: sizeKey, value: content ?? formatValue(datumSize) });
    }
    const datumColor = colorKey == null ? void 0 : datum[colorKey];
    if (datumColor != null) {
      const { colorDomain } = this;
      const content = formatManager.format(this.callWithContext.bind(this), {
        type: "number",
        value: datumColor,
        datum,
        seriesId,
        legendItemName: void 0,
        key: colorKey,
        source: "tooltip",
        property: "color",
        boundSeries: this.getFormatterContext("color"),
        domain: colorDomain,
        fractionDigits: void 0,
        visibleDomain: void 0
      });
      data.push({ label: colorName, fallbackLabel: colorKey, value: content ?? formatValue(datumColor) });
    }
    const format = this.getItemStyle(
      { ...nodeDatum, colorValue: datumColor ?? nodeDatum.colorValue },
      false
    );
    const color2 = format.fill;
    const markerStyle = {
      shape: "square",
      fill: color2,
      fillOpacity: 1,
      stroke: void 0,
      strokeWidth: 0,
      strokeOpacity: 1,
      lineDash: [0],
      lineDashOffset: 0
    };
    if (isGradientFill(markerStyle.fill)) {
      markerStyle.fill = { ...markerStyle.fill, gradient: "linear", rotation: 0, reverse: false };
    }
    return this.formatTooltipWithContext(
      tooltip,
      {
        title: labelKey == null ? void 0 : datum[labelKey],
        symbol: {
          marker: markerStyle
        },
        data
      },
      {
        seriesId,
        datum,
        title: void 0,
        depth,
        labelKey,
        secondaryLabelKey,
        childrenKey,
        sizeKey,
        sizeName,
        colorKey,
        colorName,
        ...format
      }
    );
  }
  createNodeData() {
    return void 0;
  }
  pickNodeClosestDatum(point) {
    return this.pickNodeNearestDistantObject(point, this.datumSelection.nodes());
  }
  animateEmptyUpdateReady() {
    fromToMotion3(this.id, "nodes", this.ctx.animationManager, [this.scalingGroup], {
      toFn() {
        return { scalingX: 1, scalingY: 1 };
      },
      fromFn() {
        return { scalingX: 0, scalingY: 0 };
      }
    });
  }
  computeFocusBounds(node) {
    return node;
  }
  hasItemStylers() {
    return this.properties.itemStyler != null || this.properties.label.itemStyler != null;
  }
};
SunburstSeries.className = "SunburstSeries";
SunburstSeries.type = "sunburst";

// packages/ag-charts-enterprise/src/series/sunburst/sunburstSeriesOptionsDef.ts
var { sunburstSeriesThemeableOptionsDef: sunburstSeriesThemeableOptionsDef2 } = module_support_exports;
var sunburstSeriesOptionsDef = {
  ...sunburstSeriesThemeableOptionsDef2,
  ...without(commonSeriesOptionsDefs, ["highlightStyle", "highlight", "showInLegend"]),
  type: required(constant("sunburst")),
  labelKey: string,
  secondaryLabelKey: string,
  childrenKey: string,
  sizeKey: string,
  colorKey: string,
  sizeName: string,
  colorName: string
};

// packages/ag-charts-enterprise/src/series/sunburst/sunburstModule.ts
var themeTemplate7 = {
  series: {
    fills: {
      $applyCycle: [
        { $size: { $path: ["./data", { $path: "/data" }] } },
        { $palette: "fills" },
        {
          $applySwitch: [
            { $path: ["/type", void 0, { $value: "$1" }] },
            { $value: "$1" },
            ["gradient", FILL_GRADIENT_RADIAL_REVERSED_SERIES_DEFAULTS],
            ["pattern", FILL_PATTERN_DEFAULTS],
            ["image", FILL_IMAGE_DEFAULTS]
          ]
        }
      ]
    },
    strokes: {
      $applyCycle: [{ $size: { $path: ["./data", { $path: "/data" }] } }, { $palette: "strokes" }]
    },
    colorRange: { $palette: "divergingColors" },
    strokeWidth: { $isUserOption: ["./strokes/0", 2, 0] },
    label: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: true,
      fontFamily: { $ref: "fontFamily" },
      fontSize: { $rem: FONT_SIZE_RATIO.LARGE },
      minimumFontSize: { $rem: 9 / BASE_FONT_SIZE },
      fontWeight: { $ref: "fontWeight" },
      color: { $ref: "chartBackgroundColor" },
      overflowStrategy: "ellipsis",
      wrapping: "never",
      spacing: 2
    },
    secondaryLabel: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: true,
      fontFamily: { $ref: "fontFamily" },
      fontSize: { $rem: FONT_SIZE_RATIO.SMALLEST },
      minimumFontSize: { $rem: 7 / BASE_FONT_SIZE },
      fontWeight: { $ref: "fontWeight" },
      color: { $ref: "chartBackgroundColor" },
      overflowStrategy: "ellipsis",
      wrapping: "never"
    },
    sectorSpacing: 2,
    padding: 3,
    highlight: {
      unhighlightedItem: {
        fillOpacity: 0.6,
        strokeOpacity: 0.6
      },
      unhighlightedBranch: {
        fillOpacity: 0.2,
        strokeOpacity: 0.2
      }
    }
  },
  gradientLegend: {
    enabled: { $if: [{ $path: "../series/0/colorKey" }, true, false] }
  }
};
var SunburstSeriesModule = {
  type: "series",
  name: "sunburst",
  chartType: "standalone",
  enterprise: true,
  solo: true,
  version: VERSION,
  dependencies: [StandaloneChartModule],
  options: sunburstSeriesOptionsDef,
  themeTemplate: themeTemplate7,
  create: (ctx) => new SunburstSeries(ctx)
};

// packages/ag-charts-enterprise/src/series/treemap/treemapSeriesProperties.ts
var { HierarchySeriesProperties: HierarchySeriesProperties3, makeSeriesTooltip: makeSeriesTooltip6, Label: Label6 } = module_support_exports;
var TreemapGroupLabel = class extends Label6 {
  constructor() {
    super(...arguments);
    this.spacing = 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapGroupLabel.prototype, "spacing", 2);
var TreemapSeriesGroupHighlightStyle = class extends BaseProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroupHighlightStyle.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroupHighlightStyle.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroupHighlightStyle.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroupHighlightStyle.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroupHighlightStyle.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroupHighlightStyle.prototype, "opacity", 2);
var TreemapSeriesGroupHighlight = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.highlightedItem = new TreemapSeriesGroupHighlightStyle();
    this.unhighlightedItem = new TreemapSeriesGroupHighlightStyle();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroupHighlight.prototype, "highlightedItem", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroupHighlight.prototype, "unhighlightedItem", 2);
var TreemapSeriesTileHighlightStyle = class extends BaseProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTileHighlightStyle.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTileHighlightStyle.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTileHighlightStyle.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTileHighlightStyle.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTileHighlightStyle.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTileHighlightStyle.prototype, "opacity", 2);
var TreemapSeriesTileHighlight = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.highlightedBranch = new TreemapSeriesTileHighlightStyle();
    this.highlightedItem = new TreemapSeriesTileHighlightStyle();
    this.unhighlightedItem = new TreemapSeriesTileHighlightStyle();
    this.unhighlightedBranch = new TreemapSeriesTileHighlightStyle();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTileHighlight.prototype, "highlightedBranch", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTileHighlight.prototype, "highlightedItem", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTileHighlight.prototype, "unhighlightedItem", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTileHighlight.prototype, "unhighlightedBranch", 2);
var TreemapSeriesGroup = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.fill = void 0;
    this.fillOpacity = 1;
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.cornerRadius = 0;
    this.textAlign = "center";
    this.gap = 0;
    this.padding = 0;
    this.interactive = true;
    this.label = new TreemapGroupLabel();
    this.highlight = new TreemapSeriesGroupHighlight();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroup.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroup.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroup.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroup.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroup.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroup.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroup.prototype, "textAlign", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroup.prototype, "gap", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroup.prototype, "padding", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroup.prototype, "interactive", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroup.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesGroup.prototype, "highlight", 2);
var TreemapSeriesTile = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.fill = void 0;
    this.fillOpacity = 1;
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.cornerRadius = 0;
    this.textAlign = "center";
    this.verticalAlign = "middle";
    this.gap = 0;
    this.padding = 0;
    this.label = new AutoSizedLabel();
    this.secondaryLabel = new AutoSizedSecondaryLabel();
    this.highlight = new TreemapSeriesTileHighlight();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTile.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTile.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTile.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTile.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTile.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTile.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTile.prototype, "textAlign", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTile.prototype, "verticalAlign", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTile.prototype, "gap", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTile.prototype, "padding", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTile.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTile.prototype, "secondaryLabel", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesTile.prototype, "highlight", 2);
var TreemapSeriesProperties = class extends HierarchySeriesProperties3 {
  constructor() {
    super(...arguments);
    this.tooltip = makeSeriesTooltip6();
    this.group = new TreemapSeriesGroup();
    this.tile = new TreemapSeriesTile();
    this.undocumentedGroupFills = [];
    this.undocumentedGroupStrokes = [];
  }
  getStyle(isLeaf, fills, strokes, index) {
    const {
      fillOpacity,
      strokeWidth,
      strokeOpacity,
      fill = isLeaf ? fills[index % fills.length] : fills[Math.min(index, fills.length)],
      stroke: stroke3 = isLeaf ? strokes[index % fills.length] : strokes[Math.min(index, strokes.length)]
    } = isLeaf ? this.tile : this.group;
    return {
      fill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      opacity: 1
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesProperties.prototype, "sizeName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesProperties.prototype, "labelKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesProperties.prototype, "secondaryLabelKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesProperties.prototype, "itemStyler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesProperties.prototype, "tooltip", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesProperties.prototype, "group", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesProperties.prototype, "tile", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesProperties.prototype, "undocumentedGroupFills", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], TreemapSeriesProperties.prototype, "undocumentedGroupStrokes", 2);

// packages/ag-charts-enterprise/src/series/treemap/treemapSeries.ts
var {
  createDatumId: createDatumId6,
  Rect: Rect3,
  Group: Group7,
  BBox: BBox8,
  Selection: Selection5,
  Text: Text3,
  Transformable: Transformable3,
  getLabelStyles: getLabelStyles6,
  HierarchyHighlightState: HierarchyHighlightState2,
  toHierarchyHighlightString: toHierarchyHighlightString3
} = module_support_exports;
var TreemapNode = class extends module_support_exports.HierarchyNode {
  constructor() {
    super(...arguments);
    this.labelValue = void 0;
    this.secondaryLabelValue = void 0;
    this.label = void 0;
    this.secondaryLabel = void 0;
    this.bbox = void 0;
    this.padding = void 0;
  }
};
function nodeSize(node) {
  return node.children.length > 0 ? node.sumSize - node.sizeValue : node.sizeValue;
}
var textAlignFactors = {
  left: 0,
  center: 0.5,
  right: 1
};
var verticalAlignFactors = {
  top: 0,
  middle: 0.5,
  bottom: 1
};
var DistantGroup = class extends module_support_exports.Group {
  distanceSquared(x, y) {
    return this.getBBox().distanceSquared(x, y);
  }
};
var TreemapSeries = class extends module_support_exports.HierarchySeries {
  constructor() {
    super(...arguments);
    this.NodeClass = TreemapNode;
    this.properties = new TreemapSeriesProperties();
    this.rectGroup = this.contentGroup.appendChild(new Group7());
    this.datumSelection = Selection5.select(this.rectGroup, Rect3);
    this.labelSelection = Selection5.select(this.labelGroup, Group7);
    this.highlightSelection = Selection5.select(
      this.rectGroup,
      Rect3
    );
  }
  groupTitleHeight(node, bbox) {
    const heightRatioThreshold = 3;
    const { label } = this.properties.group;
    const { labelValue } = node;
    const { fontSize } = label;
    if (label.enabled && labelValue != null && fontSize <= bbox.width / heightRatioThreshold && fontSize <= bbox.height / heightRatioThreshold) {
      const { height: fontHeight } = cachedTextMeasurer(label).measureLines(labelValue);
      return Math.max(fontHeight, fontSize);
    }
  }
  getNodePadding(node, bbox) {
    if (node.parent == null) {
      return { top: 0, right: 0, bottom: 0, left: 0 };
    } else if (node.children.length === 0) {
      const { padding: padding3 } = this.properties.tile;
      return { top: padding3, right: padding3, bottom: padding3, left: padding3 };
    }
    const {
      padding: padding2,
      label: { spacing }
    } = this.properties.group;
    const fontHeight = this.groupTitleHeight(node, bbox);
    const titleHeight = fontHeight == null ? 0 : fontHeight + spacing;
    return {
      top: padding2 + titleHeight,
      right: padding2,
      bottom: padding2,
      left: padding2
    };
  }
  sortChildren({ children }) {
    const sortedChildrenIndices = Array.from(children, (_, i) => i).filter((i) => nodeSize(children[i]) > 0).sort((aIndex, bIndex) => nodeSize(children[bIndex]) - nodeSize(children[aIndex]));
    const childAt = (i) => {
      const sortedIndex = sortedChildrenIndices[i];
      return children[sortedIndex];
    };
    return { sortedChildrenIndices, childAt };
  }
  /**
   * Squarified Treemap algorithm
   * https://www.win.tue.nl/~vanwijk/stm.pdf
   */
  squarify(node, bbox) {
    const { datum, children } = node;
    if (bbox.width <= 0 || bbox.height <= 0) {
      node.bbox = void 0;
      node.padding = void 0;
      node.midPoint.x = Number.NaN;
      node.midPoint.y = Number.NaN;
      return;
    }
    const padding2 = datum == null ? { top: 0, right: 0, bottom: 0, left: 0 } : this.getNodePadding(node, bbox);
    if (node.parent == null) {
      node.bbox = void 0;
      node.padding = void 0;
      node.midPoint.x = Number.NaN;
      node.midPoint.y = Number.NaN;
    } else {
      node.bbox = bbox;
      node.padding = padding2;
      node.midPoint.x = bbox.x + bbox.width / 2;
      node.midPoint.y = bbox.y;
    }
    const { sortedChildrenIndices, childAt } = this.sortChildren(node);
    const allLeafNodes = sortedChildrenIndices.every((sortedIndex) => children[sortedIndex].children.length === 0);
    const targetTileAspectRatio = 1;
    const width2 = bbox.width - padding2.left - padding2.right;
    const height2 = bbox.height - padding2.top - padding2.bottom;
    if (width2 <= 0 || height2 <= 0)
      return;
    const numChildren = sortedChildrenIndices.length;
    let stackSum = 0;
    let startIndex = 0;
    let minRatioDiff = Infinity;
    let partitionSum = sortedChildrenIndices.reduce((sum, sortedIndex) => sum + nodeSize(children[sortedIndex]), 0);
    const innerBox = new BBox8(bbox.x + padding2.left, bbox.y + padding2.top, width2, height2);
    const partition = innerBox.clone();
    let i = 0;
    while (i < numChildren) {
      const value = nodeSize(childAt(i));
      const firstValue = nodeSize(childAt(startIndex));
      const isVertical2 = partition.width < partition.height;
      stackSum += value;
      const partThickness = isVertical2 ? partition.height : partition.width;
      const partLength = isVertical2 ? partition.width : partition.height;
      const firstTileLength = partLength * firstValue / stackSum;
      let stackThickness = partThickness * stackSum / partitionSum;
      const ratio2 = Math.max(firstTileLength, stackThickness) / Math.min(firstTileLength, stackThickness);
      const diff9 = Math.abs(targetTileAspectRatio - ratio2);
      if (diff9 < minRatioDiff) {
        minRatioDiff = diff9;
        i++;
        continue;
      }
      stackSum -= value;
      stackThickness = partThickness * stackSum / partitionSum;
      let start3 = isVertical2 ? partition.x : partition.y;
      for (let j = startIndex; j < i; j++) {
        const child = childAt(j);
        const childSize = nodeSize(child);
        const x = isVertical2 ? start3 : partition.x;
        const y = isVertical2 ? partition.y : start3;
        const length2 = partLength * childSize / stackSum;
        const stackWidth = isVertical2 ? length2 : stackThickness;
        const stackHeight = isVertical2 ? stackThickness : length2;
        const childBbox = new BBox8(x, y, stackWidth, stackHeight);
        this.applyGap(innerBox, childBbox, allLeafNodes);
        this.squarify(child, childBbox);
        partitionSum -= childSize;
        start3 += length2;
      }
      if (isVertical2) {
        partition.y += stackThickness;
        partition.height -= stackThickness;
      } else {
        partition.x += stackThickness;
        partition.width -= stackThickness;
      }
      startIndex = i;
      stackSum = 0;
      minRatioDiff = Infinity;
    }
    const isVertical = partition.width < partition.height;
    let start2 = isVertical ? partition.x : partition.y;
    for (let childIdx = startIndex; childIdx < numChildren; childIdx++) {
      const child = childAt(childIdx);
      const x = isVertical ? start2 : partition.x;
      const y = isVertical ? partition.y : start2;
      const part = nodeSize(child) / partitionSum;
      const childWidth = partition.width * (isVertical ? part : 1);
      const childHeight = partition.height * (isVertical ? 1 : part);
      const childBox = new BBox8(x, y, childWidth, childHeight);
      this.applyGap(innerBox, childBox, allLeafNodes);
      this.squarify(child, childBox);
      start2 += isVertical ? childWidth : childHeight;
    }
  }
  applyGap(innerBox, childBox, allLeafNodes) {
    const gap = allLeafNodes ? this.properties.tile.gap * 0.5 : this.properties.group.gap * 0.5;
    const getBounds = (box) => ({
      left: box.x,
      top: box.y,
      right: box.x + box.width,
      bottom: box.y + box.height
    });
    const innerBounds = getBounds(innerBox);
    const childBounds = getBounds(childBox);
    const sides = ["top", "right", "bottom", "left"];
    for (const side of sides) {
      if (!isNumberEqual(innerBounds[side], childBounds[side])) {
        childBox.shrink(gap, side);
      }
    }
  }
  createNodeData() {
    return void 0;
  }
  getItemStyle(nodeDatum, isLeaf, isHighlight) {
    const { properties, colorScale } = this;
    const { itemStyler } = properties;
    const rootIndex = nodeDatum.datumIndex?.[0] ?? 0;
    const fills = isLeaf ? properties.fills : properties.undocumentedGroupFills;
    const strokes = isLeaf ? properties.strokes : properties.undocumentedGroupStrokes;
    const index = isLeaf ? rootIndex : nodeDatum.depth ?? -1;
    const highlightedNode = this.getActiveHighlightNode();
    const tileHighlightState = this.getHierarchyHighlightState(isHighlight, highlightedNode, nodeDatum);
    const groupHighlightState = this.getGroupHighlightState(isHighlight, highlightedNode, nodeDatum);
    const highlightState = isLeaf ? tileHighlightState : groupHighlightState;
    const highlightStyle = isLeaf ? this.getTileHighlightStyle(tileHighlightState, groupHighlightState, highlightedNode) : this.getGroupHighlightStyle(groupHighlightState);
    const baseStyle = mergeDefaults(highlightStyle, properties.getStyle(isLeaf, fills, strokes, index));
    if (isLeaf && nodeDatum.colorValue != null && highlightStyle?.fill == null) {
      baseStyle.fill = colorScale.convert(nodeDatum.colorValue);
    }
    let style2 = baseStyle;
    if (itemStyler != null && nodeDatum != null) {
      const overrides = this.cachedDatumCallback(
        createDatumId6(this.getDatumId(nodeDatum), isHighlight ? "highlight" : "node"),
        () => {
          const params = this.makeItemStylerParams(
            nodeDatum,
            style2,
            toHierarchyHighlightString3(highlightState)
          );
          return this.callWithContext(itemStyler, params);
        }
      );
      if (overrides) {
        style2 = mergeDefaults(overrides, style2);
      }
    }
    return style2;
  }
  makeItemStylerParams(nodeDatum, style2, highlightState) {
    const { id: seriesId } = this;
    const fill = this.filterItemStylerFillParams(style2.fill) ?? style2.fill;
    return {
      seriesId,
      datum: nodeDatum.datum,
      depth: nodeDatum.depth ?? -1,
      highlightState,
      ...style2,
      fill
    };
  }
  updateSelections() {
    const highlightedNode = this.getActiveHighlightNode();
    this.highlightSelection.update(
      highlightedNode == null ? [] : [highlightedNode],
      void 0,
      (node) => this.getDatumId(node)
    );
    if (!this.nodeDataRefresh) {
      return;
    }
    this.nodeDataRefresh = false;
    const { seriesRect } = this.chart ?? {};
    if (!seriesRect)
      return;
    const descendants = Array.from(this.rootNode);
    const updateLabelGroup = (group) => {
      group.append([new Text3({ tag: 0 /* Primary */ }), new Text3({ tag: 1 /* Secondary */ })]);
    };
    this.datumSelection.update(descendants, void 0, (node) => this.getDatumId(node));
    this.labelSelection.update(descendants, updateLabelGroup, (node) => this.getDatumId(node));
  }
  getActiveHighlightNode() {
    const highlightedNode = super.getActiveHighlightNode();
    if (highlightedNode?.children.length && !this.properties.group.interactive) {
      return void 0;
    }
    return highlightedNode;
  }
  updateNodes() {
    const { rootNode, data } = this;
    const { childrenKey, colorKey, colorName, labelKey, secondaryLabelKey, sizeKey, sizeName, tile, group } = this.properties;
    const { seriesRect } = this.chart ?? {};
    if (!seriesRect || !data)
      return;
    this.rootNode?.walk((node) => {
      const { datum, depth, children } = node;
      const isLeaf = children.length === 0;
      const labelStyle = isLeaf ? tile.label : group.label;
      let labelValue;
      if (labelStyle.enabled && datum != null && depth != null && labelKey != null) {
        const value = datum[labelKey];
        labelValue = this.getLabelText(
          value,
          datum,
          labelKey,
          "label",
          [],
          labelStyle,
          {
            depth,
            datum,
            childrenKey,
            colorKey,
            colorName,
            labelKey,
            secondaryLabelKey,
            sizeKey,
            sizeName,
            value
          }
        );
      }
      if (labelValue === "") {
        labelValue = void 0;
      }
      let secondaryLabelValue;
      if (tile.secondaryLabel.enabled && isLeaf && datum != null && depth != null && secondaryLabelKey != null) {
        const value = datum[secondaryLabelKey];
        secondaryLabelValue = this.getLabelText(
          value,
          datum,
          secondaryLabelKey,
          "secondaryLabel",
          [],
          tile.secondaryLabel,
          {
            depth,
            datum,
            childrenKey,
            colorKey,
            colorName,
            labelKey,
            secondaryLabelKey,
            sizeKey,
            sizeName,
            value
          }
        );
      }
      if (secondaryLabelValue === "") {
        secondaryLabelValue = void 0;
      }
      node.labelValue = toPlainText(labelValue);
      node.secondaryLabelValue = toPlainText(secondaryLabelValue);
    });
    const { width: width2, height: height2 } = seriesRect;
    this.squarify(rootNode, new BBox8(0, 0, width2, height2));
    this.rootNode?.walk((node) => {
      const { bbox, children, labelValue, secondaryLabelValue } = node;
      node.label = void 0;
      node.secondaryLabel = void 0;
      if (bbox == null)
        return;
      if (children.length === 0) {
        const layout = {
          width: bbox.width,
          height: bbox.height,
          meta: null
        };
        const formatting = formatLabels(
          labelValue,
          this.properties.tile.label,
          secondaryLabelValue,
          this.properties.tile.secondaryLabel,
          { padding: tile.padding },
          () => layout
        );
        if (formatting == null) {
          return;
        }
        const { height: labelHeight, label, secondaryLabel } = formatting;
        const { textAlign, verticalAlign, padding: padding2 } = tile;
        const textAlignFactor = textAlignFactors[textAlign] ?? 0.5;
        const labelX = bbox.x + padding2 + (bbox.width - 2 * padding2) * textAlignFactor;
        const verticalAlignFactor = verticalAlignFactors[verticalAlign] ?? 0.5;
        const labelYStart = bbox.y + padding2 + labelHeight * 0.5 + (bbox.height - 2 * padding2 - labelHeight) * verticalAlignFactor;
        if (label != null) {
          const {
            fontStyle = "normal",
            fontFamily,
            fontWeight: fontWeight2 = "normal",
            color: color2 = "black"
          } = this.properties.tile.label;
          node.label = {
            text: label.text,
            fontSize: label.fontSize,
            lineHeight: label.lineHeight,
            fontStyle,
            fontFamily,
            fontWeight: fontWeight2,
            color: color2,
            textAlign,
            verticalAlign: "middle",
            x: labelX,
            y: labelYStart - (labelHeight - label.height) * 0.5
          };
        }
        if (secondaryLabel != null) {
          const {
            fontStyle = "normal",
            fontFamily,
            fontWeight: fontWeight2 = "normal",
            color: color2 = "black"
          } = this.properties.tile.secondaryLabel;
          node.secondaryLabel = {
            text: secondaryLabel.text,
            fontSize: secondaryLabel.fontSize,
            lineHeight: secondaryLabel.fontSize,
            fontStyle,
            fontFamily,
            fontWeight: fontWeight2,
            color: color2,
            textAlign,
            verticalAlign: "middle",
            x: labelX,
            y: labelYStart + (labelHeight - secondaryLabel.height) * 0.5
          };
        }
      } else if (labelValue == null) {
        return;
      } else {
        const { padding: padding2, textAlign } = group;
        const groupTitleHeight = this.groupTitleHeight(node, bbox);
        if (groupTitleHeight == null)
          return;
        const innerWidth = bbox.width - 2 * padding2;
        const text2 = wrapText(labelValue, {
          maxWidth: bbox.width - 2 * padding2,
          font: group.label,
          textWrap: "never"
        });
        const textAlignFactor = textAlignFactors[textAlign] ?? 0.5;
        const {
          fontStyle = "normal",
          fontFamily,
          fontWeight: fontWeight2 = "normal",
          color: color2 = "black"
        } = this.properties.group.label;
        node.label = {
          text: text2,
          fontSize: group.label.fontSize,
          lineHeight: calcLineHeight(group.label.fontSize),
          fontStyle,
          fontFamily,
          fontWeight: fontWeight2,
          color: color2,
          textAlign,
          verticalAlign: "middle",
          x: bbox.x + padding2 + innerWidth * textAlignFactor,
          y: bbox.y + padding2 + groupTitleHeight * 0.5
        };
      }
    });
    const fillBBox = {
      series: new BBox8(0, 0, width2, height2),
      axis: new BBox8(0, 0, width2, height2)
    };
    const updateRectFn = (node, rect2, isHighlight) => {
      const { bbox } = node;
      if (bbox == null) {
        rect2.visible = false;
        return;
      }
      const { depth = -1 } = node;
      const isLeaf = node.children.length === 0;
      const style2 = this.getItemStyle(node, isLeaf, isHighlight);
      rect2.crisp = true;
      rect2.setStyleProperties(style2, fillBBox);
      rect2.cornerRadius = isLeaf ? tile.cornerRadius : group.cornerRadius;
      rect2.zIndex = [0, depth, isHighlight ? 1 : 0];
      const onlyLeaves = node.parent?.children.every((n) => n.children.length === 0);
      const parentBbox = node.parent == null ? void 0 : node.parent.bbox;
      const parentPadding = node.parent == null ? void 0 : node.parent.padding;
      if (onlyLeaves === true && parentBbox != null && parentPadding != null) {
        rect2.clipBBox = bbox;
        rect2.x = parentBbox.x + parentPadding.left;
        rect2.y = parentBbox.y + parentPadding.top;
        rect2.width = parentBbox.width - (parentPadding.left + parentPadding.right);
        rect2.height = parentBbox.height - (parentPadding.top + parentPadding.bottom);
      } else {
        rect2.clipBBox = void 0;
        rect2.x = bbox.x;
        rect2.y = bbox.y;
        rect2.width = bbox.width;
        rect2.height = bbox.height;
      }
      rect2.visible = true;
    };
    this.datumSelection.each((rect2, datum) => updateRectFn(datum, rect2, false));
    this.highlightSelection.each((rect2, datum) => {
      updateRectFn(datum, rect2, true);
    });
    const updateLabelFn = (node, text2, tag, highlighted) => {
      const isLeaf = node.children.length === 0;
      const label = tag === 0 /* Primary */ ? node.label : node.secondaryLabel;
      if (label == null) {
        text2.visible = false;
        return;
      }
      let labelProps;
      let labelPath;
      if (tag === 0 /* Primary */) {
        labelProps = isLeaf ? tile.label : group.label;
        labelPath = ["series", `${this.declarationOrder}`, isLeaf ? "tile" : "group", "label"];
      } else {
        labelProps = tile.secondaryLabel;
        labelPath = ["series", `${this.declarationOrder}`, "tile", "secondaryLabel"];
      }
      const { opacity: highlightOpacity } = this.getItemStyle(node, isLeaf, highlighted) ?? {};
      const params = {
        childrenKey: this.properties.childrenKey,
        colorKey: this.properties.colorKey,
        colorName: this.properties.colorName ?? this.properties.colorKey,
        depth: node.depth ?? Number.NaN,
        labelKey: this.properties.labelKey,
        secondaryLabelKey: this.properties.secondaryLabelKey,
        sizeKey: this.properties.sizeKey,
        sizeName: this.properties.sizeName ?? this.properties.sizeKey
      };
      const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
      const style2 = getLabelStyles6(this, node, params, labelProps, highlighted, activeHighlight, labelPath);
      text2.text = label.text;
      text2.fontSize = label.fontSize;
      text2.lineHeight = label.lineHeight;
      text2.fontStyle = label.fontStyle;
      text2.fontFamily = label.fontFamily;
      text2.fontWeight = label.fontWeight;
      text2.fillOpacity = highlightOpacity ?? 1;
      text2.fill = style2.color;
      text2.setBoxing(style2);
      text2.textAlign = label.textAlign;
      text2.textBaseline = label.verticalAlign;
      text2.x = label.x;
      text2.y = label.y;
      text2.visible = true;
      text2.zIndex = 1;
    };
    const highlightedDatum = this.getActiveHighlightNode();
    for (const text2 of this.labelSelection.selectByClass(Text3)) {
      const datum = text2.closestDatum();
      updateLabelFn(datum, text2, text2.tag, datum === highlightedDatum);
    }
  }
  getGroupHighlightState(isHighlight, highlightedNode, nodeDatum) {
    const nodeIndex = nodeDatum.datumIndex;
    const highlightedIndex = highlightedNode?.datumIndex;
    const isDescendant = this.isDescendantDatumIndex(nodeIndex, highlightedIndex);
    if (nodeDatum.children?.length === 0) {
      if (nodeIndex == null || highlightedNode == null || highlightedNode.children?.length === 0) {
        return HierarchyHighlightState2.None;
      }
      return isDescendant ? HierarchyHighlightState2.Item : HierarchyHighlightState2.OtherItem;
    }
    if (highlightedNode == null || highlightedNode.children?.length === 0) {
      return HierarchyHighlightState2.None;
    }
    const isSibling = nodeDatum.depth != null && highlightedNode.depth != null && nodeDatum.depth === highlightedNode.depth;
    if (isDescendant && !isSibling) {
      return HierarchyHighlightState2.None;
    }
    return isHighlight ? HierarchyHighlightState2.Item : HierarchyHighlightState2.OtherItem;
  }
  getTileHighlightStyle(tileHighlightState, groupHighlightState, highlightedNode) {
    const isGroupHighlighted = highlightedNode?.children && highlightedNode.children.length > 0;
    if (isGroupHighlighted) {
      const groupStyle = this.getGroupHighlightStyle(groupHighlightState);
      if (groupStyle?.fillOpacity == null && groupStyle?.strokeOpacity == null) {
        return void 0;
      }
      return { fillOpacity: groupStyle.fillOpacity, strokeOpacity: groupStyle.strokeOpacity };
    }
    return this.getHierarchyHighlightStyles(tileHighlightState, this.properties.tile.highlight);
  }
  getGroupHighlightStyle(highlightState) {
    const { highlight: highlight5 } = this.properties.group;
    switch (highlightState) {
      case HierarchyHighlightState2.Item:
        return highlight5.highlightedItem;
      case HierarchyHighlightState2.OtherItem:
        return highlight5.unhighlightedItem;
      default:
        return void 0;
    }
  }
  getHighlightStateString(_datum, isHighlight, datumIndex) {
    if (datumIndex == null) {
      return toHierarchyHighlightString3(HierarchyHighlightState2.None);
    }
    const nodeDatum = datumIndex.reduce((node, idx) => node?.children[idx], this.rootNode);
    const highlightedNode = this.getActiveHighlightNode();
    if (nodeDatum == null) {
      return toHierarchyHighlightString3(HierarchyHighlightState2.None);
    }
    const isLeaf = (nodeDatum.children?.length ?? 0) === 0;
    if (isLeaf) {
      const tileState = this.getHierarchyHighlightState(isHighlight ?? false, highlightedNode, nodeDatum);
      return toHierarchyHighlightString3(tileState);
    }
    const groupState = this.getGroupHighlightState(isHighlight ?? false, highlightedNode, nodeDatum);
    return toHierarchyHighlightString3(groupState);
  }
  isDescendantDatumIndex(nodeIndex, ancestorIndex) {
    if (ancestorIndex == null || ancestorIndex.length === 0) {
      return true;
    }
    if (nodeIndex == null || nodeIndex.length < ancestorIndex.length) {
      return false;
    }
    for (let i = 0; i < ancestorIndex.length; i += 1) {
      if (nodeIndex[i] !== ancestorIndex[i]) {
        return false;
      }
    }
    return true;
  }
  pickNodesExactShape(point) {
    const nodes = super.pickNodesExactShape(point);
    nodes.sort((a, b) => b.datumIndex.length - a.datumIndex.length);
    return nodes;
  }
  pickNodeClosestDatum(point) {
    const exactMatch = this.pickNodesExactShape(point);
    if (exactMatch.length !== 0) {
      return { datum: exactMatch[0], distance: 0 };
    }
    return this.pickNodeNearestDistantObject(point, this.datumSelection.nodes());
  }
  getTooltipContent(datumIndex) {
    const { id: seriesId, properties, ctx } = this;
    const { formatManager } = ctx;
    const { labelKey, secondaryLabelKey, childrenKey, sizeKey, sizeName, colorKey, colorName, tooltip } = properties;
    const nodeDatum = datumIndex.reduce((n, i) => n?.children[i], this.rootNode);
    if (nodeDatum == null)
      return;
    const { datum, depth, children } = nodeDatum;
    if (datum == null || depth == null)
      return;
    const isLeaf = children.length === 0;
    const data = [];
    const datumSize = sizeKey == null ? void 0 : datum[sizeKey];
    if (datumSize != null) {
      const sizeDomain = [0, this.rootNode?.sumSize ?? 0];
      const content = formatManager.format(this.callWithContext.bind(this), {
        type: "number",
        value: datumSize,
        datum,
        seriesId,
        legendItemName: void 0,
        key: sizeKey,
        source: "tooltip",
        property: "size",
        boundSeries: this.getFormatterContext("size"),
        domain: sizeDomain,
        fractionDigits: void 0,
        visibleDomain: void 0
      });
      data.push({ label: sizeName, fallbackLabel: sizeKey, value: content ?? formatValue(datumSize) });
    }
    const datumColor = colorKey == null ? void 0 : datum[colorKey];
    if (datumColor != null) {
      const { colorDomain } = this;
      const content = formatManager.format(this.callWithContext.bind(this), {
        type: "number",
        value: datumColor,
        datum,
        seriesId,
        legendItemName: void 0,
        key: colorKey,
        source: "tooltip",
        property: "color",
        boundSeries: this.getFormatterContext("color"),
        domain: colorDomain,
        fractionDigits: void 0,
        visibleDomain: void 0
      });
      data.push({ label: colorName, fallbackLabel: colorKey, value: content ?? formatValue(datumColor) });
    }
    const format = this.getItemStyle(
      { ...nodeDatum, colorValue: datumColor ?? nodeDatum.colorValue },
      isLeaf,
      false
    );
    const color2 = format.fill;
    const markerStyle = {
      shape: "square",
      fill: color2,
      fillOpacity: 1,
      stroke: void 0,
      strokeWidth: 0,
      strokeOpacity: 1,
      lineDash: [0],
      lineDashOffset: 0
    };
    if (isGradientFill(markerStyle.fill)) {
      markerStyle.fill = { ...markerStyle.fill, gradient: "linear", rotation: 0, reverse: false };
    }
    const symbol = isLeaf ? { marker: markerStyle } : void 0;
    return this.formatTooltipWithContext(
      tooltip,
      {
        title: labelKey == null ? void 0 : datum[labelKey],
        symbol,
        data
      },
      {
        seriesId,
        datum,
        title: void 0,
        depth,
        labelKey,
        secondaryLabelKey,
        childrenKey,
        sizeKey,
        sizeName,
        colorKey,
        colorName,
        ...format
      }
    );
  }
  computeFocusBounds(node) {
    return Transformable3.toCanvas(this.contentGroup, node.getBBox());
  }
  hasItemStylers() {
    return this.properties.itemStyler != null || this.properties.tile.label.itemStyler != null || this.properties.group.label.itemStyler != null;
  }
};
TreemapSeries.className = "TreemapSeries";
TreemapSeries.type = "treemap";

// packages/ag-charts-enterprise/src/series/treemap/treemapSeriesOptionsDef.ts
var { treemapSeriesThemeableOptionsDef: treemapSeriesThemeableOptionsDef2 } = module_support_exports;
var treemapSeriesOptionsDef = {
  ...treemapSeriesThemeableOptionsDef2,
  ...without(commonSeriesOptionsDefs, ["highlightStyle", "highlight", "showInLegend"]),
  type: required(constant("treemap")),
  labelKey: string,
  secondaryLabelKey: string,
  childrenKey: string,
  sizeKey: string,
  colorKey: string,
  sizeName: string,
  colorName: string
};
treemapSeriesOptionsDef.undocumentedGroupFills = undocumented(arrayOf(color));
treemapSeriesOptionsDef.undocumentedGroupStrokes = undocumented(arrayOf(color));

// packages/ag-charts-enterprise/src/series/treemap/treemapModule.ts
var TreemapSeriesModule = {
  type: "series",
  name: "treemap",
  chartType: "standalone",
  enterprise: true,
  solo: true,
  version: VERSION,
  dependencies: [StandaloneChartModule],
  options: treemapSeriesOptionsDef,
  themeTemplate: {
    series: {
      fills: {
        $applyCycle: [
          { $size: { $path: ["./data", { $path: "/data" }] } },
          { $palette: "fills" },
          {
            $applySwitch: [
              { $path: ["/type", void 0, { $value: "$1" }] },
              { $value: "$1" },
              ["gradient", FILL_GRADIENT_LINEAR_DEFAULTS],
              ["pattern", FILL_PATTERN_DEFAULTS],
              ["image", FILL_IMAGE_DEFAULTS]
            ]
          }
        ]
      },
      strokes: {
        $applyCycle: [{ $size: { $path: ["./data", { $path: "/data" }] } }, { $palette: "strokes" }]
      },
      colorRange: { $palette: "divergingColors" },
      undocumentedGroupFills: { $palette: "hierarchyColors" },
      undocumentedGroupStrokes: { $palette: "secondHierarchyColors" },
      group: {
        label: {
          ...LABEL_BOXING_DEFAULTS,
          enabled: true,
          color: { $ref: "textColor" },
          fontStyle: void 0,
          fontWeight: { $ref: "fontWeight" },
          fontSize: { $ref: "fontSize" },
          fontFamily: { $ref: "fontFamily" },
          spacing: 4
        },
        fill: void 0,
        // Override default fill
        stroke: void 0,
        // Override default stroke
        strokeWidth: 1,
        padding: 4,
        gap: 2,
        textAlign: "left",
        highlight: {
          unhighlightedItem: {
            opacity: 0.2,
            fillOpacity: 0.2,
            strokeOpacity: 0.2
          }
        }
      },
      tile: {
        label: {
          ...LABEL_BOXING_DEFAULTS,
          enabled: true,
          color: { $ref: "chartBackgroundColor" },
          fontStyle: void 0,
          fontWeight: { $ref: "fontWeight" },
          fontSize: { $rem: 1.5 },
          minimumFontSize: { $rem: FONT_SIZE_RATIO.SMALLER },
          fontFamily: { $ref: "fontFamily" },
          wrapping: "on-space",
          overflowStrategy: "ellipsis",
          spacing: 2
        },
        secondaryLabel: {
          ...LABEL_BOXING_DEFAULTS,
          enabled: true,
          color: { $ref: "chartBackgroundColor" },
          fontStyle: void 0,
          fontWeight: void 0,
          fontSize: { $ref: "fontSize" },
          minimumFontSize: { $rem: FONT_SIZE_RATIO.SMALLER },
          fontFamily: { $ref: "fontFamily" },
          wrapping: "never",
          overflowStrategy: "ellipsis"
        },
        fill: void 0,
        // Override default fill
        stroke: void 0,
        // Override default stroke
        strokeWidth: { $isUserOption: ["../strokes/0", 2, { $isUserOption: ["./stroke", 2, 0] }] },
        padding: 3,
        gap: 1,
        highlight: {
          unhighlightedItem: {
            fillOpacity: 0.6,
            strokeOpacity: 0.6
          },
          unhighlightedBranch: {
            fillOpacity: 0.2,
            strokeOpacity: 0.2
          }
        }
      }
    },
    gradientLegend: {
      enabled: { $if: [{ $path: "../series/0/colorKey" }, true, false] }
    }
  },
  create: (ctx) => new TreemapSeries(ctx)
};

// packages/ag-charts-enterprise/src/features/animation/animation.ts
var Animation2 = class extends AbstractModuleInstance {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.enabled = true;
    ctx.animationManager.skip(false);
    this.cleanup.register(() => ctx.animationManager.skip(true));
  }
};
__decorateClass([
  ObserveChanges((target, newValue) => {
    target.ctx.animationManager.skip(!newValue);
  }),
  addFakeTransformToInstanceProperty
], Animation2.prototype, "enabled", 2);
__decorateClass([
  ObserveChanges((target, newValue) => {
    if (newValue != null) {
      target.ctx.animationManager.defaultDuration = newValue;
    }
  }),
  addFakeTransformToInstanceProperty
], Animation2.prototype, "duration", 2);
__decorateClass([
  ObserveChanges((target, newValue) => {
    target.ctx.animationManager.maxAnimatableItems = newValue ?? Infinity;
  }),
  addFakeTransformToInstanceProperty
], Animation2.prototype, "maxAnimatableItems", 2);

// packages/ag-charts-enterprise/src/features/animation/animationModule.ts
var AnimationModule = {
  type: "plugin",
  name: "animation",
  enterprise: true,
  version: VERSION,
  options: {
    enabled: boolean,
    duration: positiveNumber
  },
  themeTemplate: {
    enabled: true
  },
  create: (ctx) => new Animation2(ctx)
};
AnimationModule.options.maxAnimatableItems = undocumented(positiveNumber);

// packages/ag-charts-enterprise/src/features/shared-toolbar/sharedToolbar.ts
var _SharedToolbar = class _SharedToolbar extends AbstractModuleInstance {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.activeSections = /* @__PURE__ */ new Set();
    this.sectionButtons = {
      annotations: [],
      chartToolbar: []
    };
    this.container = this.ctx.domManager.addChild("canvas-overlay", "shared-toolbar");
    this.container.role = "presentation";
  }
  getSharedToolbar(section) {
    if (!this.sharedToolbar) {
      this.createSharedToolbar();
    }
    if (section === "chartToolbar" && this.sharedToolbar) {
      this.sharedToolbar.setAriaLabelId("ariaLabelFinancialCharts");
    }
    return this.toolbarWithSection(section);
  }
  createSharedToolbar() {
    this.sharedToolbar = new module_support_exports.Toolbar(this.ctx, "ariaLabelAnnotationsToolbar", "vertical");
    this.sharedToolbar.addClass("ag-charts-shared-toolbar");
    this.container.append(this.sharedToolbar.getElement());
    this.cleanup.register(() => {
      if (!this.sharedToolbar)
        return;
      this.sharedToolbar.getElement().remove();
      this.sharedToolbar.destroy();
      this.sharedToolbar = void 0;
    });
  }
  toolbarWithSection(section) {
    const sharedToolbar = this.sharedToolbar;
    const withSection = {
      layout: (layoutBox, padding2) => {
        if (this.firstLayoutSection != null && this.firstLayoutSection !== section && this.activeSections.has(this.firstLayoutSection)) {
          return;
        }
        this.firstLayoutSection = section;
        const width2 = sharedToolbar.getBounds().width;
        sharedToolbar.setBounds({
          x: layoutBox.x,
          y: layoutBox.y,
          width: width2
        });
        layoutBox.shrink({ left: width2 + sharedToolbar.horizontalSpacing + (padding2 ?? 0) });
      },
      addToolbarListener: (eventType, handler) => {
        return sharedToolbar.addToolbarListener(eventType, (sharedEvent) => {
          const sectionIndex = this.getSectionIndex(section, sharedEvent.button.index);
          if (sectionIndex < 0)
            return;
          const event = {
            ...sharedEvent,
            button: this.sectionButtons[section][sectionIndex]
          };
          handler(event);
        });
      },
      updateButtons: (buttons) => {
        this.sectionButtons[section] = buttons;
        const sharedButtons = _SharedToolbar.SECTION_ORDER.flatMap((order) => this.sectionButtons[order]);
        sharedToolbar.updateButtons(sharedButtons);
      },
      updateButtonByIndex: (index, button) => {
        sharedToolbar.updateButtonByIndex(this.getIndex(section, index), button);
      },
      toggleActiveButtonByIndex: (index) => {
        sharedToolbar.toggleActiveButtonByIndex(this.getIndex(section, index));
      },
      toggleButtonEnabledByIndex: (index, enabled) => {
        sharedToolbar.toggleButtonEnabledByIndex(this.getIndex(section, index), enabled);
      },
      setHidden: (hidden) => {
        if (hidden) {
          this.activeSections.delete(section);
        } else {
          this.activeSections.add(section);
        }
        let sum = 0;
        for (const order of _SharedToolbar.SECTION_ORDER) {
          if (order !== section) {
            sum += this.sectionButtons[order].length;
            continue;
          }
          for (const index of this.sectionButtons[section].keys()) {
            sharedToolbar.setButtonHiddenByIndex(sum + index, hidden);
          }
        }
      },
      destroy: () => {
        withSection.setHidden(true);
        if (this.activeSections.size === 0) {
          this.destroy();
        }
      },
      clearActiveButton: sharedToolbar.clearActiveButton.bind(sharedToolbar),
      addListener: sharedToolbar.addListener.bind(sharedToolbar),
      removeListener: sharedToolbar.removeListener.bind(sharedToolbar)
    };
    withSection.setHidden(false);
    return withSection;
  }
  getIndex(section, index) {
    let sum = 0;
    for (const order of _SharedToolbar.SECTION_ORDER) {
      if (order === section)
        return sum + index;
      sum += this.sectionButtons[order].length;
    }
    return -1;
  }
  getSectionIndex(section, index) {
    let sum = 0;
    for (const order of _SharedToolbar.SECTION_ORDER) {
      if (order === section) {
        if (index >= sum + this.sectionButtons[section].length)
          return -1;
        return index - sum;
      }
      sum += this.sectionButtons[order].length;
    }
    return -1;
  }
};
_SharedToolbar.SECTION_ORDER = ["chartToolbar", "annotations"];
var SharedToolbar = _SharedToolbar;

// packages/ag-charts-enterprise/src/features/text-input/textInputTemplate.html
var textInputTemplate_default = '<div contenteditable="plaintext-only" class="ag-charts-text-input__textarea" tabindex="0"></div>';

// packages/ag-charts-enterprise/src/features/text-input/textInput.ts
var moduleId = "text-input";
var canvasOverlay2 = "canvas-overlay";
var TextInput = class {
  constructor(ctx) {
    this.ctx = ctx;
    this.cleanup = new CleanupRegistry();
    this.layout = {
      getTextInputCoords: () => ({ x: 0, y: 0 }),
      getTextPosition: () => "center",
      alignment: "center",
      textAlign: "center"
    };
    this.visible = false;
    this.element = ctx.domManager.addChild(canvasOverlay2, moduleId);
    this.element.classList.add("ag-charts-text-input");
    this.cleanup.register(() => ctx.domManager.removeChild(canvasOverlay2, moduleId));
  }
  setKeyDownHandler(handler) {
    this.cleanup.register(attachListener(this.element, "keydown", handler));
  }
  show(opts) {
    this.element.innerHTML = textInputTemplate_default;
    const textArea = this.element.firstElementChild;
    setAttributes(textArea, {
      role: "textbox",
      // AG-15233
      "data-preventdefault": false
      // AG-13715
    });
    if (!textArea.isContentEditable) {
      textArea.contentEditable = "true";
    }
    textArea.setAttribute(
      "placeholder",
      this.ctx.localeManager.t(opts.placeholderText ?? "inputTextareaPlaceholder")
    );
    if (opts.styles?.placeholderColor) {
      textArea.style.setProperty("--placeholder-text-color", opts.styles?.placeholderColor);
    }
    textArea.innerText = opts.text ?? "";
    textArea.style.color = opts.styles?.color ?? "inherit";
    textArea.style.fontFamily = opts.styles?.fontFamily ?? "inherit";
    textArea.style.fontSize = opts.styles?.fontSize ? `${opts.styles.fontSize}px` : "inherit";
    textArea.style.fontStyle = opts.styles?.fontStyle ?? "inherit";
    textArea.style.fontWeight = typeof opts.styles?.fontWeight === "number" ? `${opts.styles.fontWeight}` : opts.styles?.fontWeight ?? "inherit";
    focusCursorAtEnd(textArea);
    textArea.addEventListener("input", () => {
      this.updatePosition();
      opts.onChange?.(this.getValue(), this.getBBox());
    });
    textArea.addEventListener("click", (event) => {
      event.stopPropagation();
    });
    if (opts.layout) {
      this.layout = opts.layout;
      this.updatePosition();
    }
    opts.onChange?.(this.getValue(), this.getBBox());
    this.visible = true;
  }
  hide() {
    this.element.innerHTML = "";
    this.layout = {
      getTextInputCoords: () => ({ x: 0, y: 0 }),
      getTextPosition: () => "center",
      alignment: "center",
      textAlign: "center"
    };
    this.visible = false;
  }
  isVisible() {
    return this.visible;
  }
  updateColor(color2) {
    if (!this.element.firstElementChild)
      return;
    this.element.firstElementChild.style.color = color2;
  }
  updateFontSize(fontSize) {
    if (!this.element.firstElementChild)
      return;
    this.element.firstElementChild.style.fontSize = `${fontSize}px`;
    this.updatePosition();
    return this.getBBox();
  }
  getValue() {
    if (!this.element.firstElementChild)
      return;
    return this.element.firstElementChild.innerText.trim();
  }
  updatePosition() {
    const { element: element2 } = this;
    const textArea = element2.firstElementChild;
    if (!textArea)
      return;
    const sceneRect = this.ctx.domManager.getBoundingClientRect();
    const { width: width2, getTextInputCoords, getTextPosition, alignment, textAlign } = this.layout;
    element2.style.setProperty("width", width2 ? `${width2}px` : "unset");
    const textRect = textArea.getBoundingClientRect();
    const point = getTextInputCoords(textRect.height);
    let horizontalPosition = point.x;
    if (alignment === "center") {
      horizontalPosition -= (width2 ?? textRect.width) / 2;
    } else if (alignment === "right") {
      horizontalPosition -= width2 ?? textRect.width;
    }
    const position = getTextPosition();
    let verticalPosition = point.y;
    if (position === "center") {
      verticalPosition -= textRect.height / 2;
    } else if (position === "bottom") {
      verticalPosition -= textRect.height;
    }
    element2.style.setProperty("top", `${verticalPosition}px`);
    element2.style.setProperty("left", `${horizontalPosition}px`);
    element2.style.setProperty("max-width", `${sceneRect.width - horizontalPosition}px`);
    element2.style.setProperty("text-align", alignment);
    textArea.style.setProperty("text-align", textAlign);
  }
  getBBox() {
    const { left, top, width: width2, height: height2 } = this.element.getBoundingClientRect();
    return new module_support_exports.BBox(left, top, ceilTo(width2, 2), height2);
  }
  destroy() {
    this.cleanup.flush();
  }
};

// packages/ag-charts-enterprise/src/features/annotations/annotationAxesButtons.ts
var AxesButtons = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = false;
    this.axes = "y";
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], AxesButtons.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxesButtons.prototype, "axes", 2);

// packages/ag-charts-enterprise/src/features/annotations/annotationTypes.ts
var AnnotationType = /* @__PURE__ */ ((AnnotationType2) => {
  AnnotationType2["Line"] = "line";
  AnnotationType2["HorizontalLine"] = "horizontal-line";
  AnnotationType2["VerticalLine"] = "vertical-line";
  AnnotationType2["DisjointChannel"] = "disjoint-channel";
  AnnotationType2["ParallelChannel"] = "parallel-channel";
  AnnotationType2["FibonacciRetracement"] = "fibonacci-retracement";
  AnnotationType2["FibonacciRetracementTrendBased"] = "fibonacci-retracement-trend-based";
  AnnotationType2["Callout"] = "callout";
  AnnotationType2["Comment"] = "comment";
  AnnotationType2["Note"] = "note";
  AnnotationType2["Text"] = "text";
  AnnotationType2["Arrow"] = "arrow";
  AnnotationType2["ArrowUp"] = "arrow-up";
  AnnotationType2["ArrowDown"] = "arrow-down";
  AnnotationType2["DateRange"] = "date-range";
  AnnotationType2["PriceRange"] = "price-range";
  AnnotationType2["DatePriceRange"] = "date-price-range";
  AnnotationType2["QuickDatePriceRange"] = "quick-date-price-range";
  return AnnotationType2;
})(AnnotationType || {});
var ANNOTATION_TYPES = Object.values(AnnotationType);
function stringToAnnotationType(value) {
  for (const t of ANNOTATION_TYPES) {
    if (t === value)
      return t;
  }
}

// packages/ag-charts-enterprise/src/features/annotations/annotationProperties.ts
var PointProperties = class extends BaseProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], PointProperties.prototype, "x", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PointProperties.prototype, "y", 2);
var ChannelAnnotationMiddleProperties = class extends Stroke(LineStyle(Visible(BaseProperties))) {
};
var AxisLabelProperties = class extends Stroke(LineStyle(Fill(Label7(Font(BaseProperties))))) {
  constructor() {
    super(...arguments);
    this.cornerRadius = 2;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabelProperties.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisLabelProperties.prototype, "cornerRadius", 2);
var BackgroundProperties = class extends Fill(BaseProperties) {
};
var HandleProperties = class extends Stroke(LineStyle(Fill(BaseProperties))) {
};
var LineTextProperties = class extends Font(BaseProperties) {
  constructor() {
    super(...arguments);
    this.label = "";
    this.position = "top";
    this.alignment = "left";
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], LineTextProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineTextProperties.prototype, "position", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LineTextProperties.prototype, "alignment", 2);
var LabelTextProperties = class extends Font(BaseProperties) {
};
var ChannelTextProperties = class extends Font(BaseProperties) {
  constructor() {
    super(...arguments);
    this.label = "";
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ChannelTextProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChannelTextProperties.prototype, "position", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ChannelTextProperties.prototype, "alignment", 2);
function Annotation(Parent) {
  class AnnotationInternal extends Writeable(Visible(Parent)) {
    constructor() {
      super(...arguments);
      // A uuid is required, over the usual incrementing index, as annotations can be restored from external databases
      this.id = generateUUID();
    }
  }
  return AnnotationInternal;
}
function Line2(Parent) {
  class LineInternal extends Parent {
    constructor() {
      super(...arguments);
      this.start = new PointProperties();
      this.end = new PointProperties();
    }
  }
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], LineInternal.prototype, "start", 2);
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], LineInternal.prototype, "end", 2);
  return LineInternal;
}
function Point(Parent) {
  class PointInternal extends Parent {
  }
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], PointInternal.prototype, "x", 2);
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], PointInternal.prototype, "y", 2);
  return PointInternal;
}
function Value(Parent) {
  class ValueInternal extends Parent {
  }
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], ValueInternal.prototype, "value", 2);
  return ValueInternal;
}
function Background2(Parent) {
  class BackgroundInternal extends Parent {
    constructor() {
      super(...arguments);
      this.background = new BackgroundProperties();
    }
  }
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], BackgroundInternal.prototype, "background", 2);
  return BackgroundInternal;
}
function Handle(Parent) {
  class HandleInternal extends Parent {
    constructor() {
      super(...arguments);
      this.handle = new HandleProperties();
    }
  }
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], HandleInternal.prototype, "handle", 2);
  return HandleInternal;
}
function AxisLabel2(Parent) {
  class AxisLabelInternal extends Parent {
    constructor() {
      super(...arguments);
      this.axisLabel = new AxisLabelProperties();
    }
  }
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], AxisLabelInternal.prototype, "axisLabel", 2);
  return AxisLabelInternal;
}
function Label7(Parent) {
  class LabelInternal extends Parent {
    constructor() {
      super(...arguments);
      this.padding = void 0;
      this.textAlign = "center";
      this.formatter = void 0;
    }
    // TODO: making this generic causes issues with mixins sequence
  }
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], LabelInternal.prototype, "padding", 2);
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], LabelInternal.prototype, "textAlign", 2);
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], LabelInternal.prototype, "formatter", 2);
  return LabelInternal;
}
function Cappable(Parent) {
  class CappableInternal extends Parent {
  }
  return CappableInternal;
}
function Extendable(Parent) {
  class ExtendableInternal extends Parent {
  }
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], ExtendableInternal.prototype, "extendStart", 2);
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], ExtendableInternal.prototype, "extendEnd", 2);
  return ExtendableInternal;
}
function Writeable(Parent) {
  class WriteableInternal extends Parent {
    isWriteable() {
      return !this.locked && !this.readOnly;
    }
    isHoverable() {
      return !this.readOnly;
    }
  }
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], WriteableInternal.prototype, "locked", 2);
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], WriteableInternal.prototype, "readOnly", 2);
  return WriteableInternal;
}
function Localisable(Parent) {
  class LocalisableInternal extends Parent {
    setLocaleManager(localeManager) {
      this.localeManager ?? (this.localeManager = localeManager);
    }
  }
  return LocalisableInternal;
}
function Visible(Parent) {
  class VisibleInternal extends Parent {
  }
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], VisibleInternal.prototype, "visible", 2);
  return VisibleInternal;
}
function Fill(Parent) {
  class FillInternal extends Parent {
  }
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], FillInternal.prototype, "fill", 2);
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], FillInternal.prototype, "fillOpacity", 2);
  return FillInternal;
}
function Stroke(Parent) {
  class StrokeInternal extends Parent {
  }
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], StrokeInternal.prototype, "stroke", 2);
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], StrokeInternal.prototype, "strokeOpacity", 2);
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], StrokeInternal.prototype, "strokeWidth", 2);
  return StrokeInternal;
}
function LineStyle(Parent) {
  class LineDashInternal extends Parent {
    constructor() {
      super(...arguments);
      this.lineCap = void 0;
      this.computedLineDash = void 0;
    }
  }
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], LineDashInternal.prototype, "lineDash", 2);
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], LineDashInternal.prototype, "lineDashOffset", 2);
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], LineDashInternal.prototype, "lineStyle", 2);
  return LineDashInternal;
}
function Font(Parent) {
  class FontInternal extends Parent {
    constructor() {
      super(...arguments);
      this.fontSize = 12 /* SMALL */;
      this.fontFamily = "Verdana, sans-serif";
    }
  }
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], FontInternal.prototype, "fontStyle", 2);
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], FontInternal.prototype, "fontWeight", 2);
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], FontInternal.prototype, "fontSize", 2);
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], FontInternal.prototype, "fontFamily", 2);
  __decorateClass([
    addFakeTransformToInstanceProperty
  ], FontInternal.prototype, "color", 2);
  return FontInternal;
}

// packages/ag-charts-enterprise/src/features/annotations/utils/scale.ts
function getGrouping(d) {
  if (isNumber(d) || isString(d) || isDate(d)) {
    return { value: d, groupPercentage: 0 };
  }
  return d ?? { value: void 0, groupPercentage: 0 };
}
function getGroupingValue(d) {
  return getGrouping(d)?.value;
}

// packages/ag-charts-enterprise/src/features/annotations/utils/values.ts
function convertLine(datum, context) {
  if (datum.start == null || datum.end == null)
    return;
  const start2 = convertPoint(datum.start, context);
  const end3 = convertPoint(datum.end, context);
  if (start2 == null || end3 == null)
    return;
  return { x1: start2.x, y1: start2.y, x2: end3.x, y2: end3.y };
}
function convertPoint(point, context) {
  const x = convert(point.x, context.xAxis);
  const y = convert(point.y, context.yAxis);
  return { x, y };
}
function convert(p, context) {
  if (p == null)
    return 0;
  const { value, groupPercentage } = getGrouping(p);
  const { scale: scale2, snapToGroup } = context;
  const width2 = scale2.bandwidth === 0 ? scale2.step ?? 0 : scale2.bandwidth ?? 0;
  const offset = snapToGroup ? width2 / 2 : width2 * groupPercentage;
  return scale2.convert(value) + offset;
}
function invertCoords(coords, context) {
  const x = invert(coords.x, context.xAxis);
  const y = invert(coords.y, context.yAxis);
  return { x, y };
}
function invert(n, context) {
  const { scale: scale2 } = context;
  if (context.continuous && scale2.step == null) {
    return context.scaleInvert(n);
  }
  const value = context.scaleInvertNearest(n);
  const width2 = scale2.bandwidth === 0 ? scale2.step : scale2.bandwidth ?? 0;
  const bandStart = scale2.convert(value);
  const bandEnd = bandStart + width2;
  const groupPercentage = bandStart === bandEnd ? 0 : (n - bandStart) / (bandEnd - bandStart);
  return { value, groupPercentage };
}

// packages/ag-charts-enterprise/src/features/annotations/properties/startEndProperties.ts
var StartEndProperties = class extends Annotation(Line2(Handle(BaseProperties))) {
  constructor() {
    super(...arguments);
    this.snapToAngle = 45;
  }
  getDefaultColor(_colorPickerType) {
    return void 0;
  }
  getDefaultOpacity(_colorPickerType) {
    return void 0;
  }
};

// packages/ag-charts-enterprise/src/features/annotations/properties/textualStartEndProperties.ts
var TextualStartEndProperties = class extends Localisable(Label7(Font(StartEndProperties))) {
  constructor() {
    super(...arguments);
    this.text = "";
    this.position = "top";
    this.alignment = "left";
    this.placement = "inside";
    this.placeholderText = "inputTextareaPlaceholder";
  }
  getDefaultColor(_colorPickerType) {
    return this.color;
  }
  getDefaultOpacity(_colorPickerType) {
    return void 0;
  }
  getPlaceholderColor() {
    return void 0;
  }
  getPadding() {
    const { padding: padding2 = 0 } = this;
    return {
      top: padding2,
      right: padding2,
      bottom: padding2,
      left: padding2
    };
  }
  getText() {
    const isPlaceholder = this.text.length == 0;
    let text2 = this.text;
    if (isPlaceholder) {
      text2 = this.placeholderText ?? "";
      if (this.localeManager)
        text2 = this.localeManager.t(text2);
    }
    return {
      text: text2,
      isPlaceholder
    };
  }
  getTextInputCoords(context, _height) {
    return convertPoint(this.end, context);
  }
  getTextPosition() {
    return this.position;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], TextualStartEndProperties.prototype, "text", 2);

// packages/ag-charts-enterprise/src/features/annotations/callout/calloutProperties.ts
var DEFAULT_CALLOUT_PADDING = {
  top: 6,
  right: 12,
  bottom: 9,
  left: 12
};
var CalloutProperties = class extends Fill(Stroke(TextualStartEndProperties)) {
  constructor() {
    super(...arguments);
    this.type = "callout" /* Callout */;
    this.position = "bottom";
    this.alignment = "left";
  }
  static is(value) {
    return isObject(value) && value.type === "callout" /* Callout */;
  }
  getDefaultColor(colorPickerType) {
    switch (colorPickerType) {
      case `fill-color`:
        return this.fill;
      case `line-color`:
        return this.stroke;
      case `text-color`:
      default:
        return this.color;
    }
  }
  getDefaultOpacity(colorPickerType) {
    switch (colorPickerType) {
      case `fill-color`:
        return this.fillOpacity;
      case `line-color`:
        return this.strokeOpacity;
      case `text-color`:
      default:
        return void 0;
    }
  }
  getPlaceholderColor() {
    const { r, g, b } = Color.fromString(this.color ?? "#888888");
    return new Color(r, g, b, 0.66).toString();
  }
  getPadding() {
    const { padding: padding2 } = this;
    if (padding2 == null) {
      return { ...DEFAULT_CALLOUT_PADDING };
    }
    return {
      top: padding2,
      right: padding2,
      bottom: padding2,
      left: padding2
    };
  }
  getTextInputCoords(context, height2) {
    const coords = super.getTextInputCoords(context, height2);
    const padding2 = this.getPadding();
    const paddingLeft = padding2.left ?? 0;
    const paddingBottom = padding2.bottom ?? 0;
    return {
      x: coords.x + paddingLeft,
      y: coords.y - paddingBottom
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], CalloutProperties.prototype, "type", 2);

// packages/ag-charts-enterprise/src/features/annotations/properties/textualPointProperties.ts
var TextualPointProperties = class extends Annotation(Point(Handle(Label7(Font(BaseProperties))))) {
  constructor() {
    super(...arguments);
    this.text = "";
    this.position = "top";
    this.alignment = "left";
    this.placement = "inside";
    this.placeholderText = "inputTextareaPlaceholder";
  }
  getDefaultColor(_colorPickerType) {
    return this.color;
  }
  getDefaultOpacity(_colorPickerType) {
    return void 0;
  }
  getPlaceholderColor() {
    return void 0;
  }
  getPadding() {
    const { padding: padding2 = 0 } = this;
    return {
      top: padding2,
      right: padding2,
      bottom: padding2,
      left: padding2
    };
  }
  getText() {
    const isPlaceholder = this.text.length == 0;
    const text2 = isPlaceholder ? this.placeholderText ?? "" : this.text;
    return {
      text: text2,
      isPlaceholder
    };
  }
  getTextInputCoords(context, _height) {
    return convertPoint(this, context);
  }
  getTextPosition() {
    return this.position;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], TextualPointProperties.prototype, "text", 2);

// packages/ag-charts-enterprise/src/features/annotations/comment/commentProperties.ts
var DEFAULT_COMMENT_PADDING = {
  top: 8,
  right: 14,
  bottom: 8,
  left: 14
};
var CommentProperties = class extends Fill(Stroke(TextualPointProperties)) {
  constructor() {
    super(...arguments);
    this.type = "comment" /* Comment */;
    this.position = "bottom";
    this.alignment = "left";
  }
  static is(value) {
    return isObject(value) && value.type === "comment" /* Comment */;
  }
  getDefaultColor(colorPickerType) {
    switch (colorPickerType) {
      case `fill-color`:
        return this.fill;
      case `line-color`:
        return this.stroke;
      case `text-color`:
      default:
        return this.color;
    }
  }
  getDefaultOpacity(colorPickerType) {
    switch (colorPickerType) {
      case `fill-color`:
        return this.fillOpacity;
      case `line-color`:
        return this.strokeOpacity;
      case `text-color`:
      default:
        return void 0;
    }
  }
  getPlaceholderColor() {
    const { r, g, b } = Color.fromString(this.color ?? "#888888");
    return new Color(r, g, b, 0.66).toString();
  }
  getPadding() {
    const { padding: padding2, fontSize } = this;
    if (padding2 == null) {
      return {
        top: Math.max(fontSize * 0.4, DEFAULT_COMMENT_PADDING.top),
        bottom: Math.max(fontSize * 0.4, DEFAULT_COMMENT_PADDING.bottom),
        left: Math.max(fontSize * 0.8, DEFAULT_COMMENT_PADDING.left),
        right: Math.max(fontSize * 0.8, DEFAULT_COMMENT_PADDING.right)
      };
    }
    return {
      top: padding2,
      right: padding2,
      bottom: padding2,
      left: padding2
    };
  }
  getTextInputCoords(context, height2) {
    const coords = super.getTextInputCoords(context, height2);
    const padding2 = this.getPadding();
    return {
      x: coords.x + padding2.left,
      y: coords.y - padding2.bottom
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], CommentProperties.prototype, "type", 2);

// packages/ag-charts-enterprise/src/features/annotations/utils/line.ts
function getLineStyle(lineDash, lineStyle) {
  return lineDash ? "dashed" : lineStyle ?? "solid";
}
function getComputedLineDash(strokeWidth, styleType) {
  switch (styleType) {
    case "solid":
      return [];
    case "dashed":
      return [strokeWidth * 4, strokeWidth * 2];
    case "dotted":
      return [0, strokeWidth * 2];
  }
}
function getLineDash(lineDash, computedLineDash, lineStyle, strokeWidth) {
  const styleType = getLineStyle(lineDash, lineStyle);
  return computedLineDash ?? lineDash ?? getComputedLineDash(strokeWidth ?? 1, styleType);
}
function getLineCap(lineCap, lineDash, lineStyle) {
  const styleType = getLineStyle(lineDash, lineStyle);
  return lineCap ?? styleType === "dotted" ? "round" : void 0;
}
function boundsIntersections(coords, bounds) {
  const [p1, p2] = vector_exports.from(coords);
  const reflection = bounds.height;
  const gradient2 = vector_exports.gradient(p2, p1, reflection);
  const intercept2 = vector_exports.intercept(p2, gradient2, reflection);
  const fallback = [
    { x: p1.x, y: reflection ?? 0 },
    { x: p1.x, y: reflection == null ? bounds.height : reflection - bounds.height }
  ];
  if (gradient2 === Infinity) {
    return fallback;
  }
  let points = [
    vector_exports.intersectAtY(gradient2, intercept2, 0, reflection),
    vector_exports.intersectAtY(gradient2, intercept2, bounds.height, reflection),
    vector_exports.intersectAtX(gradient2, intercept2, 0, reflection),
    vector_exports.intersectAtX(gradient2, intercept2, bounds.width, reflection)
  ];
  points = points.filter((p) => p.x >= bounds.x && p.x <= bounds.width && p.y >= bounds.y && p.y <= bounds.height).sort((a, b) => {
    if (a.x === b.x)
      return 0;
    return a.x < b.x ? -1 : 1;
  });
  if (points.length !== 2) {
    return fallback;
  }
  return points;
}

// packages/ag-charts-enterprise/src/features/annotations/measurer/measurerProperties.ts
var MeasurerStatisticsDivider = class extends Stroke(BaseProperties) {
};
var MeasurerStatistics = class extends Font(Fill(Stroke(BaseProperties))) {
  constructor() {
    super(...arguments);
    this.divider = new MeasurerStatisticsDivider();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], MeasurerStatistics.prototype, "divider", 2);
var MeasurerDirectionProperties = class extends Fill(Stroke(Handle(BaseProperties))) {
  constructor() {
    super(...arguments);
    this.statistics = new MeasurerStatistics();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], MeasurerDirectionProperties.prototype, "statistics", 2);
var MeasurerTypeProperties = class extends Localisable(Background2(Stroke(LineStyle(StartEndProperties)))) {
  constructor() {
    super(...arguments);
    this.direction = "both";
    this.hasDateRange = false;
    this.hasPriceRange = false;
    this.statistics = new MeasurerStatistics();
    this.getVolume = () => void 0;
    this.text = new LineTextProperties();
  }
  getDefaultColor(colorPickerType) {
    switch (colorPickerType) {
      case `fill-color`:
        return this.background.fill;
      case `line-color`:
        return this.stroke;
      case `text-color`:
        return this.text.color;
    }
  }
  getDefaultOpacity(colorPickerType) {
    switch (colorPickerType) {
      case `fill-color`:
        return this.background.fillOpacity;
      case `line-color`:
        return this.strokeOpacity;
    }
  }
  getLineDash() {
    return getLineDash(this.lineDash, this.computedLineDash, this.lineStyle, this.strokeWidth);
  }
  getLineCap() {
    return getLineCap(this.lineCap, this.lineDash, this.lineStyle);
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], MeasurerTypeProperties.prototype, "statistics", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MeasurerTypeProperties.prototype, "text", 2);
function DateRange(Parent) {
  class DateRangeInternal extends Parent {
    constructor() {
      super(...arguments);
      this.hasDateRange = true;
    }
  }
  return DateRangeInternal;
}
function PriceRange(Parent) {
  class PriceRangeInternal extends Parent {
    constructor() {
      super(...arguments);
      this.hasPriceRange = true;
    }
  }
  return PriceRangeInternal;
}
var DateRangeProperties = class extends DateRange(MeasurerTypeProperties) {
  constructor() {
    super(...arguments);
    this.type = "date-range" /* DateRange */;
    this.direction = "horizontal";
  }
  static is(value) {
    return isObject(value) && value.type === "date-range" /* DateRange */;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], DateRangeProperties.prototype, "type", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DateRangeProperties.prototype, "extendAbove", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DateRangeProperties.prototype, "extendBelow", 2);
var PriceRangeProperties = class extends PriceRange(MeasurerTypeProperties) {
  constructor() {
    super(...arguments);
    this.type = "price-range" /* PriceRange */;
    this.direction = "vertical";
  }
  static is(value) {
    return isObject(value) && value.type === "price-range" /* PriceRange */;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], PriceRangeProperties.prototype, "type", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PriceRangeProperties.prototype, "extendLeft", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PriceRangeProperties.prototype, "extendRight", 2);
var DatePriceRangeProperties = class extends DateRange(PriceRange(MeasurerTypeProperties)) {
  constructor() {
    super(...arguments);
    this.type = "date-price-range" /* DatePriceRange */;
    this.direction = "both";
  }
  static is(value) {
    return isObject(value) && value.type === "date-price-range" /* DatePriceRange */;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], DatePriceRangeProperties.prototype, "type", 2);
var QuickDatePriceRangeProperties = class extends DateRange(PriceRange(MeasurerTypeProperties)) {
  constructor() {
    super(...arguments);
    this.type = "quick-date-price-range" /* QuickDatePriceRange */;
    this.up = new MeasurerDirectionProperties();
    this.down = new MeasurerDirectionProperties();
    this.direction = "both";
  }
  static is(value) {
    return isObject(value) && value.type === "quick-date-price-range" /* QuickDatePriceRange */;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], QuickDatePriceRangeProperties.prototype, "type", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], QuickDatePriceRangeProperties.prototype, "up", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], QuickDatePriceRangeProperties.prototype, "down", 2);

// packages/ag-charts-enterprise/src/features/annotations/text/util.ts
var { BBox: BBox9 } = module_support_exports;
var ANNOTATION_TEXT_LINE_HEIGHT = 1.38;
function maybeWrapText(options, text2, maxWidth) {
  return maxWidth ? wrapText(text2, { maxWidth, font: options, textWrap: "always", avoidOrphans: false }) : text2;
}
function measureAnnotationText(options, text2) {
  const { lineMetrics, width: width2 } = cachedTextMeasurer(options).measureLines(text2);
  const height2 = lineMetrics.length * calcLineHeight(options.fontSize, ANNOTATION_TEXT_LINE_HEIGHT);
  return { width: width2, height: height2 };
}
function getBBox(options, text2, coords, bbox) {
  let width2 = bbox?.width ?? 0;
  let height2 = bbox?.height ?? 0;
  if (!bbox) {
    const wrappedText = options.width == null ? text2 : maybeWrapText(options, text2, options.width);
    ({ width: width2, height: height2 } = measureAnnotationText(options, wrappedText));
  }
  return new BBox9(coords.x, coords.y, width2, height2);
}
function updateTextNode(node, text2, isPlaceholder, config, { x, y }, textBaseline) {
  const { visible = true, fontFamily, fontSize = 14, fontStyle, fontWeight: fontWeight2, textAlign } = config;
  const lineHeight = calcLineHeight(fontSize, ANNOTATION_TEXT_LINE_HEIGHT);
  textBaseline ?? (textBaseline = config.position == "center" ? "middle" : config.position);
  const fill = isPlaceholder ? config.getPlaceholderColor() : config.color;
  node.setProperties({
    x,
    y,
    visible,
    text: text2,
    fill,
    fontFamily,
    fontSize,
    fontStyle,
    fontWeight: fontWeight2,
    textAlign,
    lineHeight,
    textBaseline
  });
}

// packages/ag-charts-enterprise/src/features/annotations/note/noteProperties.ts
var DEFAULT_NOTE_PADDING = 10;
var HANDLE_SIZE = 11;
var ICON_HEIGHT = 20;
var ICON_WIDTH = 22;
var ICON_SPACING = 10;
var LABEL_OFFSET = ICON_HEIGHT + ICON_SPACING;
var TOOLBAR_OFFSET = 34;
var NoteBackgroundProperties = class extends Fill(Stroke(BaseProperties)) {
};
var NoteProperties = class extends Fill(Stroke(TextualPointProperties)) {
  constructor() {
    super(...arguments);
    this.type = "note" /* Note */;
    this.background = new NoteBackgroundProperties();
    this.position = "bottom";
    this.alignment = "center";
    this.width = 200;
  }
  static is(value) {
    return isObject(value) && value.type === "note" /* Note */;
  }
  getDefaultColor(colorPickerType) {
    switch (colorPickerType) {
      case `line-color`:
        return this.fill;
      case `text-color`:
        return this.color;
    }
  }
  getDefaultOpacity(colorPickerType) {
    switch (colorPickerType) {
      case `line-color`:
        return this.fillOpacity;
      case `text-color`:
        return void 0;
    }
  }
  getPadding() {
    const padding2 = this.padding ?? DEFAULT_NOTE_PADDING;
    return {
      top: padding2,
      right: padding2,
      bottom: padding2,
      left: padding2
    };
  }
  getTextInputCoords(context, height2) {
    const { width: width2, text: text2 } = this;
    const textInputCoords = super.getTextInputCoords(context, height2);
    const padding2 = this.getPadding().top;
    const bbox = getBBox(this, text2, textInputCoords);
    bbox.x = clamp(width2 / 2, bbox.x, context.seriesRect.width - width2 / 2);
    const topY = bbox.y - LABEL_OFFSET - padding2 * 2;
    const bottomY = bbox.y + HANDLE_SIZE + padding2 * 2;
    const textHeight = Math.max(bbox.height, height2);
    if (topY - textHeight - TOOLBAR_OFFSET < 0) {
      bbox.y = bottomY;
      this.position = "top";
    } else {
      bbox.y = topY + padding2;
      this.position = "bottom";
    }
    return {
      x: bbox.x,
      y: bbox.y
    };
  }
  isHoverable() {
    return true;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], NoteProperties.prototype, "type", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], NoteProperties.prototype, "background", 2);

// packages/ag-charts-enterprise/src/features/annotations/properties/pointProperties.ts
var PointProperties2 = class extends Annotation(Point(Handle(BaseProperties))) {
  getDefaultColor(_colorPickerType) {
    return void 0;
  }
  getDefaultOpacity(_colorPickerType) {
    return void 0;
  }
};

// packages/ag-charts-enterprise/src/features/annotations/properties/shapePointProperties.ts
var ShapePointProperties = class _ShapePointProperties extends Fill(PointProperties2) {
  constructor() {
    super(...arguments);
    this.size = 32;
  }
  static is(value) {
    return value instanceof _ShapePointProperties;
  }
  getDefaultColor(colorPickerType) {
    return colorPickerType === `fill-color` ? this.fill : void 0;
  }
  getDefaultOpacity(colorPickerType) {
    return colorPickerType === `fill-color` ? this.fillOpacity : void 0;
  }
};

// packages/ag-charts-enterprise/src/features/annotations/cross-line/crossLineProperties.ts
var HorizontalLineProperties = class extends Annotation(Value(Handle(AxisLabel2(Stroke(LineStyle(BaseProperties)))))) {
  constructor() {
    super(...arguments);
    this.direction = "horizontal";
    this.type = "horizontal-line" /* HorizontalLine */;
    this.text = new LineTextProperties();
  }
  static is(value) {
    return isObject(value) && value.type === "horizontal-line" /* HorizontalLine */;
  }
  getDefaultColor() {
    return this.stroke;
  }
  getDefaultOpacity() {
    return this.strokeOpacity;
  }
  getLineDash() {
    return getLineDash(this.lineDash, this.computedLineDash, this.lineStyle, this.strokeWidth);
  }
  getLineCap() {
    return getLineCap(this.lineCap, this.lineDash, this.lineStyle);
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], HorizontalLineProperties.prototype, "type", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HorizontalLineProperties.prototype, "text", 2);
var VerticalLineProperties = class extends Annotation(Value(Handle(AxisLabel2(Stroke(LineStyle(BaseProperties)))))) {
  constructor() {
    super(...arguments);
    this.direction = "vertical";
    this.type = "vertical-line" /* VerticalLine */;
    this.text = new LineTextProperties();
  }
  static is(value) {
    return isObject(value) && value.type === "vertical-line" /* VerticalLine */;
  }
  getDefaultColor() {
    return this.stroke;
  }
  getDefaultOpacity() {
    return this.strokeOpacity;
  }
  getLineDash() {
    return getLineDash(this.lineDash, this.computedLineDash, this.lineStyle, this.strokeWidth);
  }
  getLineCap() {
    return getLineCap(this.lineCap, this.lineDash, this.lineStyle);
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], VerticalLineProperties.prototype, "type", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], VerticalLineProperties.prototype, "text", 2);

// packages/ag-charts-enterprise/src/features/annotations/disjoint-channel/disjointChannelProperties.ts
var DisjointChannelProperties = class extends Annotation(
  Background2(Line2(Handle(Extendable(Stroke(LineStyle(BaseProperties))))))
) {
  constructor() {
    super(...arguments);
    this.type = "disjoint-channel" /* DisjointChannel */;
    this.text = new ChannelTextProperties();
    this.snapToAngle = 45;
  }
  static is(value) {
    return isObject(value) && value.type === "disjoint-channel" /* DisjointChannel */;
  }
  get bottom() {
    const bottom = {
      start: { x: this.start.x, y: this.start.y },
      end: { x: this.end.x, y: this.end.y }
    };
    if (typeof bottom.start.y === "number" && typeof bottom.end.y === "number") {
      bottom.start.y -= this.startHeight;
      bottom.end.y -= this.endHeight;
    } else {
      logger_exports.warnOnce(`Annotation [${this.type}] can only be used with a numeric y-axis.`);
    }
    return bottom;
  }
  getDefaultColor(colorPickerType) {
    switch (colorPickerType) {
      case `fill-color`:
        return this.background.fill;
      case `line-color`:
        return this.stroke;
      case "text-color":
        return this.text.color;
    }
  }
  getDefaultOpacity(colorPickerType) {
    switch (colorPickerType) {
      case `fill-color`:
        return this.background.fillOpacity;
      case `line-color`:
        return this.strokeOpacity;
    }
  }
  getLineDash() {
    return getLineDash(this.lineDash, this.computedLineDash, this.lineStyle, this.strokeWidth);
  }
  getLineCap() {
    return getLineCap(this.lineCap, this.lineDash, this.lineStyle);
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], DisjointChannelProperties.prototype, "type", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DisjointChannelProperties.prototype, "startHeight", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DisjointChannelProperties.prototype, "endHeight", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], DisjointChannelProperties.prototype, "text", 2);

// packages/ag-charts-enterprise/src/features/annotations/line/lineProperties.ts
var LineTypeProperties = class extends Localisable(
  Cappable(Extendable(Stroke(LineStyle(StartEndProperties))))
) {
  constructor() {
    super(...arguments);
    this.text = new LineTextProperties();
  }
  getDefaultColor(colorPickerType) {
    switch (colorPickerType) {
      case "line-color":
        return this.stroke;
      case "text-color":
        return this.text.color;
    }
  }
  getDefaultOpacity() {
    return this.strokeOpacity;
  }
  getLineDash() {
    return getLineDash(this.lineDash, this.computedLineDash, this.lineStyle, this.strokeWidth);
  }
  getLineCap() {
    return getLineCap(this.lineCap, this.lineDash, this.lineStyle);
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], LineTypeProperties.prototype, "text", 2);
var ArrowProperties = class extends LineTypeProperties {
  constructor() {
    super(...arguments);
    this.type = "arrow" /* Arrow */;
    this.endCap = "arrow";
  }
  static is(value) {
    return isObject(value) && value.type === "arrow" /* Arrow */;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ArrowProperties.prototype, "type", 2);
var LineProperties = class extends LineTypeProperties {
  constructor() {
    super(...arguments);
    this.type = "line" /* Line */;
  }
  static is(value) {
    return isObject(value) && value.type === "line" /* Line */;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], LineProperties.prototype, "type", 2);

// packages/ag-charts-enterprise/src/features/annotations/properties/fibonacciProperties.ts
var FibonacciProperties = class extends LineTypeProperties {
  constructor() {
    super(...arguments);
    this.label = new LabelTextProperties();
    this.reverse = false;
    this.showFill = true;
    this.isMultiColor = true;
    this.strokes = [];
    this.bands = 10;
  }
  getDefaultColor(colorPickerType) {
    switch (colorPickerType) {
      case "line-color":
        return this.rangeStroke ?? this.stroke;
      case "text-color":
        return this.text.color;
    }
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], FibonacciProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FibonacciProperties.prototype, "reverse", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FibonacciProperties.prototype, "showFill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FibonacciProperties.prototype, "isMultiColor", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FibonacciProperties.prototype, "strokes", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FibonacciProperties.prototype, "rangeStroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FibonacciProperties.prototype, "bands", 2);

// packages/ag-charts-enterprise/src/features/annotations/fibonacci-retracement-trend-based/fibonacciRetracementTrendBasedProperties.ts
var FibonacciRetracementTrendBasedProperties = class extends FibonacciProperties {
  constructor() {
    super(...arguments);
    this.type = "fibonacci-retracement-trend-based" /* FibonacciRetracementTrendBased */;
    this.endRetracement = new PointProperties();
  }
  static is(value) {
    return isObject(value) && value.type === "fibonacci-retracement-trend-based" /* FibonacciRetracementTrendBased */;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], FibonacciRetracementTrendBasedProperties.prototype, "type", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FibonacciRetracementTrendBasedProperties.prototype, "endRetracement", 2);

// packages/ag-charts-enterprise/src/features/annotations/fibonacci-retracement/fibonacciRetracementProperties.ts
var FibonacciRetracementProperties = class extends FibonacciProperties {
  constructor() {
    super(...arguments);
    this.type = "fibonacci-retracement" /* FibonacciRetracement */;
  }
  static is(value) {
    return isObject(value) && value.type === "fibonacci-retracement" /* FibonacciRetracement */;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], FibonacciRetracementProperties.prototype, "type", 2);

// packages/ag-charts-enterprise/src/features/annotations/parallel-channel/parallelChannelProperties.ts
var ParallelChannelProperties = class extends Annotation(
  Background2(Line2(Handle(Extendable(Stroke(LineStyle(BaseProperties))))))
) {
  constructor() {
    super(...arguments);
    this.type = "parallel-channel" /* ParallelChannel */;
    this.middle = new ChannelAnnotationMiddleProperties();
    this.text = new ChannelTextProperties();
    this.snapToAngle = 45;
  }
  static is(value) {
    return isObject(value) && value.type === "parallel-channel" /* ParallelChannel */;
  }
  get bottom() {
    const bottom = {
      start: { x: this.start.x, y: this.start.y },
      end: { x: this.end.x, y: this.end.y }
    };
    if (typeof bottom.start.y === "number" && typeof bottom.end.y === "number") {
      bottom.start.y -= this.height;
      bottom.end.y -= this.height;
    } else {
      logger_exports.warnOnce(`Annotation [${this.type}] can only be used with a numeric y-axis.`);
    }
    return bottom;
  }
  getDefaultColor(colorPickerType) {
    switch (colorPickerType) {
      case `fill-color`:
        return this.background.fill;
      case `line-color`:
        return this.stroke;
      case "text-color":
        return this.text.color;
    }
  }
  getDefaultOpacity(colorPickerType) {
    switch (colorPickerType) {
      case `fill-color`:
        return this.background.fillOpacity;
      case `line-color`:
        return this.strokeOpacity;
    }
  }
  getLineDash() {
    return getLineDash(this.lineDash, this.computedLineDash, this.lineStyle, this.strokeWidth);
  }
  getLineCap() {
    return getLineCap(this.lineCap, this.lineDash, this.lineStyle);
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ParallelChannelProperties.prototype, "type", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ParallelChannelProperties.prototype, "height", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ParallelChannelProperties.prototype, "middle", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ParallelChannelProperties.prototype, "text", 2);

// packages/ag-charts-enterprise/src/features/annotations/text/textProperties.ts
var TextProperties = class extends TextualPointProperties {
  constructor() {
    super(...arguments);
    this.type = "text" /* Text */;
    this.position = "bottom";
  }
  static is(value) {
    return isObject(value) && value.type === "text" /* Text */;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], TextProperties.prototype, "type", 2);

// packages/ag-charts-enterprise/src/features/annotations/utils/types.ts
function isEphemeralType(datum) {
  return QuickDatePriceRangeProperties.is(datum);
}
function isLineType(datum) {
  return LineProperties.is(datum) || HorizontalLineProperties.is(datum) || VerticalLineProperties.is(datum) || ArrowProperties.is(datum) || isFibonacciType(datum);
}
function isChannelType(datum) {
  return DisjointChannelProperties.is(datum) || ParallelChannelProperties.is(datum);
}
function isFibonacciType(datum) {
  return FibonacciRetracementProperties.is(datum) || FibonacciRetracementTrendBasedProperties.is(datum);
}
function isTextType(datum) {
  return CalloutProperties.is(datum) || CommentProperties.is(datum) || NoteProperties.is(datum) || TextProperties.is(datum);
}
function isMeasurerType(datum) {
  return DateRangeProperties.is(datum) || PriceRangeProperties.is(datum) || DatePriceRangeProperties.is(datum) || QuickDatePriceRangeProperties.is(datum);
}

// packages/ag-charts-enterprise/src/features/annotations/utils/has.ts
function hasFontSize(datum) {
  return isTextType(datum) && !NoteProperties.is(datum);
}
function hasLineStyle(datum) {
  return isLineType(datum) || isChannelType(datum) || isMeasurerType(datum) && !QuickDatePriceRangeProperties.is(datum);
}
function hasLineColor(datum) {
  return isLineType(datum) || isChannelType(datum) || isMeasurerType(datum) || CalloutProperties.is(datum) || NoteProperties.is(datum);
}
function hasIconColor(datum) {
  return NoteProperties.is(datum);
}
function hasFillColor(datum) {
  return isChannelType(datum) || isMeasurerType(datum) || CalloutProperties.is(datum) || CommentProperties.is(datum) || ShapePointProperties.is(datum);
}
function hasTextColor(datum) {
  return isTextType(datum) && !NoteProperties.is(datum);
}
function hasLineText(datum) {
  return (isLineType(datum) || isChannelType(datum) || isMeasurerType(datum)) && !isEphemeralType(datum) && isObject(datum.text);
}

// packages/ag-charts-enterprise/src/features/annotations/utils/styles.ts
function setFontSize(datum, fontSize) {
  if ("fontSize" in datum)
    datum.fontSize = fontSize;
  if (hasLineText(datum))
    datum.text.fontSize = fontSize;
}
function setLineStyle(datum, style2) {
  const strokeWidth = style2?.strokeWidth ?? datum.strokeWidth ?? 1;
  const lineType = style2?.type ?? datum.lineStyle;
  const lineStyle = lineType ?? getLineStyle(datum.lineDash, lineType);
  const computedLineDash = getComputedLineDash(strokeWidth, lineStyle);
  datum.strokeWidth = strokeWidth;
  datum.computedLineDash = computedLineDash;
  datum.lineStyle = lineStyle;
  datum.lineCap = lineStyle === "dotted" ? "round" : void 0;
}
function setColor(datum, colorPickerType, colorOpacity, color2, opacity, isMultiColor) {
  switch (colorPickerType) {
    case `fill-color`: {
      if ("fill" in datum)
        datum.fill = color2;
      if ("fillOpacity" in datum)
        datum.fillOpacity = opacity;
      if ("background" in datum) {
        datum.background.fill = color2;
        datum.background.fillOpacity = opacity;
      }
      break;
    }
    case `line-color`: {
      if ("axisLabel" in datum) {
        datum.axisLabel.fill = color2;
        datum.axisLabel.fillOpacity = opacity;
        datum.axisLabel.stroke = color2;
        datum.axisLabel.strokeOpacity = opacity;
      }
      if ("fill" in datum && "fillOpacity" in datum && hasIconColor(datum)) {
        datum.fill = color2;
        datum.fillOpacity = opacity;
      } else {
        if ("strokeOpacity" in datum)
          datum.strokeOpacity = opacity;
        if ("isMultiColor" in datum && "rangeStroke" in datum) {
          datum.isMultiColor = isMultiColor;
          datum.rangeStroke = color2;
        } else if ("stroke" in datum) {
          datum.stroke = color2;
        }
      }
      break;
    }
    case `text-color`: {
      if ("color" in datum)
        datum.color = colorOpacity;
      if (hasLineText(datum))
        datum.text.color = color2;
      break;
    }
  }
}

// packages/ag-charts-enterprise/src/features/annotations/annotationDefaults.ts
var AnnotationDefaults = class {
  constructor() {
    this.mementoOriginatorKey = "annotation-defaults";
    this.colors = new Map(
      Object.values(AnnotationType).map((type) => [
        type,
        /* @__PURE__ */ new Map([
          ["line-color", void 0],
          ["fill-color", void 0],
          ["text-color", void 0]
        ])
      ])
    );
    this.fontSizes = /* @__PURE__ */ new Map([
      ["callout" /* Callout */, void 0],
      ["comment" /* Comment */, void 0],
      ["text" /* Text */, void 0],
      ["arrow" /* Arrow */, void 0],
      ["line" /* Line */, void 0],
      ["disjoint-channel" /* DisjointChannel */, void 0],
      ["parallel-channel" /* ParallelChannel */, void 0],
      ["date-range" /* DateRange */, void 0],
      ["price-range" /* PriceRange */, void 0],
      ["date-price-range" /* DatePriceRange */, void 0]
    ]);
    this.lineStyles = /* @__PURE__ */ new Map([
      ["line" /* Line */, void 0],
      ["horizontal-line" /* HorizontalLine */, void 0],
      ["vertical-line" /* VerticalLine */, void 0],
      ["disjoint-channel" /* DisjointChannel */, void 0],
      ["parallel-channel" /* ParallelChannel */, void 0],
      ["arrow" /* Arrow */, void 0],
      ["date-range" /* DateRange */, void 0],
      ["price-range" /* PriceRange */, void 0],
      ["date-price-range" /* DatePriceRange */, void 0]
    ]);
    this.lineTextAlignments = /* @__PURE__ */ new Map([
      ["line" /* Line */, void 0],
      ["horizontal-line" /* HorizontalLine */, void 0],
      ["vertical-line" /* VerticalLine */, void 0],
      ["disjoint-channel" /* DisjointChannel */, void 0],
      ["parallel-channel" /* ParallelChannel */, void 0],
      ["arrow" /* Arrow */, void 0],
      ["date-range" /* DateRange */, void 0],
      ["price-range" /* PriceRange */, void 0],
      ["date-price-range" /* DatePriceRange */, void 0]
    ]);
    this.lineTextPositions = /* @__PURE__ */ new Map([
      ["line" /* Line */, void 0],
      ["horizontal-line" /* HorizontalLine */, void 0],
      ["vertical-line" /* VerticalLine */, void 0],
      ["disjoint-channel" /* DisjointChannel */, void 0],
      ["parallel-channel" /* ParallelChannel */, void 0],
      ["arrow" /* Arrow */, void 0],
      ["date-range" /* DateRange */, void 0],
      ["price-range" /* PriceRange */, void 0],
      ["date-price-range" /* DatePriceRange */, void 0]
    ]);
    this.fibonacciOptions = /* @__PURE__ */ new Map([
      [
        "fibonacci-retracement" /* FibonacciRetracement */,
        {
          bands: void 0,
          reverse: void 0,
          showFill: void 0
        }
      ],
      [
        "fibonacci-retracement-trend-based" /* FibonacciRetracementTrendBased */,
        {
          bands: void 0,
          reverse: void 0,
          showFill: void 0
        }
      ]
    ]);
  }
  createMemento() {
    return {
      colors: deepClone(this.colors),
      fontSizes: deepClone(this.fontSizes),
      lineStyles: deepClone(this.lineStyles),
      lineTextAlignments: deepClone(this.lineTextAlignments),
      lineTextPositions: deepClone(this.lineTextPositions),
      fibonacciOptions: deepClone(this.fibonacciOptions)
    };
  }
  guardMemento(_blob) {
    return true;
  }
  restoreMemento(_version, _mementoVersion, blob) {
    this.colors = deepClone(blob.colors);
    this.fontSizes = deepClone(blob.fontSizes);
    this.lineStyles = deepClone(blob.lineStyles);
    this.lineTextAlignments = deepClone(blob.lineTextAlignments);
    this.lineTextPositions = deepClone(blob.lineTextPositions);
    this.fibonacciOptions = deepClone(blob.fibonacciOptions);
  }
  setDefaultColor(type, colorType, colorOpacity, color2, opacity, isMultiColor) {
    this.colors.get(type)?.set(colorType, [colorOpacity, color2, opacity, isMultiColor]);
  }
  setDefaultFontSize(type, fontSize) {
    this.fontSizes.set(type, fontSize);
  }
  setDefaultLineStyleType(type, lineStyleType) {
    const defaultStyle = this.lineStyles.get(type);
    if (defaultStyle) {
      defaultStyle.type = lineStyleType;
    } else {
      this.lineStyles.set(type, { type: lineStyleType });
    }
  }
  setDefaultLineStyleWidth(type, strokeWidth) {
    const defaultStyle = this.lineStyles.get(type);
    if (defaultStyle) {
      defaultStyle.strokeWidth = strokeWidth;
    } else {
      this.lineStyles.set(type, { strokeWidth });
    }
  }
  setDefaultLineTextAlignment(type, alignment) {
    this.lineTextAlignments.set(type, alignment);
  }
  setDefaultLineTextPosition(type, position) {
    this.lineTextPositions.set(type, position);
  }
  setDefaultFibonacciOptions(type, key, value) {
    if (type != "fibonacci-retracement" /* FibonacciRetracement */ && type != "fibonacci-retracement-trend-based" /* FibonacciRetracementTrendBased */)
      return;
    const options = this.fibonacciOptions.get(type);
    options[key] = value;
    this.fibonacciOptions.set(type, options);
  }
  applyDefaults(datum) {
    for (const [annotationType, colors] of this.colors) {
      if (datum.type !== annotationType)
        continue;
      for (const [colorPickerType, [colorOpacity, color2, opacity, isMultiColor] = []] of colors) {
        if (colorOpacity && color2 && opacity != null && isMultiColor != null) {
          setColor(datum, colorPickerType, colorOpacity, color2, opacity, isMultiColor);
        }
      }
    }
    for (const [annotationType, size] of this.fontSizes) {
      if (datum.type !== annotationType || size == null)
        continue;
      setFontSize(datum, size);
    }
    for (const [annotationType, style2] of this.lineStyles) {
      if (datum.type !== annotationType || style2 == null)
        continue;
      setLineStyle(datum, style2);
    }
    for (const [annotationType, position] of this.lineTextPositions) {
      if (datum.type !== annotationType || position == null)
        continue;
      datum.text.position = position;
    }
    for (const [annotationType, alignment] of this.lineTextAlignments) {
      if (datum.type !== annotationType || alignment == null)
        continue;
      datum.text.alignment = alignment;
    }
    for (const [annotationType, options] of this.fibonacciOptions) {
      if (datum.type !== annotationType || options == null)
        continue;
      for (const option of Object.keys(options)) {
        const value = options[option];
        if (value == null) {
          continue;
        }
        datum.set({ [option]: value });
      }
    }
  }
};

// packages/ag-charts-enterprise/src/components/color-picker/colorPickerTemplate.html
var colorPickerTemplate_default = '<div class="ag-charts-color-picker__palette" role="slider" tabindex="0"></div><div class="ag-charts-color-picker__color-row" role="presentation"><button class="ag-charts-color-picker__multi-color-button" tabindex="0" type="button" role="switch"></button> <input class="ag-charts-color-picker__hue-input" tabindex="0" type="range" min="0" max="360" value="0"></div><input class="ag-charts-color-picker__alpha-input" tabindex="0" type="range" min="0" max="1" value="1" step="0.01"> <label class="ag-charts-color-picker__color-field" role="presentation"><span class="ag-charts-color-picker__color-label" aria-hidden="true"></span> <input class="ag-charts-color-picker__color-input" tabindex="0" value="#000"></label>';

// packages/ag-charts-enterprise/src/components/color-picker/colorPicker.ts
var getHsva = (input) => {
  try {
    const color2 = Color.fromString(input);
    const [h, s, v] = color2.toHSB();
    return [h, s, v, color2.a];
  } catch {
    return;
  }
};
var ColorPicker = class extends module_support_exports.AnchoredPopover {
  constructor(ctx, options) {
    super(ctx, "color-picker", options);
    this.hasChanged = false;
    this.hideFns.push(() => {
      this.i18nUpdater = void 0;
      if (this.hasChanged)
        this.onChangeHide?.();
    });
    this.cleanup.register(this.ctx.eventsHub.on("locale:change", () => this.i18nUpdater?.()));
  }
  show(options) {
    this.hasChanged = false;
    this.onChangeHide = options.onChangeHide;
    const { element: element2, initialFocus } = this.createColorPicker(options);
    const popover = this.showWithChildren([element2], { initialFocus, ...options });
    popover.classList.add("ag-charts-color-picker");
    popover.setAttribute("role", "dialog");
  }
  createColorPicker(opts) {
    const { localeManager } = this.ctx;
    let isMultiColor = opts.isMultiColor ?? false;
    let [h, s, v, a] = getHsva(opts.color ?? "#f00") ?? [0, 1, 0.5, 1];
    a = opts.opacity ?? a;
    const colorPicker = createElement("div", "ag-charts-color-picker__content");
    colorPicker.innerHTML = colorPickerTemplate_default;
    colorPicker.ariaLabel = this.ctx.localeManager.t("ariaLabelColorPicker");
    const paletteInput = colorPicker.querySelector(".ag-charts-color-picker__palette");
    const hueInput = colorPicker.querySelector(".ag-charts-color-picker__hue-input");
    const multiColorButton = colorPicker.querySelector(
      ".ag-charts-color-picker__multi-color-button"
    );
    const alphaInput = colorPicker.querySelector(".ag-charts-color-picker__alpha-input");
    const colorInput = colorPicker.querySelector(".ag-charts-color-picker__color-input");
    const colorInputLabel = colorPicker.querySelector(".ag-charts-color-picker__color-label");
    const updatePaletteInputAriaValue = (first2) => {
      const key = { s: "ariaValueColorPalette", v: "ariaValueColorPaletteFirstV" }[first2];
      paletteInput.ariaValueText = localeManager.t(key, { s, v });
    };
    this.i18nUpdater = () => {
      paletteInput.ariaRoleDescription = localeManager.t("ariaRoleDescription2DSlider");
      paletteInput.ariaLabel = localeManager.t("ariaLabelColorPickerPalette");
      hueInput.ariaLabel = localeManager.t("ariaLabelColorPickerHue");
      multiColorButton.ariaLabel = localeManager.t("ariaLabelColorPickerMultiColor");
      alphaInput.ariaLabel = localeManager.t("ariaLabelColorPickerAlpha");
      colorInput.ariaLabel = localeManager.t("ariaLabelColor");
      updatePaletteInputAriaValue("s");
    };
    this.i18nUpdater();
    multiColorButton.classList.toggle(
      "ag-charts-color-picker__multi-color-button--hidden",
      !opts.hasMultiColorOption
    );
    const update = (trackChange = true) => {
      const color2 = Color.fromHSB(h, s, v, a);
      const colorString = color2.toHexString();
      colorPicker.style.setProperty("--h", `${h}`);
      colorPicker.style.setProperty("--s", `${s}`);
      colorPicker.style.setProperty("--v", `${v}`);
      colorPicker.style.setProperty("--a", `${a}`);
      colorPicker.style.setProperty("--color", colorString.slice(0, 7));
      colorPicker.style.setProperty("--color-a", colorString);
      hueInput.value = `${h}`;
      alphaInput.value = `${a}`;
      alphaInput.classList.toggle("ag-charts-color-picker__alpha-input--opaque", a === 1);
      multiColorButton.classList.toggle("ag-charts-color-picker__multi-color-button--active", isMultiColor);
      colorInputLabel.classList.toggle("ag-charts-color-picker__color-label--multi-color", isMultiColor);
      if (document.activeElement !== colorInput) {
        multiColorButton.ariaChecked = isMultiColor.toString();
        colorInput.value = isMultiColor ? localeManager.t("ariaLabelColorPickerMultiColor") : colorString.toUpperCase();
      }
      if (trackChange || opts.color == null) {
        const plainColor = Color.fromHSB(h, s, v, 1).toHexString();
        opts.onChange?.(colorString, plainColor, a, isMultiColor);
      }
      if (trackChange)
        this.hasChanged = true;
    };
    update(false);
    const preventDefault = (event) => event.preventDefault();
    const stopPropagation = (event) => event.stopPropagation();
    const beginPaletteInteraction = (e) => {
      e.preventDefault();
      const currentTarget = e.currentTarget;
      currentTarget.focus();
      const rect2 = currentTarget.getBoundingClientRect();
      const pointerMove = ({ clientX, clientY }) => {
        isMultiColor = false;
        s = Math.min(Math.max((clientX - rect2.left) / rect2.width, 0), 1);
        v = 1 - Math.min(Math.max((clientY - rect2.top) / rect2.height, 0), 1);
        update();
        updatePaletteInputAriaValue("s");
      };
      pointerMove(e);
      const pointerUp = attachListener(getWindow(), "pointermove", pointerMove);
      getWindow().addEventListener("pointerup", pointerUp, { once: true });
    };
    colorPicker.addEventListener("mousedown", stopPropagation);
    colorPicker.addEventListener("touchstart", stopPropagation);
    colorPicker.addEventListener("touchmove", stopPropagation);
    colorPicker.addEventListener("keydown", (e) => {
      e.stopPropagation();
      switch (e.key) {
        case "Enter":
        case "Escape":
          this.hide();
          break;
        default:
          return;
      }
      e.preventDefault();
    });
    paletteInput.addEventListener("pointerdown", beginPaletteInteraction);
    paletteInput.addEventListener("touchstart", preventDefault, { passive: false });
    paletteInput.addEventListener("touchmove", preventDefault, { passive: false });
    paletteInput.addEventListener("keydown", (e) => {
      if (e.key === "ArrowLeft") {
        s = clamp(0, s - 0.01, 1);
        updatePaletteInputAriaValue("s");
      } else if (e.key === "ArrowRight") {
        s = clamp(0, s + 0.01, 1);
        updatePaletteInputAriaValue("s");
      } else if (e.key === "ArrowUp") {
        v = clamp(0, v + 0.01, 1);
        updatePaletteInputAriaValue("v");
      } else if (e.key === "ArrowDown") {
        v = clamp(0, v - 0.01, 1);
        updatePaletteInputAriaValue("v");
      } else {
        return;
      }
      e.preventDefault();
      update();
    });
    paletteInput.addEventListener("focus", () => {
      updatePaletteInputAriaValue("s");
    });
    multiColorButton.addEventListener("click", () => {
      isMultiColor = !isMultiColor;
      update();
    });
    hueInput.addEventListener("input", (e) => {
      isMultiColor = false;
      h = e.currentTarget.valueAsNumber ?? 0;
      update();
    });
    alphaInput.addEventListener("input", (e) => {
      isMultiColor = false;
      a = e.currentTarget.valueAsNumber ?? 0;
      update();
    });
    colorInput.addEventListener("input", (e) => {
      isMultiColor = false;
      const hsva = getHsva(e.currentTarget.value);
      if (hsva == null)
        return;
      [h, s, v, a] = hsva;
      update();
    });
    colorInput.addEventListener("blur", () => update());
    colorInput.addEventListener("keydown", (e) => {
      if (e.key === "Enter") {
        e.currentTarget.blur();
        update();
      }
    });
    return { element: colorPicker, initialFocus: paletteInput };
  }
};

// packages/ag-charts-enterprise/src/features/toolbar/buttonProperties.ts
var ToolbarButtonProperties = class extends BaseProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ToolbarButtonProperties.prototype, "icon", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ToolbarButtonProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ToolbarButtonProperties.prototype, "ariaLabel", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ToolbarButtonProperties.prototype, "tooltip", 2);

// packages/ag-charts-enterprise/src/features/annotations/annotationsMenuOptions.ts
function channelMenuItemVisible(scale2) {
  return !(scale2 instanceof module_support_exports.LogScale) && !(scale2 instanceof module_support_exports.BandScale);
}
var LINE_ANNOTATION_ITEMS = [
  {
    label: "toolbarAnnotationsTrendLine",
    icon: "trend-line-drawing",
    value: "line" /* Line */
  },
  {
    label: "toolbarAnnotationsHorizontalLine",
    icon: "horizontal-line-drawing",
    value: "horizontal-line" /* HorizontalLine */
  },
  {
    label: "toolbarAnnotationsVerticalLine",
    icon: "vertical-line-drawing",
    value: "vertical-line" /* VerticalLine */
  },
  {
    label: "toolbarAnnotationsParallelChannel",
    icon: "parallel-channel-drawing",
    value: "parallel-channel" /* ParallelChannel */,
    visible: channelMenuItemVisible
  },
  {
    label: "toolbarAnnotationsDisjointChannel",
    icon: "disjoint-channel-drawing",
    value: "disjoint-channel" /* DisjointChannel */,
    visible: channelMenuItemVisible
  }
];
var FIBONACCI_ANNOTATION_ITEMS = [
  {
    label: "toolbarAnnotationsFibonacciRetracement",
    icon: "fibonacci-retracement-drawing",
    value: "fibonacci-retracement" /* FibonacciRetracement */
  },
  {
    label: "toolbarAnnotationsFibonacciRetracementTrendBased",
    icon: "fibonacci-retracement-trend-based-drawing",
    value: "fibonacci-retracement-trend-based" /* FibonacciRetracementTrendBased */
  }
];
var FIBONACCI_RATIO_ITEMS = [
  { label: "Fibonacci - Extended", value: 10 },
  { label: "Fibonacci - 6 Band", value: 6 },
  { label: "Fibonacci - 4 Band", value: 4 }
];
var TEXT_ANNOTATION_ITEMS = [
  { label: "toolbarAnnotationsText", icon: "text-annotation", value: "text" /* Text */ },
  { label: "toolbarAnnotationsComment", icon: "comment-annotation", value: "comment" /* Comment */ },
  { label: "toolbarAnnotationsCallout", icon: "callout-annotation", value: "callout" /* Callout */ },
  { label: "toolbarAnnotationsNote", icon: "note-annotation", value: "note" /* Note */ }
];
var SHAPE_ANNOTATION_ITEMS = [
  { label: "toolbarAnnotationsArrow", icon: "arrow-drawing", value: "arrow" /* Arrow */ },
  { label: "toolbarAnnotationsArrowUp", icon: "arrow-up-drawing", value: "arrow-up" /* ArrowUp */ },
  { label: "toolbarAnnotationsArrowDown", icon: "arrow-down-drawing", value: "arrow-down" /* ArrowDown */ }
];
var MEASURER_ANNOTATION_ITEMS = [
  {
    label: "toolbarAnnotationsQuickDatePriceRange",
    icon: "measurer-drawing",
    value: "quick-date-price-range" /* QuickDatePriceRange */
  },
  { label: "toolbarAnnotationsDateRange", icon: "date-range-drawing", value: "date-range" /* DateRange */ },
  { label: "toolbarAnnotationsPriceRange", icon: "price-range-drawing", value: "price-range" /* PriceRange */ },
  {
    label: "toolbarAnnotationsDatePriceRange",
    icon: "date-price-range-drawing",
    value: "date-price-range" /* DatePriceRange */
  }
];
var LINE_STROKE_WIDTH_ITEMS = [
  { strokeWidth: 1, label: "1", value: 1 },
  { strokeWidth: 2, label: "2", value: 2 },
  { strokeWidth: 3, label: "3", value: 3 },
  { strokeWidth: 4, label: "4", value: 4 },
  { strokeWidth: 8, label: "8", value: 8 }
];
var LINE_STYLE_TYPE_ITEMS = [
  { icon: "line-style-solid", altText: "iconAltTextLineStyleSolid", value: "solid" },
  { icon: "line-style-dashed", altText: "iconAltTextLineStyleDashed", value: "dashed" },
  { icon: "line-style-dotted", altText: "iconAltTextLineStyleDotted", value: "dotted" }
];
var TEXT_SIZE_ITEMS = [
  { label: "10", value: 10 },
  { label: "12", value: 12 },
  { label: "14", value: 14 },
  { label: "16", value: 16 },
  { label: "18", value: 18 },
  { label: "22", value: 22 },
  { label: "28", value: 28 },
  { label: "36", value: 36 },
  { label: "46", value: 46 }
];

// packages/ag-charts-enterprise/src/features/annotations/annotationOptionsToolbar.ts
var { FloatingToolbar: FloatingToolbar2, Menu: Menu2, ToolbarButtonWidget: ToolbarButtonWidget2 } = module_support_exports;
var AnnotationOptionsButtonProperties = class extends ToolbarButtonProperties {
  constructor() {
    super(...arguments);
    this.checkedOverrides = new ToolbarButtonProperties();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], AnnotationOptionsButtonProperties.prototype, "value", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AnnotationOptionsButtonProperties.prototype, "checkedOverrides", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AnnotationOptionsButtonProperties.prototype, "color", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AnnotationOptionsButtonProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AnnotationOptionsButtonProperties.prototype, "isMultiColor", 2);
var AnnotationOptionsButtonWidget = class extends ToolbarButtonWidget2 {
  update(options) {
    super.update(options);
    if (options.value === "line-stroke-width" /* LineStrokeWidth */) {
      this.updateLineStrokeWidth(options);
    }
    if (options.value === "fill-color" /* FillColor */ || options.value === "line-color" /* LineColor */ || options.value === "text-color" /* TextColor */) {
      this.updateFillColor(options);
    }
  }
  updateFillColor(options) {
    const element2 = this.getElement();
    element2.classList.add("ag-charts-annotations__color-picker-button");
    element2.classList.toggle("ag-charts-annotations__color-picker-button--multi-color", options.isMultiColor);
    element2.style.setProperty("--color", options.color ?? null);
  }
  updateLineStrokeWidth(options) {
    const element2 = this.getElement();
    element2.classList.add("ag-charts-annotations__stroke-width-button");
    element2.style.setProperty("--stroke-width", `${options.strokeWidth}px`);
  }
};
var FloatingAnnotationOptionsToolbar = class extends FloatingToolbar2 {
  createButtonWidget() {
    return new AnnotationOptionsButtonWidget(this.localeManager);
  }
};
var AnnotationOptionsToolbar = class extends BaseProperties {
  constructor(ctx, getActiveDatum) {
    super();
    this.ctx = ctx;
    this.getActiveDatum = getActiveDatum;
    this.enabled = true;
    this.buttons = new PropertiesArray(AnnotationOptionsButtonProperties);
    this.cleanup = new CleanupRegistry();
    this.events = new EventEmitter();
    this.visibleButtons = [];
    this.toolbar = new FloatingAnnotationOptionsToolbar(
      this.ctx,
      "ariaLabelAnnotationOptionsToolbar",
      "annotation-options"
    );
    this.colorPicker = new ColorPicker(this.ctx);
    this.textSizeMenu = new Menu2(this.ctx, "text-size");
    this.lineStyleTypeMenu = new Menu2(this.ctx, "annotations-line-style-type");
    this.lineStrokeWidthMenu = new Menu2(this.ctx, "annotations-line-stroke-width");
    this.cleanup.register(
      this.toolbar.addToolbarListener("button-pressed", this.onButtonPress.bind(this)),
      this.toolbar.addToolbarListener("toolbar-moved", this.onToolbarMoved.bind(this)),
      ctx.widgets.seriesWidget.addListener("drag-start", this.onDragStart.bind(this)),
      ctx.widgets.seriesWidget.addListener("drag-end", this.onDragEnd.bind(this)),
      () => {
        this.colorPicker.destroy();
        this.toolbar.destroy();
      }
    );
  }
  onDragStart() {
    this.toolbar.ignorePointerEvents();
  }
  onDragEnd() {
    this.toolbar.capturePointerEvents();
  }
  destroy() {
    this.cleanup.flush();
  }
  show() {
    if (!this.enabled)
      return;
    this.toolbar.show();
  }
  hide() {
    this.toolbar.hide();
  }
  updateButtons(datum) {
    if (!this.enabled)
      return;
    const visible = {
      ["line-style-type" /* LineStyleType */]: hasLineStyle(datum),
      ["line-stroke-width" /* LineStrokeWidth */]: hasLineStyle(datum),
      ["line-color" /* LineColor */]: hasLineColor(datum),
      ["text-color" /* TextColor */]: hasTextColor(datum),
      ["fill-color" /* FillColor */]: hasFillColor(datum),
      ["text-size" /* TextSize */]: hasFontSize(datum),
      ["settings" /* Settings */]: hasLineText(datum),
      ["lock" /* Lock */]: true,
      ["delete" /* Delete */]: true
    };
    this.visibleButtons = this.buttons.filter((button) => visible[button.value]);
    this.toolbar.clearButtons();
    this.toolbar.updateButtons(this.visibleButtons);
    this.refreshButtons(datum);
  }
  setAnchorScene(scene) {
    if (this.toolbar.hasBeenDragged())
      return;
    this.toolbar.setAnchor(scene.getAnchor());
  }
  hideOverlays() {
    this.toolbar.clearActiveButton();
    this.colorPicker.hide({ lastFocus: null });
    this.textSizeMenu.hide();
    this.lineStyleTypeMenu.hide();
    this.lineStrokeWidthMenu.hide();
    this.events.emit("hid-overlays", null);
  }
  clearActiveButton() {
    this.toolbar.clearActiveButton();
  }
  updateColors(datum) {
    this.updateColorPickerColor(
      "line-color" /* LineColor */,
      datum.getDefaultColor("line-color" /* LineColor */),
      datum.getDefaultOpacity("line-color" /* LineColor */),
      "isMultiColor" in datum && datum?.isMultiColor
    );
    this.updateColorPickerColor(
      "fill-color" /* FillColor */,
      datum.getDefaultColor("fill-color" /* FillColor */),
      datum.getDefaultOpacity("fill-color" /* FillColor */),
      "isMultiColor" in datum && datum?.isMultiColor
    );
    this.updateColorPickerColor(
      "text-color" /* TextColor */,
      datum.getDefaultColor("text-color" /* TextColor */),
      datum.getDefaultOpacity("text-color" /* TextColor */),
      "isMultiColor" in datum && datum?.isMultiColor
    );
  }
  updateColorPickerColor(colorPickerType, color2, opacity, isMultiColor) {
    if (color2 != null && opacity != null) {
      const { r, g, b } = Color.fromString(color2);
      color2 = Color.fromArray([r, g, b, opacity]).toHexString();
    }
    this.updateButtonByValue(colorPickerType, { color: color2, isMultiColor });
  }
  updateFontSize(fontSize) {
    this.updateButtonByValue("text-size" /* TextSize */, {
      label: fontSize == null ? void 0 : String(fontSize)
    });
  }
  updateLineStyleType(item) {
    this.updateButtonByValue("line-style-type" /* LineStyleType */, {
      icon: item.icon
    });
  }
  updateStrokeWidth(item) {
    this.updateButtonByValue("line-stroke-width" /* LineStrokeWidth */, {
      label: item.label,
      strokeWidth: item.value
    });
  }
  onButtonPress({
    event,
    button,
    buttonWidget
  }) {
    const datum = this.getActiveDatum();
    if (!datum)
      return;
    this.hideOverlays();
    switch (button.value) {
      case "line-style-type" /* LineStyleType */: {
        const lineStyle = hasLineStyle(datum) ? getLineStyle(datum.lineDash, datum.lineStyle) : void 0;
        this.lineStyleTypeMenu.show(buttonWidget, {
          items: LINE_STYLE_TYPE_ITEMS,
          ariaLabel: this.ctx.localeManager.t("toolbarAnnotationsLineStyle"),
          value: lineStyle,
          onPress: (item) => this.onLineStyleTypeMenuPress(item, datum),
          class: "ag-charts-annotations__line-style-type-menu"
        });
        break;
      }
      case "line-stroke-width" /* LineStrokeWidth */: {
        const strokeWidth = hasLineStyle(datum) ? datum.strokeWidth : void 0;
        this.lineStrokeWidthMenu.show(buttonWidget, {
          items: LINE_STROKE_WIDTH_ITEMS,
          ariaLabel: this.ctx.localeManager.t("toolbarAnnotationsLineStrokeWidth"),
          value: strokeWidth,
          onPress: (item) => this.onLineStrokeWidthMenuPress(item, datum),
          class: "ag-charts-annotations__line-stroke-width-menu"
        });
        break;
      }
      case "line-color" /* LineColor */:
      case "fill-color" /* FillColor */:
      case "text-color" /* TextColor */: {
        this.toolbar.toggleActiveButtonByIndex(button.index);
        this.colorPicker.show({
          color: datum?.getDefaultColor(button.value),
          opacity: datum?.getDefaultOpacity(button.value),
          sourceEvent: event.sourceEvent,
          hasMultiColorOption: "isMultiColor" in datum,
          isMultiColor: "isMultiColor" in datum && datum?.isMultiColor,
          onChange: datum == null ? void 0 : this.onColorPickerChange.bind(this, button.value, datum),
          onChangeHide: ((type) => {
            this.events.emit("saved-color", {
              type: datum.type,
              colorPickerType: button.value,
              color: datum.getDefaultColor(type)
            });
          }).bind(this, button.value)
        });
        break;
      }
      case "text-size" /* TextSize */: {
        const fontSize = isTextType(datum) ? datum.fontSize : void 0;
        this.textSizeMenu.show(buttonWidget, {
          items: TEXT_SIZE_ITEMS,
          ariaLabel: this.ctx.localeManager.t("toolbarAnnotationsTextSize"),
          value: fontSize,
          onPress: (item) => this.onTextSizeMenuPress(item, datum),
          class: "ag-charts-annotations__text-size-menu"
        });
        break;
      }
      case "delete" /* Delete */: {
        this.events.emit("pressed-delete", null);
        break;
      }
      case "lock" /* Lock */: {
        datum.locked = !datum.locked;
        this.refreshButtons(datum);
        this.events.emit("pressed-lock", { locked: datum.locked });
        break;
      }
      case "settings" /* Settings */: {
        this.toolbar.toggleActiveButtonByIndex(button.index);
        this.events.emit("pressed-settings", event);
        break;
      }
    }
  }
  onToolbarMoved(event) {
    const { buttonBounds, popoverBounds } = event;
    const colorPickerAnchor = { x: popoverBounds.x, y: popoverBounds.y + popoverBounds.height + 4 };
    const colorPickerFallbackAnchor = { y: popoverBounds.y - 4 };
    this.colorPicker.setAnchor(colorPickerAnchor, colorPickerFallbackAnchor);
    for (const [index, bounds] of buttonBounds.entries()) {
      const button = this.visibleButtons.at(index);
      if (!button)
        continue;
      const anchor = { x: bounds.x, y: bounds.y + bounds.height - 1 };
      const fallbackAnchor = { y: bounds.y };
      switch (button.value) {
        case "line-stroke-width" /* LineStrokeWidth */:
          this.lineStrokeWidthMenu.setAnchor(anchor, fallbackAnchor);
          break;
        case "line-style-type" /* LineStyleType */:
          this.lineStyleTypeMenu.setAnchor(anchor, fallbackAnchor);
          break;
        case "text-size" /* TextSize */:
          this.textSizeMenu.setAnchor(anchor, fallbackAnchor);
          break;
      }
    }
  }
  onColorPickerChange(colorPickerType, datum, colorOpacity, color2, opacity, isMultiColor) {
    this.events.emit("updated-color", {
      type: datum.type,
      colorPickerType,
      colorOpacity,
      color: color2,
      opacity,
      isMultiColor
    });
    this.updateColorPickerColor(colorPickerType, colorOpacity, opacity, isMultiColor);
  }
  onTextSizeMenuPress(item, datum) {
    if (!hasFontSize(datum))
      return;
    const fontSize = item.value;
    this.events.emit("updated-font-size", { type: datum.type, fontSize });
    this.textSizeMenu.hide();
    this.updateFontSize(fontSize);
  }
  onLineStyleTypeMenuPress(item, datum) {
    if (!hasLineStyle(datum))
      return;
    const type = item.value;
    this.events.emit("updated-line-style", { type: datum.type, lineStyleType: type });
    this.lineStyleTypeMenu.hide();
    this.updateLineStyleType(item);
  }
  onLineStrokeWidthMenuPress(item, datum) {
    if (!hasLineStyle(datum)) {
      return;
    }
    const strokeWidth = item.value;
    this.events.emit("updated-line-width", { type: datum.type, strokeWidth });
    this.lineStrokeWidthMenu.hide();
    this.updateStrokeWidth(item);
  }
  refreshButtons(datum) {
    const locked = datum.locked ?? false;
    for (const [index, button] of this.visibleButtons.entries()) {
      if (!button)
        continue;
      if (button.value === "lock" /* Lock */) {
        this.toolbar.toggleSwitchCheckedByIndex(index, locked);
        this.updateButtonByIndex(index, locked ? button.checkedOverrides.toJson() : button.toJson());
      } else {
        this.toolbar.toggleButtonEnabledByIndex(index, !locked);
      }
    }
    if (hasFontSize(datum))
      this.updateFontSize(datum.fontSize);
    this.updateColors(datum);
    this.updateLineStyles(datum);
  }
  updateLineStyles(datum) {
    if (!hasLineStyle(datum))
      return;
    const strokeWidth = datum.strokeWidth ?? 1;
    const lineStyleType = getLineStyle(datum.lineDash, datum.lineStyle);
    this.updateStrokeWidth({
      strokeWidth,
      value: strokeWidth,
      label: String(strokeWidth)
    });
    this.updateLineStyleType(
      LINE_STYLE_TYPE_ITEMS.find((item) => item.value === lineStyleType) ?? LINE_STYLE_TYPE_ITEMS[0]
    );
  }
  updateButtonByValue(value, change) {
    const index = this.visibleButtons.findIndex((button) => button.value === value);
    if (index === -1)
      return;
    this.updateButtonByIndex(index, change);
  }
  updateButtonByIndex(index, change) {
    const button = this.visibleButtons.at(index);
    if (!button)
      return;
    this.toolbar.updateButtonByIndex(index, { ...button.toJson(), ...change, value: change.value ?? button.value });
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], AnnotationOptionsToolbar.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AnnotationOptionsToolbar.prototype, "buttons", 2);

// packages/ag-charts-enterprise/src/features/annotations/states/dragState.ts
var DragStateMachine = class extends StateMachine {
  constructor(ctx) {
    const actionKeyChange = ({ context }) => {
      this.node?.drag(this.datum, this.offset, context, this.snapping);
      ctx.update();
    };
    super("idle", {
      idle: {
        dragStart: {
          target: "dragging",
          action: ({ offset, context }) => {
            this.hasMoved = false;
            this.dragStart = offset;
            this.offset = offset;
            this.node?.dragStart(this.datum, offset, context);
          }
        }
      },
      dragging: {
        keyDown: actionKeyChange,
        keyUp: actionKeyChange,
        drag: ({ offset, context }) => {
          this.hasMoved = vector_exports.lengthSquared(vector_exports.sub(offset, this.dragStart)) > 0;
          this.offset = offset;
          this.node?.drag(this.datum, offset, context, this.snapping);
          ctx.update();
        },
        dragEnd: {
          target: StateMachine.parent,
          action: () => {
            this.node?.stopDragging();
            if (this.hasMoved)
              ctx.recordAction("Move annotation");
            ctx.update();
          }
        }
      }
    });
    this.debug = debugLogger_exports.create(true, "annotations");
    this.hasMoved = false;
    this.snapping = false;
  }
};
__decorateClass([
  StateMachineProperty()
], DragStateMachine.prototype, "snapping", 2);
__decorateClass([
  StateMachineProperty()
], DragStateMachine.prototype, "datum", 2);
__decorateClass([
  StateMachineProperty()
], DragStateMachine.prototype, "node", 2);

// packages/ag-charts-enterprise/src/features/annotations/arrow-down/arrowDownProperties.ts
var ArrowDownProperties = class extends ShapePointProperties {
  constructor() {
    super(...arguments);
    this.type = "arrow-down" /* ArrowDown */;
  }
  static is(value) {
    return isObject(value) && value.type === "arrow-down" /* ArrowDown */;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ArrowDownProperties.prototype, "type", 2);

// packages/ag-charts-enterprise/src/features/annotations/scenes/annotationShape.ts
var AnnotationShape = class extends module_support_exports.Marker {
  // Use exact method for this, rather than the Marker's high performance approximation.
  isPointInPath(x, y) {
    this.updatePathIfDirty();
    return this.path.closedPath && this.path.isPointInPath(x, y);
  }
};

// packages/ag-charts-enterprise/src/features/annotations/scenes/handle.ts
var _Handle = class _Handle extends module_support_exports.Group {
  constructor() {
    super(...arguments);
    this.active = false;
    this.locked = false;
    this.visible = false;
    this.zIndex = 1;
  }
  drag(target) {
    const { handle: handle3, locked } = this;
    if (locked) {
      return { point: { x: handle3.x, y: handle3.y }, offset: { x: 0, y: 0 } };
    }
    return {
      point: target,
      offset: { x: target.x - handle3.x, y: target.y - handle3.y }
    };
  }
  toggleActive(active) {
    this.active = active;
    if (!active) {
      this.handle.strokeWidth = _Handle.INACTIVE_STROKE_WIDTH;
    }
  }
  toggleHovered(hovered) {
    this.glow.visible = !this.locked && hovered;
    this.glow.dirtyPath = true;
  }
  toggleDragging(dragging) {
    if (this.locked)
      return;
    this.handle.visible = !dragging;
    this.glow.visible = this.glow.visible && !dragging;
    this.handle.dirtyPath = true;
    this.glow.dirtyPath = true;
  }
  toggleLocked(locked) {
    this.locked = locked;
  }
  getCursor() {
    return void 0;
  }
  containsPoint(x, y) {
    return this.handle.containsPoint(x, y);
  }
};
_Handle.INACTIVE_STROKE_WIDTH = 2;
var Handle2 = _Handle;
var _InvariantHandle = class _InvariantHandle extends Handle2 {
  constructor() {
    super();
    this.handle = new AnnotationShape({ shape: "circle" });
    this.glow = new AnnotationShape({ shape: "circle" });
    this.append([this.handle]);
    this.handle.size = _InvariantHandle.HANDLE_SIZE;
    this.handle.strokeWidth = Handle2.INACTIVE_STROKE_WIDTH;
    this.handle.zIndex = 2;
  }
  update(styles) {
    this.handle.setProperties({ ...styles, strokeWidth: Handle2.INACTIVE_STROKE_WIDTH });
  }
  drag(target) {
    return { point: target, offset: { x: 0, y: 0 } };
  }
};
_InvariantHandle.HANDLE_SIZE = 7;
_InvariantHandle.GLOW_SIZE = 9;
var InvariantHandle = _InvariantHandle;
var _UnivariantHandle = class _UnivariantHandle extends Handle2 {
  constructor() {
    super();
    this.handle = new module_support_exports.Rect();
    this.glow = new module_support_exports.Rect();
    this.gradient = "horizontal";
    this.append([this.glow, this.handle]);
    this.handle.cornerRadius = _UnivariantHandle.CORNER_RADIUS;
    this.handle.width = _UnivariantHandle.HANDLE_SIZE;
    this.handle.height = _UnivariantHandle.HANDLE_SIZE;
    this.handle.strokeWidth = Handle2.INACTIVE_STROKE_WIDTH;
    this.handle.zIndex = 2;
    this.glow.cornerRadius = _UnivariantHandle.CORNER_RADIUS;
    this.glow.width = _UnivariantHandle.GLOW_SIZE;
    this.glow.height = _UnivariantHandle.GLOW_SIZE;
    this.glow.strokeWidth = 0;
    this.glow.fillOpacity = 0.2;
    this.glow.zIndex = 1;
    this.glow.visible = false;
  }
  toggleLocked(locked) {
    super.toggleLocked(locked);
    if (locked) {
      const offset = (_UnivariantHandle.HANDLE_SIZE - InvariantHandle.HANDLE_SIZE) / 2;
      this.handle.cornerRadius = 1;
      this.handle.fill = this.handle.stroke;
      this.handle.strokeWidth = 0;
      this.handle.x += offset;
      this.handle.y += offset;
      this.handle.width = InvariantHandle.HANDLE_SIZE;
      this.handle.height = InvariantHandle.HANDLE_SIZE;
      this.glow.width = InvariantHandle.GLOW_SIZE;
      this.glow.height = InvariantHandle.GLOW_SIZE;
    } else {
      this.handle.cornerRadius = _UnivariantHandle.CORNER_RADIUS;
      this.handle.width = _UnivariantHandle.HANDLE_SIZE;
      this.handle.height = _UnivariantHandle.HANDLE_SIZE;
      this.glow.width = _UnivariantHandle.GLOW_SIZE;
      this.glow.height = _UnivariantHandle.GLOW_SIZE;
      if (this.cachedStyles) {
        this.handle.setProperties(this.cachedStyles);
      }
    }
  }
  update(styles) {
    this.cachedStyles = { ...styles };
    if (!this.active) {
      delete styles.strokeWidth;
    }
    if (this.locked) {
      delete styles.fill;
      delete styles.strokeWidth;
      const offset = (_UnivariantHandle.HANDLE_SIZE - InvariantHandle.HANDLE_SIZE) / 2;
      styles.x -= offset;
      styles.y -= offset;
      this.cachedStyles.x -= offset;
      this.cachedStyles.y -= offset;
    }
    this.handle.setProperties(styles);
    this.glow.setProperties({
      ...styles,
      x: (styles.x ?? this.glow.x) - 2,
      y: (styles.y ?? this.glow.y) - 2,
      strokeWidth: 0,
      fill: styles.stroke
    });
  }
  drag(target) {
    if (this.locked) {
      return { point: target, offset: { x: 0, y: 0 } };
    }
    if (this.gradient === "vertical") {
      return {
        point: { x: target.x, y: this.handle.y },
        offset: { x: target.x - this.handle.x, y: 0 }
      };
    }
    return {
      point: { x: this.handle.x, y: target.y },
      offset: { x: 0, y: target.y - this.handle.y }
    };
  }
  getCursor() {
    if (this.locked)
      return;
    return this.gradient === "vertical" ? "col-resize" : "row-resize";
  }
};
_UnivariantHandle.HANDLE_SIZE = 12;
_UnivariantHandle.GLOW_SIZE = 16;
_UnivariantHandle.CORNER_RADIUS = 4;
var UnivariantHandle = _UnivariantHandle;
var _DivariantHandle = class _DivariantHandle extends Handle2 {
  constructor() {
    super();
    this.handle = new AnnotationShape({ shape: "circle" });
    this.glow = new AnnotationShape({ shape: "circle" });
    this.append([this.glow, this.handle]);
    this.handle.size = _DivariantHandle.HANDLE_SIZE;
    this.handle.strokeWidth = Handle2.INACTIVE_STROKE_WIDTH;
    this.handle.zIndex = 2;
    this.glow.size = _DivariantHandle.GLOW_SIZE;
    this.glow.strokeWidth = 0;
    this.glow.fillOpacity = 0.2;
    this.glow.zIndex = 1;
    this.glow.visible = false;
  }
  toggleLocked(locked) {
    super.toggleLocked(locked);
    if (locked) {
      this.handle.fill = this.handle.stroke;
      this.handle.strokeWidth = 0;
      this.handle.size = InvariantHandle.HANDLE_SIZE;
      this.glow.size = InvariantHandle.GLOW_SIZE;
    } else {
      this.handle.size = _DivariantHandle.HANDLE_SIZE;
      this.glow.size = _DivariantHandle.GLOW_SIZE;
      if (this.cachedStyles) {
        this.handle.setProperties(this.cachedStyles);
      }
    }
  }
  update(styles) {
    this.cachedStyles = { ...styles };
    if (!this.active) {
      delete styles.strokeWidth;
    }
    if (this.locked) {
      delete styles.fill;
      delete styles.strokeWidth;
    }
    this.handle.setProperties(styles);
    this.glow.setProperties({ ...styles, strokeWidth: 0, fill: styles.stroke });
  }
  getCursor() {
    return "pointer";
  }
};
_DivariantHandle.HANDLE_SIZE = 11;
_DivariantHandle.GLOW_SIZE = 17;
var DivariantHandle = _DivariantHandle;

// packages/ag-charts-enterprise/src/features/annotations/scenes/annotationScene.ts
var AnnotationScene = class extends module_support_exports.Group {
  constructor() {
    super(...arguments);
    this.name = "AnnotationScene";
    this.zIndex = 12 /* CHART_ANNOTATION */;
  }
  static isCheck(value, type) {
    return isObject(value) && Object.hasOwn(value, "type") && value.type === type;
  }
  toggleHovered(hovered, active, readOnly) {
    if (readOnly === true)
      return;
    this.toggleHandles(hovered || active);
  }
  computeBBoxWithoutHandles() {
    return module_support_exports.Transformable.toCanvas(
      this,
      module_support_exports.Group.computeChildrenBBox(this.excludeChildren({ instance: Handle2 }))
    );
  }
  updateNode(constructor, node, isConfigured) {
    if (!isConfigured && node) {
      node.remove();
      return;
    }
    if (isConfigured && node == null) {
      node = new constructor();
      this.appendChild(node);
    }
    return node;
  }
};

// packages/ag-charts-enterprise/src/features/annotations/utils/coords.ts
var { ContinuousScale: ContinuousScale2 } = module_support_exports;
function snapPoint(offset, context, snapping = false, origin3, angleStep = 1) {
  if (!snapping)
    return invertCoords(offset, context);
  const center2 = origin3 ? convertPoint(origin3, context) : vector_exports.origin();
  return invertCoords(snapToAngle(offset, center2, angleStep), context);
}
function snapToAngle(vector, center2, step) {
  const radial = vector_exports.sub(vector, center2);
  const stepRadians = toRadians(step);
  const theta = Math.round(vector_exports.angle(radial) / stepRadians) * stepRadians;
  return vector_exports.rotate(radial, theta, center2);
}
function getDragStartState(points, context) {
  const dragState = {};
  for (const [name, point] of entries(points)) {
    dragState[name] = convertPoint(point, context);
  }
  return dragState;
}
function translate(vectors, translation, context, options = {
  overflowContinuous: 0,
  translateVectors: void 0,
  invertYVectors: void 0,
  snap: void 0
}) {
  const { xAxis, yAxis } = context;
  const vectorNames = Object.keys(vectors);
  const overflowsX = [];
  const overflowsY = [];
  const translateVectors = new Set(options.translateVectors ?? vectorNames);
  const invertYVectors = new Set(options.invertYVectors ?? []);
  const movingVectors = /* @__PURE__ */ new Set([...translateVectors, ...invertYVectors]);
  const invertYTranslation = vector_exports.multiply(translation, vector_exports.from(1, -1));
  for (const name of vectorNames) {
    if (movingVectors.has(name)) {
      vectors[name] = vector_exports.add(vectors[name], invertYVectors.has(name) ? invertYTranslation : translation);
      if (options.snap) {
        vectors[name] = snapToAngle(vectors[name], options.snap.vectors[name], options.snap.angle);
      }
    }
    overflowsX.push(xAxis.getRangeOverflow(vectors[name].x));
    overflowsY.push(yAxis.getRangeOverflow(vectors[name].y));
  }
  const sortNumbersAbs = (a, b) => Math.abs(a) - Math.abs(b);
  const overflowDirection = (scale2, directionTranslation, overflows) => {
    if (options.overflowContinuous === 0 || !ContinuousScale2.is(scale2)) {
      return overflows.toSorted(sortNumbersAbs).at(-1) ?? 0;
    }
    if (vectorNames.length === movingVectors.size) {
      return overflows.toSorted(sortNumbersAbs).at(-options.overflowContinuous - 1) ?? 0;
    }
    if (overflows.filter((value) => value !== 0).length <= options.overflowContinuous) {
      return 0;
    }
    const newTranslatedOverflows = overflows.filter(
      (value, index) => value !== 0 && Math.abs(value) <= Math.abs(directionTranslation) && movingVectors.has(vectorNames[index])
    );
    return newTranslatedOverflows.toSorted(sortNumbersAbs).at(-1) ?? 0;
  };
  const overflow = vector_exports.from(
    overflowDirection(xAxis.scale, translation.x, overflowsX),
    overflowDirection(yAxis.scale, translation.y, overflowsY)
  );
  if (!vector_exports.equal(overflow, vector_exports.origin())) {
    for (const name of vectorNames) {
      if (!movingVectors.has(name))
        continue;
      vectors[name] = vector_exports.round(vector_exports.sub(vectors[name], overflow), 4);
    }
  }
  const result = {};
  for (const name of vectorNames) {
    result[name] = invertCoords(vectors[name], context);
  }
  return result;
}

// packages/ag-charts-enterprise/src/features/annotations/scenes/pointScene.ts
var PointScene = class extends AnnotationScene {
  constructor() {
    super(...arguments);
    this.handle = new DivariantHandle();
    this.anchor = {
      x: 0,
      y: 0,
      position: "above"
    };
  }
  update(datum, context) {
    const coords = convertPoint(datum, context);
    this.updateHandle(datum, coords);
    this.anchor = this.updateAnchor(datum, coords, context);
  }
  dragStart(datum, target, context) {
    this.dragState = {
      offset: target,
      ...getDragStartState({ handle: datum }, context)
    };
  }
  drag(datum, target, context) {
    const { dragState } = this;
    if (!datum.isWriteable() || !dragState)
      return;
    const { point } = translate({ point: dragState.handle }, vector_exports.sub(target, dragState.offset), context);
    datum.x = point.x;
    datum.y = point.y;
  }
  translate(datum, translation, context) {
    if (!datum.isWriteable())
      return;
    const { point } = translate({ point: convertPoint(datum, context) }, translation, context);
    datum.x = point.x;
    datum.y = point.y;
  }
  toggleHandles(show) {
    this.handle.visible = Boolean(show);
    this.handle.toggleHovered(this.activeHandle === "handle");
  }
  toggleActive(active) {
    this.toggleHandles(active);
    this.handle.toggleActive(active);
  }
  stopDragging() {
    this.handle.toggleDragging(false);
  }
  copy(datum, copiedDatum, context) {
    const coords = convertPoint(datum, context);
    const point = invertCoords({ x: coords.x - 30, y: coords.y - 30 }, context);
    copiedDatum.x = point.x;
    copiedDatum.y = point.y;
    return copiedDatum;
  }
  getAnchor() {
    return this.anchor;
  }
  getCursor() {
    return "pointer";
  }
  containsPoint(x, y) {
    const { handle: handle3 } = this;
    this.activeHandle = void 0;
    if (handle3.containsPoint(x, y)) {
      this.activeHandle = "handle";
      return true;
    }
    return false;
  }
  getNodeAtCoords(x, y) {
    if (this.handle.containsPoint(x, y))
      return "handle";
  }
  updateHandle(datum, point, bbox) {
    const { x, y } = this.getHandleCoords(datum, point, bbox);
    const styles = this.getHandleStyles(datum);
    this.handle.update({ ...styles, x, y });
    this.handle.toggleLocked(datum.locked ?? false);
  }
  updateAnchor(datum, point, context) {
    const coords = this.getHandleCoords(datum, point);
    return {
      x: coords.x + context.seriesRect.x,
      y: coords.y + context.seriesRect.y,
      position: this.anchor.position
    };
  }
  getHandleCoords(_datum, point, _bbox) {
    return {
      x: point.x,
      y: point.y
    };
  }
  getHandleStyles(datum) {
    return {
      fill: datum.handle.fill,
      stroke: datum.handle.stroke,
      strokeOpacity: datum.handle.strokeOpacity,
      strokeWidth: datum.handle.strokeWidth
    };
  }
};

// packages/ag-charts-enterprise/src/features/annotations/scenes/shapePointScene.ts
var ShapePointScene = class extends PointScene {
  constructor() {
    super();
    this.append([this.handle]);
  }
  update(datum, context) {
    super.update(datum, context);
    const coords = convertPoint(datum, context);
    this.updateShape(datum, coords);
  }
  updateShape(datum, point) {
    this.updateShapeStyles(datum);
    this.updateShapePath(datum, point);
  }
  updateShapeStyles(datum) {
    const { shape } = this;
    shape.fill = datum.fill;
    shape.fillOpacity = datum.fillOpacity ?? 1;
  }
  updateShapePath(datum, point) {
    const { shape } = this;
    shape.x = point.x;
    shape.y = point.y;
    shape.size = datum.size;
  }
  containsPoint(x, y) {
    return super.containsPoint(x, y) || this.shape.containsPoint(x, y);
  }
  getNodeAtCoords(x, y) {
    if (this.shape.containsPoint(x, y))
      return "shape";
    return super.getNodeAtCoords(x, y);
  }
};

// packages/ag-charts-enterprise/src/features/annotations/arrow-up/arrowUpScene.ts
var arrowUpPoints = [
  [0.5, 0],
  [1, 0.5],
  [0.75, 0.5],
  [0.75, 1],
  [0.25, 1],
  [0.25, 0.5],
  [0, 0.5]
];
function arrowUp(params) {
  module_support_exports.drawMarkerUnitPolygon(params, arrowUpPoints);
}
arrowUp.anchor = { x: 0.5, y: 0 };
var ArrowUpScene = class extends ShapePointScene {
  constructor() {
    super();
    this.type = "arrow-up" /* ArrowUp */;
    this.shape = new AnnotationShape({ shape: arrowUp });
    this.append([this.shape]);
  }
  static is(value) {
    return AnnotationScene.isCheck(value, "arrow-up" /* ArrowUp */);
  }
  getHandleCoords(datum, point) {
    const halfSize = DivariantHandle.HANDLE_SIZE / 2;
    const handleCoords = super.getHandleCoords(datum, point);
    handleCoords.y -= halfSize;
    return handleCoords;
  }
};

// packages/ag-charts-enterprise/src/features/annotations/arrow-down/arrowDownScene.ts
var arrowDownPoints = arrowUpPoints.map(([x, y]) => [x, 1 - y]);
function arrowDown(params) {
  module_support_exports.drawMarkerUnitPolygon(params, arrowDownPoints);
}
arrowDown.anchor = { x: 0.5, y: 1 };
var ArrowDownScene = class extends ShapePointScene {
  constructor() {
    super();
    this.type = "arrow-down" /* ArrowDown */;
    this.shape = new AnnotationShape({ shape: arrowDown });
    this.append([this.shape]);
  }
  static is(value) {
    return AnnotationScene.isCheck(value, "arrow-down" /* ArrowDown */);
  }
  updateAnchor(datum, point, context) {
    const anchor = super.updateAnchor(datum, point, context);
    anchor.y -= datum.size;
    return anchor;
  }
  getHandleCoords(datum, point) {
    const halfSize = DivariantHandle.HANDLE_SIZE / 2;
    const handleCoords = super.getHandleCoords(datum, point);
    handleCoords.y += halfSize;
    return handleCoords;
  }
};

// packages/ag-charts-enterprise/src/features/annotations/states/pointState.ts
var PointStateMachine = class extends StateMachine {
  constructor(ctx) {
    const actionCreate = ({ point }) => {
      const datum = this.createDatum();
      datum.set({ x: point.x, y: point.y });
      ctx.create(datum);
    };
    const actionFirstRender = () => {
      this.node?.toggleActive(true);
      ctx.showAnnotationOptions();
      ctx.update();
    };
    super("start", {
      start: {
        click: {
          target: "waiting-first-render",
          action: actionCreate
        },
        drag: {
          target: "waiting-first-render",
          action: actionCreate
        },
        cancel: StateMachine.parent,
        reset: StateMachine.parent
      },
      "waiting-first-render": {
        render: {
          target: StateMachine.parent,
          action: actionFirstRender
        }
      }
    });
    this.debug = debugLogger_exports.create(true, "annotations");
  }
};
__decorateClass([
  StateMachineProperty()
], PointStateMachine.prototype, "node", 2);

// packages/ag-charts-enterprise/src/features/annotations/arrow-down/arrowDownState.ts
var ArrowDownStateMachine = class extends PointStateMachine {
  createDatum() {
    return new ArrowDownProperties();
  }
};

// packages/ag-charts-enterprise/src/features/annotations/arrow-down/arrowDownConfig.ts
var arrowDownConfig = {
  type: "arrow-down" /* ArrowDown */,
  datum: ArrowDownProperties,
  scene: ArrowDownScene,
  isDatum: ArrowDownProperties.is,
  translate: (node, datum, translation, context) => {
    if (ArrowDownProperties.is(datum) && ArrowDownScene.is(node))
      node.translate(datum, translation, context);
  },
  copy: (node, datum, copiedDatum, context) => {
    if (ArrowDownProperties.is(datum) && ArrowDownProperties.is(copiedDatum) && ArrowDownScene.is(node)) {
      return node.copy(datum, copiedDatum, context);
    }
  },
  update: (node, datum, context) => {
    if (ArrowDownProperties.is(datum) && ArrowDownScene.is(node)) {
      node.update(datum, context);
    }
  },
  createState: (ctx, { createDatum }) => new ArrowDownStateMachine({
    ...ctx,
    create: createDatum("arrow-down" /* ArrowDown */)
  }),
  dragState: (ctx) => new DragStateMachine(ctx)
};

// packages/ag-charts-enterprise/src/features/annotations/arrow-up/arrowUpProperties.ts
var ArrowUpProperties = class extends ShapePointProperties {
  constructor() {
    super(...arguments);
    this.type = "arrow-up" /* ArrowUp */;
  }
  static is(value) {
    return isObject(value) && value.type === "arrow-up" /* ArrowUp */;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ArrowUpProperties.prototype, "type", 2);

// packages/ag-charts-enterprise/src/features/annotations/arrow-up/arrowUpState.ts
var ArrowUpStateMachine = class extends PointStateMachine {
  createDatum() {
    return new ArrowUpProperties();
  }
};

// packages/ag-charts-enterprise/src/features/annotations/arrow-up/arrowUpConfig.ts
var arrowUpConfig = {
  type: "arrow-up" /* ArrowUp */,
  datum: ArrowUpProperties,
  scene: ArrowUpScene,
  isDatum: ArrowUpProperties.is,
  translate: (node, datum, translation, context) => {
    if (ArrowUpProperties.is(datum) && ArrowUpScene.is(node))
      node.translate(datum, translation, context);
  },
  copy: (node, datum, copiedDatum, context) => {
    if (ArrowUpProperties.is(datum) && ArrowUpProperties.is(copiedDatum) && ArrowUpScene.is(node)) {
      return node.copy(datum, copiedDatum, context);
    }
  },
  update: (node, datum, context) => {
    if (ArrowUpProperties.is(datum) && ArrowUpScene.is(node)) {
      node.update(datum, context);
    }
  },
  createState: (ctx, { createDatum }) => new ArrowUpStateMachine({
    ...ctx,
    create: createDatum("arrow-up" /* ArrowUp */)
  }),
  dragState: (ctx) => new DragStateMachine(ctx)
};

// packages/ag-charts-enterprise/src/features/annotations/scenes/linearScene.ts
var LinearScene = class extends AnnotationScene {
  constructor() {
    super(...arguments);
    this.overflowContinuous = 0;
  }
  extendLine({ x1, y1, x2, y2 }, datum, context) {
    const linePoints = { x1, y1, x2, y2 };
    if (!datum.extendStart && !datum.extendEnd) {
      return linePoints;
    }
    const [left, right] = boundsIntersections(linePoints, context.yAxis.bounds);
    const isFlippedX = linePoints.x2 < linePoints.x1;
    const isFlippedY = linePoints.y1 >= linePoints.y2;
    const isVertical = linePoints.x2 === linePoints.x1;
    if (datum.extendEnd) {
      if (isVertical) {
        linePoints.y2 = isFlippedY ? right.y : left.y;
      } else {
        linePoints.x2 = isFlippedX ? left.x : right.x;
        linePoints.y2 = isFlippedX ? left.y : right.y;
      }
    }
    if (datum.extendStart) {
      if (isVertical) {
        linePoints.y1 = isFlippedY ? left.y : right.y;
      } else {
        linePoints.x1 = isFlippedX ? right.x : left.x;
        linePoints.y1 = isFlippedX ? right.y : left.y;
      }
    }
    return linePoints;
  }
  dragStart(datum, target, context) {
    this.dragState = {
      offset: target,
      ...getDragStartState({ start: datum.start, end: datum.end }, context)
    };
  }
  drag(datum, target, context, snapping) {
    if (!datum.isWriteable())
      return;
    if (this.activeHandle) {
      this.dragHandle(datum, target, context, snapping);
    } else {
      this.dragAll(datum, target, context);
    }
  }
  dragAll(datum, target, context) {
    const { dragState } = this;
    if (!dragState)
      return;
    this.translatePoints(datum, dragState.start, dragState.end, vector_exports.sub(target, dragState.offset), context);
  }
  translate(datum, translation, context) {
    if (!datum.isWriteable())
      return;
    this.translatePoints(
      datum,
      convertPoint(datum.start, context),
      convertPoint(datum.end, context),
      translation,
      context
    );
  }
  copy(datum, copiedDatum, context) {
    const coords = convertLine(datum, context);
    if (!coords) {
      return;
    }
    const bbox = this.computeBBoxWithoutHandles();
    const translation = { x: -bbox.width / 2, y: -bbox.height / 2 };
    this.translatePoints(copiedDatum, vector4_exports.start(coords), vector4_exports.end(coords), translation, context);
    return copiedDatum;
  }
  translatePoints(datum, start2, end3, translation, context) {
    const vectors = this.getTranslatePointsVectors(start2, end3);
    const points = translate(vectors, translation, context, {
      overflowContinuous: this.overflowContinuous
    });
    datum.start.x = points.start.x;
    datum.end.x = points.end.x;
    datum.start.y = points.start.y;
    datum.end.y = points.end.y;
  }
  getTranslatePointsVectors(start2, end3) {
    return { start: start2, end: end3 };
  }
};

// packages/ag-charts-enterprise/src/features/annotations/scenes/startEndScene.ts
var StartEndScene = class extends LinearScene {
  constructor() {
    super(...arguments);
    this.start = new DivariantHandle();
    this.end = new DivariantHandle();
    this.anchor = {
      x: 0,
      y: 0,
      position: "above"
    };
  }
  update(datum, context) {
    const coords = convertLine(datum, context);
    if (coords == null) {
      return;
    }
    this.updateHandles(datum, coords);
    this.updateAnchor(datum, coords, context);
  }
  toggleHandles(show) {
    if (typeof show === "boolean") {
      this.start.visible = show;
      this.end.visible = show;
    } else {
      for (const [handle3, visible] of entries(show)) {
        this[handle3].visible = visible;
      }
    }
    this.start.toggleHovered(this.activeHandle === "start");
    this.end.toggleHovered(this.activeHandle === "end");
  }
  toggleActive(active) {
    this.toggleHandles(active);
    this.start.toggleActive(active);
    this.end.toggleActive(active);
  }
  dragHandle(datum, target, context, snapping) {
    const { activeHandle, dragState } = this;
    if (!activeHandle || !dragState)
      return;
    this[activeHandle].toggleDragging(true);
    const snapHandle = activeHandle === "start" ? "end" : "start";
    const snap = snapping ? { vectors: { [activeHandle]: convertPoint(datum[snapHandle], context) }, angle: datum.snapToAngle } : void 0;
    const { [activeHandle]: point } = translate(
      { [activeHandle]: dragState[activeHandle] },
      vector_exports.sub(target, dragState.offset),
      context,
      { overflowContinuous: 0, snap }
    );
    datum[activeHandle].x = point.x;
    datum[activeHandle].y = point.y;
  }
  stopDragging() {
    this.start.toggleDragging(false);
    this.end.toggleDragging(false);
  }
  getAnchor() {
    return this.anchor;
  }
  getCursor() {
    return "pointer";
  }
  containsPoint(x, y) {
    const { start: start2, end: end3 } = this;
    this.activeHandle = void 0;
    if (start2.containsPoint(x, y)) {
      this.activeHandle = "start";
      return true;
    }
    if (end3.containsPoint(x, y)) {
      this.activeHandle = "end";
      return true;
    }
    return false;
  }
  getNodeAtCoords(x, y) {
    if (this.start.containsPoint(x, y) || this.end.containsPoint(x, y))
      return "handle";
  }
  updateHandles(datum, coords, bbox) {
    this.start.update({
      ...this.getHandleStyles(datum, "start"),
      ...this.getHandleCoords(datum, coords, "start")
    });
    this.end.update({
      ...this.getHandleStyles(datum, "end"),
      ...this.getHandleCoords(datum, coords, "end", bbox)
    });
    this.start.toggleLocked(datum.locked ?? false);
    this.end.toggleLocked(datum.locked ?? false);
  }
  updateAnchor(_datum, coords, context, _bbox) {
    this.anchor = {
      x: coords.x1 + context.seriesRect.x,
      y: coords.y1 + context.seriesRect.y,
      position: this.anchor.position
    };
  }
  getHandleCoords(_datum, coords, handle3, _bbox) {
    return handle3 === "start" ? vector4_exports.start(coords) : vector4_exports.end(coords);
  }
  getHandleStyles(datum, _handle) {
    return {
      fill: datum.handle.fill,
      stroke: datum.handle.stroke,
      strokeOpacity: datum.handle.strokeOpacity,
      strokeWidth: datum.handle.strokeWidth
    };
  }
};

// packages/ag-charts-enterprise/src/features/annotations/scenes/textualStartEndScene.ts
var TextualStartEndScene = class extends StartEndScene {
  constructor() {
    super(...arguments);
    this.label = new module_support_exports.Text({ zIndex: 1 });
    this.anchor = {
      x: 0,
      y: 0,
      position: "above-left"
    };
  }
  setTextInputBBox(bbox) {
    this.textInputBBox = bbox;
    this.markDirty("TextualStartEndScene");
  }
  update(datum, context) {
    const coords = convertLine(datum, context);
    if (coords == null) {
      return;
    }
    const bbox = this.getTextBBox(datum, coords);
    this.updateLabel(datum, bbox, coords);
    this.updateHandles(datum, coords, bbox);
    this.updateShape(datum, bbox, coords);
    this.updateAnchor(datum, coords, context, bbox);
  }
  containsPoint(x, y) {
    return super.containsPoint(x, y) || this.label.containsPoint(x, y);
  }
  getNodeAtCoords(x, y) {
    if (this.label.containsPoint(x, y))
      return "text";
    return super.getNodeAtCoords(x, y);
  }
  getTextBBox(datum, coords) {
    const { text: text2 } = datum.getText();
    return getBBox(datum, text2, vector4_exports.end(coords), this.textInputBBox);
  }
  updateLabel(datum, bbox, coords) {
    const { text: text2, isPlaceholder } = datum.getText();
    updateTextNode(this.label, text2, isPlaceholder, datum, this.getLabelCoords(datum, bbox, coords));
  }
  updateShape(_datum, _textBBox, _coords) {
  }
  getLabelCoords(_datum, _bbox, coords) {
    return vector4_exports.end(coords);
  }
  getHandleStyles(datum, handle3) {
    return {
      ...super.getHandleStyles(datum, handle3),
      stroke: datum.handle.stroke ?? datum.color
    };
  }
};

// packages/ag-charts-enterprise/src/features/annotations/callout/calloutScene.ts
var { drawCorner: drawCorner2, Path: Path5 } = module_support_exports;
var CalloutScene = class extends TextualStartEndScene {
  constructor() {
    super();
    this.type = "callout" /* Callout */;
    this.shape = new Path5();
    this.append([this.shape, this.label, this.start, this.end]);
  }
  static is(value) {
    return AnnotationScene.isCheck(value, "callout" /* Callout */);
  }
  drag(datum, target, context, snapping) {
    if (!datum.isWriteable())
      return;
    if (this.activeHandle === "end") {
      this.dragHandle(datum, target, context, snapping);
    } else {
      this.dragAll(datum, target, context);
    }
  }
  getLabelCoords(datum, bbox, coords) {
    const padding2 = datum.getPadding();
    const {
      bodyBounds = {
        x: 0,
        y: 0,
        width: 0,
        height: 0
      }
    } = this.getDimensions(datum, bbox, coords) ?? {};
    return {
      x: bodyBounds.x + padding2.left,
      y: bodyBounds.y - padding2.bottom
    };
  }
  getHandleStyles(datum, handle3) {
    return handle3 === "start" ? {
      fill: datum.handle.fill,
      stroke: datum.handle.stroke ?? datum.stroke,
      strokeOpacity: datum.handle.strokeOpacity,
      strokeWidth: datum.handle.strokeWidth
    } : { fill: void 0, strokeWidth: 0 };
  }
  updateAnchor(datum, coords, context, bbox) {
    const { bodyBounds } = this.getDimensions(datum, bbox, coords) ?? {};
    const bounds = bodyBounds ?? bbox;
    this.anchor = {
      x: bounds.x + context.seriesRect.x,
      y: bounds.y + context.seriesRect.y - bounds.height,
      position: this.anchor.position
    };
  }
  updateShape(datum, textBox, coords) {
    const { shape } = this;
    shape.fill = datum.fill;
    shape.fillOpacity = datum.fillOpacity ?? 1;
    shape.stroke = datum.stroke;
    shape.strokeWidth = datum.strokeWidth ?? 1;
    shape.strokeOpacity = datum.strokeOpacity ?? 1;
    const { tailPoint, bodyBounds } = this.getDimensions(datum, textBox, coords) ?? {};
    if (!tailPoint || !bodyBounds) {
      return;
    }
    this.updatePath(tailPoint, bodyBounds);
  }
  updatePath(tailPoint, bodyBounds) {
    const { x: tailX, y: tailY } = tailPoint;
    const { x, y, width: width2, height: height2 } = bodyBounds;
    const top = y - height2;
    const right = x + width2;
    const placement = this.calculateCalloutPlacement({ x: tailX, y: tailY }, bodyBounds);
    const cornerRadius = 8;
    const pathParams2 = [
      {
        coordinates: {
          x0: x,
          x1: x + cornerRadius,
          y0: top + cornerRadius,
          y1: top,
          cx: placement === `topLeft` ? tailX : x + cornerRadius,
          cy: placement === `topLeft` ? tailY : top + cornerRadius
        },
        type: placement === `topLeft` ? "calloutCorner" : "corner"
      },
      {
        coordinates: {
          x0: x + cornerRadius,
          x1: right - cornerRadius,
          y0: top,
          y1: top,
          cx: tailX,
          cy: tailY
        },
        type: placement === `top` ? "calloutSide" : "side"
      },
      {
        coordinates: {
          x0: right - cornerRadius,
          x1: right,
          y0: top,
          y1: top + cornerRadius,
          cx: placement === `topRight` ? tailX : right - cornerRadius,
          cy: placement === `topRight` ? tailY : top + cornerRadius
        },
        type: placement === `topRight` ? "calloutCorner" : "corner"
      },
      {
        coordinates: {
          x0: right,
          x1: right,
          y0: top + cornerRadius,
          y1: y - cornerRadius,
          cx: tailX,
          cy: tailY
        },
        type: placement === `right` ? "calloutSide" : "side"
      },
      {
        coordinates: {
          x0: right,
          x1: right - cornerRadius,
          y0: y - cornerRadius,
          y1: y,
          cx: placement === `bottomRight` ? tailX : right - cornerRadius,
          cy: placement === `bottomRight` ? tailY : y - cornerRadius
        },
        type: placement === `bottomRight` ? "calloutCorner" : "corner"
      },
      {
        coordinates: {
          x0: right - cornerRadius,
          x1: x + cornerRadius,
          y0: y,
          y1: y,
          cx: tailX,
          cy: tailY
        },
        type: placement === `bottom` ? "calloutSide" : "side"
      },
      {
        coordinates: {
          x0: x + cornerRadius,
          x1: x,
          y0: y,
          y1: y - cornerRadius,
          cx: placement === `bottomLeft` ? tailX : x + cornerRadius,
          cy: placement === `bottomLeft` ? tailY : y - cornerRadius
        },
        type: placement === `bottomLeft` ? "calloutCorner" : "corner"
      },
      {
        coordinates: {
          x0: x,
          x1: x,
          y0: y - cornerRadius,
          y1: top + cornerRadius,
          cx: tailX,
          cy: tailY
        },
        type: placement === `left` ? "calloutSide" : "side"
      }
    ];
    const { path } = this.shape;
    path.clear();
    path.moveTo(x, top + cornerRadius);
    for (const { coordinates, type } of pathParams2) {
      this.drawPath(path, coordinates, cornerRadius, type);
    }
    path.closePath();
  }
  drawPath(path, { x0, y0, x1, y1, cx, cy }, cornerRadius, type) {
    const sideTailRadius = 6;
    switch (type) {
      case "calloutCorner": {
        path.lineTo(cx, cy);
        path.lineTo(x1, y1);
        break;
      }
      case "corner": {
        drawCorner2(
          path,
          {
            x0,
            x1,
            y0,
            y1,
            cx,
            cy
          },
          cornerRadius,
          false
        );
        break;
      }
      case "calloutSide": {
        if (x0 === x1) {
          const direction = y0 > y1 ? -1 : 1;
          const midY = Math.min(y0, y1) + Math.abs(y0 - y1) / 2;
          path.lineTo(x0, midY - sideTailRadius * direction);
          path.lineTo(cx, cy);
          path.lineTo(x0, midY + sideTailRadius * direction);
          path.lineTo(x1, y1);
        } else {
          const direction = x0 > x1 ? -1 : 1;
          const midX = Math.min(x0, x1) + Math.abs(x1 - x0) / 2;
          path.lineTo(midX - sideTailRadius * direction, y0);
          path.lineTo(cx, cy);
          path.lineTo(midX + sideTailRadius * direction, y0);
          path.lineTo(x1, y1);
        }
        break;
      }
      case "side":
      default: {
        path.lineTo(x1, y1);
        break;
      }
    }
  }
  calculateCalloutPlacement(placement, bounds) {
    const right = bounds.x + bounds.width;
    const top = bounds.y - bounds.height;
    let xPlacement;
    let yPlacement;
    if (placement.x > right) {
      xPlacement = "right";
    } else if (placement.x < bounds.x) {
      xPlacement = "left";
    }
    if (placement.y > bounds.y) {
      yPlacement = "bottom";
    } else if (placement.y < top) {
      yPlacement = "top";
    }
    if (xPlacement && yPlacement) {
      return `${yPlacement}${xPlacement[0].toUpperCase()}${xPlacement.substring(1)}`;
    } else {
      return yPlacement ?? xPlacement;
    }
  }
  getDimensions(datum, textBox, coords) {
    const { fontSize } = datum;
    const padding2 = datum.getPadding();
    const horizontalPadding = padding2.left + padding2.right;
    const verticalPadding = padding2.top + padding2.bottom;
    const width2 = textBox.width + horizontalPadding;
    const height2 = Math.max(textBox.height + verticalPadding, fontSize + verticalPadding);
    return {
      tailPoint: {
        x: coords.x1,
        y: coords.y1
      },
      bodyBounds: {
        x: textBox.x,
        y: textBox.y,
        width: width2,
        height: height2
      }
    };
  }
  containsPoint(x, y) {
    const { start: start2, end: end3, shape } = this;
    this.activeHandle = void 0;
    if (start2.containsPoint(x, y)) {
      this.activeHandle = "start";
      return true;
    }
    const bodyContainsPoint = end3.containsPoint(x, y) || shape.containsPoint(x, y);
    if (bodyContainsPoint) {
      this.activeHandle = "end";
    }
    return bodyContainsPoint;
  }
};

// packages/ag-charts-enterprise/src/features/annotations/states/textualStateUtils.ts
function guardCancelAndExit({ key }) {
  return key === "Escape";
}
function guardSaveAndExit({ key, shiftKey }) {
  return !shiftKey && key === "Enter";
}

// packages/ag-charts-enterprise/src/features/annotations/states/textualStartEndState.ts
var TextualStartEndStateMachine = class extends StateMachine {
  constructor(ctx) {
    const actionCreate = ({ point }) => {
      const datum = this.createDatum();
      datum.set({ start: point, end: point, visible: true });
      ctx.create(datum);
    };
    const actionFirstRender = () => {
      const { node } = this;
      node?.toggleActive(true);
      node?.toggleHandles({ start: true });
    };
    const onStartEditing = () => {
      ctx.showTextInput();
      if (this.datum)
        this.datum.visible = false;
    };
    const onStopEditing = () => {
      ctx.hideTextInput();
      if (this.datum)
        this.datum.visible = true;
      ctx.deselect();
    };
    const actionUpdateTextInputBBox = (bbox) => {
      this.node?.setTextInputBBox(bbox);
      ctx.update();
    };
    const onEndHover = ({ point }) => {
      const { datum, node } = this;
      datum?.set({ end: point });
      node?.toggleActive(true);
      node?.toggleHandles({ end: false });
      ctx.update();
    };
    const onEndClick = () => {
      ctx.showAnnotationOptions();
      this.node?.toggleHandles({ end: true });
    };
    const actionColor = ({
      colorPickerType,
      colorOpacity,
      color: color2,
      opacity,
      isMultiColor
    }) => {
      const { datum } = this;
      if (!datum)
        return;
      if (colorPickerType === "text-color") {
        ctx.updateTextInputColor(color2);
      }
      setColor(datum, colorPickerType, colorOpacity, color2, opacity, isMultiColor);
      ctx.update();
    };
    const actionFontSize = (fontSize) => {
      const { datum, node } = this;
      if (!datum || !node || !isTextType(datum))
        return;
      datum.fontSize = fontSize;
      ctx.updateTextInputFontSize(fontSize);
      ctx.update();
    };
    const actionCancel = () => {
      ctx.delete();
    };
    const actionSave = ({ textInputValue, bbox }) => {
      const { datum } = this;
      if (bbox != null && textInputValue != null && textInputValue.length > 0) {
        if (!isTextType(datum)) {
          return;
        }
        const wrappedText = maybeWrapText(datum, textInputValue, bbox.width);
        datum?.set({ text: wrappedText });
        ctx.update();
        ctx.recordAction(`Create ${datum?.type} annotation`);
      } else {
        ctx.delete();
      }
    };
    super("start", {
      start: {
        click: {
          target: "waiting-first-render",
          action: actionCreate
        },
        dragStart: {
          target: "waiting-first-render",
          action: actionCreate
        },
        cancel: StateMachine.parent,
        reset: StateMachine.parent
      },
      "waiting-first-render": {
        render: {
          target: "end",
          action: actionFirstRender
        }
      },
      end: {
        hover: onEndHover,
        drag: onEndHover,
        click: {
          target: "edit",
          action: onEndClick
        },
        dragEnd: {
          target: "edit",
          action: onEndClick
        },
        reset: {
          target: StateMachine.parent,
          action: actionCancel
        },
        cancel: {
          target: StateMachine.parent,
          action: actionCancel
        }
      },
      edit: {
        onEnter: onStartEditing,
        updateTextInputBBox: actionUpdateTextInputBBox,
        color: actionColor,
        fontSize: actionFontSize,
        textInput: [
          {
            guard: guardCancelAndExit,
            target: StateMachine.parent,
            action: actionCancel
          },
          {
            guard: guardSaveAndExit,
            target: StateMachine.parent,
            action: actionSave
          }
        ],
        click: {
          target: StateMachine.parent,
          action: actionSave
        },
        dragStart: {
          target: StateMachine.parent,
          action: actionSave
        },
        resize: {
          target: StateMachine.parent,
          action: actionSave
        },
        onExit: onStopEditing,
        cancel: {
          target: StateMachine.parent,
          action: actionCancel
        }
      }
    });
    this.debug = debugLogger_exports.create(true, "annotations");
  }
};
__decorateClass([
  StateMachineProperty()
], TextualStartEndStateMachine.prototype, "datum", 2);
__decorateClass([
  StateMachineProperty()
], TextualStartEndStateMachine.prototype, "node", 2);

// packages/ag-charts-enterprise/src/features/annotations/callout/calloutState.ts
var CalloutStateMachine = class extends TextualStartEndStateMachine {
  createDatum() {
    return new CalloutProperties();
  }
};

// packages/ag-charts-enterprise/src/features/annotations/callout/calloutConfig.ts
var calloutConfig = {
  type: "callout" /* Callout */,
  datum: CalloutProperties,
  scene: CalloutScene,
  isDatum: CalloutProperties.is,
  translate: (node, datum, transition, context) => {
    if (CalloutProperties.is(datum) && CalloutScene.is(node))
      return node.translate(datum, transition, context);
  },
  copy: (node, datum, copiedDatum, context) => {
    if (CalloutProperties.is(datum) && CalloutProperties.is(copiedDatum) && CalloutScene.is(node)) {
      return node.copy(datum, copiedDatum, context);
    }
  },
  update: (node, datum, context) => {
    if (CalloutProperties.is(datum) && CalloutScene.is(node)) {
      node.update(datum, context);
    }
  },
  createState: (ctx, { createDatum }) => new CalloutStateMachine({
    ...ctx,
    create: createDatum("callout" /* Callout */)
  }),
  dragState: (ctx) => new DragStateMachine(ctx)
};

// packages/ag-charts-enterprise/src/features/annotations/scenes/textualPointScene.ts
var TextualPointScene = class extends PointScene {
  constructor() {
    super(...arguments);
    this.label = new module_support_exports.Text({ zIndex: 1 });
    this.anchor = {
      x: 0,
      y: 0,
      position: "above-left"
    };
  }
  setTextInputBBox(bbox) {
    this.textInputBBox = bbox;
    this.markDirty("TextualPointScene");
  }
  update(datum, context) {
    const coords = convertPoint(datum, context);
    const bbox = this.getTextBBox(datum, coords, context);
    this.updateLabel(datum, bbox);
    this.updateHandle(datum, coords, bbox);
    this.updateShape(datum, bbox);
    this.anchor = this.updateAnchor(datum, bbox, context);
  }
  copy(datum, copiedDatum, context) {
    const coords = convertPoint(datum, context);
    const bbox = this.getTextBBox(datum, coords, context);
    const padding2 = datum.getPadding();
    const horizontalPadding = padding2.left + padding2.right;
    const verticalPadding = padding2.top + padding2.bottom;
    const xOffset = (bbox.width + horizontalPadding) / 2;
    const yOffset = bbox.height + verticalPadding;
    const point = invertCoords({ x: coords.x - xOffset, y: coords.y - yOffset }, context);
    copiedDatum.x = point.x;
    copiedDatum.y = point.y;
    return copiedDatum;
  }
  containsPoint(x, y) {
    const { label } = this;
    return super.containsPoint(x, y) || label.visible && label.containsPoint(x, y);
  }
  getNodeAtCoords(x, y) {
    if (this.label.visible && this.label.containsPoint(x, y))
      return "text";
    return super.getNodeAtCoords(x, y);
  }
  getTextBBox(datum, coords, _context) {
    const { text: text2 } = datum.getText();
    return getBBox(datum, text2, { x: coords.x, y: coords.y }, this.textInputBBox);
  }
  updateLabel(datum, bbox) {
    const { text: text2, isPlaceholder } = datum.getText();
    updateTextNode(
      this.label,
      text2,
      isPlaceholder,
      datum,
      this.getLabelCoords(datum, bbox),
      this.getTextBaseline(datum)
    );
  }
  updateShape(_datum, _bbox) {
  }
  updateAnchor(_datum, bbox, context) {
    return {
      x: bbox.x + context.seriesRect.x,
      y: bbox.y + context.seriesRect.y - bbox.height,
      position: this.anchor.position
    };
  }
  getLabelCoords(_datum, bbox) {
    return bbox;
  }
  getTextBaseline(datum) {
    return datum.position == "center" ? "middle" : datum.position;
  }
  getHandleCoords(_datum, _coords, bbox) {
    return bbox;
  }
  getHandleStyles(datum) {
    const styles = super.getHandleStyles(datum);
    styles.stroke = datum.handle.stroke ?? datum.color;
    return styles;
  }
};

// packages/ag-charts-enterprise/src/features/annotations/comment/commentScene.ts
var { drawCorner: drawCorner3 } = module_support_exports;
var CommentScene = class extends TextualPointScene {
  constructor() {
    super();
    this.type = "comment" /* Comment */;
    this.shape = new module_support_exports.Path();
    this.append([this.shape, this.label, this.handle]);
  }
  static is(value) {
    return AnnotationScene.isCheck(value, "comment" /* Comment */);
  }
  updateShape(datum, bbox) {
    const { shape } = this;
    shape.fill = datum.fill;
    shape.fillOpacity = datum.fillOpacity ?? 1;
    shape.stroke = datum.stroke ?? "transparent";
    shape.strokeWidth = datum.strokeWidth ?? 1;
    shape.strokeOpacity = datum.strokeOpacity ?? 1;
    this.updatePath(datum, bbox);
  }
  getLabelCoords(datum, point) {
    const padding2 = datum.getPadding();
    return {
      x: point.x + padding2.left,
      y: point.y - padding2.bottom
    };
  }
  getHandleStyles(datum) {
    return {
      fill: datum.handle.fill,
      stroke: datum.handle.stroke ?? datum.stroke ?? datum.fill,
      strokeOpacity: datum.handle.strokeOpacity,
      strokeWidth: datum.handle.strokeWidth
    };
  }
  updateAnchor(datum, bbox, context) {
    const anchor = super.updateAnchor(datum, bbox, context);
    const padding2 = datum.getPadding();
    anchor.y -= padding2.bottom + padding2.top;
    return anchor;
  }
  updatePath(datum, bbox) {
    const padding2 = datum.getPadding();
    const { x, y } = bbox;
    let { width: width2, height: height2 } = bbox;
    const { fontSize } = datum;
    const horizontalPadding = padding2.left + padding2.right;
    const verticalPadding = padding2.top + padding2.bottom;
    width2 = width2 + horizontalPadding;
    height2 = Math.max(height2 + verticalPadding, fontSize + verticalPadding);
    const top = y - height2;
    const right = x + width2;
    const cornerRadius = (calcLineHeight(fontSize, ANNOTATION_TEXT_LINE_HEIGHT) + verticalPadding) / 2;
    const { path } = this.shape;
    path.clear();
    path.moveTo(x, y);
    path.lineTo(x, top + cornerRadius);
    drawCorner3(
      path,
      {
        x0: x,
        x1: x + cornerRadius,
        y0: top + cornerRadius,
        y1: top,
        cx: x + cornerRadius,
        cy: top + cornerRadius
      },
      cornerRadius,
      false
    );
    path.lineTo(right - cornerRadius, top);
    drawCorner3(
      path,
      {
        x0: right - cornerRadius,
        x1: right,
        y0: top,
        y1: top + cornerRadius,
        cx: right - cornerRadius,
        cy: top + cornerRadius
      },
      cornerRadius,
      false
    );
    path.lineTo(right, y - cornerRadius);
    drawCorner3(
      path,
      {
        x0: right,
        x1: right - cornerRadius,
        y0: y - cornerRadius,
        y1: y,
        cx: right - cornerRadius,
        cy: y - cornerRadius
      },
      cornerRadius,
      false
    );
    path.closePath();
  }
  containsPoint(x, y) {
    return super.containsPoint(x, y) || this.shape.containsPoint(x, y);
  }
};

// packages/ag-charts-enterprise/src/features/annotations/states/textualPointState.ts
var TextualPointStateMachine = class extends StateMachine {
  constructor(ctx) {
    const actionCreate = ({ point }) => {
      const datum = this.createDatum();
      datum.set({ x: point.x, y: point.y });
      ctx.create(datum);
    };
    const actionFirstRender = () => {
      this.node?.toggleActive(true);
      ctx.showAnnotationOptions();
      ctx.update();
    };
    const onStartEditing = () => {
      ctx.showTextInput();
      if (this.datum) {
        this.datum.visible = false;
      }
    };
    const onStopEditing = () => {
      ctx.hideTextInput();
      if (this.datum)
        this.datum.visible = true;
      ctx.deselect();
    };
    const actionUpdateTextInputBBox = (bbox) => {
      this.node?.setTextInputBBox(bbox);
      ctx.update();
    };
    const actionColor = ({
      colorPickerType,
      colorOpacity,
      color: color2,
      opacity,
      isMultiColor
    }) => {
      if (!this.datum)
        return;
      if (colorPickerType === "text-color") {
        ctx.updateTextInputColor(color2);
      }
      setColor(this.datum, colorPickerType, colorOpacity, color2, opacity, isMultiColor);
      ctx.update();
    };
    const actionFontSize = (fontSize) => {
      const { datum, node } = this;
      if (!datum || !node || !isTextType(datum))
        return;
      datum.fontSize = fontSize;
      ctx.updateTextInputFontSize(fontSize);
      ctx.update();
    };
    const actionCancel = () => {
      ctx.delete();
    };
    const actionSave = ({ textInputValue, bbox }) => {
      if (bbox != null && textInputValue != null && textInputValue.length > 0) {
        const { datum } = this;
        if (!isTextType(datum)) {
          return;
        }
        const wrappedText = maybeWrapText(datum, textInputValue, bbox.width);
        datum?.set({ text: wrappedText });
        ctx.update();
        ctx.recordAction(`Create ${datum?.type} annotation`);
      } else {
        ctx.delete();
      }
    };
    super("start", {
      start: {
        click: {
          target: "waiting-first-render",
          action: actionCreate
        },
        dragStart: {
          target: "waiting-first-render",
          action: actionCreate
        },
        cancel: StateMachine.parent,
        reset: StateMachine.parent
      },
      "waiting-first-render": {
        render: {
          target: "edit",
          action: actionFirstRender
        }
      },
      edit: {
        onEnter: onStartEditing,
        updateTextInputBBox: actionUpdateTextInputBBox,
        color: actionColor,
        fontSize: actionFontSize,
        textInput: [
          {
            guard: guardCancelAndExit,
            target: StateMachine.parent,
            action: actionCancel
          },
          {
            guard: guardSaveAndExit,
            target: StateMachine.parent,
            action: actionSave
          }
        ],
        click: {
          target: StateMachine.parent,
          action: actionSave
        },
        dragStart: {
          target: StateMachine.parent,
          action: actionSave
        },
        resize: {
          target: StateMachine.parent,
          action: actionSave
        },
        onExit: onStopEditing,
        cancel: {
          target: StateMachine.parent,
          action: actionCancel
        }
      }
    });
    this.debug = debugLogger_exports.create(true, "annotations");
  }
};
__decorateClass([
  StateMachineProperty()
], TextualPointStateMachine.prototype, "datum", 2);
__decorateClass([
  StateMachineProperty()
], TextualPointStateMachine.prototype, "node", 2);

// packages/ag-charts-enterprise/src/features/annotations/comment/commentState.ts
var CommentStateMachine = class extends TextualPointStateMachine {
  createDatum() {
    return new CommentProperties();
  }
};

// packages/ag-charts-enterprise/src/features/annotations/comment/commentConfig.ts
var commentConfig = {
  type: "comment" /* Comment */,
  datum: CommentProperties,
  scene: CommentScene,
  isDatum: CommentProperties.is,
  translate: (node, datum, translation, context) => {
    if (CommentProperties.is(datum) && CommentScene.is(node))
      node.translate(datum, translation, context);
  },
  copy: (node, datum, copiedDatum, context) => {
    if (CommentProperties.is(datum) && CommentProperties.is(copiedDatum) && CommentScene.is(node)) {
      return node.copy(datum, copiedDatum, context);
    }
  },
  update: (node, datum, context) => {
    if (CommentProperties.is(datum) && CommentScene.is(node)) {
      node.update(datum, context);
    }
  },
  createState: (ctx, { createDatum }) => new CommentStateMachine({
    ...ctx,
    create: createDatum("comment" /* Comment */)
  }),
  dragState: (ctx) => new DragStateMachine(ctx)
};

// packages/ag-charts-enterprise/src/features/annotations/scenes/axisLabelScene.ts
var { calculateLabelTranslation: calculateLabelTranslation2 } = module_support_exports;
var AxisLabelScene = class extends module_support_exports.Group {
  constructor() {
    super({ name: "AnnotationAxisLabelGroup" });
    this.label = new module_support_exports.Text({ zIndex: 1 });
    this.rect = new module_support_exports.Rect();
    const { label } = this;
    label.fontSize = 12;
    label.fontFamily = "Verdana, sans-serif";
    label.fill = "black";
    label.textBaseline = "middle";
    label.textAlign = "center";
    this.append([this.rect, this.label]);
  }
  update(opts) {
    this.updateLabel(opts);
    this.updateRect(opts);
    this.updatePosition(opts);
  }
  updateLabel({ value, styles, context }) {
    const { fontWeight: fontWeight2, fontSize, fontStyle, fontFamily, textAlign, color: color2 = "white", formatter: formatter2 } = styles;
    const text2 = formatter2 ? formatter2({ value }) : context.formatScaleValue(value, "annotation-label");
    this.label.setProperties({
      fontWeight: fontWeight2,
      fontSize,
      fontStyle,
      fontFamily,
      textAlign,
      fill: color2,
      text: text2
    });
  }
  updateRect({ styles }) {
    const { rect: rect2 } = this;
    const { cornerRadius, fill, fillOpacity, stroke: stroke3, strokeOpacity } = styles;
    rect2.fill = fill;
    rect2.fillOpacity = fillOpacity ?? 1;
    rect2.stroke = stroke3;
    rect2.strokeOpacity = strokeOpacity ?? 1;
    rect2.cornerRadius = cornerRadius ?? 0;
  }
  updatePosition({ x, y, context, styles: { padding: padding2 } }) {
    const { label, rect: rect2 } = this;
    const labelBBox = label.getBBox()?.clone();
    const horizontalPadding = padding2 ?? 8;
    const verticalPadding = padding2 ?? 4;
    const { xTranslation, yTranslation } = calculateLabelTranslation2({
      yDirection: true,
      padding: context.labelPadding,
      position: context.position ?? "left",
      bbox: labelBBox
    });
    labelBBox.grow(horizontalPadding, "horizontal");
    labelBBox.grow(verticalPadding, "vertical");
    const translationX = x + xTranslation;
    const translationY = y + yTranslation;
    label.x = translationX;
    label.y = translationY;
    rect2.y = translationY - Math.round(labelBBox.height / 2);
    rect2.x = translationX - Math.round(labelBBox.width / 2);
    rect2.height = labelBBox.height;
    rect2.width = labelBBox.width;
  }
};
AxisLabelScene.className = "AxisLabel";

// packages/ag-charts-enterprise/src/features/annotations/scenes/collidableLineScene.ts
var CollidableLine = class extends module_support_exports.Line {
  constructor() {
    super(...arguments);
    this.growCollisionBox = 9;
    this.clipMask = /* @__PURE__ */ new Map();
  }
  setProperties(styles) {
    super.setProperties(styles);
    this.updateCollisionBBox();
    return this;
  }
  updateCollisionBBox() {
    const { growCollisionBox, strokeWidth, x1, y1, x2, y2 } = this;
    let height2 = strokeWidth + growCollisionBox;
    if (height2 % 2 === 0)
      height2 += 1;
    const topLeft = vector_exports.from(x1, y1 - Math.floor(height2 / 2));
    const bottomRight = vector_exports.from(x2, y2);
    const width2 = vector_exports.distance(topLeft, bottomRight);
    this.collisionBBox = new module_support_exports.BBox(topLeft.x, topLeft.y, width2, height2);
  }
  isPointInPath(pointX, pointY) {
    const { collisionBBox, x1, y1, x2, y2 } = this;
    if (!collisionBBox)
      return false;
    const v1 = vector_exports.from(x1, y1);
    const v2 = vector_exports.from(x2, y2);
    const point = vector_exports.sub(vector_exports.from(pointX, pointY), v1);
    const end3 = vector_exports.sub(v2, v1);
    const rotated = vector_exports.rotate(point, vector_exports.angle(point, end3), v1);
    return collisionBBox.containsPoint(rotated.x, rotated.y) ?? false;
  }
  render(renderCtx) {
    const { clipMask } = this;
    const { ctx } = renderCtx;
    if (clipMask.size === 0) {
      super.render(renderCtx);
      return;
    }
    ctx.save();
    try {
      for (const mask of this.clipMask.values()) {
        const { x, y, radius } = mask;
        ctx.beginPath();
        ctx.rect(0, 0, ctx.canvas.width, ctx.canvas.height);
        ctx.ellipse(x, y, radius, radius, 0, Math.PI * 2, 0, true);
        ctx.clip();
      }
      super.render(renderCtx);
    } finally {
      ctx.restore();
    }
  }
  setClipMask(id, mask) {
    const cm = this.clipMask.get(id);
    if (jsonDiff(cm, mask) != null) {
      this.markDirty("CollidableLine");
    }
    if (mask) {
      this.clipMask.set(id, mask);
    } else {
      this.clipMask.delete(id);
    }
  }
};

// packages/ag-charts-enterprise/src/features/annotations/scenes/collidableTextScene.ts
var CollidableText = class extends module_support_exports.TransformableText {
  constructor() {
    super(...arguments);
    this.growCollisionBox = {
      top: 4,
      right: 4,
      bottom: 4,
      left: 4
    };
  }
  isPointInPath(pointX, pointY) {
    const localPoint = this.fromParentPoint(pointX, pointY);
    const uBBox = this.computeBBoxWithoutTransforms();
    if (!uBBox)
      return false;
    return uBBox.grow(this.growCollisionBox).containsPoint(localPoint.x, localPoint.y);
  }
};

// packages/ag-charts-enterprise/src/features/annotations/utils/lineWithText.ts
function updateLineText(id, line, coords, textProperties, textNode, text2, lineWidth) {
  if (!text2 || !textNode || !textProperties) {
    line.setClipMask(id);
    return;
  }
  const { alignment, position } = textProperties;
  const numbers = getNumbers(coords, textProperties.fontSize, lineWidth);
  const { point, textBaseline } = positionAndAlignment(numbers, position, alignment);
  setProperties(textNode, text2, textProperties, point, numbers.angle, textBaseline);
  const { x, y, width: width2, height: height2 } = textNode.getBBox();
  const diameter = vector_exports.length(vector_exports.from(width2, height2));
  const clipMask = {
    x: x + width2 / 2,
    y: y + height2 / 2,
    radius: diameter / 2 + vector_exports.length(numbers.offset)
  };
  if (position === "center") {
    line.setClipMask(id, clipMask);
  } else {
    line.setClipMask(id);
  }
  return { clipMask, numbers };
}
function updateChannelText(offsetInsideTextLabel, top, bottom, textProperties, lineWidth, textNode, text2) {
  if (!text2 || !textNode)
    return;
  const { alignment, position } = textProperties;
  const [actualTop, actualBottom] = top.y1 <= bottom.y1 ? [top, bottom] : [bottom, top];
  let relativeLine = actualTop;
  if (position === "bottom") {
    relativeLine = actualBottom;
  } else if (position === "inside") {
    relativeLine = {
      x1: (actualTop.x1 + actualBottom.x1) / 2,
      y1: (actualTop.y1 + actualBottom.y1) / 2,
      x2: (actualTop.x2 + actualBottom.x2) / 2,
      y2: (actualTop.y2 + actualBottom.y2) / 2
    };
  }
  const numbers = getNumbers(relativeLine, textProperties.fontSize, lineWidth);
  const { point, textBaseline } = positionAndAlignment(
    numbers,
    position === "inside" ? "center" : position,
    alignment,
    offsetInsideTextLabel
  );
  setProperties(textNode, text2, textProperties, point, numbers.angle, textBaseline);
}
function getNumbers(coords, fontSize, strokeWidth) {
  let [left, right] = vector_exports.from(coords);
  if (left.x > right.x)
    [left, right] = [right, left];
  const normal = vector_exports.normalized(vector_exports.sub(right, left));
  const angle2 = vector_exports.angle(normal);
  const inset = vector_exports.multiply(normal, DivariantHandle.HANDLE_SIZE / 2 + (fontSize ?? 14) / 2);
  const offset = vector_exports.multiply(normal, (strokeWidth ?? 2) / 2 + (fontSize ?? 14) / 3);
  return { left, right, normal, angle: angle2, inset, offset };
}
function positionAndAlignment({ left, right, normal, angle: angle2, inset, offset }, position, alignment, offsetInsideTextLabel) {
  let point;
  if (alignment === "right") {
    point = vector_exports.sub(right, inset);
  } else if (alignment === "center") {
    point = vector_exports.add(left, vector_exports.multiply(normal, vector_exports.distance(left, right) / 2));
  } else {
    point = vector_exports.add(left, inset);
  }
  let textBaseline = "bottom";
  if (position === "bottom") {
    point = vector_exports.rotate(offset, angle2 + Math.PI / 2, point);
    textBaseline = "top";
  } else if (position === "center" && !offsetInsideTextLabel) {
    textBaseline = "middle";
  } else {
    point = vector_exports.rotate(offset, angle2 - Math.PI / 2, point);
  }
  return { point, textBaseline };
}
function setProperties(scene, text2, textProperties, point, angle2, textBaseline) {
  scene.setProperties({
    text: text2,
    x: point.x,
    y: point.y,
    rotation: angle2,
    rotationCenterX: point.x,
    rotationCenterY: point.y,
    fill: textProperties.color,
    fontFamily: textProperties.fontFamily,
    fontSize: textProperties.fontSize,
    fontStyle: textProperties.fontStyle,
    fontWeight: textProperties.fontWeight,
    textAlign: textProperties.alignment,
    textBaseline
  });
}

// packages/ag-charts-enterprise/src/features/annotations/cross-line/crossLineScene.ts
var CrossLineScene = class extends AnnotationScene {
  constructor() {
    super();
    this.type = "cross-line";
    this.line = new CollidableLine();
    this.middle = new UnivariantHandle();
    this.isHorizontal = false;
    this.append([this.line, this.middle]);
  }
  static is(value) {
    return AnnotationScene.isCheck(value, "cross-line");
  }
  update(datum, context) {
    const { seriesRect } = context;
    this.seriesRect = seriesRect;
    this.isHorizontal = HorizontalLineProperties.is(datum);
    const axisContext = this.isHorizontal ? context.yAxis : context.xAxis;
    const coords = this.convertCrossLine(datum, axisContext);
    if (coords == null) {
      this.visible = false;
      return;
    }
    this.visible = datum.visible ?? true;
    if (!this.visible)
      return;
    this.updateLine(datum, coords);
    this.updateHandle(datum, coords);
    this.updateText(datum, coords);
    this.updateAxisLabel(datum, axisContext, coords);
  }
  updateLine(datum, coords) {
    const { line } = this;
    const { lineDashOffset, stroke: stroke3, strokeWidth, strokeOpacity } = datum;
    const { x1, y1, x2, y2 } = coords;
    line.setProperties({
      x1,
      y1,
      x2,
      y2,
      lineCap: datum.getLineCap(),
      lineDash: datum.getLineDash(),
      lineDashOffset,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      fillOpacity: 0
    });
  }
  updateHandle(datum, coords) {
    const { middle } = this;
    const { locked, stroke: stroke3, strokeWidth, strokeOpacity } = datum;
    const handleStyles = {
      fill: datum.handle.fill,
      stroke: datum.handle.stroke ?? stroke3,
      strokeOpacity: datum.handle.strokeOpacity ?? strokeOpacity,
      strokeWidth: datum.handle.strokeWidth ?? strokeWidth
    };
    const handlePosition = vector_exports.sub(
      vector4_exports.center(coords),
      vector_exports.from(middle.handle.width / 2, middle.handle.height / 2)
    );
    middle.gradient = this.isHorizontal ? "horizontal" : "vertical";
    middle.update({ ...handleStyles, ...handlePosition });
    middle.toggleLocked(locked ?? false);
  }
  updateText(datum, coords) {
    this.text = this.updateNode(CollidableText, this.text, !!datum.text.label);
    updateLineText(this.line.id, this.line, coords, datum.text, this.text, datum.text.label, datum.strokeWidth);
  }
  createAxisLabel(context) {
    const axisLabel3 = new AxisLabelScene();
    context.attachLabel(axisLabel3);
    return axisLabel3;
  }
  updateAxisLabel(datum, axisContext, coords) {
    this.axisLabel ?? (this.axisLabel = this.createAxisLabel(axisContext));
    const { axisLabel: axisLabel3, seriesRect } = this;
    const { direction, position } = axisContext;
    if (datum.axisLabel.enabled) {
      axisLabel3.visible = this.visible;
      const labelCorner = position === "left" || position === "top" ? vector4_exports.start(coords) : vector4_exports.end(coords);
      const labelPosition = direction === "x" /* X */ ? labelCorner.x : labelCorner.y;
      if (!axisContext.inRange(labelPosition)) {
        axisLabel3.visible = false;
        return;
      }
      const value = getGroupingValue(datum.value);
      axisLabel3.update({
        ...vector_exports.add(labelCorner, vector_exports.required(seriesRect)),
        value,
        styles: datum.axisLabel,
        context: axisContext
      });
    } else {
      axisLabel3.visible = false;
    }
  }
  setAxisLabelOpacity(opacity) {
    if (!this.axisLabel)
      return;
    this.axisLabel.opacity = opacity;
  }
  setAxisLabelVisible(visible) {
    if (!this.axisLabel)
      return;
    this.axisLabel.visible = visible;
  }
  toggleHandles(show) {
    this.middle.visible = show;
    this.middle.toggleHovered(this.activeHandle === "middle");
  }
  destroy() {
    super.destroy();
    this.axisLabel?.destroy();
  }
  toggleActive(active) {
    this.toggleHandles(active);
    this.middle.toggleActive(active);
  }
  dragStart(datum, target, context) {
    const middle = HorizontalLineProperties.is(datum) ? { x: target.x, y: convert(datum.value, context.yAxis) } : { x: convert(datum.value, context.xAxis), y: target.y };
    this.dragState = {
      offset: target,
      middle
    };
  }
  drag(datum, target, context) {
    const { activeHandle, dragState } = this;
    if (!datum.isWriteable() || !dragState)
      return;
    if (activeHandle) {
      this[activeHandle].toggleDragging(true);
    }
    this.translatePoint(datum, dragState.middle, vector_exports.sub(target, dragState.offset), context);
  }
  translate(datum, translation, context) {
    if (!datum.isWriteable())
      return;
    const vector = HorizontalLineProperties.is(datum) ? vector_exports.from(0, convert(datum.value, context.yAxis)) : vector_exports.from(convert(datum.value, context.xAxis), 0);
    this.translatePoint(datum, vector, translation, context);
  }
  translatePoint(datum, value, translation, context) {
    const isHorizontal2 = HorizontalLineProperties.is(datum);
    if (isHorizontal2) {
      translation.x = 0;
    } else {
      translation.y = 0;
    }
    const { point } = translate({ point: value }, translation, context);
    datum.value = isHorizontal2 ? point.y : point.x;
  }
  stopDragging() {
    this.middle.toggleDragging(false);
  }
  copy(datum, copiedDatum, context) {
    const isHorizontal2 = HorizontalLineProperties.is(datum);
    const axisContext = this.isHorizontal ? context.yAxis : context.xAxis;
    const coords = this.convertCrossLine(datum, axisContext);
    if (!coords) {
      return;
    }
    const yOffset = isHorizontal2 ? -30 : 0;
    const xOffset = isHorizontal2 ? 0 : -30;
    const point = invertCoords({ x: coords.x1 + xOffset, y: coords.y1 + yOffset }, context);
    copiedDatum.set({ value: isHorizontal2 ? point.y : point.x });
    return copiedDatum;
  }
  getCursor() {
    if (this.activeHandle == null)
      return "pointer";
    return this[this.activeHandle].getCursor();
  }
  containsPoint(x, y) {
    const { middle, line, text: text2 } = this;
    this.activeHandle = void 0;
    if (middle.containsPoint(x, y)) {
      this.activeHandle = "middle";
      return true;
    }
    return line.isPointInPath(x, y) || Boolean(text2?.containsPoint(x, y));
  }
  getNodeAtCoords(x, y) {
    if (this.text?.containsPoint(x, y))
      return "text";
    if (this.line.isPointInPath(x, y))
      return "line";
    if (this.middle.containsPoint(x, y))
      return "handle";
  }
  getAnchor() {
    const bbox = this.computeBBoxWithoutHandles();
    if (this.isHorizontal) {
      return { x: bbox.x + bbox.width / 2, y: bbox.y };
    }
    return { x: bbox.x + bbox.width, y: bbox.y + bbox.height / 2, position: "right" };
  }
  convertCrossLine(datum, context) {
    if (datum.value == null)
      return;
    let x1 = 0;
    let y1 = 0;
    let x2, y2;
    const { bounds } = context;
    const scaledValue = convert(datum.value, context);
    if (HorizontalLineProperties.is(datum)) {
      x2 = bounds.width;
      y1 = scaledValue;
      y2 = scaledValue;
    } else {
      x1 = scaledValue;
      x2 = scaledValue;
      y2 = bounds.height;
    }
    return { x1, y1, x2, y2 };
  }
};

// packages/ag-charts-enterprise/src/features/annotations/cross-line/crossLineState.ts
var CrossLineStateMachine = class extends StateMachine {
  constructor(direction, ctx) {
    const onClick = ({ point }) => {
      const isHorizontal2 = direction === "horizontal";
      const datum = isHorizontal2 ? new HorizontalLineProperties() : new VerticalLineProperties();
      datum.set({ value: isHorizontal2 ? point.y : point.x });
      ctx.create(datum);
      ctx.recordAction(
        `Create ${isHorizontal2 ? "horizontal-line" /* HorizontalLine */ : "vertical-line" /* VerticalLine */} annotation`
      );
    };
    const actionFirstRender = () => {
      this.node?.toggleActive(true);
      ctx.showAnnotationOptions();
      ctx.update();
    };
    super("start", {
      start: {
        click: {
          target: "waiting-first-render",
          action: onClick
        },
        drag: {
          target: "waiting-first-render",
          action: onClick
        },
        reset: StateMachine.parent,
        cancel: StateMachine.parent
      },
      "waiting-first-render": {
        render: {
          target: StateMachine.parent,
          action: actionFirstRender
        }
      }
    });
    this.debug = debugLogger_exports.create(true, "annotations");
  }
};
__decorateClass([
  StateMachineProperty()
], CrossLineStateMachine.prototype, "node", 2);

// packages/ag-charts-enterprise/src/features/annotations/cross-line/crossLineConfig.ts
var horizontalLineConfig = {
  type: "horizontal-line" /* HorizontalLine */,
  datum: HorizontalLineProperties,
  scene: CrossLineScene,
  isDatum: HorizontalLineProperties.is,
  translate: (node, datum, translation, context) => {
    if (HorizontalLineProperties.is(datum) && CrossLineScene.is(node))
      node.translate(datum, translation, context);
  },
  copy: (node, datum, copiedDatum, context) => {
    if (HorizontalLineProperties.is(datum) && HorizontalLineProperties.is(copiedDatum) && CrossLineScene.is(node)) {
      return node.copy(datum, copiedDatum, context);
    }
  },
  update: (node, datum, context) => {
    if (HorizontalLineProperties.is(datum) && CrossLineScene.is(node)) {
      node.update(datum, context);
    }
  },
  createState: (ctx, { createDatum }) => new CrossLineStateMachine("horizontal", {
    ...ctx,
    create: createDatum("horizontal-line" /* HorizontalLine */)
  }),
  dragState: (ctx) => new DragStateMachine(ctx)
};
var verticalLineConfig = {
  type: "vertical-line" /* VerticalLine */,
  datum: VerticalLineProperties,
  scene: CrossLineScene,
  isDatum: VerticalLineProperties.is,
  translate: (node, datum, translation, context) => {
    if (VerticalLineProperties.is(datum) && CrossLineScene.is(node))
      node.translate(datum, translation, context);
  },
  copy: (node, datum, copiedDatum, context) => {
    if (VerticalLineProperties.is(datum) && VerticalLineProperties.is(copiedDatum) && CrossLineScene.is(node)) {
      return node.copy(datum, copiedDatum, context);
    }
  },
  update: (node, datum, context) => {
    if (VerticalLineProperties.is(datum) && CrossLineScene.is(node)) {
      node.update(datum, context);
    }
  },
  createState: (ctx, { createDatum }) => new CrossLineStateMachine("vertical", {
    ...ctx,
    create: createDatum("vertical-line" /* VerticalLine */)
  }),
  dragState: (ctx) => new DragStateMachine(ctx)
};

// packages/ag-charts-enterprise/src/features/annotations/scenes/withBackgroundScene.ts
var WithBackgroundScene = class {
  static updateBackground(datum, top, bottom, context) {
    const { background } = this;
    const { seriesRect } = context;
    background.path.clear(true);
    const bounds = vector4_exports.from(0, 0, seriesRect.width, seriesRect.height);
    const points = this.getBackgroundPoints(datum, top, bottom, bounds);
    for (let i = 0; i < points.length; i++) {
      const point = points[i];
      if (i === 0) {
        background.path.moveTo(point.x, point.y);
      } else {
        background.path.lineTo(point.x, point.y);
      }
    }
    background.path.closePath();
    background.checkPathDirty();
    const backgroundStyles = this.getBackgroundStyles?.(datum) ?? datum.background;
    background.fill = backgroundStyles.fill;
    background.fillOpacity = backgroundStyles.fillOpacity ?? 1;
  }
};

// packages/ag-charts-enterprise/src/features/annotations/scenes/channelScene.ts
var ChannelScene = class extends LinearScene {
  constructor() {
    super(...arguments);
    this.handles = {};
    this.overflowContinuous = 2;
    this.topLine = new CollidableLine();
    this.bottomLine = new CollidableLine();
    this.background = new module_support_exports.Path({ zIndex: -1 });
    this.anchor = { x: 0, y: 0 };
    this.updateBackground = WithBackgroundScene.updateBackground.bind(this);
  }
  update(datum, context) {
    const { locked, visible } = datum;
    const top = convertLine(datum, context);
    const bottom = convertLine(datum.bottom, context);
    if (top == null || bottom == null) {
      this.visible = false;
      return;
    } else {
      this.visible = visible ?? true;
    }
    const topLine = this.extendLine(top, datum, context);
    const bottomLine = this.extendLine(bottom, datum, context);
    this.updateLines(datum, topLine, bottomLine, context, top, bottom);
    this.updateHandles(datum, top, bottom);
    this.updateText(datum, top, bottom);
    this.updateBackground(datum, topLine, bottomLine, context);
    this.updateAnchor(top, bottom);
    for (const handle3 of Object.values(this.handles)) {
      handle3.toggleLocked(locked ?? false);
    }
  }
  toggleHandles(show) {
    const { handles } = this;
    if (typeof show === "boolean") {
      for (const [handle3, node] of Object.entries(handles)) {
        node.visible = show;
        node.toggleHovered(this.activeHandle === handle3);
      }
      return;
    }
    for (const [handle3, visible] of Object.entries(show)) {
      const node = handles[handle3];
      node.visible = visible ?? true;
      node.toggleHovered(this.activeHandle === handle3);
    }
  }
  toggleActive(active) {
    this.toggleHandles(active);
    for (const node of Object.values(this.handles)) {
      node.toggleActive(active);
    }
  }
  stopDragging() {
    const { activeHandle, handles } = this;
    if (activeHandle == null)
      return;
    handles[activeHandle].toggleDragging(false);
  }
  getAnchor() {
    return this.anchor;
  }
  getCursor() {
    if (this.activeHandle == null)
      return "pointer";
    return this.handles[this.activeHandle].getCursor();
  }
  containsPoint(x, y) {
    const { handles, topLine, bottomLine, text: text2 } = this;
    this.activeHandle = void 0;
    for (const [handle3, child] of Object.entries(handles)) {
      if (child.containsPoint(x, y)) {
        this.activeHandle = handle3;
        return true;
      }
    }
    return topLine.containsPoint(x, y) || bottomLine.containsPoint(x, y) || Boolean(text2?.containsPoint(x, y));
  }
  getNodeAtCoords(x, y) {
    if (this.text?.containsPoint(x, y))
      return "text";
    if (this.topLine.containsPoint(x, y) || this.bottomLine.containsPoint(x, y))
      return "line";
    for (const [, child] of Object.entries(this.handles)) {
      if (child.containsPoint(x, y))
        return "handle";
    }
  }
  updateAnchor(top, bottom) {
    const { x, y } = module_support_exports.Transformable.toCanvasPoint(
      this.topLine,
      (top.x1 + top.x2) / 2,
      Math.min(top.y1, top.y2, bottom.y1, bottom.y2)
    );
    this.anchor.x = x;
    this.anchor.y = y;
  }
};

// packages/ag-charts-enterprise/src/features/annotations/disjoint-channel/disjointChannelScene.ts
var DisjointChannelScene = class extends ChannelScene {
  constructor() {
    super();
    this.type = "disjoint-channel";
    this.handles = {
      topLeft: new DivariantHandle(),
      topRight: new DivariantHandle(),
      bottomLeft: new DivariantHandle(),
      bottomRight: new UnivariantHandle()
    };
    this.append([this.background, this.topLine, this.bottomLine, ...Object.values(this.handles)]);
  }
  static is(value) {
    return AnnotationScene.isCheck(value, "disjoint-channel");
  }
  dragHandle(datum, target, context, snapping) {
    const { activeHandle, handles } = this;
    if (activeHandle == null)
      return;
    const { offset } = handles[activeHandle].drag(target);
    handles[activeHandle].toggleDragging(true);
    if (activeHandle === "bottomRight") {
      offset.x = 0;
    }
    let translateVectors = [];
    let invertYVectors = [];
    let allowSnapping = snapping;
    switch (activeHandle) {
      case "topLeft":
        translateVectors = ["topLeft"];
        invertYVectors = ["bottomLeft"];
        break;
      case "bottomLeft":
        translateVectors = ["bottomLeft"];
        invertYVectors = ["topLeft"];
        break;
      case "topRight":
        translateVectors = ["topRight"];
        invertYVectors = ["bottomRight"];
        break;
      case "bottomRight":
        translateVectors = ["bottomLeft", "bottomRight"];
        allowSnapping = false;
        break;
    }
    const top = convertLine(datum, context);
    const bottom = convertLine(datum.bottom, context);
    if (!top || !bottom)
      return;
    const vectors = {
      topLeft: vector4_exports.start(top),
      topRight: vector4_exports.end(top),
      bottomLeft: vector4_exports.start(bottom),
      bottomRight: vector4_exports.end(bottom)
    };
    const snap = {
      vectors: {
        topLeft: vectors.topRight,
        bottomLeft: vectors.bottomRight,
        topRight: vectors.topLeft,
        bottomRight: vectors.bottomLeft
      },
      angle: datum.snapToAngle
    };
    const points = translate(vectors, offset, context, {
      overflowContinuous: this.overflowContinuous,
      translateVectors,
      invertYVectors,
      snap: allowSnapping ? snap : void 0
    });
    datum.start.x = points.topLeft.x;
    datum.start.y = points.topLeft.y;
    datum.end.x = points.topRight.x;
    datum.end.y = points.topRight.y;
    datum.startHeight = points.topLeft.y - points.bottomLeft.y;
    datum.endHeight = points.topRight.y - points.bottomRight.y;
  }
  getTranslatePointsVectors(start2, end3) {
    const { bottomLeft, bottomRight, topLeft, topRight } = this.handles;
    const startHeight = bottomLeft.getBBox().y - topLeft.getBBox().y;
    const endHeight = bottomRight.getBBox().y - topRight.getBBox().y;
    const bottomStart = vector_exports.add(start2, vector_exports.from(0, startHeight));
    const bottomEnd = vector_exports.add(end3, vector_exports.from(0, endHeight));
    return { start: start2, end: end3, bottomStart, bottomEnd };
  }
  updateLines(datum, top, bottom) {
    const { topLine, bottomLine } = this;
    const { lineDashOffset, stroke: stroke3, strokeOpacity, strokeWidth } = datum;
    const lineStyles = {
      lineCap: datum.getLineCap(),
      lineDash: datum.getLineDash(),
      lineDashOffset,
      stroke: stroke3,
      strokeOpacity,
      strokeWidth
    };
    topLine.setProperties({ ...top, ...lineStyles });
    bottomLine.setProperties({ ...bottom, ...lineStyles });
  }
  updateHandles(datum, top, bottom) {
    const {
      handles: { topLeft, topRight, bottomLeft, bottomRight }
    } = this;
    const handleStyles = {
      fill: datum.handle.fill,
      stroke: datum.handle.stroke ?? datum.stroke,
      strokeOpacity: datum.handle.strokeOpacity ?? datum.strokeOpacity,
      strokeWidth: datum.handle.strokeWidth ?? datum.strokeWidth
    };
    topLeft.update({ ...handleStyles, ...vector4_exports.start(top) });
    topRight.update({ ...handleStyles, ...vector4_exports.end(top) });
    bottomLeft.update({ ...handleStyles, ...vector4_exports.start(bottom) });
    bottomRight.update({
      ...handleStyles,
      ...vector_exports.sub(vector4_exports.end(bottom), vector_exports.from(bottomRight.handle.width / 2, bottomRight.handle.height / 2))
    });
  }
  updateText(datum, top, bottom) {
    this.text = this.updateNode(CollidableText, this.text, !!datum.text.label);
    updateChannelText(false, top, bottom, datum.text, datum.strokeWidth, this.text, datum.text.label);
  }
  getBackgroundPoints(datum, top, bottom, bounds) {
    const isFlippedX = top.x1 > top.x2;
    const isFlippedY = top.y1 > top.y2;
    const topY = isFlippedY ? bounds.y2 : bounds.y1;
    const bottomY = isFlippedY ? bounds.y1 : bounds.y2;
    const points = vector_exports.from(top);
    if (datum.extendEnd && top.y2 === bottomY) {
      points.push(vector_exports.from(isFlippedX ? bounds.x1 : bounds.x2, isFlippedY ? bounds.y1 : bounds.y2));
    }
    if (datum.extendEnd && bottom.y2 === topY) {
      points.push(vector_exports.from(isFlippedX ? bounds.x1 : bounds.x2, isFlippedY ? bounds.y2 : bounds.y1));
    }
    points.push(...vector_exports.from(bottom).reverse());
    if (datum.extendStart && bottom.y1 === bottomY) {
      points.push(vector_exports.from(isFlippedX ? bounds.x2 : bounds.x1, isFlippedY ? bounds.y1 : bounds.y2));
    }
    if (datum.extendStart && top.y1 === topY) {
      points.push(vector_exports.from(isFlippedX ? bounds.x2 : bounds.x1, isFlippedY ? bounds.y2 : bounds.y1));
    }
    return points;
  }
};

// packages/ag-charts-enterprise/src/features/annotations/disjoint-channel/disjointChannelState.ts
var DisjointChannelStateMachine = class extends StateMachine {
  constructor(ctx) {
    const actionCreate = ({ point }) => {
      const datum = new DisjointChannelProperties();
      datum.set({ start: point, end: point, startHeight: 0, endHeight: 0 });
      ctx.create(datum);
    };
    const actionFirstRender = () => {
      const { node } = this;
      node?.toggleActive(true);
      node?.toggleHandles({ topLeft: true, topRight: false, bottomLeft: false, bottomRight: false });
    };
    const actionEndUpdate = ({ offset, context }) => {
      const { datum, snapping } = this;
      if (!datum)
        return;
      datum.set({ end: snapPoint(offset, context, snapping, datum.start, datum.snapToAngle) });
      ctx.update();
    };
    const actionEndFinish = () => {
      this.node?.toggleHandles({ topRight: true });
      ctx.update();
    };
    const actionHeightUpdate = ({ point }) => {
      const { datum, node } = this;
      const endY = getGroupingValue(datum?.end.y);
      const startY = getGroupingValue(datum?.start.y);
      const { y: pointY } = point;
      if (datum == null || !isNumber(startY) || !isNumber(endY) || !isNumber(pointY))
        return;
      const endHeight = endY - (pointY ?? 0);
      const startHeight = (startY - endY) * 2 + endHeight;
      const bottomStart = { x: datum?.start.x, y: startY - startHeight };
      const bottomEnd = { x: datum?.end.x, y: point.y };
      node?.toggleHandles({ bottomLeft: true, bottomRight: true });
      if (!ctx.validatePoint(bottomStart, { overflowContinuous: true }) || !ctx.validatePoint(bottomEnd, { overflowContinuous: true })) {
        return;
      }
      datum.set({ startHeight, endHeight });
      ctx.update();
    };
    const actionHeightFinish = ({ point }) => {
      const { datum, node } = this;
      const endY = getGroupingValue(datum?.end.y);
      const startY = getGroupingValue(datum?.start.y);
      const { y: pointY } = point;
      if (datum == null || !isNumber(startY) || !isNumber(endY) || !isNumber(pointY))
        return;
      const endHeight = endY - (pointY ?? 0);
      const startHeight = (startY - endY) * 2 + endHeight;
      const bottomStart = { x: datum.start.x, y: startY - endHeight };
      const bottomEnd = { x: datum.end.x, y: point.y };
      node?.toggleHandles(true);
      if (!ctx.validatePoint(bottomStart, { overflowContinuous: true }) || !ctx.validatePoint(bottomEnd, { overflowContinuous: true })) {
        return;
      }
      datum.set({ startHeight, endHeight });
      ctx.recordAction(`Create ${"disjoint-channel" /* DisjointChannel */} annotation`);
      ctx.showAnnotationOptions();
      ctx.update();
    };
    const actionCancel = () => ctx.delete();
    super("start", {
      start: {
        click: {
          target: "waiting-first-render",
          action: actionCreate
        },
        drag: {
          target: "waiting-first-render",
          action: actionCreate
        },
        reset: StateMachine.parent
      },
      "waiting-first-render": {
        render: {
          target: "end",
          action: actionFirstRender
        }
      },
      end: {
        hover: actionEndUpdate,
        drag: actionEndUpdate,
        click: {
          target: "height",
          action: actionEndFinish
        },
        dragEnd: {
          target: "height",
          action: actionEndFinish
        },
        reset: {
          target: StateMachine.parent,
          action: actionCancel
        },
        cancel: {
          target: StateMachine.parent,
          action: actionCancel
        }
      },
      height: {
        hover: actionHeightUpdate,
        click: {
          target: StateMachine.parent,
          action: actionHeightFinish
        },
        drag: {
          target: StateMachine.parent,
          action: actionHeightFinish
        },
        reset: {
          target: StateMachine.parent,
          action: actionCancel
        },
        cancel: {
          target: StateMachine.parent,
          action: actionCancel
        }
      }
    });
    this.debug = debugLogger_exports.create(true, "annotations");
    this.snapping = false;
  }
};
__decorateClass([
  StateMachineProperty()
], DisjointChannelStateMachine.prototype, "datum", 2);
__decorateClass([
  StateMachineProperty()
], DisjointChannelStateMachine.prototype, "node", 2);
__decorateClass([
  StateMachineProperty()
], DisjointChannelStateMachine.prototype, "snapping", 2);

// packages/ag-charts-enterprise/src/features/annotations/disjoint-channel/disjointChannelConfig.ts
var disjointChannelConfig = {
  type: "disjoint-channel" /* DisjointChannel */,
  datum: DisjointChannelProperties,
  scene: DisjointChannelScene,
  isDatum: DisjointChannelProperties.is,
  translate: (node, datum, transition, context) => {
    if (DisjointChannelProperties.is(datum) && DisjointChannelScene.is(node)) {
      node.translate(datum, transition, context);
    }
  },
  copy: (node, datum, copiedDatum, context) => {
    if (DisjointChannelProperties.is(datum) && DisjointChannelProperties.is(copiedDatum) && DisjointChannelScene.is(node)) {
      return node.copy(datum, copiedDatum, context);
    }
  },
  update: (node, datum, context) => {
    if (DisjointChannelProperties.is(datum) && DisjointChannelScene.is(node)) {
      node.update(datum, context);
    }
  },
  createState: (ctx, { createDatum }) => new DisjointChannelStateMachine({
    ...ctx,
    create: createDatum("disjoint-channel" /* DisjointChannel */)
  }),
  dragState: (ctx) => new DragStateMachine(ctx)
};

// packages/ag-charts-enterprise/src/features/annotations/utils/fibonacci.ts
var FIBONACCI_RETRACEMENT_RATIOS = [0, 23.6, 38.2, 50, 61.8, 78.6, 100];
var FIBONACCI_EXTENSION_RATIOS = [161.8, 261.8, 361.8, 423.6];
var FIBONACCI_RATIOS = [...FIBONACCI_RETRACEMENT_RATIOS, ...FIBONACCI_EXTENSION_RATIOS];
var FIBONACCI_RATIOS_MAP = {
  10: FIBONACCI_RATIOS,
  6: FIBONACCI_RETRACEMENT_RATIOS,
  4: FIBONACCI_RETRACEMENT_RATIOS.filter((r) => r !== 78.6 && r !== 23.6)
};
var FIBONACCI_RANGE_LABEL_PADDING = 10;
function getFibonacciCoords(coords1, coords2) {
  const { x2, y1, y2 } = coords1;
  const trendLineVerticalDistance = y1 - y2;
  if (coords2 == null) {
    return {
      x1: x2,
      x2,
      y1: y2 - trendLineVerticalDistance,
      y2
    };
  }
  return {
    x1: coords2.x1,
    x2: coords2.x2,
    y1: coords2.y2 - trendLineVerticalDistance,
    y2: coords2.y2
  };
}
function createFibonacciRangesData({ x1, y1, x2, y2 }, context, reverse, yZero, bands = 10) {
  const verticalDistance = y1 - y2;
  const direction = reverse ? -1 : 1;
  let startY = yZero;
  const data = [];
  for (const [index, ratio2] of FIBONACCI_RATIOS_MAP[bands].entries()) {
    const endY = yZero + verticalDistance * (ratio2 / 100) * direction;
    const yDatumVal = context.yAxis.scaleInvert(endY);
    data.push({
      id: index,
      x1,
      x2,
      y1: startY,
      y2: endY,
      tag: ratio2 == 100 ? 0 /* OneLine */ : 1 /* HorizontalLine */,
      label: {
        x1: Math.min(x1, x2) - FIBONACCI_RANGE_LABEL_PADDING,
        x2,
        y1: endY,
        y2: endY,
        text: `${(ratio2 / 100).toFixed(3)} (${yDatumVal.toFixed(2)})`
      }
    });
    startY = endY;
  }
  return data;
}

// packages/ag-charts-enterprise/src/features/annotations/scenes/fibonacciScene.ts
var FibonacciScene = class extends AnnotationScene {
  constructor() {
    super();
    this.trendLine = new CollidableLine();
    this.rangeFillsGroup = new module_support_exports.Group({
      name: `${this.id}-range-fills`
    });
    this.rangeFillsGroupSelection = module_support_exports.Selection.select(this.rangeFillsGroup, module_support_exports.Range);
    this.rangeStrokesGroup = new module_support_exports.Group({
      name: `${this.id}-range-strokes`
    });
    this.rangeStrokesGroupSelection = module_support_exports.Selection.select(this.rangeStrokesGroup, CollidableLine);
    this.labelsGroup = new module_support_exports.Group({
      name: `${this.id}-ranges-labels`
    });
    this.labelsGroupSelection = module_support_exports.Selection.select(this.labelsGroup, CollidableText);
    this.anchor = {
      x: 0,
      y: 0,
      position: "above"
    };
    this.append([this.trendLine, this.rangeFillsGroup, this.rangeStrokesGroup, this.labelsGroup]);
  }
  update(datum, context) {
    let coords = convertLine(datum, context);
    if (coords == null) {
      this.visible = false;
      return;
    }
    coords = vector4_exports.round(coords);
    this.visible = datum.visible ?? true;
    if (!this.visible)
      return;
    this.updateLine(datum, coords, this.trendLine);
    this.updateHandles(datum, coords);
    this.updateAnchor(datum, coords, context);
    const { reverse } = datum;
    const extendedCoords = this.extendLine(coords, datum, context);
    const yZero = reverse ? extendedCoords.y1 : extendedCoords.y2;
    const yOne = reverse ? extendedCoords.y2 : extendedCoords.y1;
    const data = createFibonacciRangesData(extendedCoords, context, datum.reverse, yZero, datum.bands);
    this.updateRanges(datum, data, context);
    const oneLinePoints = { ...extendedCoords, y1: yOne, y2: yOne };
    this.updateText(datum, oneLinePoints);
  }
  extendLine({ x1, y1, x2, y2 }, datum, context) {
    const linePoints = { x1, y1, x2, y2 };
    if (!datum.extendStart && !datum.extendEnd) {
      return linePoints;
    }
    const { x, width: width2 } = context.xAxis.bounds;
    if (datum.extendEnd) {
      linePoints[x1 > x2 ? "x1" : "x2"] = x + width2;
    }
    if (datum.extendStart) {
      linePoints[x1 > x2 ? "x2" : "x1"] = x;
    }
    return linePoints;
  }
  updateLine(datum, coords, line) {
    if (!coords || !line) {
      return;
    }
    const { lineDashOffset, strokeWidth, strokeOpacity, stroke: stroke3 } = datum;
    line.setProperties({
      ...coords,
      lineCap: datum.getLineCap(),
      lineDash: [3, 4],
      lineDashOffset,
      strokeWidth,
      strokeOpacity,
      fillOpacity: 0,
      stroke: stroke3
    });
  }
  updateRangeStrokes(datum) {
    const { lineDashOffset, strokeWidth, strokeOpacity, strokes, rangeStroke, isMultiColor } = datum;
    this.rangeStrokesGroupSelection.each((line, { x1, x2, y2, tag }, index) => {
      const y = y2;
      const color2 = isMultiColor ? strokes[index % strokes.length] : rangeStroke;
      line.setProperties({
        x1,
        x2,
        y1: y,
        y2: y,
        stroke: color2,
        strokeOpacity,
        strokeWidth,
        lineCap: datum.getLineCap(),
        lineDash: datum.getLineDash(),
        lineDashOffset,
        tag
      });
    });
  }
  updateRanges(datum, data, context) {
    const getDatumId = (d) => d.id;
    this.rangeFillsGroupSelection.update(data, void 0, getDatumId);
    this.rangeStrokesGroupSelection.update(data, void 0, getDatumId);
    this.labelsGroupSelection.update(data, void 0, getDatumId);
    this.updateRangeFills(datum);
    this.updateRangeStrokes(datum);
    this.updateRangeLabels(datum, context);
  }
  updateRangeFills(datum) {
    const {
      lineDashOffset,
      strokeWidth,
      strokeOpacity,
      strokes: colors,
      rangeStroke,
      showFill,
      isMultiColor
    } = datum;
    this.rangeFillsGroupSelection.each((range3, { x1, x2, y1, y2 }, index) => {
      const color2 = isMultiColor ? colors[index % colors.length] : rangeStroke;
      if (!showFill) {
        range3.visible = false;
        return;
      }
      range3.setProperties({
        x1,
        x2,
        y1,
        y2,
        startLine: false,
        endLine: false,
        stroke: color2,
        strokeOpacity,
        fill: color2,
        fillOpacity: (strokeOpacity ?? 1) * 0.15,
        strokeWidth,
        lineCap: datum.getLineCap(),
        lineDash: datum.getLineDash(),
        lineDashOffset,
        visible: true
      });
    });
  }
  updateRangeLabels(trendLineProperties, { xAxis }) {
    const { rangeStrokesGroupSelection } = this;
    const {
      strokes: colors,
      strokeWidth,
      rangeStroke,
      isMultiColor,
      label: { fontFamily, fontSize, fontStyle, fontWeight: fontWeight2, color: color2 }
    } = trendLineProperties;
    const labelProperties = {
      fontFamily,
      fontSize,
      fontStyle,
      fontWeight: fontWeight2
    };
    const withinBounds = this.checkWithinBounds(xAxis, labelProperties, this.labelsGroupSelection.at(0));
    this.labelsGroupSelection.each((textNode, datum, index) => {
      const textColor = color2 ?? (isMultiColor ? colors[index % colors.length] : rangeStroke);
      const line = rangeStrokesGroupSelection.at(index);
      if (!line) {
        return;
      }
      const { text: text2, ...coords } = datum.label;
      if (withinBounds) {
        textNode.setProperties({
          ...labelProperties,
          text: text2,
          x: coords.x1,
          y: coords.y1,
          textBaseline: "middle",
          textAlign: "end",
          fill: textColor
        });
        updateLineText(textNode.id, line, coords);
      } else {
        const textProperties = {
          ...labelProperties,
          label: text2,
          position: "center",
          alignment: "left",
          color: textColor
        };
        updateLineText(textNode.id, line, coords, textProperties, textNode, text2, strokeWidth);
      }
    });
  }
  checkWithinBounds(xAxis, fontOptions, textNode) {
    if (!textNode) {
      return false;
    }
    const { text: text2, ...coords } = textNode.datum.label;
    textNode.setProperties({
      ...fontOptions,
      text: text2,
      x: coords.x1,
      y: coords.y1,
      textBaseline: "middle",
      textAlign: "end"
    });
    const { x } = textNode.getBBox();
    return x >= xAxis.bounds.x && x <= xAxis.bounds.x + xAxis.bounds.width;
  }
  updateText(datum, coords) {
    const oneLine = this.rangeStrokesGroupSelection.selectByTag(0 /* OneLine */)[0];
    if (!oneLine) {
      return;
    }
    const { text: textProperties, strokeWidth } = datum;
    this.text = this.updateNode(CollidableText, this.text, !!textProperties.label);
    updateLineText(oneLine.id, oneLine, coords, textProperties, this.text, textProperties.label, strokeWidth);
  }
  updateAnchor(_datum, coords, _context, _bbox) {
    const point = vector4_exports.topCenter(coords);
    vector_exports.apply(this.anchor, module_support_exports.Transformable.toCanvasPoint(this.trendLine, point.x, point.y));
  }
  containsPoint(x, y) {
    const { trendLine, rangeStrokesGroupSelection, text: text2 } = this;
    let isInStrokePath = false;
    rangeStrokesGroupSelection.each((line) => isInStrokePath || (isInStrokePath = line.isPointInPath(x, y)));
    return isInStrokePath || trendLine.isPointInPath(x, y) || Boolean(text2?.containsPoint(x, y));
  }
  getNodeAtCoords(x, y) {
    if (this.text?.containsPoint(x, y))
      return "text";
    if (this.trendLine.isPointInPath(x, y))
      return "line";
  }
  getHandleStyles(datum) {
    return {
      fill: datum.handle.fill,
      stroke: datum.handle.stroke ?? datum.stroke,
      strokeOpacity: datum.handle.strokeOpacity ?? datum.strokeOpacity,
      strokeWidth: datum.handle.strokeWidth ?? datum.strokeWidth
    };
  }
  drag(datum, target, context, snapping) {
    if (!datum.isWriteable())
      return;
    if (this.activeHandle) {
      this.dragHandle(datum, target, context, snapping);
    } else {
      this.dragAll(datum, target, context);
    }
  }
  getAnchor() {
    return this.anchor;
  }
  getCursor() {
    return "pointer";
  }
};

// packages/ag-charts-enterprise/src/features/annotations/utils/validation.ts
var { ContinuousScale: ContinuousScale3 } = module_support_exports;
function validateDatumPoint(context, point, options = { overflowContinuous: false }, warningPrefix) {
  if (point.x == null || point.y == null) {
    if (warningPrefix) {
      logger_exports.warnOnce(`${warningPrefix}requires both an [x] and [y] property, ignoring.`);
    }
    return false;
  }
  const { xAxis, yAxis } = context;
  const continuousX = options.overflowContinuous && ContinuousScale3.is(xAxis.scale);
  const continuousY = options.overflowContinuous && ContinuousScale3.is(yAxis.scale);
  const validX = continuousX || validateDatumPointDirection(point.x, xAxis);
  const validY = continuousY || validateDatumPointDirection(point.y, yAxis);
  if (validX && validY)
    return true;
  if (warningPrefix) {
    let text2 = "x & y domains";
    if (validX)
      text2 = "y domain";
    if (validY)
      text2 = "x domain";
    const xValue = getGroupingValue(point.x);
    const yValue = getGroupingValue(point.y);
    logger_exports.warnOnce(`${warningPrefix}is outside the ${text2}, ignoring. - x: [${xValue}], y: ${yValue}]`);
  }
  return false;
}
function validateDatumPointDirection(d, context) {
  const { domain } = context.scale;
  const value = getGroupingValue(d);
  if (domain && value != null && context.continuous) {
    return value >= domain[0] && value <= domain.at(-1);
  }
  return true;
}

// packages/ag-charts-enterprise/src/features/annotations/fibonacci-retracement-trend-based/fibonacciRetracementTrendBasedScene.ts
var FibonacciRetracementTrendBasedScene = class extends FibonacciScene {
  constructor() {
    super();
    this.type = "fibonacci-retracement-trend-based";
    this.endRetracementLine = new CollidableLine();
    this.start = new DivariantHandle();
    this.end = new DivariantHandle();
    this.endRetracement = new DivariantHandle();
    this.append([this.endRetracementLine, this.start, this.end, this.endRetracement]);
  }
  static is(value) {
    return AnnotationScene.isCheck(value, "fibonacci-retracement-trend-based");
  }
  update(datum, context) {
    let { coords1, coords2 } = this.getCoords(datum, context);
    if (coords1 == null || coords2 == null) {
      this.visible = false;
      return;
    }
    coords1 = vector4_exports.round(coords1);
    coords2 = vector4_exports.round(coords2);
    this.visible = datum.visible ?? true;
    if (!this.visible)
      return;
    if (datum.endRetracement.x == void 0 || datum.endRetracement.y == void 0) {
      coords2 = void 0;
    }
    this.updateLine(datum, coords1, this.trendLine);
    this.updateLine(datum, coords2, this.endRetracementLine);
    this.updateHandles(datum, coords1, coords2);
    this.updateAnchor(datum, coords2 ?? coords1, context);
    const { reverse, bands } = datum;
    const coords = getFibonacciCoords(coords1, coords2);
    const extendedCoords = this.extendLine(coords, datum, context);
    const yZero = extendedCoords.y2;
    const yOne = extendedCoords.y1;
    const data = coords2 ? createFibonacciRangesData(extendedCoords, context, reverse, yZero, bands) : [];
    this.updateRanges(datum, data, context);
    const oneLinePoints = { ...extendedCoords, y1: yOne, y2: yOne };
    this.updateText(datum, oneLinePoints);
  }
  containsPoint(x, y) {
    const { start: start2, end: end3, endRetracement, endRetracementLine } = this;
    this.activeHandle = void 0;
    if (start2.containsPoint(x, y)) {
      this.activeHandle = "start";
      return true;
    }
    if (end3.containsPoint(x, y)) {
      this.activeHandle = "end";
      return true;
    }
    if (endRetracement.containsPoint(x, y)) {
      this.activeHandle = "endRetracement";
      return true;
    }
    return endRetracementLine.isPointInPath(x, y) || super.containsPoint(x, y);
  }
  getNodeAtCoords(x, y) {
    if (this.start.containsPoint(x, y) || this.end.containsPoint(x, y) || this.endRetracement.containsPoint(x, y))
      return "handle";
    if (this.endRetracementLine.isPointInPath(x, y))
      return "line";
    return super.getNodeAtCoords(x, y);
  }
  dragStart(datum, target, context) {
    this.dragState = {
      offset: target,
      ...getDragStartState({ start: datum.start, end: datum.end, endRetracement: datum.endRetracement }, context)
    };
  }
  stopDragging() {
    this.start.toggleDragging(false);
    this.end.toggleDragging(false);
    this.endRetracement.toggleDragging(false);
  }
  dragAll(datum, target, context) {
    const { dragState } = this;
    if (!dragState)
      return;
    this.translatePoints({
      datum,
      start: dragState.start,
      end: dragState.end,
      endRetracement: dragState.endRetracement,
      translation: vector_exports.sub(target, dragState.offset),
      context
    });
  }
  dragHandle(datum, target, context, snapping) {
    const { activeHandle, dragState } = this;
    if (!activeHandle || !dragState)
      return;
    this[activeHandle].toggleDragging(true);
    const point = snapping ? this.snapToAngle(datum, target, context) : invertCoords(this[activeHandle].drag(target).point, context);
    if (!point || !validateDatumPoint(context, point))
      return;
    datum[activeHandle].x = point.x;
    datum[activeHandle].y = point.y;
  }
  snapToAngle(datum, coords, context) {
    const { activeHandle } = this;
    const handles = ["start", "end", "endRetracement"];
    if (!activeHandle)
      return;
    const index = (handles.indexOf(activeHandle) + 1) % handles.length;
    const fixedHandle = handles[index];
    this[activeHandle].toggleDragging(true);
    const fixed = convertPoint(datum[fixedHandle], context);
    return invertCoords(snapToAngle(coords, fixed, datum.snapToAngle), context);
  }
  translatePoints({
    datum,
    start: start2,
    end: end3,
    endRetracement,
    translation,
    context
  }) {
    const points = translate({ start: start2, end: end3, endRetracement }, translation, context, { overflowContinuous: 2 });
    datum.start.x = points.start.x;
    datum.end.x = points.end.x;
    datum.endRetracement.x = points.endRetracement.x;
    datum.start.y = points.start.y;
    datum.end.y = points.end.y;
    datum.endRetracement.y = points.endRetracement.y;
  }
  translate(datum, translation, context) {
    this.translatePoints({
      datum,
      start: convertPoint(datum.start, context),
      end: convertPoint(datum.end, context),
      endRetracement: convertPoint(datum.endRetracement, context),
      translation,
      context
    });
  }
  copy(datum, copiedDatum, context) {
    const { coords1, coords2 } = this.getCoords(datum, context);
    if (!coords1 || !coords2) {
      return;
    }
    const bbox = this.computeBBoxWithoutHandles();
    this.translatePoints({
      datum: copiedDatum,
      start: vector4_exports.start(coords1),
      end: vector4_exports.end(coords1),
      endRetracement: vector4_exports.end(coords2),
      translation: { x: -bbox.width / 2, y: -bbox.height / 2 },
      context
    });
    return copiedDatum;
  }
  getCoords(datum, context) {
    return {
      coords1: convertLine(datum, context),
      coords2: convertLine({ start: datum.end, end: datum.endRetracement }, context)
    };
  }
  toggleHandles(show) {
    if (typeof show === "boolean") {
      this.start.visible = show;
      this.end.visible = show;
      this.endRetracement.visible = show;
    } else {
      for (const [handle3, visible] of entries(show)) {
        this[handle3].visible = visible;
      }
    }
    this.start.toggleHovered(this.activeHandle === "start");
    this.end.toggleHovered(this.activeHandle === "end");
    this.endRetracement.toggleHovered(this.activeHandle === "endRetracement");
  }
  toggleActive(active) {
    this.toggleHandles(active);
    this.start.toggleActive(active);
    this.end.toggleActive(active);
    this.endRetracement.toggleActive(active);
  }
  updateHandles(datum, coords1, coords2, bbox) {
    this.start.update({
      ...this.getHandleStyles(datum),
      ...this.getHandleCoords(datum, coords1, "start")
    });
    this.end.update({
      ...this.getHandleStyles(datum),
      ...this.getHandleCoords(datum, coords1, "end", bbox)
    });
    if (coords2) {
      this.endRetracement.update({
        ...this.getHandleStyles(datum),
        ...this.getHandleCoords(datum, coords2, "endRetracement", bbox)
      });
    }
    this.start.toggleLocked(datum.locked ?? false);
    this.end.toggleLocked(datum.locked ?? false);
    this.endRetracement.toggleLocked(datum.locked ?? false);
  }
  getHandleCoords(_datum, coords, handle3, _bbox) {
    return handle3 === "start" ? vector4_exports.start(coords) : vector4_exports.end(coords);
  }
};

// packages/ag-charts-enterprise/src/features/annotations/fibonacci-retracement-trend-based/fibonacciRetracementTrendBasedState.ts
var FibonacciRetracementTrendBasedStateMachine = class extends StateMachine {
  constructor(ctx) {
    const actionCreate = ({ point }) => {
      const datum = this.createDatum();
      datum.set({ start: point, end: point });
      ctx.create(datum);
    };
    const actionFirstRender = () => {
      const { node } = this;
      node?.toggleActive(true);
      node?.toggleHandles({ start: true, end: false, endRetracement: false });
    };
    const actionEndUpdate = ({ offset, context }) => {
      const { datum, snapping } = this;
      if (!datum)
        return;
      datum.set({ end: snapPoint(offset, context, snapping, datum.start, datum.snapToAngle) });
      ctx.update();
    };
    const actionEndFinish = () => {
      const { datum } = this;
      if (!datum)
        return;
      datum.endRetracement.x = datum.end.x;
      datum.endRetracement.y = datum.end.y;
      this.node?.toggleHandles({ end: true });
      ctx.update();
    };
    const actionEndRetracementUpdate = ({ offset, context }) => {
      const { datum, snapping } = this;
      if (!datum)
        return;
      datum.set({ endRetracement: snapPoint(offset, context, snapping, datum.end, datum.snapToAngle) });
      ctx.update();
    };
    const actionEndRetracementFinish = () => {
      this.node?.toggleHandles({ endRetracement: true });
      ctx.update();
    };
    const actionCancel = () => ctx.delete();
    const onExitEnd = () => {
      ctx.showAnnotationOptions();
      ctx.recordAction(`Create ${this.datum?.type} annotation`);
    };
    super("start", {
      start: {
        click: {
          target: "waiting-first-render",
          action: actionCreate
        },
        drag: {
          target: "waiting-first-render",
          action: actionCreate
        },
        reset: StateMachine.parent
      },
      "waiting-first-render": {
        render: {
          target: "end",
          action: actionFirstRender
        }
      },
      end: {
        hover: actionEndUpdate,
        click: {
          target: "endRetracement",
          action: actionEndFinish
        },
        drag: actionEndUpdate,
        dragEnd: {
          target: "endRetracement",
          action: actionEndFinish
        },
        reset: {
          target: StateMachine.parent,
          action: actionCancel
        },
        cancel: {
          target: StateMachine.parent,
          action: actionCancel
        },
        onExit: onExitEnd
      },
      endRetracement: {
        hover: actionEndRetracementUpdate,
        click: {
          target: StateMachine.parent,
          action: actionEndRetracementFinish
        },
        drag: {
          target: StateMachine.parent,
          action: actionEndRetracementFinish
        },
        reset: {
          target: StateMachine.parent,
          action: actionCancel
        },
        cancel: {
          target: StateMachine.parent,
          action: actionCancel
        }
      }
    });
    this.debug = debugLogger_exports.create(true, "annotations");
    this.snapping = false;
  }
  createDatum() {
    return new FibonacciRetracementTrendBasedProperties();
  }
};
__decorateClass([
  StateMachineProperty()
], FibonacciRetracementTrendBasedStateMachine.prototype, "datum", 2);
__decorateClass([
  StateMachineProperty()
], FibonacciRetracementTrendBasedStateMachine.prototype, "node", 2);
__decorateClass([
  StateMachineProperty()
], FibonacciRetracementTrendBasedStateMachine.prototype, "snapping", 2);

// packages/ag-charts-enterprise/src/features/annotations/fibonacci-retracement-trend-based/fibonacciRetracementTrendBasedConfig.ts
var fibonacciRetracementTrendBasedConfig = {
  type: "fibonacci-retracement-trend-based" /* FibonacciRetracementTrendBased */,
  datum: FibonacciRetracementTrendBasedProperties,
  scene: FibonacciRetracementTrendBasedScene,
  isDatum: FibonacciRetracementTrendBasedProperties.is,
  translate: (node, datum, transition, context) => {
    if (FibonacciRetracementTrendBasedProperties.is(datum) && FibonacciRetracementTrendBasedScene.is(node))
      node.translate(datum, transition, context);
  },
  copy: (node, datum, copiedDatum, context) => {
    if (FibonacciRetracementTrendBasedProperties.is(datum) && FibonacciRetracementTrendBasedProperties.is(copiedDatum) && FibonacciRetracementTrendBasedScene.is(node)) {
      return node.copy(datum, copiedDatum, context);
    }
  },
  update: (node, datum, context) => {
    if (FibonacciRetracementTrendBasedProperties.is(datum) && FibonacciRetracementTrendBasedScene.is(node)) {
      node.update(datum, context);
    }
  },
  createState: (ctx, { createDatum }) => new FibonacciRetracementTrendBasedStateMachine({
    ...ctx,
    create: createDatum("fibonacci-retracement-trend-based" /* FibonacciRetracementTrendBased */)
  }),
  dragState: (ctx) => new DragStateMachine(ctx)
};

// packages/ag-charts-enterprise/src/features/annotations/fibonacci-retracement/fibonacciRetracementScene.ts
var FibonacciRetracementScene = class extends FibonacciScene {
  constructor() {
    super();
    this.type = "fibonacci-retracement";
    this.start = new DivariantHandle();
    this.end = new DivariantHandle();
    this.append([this.start, this.end]);
  }
  static is(value) {
    return AnnotationScene.isCheck(value, "fibonacci-retracement");
  }
  containsPoint(x, y) {
    const { start: start2, end: end3 } = this;
    this.activeHandle = void 0;
    if (start2.containsPoint(x, y)) {
      this.activeHandle = "start";
      return true;
    }
    if (end3.containsPoint(x, y)) {
      this.activeHandle = "end";
      return true;
    }
    return super.containsPoint(x, y);
  }
  getNodeAtCoords(x, y) {
    if (this.start.containsPoint(x, y) || this.end.containsPoint(x, y))
      return "handle";
    return super.getNodeAtCoords(x, y);
  }
  dragStart(datum, target, context) {
    this.dragState = {
      offset: target,
      ...getDragStartState({ start: datum.start, end: datum.end }, context)
    };
  }
  stopDragging() {
    this.start.toggleDragging(false);
    this.end.toggleDragging(false);
  }
  dragAll(datum, target, context) {
    const { dragState } = this;
    if (!dragState)
      return;
    this.translatePoints({
      datum,
      start: dragState.start,
      end: dragState.end,
      translation: vector_exports.sub(target, dragState.offset),
      context
    });
  }
  dragHandle(datum, target, context, snapping) {
    const { activeHandle, dragState } = this;
    if (!activeHandle || !dragState)
      return;
    this[activeHandle].toggleDragging(true);
    const point = snapping ? this.snapToAngle(datum, target, context) : invertCoords(this[activeHandle].drag(target).point, context);
    if (!point || !validateDatumPoint(context, point))
      return;
    datum[activeHandle].x = point.x;
    datum[activeHandle].y = point.y;
  }
  snapToAngle(datum, coords, context) {
    const { activeHandle } = this;
    const handles = ["start", "end"];
    const fixedHandle = handles.find((handle3) => handle3 !== activeHandle);
    if (!activeHandle || !fixedHandle)
      return;
    this[activeHandle].toggleDragging(true);
    const fixed = convertPoint(datum[fixedHandle], context);
    return invertCoords(snapToAngle(coords, fixed, datum.snapToAngle), context);
  }
  translatePoints({
    datum,
    start: start2,
    end: end3,
    translation,
    context
  }) {
    const points = translate({ start: start2, end: end3 }, translation, context, { overflowContinuous: 1 });
    datum.start.x = points.start.x;
    datum.end.x = points.end.x;
    datum.start.y = points.start.y;
    datum.end.y = points.end.y;
  }
  translate(datum, translation, context) {
    this.translatePoints({
      datum,
      start: convertPoint(datum.start, context),
      end: convertPoint(datum.end, context),
      translation,
      context
    });
  }
  copy(datum, copiedDatum, context) {
    const coords = convertLine(datum, context);
    if (!coords) {
      return;
    }
    const bbox = this.computeBBoxWithoutHandles();
    this.translatePoints({
      datum: copiedDatum,
      start: { x: coords.x1, y: coords.y1 },
      end: { x: coords.x2, y: coords.y2 },
      translation: { x: -bbox.width / 2, y: -bbox.height / 2 },
      context
    });
    return copiedDatum;
  }
  toggleHandles(show) {
    if (typeof show === "boolean") {
      this.start.visible = show;
      this.end.visible = show;
    } else {
      for (const [handle3, visible] of entries(show)) {
        this[handle3].visible = visible;
      }
    }
    this.start.toggleHovered(this.activeHandle === "start");
    this.end.toggleHovered(this.activeHandle === "end");
  }
  toggleActive(active) {
    this.toggleHandles(active);
    this.start.toggleActive(active);
    this.end.toggleActive(active);
  }
  updateHandles(datum, coords, _coords2, bbox) {
    this.start.update({
      ...this.getHandleStyles(datum),
      ...this.getHandleCoords(datum, coords, "start")
    });
    this.end.update({
      ...this.getHandleStyles(datum),
      ...this.getHandleCoords(datum, coords, "end", bbox)
    });
    this.start.toggleLocked(datum.locked ?? false);
    this.end.toggleLocked(datum.locked ?? false);
  }
  getHandleCoords(_datum, coords, handle3, _bbox) {
    return handle3 === "start" ? vector4_exports.start(coords) : vector4_exports.end(coords);
  }
};

// packages/ag-charts-enterprise/src/features/annotations/line/lineState.ts
var LineTypeStateMachine = class extends StateMachine {
  constructor(ctx) {
    const actionCreate = ({ point }) => {
      const datum = this.createDatum();
      datum.set({ start: point, end: point });
      ctx.create(datum);
    };
    const actionFirstRender = () => {
      const { node } = this;
      node?.toggleActive(true);
      node?.toggleHandles({ start: true, end: false });
    };
    const actionEndUpdate = ({ offset, context }) => {
      const { datum, snapping } = this;
      if (!datum)
        return;
      datum.set({ end: snapPoint(offset, context, snapping, datum.start, datum.snapToAngle) });
      ctx.update();
    };
    const actionEndFinish = () => {
      this.node?.toggleHandles({ end: true });
      ctx.update();
    };
    const actionCancel = () => ctx.delete();
    const onExitEnd = () => {
      ctx.showAnnotationOptions();
      ctx.recordAction(`Create ${this.datum?.type} annotation`);
    };
    super("start", {
      start: {
        click: {
          target: "waiting-first-render",
          action: actionCreate
        },
        drag: {
          target: "waiting-first-render",
          action: actionCreate
        },
        reset: StateMachine.parent
      },
      "waiting-first-render": {
        render: {
          target: "end",
          action: actionFirstRender
        }
      },
      end: {
        hover: actionEndUpdate,
        click: {
          target: StateMachine.parent,
          action: actionEndFinish
        },
        drag: actionEndUpdate,
        dragEnd: {
          target: StateMachine.parent,
          action: actionEndFinish
        },
        reset: {
          target: StateMachine.parent,
          action: actionCancel
        },
        cancel: {
          target: StateMachine.parent,
          action: actionCancel
        },
        onExit: onExitEnd
      }
    });
    this.debug = debugLogger_exports.create(true, "annotations");
    this.snapping = false;
  }
};
__decorateClass([
  StateMachineProperty()
], LineTypeStateMachine.prototype, "datum", 2);
__decorateClass([
  StateMachineProperty()
], LineTypeStateMachine.prototype, "node", 2);
__decorateClass([
  StateMachineProperty()
], LineTypeStateMachine.prototype, "snapping", 2);
var ArrowStateMachine = class extends LineTypeStateMachine {
  createDatum() {
    return new ArrowProperties();
  }
};
var LineStateMachine = class extends LineTypeStateMachine {
  createDatum() {
    return new LineProperties();
  }
};

// packages/ag-charts-enterprise/src/features/annotations/fibonacci-retracement/fibonacciRetracementState.ts
var FibonacciRetracementStateMachine = class extends LineTypeStateMachine {
  createDatum() {
    return new FibonacciRetracementProperties();
  }
};

// packages/ag-charts-enterprise/src/features/annotations/fibonacci-retracement/fibonacciRetracementConfig.ts
var fibonacciRetracementConfig = {
  type: "fibonacci-retracement" /* FibonacciRetracement */,
  datum: FibonacciRetracementProperties,
  scene: FibonacciRetracementScene,
  isDatum: FibonacciRetracementProperties.is,
  translate: (node, datum, transition, context) => {
    if (FibonacciRetracementProperties.is(datum) && FibonacciRetracementScene.is(node))
      node.translate(datum, transition, context);
  },
  copy: (node, datum, copiedDatum, context) => {
    if (FibonacciRetracementProperties.is(datum) && FibonacciRetracementProperties.is(copiedDatum) && FibonacciRetracementScene.is(node)) {
      return node.copy(datum, copiedDatum, context);
    }
  },
  update: (node, datum, context) => {
    if (FibonacciRetracementProperties.is(datum) && FibonacciRetracementScene.is(node)) {
      node.update(datum, context);
    }
  },
  createState: (ctx, { createDatum }) => new FibonacciRetracementStateMachine({
    ...ctx,
    create: createDatum("fibonacci-retracement" /* FibonacciRetracement */)
  }),
  dragState: (ctx) => new DragStateMachine(ctx)
};

// packages/ag-charts-enterprise/src/features/annotations/scenes/capScene.ts
var CapScene = class extends module_support_exports.Group {
};
var ArrowCapScene = class extends CapScene {
  constructor() {
    super();
    this.type = "arrow";
    this.path = new module_support_exports.Path();
    this.armLength = 6;
    this.append([this.path]);
  }
  update(options) {
    const { path } = this;
    const { x, y, angle: angle2, ...rest } = options;
    const origin3 = vector_exports.from(x, y);
    const offsetAngle = 3 * Math.PI / 4;
    const armLength = this.armLength + (options.strokeWidth ?? 0) * 2;
    const leftEnd = vector_exports.rotate(vector_exports.from(0, armLength), angle2 + offsetAngle, origin3);
    const rightEnd = vector_exports.rotate(vector_exports.from(armLength, 0), angle2 - offsetAngle, origin3);
    path.setProperties(rest);
    path.fillOpacity = 0;
    path.path.clear();
    path.path.moveTo(leftEnd.x, leftEnd.y);
    path.path.lineTo(origin3.x, origin3.y);
    path.path.lineTo(rightEnd.x, rightEnd.y);
  }
};

// packages/ag-charts-enterprise/src/features/annotations/line/lineScene.ts
var { Transformable: Transformable4 } = module_support_exports;
var LineScene = class extends StartEndScene {
  constructor() {
    super();
    this.type = "line";
    this.line = new CollidableLine();
    this.append([this.line, this.start, this.end]);
  }
  static is(value) {
    return AnnotationScene.isCheck(value, "line");
  }
  update(datum, context) {
    let coords = convertLine(datum, context);
    if (coords == null) {
      this.visible = false;
      return;
    }
    coords = vector4_exports.round(coords);
    this.visible = datum.visible ?? true;
    if (!this.visible)
      return;
    this.updateLine(datum, coords, context);
    this.updateHandles(datum, coords);
    this.updateText(datum, coords);
    this.updateCaps(datum, coords);
    this.updateAnchor(datum, coords, context);
  }
  updateLine(datum, coords, context) {
    const { line } = this;
    const { lineDashOffset, stroke: stroke3, strokeWidth, strokeOpacity } = datum;
    const linePoints = this.extendLine(coords, datum, context);
    line.setProperties({
      ...linePoints,
      lineCap: datum.getLineCap(),
      lineDash: datum.getLineDash(),
      lineDashOffset,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      fillOpacity: 0
    });
  }
  updateText(datum, coords) {
    this.text = this.updateNode(CollidableText, this.text, !!datum.text.label);
    updateLineText(this.line.id, this.line, coords, datum.text, this.text, datum.text.label, datum.strokeWidth);
  }
  updateCaps(datum, coords) {
    if (!datum.startCap && this.startCap) {
      this.startCap.remove();
      this.startCap = void 0;
    }
    if (!datum.endCap && this.endCap) {
      this.endCap.remove();
      this.endCap = void 0;
    }
    if (!datum.startCap && !datum.endCap)
      return;
    const { stroke: stroke3, strokeWidth, strokeOpacity } = datum;
    const [start2, end3] = vector_exports.from(coords);
    const angle2 = vector_exports.angle(vector_exports.sub(end3, start2));
    if (datum.startCap) {
      if (this.startCap && this.startCap.type !== datum.startCap) {
        this.startCap.remove();
        this.startCap = void 0;
      }
      if (this.startCap == null) {
        this.startCap = new ArrowCapScene();
        this.append([this.startCap]);
      }
      this.startCap.update({
        x: start2.x,
        y: start2.y,
        angle: angle2 - Math.PI,
        stroke: stroke3,
        strokeWidth,
        strokeOpacity
      });
    }
    if (datum.endCap) {
      if (this.endCap && this.endCap.type !== datum.endCap) {
        this.endCap.remove();
        this.endCap = void 0;
      }
      if (this.endCap == null) {
        this.endCap = new ArrowCapScene();
        this.append([this.endCap]);
      }
      this.endCap.update({
        x: end3.x,
        y: end3.y,
        angle: angle2,
        stroke: stroke3,
        strokeWidth,
        strokeOpacity
      });
    }
  }
  updateAnchor(_datum, coords, _context, _bbox) {
    const point = vector4_exports.topCenter(coords);
    vector_exports.apply(this.anchor, Transformable4.toCanvasPoint(this.line, point.x, point.y));
  }
  containsPoint(x, y) {
    const { line, text: text2 } = this;
    return super.containsPoint(x, y) || line.isPointInPath(x, y) || Boolean(text2?.containsPoint(x, y));
  }
  getNodeAtCoords(x, y) {
    if (this.text?.containsPoint(x, y))
      return "text";
    if (this.line.isPointInPath(x, y))
      return "line";
    return super.getNodeAtCoords(x, y);
  }
  getHandleCoords(_datum, coords, handle3, _bbox) {
    const { startCap, endCap } = this;
    let [startPoint, endPoint] = vector_exports.from(coords);
    const angle2 = vector_exports.angle(vector_exports.sub(endPoint, startPoint));
    if (startCap) {
      startPoint = vector_exports.rotate(vector_exports.from(0, -DivariantHandle.HANDLE_SIZE / 2), angle2, startPoint);
    }
    if (endCap) {
      endPoint = vector_exports.rotate(vector_exports.from(0, DivariantHandle.HANDLE_SIZE / 2), angle2, endPoint);
    }
    return handle3 === "start" ? startPoint : endPoint;
  }
  getHandleStyles(datum) {
    return {
      fill: datum.handle.fill,
      stroke: datum.handle.stroke ?? datum.stroke,
      strokeOpacity: datum.handle.strokeOpacity ?? datum.strokeOpacity,
      strokeWidth: datum.handle.strokeWidth ?? datum.strokeWidth
    };
  }
};

// packages/ag-charts-enterprise/src/features/annotations/line/lineConfig.ts
var lineConfig = {
  type: "line" /* Line */,
  datum: LineProperties,
  scene: LineScene,
  isDatum: LineProperties.is,
  translate: (node, datum, transition, context) => {
    if (LineProperties.is(datum) && LineScene.is(node))
      node.translate(datum, transition, context);
  },
  copy: (node, datum, copiedDatum, context) => {
    if (LineProperties.is(datum) && LineProperties.is(copiedDatum) && LineScene.is(node)) {
      return node.copy(datum, copiedDatum, context);
    }
  },
  update: (node, datum, context) => {
    if (LineProperties.is(datum) && LineScene.is(node)) {
      node.update(datum, context);
    }
  },
  createState: (ctx, { createDatum }) => new LineStateMachine({
    ...ctx,
    create: createDatum("line" /* Line */)
  }),
  dragState: (ctx) => new DragStateMachine(ctx)
};
var arrowConfig = {
  type: "arrow" /* Arrow */,
  datum: ArrowProperties,
  scene: LineScene,
  isDatum: ArrowProperties.is,
  translate: (node, datum, transition, context) => {
    if (ArrowProperties.is(datum) && LineScene.is(node))
      node.translate(datum, transition, context);
  },
  copy: (node, datum, copiedDatum, context) => {
    if (ArrowProperties.is(datum) && ArrowProperties.is(copiedDatum) && LineScene.is(node)) {
      return node.copy(datum, copiedDatum, context);
    }
  },
  update: (node, datum, context) => {
    if (ArrowProperties.is(datum) && LineScene.is(node)) {
      node.update(datum, context);
    }
  },
  createState: (ctx, { createDatum }) => new ArrowStateMachine({
    ...ctx,
    create: createDatum("arrow" /* Arrow */)
  }),
  dragState: (ctx) => new DragStateMachine(ctx)
};

// packages/ag-charts-enterprise/src/features/annotations/utils/layout.ts
function layoutScenesRow(scenes, startX = 0, gap = 0) {
  let x = startX;
  for (const scene of scenes) {
    if (Array.isArray(scene)) {
      for (const scene_ of scene) {
        layoutSetX(scene_, x);
      }
      x += module_support_exports.Group.computeChildrenBBox(scene).width + gap;
    } else {
      layoutSetX(scene, x);
      x += scene.getBBox().width + gap;
    }
  }
}
function layoutScenesColumn(scenes, startY = 0, gap = 0) {
  let y = startY;
  for (const scene of scenes) {
    if (Array.isArray(scene)) {
      for (const scene_ of scene) {
        layoutSetY(scene_, y);
      }
      y += module_support_exports.Group.computeChildrenBBox(scene).height + gap;
    } else {
      layoutSetY(scene, y);
      y += scene.getBBox().height + gap;
    }
  }
}
function layoutSetX(scene, x) {
  if ("x1" in scene) {
    scene.x2 = x + (scene.x2 - scene.x1);
    scene.x1 = x;
  } else {
    scene.x = x;
  }
}
function layoutSetY(scene, y) {
  if ("y1" in scene) {
    scene.y2 = y + (scene.y2 - scene.y1);
    scene.y1 = y;
  } else {
    scene.y = y;
  }
}
function layoutAddX(scene, x) {
  if ("x1" in scene) {
    scene.x1 += x;
    scene.x2 += x;
  } else {
    scene.x += x;
  }
}
function layoutAddY(scene, y) {
  if ("y1" in scene) {
    scene.y1 += y;
    scene.y2 += y;
  } else {
    scene.y += y;
  }
}

// packages/ag-charts-enterprise/src/features/annotations/measurer/measurerStatisticsScene.ts
var MeasurerStatisticsScene = class extends module_support_exports.Group {
  constructor() {
    super();
    this.name = "MeasurerStatisticsScene";
    this.background = new module_support_exports.Rect();
    this.dateRangeBarsText = new module_support_exports.Text();
    this.dateRangeDivider = new module_support_exports.Line();
    this.dateRangeValueText = new module_support_exports.Text();
    this.priceRangeValueText = new module_support_exports.Text();
    this.priceRangeDivider = new module_support_exports.Line();
    this.priceRangePercentageText = new module_support_exports.Text();
    this.volumeText = new module_support_exports.Text();
    this.volumeFormatter = new Intl.NumberFormat("en-US", {
      notation: "compact",
      minimumFractionDigits: 2,
      maximumFractionDigits: 2
    });
    this.append([
      this.background,
      this.dateRangeBarsText,
      this.dateRangeDivider,
      this.dateRangeValueText,
      this.priceRangeValueText,
      this.priceRangeDivider,
      this.priceRangePercentageText,
      this.volumeText
    ]);
  }
  update(datum, stats, anchor, coords, context, verticalDirection, localeManager) {
    this.verticalDirection = verticalDirection;
    const scenes = this.updateStatistics(datum, stats, anchor, localeManager);
    const bbox = module_support_exports.Group.computeChildrenBBox(scenes.flat());
    const padding2 = 10;
    bbox.grow(padding2);
    this.updateBackground(datum, bbox, padding2);
    this.reposition(scenes, padding2, context);
    this.checkVisibility(datum, context, coords);
  }
  checkVisibility(datum, context, coords) {
    const bounds = vector4_exports.from(context.seriesRect);
    this.visible = vector4_exports.collides(coords, bounds) && (datum.visible ?? true);
  }
  updateStatistics(datum, stats, anchor, localeManager) {
    const {
      dateRangeBarsText,
      dateRangeDivider,
      dateRangeValueText,
      priceRangeValueText,
      priceRangeDivider,
      priceRangePercentageText,
      volumeText
    } = this;
    const horizontalGap = 8;
    const verticalGap = 6;
    const dividerLineHeight = datum.statistics.fontSize + 3;
    const dividerLineOffset = -2;
    const textStyles = this.getTextStyles(datum);
    const dividerLineStyles = {
      ...this.getDividerStyles(datum),
      x1: 0,
      y1: 0,
      x2: 0,
      y2: dividerLineHeight
    };
    const dateScenes = [dateRangeBarsText, dateRangeDivider, dateRangeValueText];
    const priceScenes = [priceRangeValueText, priceRangeDivider, priceRangePercentageText];
    const scenes = [];
    if (stats.priceRange) {
      priceRangeValueText.setProperties({
        ...textStyles,
        text: this.formatPriceRangeValue(stats.priceRange.value, localeManager)
      });
      priceRangeDivider.setProperties(dividerLineStyles);
      priceRangePercentageText.setProperties({
        ...textStyles,
        text: this.formatPriceRangePercentage(stats.priceRange.percentage, localeManager)
      });
      layoutScenesRow(priceScenes, anchor.x, horizontalGap);
      scenes.push(priceScenes);
    }
    if (stats.dateRange) {
      dateRangeBarsText.setProperties({
        ...textStyles,
        text: this.formatDateRangeBars(stats.dateRange.bars, localeManager)
      });
      dateRangeDivider.setProperties(dividerLineStyles);
      dateRangeValueText.setProperties({
        ...textStyles,
        text: this.formatDateRangeValue(stats.dateRange.value)
      });
      layoutScenesRow(dateScenes, anchor.x, horizontalGap);
      scenes.push(dateScenes);
    }
    if (stats.volume == null) {
      volumeText.visible = false;
    } else {
      volumeText.setProperties({
        ...textStyles,
        x: anchor.x,
        text: this.formatVolume(stats.volume, localeManager),
        visible: true
      });
      scenes.push(volumeText);
    }
    layoutScenesColumn(scenes, anchor.y, verticalGap);
    priceRangeDivider.y1 += dividerLineOffset;
    priceRangeDivider.y2 += dividerLineOffset;
    dateRangeDivider.y1 += dividerLineOffset;
    dateRangeDivider.y2 += dividerLineOffset;
    return scenes;
  }
  updateBackground(datum, bbox, padding2) {
    const styles = this.getBackgroundStyles(datum);
    this.background.setProperties({
      ...styles,
      ...bbox,
      x: bbox.x - bbox.width / 2 + padding2,
      y: bbox.y
    });
  }
  reposition(scenes, padding2, context) {
    const { width: width2, height: height2 } = context.seriesRect;
    const background = vector4_exports.from(this.background.getBBox());
    let offsetX = 0;
    if (background.x1 < 0)
      offsetX = -background.x1;
    if (background.x2 > width2)
      offsetX = width2 - background.x2;
    const offsetY = Math.min(padding2, height2 - background.y2);
    for (const scene of scenes) {
      if (Array.isArray(scene)) {
        const rowWidth = module_support_exports.Group.computeChildrenBBox(scene).width;
        for (const scene_ of scene) {
          layoutAddX(scene_, offsetX - rowWidth / 2);
          layoutAddY(scene_, offsetY);
        }
      } else {
        layoutAddX(scene, offsetX - scene.getBBox().width / 2);
        layoutAddY(scene, offsetY);
      }
    }
    this.background.x += offsetX;
    this.background.y += offsetY;
  }
  getTextStyles(datum) {
    return {
      fill: datum.statistics.color,
      fontFamily: datum.statistics.fontFamily,
      fontSize: datum.statistics.fontSize,
      fontStyle: datum.statistics.fontStyle,
      fontWeight: datum.statistics.fontWeight,
      textBaseline: "top"
    };
  }
  getDividerStyles(datum) {
    return {
      stroke: datum.statistics.divider.stroke,
      strokeOpacity: datum.statistics.divider.strokeOpacity,
      strokeWidth: datum.statistics.divider.strokeWidth
    };
  }
  getBackgroundStyles(datum) {
    return {
      fill: datum.statistics.fill,
      stroke: datum.statistics.stroke,
      strokeOpacity: datum.statistics.strokeOpacity,
      strokeWidth: datum.statistics.strokeWidth,
      cornerRadius: 4
    };
  }
  formatDateRangeBars(bars, localeManager) {
    return localeManager?.t("measurerDateRangeBars", { value: bars }) ?? `${bars}`;
  }
  formatDateRangeValue(time3) {
    const range3 = [];
    const sign = time3 >= 0 ? "" : "-";
    time3 = Math.abs(time3);
    const MINUTE = 1e3 * 60;
    const HOUR = MINUTE * 60;
    const DAY2 = HOUR * 24;
    const minutes = Math.floor(time3 / MINUTE);
    const hours = Math.floor(time3 / HOUR);
    const days = Math.floor(time3 / DAY2);
    const remainderHours = hours % (DAY2 / HOUR);
    const remainderMinutes = minutes % (HOUR / MINUTE);
    if (days >= 1)
      range3.push(`${days}d`);
    if (hours >= 1 && (time3 < DAY2 || remainderHours !== 0))
      range3.push(`${remainderHours}h`);
    if (time3 < HOUR || remainderMinutes !== 0)
      range3.push(`${remainderMinutes}m`);
    range3[0] = `${sign}${range3[0]}`;
    return range3.join(" ");
  }
  formatPriceRangeValue(value, localeManager) {
    return localeManager?.t("measurerPriceRangeValue", { value: Number(value.toFixed(2)) }) ?? `${value}`;
  }
  formatPriceRangePercentage(percentage, localeManager) {
    return localeManager?.t("measurerPriceRangePercent", { value: percentage }) ?? `${percentage}`;
  }
  formatVolume(volume, localeManager) {
    const volumeString = Number.isNaN(volume) ? "" : this.volumeFormatter.format(volume);
    return localeManager?.t("measurerVolume", { value: volumeString }) ?? volumeString;
  }
};
var QuickMeasurerStatisticsScene = class extends MeasurerStatisticsScene {
  getDirectionStyles(datum) {
    return this.verticalDirection === "down" ? datum.down.statistics : datum.up.statistics;
  }
  getTextStyles(datum) {
    const styles = this.getDirectionStyles(datum);
    return {
      ...super.getTextStyles(datum),
      fill: styles.color,
      fontFamily: styles.fontFamily,
      fontSize: styles.fontSize,
      fontStyle: styles.fontStyle,
      fontWeight: styles.fontWeight
    };
  }
  getDividerStyles(datum) {
    const styles = this.getDirectionStyles(datum);
    return {
      stroke: styles.divider.stroke,
      strokeOpacity: styles.divider.strokeOpacity,
      strokeWidth: styles.divider.strokeWidth
    };
  }
  getBackgroundStyles(datum) {
    const styles = this.getDirectionStyles(datum);
    return {
      ...super.getBackgroundStyles(datum),
      fill: styles.fill,
      stroke: styles.stroke,
      strokeOpacity: styles.strokeOpacity,
      strokeWidth: styles.strokeWidth
    };
  }
};

// packages/ag-charts-enterprise/src/features/annotations/measurer/measurerScene.ts
var MeasurerScene = class extends StartEndScene {
  constructor() {
    super();
    this.type = "measurer";
    this.horizontalLine = new CollidableLine();
    this.verticalLine = new CollidableLine();
    // These four bounding lines are named after the way they are drawn, e.g. the horizontalStartLine is a horizontal
    // line that is only shown when the measurer has the 'vertical' direction.
    this.horizontalStartLine = new CollidableLine();
    this.horizontalEndLine = new CollidableLine();
    this.verticalStartLine = new CollidableLine();
    this.verticalEndLine = new CollidableLine();
    this.horizontalEndCap = new ArrowCapScene();
    this.verticalEndCap = new ArrowCapScene();
    this.background = new module_support_exports.Path({ zIndex: -1 });
    this.updateBackground = WithBackgroundScene.updateBackground.bind(this);
    this.statistics = this.createStatisticsScene();
    this.statistics.zIndex = 1;
    this.append([
      this.background,
      this.verticalStartLine,
      this.verticalEndLine,
      this.horizontalStartLine,
      this.horizontalEndLine,
      this.horizontalLine,
      this.verticalLine,
      this.horizontalEndCap,
      this.verticalEndCap,
      this.start,
      this.end,
      this.statistics
    ]);
  }
  static is(value) {
    return AnnotationScene.isCheck(value, "measurer");
  }
  createStatisticsScene() {
    return new MeasurerStatisticsScene();
  }
  update(datum, context) {
    const coords = convertLine(datum, context);
    if (coords == null) {
      this.visible = false;
      return;
    }
    this.visible = datum.visible ?? true;
    if (!this.visible)
      return;
    const extended = this.extendPerpendicular(coords, datum, context);
    const verticalStart = { ...extended, y2: extended.y1 };
    const verticalEnd = { ...extended, y1: extended.y2 };
    this.verticalDirection = coords.y1 < coords.y2 ? "down" : "up";
    this.updateVisibilities(datum);
    this.updateLines(datum, coords);
    this.updateHandles(datum, coords);
    this.updateText(datum, coords);
    this.updateCaps(datum, coords);
    this.updateBoundingLines(datum, extended);
    this.updateBackground(datum, verticalStart, verticalEnd, context);
    this.updateStatistics(datum, coords, context);
    this.updateAnchor(datum, coords, context);
  }
  extendPerpendicular(coords, datum, context) {
    const extended = {
      x1: Math.min(coords.x1, coords.x2),
      x2: Math.max(coords.x1, coords.x2),
      y1: Math.min(coords.y1, coords.y2),
      y2: Math.max(coords.y1, coords.y2)
    };
    const [start2, end3] = vector_exports.from(context.yAxis.bounds);
    if (DateRangeProperties.is(datum)) {
      if (datum.extendAbove)
        extended.y1 = start2.y;
      if (datum.extendBelow)
        extended.y2 = end3.y;
    } else if (PriceRangeProperties.is(datum)) {
      if (datum.extendLeft)
        extended.x1 = start2.x;
      if (datum.extendRight)
        extended.x2 = end3.x;
    }
    return extended;
  }
  updateVisibilities(datum) {
    const {
      horizontalStartLine,
      horizontalEndLine,
      horizontalEndCap,
      verticalStartLine,
      verticalEndLine,
      verticalEndCap
    } = this;
    const { direction } = datum;
    verticalStartLine.visible = direction !== "vertical";
    verticalEndLine.visible = direction !== "vertical";
    horizontalEndCap.visible = direction !== "vertical";
    horizontalStartLine.visible = direction !== "horizontal";
    horizontalEndLine.visible = direction !== "horizontal";
    verticalEndCap.visible = direction !== "horizontal";
  }
  updateLines(datum, coords) {
    const { horizontalLine, verticalLine } = this;
    const { direction } = datum;
    const { x1, y1, x2, y2 } = coords;
    const center2 = vector_exports.round(vector4_exports.center(coords), 0);
    const lineStyles = this.getLineStyles(datum);
    if (direction !== "vertical") {
      horizontalLine.setProperties({
        ...lineStyles,
        x1,
        x2,
        y1: center2.y,
        y2: center2.y
      });
    }
    if (direction !== "horizontal") {
      verticalLine.setProperties({
        ...lineStyles,
        x1: center2.x,
        x2: center2.x,
        y1,
        y2
      });
    }
  }
  updateText(datum, coords) {
    const { direction } = datum;
    const center2 = vector_exports.round(vector4_exports.center(coords), 0);
    let line;
    const textCoords = { ...coords };
    if (direction === "vertical") {
      line = this.verticalLine;
      textCoords.x1 = center2.x;
      textCoords.x2 = center2.x;
    } else {
      line = this.horizontalLine;
      textCoords.y1 = center2.y;
      textCoords.y2 = center2.y;
    }
    this.text = this.updateNode(CollidableText, this.text, !!datum.text.label);
    const { id } = line;
    const clip = updateLineText(id, line, textCoords, datum.text, this.text, datum.text.label, datum.strokeWidth);
    let verticalClipMask;
    if (direction === "both" && clip && this.text) {
      const textBBox = vector4_exports.from(this.text.getBBox());
      const { offset } = clip.numbers;
      const crossesVerticalLine = textBBox.x1 <= center2.x + offset.x && textBBox.x2 >= center2.x - offset.x;
      if (crossesVerticalLine) {
        verticalClipMask = {
          x: center2.x,
          y: clip.clipMask.y,
          radius: this.text.getBBox().height / 2 + vector_exports.length(offset)
        };
      }
    }
    this.verticalLine.setClipMask(id, verticalClipMask);
  }
  updateCaps(datum, coords) {
    const { horizontalEndCap, verticalEndCap } = this;
    const { direction } = datum;
    const { x1, y1, x2, y2 } = coords;
    const center2 = vector_exports.round(vector4_exports.center(coords), 0);
    const { stroke: stroke3, strokeWidth, strokeOpacity } = this.getLineStyles(datum);
    const capStyles = { stroke: stroke3, strokeWidth, strokeOpacity };
    if (direction !== "vertical") {
      const angle2 = x1 <= x2 ? 0 : Math.PI;
      let x = x2;
      if (direction === "horizontal") {
        x += x1 <= x2 ? -2 : 2;
      }
      horizontalEndCap.update({ ...capStyles, x, y: center2.y, angle: angle2 });
    }
    if (direction !== "horizontal") {
      const angle2 = y1 <= y2 ? Math.PI / 2 : Math.PI / -2;
      let y = y2;
      if (direction === "vertical") {
        y += y1 <= y2 ? -2 : 2;
      }
      verticalEndCap.update({ ...capStyles, x: center2.x, y, angle: angle2 });
    }
  }
  updateBoundingLines(datum, extendedCoords) {
    const { verticalStartLine, verticalEndLine, horizontalStartLine, horizontalEndLine } = this;
    const { direction } = datum;
    const { x1, y1, x2, y2 } = extendedCoords;
    const lineStyles = this.getLineStyles(datum);
    if (direction === "horizontal") {
      verticalStartLine.setProperties({ ...lineStyles, x1, y1, x2: x1, y2 });
      verticalEndLine.setProperties({ ...lineStyles, x1: x2, y1, x2, y2 });
    }
    if (direction === "vertical") {
      horizontalStartLine.setProperties({ ...lineStyles, x1, y1, x2, y2: y1 });
      horizontalEndLine.setProperties({ ...lineStyles, x1, y1: y2, x2, y2 });
    }
  }
  updateStatistics(datum, coords, context) {
    const point = vector_exports.add(vector4_exports.bottomCenter(coords), vector_exports.from(0, 10));
    const statistics = { volume: this.getVolume(datum) };
    if (datum.hasPriceRange) {
      statistics.priceRange = {
        percentage: this.getPriceRangePercentage(datum),
        value: this.getPriceRangeValue(datum)
      };
    }
    if (datum.hasDateRange) {
      statistics.dateRange = {
        bars: this.getDateRangeBars(coords, context),
        value: this.getDateRangeValue(datum)
      };
    }
    this.statistics.update(datum, statistics, point, coords, context, this.verticalDirection, datum.localeManager);
  }
  updateAnchor(_datum, coords, _context, _bbox) {
    const point = vector4_exports.topCenter(coords);
    vector_exports.apply(this.anchor, module_support_exports.Transformable.toCanvasPoint(this.horizontalLine, point.x, point.y));
  }
  getBackgroundPoints(_datum, verticalStart, verticalEnd, _bounds) {
    const [startStart, startEnd] = vector_exports.from(verticalStart);
    const [endStart, endEnd] = vector_exports.from(verticalEnd);
    return [startStart, startEnd, endEnd, endStart];
  }
  getLineStyles(datum) {
    const { lineDashOffset, stroke: stroke3, strokeWidth, strokeOpacity } = datum;
    return {
      lineCap: datum.getLineCap(),
      lineDash: datum.getLineDash(),
      lineDashOffset,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      fillOpacity: 0
    };
  }
  getBackgroundStyles(datum) {
    const { background } = datum;
    return {
      fill: background.fill,
      fillOpacity: background.fillOpacity
    };
  }
  getHandleStyles(datum) {
    return {
      fill: datum.handle.fill,
      stroke: datum.handle.stroke ?? datum.stroke,
      strokeOpacity: datum.handle.strokeOpacity ?? datum.strokeOpacity,
      strokeWidth: datum.handle.strokeWidth ?? datum.strokeWidth
    };
  }
  containsPoint(x, y) {
    const {
      horizontalLine,
      text: text2,
      verticalLine,
      horizontalStartLine,
      horizontalEndLine,
      verticalStartLine,
      verticalEndLine
    } = this;
    return super.containsPoint(x, y) || horizontalLine.isPointInPath(x, y) || verticalLine.isPointInPath(x, y) || horizontalStartLine.visible && horizontalStartLine.isPointInPath(x, y) || horizontalEndLine.visible && horizontalEndLine.isPointInPath(x, y) || verticalStartLine.visible && verticalStartLine.isPointInPath(x, y) || verticalEndLine.visible && verticalEndLine.isPointInPath(x, y) || Boolean(text2?.containsPoint(x, y));
  }
  getNodeAtCoords(x, y) {
    if (this.text?.containsPoint(x, y))
      return "text";
    if (this.start.containsPoint(x, y) || this.end.containsPoint(x, y))
      return "handle";
    return "line";
  }
  getDateRangeBars(coords, context) {
    const { step } = context.xAxis.scale;
    const sign = coords.x1 <= coords.x2 ? 1 : -1;
    return step ? Math.round(vector4_exports.width(coords) / step) * sign : 0;
  }
  getDateRangeValue(datum) {
    const start2 = getGroupingValue(datum.start.x);
    const end3 = getGroupingValue(datum.end.x);
    if (!isDate(start2) || !isDate(end3)) {
      throw new Error("Can not create a date range measurement of non-date x-axis.");
    }
    return end3.getTime() - start2.getTime();
  }
  getPriceRangePercentage(datum) {
    if (datum.start.y == null || datum.end.y == null) {
      throw new Error("Can not create a price range measurement of a non-numeric y-axis");
    }
    const endY = getGroupingValue(datum.end.y);
    const startY = getGroupingValue(datum.start.y);
    if (!isNumber(endY) || !isNumber(startY)) {
      throw new Error("Can not create a price range measurement of a non-numeric y-axis");
    }
    return (endY - startY) / startY;
  }
  getPriceRangeValue(datum) {
    if (datum.start.y == null || datum.end.y == null) {
      throw new Error("Can not create a price range measurement of a non-numeric y-axis");
    }
    const endY = getGroupingValue(datum.end.y);
    const startY = getGroupingValue(datum.start.y);
    if (!isNumber(endY) || !isNumber(startY)) {
      throw new Error("Can not create a price range measurement of a non-numeric y-axis");
    }
    return endY - startY;
  }
  getVolume(datum) {
    return datum.getVolume(datum.start.x, datum.end.x);
  }
};
var QuickMeasurerScene = class extends MeasurerScene {
  constructor() {
    super(...arguments);
    this.type = "quick-measurer";
  }
  static is(value) {
    return AnnotationScene.isCheck(value, "quick-measurer");
  }
  createStatisticsScene() {
    return new QuickMeasurerStatisticsScene();
  }
  getDirectionStyles(datum) {
    return this.verticalDirection === "down" ? datum.down : datum.up;
  }
  getLineStyles(datum) {
    const styles = this.getDirectionStyles(datum);
    return {
      ...super.getLineStyles(datum),
      stroke: styles.stroke,
      strokeWidth: styles.strokeWidth,
      strokeOpacity: styles.strokeOpacity
    };
  }
  getBackgroundStyles(datum) {
    const styles = this.getDirectionStyles(datum);
    return {
      fill: styles.fill,
      fillOpacity: styles.fillOpacity
    };
  }
  getHandleStyles(datum) {
    const styles = this.getDirectionStyles(datum);
    return {
      fill: styles.handle.fill,
      stroke: styles.handle.stroke ?? styles.stroke,
      strokeOpacity: styles.handle.strokeOpacity ?? styles.strokeOpacity,
      strokeWidth: styles.handle.strokeWidth ?? styles.strokeWidth
    };
  }
};

// packages/ag-charts-enterprise/src/features/annotations/measurer/measurerState.ts
var MeasurerTypeStateMachine = class extends StateMachine {
  constructor(ctx) {
    const actionCreate = ({ point }) => {
      const datum = this.createDatum();
      datum.set({ start: point, end: point });
      ctx.create(datum);
    };
    const actionEndUpdate = ({ point }) => {
      const { datum, node } = this;
      datum?.set({ end: point });
      node?.toggleActive(true);
      node?.toggleHandles({ end: false });
      ctx.update();
    };
    const actionEndFinish = () => {
      this.node?.toggleHandles({ end: true });
    };
    const actionCancel = () => ctx.delete();
    const onExitEnd = () => {
      ctx.showAnnotationOptions();
      ctx.recordAction(`Create ${this.node?.type} annotation`);
    };
    super("start", {
      start: {
        reset: StateMachine.parent,
        click: {
          target: "end",
          action: actionCreate
        },
        drag: {
          target: "end",
          action: actionCreate
        }
      },
      end: {
        hover: actionEndUpdate,
        drag: actionEndUpdate,
        click: {
          target: StateMachine.parent,
          action: actionEndFinish
        },
        dragEnd: {
          target: StateMachine.parent,
          action: actionEndFinish
        },
        reset: {
          target: StateMachine.parent,
          action: actionCancel
        },
        cancel: {
          target: StateMachine.parent,
          action: actionCancel
        },
        onExit: onExitEnd
      }
    });
    this.debug = debugLogger_exports.create(true, "annotations");
  }
};
__decorateClass([
  StateMachineProperty()
], MeasurerTypeStateMachine.prototype, "datum", 2);
__decorateClass([
  StateMachineProperty()
], MeasurerTypeStateMachine.prototype, "node", 2);
var DateRangeStateMachine = class extends MeasurerTypeStateMachine {
  createDatum() {
    return new DateRangeProperties();
  }
};
var PriceRangeStateMachine = class extends MeasurerTypeStateMachine {
  createDatum() {
    return new PriceRangeProperties();
  }
};
var DatePriceRangeStateMachine = class extends MeasurerTypeStateMachine {
  createDatum() {
    return new DatePriceRangeProperties();
  }
};
var QuickDatePriceRangeStateMachine = class extends MeasurerTypeStateMachine {
  createDatum() {
    return new QuickDatePriceRangeProperties();
  }
};

// packages/ag-charts-enterprise/src/features/annotations/measurer/measurerConfig.ts
var dateRangeConfig = {
  type: "date-range" /* DateRange */,
  datum: DateRangeProperties,
  scene: MeasurerScene,
  isDatum: DateRangeProperties.is,
  translate: (node, datum, translation, context) => {
    if (DateRangeProperties.is(datum) && MeasurerScene.is(node)) {
      node.translate(datum, translation, context);
    }
  },
  copy: (node, datum, copiedDatum, context) => {
    if (DateRangeProperties.is(datum) && DateRangeProperties.is(copiedDatum) && MeasurerScene.is(node)) {
      return node.copy(datum, copiedDatum, context);
    }
  },
  update: (node, datum, context) => {
    if (DateRangeProperties.is(datum) && MeasurerScene.is(node)) {
      node.update(datum, context);
    }
  },
  createState: (ctx, { createDatum }) => new DateRangeStateMachine({
    ...ctx,
    create: createDatum("date-range" /* DateRange */)
  }),
  dragState: (ctx) => new DragStateMachine(ctx)
};
var priceRangeConfig = {
  type: "price-range" /* PriceRange */,
  datum: PriceRangeProperties,
  scene: MeasurerScene,
  isDatum: PriceRangeProperties.is,
  translate: (node, datum, translation, context) => {
    if (PriceRangeProperties.is(datum) && MeasurerScene.is(node)) {
      node.translate(datum, translation, context);
    }
  },
  copy: (node, datum, copiedDatum, context) => {
    if (PriceRangeProperties.is(datum) && PriceRangeProperties.is(copiedDatum) && MeasurerScene.is(node)) {
      return node.copy(datum, copiedDatum, context);
    }
  },
  update: (node, datum, context) => {
    if (PriceRangeProperties.is(datum) && MeasurerScene.is(node)) {
      node.update(datum, context);
    }
  },
  createState: (ctx, { createDatum }) => new PriceRangeStateMachine({
    ...ctx,
    create: createDatum("date-range" /* DateRange */)
  }),
  dragState: (ctx) => new DragStateMachine(ctx)
};
var datePriceRangeConfig = {
  type: "date-price-range" /* DatePriceRange */,
  datum: DatePriceRangeProperties,
  scene: MeasurerScene,
  isDatum: DatePriceRangeProperties.is,
  translate: (node, datum, translation, context) => {
    if (DatePriceRangeProperties.is(datum) && MeasurerScene.is(node)) {
      node.translate(datum, translation, context);
    }
  },
  copy: (node, datum, copiedDatum, context) => {
    if (DatePriceRangeProperties.is(datum) && DatePriceRangeProperties.is(copiedDatum) && MeasurerScene.is(node)) {
      return node.copy(datum, copiedDatum, context);
    }
  },
  update: (node, datum, context) => {
    if (DatePriceRangeProperties.is(datum) && MeasurerScene.is(node)) {
      node.update(datum, context);
    }
  },
  createState: (ctx, { createDatum }) => new DatePriceRangeStateMachine({
    ...ctx,
    create: createDatum("date-range" /* DateRange */)
  }),
  dragState: (ctx) => new DragStateMachine(ctx)
};
var quickDatePriceRangeConfig = {
  type: "quick-date-price-range" /* QuickDatePriceRange */,
  datum: QuickDatePriceRangeProperties,
  scene: QuickMeasurerScene,
  isDatum: QuickDatePriceRangeProperties.is,
  translate: (node, datum, translation, context) => {
    if (QuickDatePriceRangeProperties.is(datum) && QuickMeasurerScene.is(node)) {
      node.translate(datum, translation, context);
    }
  },
  copy: (node, datum, copiedDatum, context) => {
    if (QuickDatePriceRangeProperties.is(datum) && QuickDatePriceRangeProperties.is(copiedDatum) && QuickMeasurerScene.is(node)) {
      return node.copy(datum, copiedDatum, context);
    }
  },
  update: (node, datum, context) => {
    if (QuickDatePriceRangeProperties.is(datum) && QuickMeasurerScene.is(node)) {
      node.update(datum, context);
    }
  },
  createState: (ctx, { createDatum }) => new QuickDatePriceRangeStateMachine({
    ...ctx,
    create: createDatum("quick-date-price-range" /* QuickDatePriceRange */)
  }),
  dragState: (ctx) => new DragStateMachine(ctx)
};

// packages/ag-charts-enterprise/src/features/annotations/note/noteScene.ts
var NoteScene = class extends TextualPointScene {
  constructor() {
    super();
    this.type = "note" /* Note */;
    this.shape = new module_support_exports.Rect();
    this.iconBackground = new module_support_exports.TranslatableSvgPath(
      "M22 1.83333C22 0.820811 21.1792 0 20.1667 0H1.83333C0.820811 0 0 0.82081 0 1.83333V13.9868C0 14.9994 0.820811 15.8202 1.83333 15.8202L5.88971 15.8202C6.44575 15.8202 6.97175 16.0725 7.31971 16.5062L9.57006 19.3112C10.304 20.2259 11.6962 20.2259 12.4301 19.3112L14.6804 16.5062C15.0284 16.0725 15.5544 15.8202 16.1104 15.8202L20.1667 15.8202C21.1792 15.8202 22 14.9994 22 13.9868V1.83333Z"
    );
    this.iconLines = new module_support_exports.TranslatableSvgPath(
      "M17.1114 5.75C17.1114 6.16421 16.7756 6.5 16.3614 6.5H5.63916C5.22495 6.5 4.88916 6.16421 4.88916 5.75V5.75C4.88916 5.33579 5.22495 5 5.63916 5H16.3614C16.7756 5 17.1114 5.33579 17.1114 5.75V5.75ZM17.1114 9.25C17.1114 9.66421 16.7756 10 16.3614 10H5.63916C5.22495 10 4.88916 9.66421 4.88916 9.25V9.25C4.88916 8.83579 5.22495 8.5 5.63916 8.5H16.3614C16.7756 8.5 17.1114 8.83579 17.1114 9.25V9.25Z"
    );
    this.active = false;
    this.shape.visible = false;
    this.label.visible = false;
    this.iconBackground.fillShadow = new module_support_exports.DropShadow();
    this.append([this.shape, this.label, this.iconBackground, this.iconLines, this.handle]);
  }
  static is(value) {
    return AnnotationScene.isCheck(value, "note" /* Note */);
  }
  update(datum, context) {
    this.updateIcon(datum, context);
    super.update(datum, context);
  }
  getTextBBox(datum, coords, context) {
    const bbox = super.getTextBBox(datum, coords, context);
    bbox.x -= datum.width / 2;
    bbox.x = clamp(0, bbox.x, context.seriesRect.width - datum.width);
    const padding2 = datum.getPadding().top;
    const topY = bbox.y - LABEL_OFFSET - padding2 * 2;
    const bottomY = bbox.y + DivariantHandle.HANDLE_SIZE + padding2 * 2;
    if (topY - bbox.height - TOOLBAR_OFFSET < 0) {
      bbox.y = bottomY;
      datum.position = "top";
    } else {
      bbox.y = topY + padding2;
      datum.position = "bottom";
    }
    return bbox;
  }
  updateLabel(datum, bbox) {
    const labelVisibility = datum.visible === false ? false : this.label.visible;
    super.updateLabel(datum, bbox);
    this.label.visible = labelVisibility;
    this.label.text = wrapText(datum.text, {
      maxWidth: 200,
      font: datum,
      textWrap: "always",
      avoidOrphans: false
    });
  }
  updateShape(datum, bbox) {
    const { shape } = this;
    shape.fill = datum.background.fill;
    shape.fillOpacity = datum.background.fillOpacity ?? 1;
    shape.stroke = datum.background.stroke;
    shape.strokeOpacity = datum.background.strokeOpacity ?? 1;
    shape.strokeWidth = datum.background.strokeWidth ?? 1;
    shape.cornerRadius = 4;
    const padding2 = datum.getPadding().top;
    const isPositionTop = datum.position === "top";
    shape.x = bbox.x - padding2;
    shape.width = datum.width + padding2 * 2;
    shape.height = bbox.height + padding2 * 2;
    shape.y = bbox.y + (isPositionTop ? 0 : -bbox.height) - padding2;
  }
  updateIcon(datum, context) {
    const { active, iconBackground, iconLines } = this;
    const { x, y } = convertPoint(datum, context);
    iconBackground.translationX = x - ICON_WIDTH / 2;
    iconBackground.translationY = y - ICON_HEIGHT;
    iconLines.translationX = iconBackground.translationX;
    iconLines.translationY = iconBackground.translationY;
    iconBackground.fill = datum.fill;
    iconBackground.fillOpacity = datum.fillOpacity ?? 1;
    iconBackground.stroke = datum.stroke;
    iconBackground.strokeOpacity = datum.strokeOpacity ?? 1;
    iconBackground.strokeWidth = datum.strokeWidth ?? 1;
    iconLines.fill = datum.stroke;
    if (active) {
      iconBackground.fillShadow.color = datum.fill ?? "rgba(0, 0, 0, 0.22)";
    } else {
      iconBackground.fillShadow.color = "rgba(0, 0, 0, 0.22)";
    }
  }
  updateAnchor(datum, bbox, context) {
    const padding2 = datum.getPadding().top;
    const isPositionTop = datum.position === "top";
    const direction = isPositionTop ? 1 : -1;
    return {
      x: bbox.x + context.seriesRect.x + datum.width / 2,
      y: bbox.y + context.seriesRect.y + direction * (bbox.height + padding2),
      position: isPositionTop ? "below" : "above"
    };
  }
  getLabelCoords(datum, bbox) {
    const isPositionTop = datum.position === "top";
    const padding2 = datum.getPadding().top + calcLineHeight(datum.fontSize, ANNOTATION_TEXT_LINE_HEIGHT) / 2;
    return { x: bbox.x, y: bbox.y + (isPositionTop ? padding2 / 2 : 0) };
  }
  getTextBaseline(datum) {
    return datum.position === "top" ? "middle" : datum.position;
  }
  getHandleCoords(_datum, coords, _bbox) {
    return {
      x: coords.x,
      y: coords.y + DivariantHandle.HANDLE_SIZE / 2 + 4
    };
  }
  getHandleStyles(datum) {
    return {
      fill: datum.handle.fill,
      stroke: datum.handle.stroke ?? datum.fill,
      strokeOpacity: datum.handle.strokeOpacity,
      strokeWidth: datum.handle.strokeWidth
    };
  }
  toggleHovered(hovered, active, readOnly) {
    super.toggleHovered(hovered, active, readOnly);
    const visible = hovered || active && !readOnly;
    this.label.visible = visible;
    this.shape.visible = visible;
    this.zIndex = visible ? 13 /* CHART_ANNOTATION_FOCUSED */ : 12 /* CHART_ANNOTATION */;
  }
  toggleActive(active) {
    super.toggleActive(active);
    this.label.visible = active;
    this.shape.visible = active;
    this.active = active;
  }
  containsPoint(x, y) {
    if (this.shape.visible && this.shape.containsPoint(x, y))
      return true;
    if (this.iconBackground.containsPoint(x, y))
      return true;
    return super.containsPoint(x, y);
  }
};

// packages/ag-charts-enterprise/src/features/annotations/note/noteState.ts
var NoteStateMachine = class extends TextualPointStateMachine {
  createDatum() {
    return new NoteProperties();
  }
};

// packages/ag-charts-enterprise/src/features/annotations/note/noteConfig.ts
var noteConfig = {
  type: "note" /* Note */,
  datum: NoteProperties,
  scene: NoteScene,
  isDatum: NoteProperties.is,
  translate: (node, datum, transition, context) => {
    if (NoteProperties.is(datum) && NoteScene.is(node))
      node.translate(datum, transition, context);
  },
  copy: (node, datum, copiedDatum, context) => {
    if (NoteProperties.is(datum) && NoteProperties.is(copiedDatum) && NoteScene.is(node)) {
      return node.copy(datum, copiedDatum, context);
    }
  },
  update: (node, datum, context) => {
    if (NoteProperties.is(datum) && NoteScene.is(node)) {
      node.update(datum, context);
    }
  },
  createState: (ctx, { createDatum }) => new NoteStateMachine({
    ...ctx,
    create: createDatum("note" /* Note */)
  }),
  dragState: (ctx) => new DragStateMachine(ctx)
};

// packages/ag-charts-enterprise/src/features/annotations/parallel-channel/parallelChannelScene.ts
var ParallelChannelScene = class extends ChannelScene {
  constructor() {
    super();
    this.type = "parallel-channel";
    this.handles = {
      topLeft: new DivariantHandle(),
      topMiddle: new UnivariantHandle(),
      topRight: new DivariantHandle(),
      bottomLeft: new DivariantHandle(),
      bottomMiddle: new UnivariantHandle(),
      bottomRight: new DivariantHandle()
    };
    this.middleLine = new CollidableLine();
    this.append([this.background, this.topLine, this.middleLine, this.bottomLine, ...Object.values(this.handles)]);
  }
  static is(value) {
    return AnnotationScene.isCheck(value, "parallel-channel");
  }
  dragHandle(datum, target, context, snapping) {
    const { activeHandle, handles } = this;
    if (activeHandle == null)
      return;
    const { offset } = handles[activeHandle].drag(target);
    handles[activeHandle].toggleDragging(true);
    if (activeHandle === "topMiddle" || activeHandle === "bottomMiddle") {
      offset.x = 0;
    }
    let translateVectors = [];
    let allowSnapping = snapping;
    switch (activeHandle) {
      case "topLeft":
      case "bottomLeft":
        translateVectors = ["topLeft", "bottomLeft"];
        break;
      case "topMiddle":
        translateVectors = ["topLeft", "topRight"];
        offset.y -= UnivariantHandle.HANDLE_SIZE / 2;
        allowSnapping = false;
        break;
      case "topRight":
      case "bottomRight":
        translateVectors = ["topRight", "bottomRight"];
        break;
      case "bottomMiddle":
        translateVectors = ["bottomLeft", "bottomRight"];
        offset.y -= UnivariantHandle.HANDLE_SIZE / 2;
        allowSnapping = false;
        break;
    }
    const top = convertLine(datum, context);
    const bottom = convertLine(datum.bottom, context);
    if (!top || !bottom)
      return;
    const vectors = {
      topLeft: vector4_exports.start(top),
      topRight: vector4_exports.end(top),
      bottomLeft: vector4_exports.start(bottom),
      bottomRight: vector4_exports.end(bottom)
    };
    const snap = {
      vectors: {
        topLeft: vectors.topRight,
        bottomLeft: vectors.bottomRight,
        topRight: vectors.topLeft,
        bottomRight: vectors.bottomLeft
      },
      angle: datum.snapToAngle
    };
    const points = translate(vectors, offset, context, {
      overflowContinuous: this.overflowContinuous,
      translateVectors,
      snap: allowSnapping ? snap : void 0
    });
    datum.start.x = points.topLeft.x;
    datum.start.y = points.topLeft.y;
    datum.end.x = points.topRight.x;
    datum.end.y = points.topRight.y;
    datum.height = points.topLeft.y - points.bottomLeft.y;
  }
  getTranslatePointsVectors(start2, end3) {
    const { bottomLeft, topLeft } = this.handles;
    const height2 = bottomLeft.getBBox().y - topLeft.getBBox().y;
    const bottomStart = vector_exports.add(start2, vector_exports.from(0, height2));
    const bottomEnd = vector_exports.add(end3, vector_exports.from(0, height2));
    return { start: start2, end: end3, bottomStart, bottomEnd };
  }
  containsPoint(x, y) {
    return super.containsPoint(x, y) || this.middleLine.visible && this.middleLine.strokeWidth > 0 && this.middleLine.containsPoint(x, y);
  }
  getNodeAtCoords(x, y) {
    if (this.middleLine.visible && this.middleLine.strokeWidth > 0 && this.middleLine.containsPoint(x, y))
      return "line";
    return super.getNodeAtCoords(x, y);
  }
  updateLines(datum, top, bottom, context, naturalTop, naturalBottom) {
    const { topLine, middleLine, bottomLine } = this;
    const { lineDashOffset, stroke: stroke3, strokeOpacity, strokeWidth } = datum;
    const lineDash = datum.getLineDash();
    const lineStyles = {
      lineCap: datum.getLineCap(),
      lineDash,
      lineDashOffset,
      stroke: stroke3,
      strokeOpacity,
      strokeWidth
    };
    topLine.setProperties({ ...top, ...lineStyles });
    bottomLine.setProperties({ ...bottom, ...lineStyles });
    const middlePoints = this.extendLine(
      {
        x1: naturalTop.x1,
        y1: naturalBottom.y1 + (naturalTop.y1 - naturalBottom.y1) / 2,
        x2: naturalTop.x2,
        y2: naturalBottom.y2 + (naturalTop.y2 - naturalBottom.y2) / 2
      },
      datum,
      context
    );
    middleLine.setProperties({
      ...middlePoints,
      lineDash: datum.middle.lineDash ?? lineDash,
      lineDashOffset: datum.middle.lineDashOffset ?? lineDashOffset,
      stroke: datum.middle.stroke ?? stroke3,
      strokeOpacity: datum.middle.strokeOpacity ?? strokeOpacity,
      strokeWidth: datum.middle.strokeWidth ?? strokeWidth,
      visible: datum.middle.visible ?? true
    });
  }
  updateHandles(datum, top, bottom) {
    const {
      handles: { topLeft, topMiddle, topRight, bottomLeft, bottomMiddle, bottomRight }
    } = this;
    const handleStyles = {
      fill: datum.handle.fill,
      stroke: datum.handle.stroke ?? datum.stroke,
      strokeOpacity: datum.handle.strokeOpacity ?? datum.strokeOpacity,
      strokeWidth: datum.handle.strokeWidth ?? datum.strokeWidth
    };
    topLeft.update({ ...handleStyles, ...vector4_exports.start(top) });
    topRight.update({ ...handleStyles, ...vector4_exports.end(top) });
    bottomLeft.update({ ...handleStyles, ...vector4_exports.start(bottom) });
    bottomRight.update({ ...handleStyles, ...vector4_exports.end(bottom) });
    topMiddle.update({
      ...handleStyles,
      ...vector_exports.sub(vector4_exports.center(top), vector_exports.from(topMiddle.handle.width / 2, topMiddle.handle.height / 2))
    });
    bottomMiddle.update({
      ...handleStyles,
      ...vector_exports.sub(vector4_exports.center(bottom), vector_exports.from(bottomMiddle.handle.width / 2, bottomMiddle.handle.height / 2))
    });
  }
  updateText(datum, top, bottom) {
    this.text = this.updateNode(CollidableText, this.text, !!datum.text.label);
    updateChannelText(true, top, bottom, datum.text, datum.strokeWidth, this.text, datum.text.label);
  }
  getBackgroundPoints(datum, top, bottom, bounds) {
    const isFlippedX = top.x1 > top.x2;
    const isFlippedY = top.y1 > top.y2;
    const outOfBoundsStart = top.x1 !== bottom.x1 && top.y1 !== bottom.y1;
    const outOfBoundsEnd = top.x2 !== bottom.x2 && top.y2 !== bottom.y2;
    const points = vector_exports.from(top);
    if (datum.extendEnd && outOfBoundsEnd) {
      points.push(vector_exports.from(isFlippedX ? bounds.x1 : bounds.x2, isFlippedY ? bounds.y1 : bounds.y2));
    }
    points.push(...vector_exports.from(bottom).reverse());
    if (datum.extendStart && outOfBoundsStart) {
      points.push(vector_exports.from(isFlippedX ? bounds.x2 : bounds.x1, isFlippedY ? bounds.y2 : bounds.y1));
    }
    return points;
  }
};

// packages/ag-charts-enterprise/src/features/annotations/parallel-channel/parallelChannelState.ts
var ParallelChannelStateMachine = class extends StateMachine {
  constructor(ctx) {
    const actionCreate = ({ point }) => {
      const datum = new ParallelChannelProperties();
      datum.set({ start: point, end: point, height: 0 });
      ctx.create(datum);
    };
    const actionFirstRender = () => {
      const { node } = this;
      node?.toggleActive(true);
      node?.toggleHandles({
        topLeft: true,
        topMiddle: false,
        topRight: false,
        bottomLeft: false,
        bottomMiddle: false,
        bottomRight: false
      });
    };
    const actionEndUpdate = ({ offset, context }) => {
      const { datum, snapping } = this;
      if (!datum)
        return;
      datum.set({ end: snapPoint(offset, context, snapping, datum.start, datum.snapToAngle) });
      ctx.update();
    };
    const actionEndFinish = () => {
      this.node?.toggleHandles({
        topRight: true
      });
      ctx.update();
    };
    const actionHeightUpdate = ({ point }) => {
      const { datum, node } = this;
      const endY = getGroupingValue(datum?.end.y);
      const startY = getGroupingValue(datum?.start.y);
      const { y: pointY } = point;
      if (datum == null || !isNumber(startY) || !isNumber(endY) || !isNumber(pointY))
        return;
      const height2 = endY - (pointY ?? 0);
      const bottomStartY = startY - height2;
      node?.toggleHandles({ bottomLeft: true, bottomRight: true });
      if (!ctx.validatePoint({ x: datum.start.x, y: bottomStartY }, { overflowContinuous: true }) || !ctx.validatePoint({ x: datum.end.x, y: point.y }, { overflowContinuous: true })) {
        return;
      }
      datum.set({ height: height2 });
      ctx.update();
    };
    const actionHeightFinish = ({ point }) => {
      const { datum, node } = this;
      const endY = getGroupingValue(datum?.end.y);
      const startY = getGroupingValue(datum?.start.y);
      const { y: pointY } = point;
      if (datum == null || !isNumber(startY) || !isNumber(endY) || !isNumber(pointY))
        return;
      const height2 = endY - (pointY ?? 0);
      const bottomStartY = startY - height2;
      node?.toggleHandles(true);
      if (!ctx.validatePoint({ x: datum.start.x, y: bottomStartY }, { overflowContinuous: true }) || !ctx.validatePoint({ x: datum.end.x, y: point.y }, { overflowContinuous: true })) {
        return;
      }
      datum.set({ height: height2 });
      ctx.recordAction(`Create ${"parallel-channel" /* ParallelChannel */} annotation`);
      ctx.showAnnotationOptions();
      ctx.update();
    };
    const actionCancel = () => ctx.delete();
    super("start", {
      start: {
        click: {
          target: "waiting-first-render",
          action: actionCreate
        },
        drag: {
          target: "waiting-first-render",
          action: actionCreate
        },
        reset: StateMachine.parent
      },
      "waiting-first-render": {
        render: {
          target: "end",
          action: actionFirstRender
        }
      },
      end: {
        hover: actionEndUpdate,
        drag: actionEndUpdate,
        click: {
          target: "height",
          action: actionEndFinish
        },
        dragEnd: {
          target: "height",
          action: actionEndFinish
        },
        reset: {
          target: StateMachine.parent,
          action: actionCancel
        },
        cancel: {
          target: StateMachine.parent,
          action: actionCancel
        }
      },
      height: {
        hover: actionHeightUpdate,
        click: {
          target: StateMachine.parent,
          action: actionHeightFinish
        },
        drag: {
          target: StateMachine.parent,
          action: actionHeightFinish
        },
        reset: {
          target: StateMachine.parent,
          action: actionCancel
        },
        cancel: {
          target: StateMachine.parent,
          action: actionCancel
        }
      }
    });
    this.debug = debugLogger_exports.create(true, "annotations");
    this.snapping = false;
  }
};
__decorateClass([
  StateMachineProperty()
], ParallelChannelStateMachine.prototype, "datum", 2);
__decorateClass([
  StateMachineProperty()
], ParallelChannelStateMachine.prototype, "node", 2);
__decorateClass([
  StateMachineProperty()
], ParallelChannelStateMachine.prototype, "snapping", 2);

// packages/ag-charts-enterprise/src/features/annotations/parallel-channel/parallelChannelConfig.ts
var parallelChannelConfig = {
  type: "parallel-channel" /* ParallelChannel */,
  datum: ParallelChannelProperties,
  scene: ParallelChannelScene,
  isDatum: ParallelChannelProperties.is,
  translate: (node, datum, transition, context) => {
    if (ParallelChannelProperties.is(datum) && ParallelChannelScene.is(node)) {
      node.translate(datum, transition, context);
    }
  },
  copy: (node, datum, copiedDatum, context) => {
    if (ParallelChannelProperties.is(datum) && ParallelChannelProperties.is(copiedDatum) && ParallelChannelScene.is(node)) {
      return node.copy(datum, copiedDatum, context);
    }
  },
  update: (node, datum, context) => {
    if (ParallelChannelProperties.is(datum) && ParallelChannelScene.is(node)) {
      node.update(datum, context);
    }
  },
  createState: (ctx, { createDatum }) => new ParallelChannelStateMachine({
    ...ctx,
    create: createDatum("parallel-channel" /* ParallelChannel */)
  }),
  dragState: (ctx) => new DragStateMachine(ctx)
};

// packages/ag-charts-enterprise/src/features/annotations/text/textScene.ts
var TextScene = class extends TextualPointScene {
  constructor() {
    super();
    this.type = "text" /* Text */;
    this.append([this.label, this.handle]);
  }
  static is(value) {
    return AnnotationScene.isCheck(value, "text" /* Text */);
  }
  getHandleCoords(_datum, point) {
    const halfSize = DivariantHandle.HANDLE_SIZE / 2;
    return {
      x: point.x + halfSize,
      y: point.y + 2 + halfSize
    };
  }
};

// packages/ag-charts-enterprise/src/features/annotations/text/textState.ts
var TextStateMachine = class extends TextualPointStateMachine {
  createDatum() {
    return new TextProperties();
  }
};

// packages/ag-charts-enterprise/src/features/annotations/text/textConfig.ts
var textConfig = {
  type: "text" /* Text */,
  datum: TextProperties,
  scene: TextScene,
  isDatum: TextProperties.is,
  translate: (node, datum, transition, context) => {
    if (TextProperties.is(datum) && TextScene.is(node))
      node.translate(datum, transition, context);
  },
  copy: (node, datum, copiedDatum, context) => {
    if (TextProperties.is(datum) && TextProperties.is(copiedDatum) && TextScene.is(node)) {
      return node.copy(datum, copiedDatum, context);
    }
  },
  update: (node, datum, context) => {
    if (TextProperties.is(datum) && TextScene.is(node)) {
      node.update(datum, context);
    }
  },
  createState: (ctx, { createDatum }) => new TextStateMachine({
    ...ctx,
    create: createDatum("text" /* Text */)
  }),
  dragState: (ctx) => new DragStateMachine(ctx)
};

// packages/ag-charts-enterprise/src/features/annotations/annotationsConfig.ts
var annotationConfigs = {
  // Lines
  [lineConfig.type]: lineConfig,
  [horizontalLineConfig.type]: horizontalLineConfig,
  [verticalLineConfig.type]: verticalLineConfig,
  // Channels
  [parallelChannelConfig.type]: parallelChannelConfig,
  [disjointChannelConfig.type]: disjointChannelConfig,
  // Fibonaccis
  [fibonacciRetracementConfig.type]: fibonacciRetracementConfig,
  [fibonacciRetracementTrendBasedConfig.type]: fibonacciRetracementTrendBasedConfig,
  // Texts
  [calloutConfig.type]: calloutConfig,
  [commentConfig.type]: commentConfig,
  [noteConfig.type]: noteConfig,
  [textConfig.type]: textConfig,
  // Shapes
  [arrowConfig.type]: arrowConfig,
  [arrowUpConfig.type]: arrowUpConfig,
  [arrowDownConfig.type]: arrowDownConfig,
  // Measurers
  [dateRangeConfig.type]: dateRangeConfig,
  [priceRangeConfig.type]: priceRangeConfig,
  [datePriceRangeConfig.type]: datePriceRangeConfig,
  [quickDatePriceRangeConfig.type]: quickDatePriceRangeConfig
};
function getTypedDatum(datum) {
  for (const { isDatum } of Object.values(annotationConfigs)) {
    if (isDatum(datum)) {
      return datum;
    }
  }
}

// packages/ag-charts-enterprise/src/features/annotations/annotationsStateMachine.ts
var AnnotationsStateMachine = class extends ParallelStateMachine {
  constructor(ctx) {
    super(
      new SnappingStateMachine((snapping) => {
        this.snapping = snapping;
      }),
      new UpdateMachine(() => {
        this.node = this.active == null ? void 0 : ctx.node(this.active);
      }),
      new AnnotationsMainStateMachine(ctx, (index) => {
        this.active = index;
        this.datum = this.active == null ? void 0 : ctx.datum(this.active);
        this.node = this.active == null ? void 0 : ctx.node(this.active);
      })
    );
    this.snapping = false;
  }
  // TODO: remove this leak
  getActive() {
    return this.active;
  }
  // TODO: remove this leak
  isActive(index) {
    return index === this.active;
  }
};
__decorateClass([
  StateMachineProperty()
], AnnotationsStateMachine.prototype, "snapping", 2);
__decorateClass([
  StateMachineProperty()
], AnnotationsStateMachine.prototype, "datum", 2);
__decorateClass([
  StateMachineProperty()
], AnnotationsStateMachine.prototype, "node", 2);
var SnappingStateMachine = class extends StateMachine {
  constructor(setSnapping) {
    super("idle" /* Idle */, {
      ["idle" /* Idle */]: {
        hover: ({ shiftKey }) => setSnapping(shiftKey),
        keyDown: ({ shiftKey }) => setSnapping(shiftKey),
        keyUp: ({ shiftKey }) => setSnapping(shiftKey),
        click: ({ shiftKey }) => setSnapping(shiftKey),
        drag: ({ shiftKey }) => setSnapping(shiftKey)
      },
      ["dragging" /* Dragging */]: {},
      ["translating" /* Translating */]: {},
      ["text-input" /* TextInput */]: {}
    });
  }
};
var UpdateMachine = class extends StateMachine {
  constructor(update) {
    super("idle" /* Idle */, {
      ["idle" /* Idle */]: {
        onEnter: update,
        render: update
      },
      ["dragging" /* Dragging */]: {
        onEnter: update,
        render: update
      },
      ["translating" /* Translating */]: {
        onEnter: update,
        render: update
      },
      ["text-input" /* TextInput */]: {
        render: update
      }
    });
  }
};
var AnnotationsMainStateMachine = class extends StateMachine {
  constructor(ctx, setActive) {
    const createDatum = (type) => (datum) => {
      ctx.create(type, datum);
      this.active = ctx.selectLast();
    };
    const deleteDatum = () => {
      if (this.active != null)
        ctx.delete(this.active);
      this.active = void 0;
      ctx.select();
    };
    const stateMachineHelpers = {
      createDatum
    };
    const createStateMachineContext = {
      ...ctx,
      delete: deleteDatum,
      showTextInput: () => {
        if (this.active != null)
          ctx.showTextInput(this.active);
      },
      deselect: () => {
        const prevActive = this.active;
        this.active = void 0;
        this.hovered = void 0;
        ctx.select(this.active, prevActive);
      },
      showAnnotationOptions: () => {
        if (this.active != null)
          ctx.showAnnotationOptions(this.active);
      }
    };
    const createStateMachines = Object.fromEntries(
      Object.entries(annotationConfigs).map(([type, config]) => [
        type,
        config.createState(createStateMachineContext, stateMachineHelpers)
      ])
    );
    const dragStateMachines = Object.fromEntries(
      Object.entries(annotationConfigs).map(([type, config]) => [
        type,
        config.dragState(ctx, stateMachineHelpers)
      ])
    );
    const actionColor = ({
      colorPickerType,
      colorOpacity,
      color: color2,
      opacity,
      isMultiColor
    }) => {
      if (!this.datum)
        return;
      if (colorPickerType === "text-color") {
        ctx.updateTextInputColor(color2);
      }
      setColor(this.datum, colorPickerType, colorOpacity, color2, opacity, isMultiColor);
      ctx.update();
    };
    const actionFontSize = (fontSize) => {
      const { datum, node } = this;
      if (!datum || !node)
        return;
      if (isTextType(datum)) {
        datum.fontSize = fontSize;
        ctx.updateTextInputFontSize(fontSize);
      } else if (hasLineText(datum)) {
        datum.text.fontSize = fontSize;
      }
      ctx.update();
    };
    const actionLineStyle = (lineStyle) => {
      const { datum, node } = this;
      if (!datum || !node || !hasLineStyle(datum))
        return;
      setLineStyle(datum, lineStyle);
      ctx.update();
    };
    const actionUpdateTextInputBBox = (bbox) => {
      const { node } = this;
      if (!node || !("setTextInputBBox" in node))
        return;
      node.setTextInputBBox(bbox);
      ctx.update();
    };
    const actionSaveText = ({ textInputValue, bbox }) => {
      const { datum } = this;
      if (bbox != null && textInputValue != null && textInputValue.length > 0) {
        if (!isTextType(datum)) {
          return;
        }
        const wrappedText = maybeWrapText(datum, textInputValue, bbox.width);
        datum.set({ text: wrappedText });
        ctx.update();
        ctx.recordAction(`Change ${datum.type} annotation text`);
      } else {
        ctx.delete(this.active);
        ctx.recordAction(`Delete ${datum?.type} annotation`);
      }
    };
    const actionCancel = () => {
      ctx.updateTextInputBBox(void 0);
    };
    const guardActive = () => this.active != null;
    const guardCopied = () => this.copied != null;
    const guardActiveHasLineText = () => {
      const { active, datum } = this;
      if (active == null)
        return false;
      if (!datum)
        return false;
      return hasLineText(datum) && datum.isWriteable();
    };
    const guardActiveNotEphemeral = () => this.active != null && !isEphemeralType(this.datum);
    const guardHovered = () => this.hovered != null;
    super("idle" /* Idle */, {
      ["idle" /* Idle */]: {
        onEnter: () => {
          ctx.select(this.active, this.active);
          if (this.hoverCoords) {
            this.hovered = ctx.hoverAtCoords(this.hoverCoords, this.active, this.hovered);
          }
        },
        hover: ({ offset }) => {
          this.hovered = ctx.hoverAtCoords(offset, this.active, this.hovered);
          this.hoverCoords = offset;
        },
        translate: {
          guard: guardActive,
          target: "translating" /* Translating */,
          action: ({ translation }) => {
            ctx.startInteracting();
            ctx.translate(this.active, translation);
            ctx.update();
          }
        },
        copy: {
          guard: guardActiveNotEphemeral,
          action: () => {
            this.copied = ctx.copy(this.active);
          }
        },
        cut: {
          guard: guardActiveNotEphemeral,
          action: () => {
            this.copied = ctx.copy(this.active);
            deleteDatum();
          }
        },
        paste: {
          guard: guardCopied,
          action: () => {
            ctx.paste(this.copied);
          }
        },
        selectLast: () => {
          const previousActive = this.active;
          this.active = ctx.selectLast();
          ctx.select(this.active, previousActive);
        },
        click: [
          {
            guard: () => {
              const { active, hovered, datum } = this;
              if (active == null || hovered !== active)
                return false;
              if (!datum)
                return false;
              return isTextType(datum) && datum.isWriteable();
            },
            target: "text-input" /* TextInput */
          },
          {
            action: () => {
              const prevActive = this.active;
              this.active = this.hovered;
              ctx.select(this.active, prevActive);
            }
          }
        ],
        dblclick: {
          guard: guardActiveHasLineText,
          action: ({ offset }) => {
            const nodeAtCoords = ctx.getNodeAtCoords(offset, this.active) === "text" ? "text" : "line";
            ctx.showAnnotationSettings(this.active, void 0, nodeAtCoords);
          }
        },
        dragStart: [
          {
            guard: guardHovered,
            target: "dragging" /* Dragging */,
            action: () => {
              const prevActive = this.active;
              this.active = this.hovered;
              ctx.select(this.active, prevActive);
              ctx.startInteracting();
            }
          },
          {
            action: () => {
              const prevActive = this.active;
              this.active = this.hovered;
              ctx.select(this.active, prevActive);
            }
          }
        ],
        color: {
          guard: guardActive,
          action: actionColor
        },
        fontSize: {
          guard: guardActive,
          action: actionFontSize
        },
        lineProps: {
          guard: guardActive,
          action: (props) => {
            const datum = getTypedDatum(this.datum);
            datum?.set(props);
            ctx.update();
            ctx.recordAction(
              `Change ${datum?.type} ${Object.entries(props).map(([key, value]) => `${key} to ${value}`).join(", ")}`
            );
          }
        },
        lineStyle: {
          guard: guardActive,
          action: actionLineStyle
        },
        lineText: {
          guard: guardActive,
          action: (props) => {
            const datum = getTypedDatum(this.datum);
            if (!hasLineText(datum))
              return;
            if (isChannelType(datum) && props.position === "center") {
              props.position = "inside";
            }
            datum.text.set(props);
            ctx.update();
          }
        },
        updateTextInputBBox: {
          guard: guardActive,
          action: actionUpdateTextInputBBox
        },
        toolbarPressSettings: {
          guard: guardActiveHasLineText,
          action: (sourceEvent) => {
            ctx.showAnnotationSettings(this.active, sourceEvent);
          }
        },
        reset: () => {
          if (this.active != null) {
            this.node?.toggleActive(false);
          }
          this.hovered = void 0;
          this.active = void 0;
          ctx.select(this.active, this.active);
          ctx.resetToIdle();
        },
        delete: () => {
          if (this.active == null)
            return;
          ctx.delete(this.active);
          if (isEphemeralType(this.datum))
            return;
          ctx.recordAction(`Delete ${this.datum?.type} annotation`);
        },
        deleteAll: () => {
          ctx.deleteAll();
        },
        ...createStateMachines
      },
      ["dragging" /* Dragging */]: {
        onEnter: (_, data) => {
          if (this.active == null)
            return;
          const type = ctx.getAnnotationType(this.active);
          if (!type)
            return;
          this.transitionRoot(type);
          this.transitionRoot("dragStart", data);
        },
        ...dragStateMachines
      },
      ["translating" /* Translating */]: {
        onEnter: () => {
        },
        translate: {
          guard: guardActive,
          target: "translating" /* Translating */,
          action: ({ translation }) => {
            ctx.startInteracting();
            ctx.translate(this.active, translation);
            ctx.update();
          }
        },
        translateEnd: {
          guard: guardActive,
          target: "idle" /* Idle */
        },
        onExit: () => {
          ctx.stopInteracting();
          ctx.update();
          ctx.recordAction("Translate annotation");
        }
      },
      ["text-input" /* TextInput */]: {
        onEnter: () => {
          if (this.active == null)
            return;
          const datum = getTypedDatum(this.datum);
          if (!datum || !("getTextInputCoords" in datum))
            return;
          ctx.startInteracting();
          ctx.showTextInput(this.active);
          datum.visible = false;
          ctx.update();
        },
        updateTextInputBBox: {
          guard: guardActive,
          action: actionUpdateTextInputBBox
        },
        resize: {
          target: "idle" /* Idle */,
          action: actionSaveText
        },
        click: {
          target: "idle" /* Idle */,
          action: actionSaveText
        },
        drag: {
          target: "idle" /* Idle */,
          action: actionSaveText
        },
        textInput: [
          {
            guard: guardCancelAndExit,
            target: "idle" /* Idle */,
            action: actionCancel
          },
          {
            guard: guardSaveAndExit,
            target: "idle" /* Idle */,
            action: actionSaveText
          }
        ],
        color: {
          guard: guardActive,
          action: actionColor
        },
        fontSize: {
          guard: guardActive,
          action: actionFontSize
        },
        cancel: {
          target: "idle" /* Idle */,
          action: actionCancel
        },
        onExit: () => {
          ctx.stopInteracting();
          ctx.hideTextInput();
          const wasActive = this.active;
          this.active = this.hovered = void 0;
          ctx.select(this.active, wasActive);
          if (wasActive == null)
            return;
          const datum = ctx.datum(wasActive);
          const node = ctx.node(wasActive);
          if (!datum || !node)
            return;
          datum.visible = true;
        }
      }
    });
    this.setActive = setActive;
    this.debug = debugLogger_exports.create(true, "annotations");
    this.snapping = false;
  }
};
__decorateClass([
  ActionOnSet({
    changeValue(newValue) {
      this.setActive(newValue);
    }
  }),
  StateMachineProperty()
], AnnotationsMainStateMachine.prototype, "active", 2);
__decorateClass([
  StateMachineProperty()
], AnnotationsMainStateMachine.prototype, "hovered", 2);
__decorateClass([
  StateMachineProperty()
], AnnotationsMainStateMachine.prototype, "hoverCoords", 2);
__decorateClass([
  StateMachineProperty()
], AnnotationsMainStateMachine.prototype, "copied", 2);
__decorateClass([
  StateMachineProperty()
], AnnotationsMainStateMachine.prototype, "snapping", 2);
__decorateClass([
  StateMachineProperty()
], AnnotationsMainStateMachine.prototype, "datum", 2);
__decorateClass([
  StateMachineProperty()
], AnnotationsMainStateMachine.prototype, "node", 2);

// packages/ag-charts-enterprise/src/features/annotations/annotationsToolbar.ts
var { LayoutElement: LayoutElement2, Menu: Menu3 } = module_support_exports;
var AnnotationsToolbarButtonProperties = class extends ToolbarButtonProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], AnnotationsToolbarButtonProperties.prototype, "value", 2);
var AnnotationsToolbar = class extends BaseProperties {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.enabled = true;
    this.padding = 20;
    this.buttons = new PropertiesArray(AnnotationsToolbarButtonProperties);
    this.events = new EventEmitter();
    this.annotationMenu = new Menu3(this.ctx, "annotations");
    this.cleanup = new CleanupRegistry();
    this.toolbar = ctx.sharedToolbar.getSharedToolbar("annotations");
    const onKeyDown = this.onKeyDown.bind(this);
    this.toolbar.addListener("keydown", onKeyDown);
    this.cleanup.register(
      this.toolbar.addToolbarListener("button-pressed", this.onToolbarButtonPress.bind(this)),
      ctx.layoutManager.registerElement(LayoutElement2.ToolbarLeft, this.onLayoutStart.bind(this)),
      () => {
        this.toolbar.removeListener("keydown", onKeyDown);
        this.toolbar.destroy();
      }
    );
  }
  destroy() {
    this.cleanup.flush();
  }
  toggleClearButtonEnabled(enabled) {
    const index = this.buttons.findIndex((button) => button.value === "clear");
    this.toolbar.toggleButtonEnabledByIndex(index, enabled);
  }
  resetButtonIcons() {
    for (const [index, button] of this.buttons.entries()) {
      switch (button.value) {
        case "line-menu":
          this.updateButtonByIndex(index, { icon: "trend-line-drawing", value: "line-menu" });
          break;
        case "fibonacci-menu":
          this.updateButtonByIndex(index, { icon: "fibonacci-retracement-drawing", value: "fibonacci-menu" });
          break;
        case "text-menu":
          this.updateButtonByIndex(index, { icon: "text-annotation", value: "text-menu" });
          break;
        case "shape-menu":
          this.updateButtonByIndex(index, { icon: "arrow-drawing", value: "shape-menu" });
          break;
        case "measurer-menu":
          this.updateButtonByIndex(index, { icon: "measurer-drawing", value: "measurer-menu" });
          break;
      }
    }
  }
  hideOverlays() {
    this.annotationMenu.hide();
  }
  clearActiveButton() {
    this.toolbar.clearActiveButton();
  }
  onLayoutStart(ctx) {
    if (!this.enabled)
      return;
    this.toolbar.updateButtons(this.buttons);
    this.toolbar.layout(ctx.layoutBox, this.padding);
  }
  refreshButtonsEnabled(enabled) {
    for (const [index, button] of this.buttons.entries()) {
      if (!button)
        continue;
      this.toolbar.toggleButtonEnabledByIndex(index, enabled);
    }
  }
  onToolbarButtonPress({
    event,
    button,
    buttonBounds,
    buttonWidget
  }) {
    const axisScale = this.ctx.axisManager.getAxisContext("y" /* Y */)[0].scale;
    switch (button.value) {
      case "clear":
        this.events.emit("pressed-clear", null);
        break;
      case "line-menu":
        this.onToolbarButtonPressShowMenu(
          event,
          buttonBounds,
          buttonWidget,
          button.value,
          "toolbarAnnotationsLineAnnotations",
          LINE_ANNOTATION_ITEMS.filter((item) => item.visible ? item.visible(axisScale) : true)
        );
        break;
      case "fibonacci-menu":
        this.onToolbarButtonPressShowMenu(
          event,
          buttonBounds,
          buttonWidget,
          button.value,
          "toolbarAnnotationsFibonacciAnnotations",
          FIBONACCI_ANNOTATION_ITEMS
        );
        break;
      case "text-menu":
        this.onToolbarButtonPressShowMenu(
          event,
          buttonBounds,
          buttonWidget,
          button.value,
          "toolbarAnnotationsTextAnnotations",
          TEXT_ANNOTATION_ITEMS
        );
        break;
      case "shape-menu":
        this.onToolbarButtonPressShowMenu(
          event,
          buttonBounds,
          buttonWidget,
          button.value,
          "toolbarAnnotationsShapeAnnotations",
          SHAPE_ANNOTATION_ITEMS
        );
        break;
      case "measurer-menu":
        this.onToolbarButtonPressShowMenu(
          event,
          buttonBounds,
          buttonWidget,
          button.value,
          "toolbarAnnotationsMeasurerAnnotations",
          MEASURER_ANNOTATION_ITEMS
        );
        break;
    }
  }
  onToolbarButtonPressShowMenu(event, buttonBounds, controller, menu, ariaLabel, items) {
    this.events.emit("pressed-show-menu", null);
    const index = this.buttons.findIndex((button) => button.value === menu);
    this.toolbar.toggleActiveButtonByIndex(index);
    this.annotationMenu.setAnchor({ x: buttonBounds.x + buttonBounds.width + 6, y: buttonBounds.y });
    this.annotationMenu.show(controller, {
      items,
      ariaLabel: this.ctx.localeManager.t(ariaLabel),
      class: "ag-charts-annotations__toolbar-menu",
      sourceEvent: event.sourceEvent,
      onPress: this.onButtonPressMenuCreateAnnotation.bind(this, menu)
    });
  }
  onButtonPressMenuCreateAnnotation(menu, item) {
    const index = this.buttons.findIndex((button) => button.value === menu);
    this.updateButtonByIndex(index, { icon: item.icon });
    this.events.emit("pressed-create-annotation", { annotation: item.value });
    this.annotationMenu.hide();
  }
  onKeyDown({ sourceEvent }) {
    if (sourceEvent.key === "Escape") {
      this.events.emit("cancel-create-annotation", null);
    }
  }
  updateButtonByIndex(index, change) {
    const button = this.buttons.at(index);
    if (!button)
      return;
    button.set({ ...button.toJson(), ...change, value: change.value ?? button.value });
    this.toolbar.updateButtonByIndex(index, { ...button.toJson() });
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty,
  ActionOnSet({
    changeValue(enabled) {
      this.toolbar?.setHidden(!enabled);
    }
  })
], AnnotationsToolbar.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AnnotationsToolbar.prototype, "padding", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AnnotationsToolbar.prototype, "buttons", 2);

// packages/ag-charts-enterprise/src/features/annotations/axisButton.ts
var { InteractionState: InteractionState2 } = module_support_exports;
var DEFAULT_ANNOTATION_AXIS_BUTTON_CLASS = `ag-charts-annotations__axis-button`;
var AxisButton = class extends AbstractModuleInstance {
  constructor(ctx, axisCtx, onButtonClick, seriesRect) {
    super();
    this.ctx = ctx;
    this.axisCtx = axisCtx;
    this.onButtonClick = onButtonClick;
    this.seriesRect = seriesRect;
    this.enabled = true;
    this.snap = false;
    this.padding = 0;
    this.button = this.setup();
    this.toggleVisibility(false);
    this.updateButtonElement();
    this.snap = Boolean(axisCtx.scale.bandwidth);
    ctx.domManager.addEventListener("focusin", ({ target }) => {
      const htmlTarget = target instanceof HTMLElement ? target : void 0;
      const isSeriesAreaChild = htmlTarget && ctx.domManager.contains(htmlTarget, "series-area");
      if (!isSeriesAreaChild && htmlTarget !== this.button.getElement())
        this.hide();
    });
    this.cleanup.register(
      ctx.widgets.seriesWidget.addListener("drag-move", (e) => this.onMouseDrag(e)),
      ctx.widgets.seriesWidget.addListener("mousemove", (e) => this.onMouseMove(e)),
      ctx.widgets.seriesWidget.addListener("mouseleave", () => this.onMouseLeave()),
      ctx.widgets.seriesDragInterpreter?.events.on("click", (e) => this.onClick(e)),
      ctx.eventsHub.on("series:focus-change", () => this.onKeyPress()),
      ctx.eventsHub.on("zoom:pan-start", () => this.hide()),
      ctx.eventsHub.on("zoom:change-complete", () => this.hide()),
      () => this.destroyElements(),
      () => this.button.destroy()
    );
  }
  update(seriesRect, padding2) {
    this.seriesRect = seriesRect;
    this.padding = padding2;
  }
  setup() {
    const button = new exports_exports.ButtonWidget();
    button.addClass(DEFAULT_ANNOTATION_AXIS_BUTTON_CLASS);
    button.setTabIndex(-1);
    button.setAriaLabel(this.ctx.localeManager.t("ariaLabelAddHorizontalLine"));
    this.ctx.widgets.seriesWidget.getElement().appendChild(button.getElement());
    return button;
  }
  destroyElements() {
    this.ctx.domManager.removeChild("canvas-overlay", DEFAULT_ANNOTATION_AXIS_BUTTON_CLASS);
  }
  onMouseMove(e) {
    if (this.ctx.interactionManager.isState(InteractionState2.Clickable))
      this.show(e);
  }
  onMouseDrag(e) {
    if (this.ctx.interactionManager.isState(InteractionState2.AnnotationsMoveable))
      this.show(e);
  }
  onMouseLeave() {
    if (this.ctx.interactionManager.isState(InteractionState2.Clickable))
      this.hide();
  }
  onClick(e) {
    if (this.ctx.interactionManager.isState(InteractionState2.Clickable) && e.device === "touch")
      this.show(e);
  }
  show(event) {
    const { sourceEvent, currentX: x, currentY: y } = event;
    if (!(this.enabled && this.ctx.widgets.seriesWidget.getElement().contains(sourceEvent.target))) {
      this.hide();
      return;
    }
    this.toggleVisibility(true);
    const buttonCoords = this.getButtonCoordinates({ x, y });
    this.coords = {
      x: buttonCoords.x + this.button.clientWidth / 2,
      y: buttonCoords.y + this.button.clientHeight / 2
    };
    this.updatePosition(buttonCoords);
  }
  hide() {
    this.toggleVisibility(false);
  }
  onKeyPress() {
    if (this.snap && this.ctx.interactionManager.isState(InteractionState2.Default))
      return;
    this.hide();
  }
  getButtonCoordinates({ x, y }) {
    const {
      axisCtx: { direction, position },
      seriesRect,
      snap,
      axisCtx,
      padding: padding2
    } = this;
    const { clientWidth: buttonWidth, clientHeight: buttonHeight } = this.button;
    const [minY, maxY] = [0, seriesRect.height];
    const [minX, maxX] = [0, seriesRect.width];
    if (snap) {
      x = convert(invert(x - seriesRect.x, axisCtx), axisCtx) + seriesRect.x;
      y = convert(invert(y - seriesRect.y, axisCtx), axisCtx) + seriesRect.y;
    }
    if (direction === "x" /* X */) {
      const crosshairLabelPadding = 5;
      const offset = buttonHeight - Math.max(0, padding2 - crosshairLabelPadding);
      x = x - buttonWidth / 2;
      y = position === "top" ? minY - buttonHeight + offset : maxY - offset;
    } else {
      const crosshairLabelPadding = 9;
      const offset = buttonWidth - Math.max(0, padding2 - crosshairLabelPadding);
      x = position === "left" ? minX - buttonWidth + offset : maxX - offset;
      y = y - buttonHeight / 2;
    }
    return { x, y };
  }
  toggleVisibility(visible) {
    const { button } = this;
    if (button == null)
      return;
    const isVisible = this.enabled && visible;
    this.toggleClass("-hidden", !isVisible);
  }
  toggleClass(name, include) {
    this.button.toggleClass(`${DEFAULT_ANNOTATION_AXIS_BUTTON_CLASS}-${name}`, include);
  }
  updatePosition({ x, y }) {
    this.button.getElement().style.transform = `translate(${Math.round(x)}px, ${Math.round(y)}px)`;
  }
  updateButtonElement() {
    const { button } = this;
    button.addListener("click", () => this.onButtonClick(this.coords));
    button.addListener("touchend", () => this.onButtonClick(this.coords));
    button.addListener("drag-start", () => {
    });
    button.setInnerHTML(
      `<span class="${getIconClassNames("zoom-in")} ${DEFAULT_ANNOTATION_AXIS_BUTTON_CLASS}-icon"></span>`
    );
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], AxisButton.prototype, "enabled", 2);

// packages/ag-charts-enterprise/src/components/dialog/dialog.ts
var { DraggablePopover: DraggablePopover2, NativeWidget: NativeWidget2 } = module_support_exports;
var _Dialog = class _Dialog extends DraggablePopover2 {
  constructor(ctx, id) {
    super(ctx, id);
    this.dragHandleDraggingClass = "ag-charts-dialog__drag-handle--dragging";
    this.colorPicker = new ColorPicker(this.ctx, { detached: true });
    this.cleanup.register(ctx.eventsHub.on("layout:complete", this.onLayoutComplete.bind(this)));
  }
  showWithChildren(children, options) {
    const popover = super.showWithChildren(children, options);
    popover.classList.add("ag-charts-dialog");
    popover.setAttribute("role", "dialog");
    popover.addEventListener("mousedown", (event) => {
      if (event.target.classList?.contains("ag-charts-dialog__color-picker-button"))
        return;
      this.colorPicker.hide();
    });
    popover.addEventListener("keydown", this.onKeyDown.bind(this));
    getWindow().requestAnimationFrame(() => this.reposition());
    this.colorPicker.attachTo(this);
    return popover;
  }
  updatePosition(position) {
    super.updatePosition(position);
    const { anchor, fallbackAnchor } = this.getColorPickerAnchors() ?? {};
    if (!anchor)
      return;
    this.colorPicker.setAnchor(anchor, fallbackAnchor);
  }
  /**************
   * Containers *
   **************/
  createTabs(tablistLabel, initial, tabs) {
    const element2 = createElement("div", "ag-charts-dialog__tabs");
    const tabButtonIds = mapValues(tabs, () => createElementId());
    const tabPanelIds = mapValues(tabs, () => createElementId());
    for (const [key, tab] of entries(tabs)) {
      setAttributes(tab.panel, {
        id: tabPanelIds[key],
        role: "tabpanel",
        "aria-labelledby": tabButtonIds[key]
      });
    }
    const onPressTab = (active) => {
      for (const [key, tab] of entries(tabs)) {
        tab.panel.classList.toggle("ag-charts-dialog__tab-panel--active", key === active);
        tabButtons[key].classList.toggle("ag-charts-dialog__tab-button--active", key === active);
        setAttribute(tabButtons[key], "aria-selected", key === active);
        if (key === active)
          tab.onShow?.();
      }
    };
    const header = new NativeWidget2(createElement("div", "ag-charts-dialog__header"));
    header.addListener("drag-start", (event) => {
      const { sourceEvent } = event;
      if (sourceEvent.target instanceof Element && sourceEvent.target.classList.contains("ag-charts-dialog__header")) {
        this.onDragStart(event);
      }
    });
    header.addListener("drag-move", (event) => this.onDragMove(event));
    header.addListener("drag-end", () => this.onDragEnd());
    const dragHandle = new DragHandleWidget2();
    this.setDragHandle(dragHandle);
    const tabButtons = mapValues(
      tabs,
      (tab, key) => createButton(
        {
          label: this.ctx.localeManager.t(tab.label),
          onPress: () => onPressTab(key)
        },
        {
          id: tabButtonIds[key],
          class: "ag-charts-dialog__tab-button",
          role: "tab",
          "aria-controls": tabPanelIds[key]
        }
      )
    );
    const tabList = createElement("div", "ag-charts-dialog__tab-list");
    setAttributes(tabList, { role: "tablist", "aria-label": this.ctx.localeManager.t(tablistLabel) });
    tabList.append(...Object.values(tabButtons));
    const closeButton = this.createHeaderCloseButton();
    header.getElement().append(dragHandle.getElement(), tabList, closeButton);
    element2.append(header.getElement(), ...Object.values(tabs).map((t) => t.panel));
    onPressTab(initial);
    initRovingTabIndex({ orientation: "horizontal", buttons: Object.values(tabButtons) });
    return { tabs: element2, initialFocus: tabButtons[initial] };
  }
  createTabPanel() {
    return createElement("div", "ag-charts-dialog__tab-panel");
  }
  /**********
   * Inputs *
   **********/
  createInputGroupLine() {
    return createElement("div", "ag-charts-dialog__input-group-line");
  }
  createRadioGroup({ label, options, value, onChange }) {
    const group = this.createInputGroup(label);
    setAttributes(group, {
      role: "radiogroup",
      tabindex: -1,
      "aria-label": this.ctx.localeManager.t(label)
    });
    const activeClass = "ag-charts-dialog__button--active";
    const buttons = [];
    for (const button of options) {
      const { icon, altText: altTextKey } = button;
      const altText = this.ctx.localeManager.t(altTextKey);
      const buttonEl = createButton(
        {
          icon,
          altText,
          onPress: () => {
            for (const b of Array.from(group.children)) {
              b.classList.remove(activeClass);
              b.ariaChecked = "false";
            }
            buttonEl.classList.add(activeClass);
            buttonEl.ariaChecked = "true";
            onChange(button.value);
          }
        },
        {
          "aria-checked": button.value === value,
          class: "ag-charts-dialog__button",
          role: "radio",
          title: altText
        }
      );
      if (button.value === value) {
        buttonEl.classList.add(activeClass);
      }
      group.appendChild(buttonEl);
      buttons.push(buttonEl);
    }
    initRovingTabIndex({ orientation: "horizontal", buttons });
    return group;
  }
  createSelect({ altText, label, options, value, onChange }) {
    const group = this.createInputGroup(label);
    const altTextT = this.ctx.localeManager.t(altText);
    const select = createSelect(
      { value, options, onChange },
      { class: "ag-charts-dialog__select", "aria-label": altTextT, title: altTextT }
    );
    group.append(select);
    return group;
  }
  createTextArea({ placeholder, value, onChange }) {
    const placeholderT = placeholder ? this.ctx.localeManager.t(placeholder) : void 0;
    return createTextArea({ value, onChange }, { placeholder: placeholderT });
  }
  createCheckbox({ label, checked, onChange }) {
    const id = createElementId();
    const group = this.createInputGroup(label, { for: id });
    const checkbox = createCheckbox(
      { checked, onChange },
      { class: "ag-charts-dialog__checkbox", role: "switch", id }
    );
    group.append(checkbox);
    return group;
  }
  createColorPicker({
    color: color2,
    opacity,
    label,
    altText,
    onChange,
    onChangeHide,
    isMultiColor,
    hasMultiColorOption
  }) {
    const group = this.createInputGroup(label);
    const altTextT = this.ctx.localeManager.t(altText);
    const colorEl = createButton(
      {
        label: altTextT,
        onPress: (event) => {
          const { anchor, fallbackAnchor } = this.getColorPickerAnchors(colorEl) ?? {};
          this.colorPicker.show({
            anchor,
            fallbackAnchor,
            color: color2,
            opacity,
            isMultiColor,
            hasMultiColorOption,
            sourceEvent: event,
            onChange: (newColorOpacity, newColor, newOpacity, newIsMultiColor) => {
              colorEl.style.setProperty("--color", newColorOpacity);
              colorEl.classList.toggle(
                "ag-charts-dialog__color-picker-button--multi-color",
                newIsMultiColor
              );
              onChange(newColorOpacity, newColor, newOpacity, newIsMultiColor);
            },
            onChangeHide
          });
        }
      },
      {
        "aria-label": altTextT,
        tabindex: 0,
        class: "ag-charts-dialog__color-picker-button",
        title: altTextT
      }
    );
    if (isMultiColor) {
      colorEl.classList.toggle("ag-charts-dialog__color-picker-button--multi-color");
    } else if (color2) {
      const hex = Color.fromString(color2);
      const hexWithOpacity = new Color(hex.r, hex.g, hex.b, opacity);
      colorEl.style.setProperty("--color", hexWithOpacity.toHexString());
    }
    group.append(colorEl);
    this.hideFns.push(() => {
      this.colorPicker.hide();
    });
    return group;
  }
  /***********
   * Private *
   ***********/
  createHeaderCloseButton() {
    return createButton(
      { icon: "close", altText: this.ctx.localeManager.t("iconAltTextClose"), onPress: () => this.hide() },
      { class: "ag-charts-dialog__close-button" }
    );
  }
  createInputGroup(label, options) {
    const group = createElement("div", "ag-charts-dialog__input-group");
    const labelEl = createElement("label", "ag-charts-dialog__input-group-label");
    labelEl.innerText = this.ctx.localeManager.t(label);
    setAttribute(labelEl, "for", options?.for);
    group.appendChild(labelEl);
    return group;
  }
  onLayoutComplete(event) {
    this.seriesRect = event.series.paddedRect;
    this.reposition();
  }
  onKeyDown(event) {
    if (event.altKey || event.ctrlKey || event.metaKey || event.isComposing || event.key !== "Escape")
      return;
    this.hide();
  }
  reposition() {
    const { seriesRect, ctx } = this;
    const popover = this.getPopoverElement();
    if (!seriesRect || !popover)
      return;
    const clientRect = ctx.domManager.getBoundingClientRect();
    const outerOffset = vector_exports.from(0, seriesRect.y);
    const outerSize = vector_exports.from(clientRect.width, seriesRect.height);
    const popoverSize = vector_exports.from(popover);
    const halfWidth = vector_exports.from(0.5, 1);
    let position;
    if (seriesRect.width > 1e3) {
      const bottomCenter2 = vector_exports.sub(
        vector_exports.add(outerOffset, vector_exports.multiply(outerSize, halfWidth)),
        vector_exports.multiply(popoverSize, halfWidth)
      );
      position = vector_exports.sub(bottomCenter2, vector_exports.from(0, _Dialog.offset));
    } else {
      const bottomRight = vector_exports.sub(vector_exports.add(outerOffset, outerSize), popoverSize);
      position = vector_exports.sub(bottomRight, _Dialog.offset);
    }
    this.updatePosition(position);
  }
  getColorPickerAnchors(element2) {
    if (element2)
      this.colorPickerAnchorElement = element2;
    if (!this.colorPickerAnchorElement)
      return;
    const rect2 = this.colorPickerAnchorElement.getBoundingClientRect();
    const canvasRect = this.ctx.domManager.getBoundingClientRect();
    const topLeft = vector_exports.sub(vector_exports.from(rect2.x, rect2.y), vector_exports.from(canvasRect.left, canvasRect.top));
    const anchor = vector_exports.add(topLeft, vector_exports.from(0, rect2.height + 5));
    const fallbackAnchor = vector_exports.sub(topLeft, vector_exports.from(0, 5));
    return { anchor, fallbackAnchor };
  }
};
_Dialog.offset = 60;
var Dialog = _Dialog;
var DragHandleWidget2 = class extends NativeWidget2 {
  constructor() {
    super(createElement("div", "ag-charts-dialog__drag-handle"));
    const icon = new NativeWidget2(createElement("span", getIconClassNames("drag-handle")));
    icon.setAriaHidden(true);
    this.addChild(icon);
  }
};

// packages/ag-charts-enterprise/src/features/annotations/settings-dialog/settingsDialog.ts
var AnnotationSettingsDialog = class extends Dialog {
  constructor(ctx) {
    super(ctx, "settings");
    this.events = new EventEmitter();
    this.hideFns.push(() => this.events.emit("hidden", null));
  }
  show(datum, options) {
    const lineTab = this.createLinearLineTab(datum, options);
    const textTab = this.createLinearTextTab(datum, options);
    let lineLabel = "dialogHeaderLine";
    if (isChannelType(datum)) {
      lineLabel = "dialogHeaderChannel";
    } else if (isFibonacciType(datum)) {
      lineLabel = "dialogHeaderFibonacciRange";
    } else if (datum.type === "date-range" /* DateRange */) {
      lineLabel = "dialogHeaderDateRange";
    } else if (datum.type === "price-range" /* PriceRange */) {
      lineLabel = "dialogHeaderPriceRange";
    } else if (datum.type === "date-price-range" /* DatePriceRange */) {
      lineLabel = "dialogHeaderDatePriceRange";
    }
    const { tabs, initialFocus } = this.createTabs("ariaLabelSettingsTabBar", options.initialSelectedTab, {
      line: {
        label: lineLabel,
        panel: lineTab
      },
      text: {
        label: "dialogHeaderText",
        panel: textTab.panel,
        onShow: textTab.onShow
      }
    });
    options.initialFocus = initialFocus;
    const popover = this.showWithChildren([tabs], options);
    popover.classList.add("ag-charts-dialog--annotation-settings");
  }
  createLinearLineTab(datum, options) {
    const panel = this.createTabPanel();
    const groupOne = this.createInputGroupLine();
    const groupTwo = this.createInputGroupLine();
    const hasMultiColorOption = "isMultiColor" in datum;
    const lineColorPicker = this.createColorPickerInput(
      "line-color",
      datum.getDefaultColor("line-color"),
      datum.getDefaultOpacity("line-color"),
      hasMultiColorOption ? datum.isMultiColor : false,
      hasMultiColorOption,
      options.onChangeLineColor,
      options.onChangeHideLineColor
    );
    const strokeWidth = this.createStrokeWidthSelect(datum.strokeWidth ?? 2, options.onChangeLineStyleWidth);
    const lineStyle = this.createLineStyleRadioGroup(datum.lineStyle ?? "solid", options.onChangeLineStyleType);
    groupOne.append(lineColorPicker);
    if ("background" in datum) {
      const fillColorPicker = this.createColorPickerInput(
        "fill-color",
        datum.getDefaultColor("fill-color"),
        datum.getDefaultOpacity("fill-color"),
        false,
        false,
        options.onChangeFillColor,
        options.onChangeHideFillColor
      );
      groupOne.append(fillColorPicker);
      groupTwo.append(strokeWidth);
    } else if ("showFill" in datum) {
      groupOne.append(
        this.createCheckbox({
          label: "dialogInputShowFill",
          checked: datum.showFill ?? true,
          onChange: (showFill) => options.onChangeLine({ showFill })
        })
      );
      groupTwo.append(strokeWidth);
    } else {
      groupOne.append(strokeWidth);
    }
    groupTwo.append(lineStyle);
    panel.append(groupOne, groupTwo);
    if ("bands" in datum) {
      panel.append(
        this.createFibonacciRatioSelect(datum.bands ?? 10, (bands) => options.onChangeLine({ bands }))
      );
    }
    if ("extendStart" in datum && "extendEnd" in datum) {
      panel.append(
        this.createCheckbox({
          label: isChannelType(datum) ? "dialogInputExtendChannelStart" : "dialogInputExtendLineStart",
          checked: datum.extendStart ?? false,
          onChange: (extendStart) => options.onChangeLine({ extendStart })
        }),
        this.createCheckbox({
          label: isChannelType(datum) ? "dialogInputExtendChannelEnd" : "dialogInputExtendLineEnd",
          checked: datum.extendEnd ?? false,
          onChange: (extendEnd) => options.onChangeLine({ extendEnd })
        })
      );
    }
    if ("extendAbove" in datum && "extendBelow" in datum) {
      panel.append(
        this.createCheckbox({
          label: "dialogInputExtendAbove",
          checked: datum.extendAbove ?? false,
          onChange: (extendAbove) => options.onChangeLine({ extendAbove })
        }),
        this.createCheckbox({
          label: "dialogInputExtendBelow",
          checked: datum.extendBelow ?? false,
          onChange: (extendBelow) => options.onChangeLine({ extendBelow })
        })
      );
    }
    if ("extendLeft" in datum && "extendRight" in datum) {
      panel.append(
        this.createCheckbox({
          label: "dialogInputExtendLeft",
          checked: datum.extendLeft ?? false,
          onChange: (extendLeft) => options.onChangeLine({ extendLeft })
        }),
        this.createCheckbox({
          label: "dialogInputExtendRight",
          checked: datum.extendRight ?? false,
          onChange: (extendRight) => options.onChangeLine({ extendRight })
        })
      );
    }
    if ("reverse" in datum && "showFill" in datum) {
      panel.append(
        this.createCheckbox({
          label: "dialogInputReverse",
          checked: datum.reverse ?? false,
          onChange: (reverse) => options.onChangeLine({ reverse })
        })
      );
    }
    return panel;
  }
  createLinearTextTab(datum, options) {
    const panel = this.createTabPanel();
    const textArea = this.createTextArea({
      placeholder: "inputTextareaPlaceholder",
      value: datum.text.label,
      onChange: (value) => options.onChangeText({ label: value })
    });
    const fontSize = this.createFontSizeSelect(datum.text.fontSize, options.onChangeTextFontSize);
    const colorPicker = this.createColorPickerInput(
      "text-color",
      datum.text.color,
      1,
      false,
      false,
      options.onChangeTextColor,
      options.onChangeHideTextColor
    );
    const textPosition = datum.text.position === "inside" ? "center" : datum.text.position;
    const position = this.createPositionRadioGroup(
      textPosition ?? "top",
      (value) => options.onChangeText({ position: value })
    );
    const alignment = this.createAlignmentRadioGroup(
      datum.text.alignment ?? "center",
      (value) => options.onChangeText({ alignment: value })
    );
    const inputGroupLine = this.createInputGroupLine();
    inputGroupLine.append(fontSize, colorPicker, position, alignment);
    panel.append(textArea, inputGroupLine);
    return { panel, onShow: () => focusCursorAtEnd(textArea) };
  }
  createColorPickerInput(colorType, color2, opacity, isMultiColor, hasMultiColorOption, onChange, onChangeHide) {
    const label = colorType === "fill-color" ? "dialogInputFillColorPicker" : "dialogInputColorPicker";
    const altText = colorType === "fill-color" ? "dialogInputFillColorPickerAltText" : "dialogInputColorPickerAltText";
    return this.createColorPicker({
      label,
      altText,
      color: color2,
      opacity,
      isMultiColor,
      hasMultiColorOption,
      onChange,
      onChangeHide
    });
  }
  createStrokeWidthSelect(strokeWidth, onChange) {
    return this.createSelect({
      label: "dialogInputStrokeWidth",
      altText: "dialogInputStrokeWidthAltText",
      options: LINE_STROKE_WIDTH_ITEMS.map(({ label, value }) => ({ label, value: `${value}` })),
      value: String(strokeWidth),
      onChange: (value) => onChange(Number(value))
    });
  }
  createFibonacciRatioSelect(bands, onChange) {
    return this.createSelect({
      label: "dialogInputFibonacciBands",
      altText: "dialogInputFibonacciBandsAltText",
      options: FIBONACCI_RATIO_ITEMS.map(({ label, value }) => ({ label, value: `${value}` })),
      value: String(bands),
      onChange: (value) => onChange(Number(value))
    });
  }
  createLineStyleRadioGroup(lineStyle, onChange) {
    return this.createRadioGroup({
      label: "dialogInputLineStyle",
      options: [
        { icon: "line-style-solid", altText: "iconAltTextLineStyleSolid", value: "solid" },
        { icon: "line-style-dashed", altText: "iconAltTextLineStyleDashed", value: "dashed" },
        { icon: "line-style-dotted", altText: "iconAltTextLineStyleDotted", value: "dotted" }
      ],
      value: lineStyle,
      onChange
    });
  }
  createFontSizeSelect(fontSize, onChange) {
    return this.createSelect({
      label: "dialogInputFontSize",
      altText: "dialogInputFontSizeAltText",
      options: TEXT_SIZE_ITEMS.map(({ label, value }) => ({ label, value: String(value) })),
      value: String(fontSize),
      onChange: (value) => onChange(Number(value))
    });
  }
  createPositionRadioGroup(position, onChange) {
    return this.createRadioGroup({
      label: "dialogInputPosition",
      options: [
        { icon: "position-top", altText: "iconAltTextPositionTop", value: "top" },
        { icon: "position-center", altText: "iconAltTextPositionCenter", value: "center" },
        { icon: "position-bottom", altText: "iconAltTextPositionBottom", value: "bottom" }
      ],
      value: position,
      onChange
    });
  }
  createAlignmentRadioGroup(alignment, onChange) {
    return this.createRadioGroup({
      label: "dialogInputAlign",
      options: [
        { icon: "align-left", altText: "iconAltTextAlignLeft", value: "left" },
        { icon: "align-center", altText: "iconAltTextAlignCenter", value: "center" },
        { icon: "align-right", altText: "iconAltTextAlignRight", value: "right" }
      ],
      value: alignment,
      onChange
    });
  }
};

// packages/ag-charts-enterprise/src/features/annotations/utils/axis.ts
function calculateAxisLabelPadding(axisLayout) {
  return axisLayout.gridPadding + axisLayout.seriesAreaPadding + axisLayout.tickSize + axisLayout.label.spacing;
}

// packages/ag-charts-enterprise/src/features/annotations/utils/update.ts
function updateAnnotation(node, datum, context) {
  for (const { update } of Object.values(annotationConfigs)) {
    update(node, datum, context);
  }
}

// packages/ag-charts-enterprise/src/features/annotations/annotations.ts
var { InteractionState: InteractionState3, keyProperty: keyProperty3, valueProperty: valueProperty4, Selection: Selection6, BBox: BBox10 } = module_support_exports;
var _Annotations = class _Annotations extends AbstractModuleInstance {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.toolbar = new AnnotationsToolbar(this.ctx);
    this.optionsToolbar = new AnnotationOptionsToolbar(this.ctx, () => {
      const active = this.state.getActive();
      if (active == null)
        return;
      return getTypedDatum(this.annotationData.at(active));
    });
    this.axesButtons = new AxesButtons();
    this.enabled = true;
    this.snap = false;
    // Hidden options for use with measurer statistics
    this.data = void 0;
    this.xKey = void 0;
    this.volumeKey = void 0;
    this.annotationData = new PropertiesArray(
      _Annotations.createAnnotationDatum
    );
    this.defaults = new AnnotationDefaults();
    this.container = new module_support_exports.Group({ name: "static-annotations" });
    this.annotations = new Selection6(
      this.container,
      this.createAnnotationScene.bind(this)
    );
    this.settingsDialog = new AnnotationSettingsDialog(this.ctx);
    this.textInput = new TextInput(this.ctx);
    this.postUpdateFns = [];
    this.state = this.setupStateMachine();
    this.setupListeners();
    this.setupDOM();
    this.ctx.historyManager.addMementoOriginator(ctx.annotationManager);
    this.ctx.historyManager.addMementoOriginator(this.defaults);
    this.textInput.setKeyDownHandler(this.onTextInput.bind(this));
    this.cleanup.register(() => {
      this.clear();
      this.xAxis?.button?.destroy();
      this.yAxis?.button?.destroy();
      this.textInput.destroy();
    });
  }
  setupStateMachine() {
    const { ctx } = this;
    return new AnnotationsStateMachine({
      resetToIdle: () => {
        ctx.domManager.updateCursor("annotations");
        this.popAnnotationState(InteractionState3.Annotations);
        this.hideOverlays();
        this.optionsToolbar.hide();
        this.deleteEphemeralAnnotations();
        this.update();
      },
      hoverAtCoords: (coords, active, previousHovered) => {
        let hovered;
        this.annotations.each((annotation, datum, index) => {
          if (!datum.isHoverable())
            return;
          const contains = annotation.containsPoint(coords.x, coords.y);
          if (contains)
            hovered ?? (hovered = index);
          annotation.toggleHovered(contains, active === index, datum.readOnly);
        });
        if (hovered != null) {
          ctx.tooltipManager.suppressTooltip("annotations");
        } else if (!this.isAnnotationState()) {
          ctx.tooltipManager.unsuppressTooltip("annotations");
        }
        if (hovered == null || !this.annotationData.at(hovered)?.readOnly) {
          this.ctx.domManager.updateCursor(
            "annotations",
            hovered == null ? void 0 : this.annotations.at(hovered)?.getCursor()
          );
        }
        if (hovered !== previousHovered) {
          this.update();
        }
        return hovered;
      },
      getNodeAtCoords: (coords, active) => {
        const node = this.annotations.at(active);
        if (!node) {
          return;
        }
        return node.getNodeAtCoords(coords.x, coords.y);
      },
      translate: (index, translation) => {
        const node = this.annotations.at(index);
        const datum = getTypedDatum(this.annotationData.at(index));
        if (!node || !datum) {
          return;
        }
        return this.translateNode(node, datum, translation);
      },
      copy: (index) => {
        const node = this.annotations.at(index);
        const datum = getTypedDatum(this.annotationData.at(index));
        if (!node || !datum) {
          return;
        }
        return this.createAnnotationDatumCopy(node, datum);
      },
      paste: (datum) => {
        this.createAnnotation(datum.type, datum, false);
        this.postUpdateFns.push(() => {
          this.state.transitionAsync("selectLast");
          this.state.transitionAsync("copy");
        });
      },
      select: (index, previous) => {
        const { annotations, optionsToolbar: optionsToolbar2, toolbar: toolbar2 } = this;
        this.hideOverlays();
        toolbar2.clearActiveButton();
        toolbar2.resetButtonIcons();
        const selectedNode = index == null ? null : annotations.at(index);
        const previousNode = previous == null ? null : annotations.at(previous);
        const selectedDatum = index == null ? null : this.annotationData.at(index);
        if (previousNode === selectedNode && selectedNode != null) {
          return;
        }
        previousNode?.toggleActive(false);
        optionsToolbar2.hide();
        if (selectedNode && !selectedDatum?.readOnly) {
          this.pushAnnotationState(InteractionState3.AnnotationsSelected);
          selectedNode.toggleActive(true);
          if (!isEphemeralType(selectedDatum)) {
            optionsToolbar2.updateButtons(this.annotationData.at(index));
            this.postUpdateFns.push(() => {
              optionsToolbar2.show();
              optionsToolbar2.setAnchorScene(selectedNode);
            });
          }
        } else {
          this.popAnnotationState(InteractionState3.AnnotationsSelected);
          this.popAnnotationState(InteractionState3.Annotations);
        }
        if (!isEphemeralType(selectedDatum)) {
          this.deleteEphemeralAnnotations();
        }
        this.update();
      },
      selectLast: () => {
        this.pushAnnotationState(InteractionState3.AnnotationsSelected);
        return this.annotationData.length - 1;
      },
      startInteracting: () => {
        this.pushAnnotationState(InteractionState3.Annotations);
      },
      stopInteracting: () => {
        this.popAnnotationState(InteractionState3.Annotations);
      },
      create: (type, datum) => {
        this.createAnnotation(type, datum);
      },
      delete: (index) => {
        this.annotationData.splice(index, 1);
      },
      deleteAll: () => {
        const readOnly = this.annotationData.filter((datum) => {
          if (datum.readOnly === true)
            return datum;
        });
        this.annotationData.splice(0, this.annotationData.length);
        for (const datum of readOnly) {
          this.annotationData.push(datum);
        }
      },
      validatePoint: (point, options) => {
        const context = this.getAnnotationContext();
        return context ? validateDatumPoint(context, point, options) : true;
      },
      getAnnotationType: (index) => {
        return stringToAnnotationType(this.annotationData[index].type);
      },
      datum: (index) => {
        return this.annotationData.at(index);
      },
      node: (index) => {
        return this.annotations.at(index);
      },
      recordAction: (label) => {
        this.recordActionAfterNextUpdate(label);
      },
      update: () => {
        this.postUpdateFns.push(() => {
          const active = this.state.getActive();
          const node = active == null ? null : this.annotations.at(active);
          if (node == null)
            return;
          this.optionsToolbar.setAnchorScene(node);
        });
        this.update();
      },
      showTextInput: (active) => {
        const datum = getTypedDatum(this.annotationData.at(active));
        const node = this.annotations.at(active);
        if (!node || !datum || !("getTextInputCoords" in datum) || !("getTextPosition" in datum))
          return;
        const styles = {
          color: datum.color,
          fontFamily: datum.fontFamily,
          fontSize: datum.fontSize,
          fontStyle: datum.fontStyle,
          fontWeight: datum.fontWeight,
          placeholderColor: datum.getPlaceholderColor()
        };
        const context = this.getAnnotationContext();
        const getTextInputCoords = (height2) => vector_exports.add(datum.getTextInputCoords(context, height2), vector_exports.required(this.seriesRect));
        const getTextPosition = () => datum.getTextPosition();
        this.textInput.show({
          styles,
          layout: {
            getTextInputCoords,
            getTextPosition,
            alignment: datum.alignment,
            textAlign: datum.textAlign,
            width: datum.width
          },
          text: datum.text,
          placeholderText: datum.placeholderText,
          onChange: (_text, bbox) => {
            this.state.transition("updateTextInputBBox", bbox);
          }
        });
        this.ctx.domManager.updateCursor("annotations");
      },
      hideTextInput: () => {
        this.textInput.hide();
      },
      updateTextInputColor: (color2) => {
        this.textInput.updateColor(color2);
      },
      updateTextInputFontSize: (fontSize) => {
        const bbox = this.textInput.updateFontSize(fontSize);
        this.state.transition("updateTextInputBBox", bbox);
      },
      updateTextInputBBox: (bbox) => {
        this.state.transition("updateTextInputBBox", bbox);
      },
      showAnnotationOptions: (active) => {
        const node = this.annotations.at(active);
        if (!node || isEphemeralType(this.annotationData.at(active)))
          return;
        this.optionsToolbar.updateButtons(this.annotationData.at(active));
        this.optionsToolbar.show();
        this.optionsToolbar.setAnchorScene(node);
      },
      showAnnotationSettings: (active, sourceEvent, initialTab = "line") => {
        const datum = this.annotationData.at(active);
        if (!isLineType(datum) && !isChannelType(datum) && !isMeasurerType(datum))
          return;
        if (isEphemeralType(datum))
          return;
        const onChangeColor = (colorType) => (colorOpacity, color2, opacity, isMultiColor) => {
          this.setColorAndDefault(datum.type, colorType, colorOpacity, color2, opacity, isMultiColor);
          this.optionsToolbar.updateColorPickerColor(colorType, color2, opacity, isMultiColor);
        };
        const onChangeHideColor = (colorType) => () => {
          this.recordActionAfterNextUpdate(
            `Change ${datum.type} ${colorType} to ${datum.getDefaultColor(colorType)}`,
            ["annotations", "defaults"]
          );
          this.update();
        };
        const options = {
          initialSelectedTab: initialTab,
          ariaLabel: this.ctx.localeManager.t("ariaLabelAnnotationSettingsDialog"),
          sourceEvent,
          onChangeLine: (props) => {
            this.state.transition("lineProps", props);
            if (props.bands != null)
              this.defaults.setDefaultFibonacciOptions(datum.type, "bands", props.bands);
            if (props.reverse != null)
              this.defaults.setDefaultFibonacciOptions(datum.type, "reverse", props.reverse);
            if (props.showFill != null)
              this.defaults.setDefaultFibonacciOptions(datum.type, "showFill", props.showFill);
          },
          onChangeText: (props) => {
            this.state.transition("lineText", props);
            if (props.alignment)
              this.defaults.setDefaultLineTextAlignment(datum.type, props.alignment);
            if (props.position)
              this.defaults.setDefaultLineTextPosition(datum.type, props.position);
            this.recordActionAfterNextUpdate(
              `Change ${datum.type} text ${Object.keys(props).map((key) => `${key} to ${props[key]}`).join(", ")}`
            );
          },
          onChangeFillColor: onChangeColor("fill-color"),
          onChangeHideFillColor: onChangeHideColor("fill-color"),
          onChangeLineColor: onChangeColor("line-color"),
          onChangeHideLineColor: onChangeHideColor("line-color"),
          onChangeLineStyleType: (lineStyleType) => {
            this.setLineStyleTypeAndDefault(datum.type, lineStyleType);
            this.optionsToolbar.updateLineStyleType(
              LINE_STYLE_TYPE_ITEMS.find((item) => item.value === lineStyleType) ?? LINE_STYLE_TYPE_ITEMS[0]
            );
          },
          onChangeLineStyleWidth: (strokeWidth) => {
            this.setLineStyleWidthAndDefault(datum.type, strokeWidth);
            this.optionsToolbar.updateStrokeWidth({
              strokeWidth,
              value: strokeWidth,
              label: String(strokeWidth)
            });
          },
          onChangeTextColor: onChangeColor("text-color"),
          onChangeHideTextColor: onChangeHideColor("text-color"),
          onChangeTextFontSize: (fontSize) => {
            this.setFontSizeAndDefault(datum.type, fontSize);
          }
        };
        this.settingsDialog.show(datum, options);
      }
    });
  }
  setupListeners() {
    const { ctx, optionsToolbar: optionsToolbar2, settingsDialog, toolbar: toolbar2 } = this;
    const { seriesWidget, seriesDragInterpreter, chartWidget } = ctx.widgets;
    if (seriesDragInterpreter) {
      this.cleanup.register(
        // Interactions
        seriesDragInterpreter.events.on("click", this.hoverTouchPreHandler.bind(this)),
        seriesDragInterpreter.events.on("drag-start", this.hoverTouchPreHandler.bind(this)),
        seriesDragInterpreter.events.on("drag-move", this.dragMoveTouchPreHandler.bind(this)),
        seriesDragInterpreter.events.on("mousemove", this.onHover.bind(this)),
        seriesDragInterpreter.events.on("click", this.onClick.bind(this)),
        seriesDragInterpreter.events.on("dblclick", this.onDoubleClick.bind(this)),
        seriesDragInterpreter.events.on("drag-start", this.onDragStart.bind(this)),
        seriesDragInterpreter.events.on("drag-move", this.onDrag.bind(this)),
        seriesDragInterpreter.events.on("drag-end", this.onDragEnd.bind(this))
      );
    }
    this.cleanup.register(
      // Interactions
      seriesWidget.addListener("keydown", this.onKeyDown.bind(this)),
      seriesWidget.addListener("keyup", this.onKeyUp.bind(this)),
      chartWidget.addListener("click", this.onCancel.bind(this)),
      // Services
      ctx.eventsHub.on("annotations:restore", this.onRestoreAnnotations.bind(this)),
      ctx.eventsHub.on("layout:complete", this.onLayoutComplete.bind(this)),
      ctx.updateService.addListener("pre-scene-render", this.onPreRender.bind(this)),
      ctx.eventsHub.on("zoom:change-complete", () => this.onResize()),
      ctx.eventsHub.on("dom:resize", () => this.onResize()),
      // Toolbar
      toolbar2.events.on("cancel-create-annotation", () => {
        this.cancel();
        this.reset();
        this.update();
      }),
      toolbar2.events.on("pressed-create-annotation", ({ annotation }) => {
        this.cancel();
        this.pushAnnotationState(InteractionState3.Annotations);
        this.state.transition(annotation);
        this.update();
      }),
      toolbar2.events.on("pressed-clear", () => {
        this.clear();
        this.recordActionAfterNextUpdate("Clear all");
      }),
      toolbar2.events.on("pressed-show-menu", () => {
        this.cancel();
        this.reset();
      }),
      toolbar2.events.on("pressed-unrelated", () => {
        this.reset();
      }),
      // Annotation Options Toolbar
      optionsToolbar2.events.on("pressed-delete", () => {
        this.cancel();
        this.delete();
        this.reset();
      }),
      optionsToolbar2.events.on("pressed-settings", ({ sourceEvent }) => {
        this.state.transition("toolbarPressSettings", sourceEvent);
      }),
      optionsToolbar2.events.on("pressed-lock", ({ locked }) => {
        this.recordActionAfterNextUpdate(locked ? "Locked" : "Unlocked");
        this.update();
      }),
      optionsToolbar2.events.on("hid-overlays", () => {
        this.settingsDialog.hide();
      }),
      optionsToolbar2.events.on("saved-color", ({ type, colorPickerType, color: color2 }) => {
        this.recordActionAfterNextUpdate(`Change ${type} ${colorPickerType} to ${color2}`, [
          "annotations",
          "defaults"
        ]);
      }),
      optionsToolbar2.events.on(
        "updated-color",
        ({ type, colorPickerType, colorOpacity, color: color2, opacity, isMultiColor }) => {
          this.setColorAndDefault(type, colorPickerType, colorOpacity, color2, opacity, isMultiColor);
        }
      ),
      optionsToolbar2.events.on("updated-font-size", ({ type, fontSize }) => {
        this.setFontSizeAndDefault(type, fontSize);
      }),
      optionsToolbar2.events.on("updated-line-style", ({ type, lineStyleType }) => {
        this.setLineStyleTypeAndDefault(type, lineStyleType);
      }),
      optionsToolbar2.events.on("updated-line-width", ({ type, strokeWidth }) => {
        this.setLineStyleWidthAndDefault(type, strokeWidth);
      }),
      // Settings Dialog
      settingsDialog.events.on("hidden", () => {
        this.optionsToolbar.clearActiveButton();
      })
    );
  }
  setupDOM() {
    const { ctx, toolbar: toolbar2, optionsToolbar: optionsToolbar2 } = this;
    this.cleanup.register(ctx.annotationManager.attachNode(this.container), () => {
      ctx.domManager.removeStyles(DEFAULT_ANNOTATION_AXIS_BUTTON_CLASS);
      toolbar2.destroy();
      optionsToolbar2.destroy();
    });
  }
  async processData(dataController) {
    if (!this.enabled || this.data == null || this.xKey == null || this.volumeKey == null)
      return;
    const props = [
      keyProperty3(this.xKey, void 0, { id: "date" }),
      valueProperty4(this.volumeKey, "number", { id: "volume" })
    ];
    const dataSet = module_support_exports.DataSet.wrap(this.data) ?? module_support_exports.DataSet.empty();
    const { dataModel, processedData } = await dataController.request("annotations", dataSet, {
      props
    });
    this.dataModel = dataModel;
    this.processedData = processedData;
  }
  /**
   * Create an annotation scene within the `this.annotations` scene selection. This method is automatically called by
   * the selection when a new scene is required.
   */
  createAnnotationScene(datum) {
    if (datum.type in annotationConfigs) {
      return new annotationConfigs[datum.type].scene();
    }
    throw new Error(
      `AG Charts - Cannot create annotation scene of type [${datum.type}], expected one of [${Object.keys(annotationConfigs)}], ignoring.`
    );
  }
  /**
   * Create an annotation datum within the `this.annotationData` properties array. It is created as an instance
   * of `AnnotationProperties` from the given config for its type. This method is only called when annotations
   * are added from the initial state.
   */
  static createAnnotationDatum(params) {
    if (params.type in annotationConfigs) {
      return new annotationConfigs[params.type].datum().set(params);
    }
    throw new Error(
      `AG Charts - Cannot create annotation datum of unknown type [${params.type}], expected one of [${Object.keys(annotationConfigs)}], ignoring.`
    );
  }
  /**
   * Append an annotation datum to `this.annotationData`, applying default styles. This method is called when a user
   * interacts with the chart to draw their own annotations.
   */
  createAnnotation(type, datum, applyDefaults = true) {
    this.annotationData.push(datum);
    if (applyDefaults) {
      const styles = this.ctx.annotationManager.getAnnotationTypeStyles(type);
      if (styles)
        datum.set(styles);
      this.defaults.applyDefaults(datum);
    }
    this.injectDatumDependencies(datum);
    this.update();
  }
  injectDatumDependencies(datum) {
    if ("setLocaleManager" in datum) {
      datum.setLocaleManager(this.ctx.localeManager);
    }
    if ("getVolume" in datum) {
      datum.getVolume = this.getDatumRangeVolume.bind(this);
    }
  }
  getDatumRangeVolume(fromPoint, toPoint) {
    const { dataModel, processedData } = this;
    let from3 = getGroupingValue(fromPoint);
    let to = getGroupingValue(toPoint);
    if (!isValidDate(from3) || !isValidDate(to) || !dataModel || !processedData || this.volumeKey == null)
      return;
    if (from3 > to) {
      [from3, to] = [to, from3];
    }
    const dateValues = dataModel.resolveKeysById({ id: "annotations" }, "date", processedData);
    const volumeValues = dataModel.resolveColumnById({ id: "annotations" }, "volume", processedData);
    let sum = 0;
    for (let datumIndex = 0; datumIndex < processedData.input.count; datumIndex++) {
      const key = dateValues[datumIndex];
      if (isValidDate(key) && key >= from3 && key <= to) {
        sum += volumeValues[datumIndex];
      }
    }
    return sum;
  }
  translateNode(node, datum, translation) {
    const config = this.getAnnotationConfig(datum);
    const context = this.getAnnotationContext();
    if (!context) {
      return;
    }
    config.translate(node, datum, translation, context);
  }
  createAnnotationDatumCopy(node, datum) {
    const config = this.getAnnotationConfig(datum);
    const newDatum = new config.datum();
    newDatum.set(datum.toJson());
    const context = this.getAnnotationContext();
    if (!context) {
      return;
    }
    return config.copy(node, datum, newDatum, context);
  }
  getAnnotationConfig(datum) {
    if (datum.type in annotationConfigs) {
      return annotationConfigs[datum.type];
    }
    throw new Error(
      `AG Charts - Cannot get annotation config of unknown type [${datum.type}], expected one of [${Object.keys(annotationConfigs)}], ignoring.`
    );
  }
  onRestoreAnnotations(event) {
    if (!this.enabled)
      return;
    this.clear();
    this.annotationData.set(event.annotations);
    this.postUpdateFns.push(() => {
      this.ctx.annotationManager.fireChangedEvent();
    });
    this.update();
  }
  onLayoutComplete(event) {
    if (!this.enabled)
      return;
    const seriesRect = event.series.paddedRect;
    this.seriesRect = seriesRect;
    this.container.setClipRect(seriesRect);
    this.xAxis = this.getAxis(event.axes["x" /* X */], seriesRect, this.xAxis?.button);
    this.yAxis = this.getAxis(event.axes["y" /* Y */], seriesRect, this.yAxis?.button);
    if (this.showAnnotations()) {
      this.animateAnnotations({ from: 0, to: 1, phase: "trailing" });
    } else {
      this.animateAnnotations({ from: 1, to: 0, phase: "remove" });
    }
  }
  showAnnotations() {
    if (!this.yAxis || !this.xAxis) {
      return false;
    }
    const hasData = this.ctx.chartService.series.some((s) => s.hasData);
    const seriesIds = this.yAxis.context.seriesIds();
    const anyBoundSeriesVisible = seriesIds.some((id) => {
      const series = this.ctx.chartService.series.find((s) => s.id === id);
      return series?.visible;
    });
    return hasData && anyBoundSeriesVisible;
  }
  animateAnnotations({ from: from3, to, phase }) {
    const { annotations } = this;
    this.ctx.animationManager?.animate({
      from: from3,
      to,
      id: "chart-annotations",
      phase,
      groupId: "opacity",
      onUpdate(value) {
        annotations.each((node) => {
          node.opacity = value;
          if ("setAxisLabelOpacity" in node) {
            node.setAxisLabelOpacity(value);
          }
        });
      },
      onStop() {
        annotations.each((node) => {
          node.opacity = to;
          if ("setAxisLabelOpacity" in node) {
            node.setAxisLabelOpacity(to);
          }
        });
      }
    });
  }
  onPreRender() {
    if (!this.enabled)
      return;
    this.updateAnnotations();
    this.state.transition("render");
  }
  getAxis(axisLayout, seriesRect, button) {
    const axisCtx = this.ctx.axisManager.getAxisContext(axisLayout.direction)[0];
    const { position: axisPosition = "bottom", direction } = axisCtx;
    const padding2 = axisLayout.gridPadding + axisLayout.seriesAreaPadding;
    const bounds = new BBox10(0, 0, seriesRect.width, seriesRect.height).grow(padding2, axisPosition);
    const lineDirection = direction === "x" /* X */ ? "vertical" : "horizontal";
    const { axesButtons, snap } = this;
    const buttonEnabled = this.enabled && axesButtons.enabled && (axesButtons.axes === "xy" || axesButtons.axes === direction);
    if (buttonEnabled) {
      button ?? (button = new AxisButton(
        this.ctx,
        { ...axisCtx, snapToGroup: snap },
        (coords) => this.onAxisButtonClick(coords, lineDirection),
        seriesRect
      ));
      const axisLabelPadding = calculateAxisLabelPadding(axisLayout);
      button.update(seriesRect, axisLabelPadding);
    } else {
      button?.destroy();
      button = void 0;
    }
    return { layout: axisLayout, context: axisCtx, bounds, button };
  }
  recordActionAfterNextUpdate(label, types = ["annotations"]) {
    const {
      defaults,
      ctx: { annotationManager, historyManager }
    } = this;
    const originators = types.map((type) => type === "defaults" ? defaults : annotationManager);
    this.postUpdateFns.push(() => {
      historyManager.record(label, ...originators);
      annotationManager.fireChangedEvent();
    });
  }
  setColorAndDefault(datumType, colorPickerType, colorOpacity, color2, opacity, isMultiColor) {
    this.state.transition("color", { colorPickerType, colorOpacity, color: color2, opacity, isMultiColor });
    this.defaults.setDefaultColor(datumType, colorPickerType, colorOpacity, color2, opacity, isMultiColor);
  }
  setFontSizeAndDefault(datumType, fontSize) {
    this.state.transition("fontSize", fontSize);
    this.defaults.setDefaultFontSize(datumType, fontSize);
    this.recordActionAfterNextUpdate(`Change ${datumType} font size to ${fontSize}`, ["annotations", "defaults"]);
  }
  setLineStyleTypeAndDefault(datumType, styleType) {
    this.state.transition("lineStyle", { type: styleType });
    this.defaults.setDefaultLineStyleType(datumType, styleType);
    this.recordActionAfterNextUpdate(`Change ${datumType} line style to ${styleType}`, ["annotations", "defaults"]);
  }
  setLineStyleWidthAndDefault(datumType, strokeWidth) {
    this.state.transition("lineStyle", { strokeWidth });
    this.defaults.setDefaultLineStyleWidth(datumType, strokeWidth);
    this.recordActionAfterNextUpdate(`Change ${datumType} stroke width to ${strokeWidth}`, [
      "annotations",
      "defaults"
    ]);
  }
  updateAnnotations() {
    const {
      annotationData,
      annotations,
      seriesRect,
      ctx: { annotationManager }
    } = this;
    const context = this.getAnnotationContext();
    if (!seriesRect || !context)
      return;
    annotationManager.updateData(annotationData.toJson());
    const showAnnotations = this.showAnnotations();
    this.toolbar.refreshButtonsEnabled(showAnnotations);
    this.toolbar.toggleClearButtonEnabled(annotationData.length > 0 && showAnnotations);
    annotations.update(annotationData ?? [], void 0, (datum) => datum.id).each((node, datum) => {
      if (!showAnnotations) {
        node.visible = false;
        if ("setAxisLabelVisible" in node) {
          node.setAxisLabelVisible(false);
        }
        return;
      }
      if ("setAxisLabelVisible" in node) {
        node.setAxisLabelVisible(true);
      }
      this.injectDatumDependencies(datum);
      updateAnnotation(node, datum, context);
    });
    for (const fn of this.postUpdateFns) {
      fn();
    }
    this.postUpdateFns = [];
  }
  getAnnotationContext() {
    const { seriesRect, xAxis, yAxis, snap } = this;
    if (!(seriesRect && xAxis && yAxis)) {
      return;
    }
    return {
      seriesRect,
      xAxis: {
        ...xAxis.context,
        bounds: xAxis.bounds,
        labelPadding: calculateAxisLabelPadding(xAxis.layout),
        snapToGroup: snap
      },
      yAxis: {
        ...yAxis.context,
        bounds: yAxis.bounds,
        labelPadding: calculateAxisLabelPadding(xAxis.layout),
        snapToGroup: snap
      }
    };
  }
  onHover(event) {
    const { state } = this;
    const context = this.getAnnotationContext();
    if (!context)
      return;
    const shiftKey = event.sourceEvent.shiftKey;
    const offset = vector_exports.from(event);
    const point = invertCoords(offset, context);
    state.transition("hover", { offset, point, shiftKey, context });
  }
  onClick(event) {
    const { state } = this;
    const context = this.getAnnotationContext();
    if (!context)
      return;
    const shiftKey = event.sourceEvent.shiftKey;
    const point = invertCoords(vector_exports.from(event), context);
    const textInputValue = this.textInput.getValue();
    const bbox = this.textInput.getBBox();
    state.transition("click", { point, shiftKey, textInputValue, bbox });
  }
  onDoubleClick(event) {
    const { state } = this;
    const context = this.getAnnotationContext();
    if (!context)
      return;
    const offset = vector_exports.from(event);
    state.transition("dblclick", { offset });
  }
  onAxisButtonClick(coords, direction) {
    this.cancel();
    this.reset();
    const context = this.getAnnotationContext();
    if (!this.annotationData || !context)
      return;
    const { state } = this;
    this.pushAnnotationState(InteractionState3.Annotations);
    const isHorizontal2 = direction === "horizontal";
    state.transition(isHorizontal2 ? "horizontal-line" /* HorizontalLine */ : "vertical-line" /* VerticalLine */);
    this.optionsToolbar.hide();
    if (!coords) {
      return;
    }
    const point = invertCoords(coords, context);
    if (!validateDatumPoint(context, point)) {
      return;
    }
    state.transition("click", { point, shiftKey: false });
    this.update();
  }
  onResize() {
    const textInputValue = this.textInput.getValue();
    const bbox = this.textInput.getBBox();
    this.state.transition("resize", { textInputValue, bbox });
  }
  hoverTouchPreHandler(event) {
    if (event.device === "touch") {
      this.onHover(event);
    }
  }
  dragMoveTouchPreHandler(event) {
    if (event.device === "touch" && this.ctx.interactionManager.isState(InteractionState3.AnnotationsSelected)) {
      event.sourceEvent.preventDefault();
    }
  }
  onDragStart(event) {
    if (!this.ctx.interactionManager.isState(InteractionState3.AnnotationsDraggable))
      return;
    const context = this.getAnnotationContext();
    if (!context)
      return;
    const offset = vector_exports.from(event);
    const point = invertCoords(offset, context);
    const textInputValue = this.textInput.getValue();
    const bbox = this.textInput.getBBox();
    this.state.transition("dragStart", { context, offset, point, textInputValue, bbox });
  }
  onDrag(event) {
    if (!this.ctx.interactionManager.isState(InteractionState3.AnnotationsDraggable))
      return;
    const context = this.getAnnotationContext();
    if (!context)
      return;
    const offset = vector_exports.from(event);
    const point = invertCoords(offset, context);
    const shiftKey = event.sourceEvent.shiftKey;
    const textInputValue = this.textInput.getValue();
    const bbox = this.textInput.getBBox();
    this.state.transition("drag", { context, offset, point, shiftKey, textInputValue, bbox });
  }
  onDragEnd() {
    this.state.transition("dragEnd");
  }
  onCancel(widgetEvent) {
    const { sourceEvent } = widgetEvent ?? {};
    if (sourceEvent?.currentTarget !== sourceEvent?.target)
      return;
    this.cancel();
    this.reset();
  }
  onDelete() {
    if (this.textInput.isVisible())
      return;
    this.cancel();
    this.delete();
    this.reset();
    this.update();
  }
  onTextInput(event) {
    const { state } = this;
    const context = this.getAnnotationContext();
    if (!context)
      return;
    const { key, shiftKey } = event;
    const textInputValue = this.textInput.getValue();
    const bbox = this.textInput.getBBox();
    state.transition("textInput", { key, shiftKey, textInputValue, bbox, context });
  }
  onKeyDown(event) {
    const { state } = this;
    const context = this.getAnnotationContext();
    if (!context) {
      return;
    }
    const { sourceEvent } = event;
    const { shiftKey, ctrlKey, metaKey } = sourceEvent;
    const ctrlMeta = ctrlKey || metaKey;
    const ctrlShift = ctrlKey || shiftKey;
    state.transition("keyDown", { shiftKey, context });
    const translation = { x: 0, y: 0 };
    const xStep = Math.max(context?.xAxis.scale.bandwidth ?? 0, ctrlShift ? 10 : 1);
    const yStep = Math.max(context?.yAxis.scale.bandwidth ?? 0, ctrlShift ? 10 : 1);
    switch (sourceEvent.key) {
      case "ArrowDown":
        translation.y = yStep;
        break;
      case "ArrowUp":
        translation.y = -yStep;
        break;
      case "ArrowLeft":
        translation.x = -xStep;
        break;
      case "ArrowRight":
        translation.x = xStep;
        break;
      case "Escape":
        this.onCancel();
        return;
      case "Backspace":
      case "Delete":
        this.onDelete();
        return;
    }
    if (translation.x || translation.y) {
      state.transition("translate", { translation });
      sourceEvent.stopPropagation();
      sourceEvent.preventDefault();
    }
    if (!ctrlMeta) {
      return;
    }
    switch (sourceEvent.key) {
      case "c":
        state.transition("copy");
        return;
      case "x":
        state.transition("cut");
        this.recordActionAfterNextUpdate("Cut annotation");
        return;
      case "v":
        state.transition("paste");
        this.recordActionAfterNextUpdate("Paste annotation");
        return;
    }
  }
  onKeyUp(event) {
    const { shiftKey } = event.sourceEvent;
    const context = this.getAnnotationContext();
    if (!context) {
      return;
    }
    this.state.transition("keyUp", { shiftKey, context });
    this.state.transition("translateEnd");
  }
  clear() {
    this.cancel();
    this.deleteAll();
    this.reset();
  }
  reset() {
    this.state.transition("reset");
  }
  cancel() {
    this.state.transition("cancel");
  }
  delete() {
    this.state.transition("delete");
  }
  deleteAll() {
    this.state.transition("deleteAll");
  }
  deleteEphemeralAnnotations() {
    let deletedEphemeral = false;
    for (const [index, datum] of this.annotationData.entries()) {
      if (isEphemeralType(datum)) {
        this.annotationData.splice(index, 1);
        deletedEphemeral = true;
      }
    }
    if (deletedEphemeral) {
      this.recordActionAfterNextUpdate("Delete ephemeral annotations");
    }
  }
  hideOverlays() {
    this.settingsDialog.hide();
    this.toolbar.hideOverlays();
    this.optionsToolbar.hideOverlays();
  }
  pushAnnotationState(state) {
    this.ctx.interactionManager.pushState(state);
    this.ctx.tooltipManager.suppressTooltip("annotations");
  }
  popAnnotationState(state) {
    this.ctx.interactionManager.popState(state);
    this.ctx.tooltipManager.unsuppressTooltip("annotations");
  }
  isAnnotationState() {
    return this.ctx.interactionManager.isState(InteractionState3.Annotations) || this.ctx.interactionManager.isState(InteractionState3.AnnotationsSelected);
  }
  update(status = 8 /* PRE_SCENE_RENDER */) {
    this.ctx.updateService.update(status);
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], _Annotations.prototype, "toolbar", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], _Annotations.prototype, "optionsToolbar", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], _Annotations.prototype, "axesButtons", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ObserveChanges((target, value) => {
    const enabled = value ?? true;
    target.toolbar.enabled = enabled;
    target.optionsToolbar.enabled = enabled;
    target.axesButtons.enabled = enabled;
  })
], _Annotations.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], _Annotations.prototype, "snap", 2);
var Annotations = _Annotations;

// packages/ag-charts-enterprise/src/features/annotations/annotationsTheme.ts
var stroke = {
  stroke: { $ref: "foregroundColor" },
  strokeOpacity: 1,
  strokeWidth: 2
};
var handle = {
  fill: DEFAULT_ANNOTATION_HANDLE_FILL,
  strokeOpacity: 1,
  strokeWidth: 2
};
var font = {
  color: { $ref: "chartBackgroundColor" },
  fontSize: { $rem: FONT_SIZE_RATIO.LARGE },
  fontFamily: { $ref: "fontFamily" }
};
var axisLabel = {
  ...font,
  enabled: true,
  fill: { $ref: "foregroundColor" },
  fontSize: { $ref: "fontSize" }
};
var text = {
  ...font,
  textAlign: "left"
};
var lineText = {
  ...font,
  position: "top",
  alignment: "center",
  color: { $ref: "textColor" }
};
var channelText = {
  ...font,
  position: "top",
  alignment: "center",
  color: { $ref: "textColor" }
};
var measurerStatistics = {
  ...font,
  fontSize: { $ref: "fontSize" },
  color: DEFAULT_ANNOTATION_STATISTICS_COLOR,
  fill: DEFAULT_ANNOTATION_STATISTICS_FILL,
  stroke: DEFAULT_ANNOTATION_STATISTICS_STROKE,
  strokeWidth: 1,
  divider: {
    stroke: DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE,
    strokeWidth: 1,
    strokeOpacity: 0.5
  }
};
var measurer = {
  ...stroke,
  background: {
    fill: { $ref: "foregroundColor" },
    fillOpacity: 0.075
  },
  handle: { ...handle },
  text: { ...lineText },
  statistics: { ...measurerStatistics }
};
var toolbar = {
  buttons: {
    $shallowSimple: [
      {
        icon: "text-annotation",
        tooltip: "toolbarAnnotationsTextAnnotations",
        value: "text-menu"
      },
      {
        icon: "trend-line-drawing",
        tooltip: "toolbarAnnotationsLineAnnotations",
        value: "line-menu"
      },
      {
        icon: "arrow-drawing",
        tooltip: "toolbarAnnotationsShapeAnnotations",
        value: "shape-menu"
      },
      {
        icon: "delete",
        tooltip: "toolbarAnnotationsClearAll",
        value: "clear"
      }
    ]
  },
  padding: { $ref: "chartPadding" }
};
var optionsToolbar = {
  buttons: {
    $shallowSimple: [
      {
        icon: "text-annotation",
        tooltip: "toolbarAnnotationsTextColor",
        value: "text-color"
      },
      {
        icon: "line-color",
        tooltip: "toolbarAnnotationsLineColor",
        value: "line-color"
      },
      {
        icon: "fill-color",
        tooltip: "toolbarAnnotationsFillColor",
        value: "fill-color"
      },
      {
        tooltip: "toolbarAnnotationsTextSize",
        value: "text-size"
      },
      {
        tooltip: "toolbarAnnotationsLineStrokeWidth",
        value: "line-stroke-width"
      },
      {
        icon: "line-style-solid",
        tooltip: "toolbarAnnotationsLineStyle",
        value: "line-style-type"
      },
      {
        icon: "settings",
        tooltip: "toolbarAnnotationsSettings",
        value: "settings"
      },
      {
        icon: "unlocked",
        tooltip: "toolbarAnnotationsLock",
        ariaLabel: "toolbarAnnotationsLock",
        checkedOverrides: {
          icon: "locked",
          tooltip: "toolbarAnnotationsUnlock"
        },
        value: "lock"
      },
      {
        icon: "delete",
        tooltip: "toolbarAnnotationsDelete",
        value: "delete"
      }
    ]
  }
};
var annotationsTheme = {
  enabled: false,
  // Lines
  line: {
    ...stroke,
    handle: { ...handle },
    text: { ...lineText }
  },
  "horizontal-line": {
    ...stroke,
    handle: { ...handle },
    axisLabel: { ...axisLabel },
    text: { ...lineText }
  },
  "vertical-line": {
    ...stroke,
    handle: { ...handle },
    axisLabel: { ...axisLabel },
    text: { ...lineText }
  },
  // Channels
  "disjoint-channel": {
    ...stroke,
    background: {
      fill: { $ref: "foregroundColor" },
      fillOpacity: 0.075
    },
    handle: { ...handle },
    text: { ...channelText }
  },
  "parallel-channel": {
    ...stroke,
    middle: {
      lineDash: [6, 5],
      strokeWidth: 1
    },
    background: {
      fill: { $ref: "foregroundColor" },
      fillOpacity: 0.075
    },
    handle: { ...handle },
    text: { ...channelText }
  },
  // Fibonnaccis
  "fibonacci-retracement": {
    ...stroke,
    strokes: DEFAULT_FIBONACCI_STROKES,
    rangeStroke: { $ref: "foregroundColor" },
    handle: { ...handle },
    text: { ...lineText, position: "center" },
    label: {
      ...font,
      color: void 0,
      fontSize: { $rem: FONT_SIZE_RATIO.SMALLER }
    }
  },
  "fibonacci-retracement-trend-based": {
    ...stroke,
    strokes: DEFAULT_FIBONACCI_STROKES,
    rangeStroke: { $ref: "foregroundColor" },
    handle: { ...handle },
    text: { ...lineText, position: "center" },
    label: {
      ...font,
      color: void 0,
      fontSize: { $rem: FONT_SIZE_RATIO.SMALLER }
    }
  },
  // Texts
  callout: {
    ...stroke,
    ...text,
    color: { $ref: "textColor" },
    handle: { ...handle },
    fill: { $ref: "foregroundColor" },
    fillOpacity: 0.075
  },
  comment: {
    ...text,
    fontWeight: 700,
    handle: { ...handle },
    fill: { $ref: "foregroundColor" }
  },
  note: {
    ...text,
    color: DEFAULT_TEXTBOX_COLOR,
    fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR,
    stroke: { $ref: "chartBackgroundColor" },
    strokeWidth: 1,
    strokeOpacity: 1,
    handle: { ...handle },
    background: {
      fill: DEFAULT_TEXTBOX_FILL,
      stroke: DEFAULT_TEXTBOX_STROKE,
      strokeWidth: 1
    }
  },
  text: {
    ...text,
    color: { $ref: "textColor" },
    handle: { ...handle }
  },
  // Shapes
  arrow: {
    ...stroke,
    handle: { ...handle },
    text: { ...lineText }
  },
  "arrow-up": {
    fill: { $palette: "up.fill" },
    handle: { ...handle, stroke: { $ref: "foregroundColor" } }
  },
  "arrow-down": {
    fill: { $palette: "down.fill" },
    handle: { ...handle, stroke: { $ref: "foregroundColor" } }
  },
  // Measurers
  "date-range": {
    ...measurer
  },
  "price-range": {
    ...measurer
  },
  "date-price-range": {
    ...measurer
  },
  "quick-date-price-range": {
    up: {
      ...stroke,
      fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL,
      fillOpacity: 0.2,
      handle: { ...handle },
      statistics: {
        ...measurerStatistics,
        color: "#fff",
        fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL,
        strokeWidth: 0,
        divider: {
          stroke: "#fff",
          strokeWidth: 1,
          strokeOpacity: 0.5
        }
      }
    },
    down: {
      ...stroke,
      stroke: DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE,
      fill: DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL,
      fillOpacity: 0.2,
      handle: {
        ...handle,
        stroke: DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE
      },
      statistics: {
        ...measurerStatistics,
        color: "#fff",
        fill: DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL,
        strokeWidth: 0,
        divider: {
          stroke: "#fff",
          strokeWidth: 1,
          strokeOpacity: 0.5
        }
      }
    }
  },
  axesButtons: {},
  // Toolbars
  toolbar,
  optionsToolbar
};

// packages/ag-charts-enterprise/src/features/annotations/annotationsModule.ts
var AnnotationsModule = {
  type: "plugin",
  name: "annotations",
  chartType: "cartesian",
  enterprise: true,
  version: VERSION,
  options: module_support_exports.annotationOptionsDef,
  themeTemplate: annotationsTheme,
  create: (ctx) => new Annotations(ctx),
  patchContext: (ctx) => {
    if (ctx.sharedToolbar)
      return;
    ctx.sharedToolbar = new SharedToolbar(ctx);
    ctx.cleanup.register(() => ctx.sharedToolbar.destroy());
  }
};

// packages/ag-charts-enterprise/src/features/band-highlight/bandHighlight.ts
var {
  Range: Range2,
  TranslatableGroup: TranslatableGroup2,
  BBox: BBox11,
  FillGradientDefaults: FillGradientDefaults4,
  FillImageDefaults: FillImageDefaults4,
  FillPatternDefaults: FillPatternDefaults4,
  getShapeFill: getShapeFill2,
  InteractionState: InteractionState4
} = module_support_exports;
var BandHighlight = class extends AbstractModuleInstance {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.id = createId(this);
    this.enabled = false;
    this.stroke = "rgb(195, 195, 195)";
    this.lineDash = [6, 3];
    this.lineDashOffset = 0;
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.fill = "#c16068";
    this.fillOpacity = 1;
    this.fillGradientDefaults = new FillGradientDefaults4();
    this.fillPatternDefaults = new FillPatternDefaults4();
    this.fillImageDefaults = new FillImageDefaults4();
    this.bounds = new BBox11(0, 0, 0, 0);
    this.bandHighlightGroup = new TranslatableGroup2({
      name: "bandHighlight",
      zIndex: 1 /* AXIS_BAND_HIGHLIGHT */
    });
    this.rangeNode = this.bandHighlightGroup.appendChild(new Range2());
    this.activeAxisHighlight = void 0;
    this.axisCtx = ctx.parent;
    this.hideBand();
    ctx.domManager.addEventListener("focusin", ({ target }) => {
      const isSeriesAreaChild = target instanceof HTMLElement && ctx.domManager.contains(target, "series-area");
      if (this.bandHighlightGroup.visible && !isSeriesAreaChild) {
        this.hideBand();
        this.ctx.updateService.update(9 /* SCENE_RENDER */);
      }
    });
    const {
      widgets: { seriesWidget, seriesDragInterpreter },
      animationManager,
      eventsHub
    } = ctx;
    this.cleanup.register(
      ctx.scene.attachNode(this.bandHighlightGroup),
      seriesWidget.addListener("mousemove", (event) => this.onHoverLikeEvent(event)),
      seriesWidget.addListener("mouseleave", () => this.clearAllHighlight()),
      animationManager.addListener("animation-start", () => this.clearAllHighlight()),
      eventsHub.on("layout:complete", (event) => this.layout(event)),
      eventsHub.on("series:focus-change", () => this.onKeyPress()),
      eventsHub.on("zoom:pan-start", () => this.clearAllHighlight()),
      eventsHub.on("zoom:change-complete", () => this.clearAllHighlight()),
      eventsHub.on("dom:resize", () => this.clearAllHighlight()),
      eventsHub.on("axis:change", () => this.axisChange())
    );
    if (seriesDragInterpreter) {
      this.cleanup.register(
        seriesDragInterpreter.events.on("drag-move", (event) => this.onHoverLikeEvent(event)),
        seriesDragInterpreter.events.on("click", (event) => this.onClick(event))
      );
    }
  }
  axisChange() {
    this.onHighlightChange();
  }
  isHover(event) {
    return event.type === "mousemove" || event.type === "click" || event.device === "touch" && this.ctx.chartService.touch.dragAction === "hover";
  }
  onClick(event) {
    if (event.device === "touch") {
      this.onHoverLikeEvent(event);
    }
  }
  clearAllHighlight() {
    if (!this.ctx.interactionManager.isState(InteractionState4.Clickable))
      return;
    this.onHighlightChange();
  }
  onKeyPress() {
    if (this.ctx.interactionManager.isState(InteractionState4.Default)) {
      this.onHighlightChange();
    }
  }
  onHoverLikeEvent(event) {
    const requiredState = this.isHover(event) ? InteractionState4.Clickable : InteractionState4.AnnotationsMoveable;
    if (!this.ctx.interactionManager.isState(requiredState))
      return;
    this.handleHoverHighlight(event);
  }
  handleHoverHighlight(event) {
    if (!event)
      return;
    const { currentX: x, currentY: y } = event;
    this.onHighlightChange(this.axisCtx.pickBand({ x, y }));
  }
  layout({ series: { rect: rect2, visible }, axes }) {
    if (!visible || !axes || !this.enabled)
      return;
    const { position: axisPosition = "left", axisId } = this.axisCtx;
    const axisLayout = axes[axisId];
    if (!axisLayout)
      return;
    this.axisLayout = axisLayout;
    this.bounds = rect2.clone().grow(axisLayout.gridPadding, axisPosition);
    const { bandHighlightGroup, bounds } = this;
    bandHighlightGroup.translationX = Math.round(bounds.x);
    bandHighlightGroup.translationY = Math.round(bounds.y);
    this.updateBand();
  }
  updateBand() {
    const {
      rangeNode: node,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      fill,
      fillOpacity,
      fillGradientDefaults: fillGradientDefaults3,
      fillPatternDefaults: fillPatternDefaults3,
      fillImageDefaults: fillImageDefaults3,
      lineDashOffset,
      axisLayout
    } = this;
    if (!axisLayout)
      return;
    node.stroke = stroke3;
    node.strokeWidth = strokeWidth;
    node.strokeOpacity = strokeOpacity;
    node.lineDash = lineDash;
    node.lineDashOffset = lineDashOffset;
    node.fill = getShapeFill2(fill, fillGradientDefaults3, fillPatternDefaults3, fillImageDefaults3);
    node.fillOpacity = fillOpacity;
    node.startLine = true;
    node.endLine = true;
  }
  isVertical() {
    return this.axisCtx.direction === "x" /* X */;
  }
  onHighlightChange(axisBandDatum) {
    if (!this.enabled)
      return;
    this.activeAxisHighlight = axisBandDatum;
    if (this.activeAxisHighlight) {
      this.showBand();
    } else {
      this.hideBand();
    }
    this.ctx.updateService.update(9 /* SCENE_RENDER */);
  }
  updateBandPosition() {
    const { rangeNode, bounds } = this;
    const { band } = this.activeAxisHighlight ?? {};
    if (band == void 0) {
      this.hideBand();
      return;
    }
    let r0 = Math.min(...band);
    let r1 = Math.max(...band);
    if (r1 - r0 < 1) {
      const mid = (r0 + r1) / 2;
      r0 = mid - 0.5;
      r1 = mid + 0.5;
    }
    if (this.isVertical()) {
      rangeNode.y1 = 0;
      rangeNode.y2 = bounds.height;
      rangeNode.x1 = r0;
      rangeNode.x2 = r1;
      rangeNode.horizontal = true;
    } else {
      rangeNode.y1 = r0;
      rangeNode.y2 = r1;
      rangeNode.x1 = 0;
      rangeNode.x2 = bounds.width;
      rangeNode.horizontal = false;
    }
  }
  showBand() {
    this.updateBandPosition();
    this.bandHighlightGroup.visible = true;
  }
  hideBand() {
    this.bandHighlightGroup.visible = false;
  }
};
BandHighlight.className = "BandHighlight";
__decorateClass([
  addFakeTransformToInstanceProperty
], BandHighlight.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BandHighlight.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BandHighlight.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BandHighlight.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BandHighlight.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BandHighlight.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BandHighlight.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BandHighlight.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BandHighlight.prototype, "fillGradientDefaults", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BandHighlight.prototype, "fillPatternDefaults", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BandHighlight.prototype, "fillImageDefaults", 2);

// packages/ag-charts-enterprise/src/features/band-highlight/bandHighlightModule.ts
var BandHighlightModule = {
  type: "axis:plugin",
  name: "bandHighlight",
  chartType: "cartesian",
  axisTypes: ["category", "ordinal-time", "unit-time", "grouped-category"],
  enterprise: true,
  version: VERSION,
  themeTemplate: {
    enabled: false,
    strokeWidth: 0,
    lineDash: [],
    fill: { $foregroundBackgroundMix: 0.05 }
  },
  create: (ctx) => new BandHighlight(ctx)
};

// packages/ag-charts-enterprise/src/features/chart-toolbar/chartToolbar.ts
var { LayoutElement: LayoutElement3, Menu: Menu4 } = module_support_exports;
var menuItems = [
  { label: "toolbarSeriesTypeOHLC", icon: "ohlc-series", value: "ohlc" },
  { label: "toolbarSeriesTypeCandles", icon: "candlestick-series", value: "candlestick" },
  { label: "toolbarSeriesTypeHollowCandles", icon: "hollow-candlestick-series", value: "hollow-candlestick" },
  { label: "toolbarSeriesTypeLine", icon: "line-series", value: "line" },
  { label: "toolbarSeriesTypeStepLine", icon: "step-line-series", value: "step-line" },
  { label: "toolbarSeriesTypeHLC", icon: "hlc-series", value: "hlc" },
  { label: "toolbarSeriesTypeHighLow", icon: "high-low-series", value: "high-low" }
];
var ChartToolbar = class extends AbstractModuleInstance {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.enabled = false;
    this.menu = new Menu4(this.ctx, "chart-toolbar");
    this.toolbar = ctx.sharedToolbar.getSharedToolbar("chartToolbar");
    this.cleanup.register(
      this.toolbar.addToolbarListener("button-pressed", this.onButtonPressed.bind(this)),
      ctx.layoutManager.registerElement(LayoutElement3.ToolbarLeft, this.onLayoutStart.bind(this)),
      () => this.toolbar.destroy()
    );
  }
  onLayoutStart(ctx) {
    if (!this.enabled)
      return;
    this.updateButton();
    this.toolbar.layout(ctx.layoutBox);
  }
  onButtonPressed({ event, buttonBounds, buttonWidget }) {
    this.menu.setAnchor({ x: buttonBounds.x + buttonBounds.width + 6, y: buttonBounds.y });
    this.menu.show(buttonWidget, {
      items: menuItems,
      menuItemRole: "menuitemradio",
      ariaLabel: this.ctx.localeManager.t("toolbarSeriesTypeDropdown"),
      class: "ag-charts-chart-toolbar__menu",
      value: this.getChartType(),
      sourceEvent: event.sourceEvent,
      onPress: (item) => {
        this.setChartType(item.value);
        this.hidePopover();
      },
      onHide: () => {
        this.toolbar.clearActiveButton();
      }
    });
    this.toolbar.toggleActiveButtonByIndex(0);
  }
  updateButton() {
    const chartType = this.getChartType();
    const icon = menuItems.find((item) => item.value === chartType)?.icon;
    if (icon != null) {
      this.toolbar.updateButtons([{ icon, tooltip: "toolbarSeriesTypeDropdown", value: "menu" }]);
    }
  }
  hidePopover() {
    this.toolbar.clearActiveButton();
    this.menu.hide();
  }
  setChartType(chartType) {
    const options = { chartType };
    this.ctx.chartService.publicApi?.updateDelta(options).catch((e) => logger_exports.error(e));
  }
  getChartType() {
    const chartType = this.ctx.chartService.publicApi?.getOptions()?.chartType;
    if (chartType == null || !menuItems.some((item) => item.value === chartType)) {
      return "candlestick";
    }
    return chartType;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty,
  ActionOnSet({
    changeValue(enabled) {
      this.toolbar?.setHidden(!enabled);
    }
  })
], ChartToolbar.prototype, "enabled", 2);

// packages/ag-charts-enterprise/src/features/chart-toolbar/chartToolbarModule.ts
var ChartToolbarModule = {
  type: "plugin",
  name: "chartToolbar",
  chartType: "cartesian",
  enterprise: true,
  version: VERSION,
  options: {
    enabled: boolean
  },
  create: (ctx) => new ChartToolbar(ctx),
  patchContext: (ctx) => {
    if (ctx.sharedToolbar)
      return;
    ctx.sharedToolbar = new SharedToolbar(ctx);
    ctx.cleanup.register(() => ctx.sharedToolbar.destroy());
  }
};

// packages/ag-charts-enterprise/src/features/context-menu/contextMenuItem.ts
function showsFor(showOn, showing) {
  if (showOn === "always")
    return true;
  if (showOn === "series-area")
    return showing === "series-area" || showing === "series-node";
  return showOn === showing;
}
function appendItem(showing, item, result) {
  let mustShow = true;
  if (item.type === "separator") {
    const last = result.at(-1);
    mustShow = last !== void 0 && last.type !== "separator";
  }
  mustShow && (mustShow = showsFor(item.showOn ?? "always", showing));
  if (mustShow) {
    const menuItem = new ContextMenuItem(item);
    result.push(menuItem);
    return menuItem;
  }
}
function appendBuiltinItem(showing, registry, keyword, result) {
  if (registry.isVisible(keyword)) {
    appendItem(showing, registry.builtins.items[keyword], result);
  }
}
function expandBuiltin(showing, registry, keyword, result) {
  const { builtins } = registry;
  if (isKeyOf(keyword, builtins.lists)) {
    for (const childKeyword of builtins.lists[keyword]) {
      appendBuiltinItem(showing, registry, childKeyword, result);
    }
  } else {
    appendBuiltinItem(showing, registry, keyword, result);
  }
}
function expandBuiltinLists(showing, items, registry) {
  const unfiltered = [];
  const { builtins } = registry;
  for (const it of items) {
    if (typeof it === "string" && isKeyOf(it, builtins.lists)) {
      for (const listItem of builtins.lists[it]) {
        unfiltered.push(listItem);
      }
    } else {
      unfiltered.push(it);
    }
  }
  return unfiltered.filter((it) => {
    if (typeof it === "string") {
      const showOn = registry.builtins.items[it].showOn ?? "always";
      return registry.isVisible(it) && showsFor(showOn, showing);
    } else {
      return showsFor(it.showOn ?? "always", showing);
    }
  });
}
function expandItems(showing, registry, items, result) {
  for (const item of items) {
    if (typeof item === "string") {
      expandBuiltin(showing, registry, item, result);
    } else {
      const menuItem = appendItem(showing, item, result);
      if (item.items && menuItem && item.items.length > 0) {
        expandItems(showing, registry, item.items, menuItem.items);
      }
    }
  }
  if (result.at(-1)?.type === "separator") {
    result.pop();
  }
}
var ContextMenuItem = class {
  constructor(options) {
    this.type = "action";
    this.showOn = "always";
    this.label = "";
    this.iconUrl = void 0;
    this.enabled = true;
    this.items = [];
    this.action = void 0;
    if (options)
      this.setOptions(options);
    this.items = [];
  }
  setField(key, that, value) {
    that[key] = value;
  }
  setOptions(options) {
    let key;
    for (key in options) {
      if (options[key] !== void 0) {
        this.setField(key, this, options[key]);
      }
    }
  }
};

// packages/ag-charts-enterprise/src/features/context-menu/contextMenuStyles.ts
var DEFAULT_CONTEXT_MENU_CLASS = "ag-charts-context-menu";

// packages/ag-charts-enterprise/src/features/context-menu/contextMenu.ts
var { ContextMenuRegistry: ContextMenuRegistry2 } = module_support_exports;
var moduleId2 = "context-menu";
var DATUM_KEYS = [
  "angleKey",
  "calloutLabelKey",
  "colorKey",
  "labelKey",
  "radiusKey",
  "sectorLabelKey",
  "sizeKey",
  "xKey",
  "yKey"
];
var ContextMenu = class extends AbstractModuleInstance {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.enabled = true;
    this.darkTheme = false;
    this.items = ["defaults"];
    // State
    this.pickedNode = void 0;
    this.showEvent = void 0;
    this.x = 0;
    this.y = 0;
    this.collapsingSubMenus = 0;
    this.menuWidget = new exports_exports.MenuWidget();
    this.interactionManager = ctx.interactionManager;
    this.element = ctx.domManager.addChild("canvas-overlay", moduleId2);
    this.element.classList.add(DEFAULT_CONTEXT_MENU_CLASS);
    this.element.style.display = "none";
    this.element.addEventListener("contextmenu", (event) => event.preventDefault());
    this.element.addEventListener("focusout", ({ relatedTarget }) => {
      if (this.collapsingSubMenus > 0)
        return;
      if (relatedTarget == null || relatedTarget instanceof Node && !this.element.contains(relatedTarget)) {
        this.hide();
      }
    });
    this.cleanup.register(
      () => this.element.remove(),
      () => this.menuWidget.destroy(),
      ctx.eventsHub.on("dom:hidden", () => this.hide()),
      this.menuWidget.addListener("collapse-widget", () => this.onCollapse())
    );
    this.menuWidget.addClass(`${DEFAULT_CONTEXT_MENU_CLASS}__menu`);
    if (typeof MutationObserver !== "undefined") {
      const observer = new MutationObserver(() => {
        if (this.element.contains(this.menuWidget.getElement())) {
          this.reposition();
        }
      });
      observer.observe(this.element, { childList: true });
      this.mutationObserver = observer;
      this.cleanup.register(() => observer.disconnect());
    }
    this.ctx.contextMenuRegistry.builtins.items["download"].action = () => {
      const title = ctx.chartService.title;
      let fileName = "image";
      if (title?.enabled) {
        fileName = title.node.getPlainText().replace(/\.+/, "");
      }
      this.ctx.chartService.publicApi?.download({ fileName }).catch((e) => {
        logger_exports.error("Unable to download chart", e);
      });
    };
    this.cleanup.register(this.ctx.eventsHub.on("context-menu:complete", (e) => this.onContext(e)));
  }
  makeGetItemsParams(event) {
    const { showOn } = event;
    const { context } = this.ctx.chartService;
    const defaultItems = expandBuiltinLists(showOn, this.items, this.ctx.contextMenuRegistry);
    switch (showOn) {
      case "always":
      case "series-area":
        return { showOn, context, defaultItems };
      case "series-node": {
        if (this.pickedNode == null)
          throw new Error(`this.pickedNode is null`);
        const params = {
          showOn,
          context,
          seriesId: this.pickedNode.series.id,
          datum: this.pickedNode.datum,
          defaultItems
        };
        for (const k of DATUM_KEYS) {
          if (this.pickedNode[k] !== void 0) {
            params[k] = this.pickedNode[k];
          }
        }
        return params;
      }
      case "legend-item":
        if (this.pickedLegendItem == null)
          throw new Error(`this.pickedLegendItem is null`);
        const { itemId, seriesId, label, enabled } = this.pickedLegendItem;
        const text2 = toPlainText(label.text);
        if (typeof itemId !== "string") {
          throw new Error(`unexpected itemId type: [${typeof itemId}] (expected [string])`);
        }
        return { showOn, context, itemId, seriesId, text: text2, visible: enabled, defaultItems };
      default:
        return showOn;
    }
  }
  expandItemsOptions(event) {
    const result = [];
    let items;
    if (this.getItems) {
      const cbParams = this.makeGetItemsParams(event);
      items = this.getItems(cbParams);
    }
    items ?? (items = this.items);
    expandItems(event.showOn, this.ctx.contextMenuRegistry, items, result);
    return result;
  }
  onContext(event) {
    if (!this.enabled)
      return;
    event.widgetEvent.sourceEvent.preventDefault();
    this.showEvent = event.widgetEvent.sourceEvent;
    this.x = event.x;
    this.y = event.y;
    this.pickedNode = void 0;
    this.pickedLegendItem = void 0;
    if (ContextMenuRegistry2.check("series-node", event)) {
      this.pickedNode = event.context.pickedNode;
    } else if (ContextMenuRegistry2.check("legend-item", event)) {
      this.pickedLegendItem = event.context.legendItem;
    }
    const expandedItems = this.expandItemsOptions(event);
    if (expandedItems.length === 0)
      return;
    this.show(event.widgetEvent, expandedItems);
  }
  show(widgetEvent, expandedItems) {
    const { sourceEvent } = widgetEvent;
    this.interactionManager.pushState(module_support_exports.InteractionState.ContextMenu);
    this.element.style.display = "block";
    const overrideFocusVisible = sourceEvent.pointerType === "touch" ? false : void 0;
    if (overrideFocusVisible !== void 0) {
      this.ctx.chartService.overrideFocusVisible(overrideFocusVisible);
    }
    this.createMenu(expandedItems);
    this.element.appendChild(this.menuWidget.getElement());
    this.menuWidget.expand({ sourceEvent, overrideFocusVisible });
  }
  hide() {
    this.menuWidget.collapse();
  }
  onCollapse() {
    this.interactionManager.popState(module_support_exports.InteractionState.ContextMenu);
    this.menuWidget.getElement().remove();
    this.element.style.display = "none";
  }
  onSubMenuExpand(button, menu) {
    const bounds = button.getBounds();
    button.setFocusOverride(true);
    button.getElement().insertAdjacentElement("afterend", menu.getElement());
    menu.getElement().style.position = "absolute";
    const canvasRect = this.ctx.domManager.getBoundingClientRect();
    const buttonClientRect = button.getBoundingClientRect();
    const remainingSpaceOnRight = canvasRect.right - buttonClientRect.right;
    const remainingSpaceOnLeft = buttonClientRect.left - canvasRect.left;
    const { offsetWidth: menuOffsetWidth, offsetHeight: menuOffsetHeight } = menu.getElement();
    let y = bounds.y;
    if (canvasRect.height > menuOffsetHeight) {
      const remainingSpaceOnBottom = canvasRect.bottom - buttonClientRect.top;
      if (remainingSpaceOnBottom < menuOffsetHeight) {
        y -= menuOffsetHeight - remainingSpaceOnBottom;
      }
    }
    if (remainingSpaceOnRight >= menuOffsetWidth) {
      menu.setBounds({ x: bounds.x + bounds.width, y });
    } else {
      const x = bounds.x - menuOffsetWidth;
      const leftDelta = remainingSpaceOnLeft + x;
      if (leftDelta >= 0) {
        menu.setBounds({ x, y });
      } else {
        menu.setBounds({ x: x - leftDelta, y });
      }
    }
  }
  onSubMenuCollapse(button, menu) {
    button.setFocusOverride(void 0);
    this.collapsingSubMenus++;
    menu.remove();
    this.collapsingSubMenus--;
  }
  createMenu(expandedItems) {
    const { menuWidget } = this;
    menuWidget.clear();
    menuWidget.setTabIndex(-1);
    this.createMenuItems(menuWidget, expandedItems);
  }
  createMenuItems(menuWidget, expandedItems) {
    for (const item of expandedItems) {
      switch (item.type) {
        case "separator": {
          const sep = menuWidget.addSeparator();
          sep.classList.add(`${DEFAULT_CONTEXT_MENU_CLASS}__divider`);
          break;
        }
        case "action": {
          if (item.items.length === 0) {
            const btn = new exports_exports.MenuItemWidget();
            this.initButtonElement(btn, item);
            menuWidget.addChild(btn);
          } else {
            const { subMenuButton, subMenu } = menuWidget.addSubMenu();
            subMenu.addClass(`${DEFAULT_CONTEXT_MENU_CLASS}__menu`);
            subMenu.addListener("expand-widget", () => this.onSubMenuExpand(subMenuButton, subMenu));
            subMenu.addListener("collapse-widget", () => this.onSubMenuCollapse(subMenuButton, subMenu));
            this.initButtonElement(subMenuButton, item);
            this.createMenuItems(subMenu, item.items);
          }
          break;
        }
        default:
          throw new Error("unhandled case");
      }
    }
  }
  createButtonOnClick(showOn, callback2) {
    if (ContextMenuRegistry2.checkCallback("legend-item", showOn, callback2)) {
      return (widgetEvent) => {
        const event = widgetEvent.sourceEvent;
        if (this.pickedLegendItem) {
          const { seriesId, itemId, label } = this.pickedLegendItem;
          const { chartService: chart } = this.ctx;
          if (typeof itemId !== "string") {
            logger_exports.error(`unexpected itemId type: [${typeof itemId}] (expected [string])`);
            return;
          }
          const series = chart.series.find((s) => s.id === seriesId);
          const callers = [series?.properties, chart];
          const apiEvent = {
            type: "contextmenu",
            seriesId,
            itemId,
            text: toPlainText(label.text),
            event
          };
          callWithContext(callers, callback2, apiEvent);
          this.hide();
        } else {
          logger_exports.error("legend item not found");
        }
      };
    } else if (ContextMenuRegistry2.checkCallback("series-area", showOn, callback2)) {
      return () => {
        const caller = this.ctx.chartService;
        const apiEvent = { type: "seriesContextMenuAction", event: this.showEvent };
        callWithContext(caller, callback2, apiEvent);
        this.hide();
      };
    } else if (ContextMenuRegistry2.checkCallback("series-node", showOn, callback2)) {
      return () => {
        const { showEvent } = this;
        const { chartService: chart } = this.ctx;
        const pickedNode = this.pickedNode;
        const callers = [pickedNode?.series.properties, chart];
        const apiEvent = pickedNode?.series.createNodeContextMenuActionEvent(showEvent, pickedNode);
        if (apiEvent) {
          callWithContext(callers, callback2, apiEvent);
        } else {
          logger_exports.error("series node not found");
        }
        this.hide();
      };
    }
    return () => {
      const caller = this.ctx.chartService;
      const apiEvent = { type: "contextMenuEvent", event: this.showEvent };
      callWithContext(caller, callback2, apiEvent);
      this.hide();
    };
  }
  initTableCells(elem) {
    const cellIcon = createElement("div");
    const cellLabel = createElement("div");
    const cellArrow = createElement("div");
    cellIcon.classList.toggle(`${DEFAULT_CONTEXT_MENU_CLASS}__icon`, true);
    cellLabel.classList.toggle(`${DEFAULT_CONTEXT_MENU_CLASS}__cell`, true);
    cellArrow.classList.toggle(`${DEFAULT_CONTEXT_MENU_CLASS}__cell`, true);
    cellIcon.ariaHidden = "true";
    cellLabel.role = "presentation";
    cellArrow.ariaHidden = "true";
    elem.append(cellIcon, cellLabel, cellArrow);
    return { cellIcon, cellLabel, cellArrow };
  }
  initButtonElement(button, item) {
    button.addClass(`${DEFAULT_CONTEXT_MENU_CLASS}__item`);
    button.setEnabled(item.enabled);
    const label = this.ctx.localeManager.t(item.label);
    const cellPaddingClass = `${DEFAULT_CONTEXT_MENU_CLASS}__cellpadding`;
    const { cellIcon, cellLabel, cellArrow } = this.initTableCells(button.getElement());
    cellLabel.textContent = label;
    cellLabel.classList.add(cellPaddingClass);
    if (item.iconUrl != null) {
      const img = createElement("img");
      img.src = item.iconUrl;
      cellIcon.append(img);
      cellIcon.classList.add(cellPaddingClass);
    }
    if (item.items.length > 0) {
      const span = createElement("span", getIconClassNames("chevron-right"));
      cellArrow.append(span);
      cellArrow.classList.add(cellPaddingClass);
    }
    const { showOn, action } = item;
    if (action != null) {
      button.addListener("click", this.createButtonOnClick(showOn, action));
    }
    if (item.items.length === 0) {
      button.addListener("mouseleave", () => button.setFocusOverride(false));
      button.addListener("mouseenter", () => button.setFocusOverride(void 0));
    }
  }
  reposition() {
    let { x, y } = this;
    this.element.style.top = "unset";
    this.element.style.bottom = "unset";
    const canvasRect = this.ctx.domManager.getBoundingClientRect();
    const { offsetWidth: width2, offsetHeight: height2 } = this.element;
    x = clamp(0, x, canvasRect.width - width2);
    y = clamp(0, y, canvasRect.height - height2);
    this.element.style.left = `${x}px`;
    this.element.style.top = `calc(${y}px - 0.5em)`;
  }
  destroy() {
    super.destroy();
    this.mutationObserver?.disconnect();
    this.ctx.domManager.removeStyles(moduleId2);
    this.ctx.domManager.removeChild("canvas-overlay", moduleId2);
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ContextMenu.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ContextMenu.prototype, "darkTheme", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ContextMenu.prototype, "items", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ContextMenu.prototype, "getItems", 2);

// packages/ag-charts-enterprise/src/features/context-menu/contextMenuModule.ts
var ContextMenuModule = {
  type: "plugin",
  name: "contextMenu",
  enterprise: true,
  version: VERSION,
  options: {
    enabled: boolean,
    items: contextMenuItemsArray,
    getItems: callbackOf(contextMenuItemsArray, "a menu items array")
  },
  themeTemplate: {
    enabled: true,
    darkTheme: IS_DARK_THEME
  },
  create: (ctx) => new ContextMenu(ctx)
};
ContextMenuModule.options.darkTheme = undocumented(boolean);

// packages/ag-charts-enterprise/src/utils/datum.ts
function readDatum(nodeDatum) {
  if (typeof nodeDatum?.datum === "object") {
    return nodeDatum.datum;
  }
  return null;
}

// packages/ag-charts-enterprise/src/features/crosshair/crosshairLabel.ts
var { FormatManager: FormatManager2 } = module_support_exports;
var DEFAULT_LABEL_CLASS = "ag-charts-crosshair-label";
var CrosshairLabelProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = true;
    this.xOffset = 0;
    this.yOffset = 0;
    this.format = void 0;
    this.renderer = void 0;
    this._cachedFormatter = void 0;
  }
  formatValue(callWithContext2, type, value, params) {
    const { formatter: formatter2, format } = this;
    const { domain, boundSeries } = params;
    let result;
    if (formatter2 != null) {
      const fractionDigits = params.type === "number" ? params.fractionDigits : void 0;
      const unit = params.type === "date" ? params.unit : void 0;
      const step = params.type === "date" ? params.step : void 0;
      result = callWithContext2(formatter2, { value, domain, fractionDigits, unit, step, boundSeries });
    }
    if (format != null) {
      let cachedFormatter = this._cachedFormatter;
      if (cachedFormatter?.type !== type || cachedFormatter?.format !== format) {
        cachedFormatter = {
          type,
          format,
          formatter: FormatManager2.getFormatter(type, format)
        };
        this._cachedFormatter = cachedFormatter;
      }
      result ?? (result = cachedFormatter.formatter?.(value));
    }
    return result == null ? void 0 : String(result);
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], CrosshairLabelProperties.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CrosshairLabelProperties.prototype, "xOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CrosshairLabelProperties.prototype, "yOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CrosshairLabelProperties.prototype, "formatter", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CrosshairLabelProperties.prototype, "format", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CrosshairLabelProperties.prototype, "renderer", 2);
var CrosshairLabel = class extends CrosshairLabelProperties {
  constructor(domManager, key, axisId) {
    super();
    this.domManager = domManager;
    this.id = createId(this);
    this.element = domManager.addChild("canvas-overlay", `crosshair-label-${this.id}`);
    this.element.classList.add(DEFAULT_LABEL_CLASS);
    setAttribute(this.element, "aria-hidden", true);
    this.element.dataset.key = key;
    this.element.dataset.axisId = axisId;
  }
  show(meta) {
    const { element: element2 } = this;
    const left = meta.x + this.xOffset;
    const top = meta.y + this.yOffset;
    element2.style.top = `${Math.round(top)}px`;
    element2.style.left = `${Math.round(left)}px`;
    this.toggle(true);
  }
  setLabelHtml({ html, styles }) {
    if (html !== void 0) {
      this.element.innerHTML = html;
    }
    if (styles !== void 0) {
      const styleElement = this.element.children[0] ?? this.element;
      Object.assign(styleElement.style, styles);
    }
  }
  getBBox() {
    const { element: element2 } = this;
    return new module_support_exports.BBox(
      element2.clientLeft,
      element2.clientTop,
      element2.clientWidth,
      element2.clientHeight
    );
  }
  toggle(visible) {
    this.element.classList.toggle(`ag-charts-crosshair-label--hidden`, !visible);
  }
  destroy() {
    this.domManager.removeChild("canvas-overlay", `crosshair-label-${this.id}`);
  }
  toLabelHtml(input, defaults) {
    if (typeof input === "string") {
      return { html: input, styles: {} };
    }
    defaults = defaults ?? {};
    const {
      text: text2 = defaults.text ?? "",
      color: color2 = defaults.color,
      backgroundColor = defaults.backgroundColor,
      opacity = defaults.opacity ?? 1
    } = input;
    const styles = {
      opacity,
      "background-color": backgroundColor?.toLowerCase(),
      color: color2
    };
    return {
      html: `<div class="ag-charts-crosshair-label-content">
                    <span>${text2}</span>
                </div>`,
      styles
    };
  }
};
CrosshairLabel.className = "CrosshairLabel";

// packages/ag-charts-enterprise/src/features/crosshair/crosshair.ts
var { Group: Group8, TranslatableGroup: TranslatableGroup3, Line: Line3, BBox: BBox12, InteractionState: InteractionState5 } = module_support_exports;
var Crosshair = class extends AbstractModuleInstance {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.id = createId(this);
    this.enabled = false;
    this.stroke = "rgb(195, 195, 195)";
    this.lineDash = [6, 3];
    this.lineDashOffset = 0;
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.snap = true;
    this.label = new CrosshairLabelProperties();
    this.seriesRect = new BBox12(0, 0, 0, 0);
    this.bounds = new BBox12(0, 0, 0, 0);
    this.crosshairGroup = new TranslatableGroup3({
      name: "crosshairs",
      zIndex: 9 /* SERIES_CROSSHAIR */
    });
    this.lineGroup = this.crosshairGroup.appendChild(
      new Group8({
        name: `${this.id}-crosshair-lines`,
        zIndex: 9 /* SERIES_CROSSHAIR */
      })
    );
    this.lineGroupSelection = module_support_exports.Selection.select(this.lineGroup, Line3, false);
    this.activeHighlight = void 0;
    this.axisCtx = ctx.parent;
    this.labels = {};
    this.hideCrosshairs();
    ctx.domManager.addEventListener("focusin", ({ target }) => {
      if (this.checkInteractionState())
        return;
      const isSeriesAreaChild = target instanceof HTMLElement && ctx.domManager.contains(target, "series-area");
      if (this.crosshairGroup.visible && !isSeriesAreaChild) {
        this.hideCrosshairs();
        this.ctx.updateService.update(9 /* SCENE_RENDER */);
      }
    });
    const { seriesDragInterpreter } = ctx.widgets;
    this.cleanup.register(
      ctx.scene.attachNode(this.crosshairGroup),
      ctx.widgets.seriesWidget.addListener("mousemove", (event) => this.onMouseHoverLike(event)),
      ctx.widgets.seriesWidget.addListener("mouseleave", () => this.onMouseOut()),
      ctx.eventsHub.on("series:focus-change", () => this.onKeyPress()),
      ctx.eventsHub.on("zoom:pan-start", () => this.onMouseOut()),
      ctx.eventsHub.on("zoom:change-complete", () => this.onMouseOut()),
      ctx.eventsHub.on("highlight:change", (event) => this.onHighlightChange(event)),
      ctx.eventsHub.on("layout:complete", (event) => this.layout(event)),
      () => {
        for (const label of Object.values(this.labels)) {
          label.destroy();
        }
      }
    );
    if (seriesDragInterpreter) {
      this.cleanup.register(
        seriesDragInterpreter.events.on("drag-move", (event) => this.onMouseHoverLike(event)),
        seriesDragInterpreter.events.on("click", (event) => this.onClick(event))
      );
    }
  }
  checkInteractionState() {
    return this.ctx.interactionManager.isState(InteractionState5.Frozen);
  }
  layout({ series: { rect: rect2, visible }, axes }) {
    if (!visible || !axes || !this.enabled)
      return;
    this.seriesRect = rect2;
    const { position: axisPosition = "left", axisId } = this.axisCtx;
    const axisLayout = axes[axisId];
    if (!axisLayout)
      return;
    this.axisLayout = axisLayout;
    this.bounds = rect2.clone().grow(axisLayout.gridPadding + axisLayout.seriesAreaPadding, axisPosition);
    const { crosshairGroup, bounds } = this;
    crosshairGroup.translationX = Math.round(bounds.x);
    crosshairGroup.translationY = Math.round(bounds.y);
    const crosshairKeys = ["pointer", ...this.axisCtx.seriesKeyProperties()];
    this.updateSelections(crosshairKeys);
    this.updateLines();
    this.updateLabels(crosshairKeys);
    this.refreshPositions();
  }
  updateSelections(data) {
    this.lineGroupSelection.update(data, void 0, (key) => key);
  }
  updateLabels(keys) {
    const { labels, ctx } = this;
    for (const key of keys) {
      if (this.label.enabled) {
        labels[key] ?? (labels[key] = new CrosshairLabel(ctx.domManager, key, this.axisCtx.axisId));
      }
      if (labels[key]) {
        this.updateLabel(labels[key]);
      }
    }
  }
  updateLabel(label) {
    const { enabled, xOffset, yOffset, format, renderer } = this.label;
    label.enabled = enabled;
    label.xOffset = xOffset;
    label.yOffset = yOffset;
    label.format = format;
    label.renderer = renderer;
  }
  updateLines() {
    const { lineGroupSelection, bounds, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset, axisLayout } = this;
    if (!axisLayout)
      return;
    const isVertical = this.isVertical();
    lineGroupSelection.each((line) => {
      line.stroke = stroke3;
      line.strokeWidth = strokeWidth;
      line.strokeOpacity = strokeOpacity;
      line.lineDash = lineDash;
      line.lineDashOffset = lineDashOffset;
      line.y1 = 0;
      line.y2 = isVertical ? bounds.height : 0;
      line.x1 = 0;
      line.x2 = isVertical ? 0 : bounds.width;
    });
  }
  isVertical() {
    return this.axisCtx.direction === "x" /* X */;
  }
  isHover(event) {
    return event.type === "mousemove" || event.type === "click" || event.device === "touch" && this.ctx.chartService.touch.dragAction === "hover";
  }
  formatValue(value) {
    return toPlainText(this.axisCtx.formatScaleValue(value, "crosshair", this.label));
  }
  onClick(event) {
    if (event.device === "touch") {
      this.onMouseHoverLike(event);
    }
  }
  onMouseHoverLike(event) {
    if (!this.enabled || this.snap)
      return;
    const requiredState = this.isHover(event) ? InteractionState5.Clickable : InteractionState5.AnnotationsMoveable;
    if (!this.ctx.interactionManager.isState(requiredState))
      return;
    this.updatePositions(this.getData(event));
    this.crosshairGroup.visible = true;
    this.ctx.updateService.update(9 /* SCENE_RENDER */);
  }
  onMouseOut() {
    if (!this.ctx.interactionManager.isState(InteractionState5.Clickable))
      return;
    this.hideCrosshairs();
    this.ctx.updateService.update(9 /* SCENE_RENDER */);
  }
  onKeyPress() {
    if (this.enabled && !this.snap && this.ctx.interactionManager.isState(InteractionState5.Default)) {
      this.hideCrosshairs();
    }
  }
  onHighlightChange(event) {
    if (!this.enabled)
      return;
    const { crosshairGroup, axisCtx } = this;
    const { datum, series } = event.currentHighlight ?? {};
    const hasCrosshair = datum && (series?.axes.x?.id === axisCtx.axisId || series?.axes.y?.id === axisCtx.axisId);
    this.activeHighlight = hasCrosshair ? event.currentHighlight : void 0;
    if (!this.activeHighlight) {
      this.hideCrosshairs();
    } else if (this.snap) {
      const activeHighlightData = this.getActiveHighlightData(this.activeHighlight);
      this.updatePositions(activeHighlightData);
      crosshairGroup.visible = true;
    }
  }
  isInRange(value) {
    return this.axisCtx.inRange(value);
  }
  refreshPositions() {
    if (this.activeHighlight) {
      this.updatePositions(this.getActiveHighlightData(this.activeHighlight));
    }
  }
  updatePositions(data) {
    const { seriesRect, lineGroupSelection } = this;
    lineGroupSelection.each((line, key) => {
      const lineData = data[key];
      if (!lineData) {
        line.visible = false;
        this.hideLabel(key);
        return;
      }
      line.visible = true;
      const { value, position } = lineData;
      let x = 0;
      let y = 0;
      if (this.isVertical()) {
        x = position;
        line.x = Math.round(x);
      } else {
        y = position;
        line.y = Math.round(y);
      }
      if (this.label.enabled) {
        this.showLabel(x + seriesRect.x, y + seriesRect.y, value, key);
      } else {
        this.hideLabel(key);
      }
    });
  }
  getData(event) {
    const { axisCtx } = this;
    const key = "pointer";
    const { xKey = "", yKey = "" } = this.activeHighlight ?? {};
    const { currentX, currentY } = event;
    const datum = readDatum(this.activeHighlight);
    const isVertical = this.isVertical();
    const position = isVertical ? currentX : currentY;
    let value = datum?.[isVertical ? xKey : yKey] ?? "";
    if (axisCtx.continuous) {
      value = axisCtx.scaleInvert(position);
    }
    return { [key]: { position, value } };
  }
  getActiveHighlightData(activeHighlight) {
    const { axisCtx } = this;
    const { series, xKey = "", aggregatedValue, cumulativeValue, midPoint } = activeHighlight;
    const datum = readDatum(activeHighlight);
    const seriesKeyProperties = series.getKeyProperties(axisCtx.direction);
    const halfBandwidth = (axisCtx.scale.bandwidth ?? 0) / 2;
    const matchingAxisId = series.axes[axisCtx.direction]?.id === axisCtx.axisId;
    const isYKey = seriesKeyProperties.includes("yKey") && matchingAxisId;
    const isXKey = seriesKeyProperties.includes("xKey") && matchingAxisId;
    const datumValue = aggregatedValue ?? cumulativeValue;
    if (isYKey && datumValue !== void 0) {
      const position = axisCtx.scale.convert(datumValue) + halfBandwidth;
      const isInRange = this.isInRange(position);
      return isInRange ? {
        yKey: { value: datumValue, position }
      } : {};
    }
    if (isXKey) {
      const position = (this.isVertical() ? midPoint?.x : midPoint?.y) ?? 0;
      const value = axisCtx.continuous ? axisCtx.scaleInvert(position) : datum?.[xKey];
      return this.isInRange(position) ? { xKey: { value, position } } : {};
    }
    const activeHighlightData = {};
    for (const key of seriesKeyProperties) {
      const keyValue = series.properties[key];
      const value = datum?.[keyValue];
      const position = axisCtx.scale.convert(value) + halfBandwidth;
      const isInRange = this.isInRange(position);
      if (isInRange) {
        activeHighlightData[key] = { value, position };
      }
    }
    return activeHighlightData;
  }
  getLabelHtml(value, label) {
    const fractionDigits = this.axisLayout?.label?.fractionDigits ?? 0;
    const defaults = { text: this.formatValue(value) };
    if (this.label.renderer) {
      return label.toLabelHtml(this.label.renderer({ value, fractionDigits }), defaults);
    }
    return label.toLabelHtml(defaults);
  }
  showLabel(x, y, value, key) {
    if (!this.axisLayout)
      return;
    const { bounds } = this;
    const label = this.labels[key];
    const html = this.getLabelHtml(value, label);
    label.setLabelHtml(html);
    const { width: width2, height: height2 } = label.getBBox();
    const axisPosition = this.axisCtx.position;
    let padding2 = this.axisLayout.label.spacing + this.axisLayout.tickSize;
    if (this.axisCtx.direction === "x" /* X */) {
      padding2 -= 4;
      label.show({
        x: x - width2 / 2,
        y: axisPosition === "bottom" ? bounds.y + bounds.height + padding2 : bounds.y - height2 - padding2
      });
    } else {
      padding2 -= 8;
      label.show({
        x: axisPosition === "right" ? bounds.x + bounds.width + padding2 : bounds.x - width2 - padding2,
        y: y - height2 / 2
      });
    }
  }
  hideCrosshairs() {
    this.crosshairGroup.visible = false;
    for (const key of Object.keys(this.labels)) {
      this.hideLabel(key);
    }
  }
  hideLabel(key) {
    this.labels[key]?.toggle(false);
  }
};
Crosshair.className = "Crosshair";
__decorateClass([
  addFakeTransformToInstanceProperty
], Crosshair.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Crosshair.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Crosshair.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Crosshair.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Crosshair.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Crosshair.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Crosshair.prototype, "snap", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Crosshair.prototype, "label", 2);

// packages/ag-charts-enterprise/src/features/crosshair/crosshairModule.ts
var CrosshairModule = {
  type: "axis:plugin",
  name: "crosshair",
  chartType: "cartesian",
  enterprise: true,
  version: VERSION,
  themeTemplate: {
    enabled: {
      $if: [
        {
          $or: [
            { $eq: [{ $path: "../type" }, "number"] },
            { $eq: [{ $path: "../type" }, "log"] },
            { $eq: [{ $path: "../type" }, "time"] },
            { $eq: [{ $path: "../type" }, "unit-time"] },
            { $eq: [{ $path: "../type" }, "ordinal-time"] }
          ]
        },
        true,
        false
      ]
    },
    snap: true,
    stroke: { $ref: "subtleTextColor" },
    strokeWidth: 1,
    strokeOpacity: 1,
    lineDash: [5, 6],
    lineDashOffset: 0,
    label: {
      enabled: true
    }
  },
  create: (ctx) => new Crosshair(ctx)
};

// packages/ag-charts-enterprise/src/features/data-source/dataSource.ts
var DataSource = class extends AbstractModuleInstance {
  constructor(ctx) {
    super();
    this.enabled = true;
    this.getData = () => Promise.resolve();
    this.dataService = ctx.dataService;
    let dirty = false;
    this.cleanup.register(
      ctx.eventsHub.on("data:load", () => {
        dirty = true;
      }),
      ctx.eventsHub.on("layout:complete", () => {
        if (dirty) {
          ctx.zoomManager.updateZoom({ source: "data-update", sourceDetail: "dataSource" });
        }
      })
    );
  }
  updateCallback(enabled, getData) {
    if (!this.dataService)
      return;
    if (enabled && getData != null) {
      this.dataService.updateCallback(getData);
    } else {
      this.dataService.clearCallback();
    }
  }
};
__decorateClass([
  ActionOnSet({
    newValue(enabled) {
      this.updateCallback(enabled, this.getData);
    }
  }),
  addFakeTransformToInstanceProperty
], DataSource.prototype, "enabled", 2);
__decorateClass([
  ActionOnSet({
    newValue(getData) {
      this.updateCallback(this.enabled, getData);
    }
  }),
  addFakeTransformToInstanceProperty
], DataSource.prototype, "getData", 2);
__decorateClass([
  ActionOnSet({
    newValue(requestThrottle) {
      this.dataService.requestThrottle = requestThrottle;
    }
  })
], DataSource.prototype, "requestThrottle", 2);
__decorateClass([
  ActionOnSet({
    newValue(updateThrottle) {
      this.dataService.dispatchThrottle = updateThrottle;
    }
  })
], DataSource.prototype, "updateThrottle", 2);
__decorateClass([
  ActionOnSet({
    newValue(updateDuringInteraction) {
      this.dataService.dispatchOnlyLatest = !updateDuringInteraction;
    }
  })
], DataSource.prototype, "updateDuringInteraction", 2);

// packages/ag-charts-enterprise/src/features/data-source/dataSourceModule.ts
var DataSourceModule = {
  type: "plugin",
  name: "dataSource",
  enterprise: true,
  version: VERSION,
  options: {
    getData: callback,
    requestThrottle: undocumented(positiveNumber),
    updateThrottle: undocumented(positiveNumber),
    updateDuringInteraction: undocumented(boolean)
  },
  create: (ctx) => new DataSource(ctx)
};

// packages/ag-charts-enterprise/src/features/error-bar/errorBarNode.ts
var { BBox: BBox13 } = module_support_exports;
var HierarchicalBBox = class {
  constructor(components) {
    this.components = components;
    this.union = BBox13.merge(components);
  }
  containsPoint(x, y) {
    if (!this.union.containsPoint(x, y)) {
      return false;
    }
    for (const bbox of this.components) {
      if (bbox.containsPoint(x, y)) {
        return true;
      }
    }
    return false;
  }
};
var ErrorBarNode = class extends module_support_exports.Group {
  constructor() {
    super();
    this.capLength = Number.NaN;
    this._datum = void 0;
    this.whiskerPath = new module_support_exports.Path();
    this.capsPath = new module_support_exports.Path();
    this.bboxes = new HierarchicalBBox([]);
    this.append([this.whiskerPath, this.capsPath]);
  }
  get datum() {
    return this._datum;
  }
  set datum(datum) {
    this._datum = datum;
  }
  calculateCapLength(capsTheme, capDefaults) {
    const { lengthRatio = 1, length: length2 } = capsTheme;
    const { lengthRatioMultiplier, lengthMax } = capDefaults;
    const desiredLength = length2 ?? lengthRatio * lengthRatioMultiplier;
    return Math.min(desiredLength, lengthMax);
  }
  getItemStylerParams(options, style2, highlighted, highlightState) {
    const { datum } = this;
    if (datum == null || options.itemStyler == null)
      return;
    const { xLowerKey, xUpperKey, yLowerKey, yUpperKey } = options;
    return {
      ...style2,
      datum: datum.datum,
      seriesId: datum.series.id,
      xKey: datum.xKey,
      yKey: datum.yKey,
      xLowerKey,
      xUpperKey,
      yLowerKey,
      yUpperKey,
      highlighted,
      highlightState
    };
  }
  formatStyles(style2, options, caller, highlighted, highlightState) {
    let { cap: capsStyle, ...whiskerStyle } = style2;
    const params = this.getItemStylerParams(options, style2, highlighted, highlightState);
    if (params != null && options.itemStyler != null) {
      const result = caller.callWithContext(options.itemStyler, params);
      whiskerStyle = mergeDefaults(result, whiskerStyle);
      capsStyle = mergeDefaults(result?.cap, result, capsStyle);
    }
    return { whiskerStyle, capsStyle };
  }
  applyStyling(target, source) {
    partialAssign(
      ["visible", "stroke", "strokeWidth", "strokeOpacity", "lineDash", "lineDashOffset"],
      target,
      source
    );
  }
  update(style2, formatters2, caller, highlighted, highlightState) {
    if (this.datum === void 0) {
      return;
    }
    const { whiskerStyle, capsStyle } = this.formatStyles(style2, formatters2, caller, highlighted, highlightState);
    const { xBar, yBar, capDefaults } = this.datum;
    const whisker = this.whiskerPath;
    this.applyStyling(whisker, whiskerStyle);
    whisker.path.clear(true);
    if (yBar !== void 0) {
      whisker.path.moveTo(yBar.lowerPoint.x, yBar.lowerPoint.y);
      whisker.path.lineTo(yBar.upperPoint.x, yBar.upperPoint.y);
    }
    if (xBar !== void 0) {
      whisker.path.moveTo(xBar.lowerPoint.x, xBar.lowerPoint.y);
      whisker.path.lineTo(xBar.upperPoint.x, xBar.upperPoint.y);
    }
    whisker.path.closePath();
    this.capLength = this.calculateCapLength(capsStyle ?? {}, capDefaults);
    const capOffset = this.capLength / 2;
    const caps = this.capsPath;
    this.applyStyling(caps, capsStyle);
    caps.path.clear(true);
    if (yBar !== void 0) {
      caps.path.moveTo(yBar.lowerPoint.x - capOffset, yBar.lowerPoint.y);
      caps.path.lineTo(yBar.lowerPoint.x + capOffset, yBar.lowerPoint.y);
      caps.path.moveTo(yBar.upperPoint.x - capOffset, yBar.upperPoint.y);
      caps.path.lineTo(yBar.upperPoint.x + capOffset, yBar.upperPoint.y);
    }
    if (xBar !== void 0) {
      caps.path.moveTo(xBar.lowerPoint.x, xBar.lowerPoint.y - capOffset);
      caps.path.lineTo(xBar.lowerPoint.x, xBar.lowerPoint.y + capOffset);
      caps.path.moveTo(xBar.upperPoint.x, xBar.upperPoint.y - capOffset);
      caps.path.lineTo(xBar.upperPoint.x, xBar.upperPoint.y + capOffset);
    }
    caps.path.closePath();
  }
  updateBBoxes() {
    const { capLength, whiskerPath: whisker, capsPath: caps } = this;
    const { yBar, xBar } = this.datum ?? {};
    const capOffset = capLength / 2;
    const components = [];
    if (yBar !== void 0) {
      const whiskerHeight = yBar.lowerPoint.y - yBar.upperPoint.y;
      components.push(
        new BBox13(yBar.lowerPoint.x, yBar.upperPoint.y, whisker.strokeWidth, whiskerHeight),
        new BBox13(yBar.lowerPoint.x - capOffset, yBar.lowerPoint.y, capLength, caps.strokeWidth),
        new BBox13(yBar.upperPoint.x - capOffset, yBar.upperPoint.y, capLength, caps.strokeWidth)
      );
    }
    if (xBar !== void 0) {
      const whiskerWidth = xBar.upperPoint.x - xBar.lowerPoint.x;
      components.push(
        new BBox13(xBar.lowerPoint.x, xBar.upperPoint.y, whiskerWidth, whisker.strokeWidth),
        new BBox13(xBar.lowerPoint.x, xBar.lowerPoint.y - capOffset, caps.strokeWidth, capLength),
        new BBox13(xBar.upperPoint.x, xBar.upperPoint.y - capOffset, caps.strokeWidth, capLength)
      );
    }
    this.bboxes.components = components;
    this.bboxes.union = BBox13.merge(components);
  }
  containsPoint(x, y) {
    return this.bboxes.containsPoint(x, y);
  }
  pickNode(x, y) {
    return this.containsPoint(x, y) ? this : void 0;
  }
  nearestSquared(x, y, maxDistance) {
    const { bboxes } = this;
    if (bboxes.union.distanceSquared(x, y) > maxDistance) {
      return { nearest: void 0, distanceSquared: Infinity };
    }
    const { distanceSquared: distanceSquared2 } = nearestSquared(x, y, bboxes.components);
    return { nearest: this, distanceSquared: distanceSquared2 };
  }
};
var ErrorBarGroup = class extends module_support_exports.Group {
  nearestSquared(x, y) {
    const { nearest, distanceSquared: distanceSquared2 } = nearestSquaredInContainer(x, y, {
      children: this.children()
    });
    if (nearest !== void 0 && !Number.isNaN(distanceSquared2)) {
      return { datum: nearest.datum, distanceSquared: distanceSquared2 };
    }
  }
};

// packages/ag-charts-enterprise/src/features/error-bar/errorBarProperties.ts
var ErrorBarCap = class extends BaseProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarCap.prototype, "visible", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarCap.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarCap.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarCap.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarCap.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarCap.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarCap.prototype, "length", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarCap.prototype, "lengthRatio", 2);
var ErrorBarProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.visible = true;
    this.stroke = "black";
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.cap = new ErrorBarCap();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarProperties.prototype, "yLowerKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarProperties.prototype, "yLowerName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarProperties.prototype, "yUpperKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarProperties.prototype, "yUpperName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarProperties.prototype, "xLowerKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarProperties.prototype, "xLowerName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarProperties.prototype, "xUpperKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarProperties.prototype, "xUpperName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarProperties.prototype, "visible", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarProperties.prototype, "itemStyler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ErrorBarProperties.prototype, "cap", 2);

// packages/ag-charts-enterprise/src/features/error-bar/errorBar.ts
var { fixNumericExtent: fixNumericExtent2, groupAccumulativeValueProperty: groupAccumulativeValueProperty2, valueProperty: valueProperty5 } = module_support_exports;
var ErrorBars = class _ErrorBars extends AbstractModuleInstance {
  constructor(ctx) {
    super();
    this.properties = new ErrorBarProperties();
    const series = ctx.series;
    const { annotationGroup, annotationSelections } = series;
    this.cartesianSeries = series;
    this.groupNode = new ErrorBarGroup({
      name: `${annotationGroup.id}-errorBars`
    });
    annotationGroup.appendChild(this.groupNode);
    this.selection = module_support_exports.Selection.select(this.groupNode, () => this.errorBarFactory());
    annotationSelections.add(this.selection);
    series.addEventListener("seriesVisibilityChange", (e) => this.onToggleSeriesItem(e));
    this.cleanup.register(
      series.events.on("data-processed", (e) => this.onDataProcessed(e)),
      series.events.on("data-update", (e) => this.onDataUpdate(e)),
      ctx.eventsHub.on("highlight:change", (event) => this.onHighlightChange(event)),
      () => this.groupNode.remove(),
      () => annotationSelections.delete(this.selection)
    );
  }
  hasErrorBars() {
    const { xLowerKey, xUpperKey, yLowerKey, yUpperKey } = this.properties;
    return isDefined(xLowerKey) && isDefined(xUpperKey) || isDefined(yLowerKey) && isDefined(yUpperKey);
  }
  isStacked() {
    const stackCount = this.cartesianSeries.seriesGrouping?.stackCount;
    return stackCount == null ? false : stackCount > 0;
  }
  getUnstackPropertyDefinition(opts) {
    const props = [];
    const { xLowerKey, xUpperKey, yLowerKey, yUpperKey, xErrorsID, yErrorsID } = this.getMaybeFlippedKeys();
    const { xScaleType, yScaleType } = opts;
    if (yLowerKey != null && yUpperKey != null) {
      props.push(
        valueProperty5(yLowerKey, yScaleType, { id: `${yErrorsID}-lower` }),
        valueProperty5(yUpperKey, yScaleType, { id: `${yErrorsID}-upper` })
      );
    }
    if (xLowerKey != null && xUpperKey != null) {
      props.push(
        valueProperty5(xLowerKey, xScaleType, { id: `${xErrorsID}-lower` }),
        valueProperty5(xUpperKey, xScaleType, { id: `${xErrorsID}-upper` })
      );
    }
    return props;
  }
  getStackPropertyDefinition(opts) {
    const props = [];
    const { cartesianSeries } = this;
    const { xLowerKey, xUpperKey, yLowerKey, yUpperKey, xErrorsID, yErrorsID } = this.getMaybeFlippedKeys();
    const { xScaleType, yScaleType } = opts;
    const groupIndex = cartesianSeries.seriesGrouping?.groupIndex ?? cartesianSeries.id;
    const groupOpts = {
      invalidValue: null,
      missingValue: 0,
      separateNegative: true,
      ...cartesianSeries.visible ? {} : { forceValue: 0 }
    };
    const makeErrorProperty = (key, id, type, scaleType) => {
      return groupAccumulativeValueProperty2(
        key,
        "normal",
        {
          id: `${id}-${type}`,
          groupId: `errorGroup-${groupIndex}-${type}`,
          ...groupOpts
        },
        scaleType
      );
    };
    const pushErrorProperties = (lowerKey, upperKey, id, scaleType) => {
      props.push(
        ...makeErrorProperty(lowerKey, id, "lower", scaleType),
        ...makeErrorProperty(upperKey, id, "upper", scaleType)
      );
    };
    if (yLowerKey != null && yUpperKey != null) {
      pushErrorProperties(yLowerKey, yUpperKey, yErrorsID, yScaleType);
    }
    if (xLowerKey != null && xUpperKey != null) {
      pushErrorProperties(xLowerKey, xUpperKey, xErrorsID, xScaleType);
    }
    return props;
  }
  getPropertyDefinitions(opts) {
    if (this.isStacked()) {
      return this.getStackPropertyDefinition(opts);
    } else {
      return this.getUnstackPropertyDefinition(opts);
    }
  }
  onDataProcessed(event) {
    this.dataModel = event.dataModel;
    this.processedData = event.processedData;
  }
  getDomain(direction) {
    const { xLowerKey, xUpperKey, xErrorsID, yLowerKey, yUpperKey, yErrorsID } = this.getMaybeFlippedKeys();
    const hasAxisErrors = direction === "x" /* X */ ? isDefined(xLowerKey) && isDefined(xUpperKey) : isDefined(yLowerKey) && isDefined(yUpperKey);
    if (hasAxisErrors) {
      const { dataModel, processedData, cartesianSeries: series } = this;
      if (dataModel != null && processedData != null) {
        const id = { x: xErrorsID, y: yErrorsID }[direction];
        const lowerDomain = dataModel.getDomain(series, `${id}-lower`, "value", processedData).domain;
        const upperDomain = dataModel.getDomain(series, `${id}-upper`, "value", processedData).domain;
        const domain = [Math.min(...lowerDomain, ...upperDomain), Math.max(...lowerDomain, ...upperDomain)];
        return fixNumericExtent2(domain);
      }
    }
    return [];
  }
  onDataUpdate(event) {
    this.dataModel = event.dataModel;
    this.processedData = event.processedData;
    if (isDefined(event.dataModel) && isDefined(event.processedData)) {
      this.createNodeData();
      this.update();
    }
  }
  getNodeData() {
    return this.hasErrorBars() ? this.cartesianSeries.contextNodeData?.nodeData : void 0;
  }
  createNodeData() {
    const nodeData = this.getNodeData();
    const xScale = this.cartesianSeries.axes["x" /* X */]?.scale;
    const yScale = this.cartesianSeries.axes["y" /* Y */]?.scale;
    if (!xScale || !yScale || !nodeData) {
      return;
    }
    for (let i = 0; i < nodeData.length; i++) {
      const { midPoint, xLower, xUpper, yLower, yUpper } = this.getDatum(nodeData, i);
      if (midPoint != null) {
        let xBar, yBar;
        if (isDefined(xLower) && isDefined(xUpper)) {
          xBar = {
            lowerPoint: { x: this.convert(xScale, xLower), y: midPoint.y },
            upperPoint: { x: this.convert(xScale, xUpper), y: midPoint.y }
          };
        }
        if (isDefined(yLower) && isDefined(yUpper)) {
          yBar = {
            lowerPoint: { x: midPoint.x, y: this.convert(yScale, yLower) },
            upperPoint: { x: midPoint.x, y: this.convert(yScale, yUpper) }
          };
        }
        nodeData[i].xBar = xBar;
        nodeData[i].yBar = yBar;
      }
    }
  }
  getMaybeFlippedKeys() {
    let { xLowerKey, xUpperKey, yLowerKey, yUpperKey } = this.properties;
    let [xErrorsID, yErrorsID] = ["xValue-errors", "yValue-errors"];
    if (this.cartesianSeries.shouldFlipXY()) {
      [xLowerKey, yLowerKey] = [yLowerKey, xLowerKey];
      [xUpperKey, yUpperKey] = [yUpperKey, xUpperKey];
      [xErrorsID, yErrorsID] = [yErrorsID, xErrorsID];
    }
    return { xLowerKey, xUpperKey, xErrorsID, yLowerKey, yUpperKey, yErrorsID };
  }
  static getDatumKey(nodeDatum, key, offset) {
    if (key == null) {
      return;
    }
    const datum = readDatum(nodeDatum);
    const value = datum?.[key];
    if (value == null) {
      return;
    }
    if (typeof value !== "number") {
      logger_exports.warnOnce(`Found [${key}] error value of type ${typeof value}. Expected number type`);
      return;
    }
    return value + offset;
  }
  getDatum(nodeData, datumIndex) {
    const { xLowerKey, xUpperKey, yLowerKey, yUpperKey } = this.getMaybeFlippedKeys();
    const datum = nodeData[datumIndex];
    const d = datum.cumulativeValue == null || !this.isStacked() ? 0 : datum.cumulativeValue - datum.yValue;
    const [xOffset, yOffset] = this.cartesianSeries.shouldFlipXY() ? [d, 0] : [0, d];
    return {
      midPoint: datum.midPoint,
      xLower: _ErrorBars.getDatumKey(datum, xLowerKey, xOffset),
      xUpper: _ErrorBars.getDatumKey(datum, xUpperKey, xOffset),
      yLower: _ErrorBars.getDatumKey(datum, yLowerKey, yOffset),
      yUpper: _ErrorBars.getDatumKey(datum, yUpperKey, yOffset)
    };
  }
  convert(scale2, value) {
    const offset = (scale2.bandwidth ?? 0) / 2;
    return scale2.convert(value) + offset;
  }
  update() {
    const nodeData = this.getNodeData();
    if (nodeData != null) {
      this.selection.update(nodeData);
      this.selection.each((node, datum, i) => this.updateNode(node, datum, i));
    }
  }
  updateNode(node, datum, _index) {
    node.datum = datum;
    node.update(this.getDefaultStyle(), this.properties, this.cartesianSeries, false, "none");
    node.updateBBoxes();
  }
  pickNodeExact(point) {
    const { x, y } = point;
    const node = this.groupNode.pickNode(x, y);
    if (node != null) {
      return { datum: node.datum, distanceSquared: 0 };
    }
  }
  pickNodeNearest(point) {
    return this.groupNode.nearestSquared(point.x, point.y);
  }
  pickNodeMainAxisFirst(point, majorDirection) {
    let closestDatum;
    let closestDistance = [Infinity, Infinity];
    const referencePoints = [point.x, point.y];
    if (majorDirection === "y" /* Y */) {
      referencePoints.reverse();
    }
    for (const child of this.groupNode.children()) {
      const childBBox = child.getBBox();
      const childReferencePoints = [childBBox.x + childBBox.width / 2, childBBox.y + childBBox.height / 2];
      if (majorDirection === "y" /* Y */) {
        childReferencePoints.reverse();
      }
      const childDistances = [];
      for (let i = 0; i < referencePoints.length; i++) {
        childDistances.push(Math.abs(referencePoints[i] - childReferencePoints[i]));
      }
      if (childDistances[0] < closestDistance[0] || childDistances[0] == closestDistance[0] && childDistances[1] < closestDistance[1]) {
        closestDatum = child.datum;
        closestDistance = childDistances;
      }
    }
    if (closestDatum) {
      return {
        datum: closestDatum,
        distanceSquared: Math.pow(closestDistance[0], 2) + Math.pow(closestDistance[1], 2)
      };
    }
  }
  getTooltipParams() {
    const {
      xLowerKey,
      xUpperKey,
      yLowerKey,
      yUpperKey,
      xLowerName = xLowerKey,
      xUpperName = xUpperKey,
      yLowerName = yLowerKey,
      yUpperName = yUpperKey
    } = this.properties;
    return { xLowerKey, xLowerName, xUpperKey, xUpperName, yLowerKey, yLowerName, yUpperKey, yUpperName };
  }
  onToggleSeriesItem(event) {
    this.groupNode.visible = event.visible;
  }
  makeStyle(baseStyle) {
    return {
      visible: baseStyle.visible,
      lineDash: baseStyle.lineDash,
      lineDashOffset: baseStyle.lineDashOffset,
      stroke: baseStyle.stroke,
      strokeWidth: baseStyle.strokeWidth,
      strokeOpacity: baseStyle.strokeOpacity,
      cap: mergeDefaults(this.properties.cap, baseStyle)
    };
  }
  getDefaultStyle() {
    return this.makeStyle(this.getWhiskerProperties());
  }
  getHighlightStyle() {
    return this.makeStyle(this.getWhiskerProperties());
  }
  restyleHighlightChange(highlightChange, style2, highlighted) {
    const nodeData = this.getNodeData();
    if (nodeData == null)
      return;
    for (let i = 0; i < nodeData.length; i++) {
      if (highlightChange === nodeData[i]) {
        this.selection.at(i)?.update(
          style2,
          this.properties,
          this.cartesianSeries,
          highlighted,
          highlighted ? "highlighted-item" : "unhighlighted-item"
        );
        break;
      }
    }
  }
  onHighlightChange(event) {
    const { previousHighlight, currentHighlight } = event;
    if (currentHighlight?.series === this.cartesianSeries) {
      this.restyleHighlightChange(currentHighlight, this.getHighlightStyle(), true);
    }
    if (previousHighlight?.series === this.cartesianSeries) {
      this.restyleHighlightChange(previousHighlight, this.getDefaultStyle(), false);
    }
    this.groupNode.opacity = this.cartesianSeries.getOpacity();
  }
  errorBarFactory() {
    return new ErrorBarNode();
  }
  getWhiskerProperties() {
    const { stroke: stroke3, strokeWidth, visible, strokeOpacity, lineDash, lineDashOffset } = this.properties;
    return { stroke: stroke3, strokeWidth, visible, strokeOpacity, lineDash, lineDashOffset };
  }
};

// packages/ag-charts-enterprise/src/features/error-bar/errorBarModule.ts
var ErrorBarsModule = {
  type: "series:plugin",
  name: "errorBar",
  chartType: "cartesian",
  seriesTypes: ["bar", "line", "scatter"],
  enterprise: true,
  version: VERSION,
  options: errorBarOptionsDefs,
  themeTemplate: {
    visible: true,
    stroke: { $ref: "foregroundColor" },
    strokeWidth: 1,
    strokeOpacity: 1,
    cap: {
      lengthRatio: {
        $if: [{ $eq: [{ $path: "../../type" }, "bar"] }, 0.3, 1]
      }
    }
  },
  create: (ctx) => new ErrorBars(ctx)
};

// packages/ag-charts-enterprise/src/features/flash-on-update/flashOnUpdate.ts
function findPrimaryCategoryAxisContext(ctx) {
  for (const dir of ["x" /* X */, "y" /* Y */]) {
    for (const axisCtx of ctx.axisManager.getAxisContext(dir)) {
      if (module_support_exports.BandScale.is(axisCtx.scale)) {
        return axisCtx;
      }
    }
  }
}
var FlashOnUpdate = class extends BaseProperties {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.enabled = false;
    this.item = "chart";
    this.color = "#cfeeff";
    this.opacity = 1;
    this.flashDuration = 100;
    this.fadeDuration = 900;
    this.cleanup = new CleanupRegistry();
    this.element = this.ctx.domManager.addChild("canvas-background", "flashOnUpdate");
    this.element.role = "presentation";
    let firstUpdate = true;
    const onDataUpdate = (ev) => {
      if (firstUpdate) {
        firstUpdate = false;
      } else {
        this.onDataUpdate(ev);
      }
    };
    this.cleanup.register(
      this.ctx.eventsHub.on("data:update", onDataUpdate),
      this.ctx.eventsHub.on("datamodel:diff", (e) => this.onDataModelDiff(e))
    );
  }
  destroy() {
    this.ctx.domManager.removeChild("canvas-background", "flashOnUpdate");
    this.cleanup.flush();
  }
  clearFlash() {
    this.element.innerHTML = "";
    clearTimeout(this.animationTimeout);
    this.animationTimeout = void 0;
  }
  flashElem(el) {
    const { flashDuration, fadeDuration } = this;
    const duration = flashDuration + fadeDuration;
    el.animate(
      [
        { background: this.color, offset: 0 },
        { background: this.color, offset: flashDuration / duration },
        { background: "transparent", offset: 1 }
      ],
      { duration, easing: "ease-out" }
    );
  }
  flashCategoryBands(diff9) {
    const axisCtx = findPrimaryCategoryAxisContext(this.ctx);
    if (!axisCtx)
      return;
    this.clearFlash();
    const flashBounds = this.computeCategoryFlashBounds(axisCtx, diff9);
    for (const bounds of flashBounds) {
      const e = createElement("div");
      setAttribute(e, "role", "presentation");
      setElementStyle(e, "position", "absolute");
      setElementBBox(e, bounds);
      this.element.appendChild(e);
      this.flashElem(e);
    }
    const duration = this.flashDuration + this.fadeDuration;
    this.animationTimeout = setTimeout(() => this.clearFlash(), duration);
  }
  computeCategories(diff9) {
    const result = /* @__PURE__ */ new Set();
    for (const seriesId of Object.keys(diff9)) {
      for (const key of ["updated", "added", "moved"]) {
        for (const value of diff9[seriesId][key]) {
          result.add(value);
        }
      }
    }
    return result;
  }
  computeCategoryFlashBounds(axisCtx, diff9) {
    const seriesBounds = this.ctx.widgets.seriesWidget.getBounds();
    const makeBox = axisCtx.direction === "x" /* X */ ? ([start2, end3]) => {
      return {
        x: seriesBounds.x + start2,
        y: seriesBounds.y,
        width: end3 - start2,
        height: seriesBounds.height
      };
    } : ([start2, end3]) => {
      return {
        x: seriesBounds.x,
        y: seriesBounds.y + start2,
        width: seriesBounds.width,
        height: end3 - start2
      };
    };
    const result = [];
    const categories = this.computeCategories(diff9);
    for (const c of categories) {
      const measurements = axisCtx.measureBand(c);
      if (measurements?.band) {
        result.push(makeBox(measurements.band));
      }
    }
    return result;
  }
  onDataUpdate(ev) {
    if (!this.enabled || this.item !== "chart" || !ev)
      return;
    this.flashElem(this.ctx.widgets.containerWidget.getElement());
  }
  onDataModelDiff(ev) {
    if (!this.enabled || this.item !== "category")
      return;
    this.flashCategoryBands(ev.diff);
  }
};
FlashOnUpdate.className = "FlashOnUpdate";
__decorateClass([
  addFakeTransformToInstanceProperty
], FlashOnUpdate.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FlashOnUpdate.prototype, "item", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FlashOnUpdate.prototype, "color", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FlashOnUpdate.prototype, "opacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FlashOnUpdate.prototype, "flashDuration", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FlashOnUpdate.prototype, "fadeDuration", 2);

// packages/ag-charts-enterprise/src/features/flash-on-update/flashOnUpdateModule.ts
var FlashOnUpdateModule = {
  type: "plugin",
  name: "flashOnUpdate",
  enterprise: true,
  version: VERSION,
  options: {
    enabled: boolean,
    item: strictUnion()("chart", "category"),
    color,
    opacity: ratio,
    flashDuration: positiveNumber,
    fadeDuration: positiveNumber
  },
  themeTemplate: {
    enabled: false,
    item: "chart",
    color: "#cfeeff",
    opacity: 1,
    flashDuration: 100,
    fadeDuration: 900
  },
  create: (ctx) => new FlashOnUpdate(ctx)
};

// packages/ag-charts-enterprise/src/features/navigator/shapes/miniChartGroup.ts
var { TranslatableGroup: TranslatableGroup4 } = module_support_exports;
var MiniChartGroup = class extends TranslatableGroup4 {
  constructor() {
    super(...arguments);
    this.inset = 0;
    this.cornerRadius = 0;
  }
  applyClip(ctx, clipRect) {
    const { cornerRadius, inset } = this;
    const { x, y, width: width2, height: height2 } = clipRect;
    const Path2DCtor = getPath2D();
    const path = new Path2DCtor();
    path.roundRect(x + inset, y + inset, width2 - 2 * inset, height2 - 2 * inset, cornerRadius);
    ctx.clip(path);
  }
};
__decorateClass([
  SceneChangeDetection()
], MiniChartGroup.prototype, "inset", 2);
__decorateClass([
  SceneChangeDetection()
], MiniChartGroup.prototype, "cornerRadius", 2);

// packages/ag-charts-enterprise/src/features/navigator/miniChart.ts
var { CategoryAxis: CategoryAxis2, Group: Group9, BBox: BBox14, stackCartesianSeries: stackCartesianSeries2 } = module_support_exports;
var MiniChartPadding = class {
  constructor() {
    this.top = 0;
    this.bottom = 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], MiniChartPadding.prototype, "top", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MiniChartPadding.prototype, "bottom", 2);
var MiniChart = class extends AbstractModuleInstance {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.enabled = false;
    this.padding = new MiniChartPadding();
    this.root = new Group9({ name: "root" });
    this.seriesRoot = this.root.appendChild(
      new MiniChartGroup({ name: "Series-root", zIndex: 7 /* SERIES_LAYER */, renderToOffscreenCanvas: true })
    );
    this.axisGridGroup = this.root.appendChild(new Group9({ name: "Axes-Grids", zIndex: 2 /* AXIS_GRID */ }));
    this.axisGroup = this.root.appendChild(new Group9({ name: "Axes-Grids", zIndex: 2 /* AXIS_GRID */ }));
    this.axisLabelGroup = this.root.appendChild(new Group9({ name: "Axes-Labels", zIndex: 15 /* SERIES_LABEL */ }));
    this.axisCrosslineRangeGroup = this.root.appendChild(
      new Group9({ name: "Axes-Crosslines-Range", zIndex: 6 /* SERIES_CROSSLINE_RANGE */ })
    );
    this.axisCrosslineLineGroup = this.root.appendChild(
      new Group9({ name: "Axes-Crosslines-Line", zIndex: 10 /* SERIES_CROSSLINE_LINE */ })
    );
    this.axisCrosslineLabelGroup = this.root.appendChild(
      new Group9({ name: "Axes-Crosslines-Label", zIndex: 15 /* SERIES_LABEL */ })
    );
    this.data = [];
    this._destroyed = false;
    this.miniChartAnimationPhase = "initial";
    // Should be available after the first layout.
    this.seriesRect = void 0;
    this.axes = new module_support_exports.ChartAxes();
    this.series = [];
    this.cleanup.register(this.ctx.eventsHub.on("data:update", (data) => this.updateData(data)));
  }
  destroy() {
    if (this._destroyed) {
      return;
    }
    super.destroy();
    this.destroySeries(this.series);
    this.axes.destroy();
    this._destroyed = true;
  }
  onSeriesChange(newValue, oldValue) {
    const seriesToDestroy = oldValue?.filter((series) => !newValue.includes(series)) ?? [];
    this.destroySeries(seriesToDestroy);
    for (const series of newValue) {
      if (oldValue?.includes(series))
        continue;
      series.attachSeries(this.seriesRoot, this.seriesRoot, void 0);
      series.chart = {};
      Object.defineProperty(series.chart, "mode", {
        get: () => "standalone"
      });
      Object.defineProperty(series.chart, "isMiniChart", {
        get: () => true
      });
      Object.defineProperty(series.chart, "flashOnUpdateEnabled", {
        get: () => false
      });
      Object.defineProperty(series.chart, "seriesRect", {
        get: () => this.seriesRect
      });
      series.resetAnimation(this.miniChartAnimationPhase === "initial" ? "initial" : "disabled");
    }
    this.seriesRect = void 0;
  }
  destroySeries(allSeries) {
    if (allSeries) {
      for (const series of allSeries) {
        series.destroy();
        series.detachSeries(this.seriesRoot, this.seriesRoot, void 0);
        series.chart = void 0;
      }
    }
  }
  assignSeriesToAxes() {
    for (const axis of this.axes) {
      axis.boundSeries = this.series.filter((s) => {
        const seriesAxis = s.axes[axis.direction];
        return seriesAxis === axis;
      });
    }
  }
  assignAxesToSeries() {
    const directionToAxesMap = {};
    for (const axis of this.axes) {
      const direction = axis.direction;
      const directionAxes = directionToAxesMap[direction] ?? (directionToAxesMap[direction] = []);
      directionAxes.push(axis);
    }
    for (const series of this.series) {
      for (const direction of series.directions) {
        const seriesAxisId = series.getKeyAxis(direction) ?? direction;
        const newAxis = this.axes.findById(seriesAxisId);
        if (!newAxis) {
          logger_exports.warnOnce(
            `no matching axis for direction [${direction}] and id [${seriesAxisId}]; check series and axes configuration.`
          );
          return;
        }
        series.axes[direction] = newAxis;
      }
    }
  }
  updateData(data) {
    for (const s of this.series) {
      s.setChartData(data);
    }
    if (this.miniChartAnimationPhase === "initial") {
      this.ctx.animationManager.onBatchStop(() => {
        this.miniChartAnimationPhase = "ready";
        for (const s of this.series) {
          s.resetAnimation("disabled");
        }
      });
    }
  }
  async processData(dataController) {
    if (this.series.some((s) => s.canHaveAxes)) {
      this.assignAxesToSeries();
      this.assignSeriesToAxes();
    }
    await Promise.all(
      this.series.map(async (s) => {
        s.resetDatumCallbackCache();
        return s.processData(dataController);
      })
    );
    for (const axis of this.axes) {
      axis.processData();
    }
  }
  computeAxisPadding() {
    const padding2 = new Padding();
    if (!this.enabled) {
      return padding2;
    }
    for (const { position, thickness, line, label } of this.axes) {
      if (position == null)
        continue;
      let size;
      if (thickness) {
        size = thickness;
      } else {
        size = (line.enabled ? line.width : 0) + (label.enabled ? calcLineHeight(label.fontSize ?? 0) + label.spacing : 0);
      }
      padding2[position] = Math.ceil(size);
    }
    return padding2;
  }
  async layout(width2, height2) {
    var _a;
    const { padding: padding2 } = this;
    const animated = this.seriesRect != null;
    const seriesRect = new BBox14(0, 0, width2, height2 - (padding2.top + padding2.bottom));
    const resized = this.seriesRect?.width !== width2 || this.seriesRect?.height !== height2;
    this.seriesRect = seriesRect;
    this.seriesRoot.translationY = padding2.top;
    this.seriesRoot.setClipRectCanvasSpace(new BBox14(0, -padding2.top, width2, height2));
    for (const axis of this.axes) {
      const { position = "left" } = axis;
      switch (position) {
        case "top":
        case "bottom":
          axis.range = [0, seriesRect.width];
          axis.gridLength = seriesRect.height;
          break;
        case "right":
        case "left": {
          const isCategoryAxis = axis instanceof CategoryAxis2;
          axis.range = isCategoryAxis ? [0, seriesRect.height] : [seriesRect.height, 0];
          axis.gridLength = seriesRect.width;
          break;
        }
      }
      axis.gridPadding = 0;
      axis.translation.x = 0;
      axis.translation.y = 0;
      if (position === "right") {
        axis.translation.x = width2;
      } else if (position === "bottom") {
        axis.translation.y = height2;
      }
      if (!animated) {
        axis.resetAnimation("initial");
      }
      if (axis.crossLines) {
        for (const crossLine of axis.crossLines) {
          if (crossLine instanceof module_support_exports.CartesianCrossLine) {
            crossLine.position = axis.position ?? "top";
            (_a = crossLine.label).parallel ?? (_a.parallel = axis.label?.parallel);
          }
        }
      }
      axis.calculateLayout();
      axis.update();
    }
    if (resized) {
      stackCartesianSeries2(this.series);
    }
    await Promise.all(this.series.map(async (series) => series.update({ seriesRect })));
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], MiniChart.prototype, "enabled", 2);
__decorateClass([
  ProxyProperty(["seriesRoot", "inset"])
], MiniChart.prototype, "inset", 2);
__decorateClass([
  ProxyProperty(["seriesRoot", "cornerRadius"])
], MiniChart.prototype, "cornerRadius", 2);
__decorateClass([
  ActionOnSet({
    changeValue(newValue, oldValue = new module_support_exports.ChartAxes()) {
      const axisNodes = {
        axisNode: this.axisGroup,
        gridNode: this.axisGridGroup,
        labelNode: this.axisLabelGroup,
        crossLineLineNode: this.axisCrosslineLineGroup,
        crossLineRangeNode: this.axisCrosslineRangeGroup,
        crossLineLabelNode: this.axisCrosslineLabelGroup
      };
      for (const axis of oldValue) {
        if (newValue.includes(axis))
          continue;
        axis.detachAxis();
        axis.destroy();
      }
      for (const axis of newValue) {
        if (oldValue?.includes(axis))
          continue;
        axis.attachAxis(axisNodes);
      }
    }
  })
], MiniChart.prototype, "axes", 2);
__decorateClass([
  ActionOnSet({
    changeValue(newValue, oldValue) {
      this.onSeriesChange(newValue, oldValue);
    }
  })
], MiniChart.prototype, "series", 2);

// packages/ag-charts-enterprise/src/features/navigator/navigatorDOMProxy.ts
var { SliderWidget: SliderWidget2 } = module_support_exports;
var NavigatorDOMProxy = class {
  constructor(ctx, sliderHandlers) {
    this.ctx = ctx;
    this.sliderHandlers = sliderHandlers;
    this._min = 0;
    this._max = 1;
    this.minRange = 1e-3;
    this.dragStartX = 0;
    this.ctx = ctx;
    this.toolbar = ctx.proxyInteractionService.createProxyContainer({
      type: "toolbar",
      domManagerId: `navigator-toolbar`,
      classList: ["ag-charts-proxy-navigator-toolbar"],
      orientation: "vertical",
      ariaLabel: { id: "ariaLabelNavigator" }
    });
    this.sliders = [
      ctx.proxyInteractionService.createProxyElement({
        type: "slider",
        domIndex: 1,
        ariaLabel: { id: "ariaLabelNavigatorMinimum" },
        parent: this.toolbar,
        cursor: "ew-resize"
      }),
      ctx.proxyInteractionService.createProxyElement({
        type: "slider",
        domIndex: -Infinity,
        ariaLabel: { id: "ariaLabelNavigatorRange" },
        parent: this.toolbar,
        cursor: "grab"
      }),
      ctx.proxyInteractionService.createProxyElement({
        type: "slider",
        domIndex: 2,
        ariaLabel: { id: "ariaLabelNavigatorMaximum" },
        parent: this.toolbar,
        cursor: "ew-resize"
      })
    ];
    for (const [index, key] of ["min", "pan", "max"].entries()) {
      const slider = this.sliders[index];
      slider.step = SliderWidget2.STEP_HUNDRETH;
      slider.keyboardStep = SliderWidget2.STEP_ONE;
      slider.orientation = "horizontal";
      slider.setPreventsDefault(false);
      slider.addListener("drag-start", (ev) => this.onDragStart(index, ev, key));
      slider.addListener("drag-move", (ev) => this.onDrag(slider, ev, key));
      slider.addListener("drag-end", () => this.updateSliderRatios());
      slider.addListener("contextmenu", (ev) => this.onContextMenu(slider, ev));
    }
    this.sliders[0].addListener("change", () => this.onMinSliderChange());
    this.sliders[1].addListener("change", () => this.onPanSliderChange());
    this.sliders[2].addListener("change", () => this.onMaxSliderChange());
    this.updateSliderRatios();
    this.updateVisibility(false);
  }
  destroy() {
    this.toolbar.destroy();
  }
  updateVisibility(visible) {
    this.toolbar.setHidden(!visible);
  }
  updateZoom() {
    const { _min: min, _max: max } = this;
    if (min == null || max == null)
      return;
    this.ctx.zoomManager.updateZoom(
      { source: "user-interaction", sourceDetail: "navigatorDOM" },
      { x: { min, max } }
    );
  }
  updateBounds(bounds) {
    this.toolbar.setBounds(bounds);
  }
  updateSliderBounds(sliderIndex, bounds) {
    this.sliders[sliderIndex].setBounds(bounds);
  }
  updateMinMax(min, max) {
    this._min = min;
    this._max = max;
    this.updateSliderRatios();
  }
  updateSliderRatios() {
    let { _min: min, _max: max } = this;
    min = Math.round(min * 100) / 100;
    max = Math.round(max * 100) / 100;
    const panAria = this.ctx.localeManager.t("ariaValuePanRange", { min, max });
    this.sliders[0].setValueRatio(min);
    this.sliders[1].setValueRatio(min, { ariaValueText: panAria });
    this.sliders[2].setValueRatio(max);
  }
  toCanvasOffsets(event) {
    return { offsetX: this.dragStartX + event.originDeltaX };
  }
  moveToFront(index) {
    if (index === 1)
      return;
    const frontSlider = this.sliders[index];
    const otherSlider = this.sliders[2 - index];
    this.toolbar.moveChild(otherSlider, frontSlider.domIndex - 1);
  }
  onDragStart(index, event, key) {
    const slider = this.sliders[index];
    const toolbarLeft = this.toolbar.cssLeft();
    const sliderLeft = slider.cssLeft();
    this.dragStartX = toolbarLeft + sliderLeft + event.offsetX;
    this.moveToFront(index);
    event.sourceEvent.preventDefault();
    this.sliderHandlers.onDragStart(key, this.toCanvasOffsets(event));
  }
  onDrag(_slider, event, key) {
    event.sourceEvent.preventDefault();
    this.sliderHandlers.onDrag(key, this.toCanvasOffsets(event));
  }
  onContextMenu(slider, widgetEvent) {
    const { offsetX, offsetY } = widgetEvent;
    const { x: toolbarX, y: toolbarY } = this.toolbar.getBounds();
    const { x: sliderX, y: sliderY } = slider.getBounds();
    const canvasX = offsetX + toolbarX + sliderX;
    const canvasY = offsetY + toolbarY + sliderY;
    this.ctx.contextMenuRegistry.dispatchContext("always", { widgetEvent, canvasX, canvasY }, void 0);
  }
  onPanSliderChange() {
    const ratio2 = this.sliders[1].getValueRatio();
    const span = this._max - this._min;
    this._min = clamp(0, ratio2, 1 - span);
    this._max = this._min + span;
    this.updateZoom();
  }
  onMinSliderChange() {
    this._min = this.sliders[0].clampValueRatio(0, this._max - this.minRange);
    this.updateZoom();
  }
  onMaxSliderChange() {
    this._max = this.sliders[2].clampValueRatio(this._min + this.minRange, 1);
    this.updateZoom();
  }
};

// packages/ag-charts-enterprise/src/features/navigator/shapes/rangeHandle.ts
var { BBox: BBox15, ExtendedPath2D: ExtendedPath2D2 } = module_support_exports;
var RangeHandle = class extends module_support_exports.Path {
  constructor() {
    super(...arguments);
    this.zIndex = 3;
    this.centerX = 0;
    this.centerY = 0;
    this.width = 8;
    this.height = 16;
    this.cornerRadius = 4;
    this.grip = true;
    this.gripPath = new ExtendedPath2D2();
  }
  setCenter(x, y) {
    this.dirtyPath = true;
    if (this.centerX !== x || this.centerY !== y) {
      this.centerX = x;
      this.centerY = y;
      this.markDirty("center");
    }
  }
  static align(minHandle, maxHandle, x, y, width2, height2, min, max, pixelAlign) {
    const minHandleX = minHandle.align(x + width2 * min) + pixelAlign;
    const maxHandleX = minHandleX + minHandle.align(x + width2 * min, width2 * (max - min)) - 2 * pixelAlign;
    const handleY = minHandle.align(y + height2 / 2);
    minHandle.setCenter(minHandleX, handleY);
    maxHandle.setCenter(maxHandleX, handleY);
  }
  computeBBox() {
    const { centerX, centerY, width: width2, height: height2 } = this;
    const x = centerX - width2 / 2;
    const y = centerY - height2 / 2;
    return new BBox15(x, y, width2, height2);
  }
  isPointInPath(x, y) {
    const bbox = this.getBBox();
    return bbox.containsPoint(x, y);
  }
  updatePath() {
    const { centerX, centerY, path, gripPath, strokeWidth, cornerRadius, grip } = this;
    const pixelAlign = strokeWidth / 2;
    const pixelRatio = this.layerManager?.canvas?.pixelRatio ?? 1;
    path.clear();
    gripPath.clear();
    const halfWidth = Math.floor(this.width / 2 * pixelRatio) / pixelRatio;
    const halfHeight = Math.floor(this.height / 2 * pixelRatio) / pixelRatio;
    path.roundRect(
      centerX - halfWidth + pixelAlign,
      centerY - halfHeight + pixelAlign,
      2 * (halfWidth - pixelAlign),
      2 * (halfHeight - pixelAlign),
      cornerRadius
    );
    const gripSpacing = 3;
    if (grip) {
      for (let x = -0.5; x <= 0.5; x += 1) {
        for (let y = -1; y <= 1; y += 1) {
          gripPath.arc(centerX + x * gripSpacing, centerY + y * gripSpacing, 1, 0, 2 * Math.PI);
          gripPath.closePath();
        }
      }
    }
  }
  renderFill(ctx, path) {
    const { stroke: stroke3 } = this;
    super.renderFill(ctx, path);
    ctx.fillStyle = typeof stroke3 === "string" ? stroke3 : "black";
    ctx.fill(this.gripPath.getPath2D());
  }
};
RangeHandle.className = "RangeHandle";
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], RangeHandle.prototype, "width", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], RangeHandle.prototype, "height", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], RangeHandle.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], RangeHandle.prototype, "grip", 2);

// packages/ag-charts-enterprise/src/features/navigator/shapes/rangeMask.ts
var { Path: Path6, BBox: BBox16, ExtendedPath2D: ExtendedPath2D3, clippedRoundRect: clippedRoundRect2 } = module_support_exports;
var RangeMask = class extends Path6 {
  constructor() {
    super(...arguments);
    this.cornerRadius = 4;
    this.zIndex = 2;
    this.x = 0;
    this.y = 0;
    this.width = 200;
    this.height = 30;
    this.min = 0;
    this.max = 1;
    this.visiblePath = new ExtendedPath2D3();
  }
  layout(x, y, width2, height2, min, max) {
    min = Number.isNaN(min) ? this.min : min;
    max = Number.isNaN(max) ? this.max : max;
    if (x !== this.x || y !== this.y || width2 !== this.width || this.height !== height2 || min !== this.min || max !== this.max) {
      this.x = x;
      this.y = y;
      this.width = width2;
      this.height = height2;
      this.min = min;
      this.max = max;
      this.dirtyPath = true;
      this.markDirty("RangeMask.layout");
    }
  }
  computeBBox() {
    const { x, y, width: width2, height: height2 } = this;
    return new BBox16(x, y, width2, height2);
  }
  computeVisibleRangeBBox() {
    const { x, y, width: width2, height: height2, min, max } = this;
    const minX = x + width2 * min;
    const maxX = x + width2 * max;
    return new BBox16(minX, y, maxX - minX, height2);
  }
  updatePath() {
    const { path, visiblePath, x, y, width: width2, height: height2, min, max, strokeWidth, cornerRadius } = this;
    const pixelAlign = strokeWidth / 2;
    path.clear();
    visiblePath.clear();
    const ax = this.align(x) + pixelAlign;
    const ay = this.align(y) + pixelAlign;
    const aw = this.align(x, width2) - 2 * pixelAlign;
    const ah = this.align(y, height2) - 2 * pixelAlign;
    const minX = this.align(x + width2 * min) + pixelAlign;
    const maxX = minX + this.align(x + width2 * min, width2 * (max - min)) - 2 * pixelAlign;
    const cornerRadiusParams = {
      topLeft: cornerRadius,
      topRight: cornerRadius,
      bottomRight: cornerRadius,
      bottomLeft: cornerRadius
    };
    const drawRect = (p, x0, x1) => {
      if (x1 - x0 < 1)
        return;
      const bbox = new BBox16(x0, ay, x1 - x0, ah);
      clippedRoundRect2(p, ax, ay, aw, ah, cornerRadiusParams, bbox);
    };
    drawRect(path, ax, minX);
    drawRect(path, maxX, aw + ax);
    drawRect(visiblePath, minX, maxX);
  }
  renderStroke(ctx, path) {
    super.renderStroke(ctx, path);
    super.renderStroke(ctx, this.visiblePath.getPath2D());
  }
};
RangeMask.className = "RangeMask";
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], RangeMask.prototype, "cornerRadius", 2);

// packages/ag-charts-enterprise/src/features/navigator/shapes/rangeSelector.ts
var RangeSelector = class extends module_support_exports.Group {
  constructor(children) {
    super({ name: "rangeSelectorGroup", zIndex: 17 /* NAVIGATOR */ });
    this.x = 0;
    this.y = 0;
    this.width = 200;
    this.height = 30;
    this.lOffset = 0;
    this.rOffset = 0;
    this.background = this.appendChild(
      new module_support_exports.TranslatableGroup({ name: "navigator-background", zIndex: 1 })
    );
    this.append(children);
  }
  layout(x, y, width2, height2, lOffset, rOffset) {
    this.x = x;
    this.y = y;
    this.width = width2;
    this.height = height2;
    this.lOffset = lOffset;
    this.rOffset = rOffset;
    this.background.translationX = x;
    this.background.translationY = y;
    this.markDirty("RangeSelector");
  }
  updateBackground(oldGroup, newGroup) {
    if (oldGroup != null) {
      oldGroup.remove();
    }
    if (newGroup != null) {
      this.background.appendChild(newGroup);
    }
    this.markDirty("RangeSelector");
  }
  computeBBox() {
    const { x, y, width: width2, height: height2, lOffset, rOffset } = this;
    return new module_support_exports.BBox(x - lOffset, y, width2 + (lOffset + rOffset), height2);
  }
};

// packages/ag-charts-enterprise/src/features/navigator/navigator.ts
var Navigator = class extends AbstractModuleInstance {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.enabled = false;
    this.mask = new RangeMask();
    this.minHandle = new RangeHandle();
    this.maxHandle = new RangeHandle();
    this.maskVisibleRange = {
      id: "navigator-mask-visible-range",
      getBBox: () => this.mask.computeVisibleRangeBBox(),
      toCanvasBBox: () => this.mask.computeVisibleRangeBBox(),
      fromCanvasPoint: (x, y) => ({ x, y })
    };
    this.height = 30;
    this.cornerRadius = 0;
    this.spacing = 10;
    this.x = 0;
    this.y = 0;
    this.width = 0;
    this.rangeSelector = new RangeSelector([this.mask, this.minHandle, this.maxHandle]);
    this.cleanup.register(
      ctx.scene.attachNode(this.rangeSelector),
      ctx.eventsHub.on("locale:change", () => this.updateZoom()),
      ctx.layoutManager.registerElement(module_support_exports.LayoutElement.Navigator, (e) => this.onLayoutStart(e)),
      ctx.eventsHub.on("layout:complete", (e) => this.onLayoutComplete(e)),
      ctx.eventsHub.on("zoom:change-complete", (event) => this.onZoomChange(event))
    );
    this.domProxy = new NavigatorDOMProxy(ctx, this);
    this.updateGroupVisibility();
    this.miniChart = new MiniChart(ctx);
  }
  updateBackground(oldGroup, newGroup) {
    this.rangeSelector?.updateBackground(oldGroup, newGroup);
  }
  updateGroupVisibility() {
    const { enabled } = this;
    if (this.rangeSelector == null || enabled === this.rangeSelector.visible)
      return;
    this.rangeSelector.visible = enabled;
    this.domProxy.updateVisibility(enabled);
    if (enabled) {
      this.updateZoom();
    } else {
      this.ctx.zoomManager.updateZoom(
        { source: "chart-update", sourceDetail: "navigator" },
        { x: { min: 0, max: 1 } }
      );
    }
  }
  onLayoutStart({ layoutBox }) {
    if (this.enabled) {
      const navigatorTotalHeight = this.height + this.spacing;
      layoutBox.shrink(navigatorTotalHeight, "bottom");
      this.y = layoutBox.y + layoutBox.height + this.spacing;
    } else {
      this.y = 0;
    }
    if (this.enabled && this.miniChart) {
      const { top, bottom } = this.miniChart.computeAxisPadding();
      layoutBox.shrink(top + bottom, "bottom");
      this.y -= bottom;
      this.miniChart.inset = this.mask.strokeWidth / 2;
      this.miniChart.cornerRadius = this.mask.cornerRadius;
    }
  }
  onLayoutComplete(opts) {
    const { x, width: width2 } = opts.series.rect;
    const { y, height: height2 } = this;
    this.domProxy.updateVisibility(this.enabled);
    if (this.enabled) {
      const { _min: min, _max: max } = this.domProxy;
      this.layoutNodes(x, y, width2, height2, min, max);
      this.domProxy.updateBounds({ x, y, width: width2, height: height2 });
    }
    this.x = x;
    this.width = width2;
    this.miniChart?.layout(width2, height2).catch((e) => logger_exports.error(e));
  }
  canDrag() {
    return this.enabled && this.ctx.interactionManager.isState(module_support_exports.InteractionState.ZoomDraggable);
  }
  onDragStart(dragging, { offsetX }) {
    if (!this.canDrag())
      return;
    if (dragging === "pan") {
      this.panStart = (offsetX - this.x) / this.width - this.domProxy._min;
    }
    this.ctx.zoomManager.fireZoomPanStartEvent("navigator");
  }
  onDrag(dragging, { offsetX }) {
    if (!this.canDrag())
      return;
    const { panStart, x, width: width2 } = this;
    const { minRange } = this.domProxy;
    let { _min: min, _max: max } = this.domProxy;
    const ratio2 = (offsetX - x) / width2;
    if (dragging === "min") {
      min = clamp(0, ratio2, max - minRange);
    } else if (dragging === "max") {
      max = clamp(min + minRange, ratio2, 1);
    } else if (dragging === "pan" && panStart != null) {
      const span = max - min;
      min = clamp(0, ratio2 - panStart, 1 - span);
      max = min + span;
    }
    this.domProxy._min = min;
    this.domProxy._max = max;
    this.updateZoom();
  }
  onZoomChange(event) {
    const { x: xZoom } = event;
    if (!xZoom)
      return;
    const { x, y, width: width2, height: height2 } = this;
    const { min, max } = xZoom;
    this.domProxy.updateMinMax(min, max);
    this.layoutNodes(x, y, width2, height2, min, max);
  }
  layoutNodes(x, y, width2, height2, min, max) {
    const { rangeSelector, mask, minHandle, maxHandle } = this;
    mask.layout(x, y, width2, height2, min, max);
    rangeSelector.layout(x, y, width2, height2, minHandle.width / 2, maxHandle.width / 2);
    RangeHandle.align(minHandle, maxHandle, x, y, width2, height2, min, max, mask.strokeWidth / 2);
    if (min + (max - min) / 2 < 0.5) {
      minHandle.zIndex = 3;
      maxHandle.zIndex = 4;
    } else {
      minHandle.zIndex = 4;
      maxHandle.zIndex = 3;
    }
    for (const [index, node] of [minHandle, this.maskVisibleRange, maxHandle].entries()) {
      const bbox = node.getBBox();
      const tbox = { x: bbox.x - x, y: bbox.y - y, height: bbox.height, width: bbox.width };
      this.domProxy.updateSliderBounds(index, tbox);
    }
  }
  updateZoom() {
    if (!this.enabled)
      return;
    this.domProxy.updateZoom();
  }
  async processData(dataController) {
    return this.miniChart?.processData(dataController);
  }
};
__decorateClass([
  ObserveChanges((target, value, oldValue) => {
    target.updateBackground(oldValue?.root, value?.root);
  })
], Navigator.prototype, "miniChart", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ObserveChanges((target, value) => {
    target.ctx.zoomManager.setNavigatorEnabled(Boolean(value));
    target.updateGroupVisibility();
  })
], Navigator.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Navigator.prototype, "height", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ObserveChanges((target, value) => {
    target.mask.cornerRadius = value;
  })
], Navigator.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Navigator.prototype, "spacing", 2);

// packages/ag-charts-enterprise/src/series/box-plot/blotPlotUtil.ts
function prepareBoxPlotFromTo(isVertical) {
  const from3 = isVertical ? { scalingX: 1, scalingY: 0 } : { scalingX: 0, scalingY: 1 };
  const to = { scalingX: 1, scalingY: 1 };
  return { from: from3, to };
}
function resetBoxPlotSelectionsScalingCenterFn(isVertical) {
  return (_node, datum) => {
    if (isVertical) {
      return { scalingCenterY: datum.scaledValues.medianValue };
    }
    return { scalingCenterX: datum.scaledValues.medianValue };
  };
}

// packages/ag-charts-enterprise/src/series/box-plot/boxPlotNode.ts
var { Path: Path7, Scalable: Scalable2, ExtendedPath2D: ExtendedPath2D4, BBox: BBox17, clippedRoundRect: baseClippedRoundRect } = module_support_exports;
var BoxPlotNode = class extends Scalable2(Path7) {
  constructor() {
    super(...arguments);
    this.wickPath = new ExtendedPath2D4();
    this.horizontal = false;
    this.center = 0;
    this.thickness = 0;
    this.min = 0;
    this.q1 = 0;
    this.median = 0;
    this.q3 = 0;
    this.max = 0;
    this.cornerRadius = 0;
    this.crisp = false;
    this.strokeAlignment = 0;
    this.wickStroke = void 0;
    this.wickStrokeWidth = void 0;
    this.wickStrokeOpacity = void 0;
    this.capLengthRatio = 1;
    this.wickStrokeAlignment = 0;
  }
  computeBBox() {
    const { horizontal, center: center2, thickness, min, max } = this;
    return horizontal ? new BBox17(Math.min(min, max), center2 - thickness / 2, Math.abs(max - min), thickness) : new BBox17(center2 - thickness / 2, Math.min(min, max), thickness, Math.abs(max - min));
  }
  computeDefaultGradientFillBBox() {
    const { horizontal, center: center2, thickness, q1, q3 } = this;
    return horizontal ? new BBox17(Math.min(q1, q3), center2 - thickness / 2, Math.abs(q3 - q1), thickness) : new BBox17(center2 - thickness / 2, Math.min(q1, q3), thickness, Math.abs(q3 - q1));
  }
  isPointInPath(x, y) {
    return this.getBBox().containsPoint(x, y);
  }
  distanceSquared(x, y) {
    return this.getBBox().distanceSquared(x, y);
  }
  get midPoint() {
    return this.horizontal ? { x: (this.min + this.max) / 2, y: this.center } : { x: this.center, y: (this.min + this.max) / 2 };
  }
  alignedCoordinates() {
    const { thickness, crisp } = this;
    let { center: center2, min, q1, median, q3, max } = this;
    let x0 = center2 - thickness / 2;
    let x1 = center2 + thickness / 2;
    if (crisp && thickness > 1) {
      min = this.align(min);
      q1 = this.align(q1);
      median = this.align(median);
      q3 = this.align(q3);
      max = min + this.align(min, max - min);
      const halfWidth = this.align(thickness / 2);
      center2 = this.align(center2);
      x0 = center2 - halfWidth;
      x1 = center2 + halfWidth;
    }
    return { center: center2, x0, x1, min, max, q1, median, q3 };
  }
  updatePath() {
    const {
      path,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset,
      wickStroke,
      wickStrokeWidth,
      wickStrokeOpacity,
      wickLineDash,
      wickLineDashOffset,
      strokeAlignment,
      cornerRadius,
      capLengthRatio,
      horizontal
    } = this;
    const { center: center2, x0, x1, min, max, q1, median, q3 } = this.alignedCoordinates();
    const pixelRatio = this.layerManager?.canvas.pixelRatio ?? 1;
    const wickStrokeAlignment = this.wickStrokeAlignment > 0 ? pixelRatio / this.wickStrokeAlignment / 2 % 1 : 0;
    this.path.clear();
    this.wickPath.clear();
    const needsWickPath = wickStroke != null && wickStroke !== stroke3 || wickStrokeWidth != null && wickStrokeWidth !== strokeWidth || wickStrokeOpacity != null && wickStrokeOpacity !== strokeOpacity || wickLineDash != null && wickLineDash !== lineDash || wickLineDashOffset != null && wickLineDashOffset !== lineDashOffset;
    const wickPath = needsWickPath ? this.wickPath : path;
    if (Math.abs(x1 - x0) <= 3) {
      moveTo(wickPath, horizontal, center2, min);
      lineTo(wickPath, horizontal, center2, max);
      return;
    }
    const wickTop = Math.min(min, max);
    const wickBottom = Math.max(min, max);
    const boxTop = Math.min(q1, q3);
    const boxBottom = Math.max(q1, q3);
    const capX0 = center2 - Math.abs((x1 - x0) * capLengthRatio) / 2;
    const capX1 = center2 + Math.abs((x1 - x0) * capLengthRatio) / 2;
    moveTo(wickPath, horizontal, capX0, wickTop - wickStrokeAlignment);
    lineTo(wickPath, horizontal, capX1, wickTop - wickStrokeAlignment);
    moveTo(wickPath, horizontal, center2 - wickStrokeAlignment, wickTop - wickStrokeAlignment);
    lineTo(wickPath, horizontal, center2 - wickStrokeAlignment, boxTop + strokeWidth / 2);
    moveTo(wickPath, horizontal, center2 - wickStrokeAlignment, wickBottom + wickStrokeAlignment);
    lineTo(wickPath, horizontal, center2 - wickStrokeAlignment, boxBottom - strokeWidth / 2);
    moveTo(wickPath, horizontal, capX0, wickBottom + wickStrokeAlignment);
    lineTo(wickPath, horizontal, capX1, wickBottom + wickStrokeAlignment);
    const horizontalBoxStrokeAdjustment = strokeWidth / 2 + strokeAlignment;
    const verticalBoxStrokeAdjustment = strokeWidth / 2 - strokeAlignment;
    const rectHeight = boxBottom - boxTop - 2 * verticalBoxStrokeAdjustment;
    if (rectHeight > 0) {
      const rectX = x0 + horizontalBoxStrokeAdjustment;
      const rectY = boxTop + verticalBoxStrokeAdjustment;
      const rectWidth = x1 - x0 - 2 * horizontalBoxStrokeAdjustment;
      const cornerRadii = {
        topLeft: cornerRadius,
        topRight: cornerRadius,
        bottomRight: cornerRadius,
        bottomLeft: cornerRadius
      };
      clippedRoundRect3(
        path,
        horizontal,
        rectX,
        rectY,
        rectWidth,
        rectHeight,
        cornerRadii,
        new BBox17(rectX, rectY, rectWidth, median - rectY)
      );
      clippedRoundRect3(
        path,
        horizontal,
        rectX,
        rectY,
        rectWidth,
        rectHeight,
        cornerRadii,
        new BBox17(rectX, median, rectWidth, rectY + rectHeight - median)
      );
    } else {
      const boxMid = (boxTop + boxBottom) / 2;
      moveTo(path, horizontal, x0, boxMid);
      lineTo(path, horizontal, x1, boxMid);
    }
  }
  drawPath(ctx) {
    super.drawPath(ctx);
    const { wickPath } = this;
    if (wickPath.isEmpty())
      return;
    const {
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset,
      wickStroke = stroke3,
      wickStrokeWidth = strokeWidth,
      wickStrokeOpacity = strokeOpacity,
      wickLineDash = lineDash,
      wickLineDashOffset = lineDashOffset
    } = this;
    if (wickStrokeWidth === 0)
      return;
    ctx.globalAlpha *= wickStrokeOpacity;
    if (typeof wickStroke === "string") {
      ctx.strokeStyle = wickStroke;
    }
    ctx.lineWidth = wickStrokeWidth;
    if (wickLineDash != null) {
      ctx.setLineDash([...wickLineDash]);
    }
    ctx.lineDashOffset = wickLineDashOffset;
    ctx.stroke(wickPath.getPath2D());
  }
};
__decorateClass([
  SceneChangeDetection()
], BoxPlotNode.prototype, "horizontal", 2);
__decorateClass([
  SceneChangeDetection()
], BoxPlotNode.prototype, "center", 2);
__decorateClass([
  SceneChangeDetection()
], BoxPlotNode.prototype, "thickness", 2);
__decorateClass([
  SceneChangeDetection()
], BoxPlotNode.prototype, "min", 2);
__decorateClass([
  SceneChangeDetection()
], BoxPlotNode.prototype, "q1", 2);
__decorateClass([
  SceneChangeDetection()
], BoxPlotNode.prototype, "median", 2);
__decorateClass([
  SceneChangeDetection()
], BoxPlotNode.prototype, "q3", 2);
__decorateClass([
  SceneChangeDetection()
], BoxPlotNode.prototype, "max", 2);
__decorateClass([
  SceneChangeDetection()
], BoxPlotNode.prototype, "cornerRadius", 2);
__decorateClass([
  SceneChangeDetection()
], BoxPlotNode.prototype, "crisp", 2);
__decorateClass([
  SceneChangeDetection()
], BoxPlotNode.prototype, "strokeAlignment", 2);
__decorateClass([
  SceneChangeDetection()
], BoxPlotNode.prototype, "wickStroke", 2);
__decorateClass([
  SceneChangeDetection()
], BoxPlotNode.prototype, "wickStrokeWidth", 2);
__decorateClass([
  SceneChangeDetection()
], BoxPlotNode.prototype, "wickStrokeOpacity", 2);
__decorateClass([
  SceneArrayChangeDetection()
], BoxPlotNode.prototype, "wickLineDash", 2);
__decorateClass([
  SceneChangeDetection()
], BoxPlotNode.prototype, "wickLineDashOffset", 2);
__decorateClass([
  SceneChangeDetection()
], BoxPlotNode.prototype, "capLengthRatio", 2);
__decorateClass([
  SceneChangeDetection()
], BoxPlotNode.prototype, "wickStrokeAlignment", 2);
function moveTo(path, horizontal, x, y) {
  if (horizontal) {
    path.moveTo(y, x);
  } else {
    path.moveTo(x, y);
  }
}
function lineTo(path, horizontal, x, y) {
  if (horizontal) {
    path.lineTo(y, x);
  } else {
    path.lineTo(x, y);
  }
}
function clippedRoundRect3(path, horizontal, x, y, width2, height2, cornerRadii, clipBBox) {
  if (horizontal) {
    baseClippedRoundRect(
      // eslint-disable-next-line sonarjs/arguments-order
      path,
      y,
      x,
      height2,
      width2,
      cornerRadii,
      clipBBox == null ? void 0 : new BBox17(clipBBox.y, clipBBox.x, clipBBox.height, clipBBox.width)
    );
  } else {
    baseClippedRoundRect(path, x, y, width2, height2, cornerRadii, clipBBox);
  }
}

// packages/ag-charts-enterprise/src/series/box-plot/boxPlotSeriesProperties.ts
var { AbstractBarSeriesProperties: AbstractBarSeriesProperties2, makeSeriesTooltip: makeSeriesTooltip7 } = module_support_exports;
var BoxPlotSeriesCap = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.lengthRatio = 0.5;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesCap.prototype, "lengthRatio", 2);
var BoxPlotSeriesWhisker = class extends BaseProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesWhisker.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesWhisker.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesWhisker.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesWhisker.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesWhisker.prototype, "lineDashOffset", 2);
var BoxPlotSeriesProperties = class extends AbstractBarSeriesProperties2 {
  constructor() {
    super(...arguments);
    this.fill = "#c16068";
    this.fillOpacity = 1;
    this.stroke = "#333";
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.cornerRadius = 0;
    this.cap = new BoxPlotSeriesCap();
    this.whisker = new BoxPlotSeriesWhisker();
    this.tooltip = makeSeriesTooltip7();
  }
  toJson() {
    const { stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this;
    const properties = super.toJson();
    properties.whisker = mergeDefaults(properties.whisker, {
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset
    });
    return properties;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "xKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "minKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "q1Key", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "medianKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "q3Key", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "maxKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "xName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "yName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "minName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "q1Name", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "medianName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "q3Name", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "maxName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "styler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "itemStyler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "cap", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "whisker", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], BoxPlotSeriesProperties.prototype, "tooltip", 2);

// packages/ag-charts-enterprise/src/series/box-plot/boxPlotSeries.ts
var {
  fixNumericExtent: fixNumericExtent3,
  keyProperty: keyProperty4,
  SeriesNodePickMode: SeriesNodePickMode5,
  SMALLEST_KEY_INTERVAL: SMALLEST_KEY_INTERVAL2,
  valueProperty: valueProperty6,
  diff: diff2,
  animationValidation: animationValidation2,
  computeBarFocusBounds: computeBarFocusBounds2,
  createDatumId: createDatumId7,
  HighlightState: HighlightState4,
  motion: motion2,
  getItemStyles: getItemStyles2,
  calculateSegments: calculateSegments2,
  toHighlightString: toHighlightString2,
  processedDataIsAnimatable: processedDataIsAnimatable2,
  upsertNodeDatum: upsertNodeDatum2
} = module_support_exports;
var BoxPlotSeriesNodeEvent = class extends module_support_exports.SeriesNodeEvent {
  constructor(type, nativeEvent, datum, series) {
    super(type, nativeEvent, datum, series);
    this.xKey = series.properties.xKey;
    this.minKey = series.properties.minKey;
    this.q1Key = series.properties.q1Key;
    this.medianKey = series.properties.medianKey;
    this.q3Key = series.properties.q3Key;
    this.maxKey = series.properties.maxKey;
  }
};
var BoxPlotSeries = class extends module_support_exports.AbstractBarSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      pickModes: [SeriesNodePickMode5.NEAREST_NODE, SeriesNodePickMode5.EXACT_SHAPE_MATCH],
      propertyKeys: {
        x: ["xKey"],
        y: ["medianKey", "q1Key", "q3Key", "minKey", "maxKey"]
      },
      propertyNames: {
        x: ["xName"],
        y: ["medianName", "q1Name", "q3Name", "minName", "maxName"]
      },
      categoryKey: "xValue",
      pathsPerSeries: []
    });
    this.properties = new BoxPlotSeriesProperties();
    this.NodeEvent = BoxPlotSeriesNodeEvent;
  }
  async processData(dataController) {
    if (!this.visible)
      return;
    const { xKey, minKey, q1Key, medianKey, q3Key, maxKey } = this.properties;
    const animationEnabled = !this.ctx.animationManager.isSkipped();
    const xScale = this.getCategoryAxis()?.scale;
    const yScale = this.getValueAxis()?.scale;
    const { isContinuousX, xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale });
    const extraProps = [];
    if (this.needsDataModelDiff() && this.processedData) {
      extraProps.push(diff2(this.id, this.processedData));
    }
    if (animationEnabled) {
      extraProps.push(animationValidation2());
    }
    const allowNullKey = this.properties.allowNullKeys ?? false;
    const { processedData } = await this.requestDataModel(dataController, this.data, {
      props: [
        keyProperty4(xKey, xScaleType, { id: `xValue`, allowNullKey }),
        valueProperty6(minKey, yScaleType, { id: `minValue` }),
        valueProperty6(q1Key, yScaleType, { id: `q1Value` }),
        valueProperty6(medianKey, yScaleType, { id: `medianValue` }),
        valueProperty6(q3Key, yScaleType, { id: `q3Value` }),
        valueProperty6(maxKey, yScaleType, { id: `maxValue` }),
        ...isContinuousX ? [SMALLEST_KEY_INTERVAL2] : [],
        ...extraProps
      ]
    });
    this.smallestDataInterval = processedData.reduced?.smallestKeyInterval;
    this.animationState.transition("updateData");
  }
  getSeriesDomain(direction) {
    const { processedData, dataModel } = this;
    if (!(processedData && dataModel))
      return { domain: [] };
    if (direction !== this.getBarDirection()) {
      const { index, def } = dataModel.resolveProcessedDataDefById(this, `xValue`);
      const keys = processedData.domain.keys[index];
      if (def.type === "key" && def.valueType === "category") {
        const sortMetadata = dataModel.getKeySortMetadata(this, "xValue", processedData);
        return { domain: keys, sortMetadata };
      }
      return { domain: this.padBandExtent(keys) };
    }
    const yExtent = this.domainForClippedRange(direction, ["minValue", "maxValue"], "xValue");
    return { domain: fixNumericExtent3(yExtent) };
  }
  getSeriesRange(_direction, visibleRange) {
    return this.domainForVisibleRange("y" /* Y */, ["maxValue", "minValue"], "xValue", visibleRange);
  }
  /**
   * Creates the shared context for datum creation.
   * Caches expensive lookups and computations that are constant across all datums.
   */
  createNodeDatumContext(xAxis, yAxis) {
    const { dataModel, processedData, contextNodeData } = this;
    if (!dataModel || !processedData)
      return void 0;
    const canIncrementallyUpdate = contextNodeData?.nodeData != null && processedData.changeDescription != null;
    const animationEnabled = !this.ctx.animationManager.isSkipped();
    const { groupOffset, barOffset, barWidth } = this.getBarDimensions();
    return {
      xAxis,
      yAxis,
      rawData: processedData.dataSources.get(this.id)?.data ?? [],
      xValues: dataModel.resolveKeysById(this, "xValue", processedData),
      minValues: dataModel.resolveColumnById(this, "minValue", processedData),
      q1Values: dataModel.resolveColumnById(this, "q1Value", processedData),
      medianValues: dataModel.resolveColumnById(this, "medianValue", processedData),
      q3Values: dataModel.resolveColumnById(this, "q3Value", processedData),
      maxValues: dataModel.resolveColumnById(this, "maxValue", processedData),
      xScale: xAxis.scale,
      yScale: yAxis.scale,
      groupOffset,
      barOffset,
      barWidth,
      isVertical: this.isVertical(),
      xKey: this.properties.xKey,
      animationEnabled,
      canIncrementallyUpdate,
      nodes: canIncrementallyUpdate ? contextNodeData.nodeData : [],
      nodeIndex: 0
    };
  }
  /**
   * Validates box plot values and checks ordering constraints.
   * Returns true if values are valid (all numbers, min <= q1 <= median <= q3 <= max).
   */
  validateBoxPlotValues(minValue, q1Value, medianValue, q3Value, maxValue) {
    return [minValue, q1Value, medianValue, q3Value, maxValue].every((value) => typeof value === "number") && minValue <= q1Value && q1Value <= medianValue && medianValue <= q3Value && q3Value <= maxValue;
  }
  /**
   * Computes scaled values for a single datum.
   * Populates the scratch object to avoid allocations.
   */
  computeScaledValues(ctx, scratch, datumIndex) {
    const x = ctx.xScale.convert(ctx.xValues[datumIndex]);
    if (!Number.isFinite(x))
      return false;
    scratch.xValue = x + ctx.groupOffset + ctx.barOffset + ctx.barWidth / 2;
    scratch.minValue = ctx.yScale.convert(ctx.minValues[datumIndex]);
    scratch.q1Value = ctx.yScale.convert(ctx.q1Values[datumIndex]);
    scratch.medianValue = ctx.yScale.convert(ctx.medianValues[datumIndex]);
    scratch.q3Value = ctx.yScale.convert(ctx.q3Values[datumIndex]);
    scratch.maxValue = ctx.yScale.convert(ctx.maxValues[datumIndex]);
    return true;
  }
  /**
   * Creates a skeleton BoxPlotNodeDatum with minimal required fields.
   * The node will be populated by updateNodeDatum.
   */
  createSkeletonNodeDatum(ctx, params) {
    return {
      series: this,
      datum: params.datum,
      datumIndex: params.datumIndex,
      xKey: ctx.xKey,
      bandwidth: ctx.barWidth,
      scaledValues: {
        xValue: 0,
        minValue: 0,
        q1Value: 0,
        medianValue: 0,
        q3Value: 0,
        maxValue: 0
      },
      midPoint: { x: 0, y: 0 },
      focusRect: { x: 0, y: 0, width: 0, height: 0 }
    };
  }
  /**
   * Updates an existing BoxPlotNodeDatum in-place.
   * This is more efficient than recreating the entire node when only data values change.
   */
  updateNodeDatum(ctx, node, params) {
    const { isVertical, barWidth } = ctx;
    const scaledValues = params.scaledValues;
    const mutableNode = node;
    mutableNode.datum = params.datum;
    mutableNode.datumIndex = params.datumIndex;
    mutableNode.bandwidth = barWidth;
    const mutableScaledValues = mutableNode.scaledValues;
    mutableScaledValues.xValue = scaledValues.xValue;
    mutableScaledValues.minValue = scaledValues.minValue;
    mutableScaledValues.q1Value = scaledValues.q1Value;
    mutableScaledValues.medianValue = scaledValues.medianValue;
    mutableScaledValues.q3Value = scaledValues.q3Value;
    mutableScaledValues.maxValue = scaledValues.maxValue;
    const height2 = Math.abs(scaledValues.q3Value - scaledValues.q1Value);
    const midX = scaledValues.xValue;
    const midY = Math.min(scaledValues.q3Value, scaledValues.q1Value) + height2 / 2;
    const midPointX = isVertical ? midX : midY;
    const midPointY = isVertical ? midY : midX;
    if (mutableNode.midPoint) {
      mutableNode.midPoint.x = midPointX;
      mutableNode.midPoint.y = midPointY;
    } else {
      mutableNode.midPoint = { x: midPointX, y: midPointY };
    }
    const focusRect = mutableNode.focusRect;
    if (isVertical) {
      focusRect.x = midPointX - barWidth / 2;
      focusRect.y = scaledValues.minValue;
      focusRect.width = barWidth;
      focusRect.height = scaledValues.maxValue - scaledValues.minValue;
    } else {
      focusRect.x = scaledValues.minValue;
      focusRect.y = midPointY - barWidth / 2;
      focusRect.width = scaledValues.maxValue - scaledValues.minValue;
      focusRect.height = barWidth;
    }
  }
  /**
   * Creates a BoxPlotNodeDatum for a single data point.
   * Creates a skeleton node and uses updateNodeDatum to populate it.
   */
  createNodeDatum(ctx, params) {
    const node = this.createSkeletonNodeDatum(ctx, params);
    this.updateNodeDatum(ctx, node, params);
    return node;
  }
  /**
   * Initialize the result object shell before populating node data.
   */
  initializeResult(ctx) {
    return {
      itemId: this.properties.xKey,
      nodeData: ctx.nodes,
      labelData: [],
      scales: this.calculateScaling(),
      visible: this.visible,
      // Set by assembleResult()
      groupScale: void 0,
      styles: void 0,
      segments: void 0
    };
  }
  /**
   * Populate node data by iterating over raw data.
   */
  populateNodeData(ctx) {
    const scaledValuesScratch = {
      xValue: 0,
      minValue: 0,
      q1Value: 0,
      medianValue: 0,
      q3Value: 0,
      maxValue: 0
    };
    const paramsScratch = {
      datumIndex: 0,
      datum: void 0,
      scaledValues: scaledValuesScratch
    };
    for (let datumIndex = 0; datumIndex < ctx.rawData.length; datumIndex++) {
      const datum = ctx.rawData[datumIndex];
      const xValue = ctx.xValues[datumIndex];
      if (xValue === void 0 && !this.properties.allowNullKeys)
        continue;
      const minValue = ctx.minValues[datumIndex];
      const q1Value = ctx.q1Values[datumIndex];
      const medianValue = ctx.medianValues[datumIndex];
      const q3Value = ctx.q3Values[datumIndex];
      const maxValue = ctx.maxValues[datumIndex];
      if (!this.validateBoxPlotValues(minValue, q1Value, medianValue, q3Value, maxValue)) {
        continue;
      }
      if (!this.computeScaledValues(ctx, scaledValuesScratch, datumIndex)) {
        continue;
      }
      paramsScratch.datumIndex = datumIndex;
      paramsScratch.datum = datum;
      upsertNodeDatum2(
        ctx,
        paramsScratch,
        (c, p) => this.createNodeDatum(c, p),
        (c, n, p) => this.updateNodeDatum(c, n, p)
      );
    }
  }
  /**
   * Finalize node data by trimming excess nodes.
   */
  finalizeNodeData(ctx) {
    if (ctx.canIncrementallyUpdate && ctx.nodeIndex < ctx.nodes.length) {
      ctx.nodes.length = ctx.nodeIndex;
    }
  }
  /**
   * Assemble the final result with computed fields.
   */
  assembleResult(ctx, result) {
    const segments = calculateSegments2(
      this.properties.segmentation,
      ctx.xAxis,
      ctx.yAxis,
      this.chart.seriesRect,
      this.ctx.scene
    );
    result.groupScale = this.getScaling(this.ctx.seriesStateManager.getGroupScale(this));
    result.styles = getItemStyles2(this.getItemStyle.bind(this));
    result.segments = segments;
    return result;
  }
  legendItemSymbol() {
    const { fill, stroke: stroke3, strokeWidth, fillOpacity, strokeOpacity, lineDash, lineDashOffset } = this.getStyle(
      false,
      HighlightState4.None
    );
    return {
      marker: {
        fill: deepClone(fill),
        fillOpacity,
        stroke: stroke3,
        strokeOpacity,
        strokeWidth,
        lineDash,
        lineDashOffset
      }
    };
  }
  getLegendData(legendType) {
    const {
      id: seriesId,
      ctx: { legendManager },
      visible
    } = this;
    const { xKey, yName, showInLegend, legendItemName } = this.properties;
    if (!xKey || legendType !== "category") {
      return [];
    }
    return [
      {
        legendType: "category",
        id: seriesId,
        itemId: seriesId,
        seriesId,
        enabled: visible && legendManager.getItemEnabled({ seriesId, itemId: seriesId }),
        label: {
          text: legendItemName ?? yName ?? seriesId
        },
        symbol: this.legendItemSymbol(),
        legendItemName,
        hideInLegend: !showInLegend
      }
    ];
  }
  getTooltipContent(datumIndex) {
    const { id: seriesId, dataModel, processedData, properties } = this;
    const {
      xKey,
      xName,
      yName,
      medianKey,
      medianName,
      q1Key,
      q1Name,
      q3Key,
      q3Name,
      minKey,
      minName,
      maxKey,
      maxName,
      legendItemName,
      tooltip
    } = properties;
    const xAxis = this.getCategoryAxis();
    const yAxis = this.getValueAxis();
    if (!dataModel || !processedData || !xAxis || !yAxis)
      return;
    const datum = processedData.dataSources.get(this.id)?.data[datumIndex];
    const xValue = dataModel.resolveKeysById(this, `xValue`, processedData)[datumIndex];
    const minValue = dataModel.resolveColumnById(this, `minValue`, processedData)[datumIndex];
    const q1Value = dataModel.resolveColumnById(this, `q1Value`, processedData)[datumIndex];
    const medianValue = dataModel.resolveColumnById(this, `medianValue`, processedData)[datumIndex];
    const q3Value = dataModel.resolveColumnById(this, `q3Value`, processedData)[datumIndex];
    const maxValue = dataModel.resolveColumnById(this, `maxValue`, processedData)[datumIndex];
    const allowNullKeys = this.properties.allowNullKeys ?? false;
    if (xValue === void 0 && !allowNullKeys)
      return;
    const format = this.getItemStyle(datumIndex, false);
    const data = [
      {
        label: minName,
        fallbackLabel: minKey,
        value: this.getAxisValueText(yAxis, "tooltip", minValue, datum, minKey, legendItemName),
        missing: module_support_exports.isTooltipValueMissing(minValue)
      },
      {
        label: q1Name,
        fallbackLabel: q1Key,
        value: this.getAxisValueText(yAxis, "tooltip", q1Value, datum, q1Key, legendItemName),
        missing: module_support_exports.isTooltipValueMissing(q1Value)
      },
      {
        label: medianName,
        fallbackLabel: medianKey,
        value: this.getAxisValueText(yAxis, "tooltip", medianValue, datum, medianKey, legendItemName),
        missing: module_support_exports.isTooltipValueMissing(medianValue)
      },
      {
        label: q3Name,
        fallbackLabel: q3Key,
        value: this.getAxisValueText(yAxis, "tooltip", q3Value, datum, q3Key, legendItemName),
        missing: module_support_exports.isTooltipValueMissing(q3Value)
      },
      {
        label: maxName,
        fallbackLabel: maxKey,
        value: this.getAxisValueText(yAxis, "tooltip", maxValue, datum, maxKey, legendItemName),
        missing: module_support_exports.isTooltipValueMissing(maxValue)
      }
    ];
    return this.formatTooltipWithContext(
      tooltip,
      {
        heading: this.getAxisValueText(xAxis, "tooltip", xValue, datum, xKey, legendItemName),
        title: legendItemName ?? yName,
        symbol: this.legendItemSymbol(),
        data
      },
      {
        seriesId,
        datum,
        title: yName,
        xKey,
        xName,
        yName,
        medianKey,
        medianName,
        q1Key,
        q1Name,
        q3Key,
        q3Name,
        minKey,
        minName,
        maxKey,
        maxName,
        ...format
      }
    );
  }
  animateEmptyUpdateReady({
    datumSelection
  }) {
    const isVertical = this.isVertical();
    const { from: from3, to } = prepareBoxPlotFromTo(isVertical);
    motion2.resetMotion([datumSelection], resetBoxPlotSelectionsScalingCenterFn(isVertical));
    motion2.staticFromToMotion(this.id, "datums", this.ctx.animationManager, [datumSelection], from3, to, {
      phase: "initial"
    });
  }
  isLabelEnabled() {
    return false;
  }
  updateDatumSelection(opts) {
    const data = opts.nodeData ?? [];
    if (!processedDataIsAnimatable2(this.processedData)) {
      return opts.datumSelection.update(data);
    }
    return opts.datumSelection.update(data, void 0, (datum) => createDatumId7(datum.datumIndex));
  }
  makeStylerParams(highlightStateEnum) {
    const { id: seriesId } = this;
    const {
      cornerRadius,
      cap: { lengthRatio },
      fill,
      fillOpacity,
      lineDash,
      lineDashOffset,
      stroke: stroke3,
      strokeOpacity,
      strokeWidth,
      maxKey,
      maxName,
      medianKey,
      medianName,
      minKey,
      minName,
      q1Key,
      q1Name,
      q3Key,
      q3Name,
      whisker: {
        lineDash: whiskerLineDash,
        lineDashOffset: whiskerLineDashOffset,
        stroke: whiskerStroke,
        strokeOpacity: whiskerStrokeOpacity,
        strokeWidth: whiskerStrokeWidth
      },
      xKey,
      xName,
      yName
    } = this.properties;
    const highlightState = toHighlightString2(highlightStateEnum ?? HighlightState4.None);
    return {
      cap: { lengthRatio },
      cornerRadius,
      fill,
      fillOpacity,
      highlightState,
      lineDash,
      lineDashOffset,
      maxKey,
      maxName: maxName ?? maxKey,
      medianKey,
      medianName: medianName ?? medianKey,
      minKey,
      minName: minName ?? minKey,
      q1Key,
      q1Name: q1Name ?? q1Key,
      q3Key,
      q3Name: q3Name ?? q3Key,
      seriesId,
      stroke: stroke3,
      strokeOpacity,
      strokeWidth,
      whisker: {
        lineDash: whiskerLineDash ?? lineDash,
        lineDashOffset: whiskerLineDashOffset ?? lineDashOffset,
        stroke: whiskerStroke ?? stroke3,
        strokeOpacity: whiskerStrokeOpacity ?? strokeOpacity,
        strokeWidth: whiskerStrokeWidth ?? strokeWidth
      },
      xKey,
      xName: xName ?? xKey,
      yName
    };
  }
  getStyle(ignoreStylerCallback, highlightState) {
    const {
      cap,
      cornerRadius,
      fill,
      fillOpacity,
      lineDash,
      lineDashOffset,
      stroke: stroke3,
      strokeOpacity,
      strokeWidth,
      styler,
      whisker
    } = this.properties;
    let stylerResult = {};
    if (!ignoreStylerCallback && styler) {
      const stylerParams = this.makeStylerParams(highlightState);
      stylerResult = this.ctx.optionsGraphService.resolvePartial(
        ["series", `${this.declarationOrder}`],
        this.cachedCallWithContext(styler, stylerParams) ?? {},
        { pick: false }
      ) ?? {};
    }
    return {
      cornerRadius: stylerResult.cornerRadius ?? cornerRadius,
      fill: stylerResult.fill ?? fill,
      fillOpacity: stylerResult.fillOpacity ?? fillOpacity,
      lineDash: stylerResult.lineDash ?? lineDash,
      lineDashOffset: stylerResult.lineDashOffset ?? lineDashOffset,
      opacity: 1,
      stroke: stylerResult.stroke ?? stroke3,
      strokeOpacity: stylerResult.strokeOpacity ?? strokeOpacity,
      strokeWidth: stylerResult.strokeWidth ?? strokeWidth,
      cap: { lengthRatio: stylerResult.cap?.lengthRatio ?? cap.lengthRatio },
      whisker: {
        lineDash: stylerResult.whisker?.lineDash ?? whisker.lineDash,
        lineDashOffset: stylerResult.whisker?.lineDashOffset ?? whisker.lineDashOffset,
        stroke: stylerResult.whisker?.stroke ?? whisker.stroke,
        strokeOpacity: stylerResult.whisker?.strokeOpacity ?? whisker.strokeOpacity,
        strokeWidth: stylerResult.whisker?.strokeWidth ?? whisker.strokeWidth
      }
    };
  }
  getItemStyle(datumIndex, isHighlight, highlightState) {
    const { properties } = this;
    const { itemStyler } = properties;
    const highlightStyle = this.getHighlightStyle(isHighlight, datumIndex, highlightState);
    let style2 = mergeDefaults(highlightStyle, this.getStyle(datumIndex === void 0, highlightState));
    if (itemStyler != null && datumIndex != null) {
      const overrides = this.cachedDatumCallback(
        createDatumId7(datumIndex, isHighlight ? "highlight" : "node"),
        () => {
          const params = this.makeItemStylerParams(datumIndex, isHighlight, style2);
          return this.ctx.optionsGraphService.resolvePartial(
            ["series", `${this.declarationOrder}`],
            this.callWithContext(itemStyler, params)
          );
        }
      );
      if (overrides) {
        style2 = mergeDefaults(overrides, style2);
      }
    }
    const { stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = style2;
    style2.whisker = mergeDefaults(style2.whisker, {
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset
    });
    return style2;
  }
  makeItemStylerParams(datumIndex, isHighlight, style2) {
    const { id: seriesId } = this;
    const { xKey, minKey, q1Key, medianKey, q3Key, maxKey } = this.properties;
    const datum = this.processedData?.dataSources.get(seriesId)?.data[datumIndex];
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const highlightStateString = this.getHighlightStateString(activeHighlight, isHighlight, datumIndex);
    const fill = this.filterItemStylerFillParams(style2.fill) ?? style2.fill;
    return {
      seriesId,
      datum,
      xKey,
      minKey,
      q1Key,
      medianKey,
      q3Key,
      maxKey,
      highlightState: highlightStateString,
      ...style2,
      fill
    };
  }
  updateDatumStyles({
    datumSelection,
    isHighlight
  }) {
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    datumSelection.each((_, nodeDatum) => {
      const highlightState = this.getHighlightState(highlightedDatum, isHighlight, nodeDatum.datumIndex);
      nodeDatum.style = this.getItemStyle(nodeDatum.datumIndex, isHighlight, highlightState);
    });
  }
  updateDatumNodes({
    datumSelection,
    isHighlight
  }) {
    const { contextNodeData, properties } = this;
    if (!contextNodeData) {
      return;
    }
    const isVertical = this.isVertical();
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    const fillBBox = this.getShapeFillBBox();
    const strokeAlignment = this.getStyle(false, HighlightState4.None).strokeWidth / 2;
    const wickStrokeAlignment = properties.whisker.strokeWidth ?? properties.strokeWidth;
    datumSelection.each((boxPlotNode, nodeDatum) => {
      const style2 = nodeDatum.style ?? contextNodeData.styles[this.getHighlightState(highlightedDatum, isHighlight, nodeDatum.datumIndex)];
      boxPlotNode.setFillProperties(style2.fill, fillBBox);
      const nodeOpacity = style2.opacity ?? 1;
      const whiskerOpacity = style2.whisker?.strokeOpacity ?? style2.strokeOpacity;
      boxPlotNode.fill = style2.fill;
      boxPlotNode.fillOpacity = style2.fillOpacity * nodeOpacity;
      boxPlotNode.stroke = style2.stroke;
      boxPlotNode.strokeWidth = style2.strokeWidth;
      boxPlotNode.strokeOpacity = style2.strokeOpacity * nodeOpacity;
      boxPlotNode.lineDash = style2.lineDash;
      boxPlotNode.lineDashOffset = style2.lineDashOffset;
      boxPlotNode.wickStroke = style2.whisker.stroke;
      boxPlotNode.wickStrokeWidth = style2.whisker.strokeWidth;
      boxPlotNode.wickStrokeOpacity = whiskerOpacity * nodeOpacity;
      boxPlotNode.wickLineDash = style2.whisker.lineDash;
      boxPlotNode.wickLineDashOffset = style2.whisker.lineDashOffset;
      boxPlotNode.cornerRadius = style2.cornerRadius;
      boxPlotNode.crisp = true;
      boxPlotNode.horizontal = !isVertical;
      boxPlotNode.center = nodeDatum.scaledValues.xValue;
      boxPlotNode.thickness = nodeDatum.bandwidth;
      boxPlotNode.min = nodeDatum.scaledValues.minValue;
      boxPlotNode.q1 = nodeDatum.scaledValues.q1Value;
      boxPlotNode.median = nodeDatum.scaledValues.medianValue;
      boxPlotNode.q3 = nodeDatum.scaledValues.q3Value;
      boxPlotNode.max = nodeDatum.scaledValues.maxValue;
      boxPlotNode.capLengthRatio = style2.cap.lengthRatio;
      boxPlotNode.strokeAlignment = strokeAlignment;
      boxPlotNode.wickStrokeAlignment = wickStrokeAlignment;
    });
  }
  updateLabelNodes() {
  }
  updateLabelSelection(opts) {
    const { labelData, labelSelection } = opts;
    return labelSelection.update(labelData);
  }
  nodeFactory() {
    return new BoxPlotNode();
  }
  computeFocusBounds({ datumIndex }) {
    return computeBarFocusBounds2(this, this.contextNodeData?.nodeData[datumIndex].focusRect);
  }
  hasItemStylers() {
    return this.properties.itemStyler != null || this.properties.styler != null;
  }
};
BoxPlotSeries.className = "BoxPlotSeries";
BoxPlotSeries.type = "box-plot";

// packages/ag-charts-enterprise/src/series/box-plot/boxPlotSeriesOptionsDef.ts
var { boxPlotSeriesThemeableOptionsDef: boxPlotSeriesThemeableOptionsDef2 } = module_support_exports;
var boxPlotSeriesOptionsDef = {
  ...commonSeriesOptionsDefs,
  ...boxPlotSeriesThemeableOptionsDef2,
  type: required(constant("box-plot")),
  xKey: required(string),
  minKey: required(string),
  q1Key: required(string),
  medianKey: required(string),
  q3Key: required(string),
  maxKey: required(string),
  xKeyAxis: string,
  yKeyAxis: string,
  xName: string,
  yName: string,
  minName: string,
  q1Name: string,
  medianName: string,
  q3Name: string,
  maxName: string,
  grouped: boolean,
  legendItemName: string,
  segmentation: shapeSegmentation,
  width: positiveNumberNonZero,
  widthRatio: ratio
};

// packages/ag-charts-enterprise/src/series/box-plot/boxPlotThemes.ts
var BOX_PLOT_SERIES_THEME = {
  series: {
    direction: "vertical",
    fill: {
      $applySwitch: [
        { $path: "type" },
        {
          $if: [
            {
              $or: [
                { $isGradient: { $palette: "fill" } },
                { $isPattern: { $palette: "fill" } },
                { $isImage: { $palette: "fill" } }
              ]
            },
            { $palette: "fill" },
            { $mix: [SAFE_FILL_OPERATION, { $ref: "chartBackgroundColor" }, 0.7] }
          ]
        },
        ["gradient", FILL_GRADIENT_LINEAR_DEFAULTS],
        ["image", FILL_IMAGE_DEFAULTS],
        ["pattern", FILL_PATTERN_DEFAULTS]
      ]
    },
    stroke: { $palette: "stroke" },
    strokeWidth: 2,
    fillOpacity: 1,
    strokeOpacity: 1,
    lineDash: void 0,
    lineDashOffset: 0,
    highlight: {
      unhighlightedItem: {
        opacity: 0.5
      },
      unhighlightedSeries: {
        opacity: 0.1
      }
    },
    segmentation: SEGMENTATION_DEFAULTS
  },
  axes: {
    ["number" /* NUMBER */]: {
      crosshair: {
        snap: false
      }
    },
    ["category" /* CATEGORY */]: {
      groupPaddingInner: 0.2,
      crosshair: {
        enabled: false,
        snap: false
      }
    }
  }
};

// packages/ag-charts-enterprise/src/series/box-plot/boxPlotModule.ts
var { predictCartesianNonPrimitiveAxis: predictCartesianNonPrimitiveAxis2 } = module_support_exports;
var BoxPlotSeriesModule = {
  type: "series",
  name: "box-plot",
  chartType: "cartesian",
  enterprise: true,
  groupable: true,
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: boxPlotSeriesOptionsDef,
  matchingKeys: ["xKey", "lowKey", "q1Key", "medianKey", "q3Key", "highKey", "outlierKey", "normalizedTo"],
  predictAxis: predictCartesianNonPrimitiveAxis2,
  defaultAxes: DIRECTION_SWAP_AXES,
  axisKeys: { ["x" /* X */]: "xKeyAxis", ["y" /* Y */]: "yKeyAxis" },
  axisKeysFlipped: { ["x" /* X */]: "yKeyAxis", ["y" /* Y */]: "xKeyAxis" },
  themeTemplate: BOX_PLOT_SERIES_THEME,
  create: (ctx) => new BoxPlotSeries(ctx)
};

// packages/ag-charts-enterprise/src/series/ohlc/ohlcAggregation.ts
function aggregateOhlcData(scale2, xValues, highValues, lowValues, domainInput, smallestKeyInterval, xNeedsValueOf, yNeedsValueOf) {
  const [d0, d1] = aggregationDomain(scale2, domainInput);
  return computeExtremesAggregation([d0, d1], xValues, highValues, lowValues, {
    smallestKeyInterval,
    xNeedsValueOf,
    yNeedsValueOf
  });
}
var memoizedAggregateOhlcData = simpleMemorize2(aggregateOhlcData);
function aggregateOhlcDataFromDataModel(scale2, dataModel, processedData, series, existingFilters) {
  const xValues = dataModel.resolveKeysById(series, "xValue", processedData);
  const highValues = dataModel.resolveColumnById(series, "highValue", processedData);
  const lowValues = dataModel.resolveColumnById(series, "lowValue", processedData);
  const domainInput = dataModel.getDomain(series, "xValue", "key", processedData);
  const xNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "xValue", processedData);
  const yNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "highValue", processedData) ?? dataModel.resolveColumnNeedsValueOf(series, "lowValue", processedData);
  if (existingFilters) {
    const [d0, d1] = aggregationDomain(scale2, domainInput);
    return computeExtremesAggregation([d0, d1], xValues, highValues, lowValues, {
      smallestKeyInterval: processedData.reduced?.smallestKeyInterval,
      xNeedsValueOf,
      yNeedsValueOf,
      existingFilters
    });
  }
  return memoizedAggregateOhlcData(
    scale2,
    xValues,
    highValues,
    lowValues,
    domainInput,
    processedData.reduced?.smallestKeyInterval,
    xNeedsValueOf,
    yNeedsValueOf
  );
}
function aggregateOhlcDataFromDataModelPartial(scale2, dataModel, processedData, series, targetRange, existingFilters) {
  const xValues = dataModel.resolveKeysById(series, "xValue", processedData);
  const highValues = dataModel.resolveColumnById(series, "highValue", processedData);
  const lowValues = dataModel.resolveColumnById(series, "lowValue", processedData);
  const domainInput = dataModel.getDomain(series, "xValue", "key", processedData);
  const xNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "xValue", processedData);
  const yNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "highValue", processedData) ?? dataModel.resolveColumnNeedsValueOf(series, "lowValue", processedData);
  const [d0, d1] = aggregationDomain(scale2, domainInput);
  return computeExtremesAggregationPartial([d0, d1], xValues, highValues, lowValues, {
    smallestKeyInterval: processedData.reduced?.smallestKeyInterval,
    targetRange,
    xNeedsValueOf,
    yNeedsValueOf,
    existingFilters
  });
}

// packages/ag-charts-enterprise/src/series/ohlc/ohlcNode.ts
var { Path: Path8, BBox: BBox18 } = module_support_exports;
var OhlcBaseNode = class extends Path8 {
  constructor() {
    super(...arguments);
    this.centerX = 0;
    this.y = 0;
    this.width = 0;
    this.height = 0;
    this.yOpen = 0;
    this.yClose = 0;
    this.crisp = false;
  }
  /**
   * High-performance static property setter that bypasses the decorator system entirely.
   * Writes directly to backing fields (__propertyName) to avoid:
   * - Decorator setter chains and equality checks
   * - Multiple onChangeDetection calls per property
   * - Object.keys() iteration in assignIfNotStrictlyEqual
   * - Object allocation overhead
   *
   * A single markDirty() call at the end ensures the scene graph is properly invalidated.
   * WARNING: Only use for hot paths where performance is critical and properties don't need
   * individual change detection (e.g., when updating many nodes in a loop).
   */
  setStaticProperties(centerX, width2, y, height2, yOpen, yClose, crisp) {
    this.__centerX = centerX;
    this.__width = width2;
    this.__y = y;
    this.__height = height2;
    this.__yOpen = yOpen;
    this.__yClose = yClose;
    this.__crisp = crisp;
    this.dirtyPath = true;
    this.markDirty();
  }
  computeBBox() {
    const { __centerX: centerX, __y: y, __width: width2, __height: height2 } = this;
    return new BBox18(centerX - width2 / 2, y, width2, height2);
  }
  isPointInPath(x, y) {
    return this.getBBox().containsPoint(x, y);
  }
  distanceSquared(x, y) {
    return this.getBBox().distanceSquared(x, y);
  }
  get midPoint() {
    return { x: this.__centerX, y: this.__y + this.__height / 2 };
  }
  alignedCoordinates() {
    const { __y: y, __width: width2, __height: height2, __crisp: crisp } = this;
    let { __centerX: centerX, __yOpen: yOpen, __yClose: yClose } = this;
    let x0 = centerX - width2 / 2;
    let x1 = centerX + width2 / 2;
    let y0 = y;
    let y1 = y + height2;
    if (crisp && width2 > 1) {
      centerX = this.align(centerX);
      if (yOpen <= yClose) {
        const h = this.align(yOpen, yClose - yOpen);
        yOpen = this.align(yOpen);
        yClose = yOpen + h;
      } else {
        const h = this.align(yClose, yOpen - yClose);
        yClose = this.align(yClose);
        yOpen = yClose + h;
      }
      const halfWidth = this.align(width2 / 2);
      x0 = centerX - halfWidth;
      x1 = centerX + halfWidth;
      y0 = this.align(y);
      y1 = y0 + this.align(y0, height2);
    }
    return { centerX, x0, x1, y0, y1, yOpen, yClose };
  }
  executeStroke(ctx, path) {
    const { __width: width2, strokeWidth } = this;
    if (width2 < strokeWidth) {
      ctx.lineWidth = width2;
    }
    super.executeStroke(ctx, path);
  }
};
__decorateClass([
  DeclaredSceneChangeDetection()
], OhlcBaseNode.prototype, "centerX", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], OhlcBaseNode.prototype, "y", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], OhlcBaseNode.prototype, "width", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], OhlcBaseNode.prototype, "height", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], OhlcBaseNode.prototype, "yOpen", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], OhlcBaseNode.prototype, "yClose", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], OhlcBaseNode.prototype, "crisp", 2);
var OhlcNode = class extends OhlcBaseNode {
  constructor() {
    super(...arguments);
    this.strokeAlignment = 0;
  }
  updatePath() {
    const { path } = this;
    const { centerX, x0, x1, y0, y1, yOpen, yClose } = this.alignedCoordinates();
    const pixelRatio = this.layerManager?.canvas.pixelRatio ?? 1;
    const strokeAlignment = this.__strokeAlignment > 0 ? pixelRatio / this.__strokeAlignment / 2 % 1 : 0;
    path.clear();
    path.moveTo(centerX - strokeAlignment, y0);
    path.lineTo(centerX - strokeAlignment, y1);
    if (Math.abs(x1 - x0) > 1) {
      path.moveTo(x0, yOpen - strokeAlignment);
      path.lineTo(centerX - strokeAlignment, yOpen - strokeAlignment);
      path.moveTo(centerX - strokeAlignment, yClose - strokeAlignment);
      path.lineTo(x1, yClose - strokeAlignment);
    }
  }
};
__decorateClass([
  DeclaredSceneChangeDetection()
], OhlcNode.prototype, "strokeAlignment", 2);

// packages/ag-charts-enterprise/src/series/ohlc/ohlcSeriesBase.ts
var OPEN = AGGREGATION_INDEX_X_MIN;
var HIGH = AGGREGATION_INDEX_Y_MAX;
var LOW = AGGREGATION_INDEX_Y_MIN;
var CLOSE = AGGREGATION_INDEX_X_MAX;
var SPAN2 = AGGREGATION_SPAN;
var {
  AggregationManager: AggregationManager2,
  fixNumericExtent: fixNumericExtent4,
  keyProperty: keyProperty5,
  createDatumId: createDatumId8,
  SeriesNodePickMode: SeriesNodePickMode6,
  SMALLEST_KEY_INTERVAL: SMALLEST_KEY_INTERVAL3,
  valueProperty: valueProperty7,
  diff: diff3,
  animationValidation: animationValidation3,
  computeBarFocusBounds: computeBarFocusBounds3,
  visibleRangeIndices: visibleRangeIndices2,
  BandScale: BandScale2,
  processedDataIsAnimatable: processedDataIsAnimatable3,
  getItemStylesPerItemId: getItemStylesPerItemId2
} = module_support_exports;
var OhlcSeriesNodeEvent = class extends module_support_exports.SeriesNodeEvent {
  constructor(type, nativeEvent, datum, series) {
    super(type, nativeEvent, datum, series);
    this.xKey = series.properties.xKey;
    this.openKey = series.properties.openKey;
    this.closeKey = series.properties.closeKey;
    this.highKey = series.properties.highKey;
    this.lowKey = series.properties.lowKey;
  }
};
function resetOhlcSelectionsDirect(selections) {
  for (const selection of selections) {
    const nodes = selection.nodes();
    selection.batchedUpdate(function resetOhlcNodes() {
      for (const node of nodes) {
        const datum = node.datum;
        if (datum == null)
          continue;
        node.setStaticProperties(
          datum.centerX,
          datum.width,
          datum.y,
          datum.height,
          datum.yOpen,
          datum.yClose,
          datum.crisp
        );
      }
      selection.cleanup();
    });
  }
}
var OhlcSeriesBase = class extends module_support_exports.AbstractBarSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      pickModes: [SeriesNodePickMode6.AXIS_ALIGNED, SeriesNodePickMode6.EXACT_SHAPE_MATCH],
      propertyKeys: {
        x: ["xKey"],
        y: ["lowKey", "highKey", "openKey", "closeKey"]
      },
      propertyNames: {
        x: ["xName"],
        y: ["lowName", "highName", "openName", "closeName"]
      },
      categoryKey: "xValue",
      pathsPerSeries: []
    });
    this.NodeEvent = OhlcSeriesNodeEvent;
    this.aggregationManager = new AggregationManager2();
  }
  async processData(dataController) {
    if (!this.visible)
      return;
    const { xKey, openKey, closeKey, highKey, lowKey } = this.properties;
    const animationEnabled = !this.ctx.animationManager.isSkipped();
    const xScale = this.getCategoryAxis()?.scale;
    const yScale = this.getValueAxis()?.scale;
    const { isContinuousX, xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale });
    const extraProps = [];
    if (this.needsDataModelDiff() && this.processedData) {
      extraProps.push(diff3(this.id, this.processedData));
    }
    if (animationEnabled) {
      extraProps.push(animationValidation3());
    }
    if (openKey) {
      extraProps.push(
        valueProperty7(openKey, yScaleType, {
          id: `openValue`,
          invalidValue: void 0,
          missingValue: void 0
        })
      );
    }
    const allowNullKey = this.properties.allowNullKeys ?? false;
    const { dataModel, processedData } = await this.requestDataModel(dataController, this.data, {
      props: [
        keyProperty5(xKey, xScaleType, { id: `xValue`, allowNullKey }),
        valueProperty7(closeKey, yScaleType, { id: `closeValue` }),
        valueProperty7(highKey, yScaleType, { id: `highValue` }),
        valueProperty7(lowKey, yScaleType, { id: `lowValue` }),
        ...isContinuousX ? [SMALLEST_KEY_INTERVAL3] : [],
        ...extraProps
      ]
    });
    this.smallestDataInterval = processedData.reduced?.smallestKeyInterval;
    this.aggregateData(dataModel, processedData);
    this.animationState.transition("updateData");
  }
  aggregateData(dataModel, processedData) {
    this.aggregationManager.markStale(processedData.input.count);
    if (processedData.type !== "ungrouped")
      return;
    if (processedDataIsAnimatable3(processedData))
      return;
    const xAxis = this.axes["x" /* X */];
    if (xAxis == null)
      return;
    const targetRange = this.estimateTargetRange();
    this.aggregationManager.aggregate({
      computePartial: (existingFilters) => aggregateOhlcDataFromDataModelPartial(
        xAxis.scale.type,
        dataModel,
        processedData,
        this,
        targetRange,
        existingFilters
      ),
      computeFull: (existingFilters) => aggregateOhlcDataFromDataModel(xAxis.scale.type, dataModel, processedData, this, existingFilters),
      targetRange
    });
    const filters = this.aggregationManager.filters;
    if (filters && filters.length > 0) {
      debugMetrics_exports.record(
        `${this.type}:aggregation`,
        filters.map((f) => f.maxRange)
      );
    }
  }
  estimateTargetRange() {
    const xAxis = this.axes["x" /* X */];
    if (!xAxis)
      return -1;
    const [r0, r1] = xAxis.scale.range;
    return Math.abs(r1 - r0);
  }
  getSeriesDomain(direction) {
    const { processedData, dataModel } = this;
    if (!(processedData && dataModel))
      return { domain: [] };
    if (direction !== this.getBarDirection()) {
      const { def } = dataModel.resolveProcessedDataDefById(this, `xValue`);
      const keys = dataModel.getDomain(this, `xValue`, "key", processedData);
      if (def.type === "key" && def.valueType === "category") {
        return keys;
      }
      return { domain: this.padBandExtent(keys.domain) };
    }
    const yExtent = this.domainForClippedRange(direction, ["highValue", "lowValue"], "xValue");
    return { domain: fixNumericExtent4(yExtent) };
  }
  getSeriesRange(_direction, visibleRange) {
    return this.domainForVisibleRange("y" /* Y */, ["highValue", "lowValue"], "xValue", visibleRange);
  }
  getZoomRangeFittingItems(xVisibleRange, yVisibleRange, minVisibleItems) {
    return this.zoomFittingVisibleItems(
      "xValue",
      ["highValue", "lowValue"],
      xVisibleRange,
      yVisibleRange,
      minVisibleItems
    );
  }
  getVisibleItems(xVisibleRange, yVisibleRange, minVisibleItems) {
    return this.countVisibleItems(
      "xValue",
      ["highValue", "lowValue"],
      xVisibleRange,
      yVisibleRange,
      minVisibleItems
    );
  }
  /**
   * Creates shared context for node datum creation/update operations.
   * This context is instantiated once and reused across all datum operations
   * to minimize memory allocations. Only caches values that are expensive to
   * compute - cheap property lookups use `this` directly.
   */
  buildDatumContext(xAxis, yAxis) {
    const { dataModel, processedData } = this;
    if (!dataModel || !processedData)
      return void 0;
    const rawData = processedData.dataSources.get(this.id)?.data ?? [];
    if (rawData.length === 0)
      return void 0;
    const xScale = xAxis.scale;
    const yScale = yAxis.scale;
    const applyWidthOffset = BandScale2.is(xScale);
    const [r0, r1] = xScale.range;
    const range3 = Math.abs(r1 - r0);
    this.aggregationManager.ensureLevelForRange(range3);
    const dataAggregationFilter = this.aggregationManager.getFilterForRange(range3);
    const crisp = dataAggregationFilter == null;
    const canIncrementallyUpdate = this.contextNodeData?.nodeData != null && (processedData.changeDescription != null || !processedDataIsAnimatable3(processedData) || dataAggregationFilter != null);
    const { groupOffset, barWidth } = this.getBarDimensions();
    return {
      rawData,
      xValues: dataModel.resolveKeysById(this, "xValue", processedData),
      openValues: dataModel.resolveColumnById(this, "openValue", processedData),
      closeValues: dataModel.resolveColumnById(this, "closeValue", processedData),
      highValues: dataModel.resolveColumnById(this, "highValue", processedData),
      lowValues: dataModel.resolveColumnById(this, "lowValue", processedData),
      xScale,
      yScale,
      xAxis,
      yAxis,
      groupOffset,
      barWidth,
      applyWidthOffset,
      // TODO: replace with barOffset?
      crisp,
      xKey: this.properties.xKey,
      openKey: this.properties.openKey,
      closeKey: this.properties.closeKey,
      highKey: this.properties.highKey,
      lowKey: this.properties.lowKey,
      dataAggregationFilter,
      range: range3,
      nodeDatumStateScratch: {
        datum: void 0,
        xValue: void 0,
        openValue: 0,
        closeValue: 0,
        highValue: 0,
        lowValue: 0,
        isRising: true,
        itemType: "up"
      },
      canIncrementallyUpdate,
      nodeIndex: 0,
      nodeData: canIncrementallyUpdate ? this.contextNodeData.nodeData : []
    };
  }
  /**
   * Validates and prepares state for a single OHLC datum.
   * Mutates ctx.nodeDatumStateScratch with computed values.
   * Returns the scratch object if valid, undefined if invalid.
   */
  prepareOhlcNodeDatumState(ctx, datumIndex) {
    const xValue = ctx.xValues[datumIndex];
    if (xValue === void 0 && !this.properties.allowNullKeys) {
      return void 0;
    }
    const openValue = ctx.openValues[datumIndex];
    const closeValue = ctx.closeValues[datumIndex];
    const highValue = ctx.highValues[datumIndex];
    const lowValue = ctx.lowValues[datumIndex];
    const validLowValue = lowValue != null && lowValue <= openValue && lowValue <= closeValue;
    const validHighValue = highValue != null && highValue >= openValue && highValue >= closeValue;
    if (!validLowValue) {
      logger_exports.warnOnce(
        `invalid low value for key [${ctx.lowKey}] in data element, low value cannot be higher than datum open or close values`
      );
      return void 0;
    }
    if (!validHighValue) {
      logger_exports.warnOnce(
        `invalid high value for key [${ctx.highKey}] in data element, high value cannot be lower than datum open or close values.`
      );
      return void 0;
    }
    const datum = ctx.rawData[datumIndex];
    const isRising = closeValue > openValue;
    const itemType = isRising ? "up" : "down";
    const scratch = ctx.nodeDatumStateScratch;
    scratch.datum = datum;
    scratch.xValue = xValue;
    scratch.openValue = openValue;
    scratch.closeValue = closeValue;
    scratch.highValue = highValue;
    scratch.lowValue = lowValue;
    scratch.isRising = isRising;
    scratch.itemType = itemType;
    return scratch;
  }
  /**
   * Creates a skeleton OhlcNodeDatum from prepared state.
   * Takes pre-computed positioning and state from scratch object.
   */
  createSkeletonNodeDatum(ctx, scratch, datumIndex, centerX, width2, crisp) {
    const xOffset = ctx.applyWidthOffset ? width2 / 2 : 0;
    const adjustedCenterX = centerX + xOffset;
    const yOpen = ctx.yScale.convert(scratch.openValue);
    const yClose = ctx.yScale.convert(scratch.closeValue);
    const yHigh = ctx.yScale.convert(scratch.highValue);
    const yLow = ctx.yScale.convert(scratch.lowValue);
    const y = Math.min(yHigh, yLow);
    const height2 = Math.max(yHigh, yLow) - y;
    return {
      series: this,
      itemType: scratch.itemType,
      datum: scratch.datum,
      datumIndex,
      xKey: ctx.xKey,
      xValue: scratch.xValue,
      openValue: scratch.openValue,
      closeValue: scratch.closeValue,
      highValue: scratch.highValue,
      lowValue: scratch.lowValue,
      midPoint: {
        x: adjustedCenterX,
        y: y + height2 / 2
      },
      aggregatedValue: scratch.closeValue,
      isRising: scratch.isRising,
      centerX: adjustedCenterX,
      width: width2,
      y,
      height: height2,
      yOpen,
      yClose,
      crisp
    };
  }
  /**
   * Updates an existing OhlcNodeDatum in-place for value-only changes.
   * This is more efficient than recreating the entire node when only data values change
   * but the structure (insertions/removals) remains the same.
   */
  updateNodeDatum(ctx, node, prepared, datumIndex, centerX, width2, crisp) {
    const mutableNode = node;
    const xOffset = ctx.applyWidthOffset ? width2 / 2 : 0;
    const adjustedCenterX = centerX + xOffset;
    const yOpen = ctx.yScale.convert(prepared.openValue);
    const yClose = ctx.yScale.convert(prepared.closeValue);
    const yHigh = ctx.yScale.convert(prepared.highValue);
    const yLow = ctx.yScale.convert(prepared.lowValue);
    const y = Math.min(yHigh, yLow);
    const height2 = Math.max(yHigh, yLow) - y;
    mutableNode.datum = prepared.datum;
    mutableNode.datumIndex = datumIndex;
    mutableNode.itemType = prepared.itemType;
    mutableNode.xValue = prepared.xValue;
    mutableNode.openValue = prepared.openValue;
    mutableNode.closeValue = prepared.closeValue;
    mutableNode.highValue = prepared.highValue;
    mutableNode.lowValue = prepared.lowValue;
    mutableNode.aggregatedValue = prepared.closeValue;
    mutableNode.isRising = prepared.isRising;
    mutableNode.centerX = adjustedCenterX;
    mutableNode.width = width2;
    mutableNode.y = y;
    mutableNode.height = height2;
    mutableNode.yOpen = yOpen;
    mutableNode.yClose = yClose;
    mutableNode.crisp = crisp;
    const mutableMidPoint = mutableNode.midPoint;
    mutableMidPoint.x = adjustedCenterX;
    mutableMidPoint.y = y + height2 / 2;
  }
  /**
   * Handles node creation/update - reuses existing nodes when possible for incremental updates.
   * This method decides whether to update existing nodes in-place or create new ones.
   */
  upsertNodeDatum(ctx, datumIndex, centerX, width2, crisp) {
    const prepared = this.prepareOhlcNodeDatumState(ctx, datumIndex);
    if (!prepared)
      return;
    const canReuse = ctx.canIncrementallyUpdate && ctx.nodeIndex < ctx.nodeData.length;
    if (canReuse) {
      this.updateNodeDatum(ctx, ctx.nodeData[ctx.nodeIndex], prepared, datumIndex, centerX, width2, crisp);
    } else {
      const newNode = this.createSkeletonNodeDatum(ctx, prepared, datumIndex, centerX, width2, crisp);
      ctx.nodeData.push(newNode);
    }
    ctx.nodeIndex++;
  }
  createNodeData() {
    const { visible } = this;
    const xAxis = this.getCategoryAxis();
    const yAxis = this.getValueAxis();
    if (!xAxis || !yAxis)
      return;
    const ctx = this.buildDatumContext(xAxis, yAxis);
    const resultContext = {
      itemId: this.properties.xKey,
      nodeData: ctx?.nodeData ?? [],
      labelData: [],
      scales: this.calculateScaling(),
      groupScale: this.getScaling(this.ctx.seriesStateManager.getGroupScale(this)),
      visible: this.visible,
      styles: getItemStylesPerItemId2(this.getItemStyle.bind(this), "up", "down")
    };
    if (!visible || !ctx)
      return resultContext;
    const xPosition = (index) => {
      const x = ctx.xScale.convert(ctx.xValues[index]);
      if (!Number.isFinite(x))
        return Number.NaN;
      return x + ctx.groupOffset;
    };
    if (ctx.dataAggregationFilter == null) {
      const invalidData = this.processedData.invalidData?.get(this.id);
      let [start2, end3] = visibleRangeIndices2(1, ctx.rawData.length, ctx.xAxis.range, (index) => {
        const xOffset = ctx.applyWidthOffset ? 0 : -ctx.barWidth / 2;
        const x = xPosition(index) + xOffset;
        return [x, x + ctx.barWidth];
      });
      if (this.processedData.input.count < 1e3) {
        start2 = 0;
        end3 = this.processedData.input.count;
      }
      for (let datumIndex = start2; datumIndex < end3; datumIndex += 1) {
        if (invalidData?.[datumIndex] === true)
          continue;
        const centerX = xPosition(datumIndex);
        this.upsertNodeDatum(ctx, datumIndex, centerX, ctx.barWidth, ctx.crisp);
      }
      if (ctx.canIncrementallyUpdate && ctx.nodeIndex < ctx.nodeData.length) {
        ctx.nodeData.length = ctx.nodeIndex;
      }
    } else {
      const { maxRange, indexData, midpointIndices } = ctx.dataAggregationFilter;
      const [start2, end3] = visibleRangeIndices2(1, maxRange, ctx.xAxis.range, (index) => {
        const aggIndex = index * SPAN2;
        const closeIndex = indexData[aggIndex + CLOSE];
        const midDatumIndex = midpointIndices[index];
        if (midDatumIndex === -1)
          return;
        const xOffset = ctx.applyWidthOffset ? 0 : -ctx.barWidth / 2;
        return [xPosition(midDatumIndex) + xOffset, xPosition(closeIndex) + xOffset + ctx.barWidth];
      });
      for (let i = start2; i < end3; i += 1) {
        const aggIndex = i * SPAN2;
        const openIndex = indexData[aggIndex + OPEN];
        const closeIndex = indexData[aggIndex + CLOSE];
        const highIndex = indexData[aggIndex + HIGH];
        const lowIndex = indexData[aggIndex + LOW];
        const midDatumIndex = midpointIndices[i];
        if (midDatumIndex === -1)
          continue;
        const prepared = this.prepareOhlcNodeDatumState(ctx, midDatumIndex);
        if (!prepared)
          continue;
        prepared.openValue = ctx.openValues[openIndex];
        prepared.closeValue = ctx.closeValues[closeIndex];
        prepared.highValue = ctx.highValues[highIndex];
        prepared.lowValue = ctx.lowValues[lowIndex];
        prepared.isRising = prepared.closeValue > prepared.openValue;
        prepared.itemType = prepared.isRising ? "up" : "down";
        const centerX = xPosition(midDatumIndex);
        const width2 = Math.abs(xPosition(closeIndex) - xPosition(openIndex)) + ctx.barWidth;
        const canReuse = ctx.canIncrementallyUpdate && ctx.nodeIndex < ctx.nodeData.length;
        if (canReuse) {
          this.updateNodeDatum(
            ctx,
            ctx.nodeData[ctx.nodeIndex],
            prepared,
            midDatumIndex,
            centerX,
            width2,
            false
          );
        } else {
          const nodeDatum = this.createSkeletonNodeDatum(ctx, prepared, midDatumIndex, centerX, width2, false);
          ctx.nodeData.push(nodeDatum);
        }
        ctx.nodeIndex++;
      }
      if (ctx.canIncrementallyUpdate && ctx.nodeIndex < ctx.nodeData.length) {
        ctx.nodeData.length = ctx.nodeIndex;
      }
    }
    return resultContext;
  }
  isVertical() {
    return true;
  }
  isLabelEnabled() {
    return false;
  }
  resetDatumAnimation(data) {
    resetOhlcSelectionsDirect([data.datumSelection]);
  }
  updateDatumSelection(opts) {
    const data = opts.nodeData ?? [];
    if (!processedDataIsAnimatable3(this.processedData)) {
      return opts.datumSelection.update(data);
    }
    return opts.datumSelection.update(data, void 0, (datum) => createDatumId8(datum.xValue));
  }
  updateLabelNodes(_opts) {
  }
  updateLabelSelection(opts) {
    const { labelData, labelSelection } = opts;
    return labelSelection.update(labelData);
  }
  getItemStyle(datumIndex, isHighlight, highlightState, itemType = "up") {
    const { properties, dataModel, processedData } = this;
    const { itemStyler } = properties;
    const highlightStyle = this.getHighlightStyle(isHighlight, datumIndex, highlightState);
    const baseStyle = mergeDefaults(highlightStyle, properties.getStyle(itemType));
    let style2 = baseStyle;
    if (itemStyler && dataModel != null && processedData != null && datumIndex != null) {
      const xValue = dataModel.resolveKeysById(this, `xValue`, processedData)[datumIndex];
      const overrides = this.cachedDatumCallback(
        createDatumId8(createDatumId8(xValue), isHighlight ? "highlight" : "node"),
        () => {
          const params = this.makeItemStylerParams(itemType, datumIndex, isHighlight, style2);
          return this.ctx.optionsGraphService.resolvePartial(
            ["series", `${this.declarationOrder}`, "item", itemType],
            this.callWithContext(itemStyler, params)
          );
        }
      );
      if (overrides) {
        style2 = mergeDefaults(overrides, style2);
      }
    }
    return style2;
  }
  makeItemStylerParams(itemType, datumIndex, isHighlight, style2) {
    const { id: seriesId, properties, processedData } = this;
    const { xKey, openKey, closeKey, highKey, lowKey } = properties;
    const datum = processedData.dataSources.get(seriesId)?.data[datumIndex];
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const highlightStateString = this.getHighlightStateString(activeHighlight, isHighlight, datumIndex);
    const params = {
      seriesId,
      datum,
      itemType,
      xKey,
      openKey,
      closeKey,
      highKey,
      lowKey,
      highlightState: highlightStateString,
      ...style2
    };
    if ("fill" in params && "fill" in style2) {
      params.fill = this.filterItemStylerFillParams(style2.fill) ?? style2.fill;
    }
    return params;
  }
  getTooltipContent(datumIndex) {
    const { id: seriesId, dataModel, processedData, properties } = this;
    const {
      xKey,
      xName,
      yName,
      openKey,
      openName,
      highKey,
      highName,
      lowKey,
      lowName,
      closeKey,
      closeName,
      legendItemName,
      tooltip
    } = properties;
    const xAxis = this.getCategoryAxis();
    const yAxis = this.getValueAxis();
    if (!dataModel || !processedData || !xAxis || !yAxis)
      return;
    const datum = processedData.dataSources.get(this.id)?.data[datumIndex];
    const xValue = dataModel.resolveKeysById(this, `xValue`, processedData)[datumIndex];
    const openValue = dataModel.resolveColumnById(this, `openValue`, processedData)[datumIndex];
    const highValue = dataModel.resolveColumnById(this, `highValue`, processedData)[datumIndex];
    const lowValue = dataModel.resolveColumnById(this, `lowValue`, processedData)[datumIndex];
    const closeValue = dataModel.resolveColumnById(this, `closeValue`, processedData)[datumIndex];
    const allowNullKeys = this.properties.allowNullKeys ?? false;
    if (xValue === void 0 && !allowNullKeys)
      return;
    const itemType = closeValue >= openValue ? "up" : "down";
    const item = this.properties.item[itemType];
    const format = this.getItemStyle(datumIndex, false);
    const marker = {
      fill: item.fill ?? item.stroke,
      fillOpacity: item.fillOpacity ?? item.strokeOpacity ?? 1,
      stroke: item.stroke,
      strokeWidth: item.strokeWidth ?? 1,
      strokeOpacity: item.strokeOpacity ?? 1,
      lineDash: item.lineDash ?? [0],
      lineDashOffset: item.lineDashOffset ?? 0
    };
    return this.formatTooltipWithContext(
      tooltip,
      {
        heading: this.getAxisValueText(xAxis, "tooltip", xValue, datum, xKey, legendItemName),
        title: legendItemName,
        symbol: {
          marker
        },
        data: [
          {
            label: openName,
            fallbackLabel: openKey,
            value: this.getAxisValueText(yAxis, "tooltip", openValue, datum, openKey, legendItemName),
            missing: module_support_exports.isTooltipValueMissing(openValue)
          },
          {
            label: highName,
            fallbackLabel: highKey,
            value: this.getAxisValueText(yAxis, "tooltip", highValue, datum, highKey, legendItemName),
            missing: module_support_exports.isTooltipValueMissing(highValue)
          },
          {
            label: lowName,
            fallbackLabel: lowKey,
            value: this.getAxisValueText(yAxis, "tooltip", lowValue, datum, lowKey, legendItemName),
            missing: module_support_exports.isTooltipValueMissing(lowValue)
          },
          {
            label: closeName,
            fallbackLabel: closeKey,
            value: this.getAxisValueText(yAxis, "tooltip", closeValue, datum, closeKey, legendItemName),
            missing: module_support_exports.isTooltipValueMissing(closeValue)
          }
        ]
      },
      {
        seriesId,
        datum,
        title: yName,
        itemType,
        xKey,
        xName,
        yName,
        openKey,
        openName,
        highKey,
        highName,
        lowKey,
        lowName,
        closeKey,
        closeName,
        ...format
      }
    );
  }
  computeFocusBounds(opts) {
    const nodeDatum = this.getNodeData()?.at(opts.datumIndex);
    if (nodeDatum == null)
      return;
    const { centerX, y, width: width2, height: height2 } = nodeDatum;
    const datum = {
      x: centerX - width2 / 2,
      y,
      width: width2,
      height: height2
    };
    return computeBarFocusBounds3(this, datum);
  }
};

// packages/ag-charts-enterprise/src/series/candlestick/candlestickNode.ts
var { ExtendedPath2D: ExtendedPath2D5, BBox: BBox19 } = module_support_exports;
var CandlestickNode = class extends OhlcBaseNode {
  constructor() {
    super(...arguments);
    this.wickPath = new ExtendedPath2D5();
    this.wickStroke = void 0;
    this.wickStrokeWidth = void 0;
    this.wickStrokeOpacity = void 0;
    this.wickStrokeAlignment = 0;
  }
  /**
   * High-performance wick property setter that bypasses the decorator system entirely.
   * Writes directly to backing fields (__propertyName) to avoid:
   * - Decorator setter chains and equality checks
   * - Multiple onChangeDetection calls per property
   * - Object.keys() iteration in assignIfNotStrictlyEqual
   * - Object allocation overhead
   *
   * A single markDirty() call at the end ensures the scene graph is properly invalidated.
   * WARNING: Only use for hot paths where performance is critical and properties don't need
   * individual change detection (e.g., when updating many nodes in a loop).
   */
  setWickProperties(wickStroke, wickStrokeWidth, wickStrokeOpacity, wickLineDash, wickLineDashOffset) {
    this.__wickStroke = wickStroke;
    this.__wickStrokeWidth = wickStrokeWidth;
    this.__wickStrokeOpacity = wickStrokeOpacity;
    this.wickLineDash = wickLineDash;
    this.__wickLineDashOffset = wickLineDashOffset;
    this.dirtyPath = true;
    this.markDirty();
  }
  computeDefaultGradientFillBBox() {
    const { __width: width2, __centerX: centerX, __yOpen: yOpen, __yClose: yClose } = this;
    const boxTop = Math.min(yOpen, yClose);
    const boxBottom = Math.max(yOpen, yClose);
    const rectHeight = boxBottom - boxTop;
    const x0 = centerX - width2 / 2;
    const x1 = centerX + width2 / 2;
    return new BBox19(x0, boxTop, x1 - x0, rectHeight);
  }
  updatePath() {
    const {
      path,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset,
      __wickStroke: wickStroke,
      __wickStrokeWidth: wickStrokeWidth,
      __wickStrokeOpacity: wickStrokeOpacity,
      wickLineDash,
      __wickLineDashOffset: wickLineDashOffset
    } = this;
    const { centerX, x0, x1, y0, y1, yOpen, yClose } = this.alignedCoordinates();
    const pixelRatio = this.layerManager?.canvas.pixelRatio ?? 1;
    const wickStrokeAlignment = this.__wickStrokeAlignment > 0 ? pixelRatio / this.__wickStrokeAlignment / 2 % 1 : 0;
    this.path.clear();
    this.wickPath.clear();
    const needsWickPath = wickStroke != null && wickStroke !== stroke3 || wickStrokeWidth != null && wickStrokeWidth !== strokeWidth || wickStrokeOpacity != null && wickStrokeOpacity !== strokeOpacity || wickLineDash != null && wickLineDash !== lineDash || wickLineDashOffset != null && wickLineDashOffset !== lineDashOffset;
    const wickPath = needsWickPath ? this.wickPath : path;
    if (Math.abs(x1 - x0) <= 3) {
      wickPath.moveTo(centerX - wickStrokeAlignment, y0);
      wickPath.lineTo(centerX - wickStrokeAlignment, y1);
      return;
    }
    const boxTop = Math.min(yOpen, yClose);
    const boxBottom = Math.max(yOpen, yClose);
    const boxStrokeAdjustment = strokeWidth / 2;
    wickPath.moveTo(centerX - wickStrokeAlignment, y0);
    wickPath.lineTo(centerX - wickStrokeAlignment, boxTop + boxStrokeAdjustment);
    wickPath.moveTo(centerX - wickStrokeAlignment, y1);
    wickPath.lineTo(centerX - wickStrokeAlignment, boxBottom - boxStrokeAdjustment);
    const rectHeight = boxBottom - boxTop - 2 * boxStrokeAdjustment;
    if (rectHeight > 0) {
      path.rect(
        x0 + boxStrokeAdjustment,
        boxTop + boxStrokeAdjustment,
        x1 - x0 - 2 * boxStrokeAdjustment,
        rectHeight
      );
    } else {
      const boxMid = (boxTop + boxBottom) / 2;
      path.moveTo(x0, boxMid);
      path.lineTo(x1, boxMid);
    }
  }
  drawPath(ctx) {
    super.drawPath(ctx);
    const { wickPath } = this;
    if (wickPath.isEmpty())
      return;
    const {
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset,
      __wickStroke: wickStroke = stroke3,
      __wickStrokeWidth: wickStrokeWidth = strokeWidth,
      __wickStrokeOpacity: wickStrokeOpacity = strokeOpacity,
      wickLineDash = lineDash,
      __wickLineDashOffset: wickLineDashOffset = lineDashOffset
    } = this;
    if (wickStrokeWidth === 0)
      return;
    ctx.globalAlpha *= wickStrokeOpacity;
    if (typeof wickStroke === "string") {
      ctx.strokeStyle = wickStroke;
    }
    ctx.lineWidth = wickStrokeWidth;
    if (wickLineDash != null) {
      ctx.setLineDash([...wickLineDash]);
    }
    ctx.lineDashOffset = wickLineDashOffset;
    ctx.stroke(wickPath.getPath2D());
  }
};
__decorateClass([
  DeclaredSceneChangeDetection()
], CandlestickNode.prototype, "wickStroke", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], CandlestickNode.prototype, "wickStrokeWidth", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], CandlestickNode.prototype, "wickStrokeOpacity", 2);
__decorateClass([
  SceneArrayChangeDetection()
], CandlestickNode.prototype, "wickLineDash", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], CandlestickNode.prototype, "wickLineDashOffset", 2);
__decorateClass([
  DeclaredSceneChangeDetection()
], CandlestickNode.prototype, "wickStrokeAlignment", 2);

// packages/ag-charts-enterprise/src/series/ohlc/ohlcSeriesProperties.ts
var { AbstractBarSeriesProperties: AbstractBarSeriesProperties3, makeSeriesTooltip: makeSeriesTooltip8 } = module_support_exports;
var OhlcSeriesItem = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.stroke = "#333";
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesItem.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesItem.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesItem.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesItem.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesItem.prototype, "lineDashOffset", 2);
var OhlcSeriesItems = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.up = new OhlcSeriesItem();
    this.down = new OhlcSeriesItem();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesItems.prototype, "up", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesItems.prototype, "down", 2);
var OhlcSeriesBaseProperties = class extends AbstractBarSeriesProperties3 {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesBaseProperties.prototype, "xKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesBaseProperties.prototype, "openKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesBaseProperties.prototype, "closeKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesBaseProperties.prototype, "highKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesBaseProperties.prototype, "lowKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesBaseProperties.prototype, "xName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesBaseProperties.prototype, "yName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesBaseProperties.prototype, "openName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesBaseProperties.prototype, "closeName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesBaseProperties.prototype, "highName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesBaseProperties.prototype, "lowName", 2);
var OhlcSeriesProperties = class extends OhlcSeriesBaseProperties {
  constructor() {
    super(...arguments);
    this.tooltip = makeSeriesTooltip8();
    this.item = new OhlcSeriesItems();
  }
  getStyle(itemType) {
    const { strokeWidth, strokeOpacity, stroke: stroke3, lineDash, lineDashOffset } = this.item[itemType];
    return {
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset,
      opacity: 1
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesProperties.prototype, "tooltip", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesProperties.prototype, "item", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], OhlcSeriesProperties.prototype, "itemStyler", 2);

// packages/ag-charts-enterprise/src/series/candlestick/candlestickSeriesProperties.ts
var { makeSeriesTooltip: makeSeriesTooltip9 } = module_support_exports;
var CandlestickSeriesWick = class extends BaseProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], CandlestickSeriesWick.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CandlestickSeriesWick.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CandlestickSeriesWick.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CandlestickSeriesWick.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CandlestickSeriesWick.prototype, "lineDashOffset", 2);
var CandlestickSeriesItem = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.fill = "#c16068";
    this.fillOpacity = 1;
    this.stroke = "#333";
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.cornerRadius = 0;
    this.wick = new CandlestickSeriesWick();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], CandlestickSeriesItem.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CandlestickSeriesItem.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CandlestickSeriesItem.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CandlestickSeriesItem.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CandlestickSeriesItem.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CandlestickSeriesItem.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CandlestickSeriesItem.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CandlestickSeriesItem.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CandlestickSeriesItem.prototype, "wick", 2);
var CandlestickSeriesItems = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.up = new CandlestickSeriesItem();
    this.down = new CandlestickSeriesItem();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], CandlestickSeriesItems.prototype, "up", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CandlestickSeriesItems.prototype, "down", 2);
var CandlestickSeriesProperties = class extends OhlcSeriesBaseProperties {
  constructor() {
    super(...arguments);
    this.item = new CandlestickSeriesItems();
    this.tooltip = makeSeriesTooltip9();
  }
  getStyle(itemType) {
    const { fill, fillOpacity, strokeWidth, strokeOpacity, stroke: stroke3, lineDash, lineDashOffset, cornerRadius, wick } = this.item[itemType];
    return {
      fill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset,
      cornerRadius,
      opacity: 1,
      wick
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], CandlestickSeriesProperties.prototype, "item", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CandlestickSeriesProperties.prototype, "tooltip", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], CandlestickSeriesProperties.prototype, "itemStyler", 2);

// packages/ag-charts-enterprise/src/series/candlestick/candlestickSeries.ts
var CandlestickSeries = class extends OhlcSeriesBase {
  constructor() {
    super(...arguments);
    this.properties = new CandlestickSeriesProperties();
  }
  nodeFactory() {
    const node = new CandlestickNode();
    node.lineCap = "butt";
    return node;
  }
  updateDatumStyles({
    datumSelection,
    isHighlight
  }) {
    datumSelection.each((_, datum) => {
      datum.style = this.getItemStyle(datum.datumIndex, isHighlight, void 0, datum.itemType);
    });
  }
  updateDatumNodes({
    datumSelection,
    isHighlight
  }) {
    const { contextNodeData, properties } = this;
    if (!contextNodeData) {
      return;
    }
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    const { up, down } = properties.item;
    const fillBBox = this.getShapeFillBBox();
    const series = this;
    datumSelection.each(function updateCandlestickNode(node, datum) {
      const { centerX, width: width2, y, height: height2, yOpen, yClose, crisp } = datum;
      const baseStyle = datum.isRising ? up : down;
      const highlightState = series.getHighlightState(highlightedDatum, isHighlight, datum.datumIndex);
      const style2 = datum.style ?? contextNodeData.styles[datum.itemType][highlightState];
      node.setStaticProperties(centerX, width2, y, height2, yOpen, yClose, crisp);
      node.setStyleProperties(style2, fillBBox);
      const styleWick = style2?.wick;
      node.setWickProperties(
        styleWick?.stroke,
        styleWick?.strokeWidth,
        styleWick?.strokeOpacity,
        styleWick?.lineDash,
        styleWick?.lineDashOffset
      );
      node.wickStrokeAlignment = baseStyle.wick.strokeWidth ?? baseStyle.strokeWidth;
    });
  }
  legendItemSymbol() {
    const { up, down } = this.properties.item;
    const upColorStops = isGradientFill(up.fill) ? up.fill.colorStops.map(
      (c) => typeof c === "string" ? c : { color: c.color, stop: c.stop == null ? void 0 : c.stop * 0.5 }
    ) : [
      { color: isPatternFill(up.fill) || isImageFill(up.fill) ? up.stroke : up.fill, stop: 0 },
      { color: isPatternFill(up.fill) || isImageFill(up.fill) ? up.stroke : up.fill, stop: 0.5 }
    ];
    const downColorStops = isGradientFill(down.fill) ? down.fill.colorStops.map(
      (c) => typeof c === "string" ? c : { color: c.color, stop: c.stop == null ? void 0 : c.stop * 0.5 }
    ) : [{ color: isPatternFill(down.fill) || isImageFill(down.fill) ? down.stroke : down.fill, stop: 0.5 }];
    const fill = {
      type: "gradient",
      gradient: "linear",
      rotation: 90,
      colorStops: [...upColorStops, ...downColorStops],
      reverse: false
    };
    const stroke3 = {
      type: "gradient",
      gradient: "linear",
      rotation: 90,
      colorStops: [
        { color: up.stroke, stop: 0 },
        { color: up.stroke, stop: 0.5 },
        { color: down.stroke, stop: 0.5 }
      ],
      reverse: false
    };
    return {
      marker: {
        fill,
        fillOpacity: up.fillOpacity,
        stroke: stroke3,
        strokeWidth: up.strokeWidth ?? 1,
        strokeOpacity: up.strokeOpacity ?? 1,
        lineDash: up.lineDash,
        lineDashOffset: up.lineDashOffset
      }
    };
  }
  getLegendData(legendType) {
    const {
      id,
      data,
      visible,
      ctx: { legendManager }
    } = this;
    const { xKey, yName, showInLegend, legendItemName } = this.properties;
    if (!data?.data.length || !xKey || legendType !== "category") {
      return [];
    }
    return [
      {
        legendType: "category",
        id,
        itemId: id,
        seriesId: id,
        enabled: visible && legendManager.getItemEnabled({ seriesId: id, itemId: id }),
        label: {
          text: legendItemName ?? yName ?? id
        },
        symbol: this.legendItemSymbol(),
        legendItemName,
        hideInLegend: !showInLegend
      }
    ];
  }
  hasItemStylers() {
    return this.properties.itemStyler != null;
  }
};
CandlestickSeries.className = "CandleStickSeries";
CandlestickSeries.type = "candlestick";

// packages/ag-charts-enterprise/src/series/candlestick/candlestickSeriesOptionsDef.ts
var { candlestickSeriesThemeableOptionsDef: candlestickSeriesThemeableOptionsDef2 } = module_support_exports;
var candlestickSeriesOptionsDef = {
  ...commonSeriesOptionsDefs,
  ...candlestickSeriesThemeableOptionsDef2,
  type: required(constant("candlestick")),
  xKey: required(string),
  openKey: required(string),
  highKey: required(string),
  lowKey: required(string),
  closeKey: required(string),
  xName: string,
  yName: string,
  openName: string,
  highName: string,
  lowName: string,
  closeName: string,
  xKeyAxis: string,
  yKeyAxis: string
};
candlestickSeriesOptionsDef.pickOutsideVisibleMinorAxis = undocumented(boolean);
candlestickSeriesOptionsDef.focusPriority = undocumented(number);

// packages/ag-charts-enterprise/src/series/candlestick/candlestickThemes.ts
function itemTheme(key) {
  return {
    fill: {
      $applySwitch: [
        { $path: "type" },
        {
          $if: [
            { $eq: [{ $palette: "type" }, "user-indexed"] },
            key === "up" ? "transparent" : { $palette: "fill" },
            { $palette: `${key}.fill` }
          ]
        },
        ["gradient", FILL_GRADIENT_LINEAR_KEYED_DEFAULTS(key)],
        ["image", FILL_IMAGE_DEFAULTS],
        ["pattern", FILL_PATTERN_KEYED_DEFAULTS(key)]
      ]
    },
    stroke: {
      $if: [
        { $eq: [{ $palette: "type" }, "user-indexed"] },
        { $palette: "stroke" },
        { $palette: `${key}.stroke` }
      ]
    }
  };
}
var CANDLESTICK_SERIES_THEME = {
  series: {
    item: {
      up: itemTheme("up"),
      down: itemTheme("down")
    },
    tooltip: {
      range: { $path: ["/tooltip/range", "nearest"] }
    },
    highlight: MULTI_SERIES_HIGHLIGHT_STYLE
  },
  animation: { enabled: false },
  axes: {
    ["number" /* NUMBER */]: {
      crosshair: {
        snap: false
      }
    },
    ["ordinal-time" /* ORDINAL_TIME */]: {
      groupPaddingInner: 0,
      crosshair: {
        enabled: true
      }
    }
  }
};

// packages/ag-charts-enterprise/src/series/candlestick/candlestickModule.ts
var { predictCartesianFinancialAxis: predictCartesianFinancialAxis2 } = module_support_exports;
var CandlestickSeriesModule = {
  type: "series",
  name: "candlestick",
  chartType: "cartesian",
  enterprise: true,
  groupable: false,
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: candlestickSeriesOptionsDef,
  matchingKeys: ["xKey", "lowKey", "highKey", "openKey", "closeKey", "normalizedTo"],
  predictAxis: predictCartesianFinancialAxis2,
  defaultAxes: {
    y: {
      type: "number" /* NUMBER */,
      position: "left" /* LEFT */
    },
    x: {
      type: "ordinal-time" /* ORDINAL_TIME */,
      position: "bottom" /* BOTTOM */
    }
  },
  axisKeys: { ["x" /* X */]: "xKeyAxis", ["y" /* Y */]: "yKeyAxis" },
  themeTemplate: CANDLESTICK_SERIES_THEME,
  create: (ctx) => new CandlestickSeries(ctx)
};

// packages/ag-charts-enterprise/src/series/heatmap/heatmapSeriesProperties.ts
var { CartesianSeriesProperties: CartesianSeriesProperties2, makeSeriesTooltip: makeSeriesTooltip10 } = module_support_exports;
var HeatmapSeriesProperties = class extends CartesianSeriesProperties2 {
  constructor() {
    super(...arguments);
    this.colorRange = ["black", "black"];
    this.stroke = "black";
    this.strokeOpacity = 1;
    this.strokeWidth = 0;
    this.textAlign = "center";
    this.verticalAlign = "middle";
    this.itemPadding = 0;
    this.label = new AutoSizedLabel();
    this.tooltip = makeSeriesTooltip10();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], HeatmapSeriesProperties.prototype, "title", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HeatmapSeriesProperties.prototype, "xKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HeatmapSeriesProperties.prototype, "yKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HeatmapSeriesProperties.prototype, "colorKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HeatmapSeriesProperties.prototype, "xName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HeatmapSeriesProperties.prototype, "yName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HeatmapSeriesProperties.prototype, "colorName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HeatmapSeriesProperties.prototype, "colorRange", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HeatmapSeriesProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HeatmapSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HeatmapSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HeatmapSeriesProperties.prototype, "textAlign", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HeatmapSeriesProperties.prototype, "verticalAlign", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HeatmapSeriesProperties.prototype, "itemPadding", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HeatmapSeriesProperties.prototype, "itemStyler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HeatmapSeriesProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], HeatmapSeriesProperties.prototype, "tooltip", 2);

// packages/ag-charts-enterprise/src/series/heatmap/heatmapSeries.ts
var {
  SeriesNodePickMode: SeriesNodePickMode7,
  computeBarFocusBounds: computeBarFocusBounds4,
  getMissCount: getMissCount2,
  valueProperty: valueProperty8,
  DEFAULT_CARTESIAN_DIRECTION_KEYS: DEFAULT_CARTESIAN_DIRECTION_KEYS2,
  DEFAULT_CARTESIAN_DIRECTION_NAMES: DEFAULT_CARTESIAN_DIRECTION_NAMES2,
  createDatumId: createDatumId9,
  ColorScale: ColorScale2,
  Rect: Rect4,
  PointerEvents: PointerEvents4,
  addHitTestersToQuadtree: addHitTestersToQuadtree2,
  findQuadtreeMatch: findQuadtreeMatch2,
  updateLabelNode: updateLabelNode2,
  upsertNodeDatum: upsertNodeDatum3
} = module_support_exports;
var HeatmapSeriesNodeEvent = class extends module_support_exports.CartesianSeriesNodeEvent {
  constructor(type, nativeEvent, datum, series) {
    super(type, nativeEvent, datum, series);
    this.colorKey = series.properties.colorKey;
  }
};
var textAlignFactors2 = {
  left: -0.5,
  center: 0,
  right: -0.5
};
var verticalAlignFactors2 = {
  top: -0.5,
  middle: 0,
  bottom: -0.5
};
var HeatmapSeries = class extends module_support_exports.CartesianSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      propertyKeys: {
        ...DEFAULT_CARTESIAN_DIRECTION_KEYS2,
        color: ["colorKey"]
      },
      propertyNames: {
        ...DEFAULT_CARTESIAN_DIRECTION_NAMES2,
        color: ["colorName"]
      },
      categoryKey: void 0,
      pickModes: [SeriesNodePickMode7.NEAREST_NODE, SeriesNodePickMode7.EXACT_SHAPE_MATCH],
      pathsPerSeries: []
    });
    this.properties = new HeatmapSeriesProperties();
    this.NodeEvent = HeatmapSeriesNodeEvent;
    this.colorScale = new ColorScale2();
  }
  async processData(dataController) {
    const xAxis = this.axes["x" /* X */];
    const yAxis = this.axes["y" /* Y */];
    if (!xAxis || !yAxis) {
      return;
    }
    const { xKey, yKey, colorRange, colorKey } = this.properties;
    const xScale = this.axes["x" /* X */]?.scale;
    const yScale = this.axes["y" /* Y */]?.scale;
    const { xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale });
    const colorScaleType = this.colorScale.type;
    const allowNullKey = this.properties.allowNullKeys ?? false;
    const { dataModel, processedData } = await this.requestDataModel(dataController, this.data, {
      props: [
        valueProperty8(xKey, xScaleType, { id: "xValue", allowNullKey }),
        valueProperty8(yKey, yScaleType, { id: "yValue", allowNullKey }),
        ...colorKey ? [valueProperty8(colorKey, colorScaleType, { id: "colorValue", invalidValue: void 0 })] : []
      ]
    });
    if (this.isColorScaleValid()) {
      const colorKeyIdx = dataModel.resolveProcessedDataIndexById(this, "colorValue");
      const rawDomain = processedData.domain.values[colorKeyIdx].filter((v) => v != null);
      const domain = extent(rawDomain);
      this.colorScale.domain = domain ?? [];
      if (domain?.length && domain[0] === domain[1]) {
        const midIndex = Math.floor(colorRange.length / 2);
        this.colorScale.range = [colorRange[midIndex], colorRange[midIndex]];
      } else {
        this.colorScale.range = colorRange;
      }
      this.colorScale.update();
    }
  }
  isColorScaleValid() {
    const { colorKey } = this.properties;
    if (!colorKey) {
      return false;
    }
    const { dataModel, processedData } = this;
    if (!dataModel || !processedData) {
      return false;
    }
    const colorDataIdx = dataModel.resolveProcessedDataIndexById(this, "colorValue");
    const dataCount = processedData.input.count;
    const missCount = getMissCount2(this, processedData.defs.values[colorDataIdx].missing);
    const colorKeyIdx = dataModel.resolveProcessedDataIndexById(this, "colorValue");
    const actualCount = processedData.domain.values[colorKeyIdx].filter((v) => v != null).length;
    const colorDataMissing = dataCount === 0 || dataCount === missCount || actualCount === 0;
    return !colorDataMissing;
  }
  xCoordinateRange(xValue, pixelSize) {
    const xScale = this.axes["x" /* X */].scale;
    const xOffset = pixelSize * (xScale.bandwidth ?? 0) / 2;
    const x = xScale.convert(xValue) + xOffset;
    const width2 = pixelSize * (xScale.bandwidth ?? 10);
    return [x, x + width2];
  }
  yCoordinateRange(yValues, pixelSize) {
    const yScale = this.axes["y" /* Y */].scale;
    const yOffset = pixelSize * (yScale.bandwidth ?? 0) / 2;
    const y = yScale.convert(yValues[0]) + yOffset;
    const height2 = pixelSize * (yScale.bandwidth ?? 10);
    return [y, y + height2];
  }
  getSeriesDomain(direction) {
    const { dataModel, processedData } = this;
    if (!dataModel || !processedData)
      return { domain: [] };
    if (direction === "x" /* X */) {
      const domain = dataModel.getDomain(this, `xValue`, "value", processedData).domain;
      return { domain };
    } else {
      const domain = dataModel.getDomain(this, `yValue`, "value", processedData).domain;
      return { domain };
    }
  }
  getSeriesRange() {
    return [Number.NaN, Number.NaN];
  }
  /**
   * Template method hook: Validates preconditions for createNodeData.
   * Overrides base to add heatmap-specific category axis validation.
   */
  validateCreateNodeDataPreconditions() {
    const result = super.validateCreateNodeDataPreconditions();
    if (!result)
      return void 0;
    const { xAxis, yAxis } = result;
    if (xAxis.type !== "category" || yAxis.type !== "category") {
      logger_exports.warnOnce(
        `Heatmap series expected axes to have "category" type, but received "${xAxis.type}" and "${yAxis.type}" instead.`
      );
      return void 0;
    }
    return result;
  }
  /**
   * Template method hook: Iterates over data and creates/updates node datums.
   */
  populateNodeData(ctx) {
    for (const [datumIndex, datum] of ctx.rawData.entries()) {
      const nodeDatum = upsertNodeDatum3(
        ctx,
        { datumIndex, datum },
        (c, p) => this.createNodeDatum(c, p.datumIndex, p.datum),
        (c, n, p) => this.updateNodeDatum(c, n, p.datumIndex, p.datum)
      );
      if (nodeDatum) {
        const labelDatum = this.createLabelDatum(ctx, datumIndex, datum, nodeDatum);
        if (labelDatum) {
          ctx.labels.push(labelDatum);
        }
      }
    }
  }
  /**
   * Template method hook: Creates the result object shell.
   */
  initializeResult(ctx) {
    return {
      itemId: this.properties.yKey ?? this.id,
      nodeData: ctx.nodes,
      labelData: ctx.labels,
      scales: this.calculateScaling(),
      visible: this.visible
    };
  }
  /**
   * Template method hook: Creates the shared context for datum creation.
   * Caches expensive lookups and computations that are constant across all datums.
   */
  createNodeDatumContext(xAxis, yAxis) {
    const { dataModel, processedData, contextNodeData } = this;
    if (!dataModel || !processedData)
      return void 0;
    const { xKey, xName, yKey, yName, colorKey, colorName, textAlign, verticalAlign, itemPadding } = this.properties;
    const xScale = xAxis.scale;
    const yScale = yAxis.scale;
    const xValues = dataModel.resolveColumnById(this, `xValue`, processedData);
    const yValues = dataModel.resolveColumnById(this, `yValue`, processedData);
    const colorValues = colorKey ? dataModel.resolveColumnById(this, `colorValue`, processedData) : void 0;
    const colorDomain = colorKey ? dataModel.getDomain(this, "colorValue", "value", processedData).domain : [];
    const width2 = xScale.bandwidth ?? 10;
    const height2 = yScale.bandwidth ?? 10;
    const rawData = processedData.dataSources.get(this.id)?.data ?? [];
    const canIncrementallyUpdate = contextNodeData?.nodeData != null && processedData.changeDescription != null;
    return {
      // Base context fields
      xAxis,
      yAxis,
      xScale,
      yScale,
      rawData,
      xValues,
      xKey,
      yKey,
      xName,
      yName,
      animationEnabled: !this.ctx.animationManager.isSkipped(),
      canIncrementallyUpdate,
      nodes: canIncrementallyUpdate ? contextNodeData.nodeData : [],
      nodeIndex: 0,
      // Heatmap-specific positioning
      xOffset: (xScale.bandwidth ?? 0) / 2,
      yOffset: (yScale.bandwidth ?? 0) / 2,
      width: width2,
      height: height2,
      textAlignFactor: (width2 - 2 * itemPadding) * textAlignFactors2[textAlign],
      verticalAlignFactor: (height2 - 2 * itemPadding) * verticalAlignFactors2[verticalAlign],
      // Heatmap-specific data
      yValues,
      colorKey,
      colorName,
      colorValues,
      colorDomain,
      itemPadding,
      // Label support - labels are always rebuilt from scratch (not incrementally updated)
      labels: [],
      labelIndex: 0
    };
  }
  /**
   * Creates a skeleton HeatmapNodeDatum with minimal required fields.
   * The node will be populated by updateNodeDatum.
   */
  createSkeletonNodeDatum(ctx, datumIndex, datum) {
    const { xKey, yKey, width: width2, height: height2, colorValues } = ctx;
    const xDatum = ctx.xValues[datumIndex];
    const yDatum = ctx.yValues[datumIndex];
    const colorValue = colorValues?.[datumIndex];
    return {
      series: this,
      datumIndex,
      yKey,
      xKey,
      xValue: xDatum,
      yValue: yDatum,
      colorValue,
      datum,
      point: { x: 0, y: 0, size: 0 },
      width: width2,
      height: height2,
      midPoint: { x: 0, y: 0 },
      missing: colorValues != null && colorValue == null,
      style: {}
    };
  }
  /**
   * Updates an existing HeatmapNodeDatum in-place.
   */
  updateNodeDatum(ctx, node, datumIndex, datum) {
    const { xScale, yScale, xOffset, yOffset, width: width2, height: height2, xKey, yKey, colorValues } = ctx;
    const mutableNode = node;
    const xDatum = ctx.xValues[datumIndex];
    const yDatum = ctx.yValues[datumIndex];
    const x = xScale.convert(xDatum) + xOffset;
    const y = yScale.convert(yDatum) + yOffset;
    if (!Number.isFinite(x) || !Number.isFinite(y))
      return;
    const colorValue = colorValues?.[datumIndex];
    mutableNode.datumIndex = datumIndex;
    mutableNode.datum = datum;
    mutableNode.yKey = yKey;
    mutableNode.xKey = xKey;
    mutableNode.xValue = xDatum;
    mutableNode.yValue = yDatum;
    mutableNode.colorValue = colorValue;
    mutableNode.width = width2;
    mutableNode.height = height2;
    mutableNode.missing = colorValues != null && colorValue == null;
    const mutablePoint = mutableNode.point;
    mutablePoint.x = x;
    mutablePoint.y = y;
    mutablePoint.size = 0;
    mutableNode.midPoint.x = x;
    mutableNode.midPoint.y = y;
    mutableNode.style = this.getItemStyle({ datumIndex, datum, colorValue }, false);
  }
  /**
   * Creates a HeatmapNodeDatum for a single data point.
   * Returns undefined for invalid data points (e.g., null/undefined keys when not allowed).
   */
  createNodeDatum(ctx, datumIndex, datum) {
    const { xScale, yScale, xOffset, yOffset } = ctx;
    const xDatum = ctx.xValues[datumIndex];
    const yDatum = ctx.yValues[datumIndex];
    const x = xScale.convert(xDatum) + xOffset;
    const y = yScale.convert(yDatum) + yOffset;
    if (!Number.isFinite(x) || !Number.isFinite(y)) {
      return void 0;
    }
    const node = this.createSkeletonNodeDatum(ctx, datumIndex, datum);
    this.updateNodeDatum(ctx, node, datumIndex, datum);
    return node;
  }
  createLabelDatum(ctx, datumIndex, datum, nodeDatum) {
    const { label } = this.properties;
    const {
      width: width2,
      height: height2,
      textAlignFactor,
      verticalAlignFactor,
      itemPadding,
      colorKey,
      colorName,
      colorDomain,
      xKey,
      yKey,
      xName,
      yName
    } = ctx;
    const colorValue = ctx.colorValues?.[datumIndex];
    const labelText = label.enabled && colorValue != null ? this.getLabelText(
      colorValue,
      datum,
      colorKey,
      "color",
      colorDomain,
      label,
      { value: colorValue, datum, colorKey, colorName, xKey, yKey, xName, yName }
    ) : void 0;
    const sizeFittingHeight = () => ({ width: width2, height: height2, meta: null });
    const labels = formatLabels(
      toPlainText(labelText),
      this.properties.label,
      void 0,
      this.properties.label,
      { padding: itemPadding },
      sizeFittingHeight
    );
    if (labels?.label == null) {
      return void 0;
    }
    const { text: text2, fontSize, lineHeight, height: labelHeight } = labels.label;
    const { fontStyle, fontFamily, fontWeight: fontWeight2, color: color2 } = this.properties.label;
    const { textAlign, verticalAlign } = this.properties;
    const lx = nodeDatum.point.x + textAlignFactor * (width2 - 2 * itemPadding);
    const ly = nodeDatum.point.y + verticalAlignFactor * (height2 - 2 * itemPadding) - (labels.height - labelHeight) * 0.5;
    return {
      series: this,
      datum,
      datumIndex,
      text: text2,
      fontSize,
      lineHeight,
      fontStyle,
      fontFamily,
      fontWeight: fontWeight2,
      color: color2,
      textAlign,
      textBaseline: verticalAlign,
      x: lx,
      y: ly,
      style: nodeDatum.style
    };
  }
  nodeFactory() {
    return new Rect4();
  }
  update(params) {
    this.ctx.animationManager.skipCurrentBatch();
    return super.update(params);
  }
  updateDatumSelection(opts) {
    const { nodeData, datumSelection } = opts;
    const data = nodeData ?? [];
    return datumSelection.update(data);
  }
  getItemStyle({ datumIndex, datum, colorValue }, isHighlight, highlightState) {
    const { properties } = this;
    const { itemStyler, stroke: stroke3, strokeWidth, strokeOpacity } = properties;
    const highlightStyle = this.getHighlightStyle(isHighlight, datumIndex, highlightState);
    const style2 = mergeDefaults(highlightStyle, {
      fill: this.isColorScaleValid() && colorValue != null ? this.colorScale.convert(colorValue) : "transparent",
      fillOpacity: 1,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      opacity: 1
    });
    let overrides;
    if (itemStyler != null && datumIndex != null) {
      overrides = this.cachedDatumCallback(createDatumId9(datumIndex, isHighlight ? "highlight" : "node"), () => {
        const params = this.makeItemStylerParams(datum, datumIndex, isHighlight, style2);
        return this.callWithContext(itemStyler, params);
      });
    }
    return overrides ? mergeDefaults(overrides, style2) : style2;
  }
  makeItemStylerParams(datum, datumIndex, isHighlight, style2) {
    const { id: seriesId, properties } = this;
    const { xKey, yKey } = properties;
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const highlightState = this.getHighlightStateString(activeHighlight, isHighlight, datumIndex);
    const fill = this.filterItemStylerFillParams(style2.fill) ?? style2.fill;
    return {
      seriesId,
      datum,
      xKey,
      yKey,
      highlightState,
      ...style2,
      fill
    };
  }
  updateDatumStyles({
    datumSelection,
    isHighlight
  }) {
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    datumSelection.each((_, nodeDatum) => {
      const highlightState = this.getHighlightState(activeHighlight, isHighlight, nodeDatum.datumIndex);
      nodeDatum.style = this.getItemStyle(nodeDatum, isHighlight, highlightState);
    });
  }
  updateDatumNodes({
    datumSelection
  }) {
    const xAxis = this.axes["x" /* X */];
    const [visibleMin, visibleMax] = xAxis?.visibleRange ?? [];
    const isZoomed = visibleMin !== 0 || visibleMax !== 1;
    const crisp = !isZoomed;
    datumSelection.each((rect2, nodeDatum) => {
      const { point, width: width2, height: height2, style: style2 } = nodeDatum;
      rect2.setStyleProperties(style2);
      rect2.crisp = crisp;
      rect2.x = Math.floor(point.x - width2 / 2);
      rect2.y = Math.floor(point.y - height2 / 2);
      rect2.width = Math.ceil(width2);
      rect2.height = Math.ceil(height2);
    });
  }
  updateLabelSelection(opts) {
    const { labelData, labelSelection } = opts;
    const { enabled } = this.properties.label;
    const data = enabled ? labelData : [];
    return labelSelection.update(data);
  }
  updateLabelNodes(opts) {
    const { isHighlight = false } = opts;
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    opts.labelSelection.each((text2, datum) => {
      text2.pointerEvents = PointerEvents4.None;
      text2.text = datum.text;
      text2.fillOpacity = this.getHighlightStyle(isHighlight, datum.datumIndex)?.opacity ?? 1;
      updateLabelNode2(
        this,
        text2,
        this.properties,
        this.properties.label,
        datum,
        isHighlight,
        activeHighlight
      );
    });
  }
  getTooltipContent(datumIndex) {
    const { id: seriesId, dataModel, processedData, axes, properties, colorScale, ctx } = this;
    const { formatManager } = ctx;
    const { xKey, xName, yKey, yName, colorKey, colorName, colorRange, title, legendItemName, tooltip } = properties;
    const xAxis = axes["x" /* X */];
    const yAxis = axes["y" /* Y */];
    if (!dataModel || !processedData || !xAxis || !yAxis)
      return;
    const datum = processedData.dataSources.get(this.id)?.data[datumIndex];
    const xValue = dataModel.resolveColumnById(this, `xValue`, processedData)[datumIndex];
    const yValue = dataModel.resolveColumnById(this, `yValue`, processedData)[datumIndex];
    const colorValue = colorKey != null && this.isColorScaleValid() ? dataModel.resolveColumnById(this, `colorValue`, processedData)[datumIndex] : void 0;
    const allowNullKeys = this.properties.allowNullKeys ?? false;
    if (xValue === void 0 && !allowNullKeys)
      return;
    const data = [];
    let fill;
    if (colorValue == null) {
      fill = colorRange[0];
    } else {
      fill = colorScale.convert(colorValue);
      const domain = dataModel.getDomain(this, `colorValue`, "value", processedData).domain;
      const content = formatManager.format(this.callWithContext.bind(this), {
        type: "number",
        value: colorValue,
        datum,
        seriesId,
        legendItemName,
        key: colorKey,
        source: "tooltip",
        property: "color",
        domain,
        boundSeries: this.getFormatterContext("color"),
        fractionDigits: void 0,
        visibleDomain: void 0
      });
      data.push({ label: colorName, fallbackLabel: colorKey, value: content ?? formatValue(colorValue) });
    }
    data.push(
      {
        label: xName,
        fallbackLabel: xKey,
        value: this.getAxisValueText(xAxis, "tooltip", xValue, datum, xKey, legendItemName)
      },
      {
        label: yName,
        fallbackLabel: yKey,
        value: this.getAxisValueText(yAxis, "tooltip", yValue, datum, yKey, legendItemName)
      }
    );
    const format = this.getItemStyle({ datumIndex, datum, colorValue }, false);
    if (format.fill != null) {
      fill = format.fill;
    }
    const symbol = fill == null ? void 0 : {
      marker: {
        shape: "square",
        fill,
        fillOpacity: 1,
        stroke: void 0,
        strokeWidth: 0,
        strokeOpacity: 1,
        lineDash: [0],
        lineDashOffset: 0
      }
    };
    return this.formatTooltipWithContext(
      tooltip,
      { title: title ?? legendItemName, symbol, data },
      {
        seriesId,
        datum,
        title,
        xKey,
        xName,
        yKey,
        yName,
        colorKey,
        colorName,
        ...format
      }
    );
  }
  getLegendData(legendType) {
    if (legendType !== "gradient" || !this.isColorScaleValid() || !this.dataModel) {
      return [];
    }
    return [
      {
        legendType: "gradient",
        enabled: this.visible,
        seriesId: this.id,
        series: this.getFormatterContext("color"),
        colorDomain: this.colorScale.domain,
        colorRange: this.colorScale.range
      }
    ];
  }
  isLabelEnabled() {
    return this.properties.label.enabled && Boolean(this.properties.colorKey);
  }
  getBandScalePadding() {
    return { inner: 0, outer: 0 };
  }
  computeFocusBounds({ datumIndex }) {
    const datum = this.contextNodeData?.nodeData[datumIndex];
    if (datum === void 0)
      return void 0;
    const { width: width2, height: height2, midPoint } = datum;
    const focusRect = { x: midPoint.x - width2 / 2, y: midPoint.y - height2 / 2, width: width2, height: height2 };
    return computeBarFocusBounds4(this, focusRect);
  }
  initQuadTree(quadtree) {
    addHitTestersToQuadtree2(quadtree, this.datumNodesIter());
  }
  pickNodesExactShape(point) {
    const item = findQuadtreeMatch2(this, point);
    return item != null && item.distance <= 0 ? [item.datum] : [];
  }
  pickNodeClosestDatum(point) {
    return findQuadtreeMatch2(this, point);
  }
  hasItemStylers() {
    return this.properties.itemStyler != null || this.properties.label.itemStyler != null || this.isColorScaleValid();
  }
};
HeatmapSeries.className = "HeatmapSeries";
HeatmapSeries.type = "heatmap";

// packages/ag-charts-enterprise/src/series/heatmap/heatmapSeriesOptionsDef.ts
var { heatmapSeriesThemeableOptionsDef: heatmapSeriesThemeableOptionsDef2 } = module_support_exports;
var heatmapSeriesOptionsDef = {
  ...without(heatmapSeriesThemeableOptionsDef2, ["showInLegend"]),
  ...without(commonSeriesOptionsDefs, ["showInLegend"]),
  type: required(constant("heatmap")),
  xKey: required(string),
  yKey: required(string),
  xKeyAxis: string,
  yKeyAxis: string,
  colorKey: string,
  xName: string,
  yName: string,
  colorName: string,
  colorRange: arrayOf(color)
};

// packages/ag-charts-enterprise/src/series/heatmap/heatmapThemes.ts
var HEATMAP_SERIES_THEME = {
  series: {
    stroke: {
      $if: [
        { $eq: [{ $palette: "type" }, "inbuilt"] },
        { $ref: "chartBackgroundColor" },
        { $path: ["/0", { $palette: "stroke" }, { $palette: "strokes" }] }
      ]
    },
    strokeWidth: { $isUserOption: ["./stroke", 2, void 0] },
    label: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: false,
      color: { $ref: "textColor" },
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      fontWeight: { $ref: "fontWeight" },
      wrapping: "on-space",
      overflowStrategy: "ellipsis"
    },
    itemPadding: 3,
    highlight: {
      unhighlightedItem: {
        opacity: 0.6
      }
    }
  },
  gradientLegend: {
    enabled: true
  }
};
HEATMAP_SERIES_THEME.series.colorRange = {
  $if: [{ $eq: [{ $palette: "type" }, "inbuilt"] }, { $palette: "divergingColors" }, SAFE_RANGE2_OPERATION]
};

// packages/ag-charts-enterprise/src/series/heatmap/heatmapModule.ts
var HeatmapSeriesModule = {
  type: "series",
  name: "heatmap",
  chartType: "cartesian",
  enterprise: true,
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: heatmapSeriesOptionsDef,
  defaultAxes: {
    y: { type: "category" /* CATEGORY */, position: "left" /* LEFT */ },
    x: { type: "category" /* CATEGORY */, position: "bottom" /* BOTTOM */ }
  },
  axisKeys: { ["x" /* X */]: "xKeyAxis", ["y" /* Y */]: "yKeyAxis" },
  themeTemplate: HEATMAP_SERIES_THEME,
  create: (ctx) => new HeatmapSeries(ctx)
};

// packages/ag-charts-enterprise/src/series/ohlc/ohlcSeries.ts
var OhlcSeries = class extends OhlcSeriesBase {
  constructor() {
    super(...arguments);
    this.properties = new OhlcSeriesProperties();
  }
  nodeFactory() {
    const node = new OhlcNode();
    node.lineCap = "square";
    return node;
  }
  updateDatumStyles({
    datumSelection,
    isHighlight
  }) {
    datumSelection.each((_, datum) => {
      datum.style = this.getItemStyle(datum.datumIndex, isHighlight, void 0, datum.itemType);
    });
  }
  updateDatumNodes({
    datumSelection,
    isHighlight
  }) {
    const { contextNodeData, properties } = this;
    if (!contextNodeData) {
      return;
    }
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    const { up, down } = properties.item;
    const series = this;
    datumSelection.each(function updateOhlcNode(node, datum) {
      const { centerX, width: width2, y, height: height2, yOpen, yClose, crisp } = datum;
      const baseStyle = datum.isRising ? up : down;
      node.setStaticProperties(centerX, width2, y, height2, yOpen, yClose, crisp);
      const style2 = datum.style ?? contextNodeData.styles[datum.itemType][series.getHighlightState(highlightedDatum, isHighlight, datum.datumIndex)];
      node.setStyleProperties(style2);
      node.strokeAlignment = baseStyle.strokeWidth;
    });
  }
  getLegendData(legendType) {
    const {
      id,
      data,
      ctx: { legendManager },
      visible
    } = this;
    const {
      xKey,
      yName,
      item: { up, down },
      showInLegend,
      legendItemName
    } = this.properties;
    if (!data?.data.length || !xKey || legendType !== "category") {
      return [];
    }
    const fill = {
      type: "gradient",
      gradient: "linear",
      colorSpace: "rgb",
      colorStops: [
        { color: up.stroke, stop: 0 },
        { color: up.stroke, stop: 0.5 },
        { color: down.stroke, stop: 0.5 }
      ],
      rotation: 90
    };
    return [
      {
        legendType: "category",
        id,
        itemId: id,
        seriesId: id,
        enabled: visible && legendManager.getItemEnabled({ seriesId: id, itemId: id }),
        label: {
          text: legendItemName ?? yName ?? id
        },
        symbol: {
          marker: {
            fill,
            fillOpacity: up.strokeOpacity,
            stroke: void 0,
            strokeWidth: 0,
            strokeOpacity: 1,
            lineDash: [0],
            lineDashOffset: 0
          }
        },
        legendItemName,
        hideInLegend: !showInLegend
      }
    ];
  }
  hasItemStylers() {
    return this.properties.itemStyler != null;
  }
};
OhlcSeries.className = "ohlc";
OhlcSeries.type = "ohlc";

// packages/ag-charts-enterprise/src/series/ohlc/ohlcSeriesOptionsDef.ts
var { ohlcSeriesThemeableOptionsDef: ohlcSeriesThemeableOptionsDef2 } = module_support_exports;
var ohlcSeriesOptionsDef = {
  ...commonSeriesOptionsDefs,
  ...ohlcSeriesThemeableOptionsDef2,
  type: required(constant("ohlc")),
  xKey: required(string),
  openKey: required(string),
  highKey: required(string),
  lowKey: required(string),
  closeKey: required(string),
  xKeyAxis: string,
  yKeyAxis: string,
  xName: string,
  yName: string,
  openName: string,
  highName: string,
  lowName: string,
  closeName: string
};
ohlcSeriesOptionsDef.pickOutsideVisibleMinorAxis = undocumented(boolean);
ohlcSeriesOptionsDef.focusPriority = undocumented(number);

// packages/ag-charts-enterprise/src/series/ohlc/ohlcModule.ts
var { predictCartesianFinancialAxis: predictCartesianFinancialAxis3 } = module_support_exports;
var themeTemplate8 = {
  animation: { enabled: false },
  series: {
    item: {
      up: {
        stroke: {
          $if: [
            { $eq: [{ $palette: "type" }, "user-indexed"] },
            { $palette: "stroke" },
            { $palette: "up.stroke" }
          ]
        }
      },
      down: {
        stroke: {
          $if: [
            { $eq: [{ $palette: "type" }, "user-indexed"] },
            { $palette: "stroke" },
            { $palette: "down.stroke" }
          ]
        }
      }
    },
    tooltip: {
      range: { $path: ["/tooltip/range", "nearest"] }
    },
    highlight: MULTI_SERIES_HIGHLIGHT_STYLE
  },
  axes: {
    ["number" /* NUMBER */]: {
      crosshair: {
        snap: false
      }
    },
    ["ordinal-time" /* ORDINAL_TIME */]: {
      groupPaddingInner: 0,
      crosshair: {
        enabled: true
      }
    }
  }
};
var OhlcSeriesModule = {
  type: "series",
  name: "ohlc",
  chartType: "cartesian",
  enterprise: true,
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: ohlcSeriesOptionsDef,
  matchingKeys: ["xKey", "lowKey", "highKey", "openKey", "closeKey", "normalizedTo"],
  predictAxis: predictCartesianFinancialAxis3,
  defaultAxes: {
    y: { type: "number" /* NUMBER */, position: "left" /* LEFT */ },
    x: { type: "ordinal-time" /* ORDINAL_TIME */, position: "bottom" /* BOTTOM */ }
  },
  axisKeys: { ["x" /* X */]: "xKeyAxis", ["y" /* Y */]: "yKeyAxis" },
  themeTemplate: themeTemplate8,
  create: (ctx) => new OhlcSeries(ctx)
};

// packages/ag-charts-enterprise/src/series/range-area/rangeAreaAggregation.ts
function aggregateRangeAreaData(scale2, xValues, highValues, lowValues, domainInput, smallestKeyInterval, xNeedsValueOf, yNeedsValueOf) {
  const [d0, d1] = aggregationDomain(scale2, domainInput);
  return computeExtremesAggregation([d0, d1], xValues, highValues, lowValues, {
    smallestKeyInterval,
    xNeedsValueOf,
    yNeedsValueOf
  });
}
var memoizedAggregateRangeAreaData = simpleMemorize2(aggregateRangeAreaData);
function aggregateRangeAreaDataFromDataModel(scale2, dataModel, processedData, series, existingFilters) {
  const xValues = dataModel.resolveKeysById(series, "xValue", processedData);
  const highValues = dataModel.resolveColumnById(series, "yHighValue", processedData);
  const lowValues = dataModel.resolveColumnById(series, "yLowValue", processedData);
  const domainInput = dataModel.getDomain(series, "xValue", "key", processedData);
  const xNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "xValue", processedData);
  const yNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "yHighValue", processedData) ?? dataModel.resolveColumnNeedsValueOf(series, "yLowValue", processedData);
  if (existingFilters) {
    const [d0, d1] = aggregationDomain(scale2, domainInput);
    return computeExtremesAggregation([d0, d1], xValues, highValues, lowValues, {
      smallestKeyInterval: processedData.reduced?.smallestKeyInterval,
      xNeedsValueOf,
      yNeedsValueOf,
      existingFilters
    });
  }
  return memoizedAggregateRangeAreaData(
    scale2,
    xValues,
    highValues,
    lowValues,
    domainInput,
    processedData.reduced?.smallestKeyInterval,
    xNeedsValueOf,
    yNeedsValueOf
  );
}
function aggregateRangeAreaDataFromDataModelPartial(scale2, dataModel, processedData, series, targetRange, existingFilters) {
  const xValues = dataModel.resolveKeysById(series, "xValue", processedData);
  const highValues = dataModel.resolveColumnById(series, "yHighValue", processedData);
  const lowValues = dataModel.resolveColumnById(series, "yLowValue", processedData);
  const domainInput = dataModel.getDomain(series, "xValue", "key", processedData);
  const xNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "xValue", processedData);
  const yNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "yHighValue", processedData) ?? dataModel.resolveColumnNeedsValueOf(series, "yLowValue", processedData);
  const [d0, d1] = aggregationDomain(scale2, domainInput);
  return computeExtremesAggregationPartial([d0, d1], xValues, highValues, lowValues, {
    smallestKeyInterval: processedData.reduced?.smallestKeyInterval,
    targetRange,
    xNeedsValueOf,
    yNeedsValueOf,
    existingFilters
  });
}

// packages/ag-charts-enterprise/src/series/range-area/rangeAreaIntersection.ts
function getYValueAtX({ span }, x) {
  switch (span.type) {
    case "linear":
    case "step":
    case "multi-line": {
      const t = (x - span.x0) / (span.x1 - span.x0);
      return span.y0 + t * (span.y1 - span.y0);
    }
    case "cubic": {
      const { cp0x, cp0y, cp1x, cp1y, cp2x, cp2y, cp3x, cp3y } = span;
      let t = 0.5;
      const tolerance = 1e-6;
      for (let i = 0; i < 10; i++) {
        const mt2 = 1 - t;
        const xt = mt2 * mt2 * mt2 * cp0x + 3 * mt2 * mt2 * t * cp1x + 3 * mt2 * t * t * cp2x + t * t * t * cp3x;
        const fx = xt - x;
        if (Math.abs(fx) < tolerance)
          break;
        const dxdt = 3 * mt2 * mt2 * (cp1x - cp0x) + 6 * mt2 * t * (cp2x - cp1x) + 3 * t * t * (cp3x - cp2x);
        if (Math.abs(dxdt) < 1e-12)
          break;
        t = t - fx / dxdt;
        t = Math.max(0, Math.min(1, t));
      }
      const mt = 1 - t;
      return mt * mt * mt * cp0y + 3 * mt * mt * t * cp1y + 3 * mt * t * t * cp2y + t * t * t * cp3y;
    }
  }
}
function findSpanForX(spans, x, startIndex = 0) {
  for (let i = startIndex; i < spans.length; i++) {
    const span = spans[i];
    const [start2, end3] = spanRange(span.span);
    if (x >= start2.x && x <= end3.x) {
      return { span, index: i };
    }
    if (x < start2.x) {
      break;
    }
  }
  return { span: null, index: startIndex };
}
function checkForIntersection(highSpans, lowSpans, x, wasInverted, spanIndex) {
  const high = findSpanForX(highSpans, x, spanIndex);
  const low = findSpanForX(lowSpans, x, spanIndex);
  if (!high.span || !low.span) {
    return { intersection: null, spanIndex: high.index, isInverted: wasInverted };
  }
  const highY = getYValueAtX(high.span, x);
  const lowY = getYValueAtX(low.span, x);
  const isInverted = highY > lowY;
  const intersection = wasInverted === isInverted ? null : { x, y: highY };
  return { intersection, spanIndex: high.index, isInverted };
}
function findRangeAreaIntersections(highSpans, lowSpans, minX, maxX, initiallyInverted = false) {
  if (highSpans.length === 0 || lowSpans.length === 0)
    return [];
  const intersections = [];
  let wasInverted = initiallyInverted;
  let spanIndex = 0;
  for (let x = minX; x <= maxX; x += 0.5) {
    const result = checkForIntersection(highSpans, lowSpans, x, wasInverted, spanIndex);
    if (result.intersection) {
      intersections.push(result.intersection.x);
    }
    spanIndex = result.spanIndex;
    wasInverted = result.isInverted;
  }
  return intersections;
}
function calculateIntersectionSegments(intersections, seriesRect, chartSize, startsInverted, style2 = {}) {
  const horizontalMargin = Math.max(seriesRect.x, chartSize.width - (seriesRect.x + seriesRect.width));
  const verticalMargin = Math.max(seriesRect.y, chartSize.height - (seriesRect.y + seriesRect.height));
  const result = [];
  const createClipRect = (x0, x1) => ({
    x0,
    y0: -verticalMargin,
    x1,
    y1: seriesRect.height + verticalMargin
  });
  if (startsInverted) {
    result.push({
      clipRect: createClipRect(-horizontalMargin, intersections[0] ?? seriesRect.width + horizontalMargin),
      ...style2
    });
  }
  const startIndex = startsInverted ? 1 : 0;
  for (let i = startIndex; i < intersections.length; i += 2) {
    result.push({
      clipRect: createClipRect(intersections[i], intersections[i + 1] ?? seriesRect.width + horizontalMargin),
      ...style2
    });
  }
  return result;
}

// packages/ag-charts-enterprise/src/series/range-area/rangeAreaProperties.ts
var { CartesianSeriesProperties: CartesianSeriesProperties3, SeriesMarker: SeriesMarker2, makeSeriesTooltip: makeSeriesTooltip11, DropShadow: DropShadow3, Label: Label8 } = module_support_exports;
var RangeAreaSeriesLabel = class extends Label8 {
  constructor() {
    super(...arguments);
    this.placement = "outside";
    this.spacing = 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaSeriesLabel.prototype, "placement", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaSeriesLabel.prototype, "spacing", 2);
var RangeAreaInvertedStyle = class {
  constructor() {
    this.enabled = false;
    this.fillOpacity = 1;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaInvertedStyle.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaInvertedStyle.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaInvertedStyle.prototype, "fillOpacity", 2);
var RangeAreaLineStyle = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.stroke = "#99CCFF";
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.marker = new SeriesMarker2();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaLineStyle.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaLineStyle.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaLineStyle.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaLineStyle.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaLineStyle.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaLineStyle.prototype, "marker", 2);
var RangeAreaItemProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.low = new RangeAreaLineStyle();
    this.high = new RangeAreaLineStyle();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaItemProperties.prototype, "low", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaItemProperties.prototype, "high", 2);
var SharedRangeAreaMarker = class extends BaseProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], SharedRangeAreaMarker.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SharedRangeAreaMarker.prototype, "shape", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SharedRangeAreaMarker.prototype, "size", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SharedRangeAreaMarker.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SharedRangeAreaMarker.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SharedRangeAreaMarker.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SharedRangeAreaMarker.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SharedRangeAreaMarker.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SharedRangeAreaMarker.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SharedRangeAreaMarker.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], SharedRangeAreaMarker.prototype, "itemStyler", 2);
var RangeAreaProperties = class extends CartesianSeriesProperties3 {
  constructor() {
    super(...arguments);
    this.fill = "#99CCFF";
    this.fillOpacity = 1;
    this.stroke = "#99CCFF";
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.interpolation = new InterpolationProperties();
    this.item = new RangeAreaItemProperties();
    this.invertedStyle = new RangeAreaInvertedStyle();
    this.shadow = new DropShadow3().set({ enabled: false });
    this.marker = new SharedRangeAreaMarker();
    this.label = new RangeAreaSeriesLabel();
    this.tooltip = makeSeriesTooltip11();
    this.connectMissingData = false;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "xKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "yLowKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "yHighKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "xName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "yName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "yLowName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "yHighName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "interpolation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "styler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "item", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "invertedStyle", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "shadow", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "marker", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "tooltip", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeAreaProperties.prototype, "connectMissingData", 2);

// packages/ag-charts-enterprise/src/series/range-area/rangeAreaUtil.ts
var {
  CollapseMode: CollapseMode2,
  pairUpSpans: pairUpSpans2,
  prepareAreaFillAnimationFns: prepareAreaFillAnimationFns2,
  plotInterpolatedLinePathStroke: plotInterpolatedLinePathStroke2,
  prepareLinePathPropertyAnimation: prepareLinePathPropertyAnimation2
} = module_support_exports;
function prepareRangeAreaPathStrokeAnimationFns(status, highSpans, lowSpans, visibleToggleMode) {
  const removePhaseFn = (ratio2, path) => {
    plotInterpolatedLinePathStroke2(ratio2, path, highSpans.removed);
    plotInterpolatedLinePathStroke2(ratio2, path, lowSpans.removed);
  };
  const updatePhaseFn = (ratio2, path) => {
    plotInterpolatedLinePathStroke2(ratio2, path, highSpans.moved);
    plotInterpolatedLinePathStroke2(ratio2, path, lowSpans.moved);
  };
  const addPhaseFn = (ratio2, path) => {
    plotInterpolatedLinePathStroke2(ratio2, path, highSpans.added);
    plotInterpolatedLinePathStroke2(ratio2, path, lowSpans.added);
  };
  const pathProperties = prepareLinePathPropertyAnimation2(status, visibleToggleMode);
  return { status, path: { addPhaseFn, updatePhaseFn, removePhaseFn }, pathProperties };
}
function prepareRangeAreaPathAnimation(newData, oldData, diff9) {
  const isCategoryBased = newData.scales.x?.type === "category";
  const wasCategoryBased = oldData.scales.x?.type === "category";
  if (isCategoryBased !== wasCategoryBased || !isScaleValid(newData.scales.x) || !isScaleValid(oldData.scales.x)) {
    return;
  }
  let status = "updated";
  if (oldData.visible && !newData.visible) {
    status = "removed";
  } else if (!oldData.visible && newData.visible) {
    status = "added";
  }
  const fillSpans = pairUpSpans2(
    { scales: newData.scales, data: newData.fillData.spans },
    { scales: oldData.scales, data: oldData.fillData.spans },
    CollapseMode2.Split
  );
  if (fillSpans == null)
    return;
  const fillPhantomSpans = pairUpSpans2(
    { scales: newData.scales, data: newData.fillData.phantomSpans },
    { scales: oldData.scales, data: oldData.fillData.phantomSpans },
    CollapseMode2.Split
  );
  if (fillPhantomSpans == null)
    return;
  const highStrokeSpans = pairUpSpans2(
    { scales: newData.scales, data: newData.highStrokeData.spans },
    { scales: oldData.scales, data: oldData.highStrokeData.spans },
    CollapseMode2.Split
  );
  if (highStrokeSpans == null)
    return;
  const lowStrokeSpans = pairUpSpans2(
    { scales: newData.scales, data: newData.lowStrokeData.spans },
    { scales: oldData.scales, data: oldData.lowStrokeData.spans },
    CollapseMode2.Split
  );
  if (lowStrokeSpans == null)
    return;
  const fadeMode = "fade";
  const fill = prepareAreaFillAnimationFns2(status, fillSpans, fillPhantomSpans, fadeMode);
  const stroke3 = prepareRangeAreaPathStrokeAnimationFns(status, highStrokeSpans, lowStrokeSpans, fadeMode);
  const hasMotion = (diff9?.changed ?? true) || !areScalingEqual(newData.scales.x, oldData.scales.x) || !areScalingEqual(newData.scales.y, oldData.scales.y) || status !== "updated";
  return { status, fill, stroke: stroke3, hasMotion };
}

// packages/ag-charts-enterprise/src/series/range-area/rangeArea.ts
var HIGH2 = AGGREGATION_INDEX_Y_MAX;
var LOW2 = AGGREGATION_INDEX_Y_MIN;
var SPAN3 = AGGREGATION_SPAN;
var {
  valueProperty: valueProperty9,
  keyProperty: keyProperty6,
  updateLabelNode: updateLabelNode3,
  fixNumericExtent: fixNumericExtent5,
  buildResetPathFn: buildResetPathFn2,
  resetLabelFn: resetLabelFn2,
  resetMarkerFn: resetMarkerFn2,
  resetMarkerPositionFn: resetMarkerPositionFn2,
  pathSwipeInAnimation: pathSwipeInAnimation2,
  resetMotion: resetMotion2,
  markerSwipeScaleInAnimation: markerSwipeScaleInAnimation2,
  seriesLabelFadeInAnimation: seriesLabelFadeInAnimation3,
  animationValidation: animationValidation4,
  diff: diff4,
  updateClipPath: updateClipPath2,
  computeMarkerFocusBounds: computeMarkerFocusBounds2,
  plotAreaPathFill: plotAreaPathFill2,
  plotLinePathStroke: plotLinePathStroke2,
  interpolatePoints: interpolatePoints2,
  pathFadeInAnimation: pathFadeInAnimation2,
  markerFadeInAnimation: markerFadeInAnimation2,
  fromToMotion: fromToMotion4,
  pathMotion: pathMotion2,
  PointerEvents: PointerEvents5,
  Marker: Marker2,
  BBox: BBox20,
  processedDataIsAnimatable: processedDataIsAnimatable4,
  markerEnabled: markerEnabled2,
  getMarkerStyles: getMarkerStyles2,
  calculateSegments: calculateSegments3,
  toHighlightString: toHighlightString3,
  HighlightState: HighlightState5,
  AggregationManager: AggregationManager3,
  resetMarkerSelectionsDirect: resetMarkerSelectionsDirect2,
  createDatumId: createDatumId10,
  visibleRangeIndices: visibleRangeIndices3
} = module_support_exports;
var RangeAreaSeriesNodeEvent = class extends module_support_exports.SeriesNodeEvent {
  constructor(type, nativeEvent, datum, series) {
    super(type, nativeEvent, datum, series);
    this.xKey = series.properties.xKey;
    this.yLowKey = series.properties.yLowKey;
    this.yHighKey = series.properties.yHighKey;
  }
};
var RangeAreaSeries = class extends module_support_exports.CartesianSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      pathsPerSeries: ["fill", "lowStroke", "highStroke"],
      pickModes: [module_support_exports.SeriesNodePickMode.AXIS_ALIGNED],
      propertyKeys: {
        ["x" /* X */]: ["xKey"],
        ["y" /* Y */]: ["yLowKey", "yHighKey"]
      },
      propertyNames: {
        ["x" /* X */]: ["xName"],
        ["y" /* Y */]: ["yLowName", "yHighName", "yName"]
      },
      categoryKey: "xValue",
      animationResetFns: {
        path: buildResetPathFn2({ getVisible: () => this.visible, getOpacity: () => this.getOpacity() }),
        label: resetLabelFn2,
        datum: (node, datum) => ({ ...resetMarkerFn2(node), ...resetMarkerPositionFn2(node, datum) })
      },
      clipFocusBox: false
    });
    this.properties = new RangeAreaProperties();
    this.NodeEvent = RangeAreaSeriesNodeEvent;
    this.aggregationManager = new AggregationManager3();
  }
  renderToOffscreenCanvas() {
    const hasMarkers = (this.contextNodeData?.nodeData?.length ?? 0) > 0;
    return hasMarkers && this.getDrawingMode(false) === "cutout" || super.renderToOffscreenCanvas();
  }
  async processData(dataController) {
    const { xKey, yLowKey, yHighKey } = this.properties;
    const xScale = this.axes["x" /* X */]?.scale;
    const yScale = this.axes["y" /* Y */]?.scale;
    const { xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale });
    const extraProps = [];
    const animationEnabled = !this.ctx.animationManager.isSkipped();
    if (this.needsDataModelDiff() && this.processedData) {
      extraProps.push(diff4(this.id, this.processedData));
    }
    if (animationEnabled) {
      extraProps.push(animationValidation4());
    }
    const allowNullKey = this.properties.allowNullKeys ?? false;
    const { dataModel, processedData } = await this.requestDataModel(dataController, this.data, {
      props: [
        keyProperty6(xKey, xScaleType, { id: `xValue`, allowNullKey }),
        valueProperty9(yLowKey, yScaleType, { id: `yLowValue` }),
        valueProperty9(yHighKey, yScaleType, { id: `yHighValue` }),
        ...extraProps
      ]
    });
    this.aggregateData(dataModel, processedData);
    this.animationState.transition("updateData");
  }
  aggregateData(dataModel, processedData) {
    this.aggregationManager.markStale(processedData.input.count);
    if (processedData.type !== "ungrouped")
      return;
    if (processedDataIsAnimatable4(processedData))
      return;
    const xAxis = this.axes["x" /* X */];
    if (xAxis == null)
      return;
    const targetRange = this.estimateTargetRange();
    this.aggregationManager.aggregate({
      computePartial: (existingFilters) => aggregateRangeAreaDataFromDataModelPartial(
        xAxis.scale.type,
        dataModel,
        processedData,
        this,
        targetRange,
        existingFilters
      ),
      computeFull: (existingFilters) => aggregateRangeAreaDataFromDataModel(xAxis.scale.type, dataModel, processedData, this, existingFilters),
      targetRange
    });
    const filters = this.aggregationManager.filters;
    if (filters && filters.length > 0) {
      debugMetrics_exports.record(
        `${this.type}:aggregation`,
        filters.map((f) => f.maxRange)
      );
    }
  }
  estimateTargetRange() {
    const xAxis = this.axes["x" /* X */];
    if (xAxis?.scale?.range) {
      const [r0, r1] = xAxis.scale.range;
      return Math.abs(r1 - r0);
    }
    return this.ctx.scene?.canvas?.width ?? 800;
  }
  /**
   * Creates the context object for efficient node datum creation.
   * Caches expensive-to-compute values that are reused across all datum iterations.
   */
  createNodeDatumContext(xAxis, yAxis) {
    const { dataModel, processedData } = this;
    if (!dataModel || !processedData)
      return void 0;
    const rawData = processedData.dataSources.get(this.id)?.data ?? [];
    const xScale = xAxis.scale;
    const yScale = yAxis.scale;
    const xAxisRange = xAxis.range;
    const [r0, r1] = xScale.range;
    const range3 = Math.abs(r1 - r0);
    this.aggregationManager.ensureLevelForRange(range3);
    const dataAggregationFilter = this.aggregationManager.getFilterForRange(range3);
    const existingNodes = this.contextNodeData?.nodeData;
    const animationEnabled = !this.ctx.animationManager.isSkipped();
    const canIncrementallyUpdate = existingNodes != null && (processedData.changeDescription != null || !processedDataIsAnimatable4(processedData) || dataAggregationFilter != null);
    return {
      xAxis,
      yAxis,
      rawData,
      xValues: dataModel.resolveKeysById(this, "xValue", processedData),
      yHighValues: dataModel.resolveColumnById(this, "yHighValue", processedData),
      yLowValues: dataModel.resolveColumnById(this, "yLowValue", processedData),
      xScale,
      yScale,
      xAxisRange,
      xOffset: (xScale.bandwidth ?? 0) / 2,
      dataAggregationFilter,
      range: range3,
      labelsEnabled: this.properties.label.enabled,
      animationEnabled,
      canIncrementallyUpdate,
      xKey: this.properties.xKey,
      yLowKey: this.properties.yLowKey,
      yHighKey: this.properties.yHighKey,
      item: this.properties.item,
      yDomain: this.getSeriesDomain("y" /* Y */).domain,
      connectMissingData: this.properties.connectMissingData,
      interpolation: this.properties.interpolation,
      nodes: canIncrementallyUpdate ? existingNodes : [],
      labelData: [],
      spanPoints: [],
      nodeIndex: 0
    };
  }
  xCoordinateRange(xValue) {
    const x = this.axes["x" /* X */].scale.convert(xValue);
    return [x, x];
  }
  yCoordinateRange(yValues) {
    const y = this.axes["y" /* Y */].scale.convert(yValues[0]);
    return [y, y];
  }
  getSeriesDomain(direction) {
    const { processedData, dataModel } = this;
    if (!(processedData && dataModel))
      return { domain: [] };
    const {
      domain: {
        keys: [keys]
      }
    } = processedData;
    if (direction === "x" /* X */) {
      const keyDef = dataModel.resolveProcessedDataDefById(this, `xValue`);
      if (keyDef?.def.type === "key" && keyDef.def.valueType === "category") {
        const sortMetadata = dataModel.getKeySortMetadata(this, "xValue", processedData);
        return { domain: keys, sortMetadata };
      }
      return { domain: fixNumericExtent5(extent(keys)) };
    } else {
      const yExtent = this.domainForClippedRange("y" /* Y */, ["yHighValue", "yLowValue"], "xValue");
      const fixedYExtent = findMinMax(yExtent);
      return { domain: fixNumericExtent5(fixedYExtent) };
    }
  }
  getSeriesRange(_direction, visibleRange) {
    return this.domainForVisibleRange("y" /* Y */, ["yHighValue", "yLowValue"], "xValue", visibleRange);
  }
  /**
   * Processes a single datum and updates the context's marker, label, and span arrays.
   * Uses the scratch object to avoid per-iteration allocations.
   *
   * @param yHighValueOverride - Optional override for yHighValue, used in aggregation mode
   *                             when the extreme values come from different data points
   * @param yLowValueOverride - Optional override for yLowValue, used in aggregation mode
   */
  handleDatumPoint(ctx, scratch, datumIndex, yHighValueOverride, yLowValueOverride) {
    scratch.xValue = ctx.xValues[datumIndex];
    if (scratch.xValue === void 0 && !this.properties.allowNullKeys)
      return;
    scratch.datum = ctx.rawData[datumIndex];
    scratch.yHighValue = yHighValueOverride ?? ctx.yHighValues[datumIndex];
    scratch.yLowValue = yLowValueOverride ?? ctx.yLowValues[datumIndex];
    const currentSpanPoints = ctx.spanPoints.at(-1);
    if (Number.isFinite(scratch.yHighValue) && Number.isFinite(scratch.yLowValue)) {
      scratch.inverted = scratch.yLowValue > scratch.yHighValue;
      scratch.x = ctx.xScale.convert(scratch.xValue) + ctx.xOffset;
      if (!Number.isFinite(scratch.x))
        return;
      scratch.yHighCoordinate = ctx.yScale.convert(scratch.yHighValue);
      scratch.yLowCoordinate = ctx.yScale.convert(scratch.yLowValue);
      this.upsertMarkerDatum(ctx, scratch, datumIndex, "high", scratch.yHighValue, scratch.yHighCoordinate);
      this.upsertMarkerDatum(ctx, scratch, datumIndex, "low", scratch.yLowValue, scratch.yLowCoordinate);
      const spanPoint = {
        high: {
          point: { x: scratch.x, y: scratch.yHighCoordinate },
          xDatum: scratch.xValue,
          yDatum: scratch.yHighValue
        },
        low: {
          point: { x: scratch.x, y: scratch.yLowCoordinate },
          xDatum: scratch.xValue,
          yDatum: scratch.yLowValue
        }
      };
      if (Array.isArray(currentSpanPoints)) {
        currentSpanPoints.push(spanPoint);
      } else if (currentSpanPoints == null) {
        ctx.spanPoints.push([spanPoint]);
      } else {
        currentSpanPoints.skip += 1;
        ctx.spanPoints.push([spanPoint]);
      }
    } else if (!ctx.connectMissingData) {
      if (Array.isArray(currentSpanPoints) || currentSpanPoints == null) {
        ctx.spanPoints.push({ skip: 0 });
      } else {
        currentSpanPoints.skip += 1;
      }
    }
  }
  /**
   * Creates or updates marker datum for a single boundary (high or low).
   * Supports incremental updates by reusing existing marker data objects when possible.
   */
  upsertMarkerDatum(ctx, scratch, datumIndex, itemType, yValue, y) {
    const { size } = ctx.item[itemType].marker;
    const canReuseNode = ctx.canIncrementallyUpdate && ctx.nodeIndex < ctx.nodes.length;
    if (canReuseNode) {
      const existingNode = ctx.nodes[ctx.nodeIndex];
      existingNode.index = datumIndex;
      existingNode.itemType = itemType;
      existingNode.datum = scratch.datum;
      existingNode.datumIndex = datumIndex;
      existingNode.midPoint = { x: scratch.x, y };
      existingNode.yHighValue = scratch.yHighValue;
      existingNode.yLowValue = scratch.yLowValue;
      existingNode.xValue = scratch.xValue;
      existingNode.point = { x: scratch.x, y, size };
    } else {
      ctx.nodes.push({
        index: datumIndex,
        series: this,
        itemType,
        datum: scratch.datum,
        datumIndex,
        midPoint: { x: scratch.x, y },
        yHighValue: scratch.yHighValue,
        yLowValue: scratch.yLowValue,
        xValue: scratch.xValue,
        xKey: ctx.xKey,
        yLowKey: ctx.yLowKey,
        yHighKey: ctx.yHighKey,
        point: { x: scratch.x, y, size },
        enabled: true
      });
    }
    ctx.nodeIndex++;
    if (ctx.labelsEnabled) {
      const labelDatum = this.createLabelData({
        datumIndex,
        point: { x: scratch.x, y },
        value: yValue,
        yLowValue: scratch.yLowValue,
        yHighValue: scratch.yHighValue,
        itemType,
        inverted: scratch.inverted,
        datum: scratch.datum,
        series: this
      });
      ctx.labelData.push(labelDatum);
    }
  }
  populateNodeData(ctx) {
    const { processedData } = this;
    if (!processedData)
      return;
    const scratch = {
      datum: void 0,
      xValue: void 0,
      yHighValue: 0,
      yLowValue: 0,
      x: 0,
      yHighCoordinate: 0,
      yLowCoordinate: 0,
      inverted: false
    };
    const xPosition = (index) => ctx.xScale.convert(ctx.xValues[index]) + ctx.xOffset;
    if (processedData.input.count < 1e3 || ctx.dataAggregationFilter == null) {
      let [start2, end3] = visibleRangeIndices3(1, ctx.xValues.length, ctx.xAxisRange, (index) => {
        const x = xPosition(index);
        return [x, x];
      });
      if (processedData.input.count < 1e3) {
        start2 = 0;
        end3 = processedData.input.count;
      }
      start2 = Math.max(start2 - 1, 0);
      end3 = Math.min(end3 + 1, ctx.xValues.length);
      for (let datumIndex = start2; datumIndex < end3; datumIndex += 1) {
        this.handleDatumPoint(ctx, scratch, datumIndex);
      }
    } else {
      const { maxRange, indexData, midpointIndices } = ctx.dataAggregationFilter;
      const [start2, end3] = visibleRangeIndices3(1, maxRange, ctx.xAxisRange, (index) => {
        const midDatumIndex = midpointIndices[index];
        if (midDatumIndex === AGGREGATION_INDEX_UNSET)
          return;
        return [xPosition(midDatumIndex), xPosition(midDatumIndex)];
      });
      for (let bucketIndex = start2; bucketIndex < end3; bucketIndex += 1) {
        const midIndex = midpointIndices[bucketIndex];
        if (midIndex === AGGREGATION_INDEX_UNSET)
          continue;
        const aggIndex = bucketIndex * SPAN3;
        const yHighDatumIndex = indexData[aggIndex + HIGH2];
        const yLowDatumIndex = indexData[aggIndex + LOW2];
        this.handleDatumPoint(
          ctx,
          scratch,
          yHighDatumIndex,
          ctx.yHighValues[yHighDatumIndex],
          ctx.yLowValues[yLowDatumIndex]
        );
      }
    }
  }
  finalizeNodeData(ctx) {
    if (ctx.canIncrementallyUpdate && ctx.nodeIndex < ctx.nodes.length) {
      ctx.nodes.length = ctx.nodeIndex;
    }
  }
  initializeResult(ctx) {
    return {
      itemId: `${ctx.yLowKey}-${ctx.yHighKey}`,
      labelData: ctx.labelData,
      nodeData: ctx.nodes,
      fillData: { itemType: "high", spans: [], phantomSpans: [] },
      highStrokeData: { itemType: "high", spans: [] },
      lowStrokeData: { itemType: "low", spans: [] },
      scales: this.calculateScaling(),
      visible: this.visible,
      styles: {
        low: this.getLowOrHighMarkerStyles("low"),
        high: this.getLowOrHighMarkerStyles("high")
      },
      segments: void 0,
      intersectionSegments: void 0
    };
  }
  assembleResult(ctx, result) {
    const xAxis = this.axes["x" /* X */];
    const yAxis = this.axes["y" /* Y */];
    if (!xAxis || !yAxis || !this.chart?.seriesRect)
      return result;
    const highSpans = ctx.spanPoints.flatMap((p) => {
      if (!Array.isArray(p))
        return [];
      const highPoints = p.map((d) => d.high);
      return interpolatePoints2(highPoints, ctx.interpolation);
    });
    const lowSpans = ctx.spanPoints.flatMap((p) => {
      if (!Array.isArray(p))
        return [];
      const lowPoints = p.map((d) => d.low);
      return interpolatePoints2(lowPoints, ctx.interpolation);
    });
    const segments = calculateSegments3(
      this.properties.segmentation,
      xAxis,
      yAxis,
      this.chart.seriesRect,
      this.ctx.scene,
      false
    );
    let intersectionSegments = void 0;
    if (this.properties.invertedStyle.enabled) {
      const startsInverted = ctx.yHighValues[0] < ctx.yLowValues[0];
      const intersectionXValues = findRangeAreaIntersections(
        highSpans,
        lowSpans,
        ctx.xScale.range[0],
        ctx.xScale.range[1],
        startsInverted
      );
      intersectionSegments = calculateIntersectionSegments(
        intersectionXValues,
        this.chart.seriesRect,
        this.ctx.scene,
        startsInverted,
        this.properties.invertedStyle
      );
    }
    result.fillData = { itemType: "high", spans: highSpans, phantomSpans: lowSpans };
    result.highStrokeData = { itemType: "high", spans: highSpans };
    result.lowStrokeData = { itemType: "low", spans: lowSpans };
    result.segments = segments;
    result.intersectionSegments = intersectionSegments;
    return result;
  }
  getLowOrHighMarkerStyles(lowOrHigh) {
    const { fill, fillOpacity, item } = this.properties;
    const line = item[lowOrHigh];
    const { stroke: stroke3, strokeWidth, strokeOpacity } = line;
    const inheritedStyles = { fill, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity };
    return getMarkerStyles2(this, line, line.marker, inheritedStyles);
  }
  createLabelData({
    datumIndex,
    point,
    value,
    itemType,
    inverted,
    datum,
    series
  }) {
    const { xKey, yLowKey, yHighKey, xName, yName, yLowName, yHighName, legendItemName, label } = this.properties;
    const { placement } = label;
    const spacing = label.spacing + (typeof label.padding === "number" ? label.padding : 0);
    let actualItemId = itemType;
    if (inverted) {
      actualItemId = itemType === "low" ? "high" : "low";
    }
    const direction = placement === "outside" && actualItemId === "high" || placement === "inside" && actualItemId === "low" ? -1 : 1;
    const yDomain = this.getSeriesDomain("y" /* Y */).domain;
    return {
      x: point.x,
      y: point.y + spacing * direction,
      series,
      itemType,
      datum,
      datumIndex,
      text: this.getLabelText(
        value,
        datum,
        itemType === "high" ? yHighKey : yLowKey,
        "y",
        yDomain,
        label,
        { value, datum, itemType, xKey, yLowKey, yHighKey, xName, yLowName, yHighName, yName, legendItemName }
      ),
      textAlign: "center",
      textBaseline: direction === -1 ? "bottom" : "top"
    };
  }
  isPathOrSelectionDirty() {
    const { low, high } = this.properties.item;
    return low.marker.isDirty() || high.marker.isDirty();
  }
  strokewidthChange() {
    const itemStrokeWidthChange = (lowOrHigh) => {
      const unhighlightedStrokeWidth = this.properties.item[lowOrHigh].strokeWidth ?? 0;
      const highlightedSeriesStrokeWidth = this.properties.highlight.highlightedSeries.item?.[lowOrHigh]?.strokeWidth ?? unhighlightedStrokeWidth;
      const highlightedItemStrokeWidth = this.properties.highlight.highlightedItem.item?.[lowOrHigh]?.strokeWidth ?? unhighlightedStrokeWidth;
      return unhighlightedStrokeWidth > highlightedItemStrokeWidth || highlightedSeriesStrokeWidth > highlightedItemStrokeWidth;
    };
    return itemStrokeWidthChange("low") || itemStrokeWidthChange("high");
  }
  updatePathNodes(opts) {
    const { visible } = opts;
    const [fillPath, lowStrokePath, highStrokePath] = opts.paths;
    const segments = this.contextNodeData?.segments;
    const highlightDatum = this.ctx.highlightManager?.getActiveHighlight();
    const highlightState = this.getHighlightState(highlightDatum, false);
    const highlightStyle = this.getHighlightStyle();
    const { item, fill, fillOpacity, opacity } = mergeDefaults(highlightStyle, this.getStyle(highlightState));
    lowStrokePath.setProperties({
      datum: segments,
      segments,
      fill: void 0,
      lineCap: "round",
      lineJoin: "round",
      pointerEvents: PointerEvents5.None,
      stroke: item.low.stroke,
      strokeWidth: item.low.strokeWidth,
      strokeOpacity: item.low.strokeOpacity,
      lineDash: item.low.lineDash,
      lineDashOffset: item.low.lineDashOffset,
      opacity,
      visible
    });
    highStrokePath.setProperties({
      segments,
      fill: void 0,
      lineCap: "round",
      lineJoin: "round",
      pointerEvents: PointerEvents5.None,
      stroke: item.high.stroke,
      strokeWidth: item.high.strokeWidth,
      strokeOpacity: item.high.strokeOpacity,
      lineDash: item.high.lineDash,
      lineDashOffset: item.high.lineDashOffset,
      opacity,
      visible
    });
    const fillBBox = this.getShapeFillBBox();
    fillPath.setFillProperties(fill, fillBBox);
    fillPath.setStyleProperties({ stroke: void 0, fill, fillOpacity, opacity }, fillBBox);
    const fillSegments = this.contextNodeData?.intersectionSegments ?? segments;
    fillPath.setProperties({
      segments: fillSegments,
      pointerEvents: PointerEvents5.None,
      lineJoin: "round",
      fillShadow: this.properties.shadow,
      opacity,
      visible
    });
    fillPath.datum = fillSegments;
    updateClipPath2(this, fillPath);
    updateClipPath2(this, lowStrokePath);
    updateClipPath2(this, highStrokePath);
  }
  updatePaths(opts) {
    this.updateAreaPaths(opts.paths, opts.contextData);
  }
  updateAreaPaths(paths, contextData) {
    for (const path of paths) {
      path.visible = contextData.visible;
    }
    if (contextData.visible) {
      this.updateFillPath(paths, contextData);
      this.updateStrokePath(paths, contextData);
    } else {
      for (const path of paths) {
        path.path.clear();
        path.markDirty("RangeArea");
      }
    }
  }
  updateFillPath(paths, contextData) {
    const [fill] = paths;
    fill.path.clear();
    plotAreaPathFill2(fill, contextData.fillData);
    fill.markDirty("RangeArea");
  }
  updateStrokePath(paths, contextData) {
    const [, lowStroke, highStroke] = paths;
    lowStroke.path.clear();
    highStroke.path.clear();
    plotLinePathStroke2(lowStroke, contextData.lowStrokeData.spans);
    plotLinePathStroke2(highStroke, contextData.highStrokeData.spans);
    lowStroke.markDirty("RangeArea");
    highStroke.markDirty("RangeArea");
  }
  resetDatumAnimation(data) {
    resetMarkerSelectionsDirect2([data.datumSelection]);
  }
  updateDatumSelection(opts) {
    const { nodeData, datumSelection } = opts;
    const { processedData, axes, properties } = this;
    const rules = properties.styler ? this.getStylerMarkerOptions().item : properties.item;
    const { low, high } = rules;
    const markersEnabled = markerEnabled2(processedData.input.count, axes["x" /* X */].scale, {
      enabled: low.marker.enabled || high.marker.enabled
    });
    if (properties.item.low.marker.isDirty() || properties.item.high.marker.isDirty()) {
      datumSelection.clear();
      datumSelection.cleanup();
    }
    let resolvedNodeData;
    if (markersEnabled) {
      if (low.marker.enabled && high.marker.enabled) {
        resolvedNodeData = nodeData;
      } else {
        resolvedNodeData = [];
        for (const datum of nodeData) {
          if (rules[datum.itemType].marker.enabled) {
            resolvedNodeData.push(datum);
          }
        }
      }
    } else {
      resolvedNodeData = [];
    }
    if (!processedDataIsAnimatable4(this.processedData)) {
      return datumSelection.update(resolvedNodeData);
    }
    return datumSelection.update(
      resolvedNodeData,
      void 0,
      (datum) => createDatumId10(datum.xValue, datum.itemType)
    );
  }
  updateDatumStyles({
    datumSelection,
    isHighlight
  }) {
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    datumSelection.each((_, datum) => {
      const highlightState = this.getHighlightState(highlightedDatum, isHighlight, datum.datumIndex);
      const stylerStyle = this.getStyle(highlightState);
      const { fill, fillOpacity, item } = stylerStyle;
      const { stroke: stroke3, strokeWidth, strokeOpacity } = item[datum.itemType];
      const { marker } = this.properties.item[datum.itemType];
      const params = this.makeItemStylerParams(datum.itemType);
      datum.style = this.getMarkerStyle(
        marker,
        datum,
        params,
        { isHighlight, highlightState, resolveMarkerSubPath: ["item", datum.itemType, "marker"] },
        stylerStyle.item[datum.itemType].marker,
        {
          fill,
          fillOpacity,
          stroke: stroke3,
          strokeWidth,
          strokeOpacity
        }
      );
    });
  }
  updateDatumNodes(opts) {
    const { contextNodeData } = this;
    if (!contextNodeData) {
      return;
    }
    const { datumSelection, isHighlight } = opts;
    const fillBBox = this.getShapeFillBBox();
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    const drawingMode = this.getDrawingMode(isHighlight, opts.drawingMode);
    datumSelection.each((node, datum) => {
      const { itemType } = datum;
      const style2 = datum.style ?? contextNodeData.styles[itemType][this.getHighlightState(highlightedDatum, isHighlight, datum.datumIndex)];
      this.applyMarkerStyle(style2, node, datum.point, fillBBox);
      node.drawingMode = drawingMode;
    });
    if (!isHighlight) {
      this.properties.item.low.marker.markClean();
      this.properties.item.high.marker.markClean();
    }
  }
  updateLabelSelection(opts) {
    const { labelData, labelSelection } = opts;
    return labelSelection.update(labelData, (text2) => {
      text2.pointerEvents = PointerEvents5.None;
    });
  }
  updateLabelNodes(opts) {
    const params = {
      xKey: this.properties.xKey,
      xName: this.properties.xName ?? this.properties.xKey,
      yName: this.properties.yName,
      yLowKey: this.properties.yLowKey,
      yLowName: this.properties.yLowName ?? this.properties.yLowKey,
      yHighKey: this.properties.yHighKey,
      yHighName: this.properties.yHighName ?? this.properties.yHighKey,
      legendItemName: this.properties.legendItemName
    };
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const { isHighlight = false, labelSelection } = opts;
    labelSelection.each((textNode, datum) => {
      textNode.fillOpacity = this.getHighlightStyle(isHighlight, datum.datumIndex).opacity ?? 1;
      updateLabelNode3(this, textNode, params, this.properties.label, datum, isHighlight, activeHighlight);
    });
  }
  getHighlightLabelData(labelData, highlightedItem) {
    if (!labelData?.length)
      return [];
    return labelData.filter((labelDatum) => labelDatum.datum === highlightedItem.datum);
  }
  getHighlightData(nodeData, highlightedItem) {
    const highlightItems = nodeData.filter((nodeDatum) => nodeDatum.datum === highlightedItem.datum).map((nodeDatum) => ({ ...nodeDatum }));
    return highlightItems.length > 0 ? highlightItems : void 0;
  }
  getStyle(highlightState) {
    return this.getStylerCouple(highlightState)[0];
  }
  getStylerMarkerOptions() {
    return this.getStylerCouple()[1];
  }
  getStylerCouple(highlightState) {
    const { fill, fillOpacity, item, styler } = this.properties;
    let stylerResult = {};
    if (styler) {
      const stylerParams = this.makeStylerParams(highlightState);
      stylerResult = this.ctx.optionsGraphService.resolvePartial(
        ["series", `${this.declarationOrder}`],
        this.cachedCallWithContext(styler, stylerParams) ?? {},
        { pick: false }
      ) ?? {};
    }
    const markerOpts = {
      item: { low: { marker: { enabled: false } }, high: { marker: { enabled: false } } }
    };
    const makeItemResult = (lowOrHigh) => {
      const stylerItem = stylerResult.item?.[lowOrHigh];
      const { lineDash, lineDashOffset, marker, stroke: stroke3, strokeOpacity, strokeWidth } = item[lowOrHigh];
      markerOpts.item[lowOrHigh].marker.enabled = stylerItem?.marker?.enabled ?? marker.enabled;
      return {
        marker: {
          fill: stylerItem?.marker?.fill ?? marker.fill ?? fill,
          fillOpacity: stylerItem?.marker?.fillOpacity ?? marker.fillOpacity,
          shape: stylerItem?.marker?.shape ?? marker.shape,
          size: stylerItem?.marker?.size ?? marker.size,
          lineDash: stylerItem?.marker?.lineDash ?? marker.lineDash,
          lineDashOffset: stylerItem?.marker?.lineDashOffset ?? marker.lineDashOffset,
          stroke: stylerItem?.marker?.stroke ?? marker.stroke ?? stroke3,
          strokeOpacity: stylerItem?.marker?.strokeOpacity ?? marker.strokeOpacity,
          strokeWidth: stylerItem?.marker?.strokeWidth ?? marker.strokeWidth
        },
        lineDash: stylerItem?.lineDash ?? lineDash,
        lineDashOffset: stylerItem?.lineDashOffset ?? lineDashOffset,
        stroke: stylerItem?.stroke ?? stroke3,
        strokeOpacity: stylerItem?.strokeOpacity ?? strokeOpacity,
        strokeWidth: stylerItem?.strokeWidth ?? strokeWidth
      };
    };
    const style2 = {
      fill: stylerResult.fill ?? fill,
      fillOpacity: stylerResult.fillOpacity ?? fillOpacity,
      opacity: 1,
      topLevel: {
        lineDash: this.properties.lineDash,
        lineDashOffset: this.properties.lineDashOffset,
        marker: this.properties.marker,
        stroke: this.properties.stroke,
        strokeOpacity: this.properties.strokeOpacity,
        strokeWidth: this.properties.strokeWidth
      },
      item: {
        low: makeItemResult("low"),
        high: makeItemResult("high")
      }
    };
    return [style2, markerOpts];
  }
  makeStylerParams(highlightStateEnum) {
    const { id: seriesId } = this;
    const { fill, fillOpacity, item, xKey, yHighKey, yLowKey } = this.properties;
    const highlightState = toHighlightString3(highlightStateEnum ?? HighlightState5.None);
    const makeItemParam = (lowOrHigh) => {
      const { lineDash, lineDashOffset, marker, stroke: stroke3, strokeOpacity, strokeWidth } = item[lowOrHigh];
      return {
        marker: {
          fill: marker.fill ?? fill,
          fillOpacity: marker.fillOpacity,
          size: marker.size,
          shape: marker.shape,
          stroke: marker.stroke ?? stroke3,
          strokeOpacity: marker.strokeOpacity,
          strokeWidth: marker.strokeWidth,
          lineDash: marker.lineDash,
          lineDashOffset: marker.lineDashOffset
        },
        lineDash,
        lineDashOffset,
        stroke: stroke3,
        strokeOpacity,
        strokeWidth
      };
    };
    return {
      item: {
        low: makeItemParam("low"),
        high: makeItemParam("high")
      },
      fill,
      fillOpacity,
      highlightState,
      seriesId,
      xKey,
      yLowKey,
      yHighKey
    };
  }
  makeItemStylerParams(itemType) {
    const { xKey, yLowKey, yHighKey } = this.properties;
    return { xKey, yLowKey, yHighKey, itemType };
  }
  getTooltipContent(datumIndex, removeThisDatum) {
    const itemType = removeThisDatum?.itemType ?? "high";
    const { id: seriesId, dataModel, processedData, axes, properties } = this;
    const { xName, yName, yLowKey, yLowName, xKey, yHighKey, yHighName, tooltip, legendItemName } = properties;
    const xAxis = axes["x" /* X */];
    const yAxis = axes["y" /* Y */];
    if (!dataModel || !processedData || !xAxis || !yAxis)
      return;
    const datum = processedData.dataSources.get(this.id)?.data[datumIndex];
    const xValue = dataModel.resolveKeysById(this, `xValue`, processedData)[datumIndex];
    const yHighValue = dataModel.resolveColumnById(this, `yHighValue`, processedData)[datumIndex];
    const yLowValue = dataModel.resolveColumnById(this, `yLowValue`, processedData)[datumIndex];
    const allowNullKeys = this.properties.allowNullKeys ?? false;
    if (xValue === void 0 && !allowNullKeys)
      return;
    const stylerStyle = this.getStyle();
    const params = this.makeItemStylerParams(itemType);
    const format = this.getMarkerStyle(
      this.properties.item[itemType].marker,
      { datumIndex, datum },
      params,
      { isHighlight: false, resolveMarkerSubPath: ["item", itemType, "marker"] },
      stylerStyle.item[itemType].marker
    );
    const value = `${this.getAxisValueText(yAxis, "tooltip", yLowValue, datum, yLowKey, legendItemName)} - ${this.getAxisValueText(yAxis, "tooltip", yHighValue, datum, yHighKey, legendItemName)}`;
    return this.formatTooltipWithContext(
      tooltip,
      {
        heading: this.getAxisValueText(xAxis, "tooltip", xValue, datum, xKey, legendItemName),
        symbol: this.legendItemSymbol(),
        data: [
          {
            label: yName,
            fallbackLabel: `${yLowName ?? yLowKey} - ${yHighName ?? yHighKey}`,
            value,
            missing: module_support_exports.isTooltipValueMissing(yHighValue) && module_support_exports.isTooltipValueMissing(yLowValue)
          }
        ]
      },
      {
        seriesId,
        datum,
        title: yName,
        itemType,
        xName,
        yName,
        yLowKey,
        yLowName,
        xKey,
        yHighKey,
        yHighName,
        legendItemName,
        ...format
      }
    );
  }
  legendItemSymbol() {
    const { fill, topLevel } = this.getStyle();
    const { stroke: stroke3, strokeWidth, strokeOpacity, lineDash, marker } = topLevel;
    const markerStyle = {
      shape: marker.shape,
      fill: marker.fill ?? fill,
      stroke: marker.stroke ?? stroke3,
      fillOpacity: marker.fillOpacity,
      strokeOpacity: marker.strokeOpacity,
      strokeWidth: marker.strokeWidth,
      lineDash: marker.lineDash,
      lineDashOffset: marker.lineDashOffset
    };
    return {
      marker: markerStyle,
      line: {
        enabled: true,
        stroke: stroke3,
        strokeOpacity,
        strokeWidth,
        lineDash
      }
    };
  }
  getLegendData(legendType) {
    if (legendType !== "category") {
      return [];
    }
    const { id: seriesId, visible } = this;
    const { yLowKey, yHighKey, yName, yLowName, yHighName, legendItemName, showInLegend } = this.properties;
    const legendItemText = legendItemName ?? yName ?? `${yLowName ?? yLowKey} - ${yHighName ?? yHighKey}`;
    const itemId = `${yLowKey}-${yHighKey}`;
    return [
      {
        legendType: "category",
        id: seriesId,
        itemId,
        seriesId,
        enabled: visible,
        label: { text: `${legendItemText}` },
        symbol: this.legendItemSymbol(),
        legendItemName,
        hideInLegend: !showInLegend
      }
    ];
  }
  isLabelEnabled() {
    return this.properties.label.enabled;
  }
  nodeFactory() {
    return new Marker2();
  }
  animateEmptyUpdateReady(animationData) {
    const { datumSelection, labelSelection, contextData, paths } = animationData;
    const { animationManager } = this.ctx;
    this.updateAreaPaths(paths, contextData);
    pathSwipeInAnimation2(this, animationManager, ...paths);
    resetMotion2([datumSelection], resetMarkerPositionFn2);
    markerSwipeScaleInAnimation2(
      this,
      animationManager,
      { ...this.getAnimationDrawingModes(), phase: "initial" },
      datumSelection
    );
    seriesLabelFadeInAnimation3(this, "labels", animationManager, labelSelection, this.highlightLabelSelection);
  }
  animateReadyResize(animationData) {
    const { contextData, paths } = animationData;
    this.updateAreaPaths(paths, contextData);
    super.animateReadyResize(animationData);
  }
  animateWaitingUpdateReady(animationData) {
    const { animationManager } = this.ctx;
    const { datumSelection, labelSelection, contextData, paths, previousContextData } = animationData;
    const [fill, lowStroke, highStroke] = paths;
    if (fill == null && lowStroke == null && highStroke == null)
      return;
    this.resetDatumAnimation(animationData);
    this.resetLabelAnimation(animationData);
    const update = () => {
      this.resetPathAnimation(animationData);
      this.updateAreaPaths(paths, contextData);
    };
    const skip = () => {
      animationManager.skipCurrentBatch();
      update();
    };
    if (contextData == null || previousContextData == null) {
      update();
      markerFadeInAnimation2(this, animationManager, "added", this.getAnimationDrawingModes(), datumSelection);
      pathFadeInAnimation2(this, "fill_path_properties", animationManager, "add", fill);
      pathFadeInAnimation2(this, "low_stroke_path_properties", animationManager, "add", lowStroke);
      pathFadeInAnimation2(this, "high_stroke_path_properties", animationManager, "add", highStroke);
      seriesLabelFadeInAnimation3(this, "labels", animationManager, labelSelection, this.highlightLabelSelection);
      return;
    }
    const fns = prepareRangeAreaPathAnimation(
      contextData,
      previousContextData,
      this.processedData?.reduced?.diff?.[this.id]
    );
    if (fns === void 0) {
      skip();
      return;
    } else if (fns.status === "no-op") {
      return;
    }
    fromToMotion4(this.id, "fill_path_properties", animationManager, [fill], fns.fill.pathProperties);
    fromToMotion4(this.id, "low_stroke_path_properties", animationManager, [lowStroke], fns.stroke.pathProperties);
    fromToMotion4(this.id, "high_stroke_path_properties", animationManager, [highStroke], fns.stroke.pathProperties);
    if (fns.status === "added") {
      this.updateAreaPaths(paths, contextData);
    } else if (fns.status === "removed") {
      this.updateAreaPaths(paths, previousContextData);
    } else {
      pathMotion2(this.id, "fill_path_update", animationManager, [fill], fns.fill.path);
      pathMotion2(this.id, "low_stroke_path_update", animationManager, [lowStroke], fns.stroke.path);
      pathMotion2(this.id, "high_stroke_path_update", animationManager, [highStroke], fns.stroke.path);
    }
    if (fns.hasMotion) {
      markerFadeInAnimation2(this, animationManager, void 0, this.getAnimationDrawingModes(), datumSelection);
      seriesLabelFadeInAnimation3(this, "labels", animationManager, labelSelection, this.highlightLabelSelection);
    }
    this.ctx.animationManager.animate({
      id: this.id,
      groupId: "reset_after_animation",
      phase: "trailing",
      from: {},
      to: {},
      onComplete: () => this.updateAreaPaths(paths, contextData)
    });
  }
  getFormattedMarkerStyle(datum) {
    const stylerStyle = this.getStyle();
    const params = this.makeItemStylerParams(datum.itemType);
    return this.getMarkerStyle(
      this.properties.item[datum.itemType].marker,
      datum,
      params,
      { isHighlight: true, resolveMarkerSubPath: ["item", datum.itemType, "marker"] },
      void 0,
      stylerStyle
    );
  }
  getMarkerStyle(marker, datum, params, opts, defaultOverrideStyle, inheritedStyle) {
    true;
    marker.itemStyler = this.properties.marker.itemStyler;
    return super.getMarkerStyle(marker, datum, params, opts, defaultOverrideStyle, inheritedStyle);
  }
  computeFocusBounds(opts) {
    const hiBox = computeMarkerFocusBounds2(this, opts);
    const loBox = computeMarkerFocusBounds2(this, { ...opts, datumIndex: opts.datumIndex + 1 });
    if (hiBox && loBox) {
      return BBox20.merge([hiBox, loBox]);
    }
    return void 0;
  }
  isDatumEnabled(nodeData, datumIndex) {
    return datumIndex % 2 === 0 && super.isDatumEnabled(nodeData, datumIndex);
  }
  hasItemStylers() {
    return this.properties.styler != null || this.properties.marker.itemStyler != null || this.properties.label.itemStyler != null;
  }
};
RangeAreaSeries.className = "RangeAreaSeries";
RangeAreaSeries.type = "range-area";

// packages/ag-charts-enterprise/src/series/range-area/rangeAreaSeriesOptionsDef.ts
var { rangeAreaSeriesThemeableOptionsDef: rangeAreaSeriesThemeableOptionsDef2 } = module_support_exports;
var rangeAreaSeriesOptionsDef = {
  ...commonSeriesOptionsDefs,
  ...rangeAreaSeriesThemeableOptionsDef2,
  type: required(constant("range-area")),
  xKey: required(string),
  yLowKey: required(string),
  yHighKey: required(string),
  xKeyAxis: string,
  yKeyAxis: string,
  xName: string,
  yName: string,
  yLowName: string,
  yHighName: string,
  legendItemName: string,
  segmentation: shapeSegmentation,
  invertedStyle: {
    enabled: boolean,
    ...fillOptionsDef
  }
};
rangeAreaSeriesOptionsDef.pickOutsideVisibleMinorAxis = undocumented(boolean);
rangeAreaSeriesOptionsDef.focusPriority = undocumented(number);

// packages/ag-charts-enterprise/src/series/range-area/rangeAreaThemes.ts
var RANGE_AREA_ITEM = {
  lineDash: {
    $path: "/series/$index/lineDash"
  },
  lineDashOffset: {
    $path: "/series/$index/lineDashOffset"
  },
  stroke: {
    $path: ["/series/$index/stroke", { $palette: "stroke" }]
  },
  strokeOpacity: {
    $path: "/series/$index/strokeOpacity"
  },
  strokeWidth: {
    $path: ["/series/$index/strokeWidth", 1]
  },
  marker: {
    enabled: {
      $path: "/series/$index/marker/enabled"
    },
    fill: {
      $isUserOption: [
        "/series/$index/marker/fill",
        {
          $if: [
            {
              $or: [
                { $isGradient: { $path: "/series/$index/marker/fill" } },
                { $isImage: { $path: "/series/$index/marker/fill" } },
                { $isPattern: { $path: "/series/$index/marker/fill" } }
              ]
            },
            {
              $merge: [
                { $path: "/series/$index/marker/fill" },
                {
                  $applySwitch: [
                    { $path: "type" },
                    void 0,
                    // default case shouldn't be hit because of $if
                    ["gradient", FILL_GRADIENT_RADIAL_REVERSED_DEFAULTS],
                    ["image", FILL_IMAGE_DEFAULTS],
                    ["pattern", FILL_PATTERN_DEFAULTS]
                  ]
                }
              ]
            },
            {
              $isUserOption: [
                "/series/$index/marker/fill",
                { $path: "/series/$index/marker/fill" },
                { $palette: "fill" }
              ]
            }
          ]
        },
        {
          $applySwitch: [
            { $path: "type" },
            { $palette: "fill" },
            ["gradient", FILL_GRADIENT_RADIAL_REVERSED_DEFAULTS],
            ["image", FILL_IMAGE_DEFAULTS],
            ["pattern", FILL_PATTERN_DEFAULTS]
          ]
        }
      ]
    },
    fillOpacity: {
      $path: "/series/$index/marker/fillOpacity"
    },
    lineDash: {
      $path: "/series/$index/marker/lineDash"
    },
    lineDashOffset: {
      $path: "/series/$index/marker/lineDashOffset"
    },
    shape: {
      $path: "/series/$index/marker/shape"
    },
    size: {
      $path: ["/series/$index/marker/size", 6]
    },
    stroke: {
      $path: ["/series/$index/marker/stroke", { $palette: "stroke" }]
    },
    strokeOpacity: {
      $path: "/series/$index/marker/strokeOpacity"
    },
    strokeWidth: {
      $path: ["/series/$index/marker/strokeWidth", 2]
    }
  }
};
var RANGE_AREA_SERIES_THEME = {
  series: {
    fill: {
      $applySwitch: [
        { $path: "type" },
        { $palette: "fill" },
        ["gradient", FILL_GRADIENT_LINEAR_DEFAULTS],
        ["pattern", FILL_PATTERN_DEFAULTS]
      ]
    },
    fillOpacity: 0.7,
    stroke: { $palette: "stroke" },
    strokeWidth: 1,
    marker: {
      enabled: false,
      fill: {
        $applySwitch: [
          { $path: "type" },
          { $palette: "fill" },
          ["gradient", FILL_GRADIENT_RADIAL_REVERSED_DEFAULTS],
          ["image", FILL_IMAGE_DEFAULTS],
          ["pattern", FILL_PATTERN_DEFAULTS]
        ]
      },
      shape: "circle",
      stroke: { $palette: "stroke" },
      size: 6,
      strokeWidth: 2
    },
    nodeClickRange: "nearest",
    item: {
      low: RANGE_AREA_ITEM,
      high: RANGE_AREA_ITEM
    },
    label: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: false,
      placement: "outside",
      padding: { $isUserOption: ["./spacing", 0, 10] },
      // compatibility with old `padding` property (now named `spacing`).
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      fontWeight: { $ref: "fontWeight" },
      color: { $ref: "textColor" }
    },
    interpolation: {
      type: "linear"
    },
    tooltip: {
      range: { $path: ["/tooltip/range", "nearest"] }
    },
    highlight: MARKER_SERIES_HIGHLIGHT_STYLE,
    segmentation: SEGMENTATION_DEFAULTS,
    invertedStyle: {
      enabled: false,
      fill: {
        $applySwitch: [
          { $path: "type" },
          { $palette: "fill" },
          // @todo(AG-14792) should be { $path: '../fill' } to inherit from series.fill
          ["gradient", FILL_GRADIENT_LINEAR_DEFAULTS],
          ["image", FILL_IMAGE_DEFAULTS],
          ["pattern", FILL_PATTERN_DEFAULTS]
        ]
      },
      fillOpacity: { $path: "../fillOpacity" }
    }
  },
  axes: {
    ["number" /* NUMBER */]: {
      crosshair: { enabled: true }
    }
  }
};

// packages/ag-charts-enterprise/src/series/range-area/rangeAreaModule.ts
var { predictCartesianNonPrimitiveAxis: predictCartesianNonPrimitiveAxis3 } = module_support_exports;
var RangeAreaSeriesModule = {
  type: "series",
  name: "range-area",
  chartType: "cartesian",
  enterprise: true,
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: rangeAreaSeriesOptionsDef,
  matchingKeys: ["xKey", "yLowKey", "yHighKey", "normalizedTo"],
  predictAxis: predictCartesianNonPrimitiveAxis3,
  defaultAxes: {
    y: { type: "number" /* NUMBER */, position: "left" /* LEFT */ },
    x: { type: "category" /* CATEGORY */, position: "bottom" /* BOTTOM */ }
  },
  axisKeys: { ["x" /* X */]: "xKeyAxis", ["y" /* Y */]: "yKeyAxis" },
  themeTemplate: RANGE_AREA_SERIES_THEME,
  create: (ctx) => new RangeAreaSeries(ctx)
};

// packages/ag-charts-enterprise/src/series/range-bar/rangeBarAggregation.ts
function aggregateRangeBarData(scale2, xValues, highValues, lowValues, domainInput, smallestKeyInterval, xNeedsValueOf, yNeedsValueOf) {
  const [d0, d1] = aggregationDomain(scale2, domainInput);
  return computeExtremesAggregation([d0, d1], xValues, highValues, lowValues, {
    smallestKeyInterval,
    xNeedsValueOf,
    yNeedsValueOf
  });
}
var memoizedAggregateRangeBarData = simpleMemorize2(aggregateRangeBarData);
function aggregateRangeBarDataFromDataModel(scale2, dataModel, processedData, series, existingFilters) {
  const xValues = dataModel.resolveKeysById(series, "xValue", processedData);
  const highValues = dataModel.resolveColumnById(series, "yHighValue", processedData);
  const lowValues = dataModel.resolveColumnById(series, "yLowValue", processedData);
  const domainInput = dataModel.getDomain(series, "xValue", "key", processedData);
  const xNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "xValue", processedData);
  const yNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "yHighValue", processedData) ?? dataModel.resolveColumnNeedsValueOf(series, "yLowValue", processedData);
  if (existingFilters) {
    const [d0, d1] = aggregationDomain(scale2, domainInput);
    return computeExtremesAggregation([d0, d1], xValues, highValues, lowValues, {
      smallestKeyInterval: processedData.reduced?.smallestKeyInterval,
      xNeedsValueOf,
      yNeedsValueOf,
      existingFilters
    });
  }
  return memoizedAggregateRangeBarData(
    scale2,
    xValues,
    highValues,
    lowValues,
    domainInput,
    processedData.reduced?.smallestKeyInterval,
    xNeedsValueOf,
    yNeedsValueOf
  );
}
function aggregateRangeBarDataFromDataModelPartial(scale2, dataModel, processedData, series, targetRange, existingFilters) {
  const xValues = dataModel.resolveKeysById(series, "xValue", processedData);
  const highValues = dataModel.resolveColumnById(series, "yHighValue", processedData);
  const lowValues = dataModel.resolveColumnById(series, "yLowValue", processedData);
  const domainInput = dataModel.getDomain(series, "xValue", "key", processedData);
  const xNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "xValue", processedData);
  const yNeedsValueOf = dataModel.resolveColumnNeedsValueOf(series, "yHighValue", processedData) ?? dataModel.resolveColumnNeedsValueOf(series, "yLowValue", processedData);
  const [d0, d1] = aggregationDomain(scale2, domainInput);
  return computeExtremesAggregationPartial([d0, d1], xValues, highValues, lowValues, {
    smallestKeyInterval: processedData.reduced?.smallestKeyInterval,
    targetRange,
    xNeedsValueOf,
    yNeedsValueOf,
    existingFilters
  });
}

// packages/ag-charts-enterprise/src/series/range-bar/rangeBarProperties.ts
var { AbstractBarSeriesProperties: AbstractBarSeriesProperties4, makeSeriesTooltip: makeSeriesTooltip12, DropShadow: DropShadow4, Label: Label9 } = module_support_exports;
var RangeBarSeriesLabel = class extends Label9 {
  constructor() {
    super(...arguments);
    this.placement = "inside";
    this.spacing = 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarSeriesLabel.prototype, "placement", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarSeriesLabel.prototype, "spacing", 2);
var RangeBarProperties = class extends AbstractBarSeriesProperties4 {
  constructor() {
    super(...arguments);
    this.fill = "#99CCFF";
    this.fillOpacity = 1;
    this.stroke = "#99CCFF";
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.cornerRadius = 0;
    this.shadow = new DropShadow4().set({ enabled: false });
    this.label = new RangeBarSeriesLabel();
    this.tooltip = makeSeriesTooltip12();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "xKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "yLowKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "yHighKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "xName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "yName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "yLowName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "yHighName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "styler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "itemStyler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "shadow", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RangeBarProperties.prototype, "tooltip", 2);

// packages/ag-charts-enterprise/src/series/range-bar/rangeBarSeries.ts
var {
  SeriesNodePickMode: SeriesNodePickMode8,
  valueProperty: valueProperty10,
  keyProperty: keyProperty7,
  checkCrisp: checkCrisp2,
  updateLabelNode: updateLabelNode4,
  SMALLEST_KEY_INTERVAL: SMALLEST_KEY_INTERVAL4,
  LARGEST_KEY_INTERVAL: LARGEST_KEY_INTERVAL2,
  diff: diff5,
  prepareBarAnimationFunctions: prepareBarAnimationFunctions2,
  midpointStartingBarPosition: midpointStartingBarPosition2,
  resetBarSelectionsFn: resetBarSelectionsFn2,
  resetBarSelectionsDirect: resetBarSelectionsDirect2,
  fixNumericExtent: fixNumericExtent6,
  seriesLabelFadeInAnimation: seriesLabelFadeInAnimation4,
  resetLabelFn: resetLabelFn3,
  animationValidation: animationValidation5,
  computeBarFocusBounds: computeBarFocusBounds5,
  visibleRangeIndices: visibleRangeIndices4,
  createDatumId: createDatumId11,
  Rect: Rect5,
  PointerEvents: PointerEvents6,
  motion: motion3,
  processedDataIsAnimatable: processedDataIsAnimatable5,
  getItemStyles: getItemStyles3,
  calculateSegments: calculateSegments4,
  toHighlightString: toHighlightString4,
  HighlightState: HighlightState6,
  AggregationManager: AggregationManager4,
  upsertNodeDatum: upsertNodeDatum4
} = module_support_exports;
var RangeBarSeriesNodeEvent = class extends module_support_exports.SeriesNodeEvent {
  constructor(type, nativeEvent, datum, series) {
    super(type, nativeEvent, datum, series);
    this.xKey = series.properties.xKey;
    this.yLowKey = series.properties.yLowKey;
    this.yHighKey = series.properties.yHighKey;
  }
};
var RangeBarSeries = class extends module_support_exports.AbstractBarSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      pickModes: [SeriesNodePickMode8.AXIS_ALIGNED, SeriesNodePickMode8.EXACT_SHAPE_MATCH],
      propertyKeys: {
        x: ["xKey"],
        y: ["yLowKey", "yHighKey"]
      },
      propertyNames: {
        x: ["xName"],
        y: ["yLowName", "yHighName", "yName"]
      },
      categoryKey: "xValue",
      datumSelectionGarbageCollection: false,
      animationResetFns: {
        datum: resetBarSelectionsFn2,
        label: resetLabelFn3
      }
    });
    this.properties = new RangeBarProperties();
    this.aggregationManager = new AggregationManager4();
    this.NodeEvent = RangeBarSeriesNodeEvent;
  }
  async processData(dataController) {
    const { xKey, yLowKey, yHighKey } = this.properties;
    const xScale = this.getCategoryAxis()?.scale;
    const yScale = this.getValueAxis()?.scale;
    const { isContinuousX, xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale });
    const extraProps = [];
    if (this.needsDataModelDiff() && this.processedData) {
      extraProps.push(diff5(this.id, this.processedData));
    }
    if (!this.ctx.animationManager.isSkipped()) {
      extraProps.push(animationValidation5());
    }
    const visibleProps = this.visible ? {} : { forceValue: 0 };
    const allowNullKey = this.properties.allowNullKeys ?? false;
    const { dataModel, processedData } = await this.requestDataModel(dataController, this.data, {
      props: [
        keyProperty7(xKey, xScaleType, { id: "xValue", allowNullKey }),
        valueProperty10(yLowKey, yScaleType, { id: `yLowValue`, invalidValue: null, ...visibleProps }),
        valueProperty10(yHighKey, yScaleType, { id: `yHighValue`, invalidValue: null, ...visibleProps }),
        ...isContinuousX ? [SMALLEST_KEY_INTERVAL4, LARGEST_KEY_INTERVAL2] : [],
        ...extraProps
      ],
      groupByKeys: false
    });
    this.smallestDataInterval = processedData.reduced?.smallestKeyInterval;
    this.largestDataInterval = processedData.reduced?.largestKeyInterval;
    this.aggregateData(dataModel, processedData);
    this.animationState.transition("updateData");
  }
  aggregateData(dataModel, processedData) {
    this.aggregationManager.markStale(processedData.input.count);
    if (processedData.type !== "ungrouped")
      return;
    if (processedDataIsAnimatable5(processedData))
      return;
    const xAxis = this.axes["x" /* X */];
    if (xAxis == null)
      return;
    const targetRange = this.estimateTargetRange();
    this.aggregationManager.aggregate({
      computePartial: (existingFilters) => aggregateRangeBarDataFromDataModelPartial(
        xAxis.scale.type,
        dataModel,
        processedData,
        this,
        targetRange,
        existingFilters
      ),
      computeFull: (existingFilters) => aggregateRangeBarDataFromDataModel(xAxis.scale.type, dataModel, processedData, this, existingFilters),
      targetRange
    });
    const filters = this.aggregationManager.filters;
    if (filters && filters.length > 0) {
      debugMetrics_exports.record(
        `${this.type}:aggregation`,
        filters.map((f) => f.maxRange)
      );
    }
  }
  estimateTargetRange() {
    const xAxis = this.axes["x" /* X */];
    if (xAxis?.scale == null)
      return 0;
    const [r0, r1] = xAxis.scale.range;
    return Math.abs(r1 - r0);
  }
  getSeriesDomain(direction) {
    const { processedData, dataModel } = this;
    if (!processedData || !dataModel)
      return { domain: [] };
    const {
      keys: [keys]
    } = processedData.domain;
    if (direction === this.getCategoryDirection()) {
      const keyDef = dataModel.resolveProcessedDataDefById(this, `xValue`);
      if (keyDef?.def.type === "key" && keyDef?.def.valueType === "category") {
        const sortMetadata = dataModel.getKeySortMetadata(this, "xValue", processedData);
        return { domain: keys, sortMetadata };
      }
      return { domain: this.padBandExtent(keys) };
    } else {
      const yExtent = this.domainForClippedRange(direction, ["yHighValue", "yLowValue"], "xValue");
      const fixedYExtent = findMinMax(yExtent);
      return { domain: fixNumericExtent6(fixedYExtent) };
    }
  }
  getSeriesRange(_direction, visibleRange) {
    return this.domainForVisibleRange("y" /* Y */, ["yHighValue", "yLowValue"], "xValue", visibleRange);
  }
  /**
   * Creates shared context for node datum creation/update operations.
   * This context is instantiated once and reused across all datum operations
   * to minimize memory allocations. Only caches values that are expensive to
   * compute - cheap property lookups use `this` directly.
   */
  createNodeDatumContext(xAxis, yAxis) {
    const { dataModel, processedData } = this;
    if (!dataModel || !processedData)
      return void 0;
    const rawData = processedData.dataSources?.get(this.id)?.data;
    if (rawData == null)
      return void 0;
    const xScale = xAxis.scale;
    const yScale = yAxis.scale;
    const barAlongX = this.getBarDirection() === "x" /* X */;
    const crisp = checkCrisp2(
      xAxis?.scale,
      xAxis?.visibleRange,
      this.smallestDataInterval,
      this.largestDataInterval
    );
    const [r0, r1] = xScale.range;
    const range3 = Math.abs(r1 - r0);
    this.aggregationManager.ensureLevelForRange(range3);
    const dataAggregationFilter = this.aggregationManager.getFilterForRange(range3);
    const animationEnabled = !this.ctx.animationManager.isSkipped();
    const canIncrementallyUpdate = this.contextNodeData?.nodeData != null && (processedData.changeDescription != null || !processedDataIsAnimatable5(processedData) || dataAggregationFilter != null);
    const { groupOffset, barOffset, barWidth } = this.getBarDimensions();
    return {
      xAxis,
      yAxis,
      rawData,
      xValues: dataModel.resolveKeysById(this, `xValue`, processedData),
      yLowValues: dataModel.resolveColumnById(this, `yLowValue`, processedData),
      yHighValues: dataModel.resolveColumnById(this, `yHighValue`, processedData),
      xScale,
      yScale,
      groupOffset,
      barOffset,
      barWidth,
      barAlongX,
      crisp,
      dataAggregationFilter,
      animationEnabled,
      xKey: this.properties.xKey,
      yLowKey: this.properties.yLowKey,
      yHighKey: this.properties.yHighKey,
      labelEnabled: this.properties.label.enabled,
      labelPlacement: this.properties.label.placement,
      labelPadding: (this.properties.label.spacing + (typeof this.properties.label.padding === "number" ? this.properties.label.padding : 0)) * (this.properties.label.placement === "outside" ? 1 : -1),
      canIncrementallyUpdate,
      nodes: canIncrementallyUpdate ? this.contextNodeData.nodeData : [],
      nodeIndex: 0
    };
  }
  /**
   * Validates and prepares state needed for node creation/update.
   * Returns undefined if datum should be skipped.
   */
  prepareNodeDatumState(ctx, scratch, datumIndex) {
    const datum = ctx.rawData[datumIndex];
    const xValue = ctx.xValues[datumIndex];
    if (xValue === void 0 && !this.properties.allowNullKeys)
      return void 0;
    const rawLowValue = ctx.yLowValues[datumIndex];
    const rawHighValue = ctx.yHighValues[datumIndex];
    if (!Number.isFinite(rawLowValue?.valueOf()) || !Number.isFinite(rawHighValue?.valueOf()))
      return void 0;
    const [yLowValue, yHighValue] = rawLowValue < rawHighValue ? [rawLowValue, rawHighValue] : [rawHighValue, rawLowValue];
    scratch.datum = datum;
    scratch.xValue = xValue;
    scratch.yLowValue = yLowValue;
    scratch.yHighValue = yHighValue;
    scratch.rawLowValue = rawLowValue;
    scratch.rawHighValue = rawHighValue;
    return scratch;
  }
  /**
   * Creates a minimal skeleton node - actual values set by updateNodeDatum.
   */
  createSkeletonNodeDatum(ctx, params) {
    const scratch = params.nodeDatumScratch;
    return {
      index: params.groupedDataIndex,
      series: this,
      datum: scratch.datum,
      datumIndex: params.datumIndex,
      xValue: scratch.xValue,
      yLowValue: 0,
      // Will be updated by updateNodeDatum
      yHighValue: 0,
      // Will be updated by updateNodeDatum
      yLowKey: ctx.yLowKey,
      yHighKey: ctx.yHighKey,
      xKey: ctx.xKey,
      x: 0,
      // Will be updated by updateNodeDatum
      y: 0,
      // Will be updated by updateNodeDatum
      width: 0,
      // Will be updated by updateNodeDatum
      height: 0,
      // Will be updated by updateNodeDatum
      midPoint: { x: 0, y: 0 },
      // Will be updated by updateNodeDatum
      crisp: params.crisp,
      labels: []
      // Will be updated by updateNodeDatum
    };
  }
  /**
   * Creates a new node: skeleton + update.
   */
  createNodeDatum(ctx, params, _itemId, strokeWidth) {
    const prepared = this.prepareNodeDatumState(ctx, params.nodeDatumScratch, params.datumIndex);
    if (!prepared)
      return void 0;
    const nodeData = this.createSkeletonNodeDatum(ctx, params);
    this.updateNodeDatum(ctx, nodeData, params, strokeWidth, prepared);
    return nodeData;
  }
  /**
   * Updates node properties in-place.
   * Shared by both create (skeleton + update) and incremental update paths.
   */
  updateNodeDatum(ctx, node, params, strokeWidth, prepared) {
    prepared ?? (prepared = this.prepareNodeDatumState(ctx, params.nodeDatumScratch, params.datumIndex));
    if (!prepared)
      return;
    const mutableNode = node;
    mutableNode.index = params.groupedDataIndex;
    mutableNode.datum = prepared.datum;
    mutableNode.datumIndex = params.datumIndex;
    mutableNode.xValue = prepared.xValue;
    mutableNode.yLowValue = prepared.rawLowValue;
    mutableNode.yHighValue = prepared.rawHighValue;
    mutableNode.crisp = params.crisp;
    const y = Math.round(ctx.yScale.convert(params.yHigh));
    const bottomY = Math.round(ctx.yScale.convert(params.yLow));
    const height2 = Math.max(strokeWidth, Math.abs(bottomY - y));
    const rect2 = {
      x: ctx.barAlongX ? Math.min(y, bottomY) : params.x,
      y: ctx.barAlongX ? params.x : Math.min(y, bottomY),
      width: ctx.barAlongX ? height2 : params.width,
      height: ctx.barAlongX ? params.width : height2
    };
    mutableNode.x = rect2.x;
    mutableNode.y = rect2.y;
    mutableNode.width = rect2.width;
    mutableNode.height = rect2.height;
    const mutableMidPoint = mutableNode.midPoint;
    mutableMidPoint.x = rect2.x + rect2.width / 2;
    mutableMidPoint.y = rect2.y + rect2.height / 2;
    const existingClipBBox = mutableNode.clipBBox;
    if (existingClipBBox) {
      existingClipBBox.x = rect2.x;
      existingClipBBox.y = rect2.y;
      existingClipBBox.width = rect2.width;
      existingClipBBox.height = rect2.height;
    }
    const labelParams = params.labelParamsScratch;
    labelParams.labels = mutableNode.labels;
    labelParams.datumIndex = params.datumIndex;
    labelParams.rectX = rect2.x;
    labelParams.rectY = rect2.y;
    labelParams.rectWidth = rect2.width;
    labelParams.rectHeight = rect2.height;
    labelParams.yLowValue = prepared.yLowValue;
    labelParams.yHighValue = prepared.yHighValue;
    labelParams.datum = prepared.datum;
    this.updateLabelData(ctx, labelParams);
  }
  /**
   * Creates node data using aggregation filters for large datasets.
   */
  createNodeDataWithAggregation(ctx, xPosition, nodeDatumParamsScratch, itemId, strokeWidth, dataAggregationFilter) {
    const { maxRange, indexData, midpointIndices } = dataAggregationFilter;
    const [start2, end3] = visibleRangeIndices4(1, maxRange, ctx.xAxis.range, (index) => {
      const aggIndex = index * AGGREGATION_SPAN;
      const xMaxIndex = indexData[aggIndex + AGGREGATION_INDEX_X_MAX];
      const midDatumIndex = midpointIndices[index];
      if (midDatumIndex === -1)
        return;
      return [xPosition(midDatumIndex), xPosition(xMaxIndex) + ctx.barWidth];
    });
    for (let i = start2; i < end3; i += 1) {
      const aggIndex = i * AGGREGATION_SPAN;
      const xMinIndex = indexData[aggIndex + AGGREGATION_INDEX_X_MIN];
      const xMaxIndex = indexData[aggIndex + AGGREGATION_INDEX_X_MAX];
      const yMinIndex = indexData[aggIndex + AGGREGATION_INDEX_Y_MIN];
      const yMaxIndex = indexData[aggIndex + AGGREGATION_INDEX_Y_MAX];
      const midDatumIndex = midpointIndices[i];
      if (midDatumIndex === -1)
        continue;
      const xValue = ctx.xValues[midDatumIndex];
      if (xValue === void 0 && !this.properties.allowNullKeys)
        continue;
      nodeDatumParamsScratch.datumIndex = midDatumIndex;
      nodeDatumParamsScratch.groupedDataIndex = 0;
      nodeDatumParamsScratch.x = xPosition(midDatumIndex);
      nodeDatumParamsScratch.width = Math.abs(xPosition(xMinIndex) - xPosition(xMaxIndex)) + ctx.barWidth;
      nodeDatumParamsScratch.yLow = ctx.yLowValues[yMinIndex];
      nodeDatumParamsScratch.yHigh = ctx.yHighValues[yMaxIndex];
      nodeDatumParamsScratch.crisp = false;
      upsertNodeDatum4(
        ctx,
        nodeDatumParamsScratch,
        (c, p) => this.createNodeDatum(c, p, itemId, strokeWidth),
        (c, n, p) => this.updateNodeDatum(c, n, p, strokeWidth)
      );
    }
  }
  /**
   * Creates node data for simple (ungrouped) data processing.
   */
  createNodeDataSimple(ctx, xPosition, nodeDatumParamsScratch, itemId, strokeWidth, processedData) {
    const invalidData = processedData.invalidData?.get(this.id);
    let [start2, end3] = this.visibleRangeIndices("xValue", ctx.xAxis.range);
    if (processedData.input.count < 1e3) {
      start2 = 0;
      end3 = processedData.input.count;
    }
    for (let datumIndex = start2; datumIndex < end3; datumIndex += 1) {
      if (invalidData?.[datumIndex] === true)
        continue;
      nodeDatumParamsScratch.datumIndex = datumIndex;
      nodeDatumParamsScratch.groupedDataIndex = 0;
      nodeDatumParamsScratch.x = xPosition(datumIndex);
      nodeDatumParamsScratch.width = ctx.barWidth;
      nodeDatumParamsScratch.yLow = ctx.yLowValues[datumIndex];
      nodeDatumParamsScratch.yHigh = ctx.yHighValues[datumIndex];
      nodeDatumParamsScratch.crisp = ctx.crisp;
      upsertNodeDatum4(
        ctx,
        nodeDatumParamsScratch,
        (c, p) => this.createNodeDatum(c, p, itemId, strokeWidth),
        (c, n, p) => this.updateNodeDatum(c, n, p, strokeWidth)
      );
    }
  }
  /**
   * Creates node data for grouped data processing.
   */
  createNodeDataGrouped(ctx, xPosition, nodeDatumParamsScratch, itemId, strokeWidth) {
    const processedData = this.processedData;
    for (const { datumIndex, groupIndex: groupDataIndex } of this.dataModel.forEachGroupDatum(
      this,
      processedData
    )) {
      nodeDatumParamsScratch.datumIndex = datumIndex;
      nodeDatumParamsScratch.groupedDataIndex = groupDataIndex;
      nodeDatumParamsScratch.x = xPosition(datumIndex);
      nodeDatumParamsScratch.width = ctx.barWidth;
      nodeDatumParamsScratch.yLow = ctx.yLowValues[datumIndex];
      nodeDatumParamsScratch.yHigh = ctx.yHighValues[datumIndex];
      nodeDatumParamsScratch.crisp = ctx.crisp;
      upsertNodeDatum4(
        ctx,
        nodeDatumParamsScratch,
        (c, p) => this.createNodeDatum(c, p, itemId, strokeWidth),
        (c, n, p) => this.updateNodeDatum(c, n, p, strokeWidth)
      );
    }
  }
  populateNodeData(ctx) {
    const { processedData } = this;
    if (!processedData)
      return;
    const { yLowKey, yHighKey, strokeWidth } = this.properties;
    const itemId = `${yLowKey}-${yHighKey}`;
    const xPosition = (datumIndex) => {
      const x = ctx.xScale.convert(ctx.xValues[datumIndex]);
      if (!Number.isFinite(x))
        return Number.NaN;
      return Math.round(x) + ctx.groupOffset + ctx.barOffset;
    };
    const nodeDatumParamsScratch = {
      nodeDatumScratch: {
        datum: void 0,
        xValue: void 0,
        yLowValue: 0,
        yHighValue: 0,
        rawLowValue: void 0,
        rawHighValue: void 0
      },
      labelParamsScratch: {
        labels: [],
        datumIndex: 0,
        rectX: 0,
        rectY: 0,
        rectWidth: 0,
        rectHeight: 0,
        yLowValue: 0,
        yHighValue: 0,
        datum: void 0
      },
      datumIndex: 0,
      groupedDataIndex: 0,
      x: 0,
      width: 0,
      yLow: 0,
      yHigh: 0,
      crisp: false
    };
    if (ctx.dataAggregationFilter != null) {
      this.createNodeDataWithAggregation(
        ctx,
        xPosition,
        nodeDatumParamsScratch,
        itemId,
        strokeWidth,
        ctx.dataAggregationFilter
      );
    } else if (processedData.type === "ungrouped") {
      this.createNodeDataSimple(ctx, xPosition, nodeDatumParamsScratch, itemId, strokeWidth, processedData);
    } else {
      this.createNodeDataGrouped(ctx, xPosition, nodeDatumParamsScratch, itemId, strokeWidth);
    }
  }
  finalizeNodeData(ctx) {
    if (ctx.canIncrementallyUpdate && ctx.nodeIndex < ctx.nodes.length) {
      ctx.nodes.length = ctx.nodeIndex;
    }
  }
  initializeResult(ctx) {
    const { yLowKey, yHighKey } = this.properties;
    const itemId = `${yLowKey}-${yHighKey}`;
    const xAxis = this.getCategoryAxis();
    const yAxis = this.getValueAxis();
    const segments = xAxis && yAxis && this.chart?.seriesRect ? calculateSegments4(this.properties.segmentation, xAxis, yAxis, this.chart.seriesRect, this.ctx.scene) : void 0;
    return {
      itemId,
      nodeData: ctx.nodes,
      labelData: [],
      scales: this.calculateScaling(),
      groupScale: this.getScaling(this.ctx.seriesStateManager.getGroupScale(this)),
      visible: this.visible,
      styles: getItemStyles3(this.getItemStyle.bind(this)),
      segments
    };
  }
  assembleResult(ctx, result) {
    for (const node of ctx.nodes) {
      result.labelData.push(...node.labels);
    }
    return result;
  }
  /**
   * Updates existing label data in place or creates new labels if needed.
   * This avoids array allocations during incremental updates.
   * Uses positional params (no destructuring) for performance in hot path.
   */
  updateLabelData(ctx, params) {
    const labels = params.labels;
    if (!ctx.labelEnabled) {
      if (labels.length > 0) {
        labels.length = 0;
      }
      return;
    }
    const { xKey, yLowKey, yHighKey, xName, yLowName, yHighName, yName, legendItemName, label } = this.properties;
    const barAlongX = ctx.barAlongX;
    const placement = ctx.labelPlacement;
    const labelPadding = ctx.labelPadding;
    const rectX = params.rectX;
    const rectY = params.rectY;
    const rectWidth = params.rectWidth;
    const rectHeight = params.rectHeight;
    const yLowX = rectX + (barAlongX ? -labelPadding : rectWidth / 2);
    const yLowY = rectY + (barAlongX ? rectHeight / 2 : rectHeight + labelPadding);
    let yLowTextAlign;
    if (placement === "outside") {
      yLowTextAlign = barAlongX ? "right" : "center";
    } else {
      yLowTextAlign = barAlongX ? "left" : "center";
    }
    let yLowTextBaseline;
    if (placement === "outside") {
      yLowTextBaseline = barAlongX ? "middle" : "top";
    } else {
      yLowTextBaseline = barAlongX ? "middle" : "bottom";
    }
    const yHighX = rectX + (barAlongX ? rectWidth + labelPadding : rectWidth / 2);
    const yHighY = rectY + (barAlongX ? rectHeight / 2 : -labelPadding);
    let yHighTextAlign;
    if (placement === "outside") {
      yHighTextAlign = barAlongX ? "left" : "center";
    } else {
      yHighTextAlign = barAlongX ? "right" : "center";
    }
    let yHighTextBaseline;
    if (placement === "outside") {
      yHighTextBaseline = barAlongX ? "middle" : "bottom";
    } else {
      yHighTextBaseline = barAlongX ? "middle" : "top";
    }
    const datum = params.datum;
    const yLowValue = params.yLowValue;
    const yHighValue = params.yHighValue;
    const datumIndex = params.datumIndex;
    const labelTextParams = { datum, xKey, yLowKey, yHighKey, xName, yLowName, yHighName, yName, legendItemName };
    const yDomain = this.getSeriesDomain("y" /* Y */).domain;
    const yLowText = this.getLabelText(
      yLowValue,
      datum,
      yLowKey,
      "y",
      yDomain,
      label,
      { itemType: "low", value: yLowValue, ...labelTextParams }
    );
    const yHighText = this.getLabelText(
      yHighValue,
      datum,
      yHighKey,
      "y",
      yDomain,
      label,
      { itemType: "high", value: yHighValue, ...labelTextParams }
    );
    if (labels.length > 0 && labels[0].itemType === "low") {
      const yLowLabel = labels[0];
      yLowLabel.datumIndex = datumIndex;
      yLowLabel.x = yLowX;
      yLowLabel.y = yLowY;
      yLowLabel.textAlign = yLowTextAlign;
      yLowLabel.textBaseline = yLowTextBaseline;
      yLowLabel.text = yLowText;
      yLowLabel.datum = datum;
    } else {
      labels[0] = {
        datumIndex,
        x: yLowX,
        y: yLowY,
        textAlign: yLowTextAlign,
        textBaseline: yLowTextBaseline,
        text: yLowText,
        itemType: "low",
        datum,
        series: this
      };
    }
    if (labels.length > 1 && labels[1].itemType === "high") {
      const yHighLabel = labels[1];
      yHighLabel.datumIndex = datumIndex;
      yHighLabel.x = yHighX;
      yHighLabel.y = yHighY;
      yHighLabel.textAlign = yHighTextAlign;
      yHighLabel.textBaseline = yHighTextBaseline;
      yHighLabel.text = yHighText;
      yHighLabel.datum = datum;
    } else {
      labels[1] = {
        datumIndex,
        x: yHighX,
        y: yHighY,
        textAlign: yHighTextAlign,
        textBaseline: yHighTextBaseline,
        text: yHighText,
        itemType: "high",
        datum,
        series: this
      };
    }
    labels.length = 2;
  }
  nodeFactory() {
    return new Rect5();
  }
  getStyle(ignoreStylerCallback, highlightState) {
    const {
      cornerRadius,
      fill,
      fillOpacity,
      lineDash,
      lineDashOffset,
      stroke: stroke3,
      strokeOpacity,
      strokeWidth,
      styler
    } = this.properties;
    let stylerResult = {};
    if (!ignoreStylerCallback && styler) {
      const stylerParams = this.makeStylerParams(highlightState);
      stylerResult = this.ctx.optionsGraphService.resolvePartial(
        ["series", `${this.declarationOrder}`],
        this.cachedCallWithContext(styler, stylerParams) ?? {},
        { pick: false }
      ) ?? {};
    }
    return {
      cornerRadius: stylerResult.cornerRadius ?? cornerRadius,
      fill: stylerResult.fill ?? fill,
      fillOpacity: stylerResult.fillOpacity ?? fillOpacity,
      lineDash: stylerResult.lineDash ?? lineDash,
      lineDashOffset: stylerResult.lineDashOffset ?? lineDashOffset,
      opacity: 1,
      stroke: stylerResult.stroke ?? stroke3,
      strokeOpacity: stylerResult.strokeOpacity ?? strokeOpacity,
      strokeWidth: stylerResult.strokeWidth ?? strokeWidth
    };
  }
  makeStylerParams(highlightStateEnum) {
    const { id: seriesId } = this;
    const {
      cornerRadius,
      fill,
      fillOpacity,
      lineDash,
      lineDashOffset,
      stroke: stroke3,
      strokeOpacity,
      strokeWidth,
      xKey,
      yLowKey,
      yHighKey
    } = this.properties;
    const highlightState = toHighlightString4(highlightStateEnum ?? HighlightState6.None);
    return {
      cornerRadius,
      fill,
      fillOpacity,
      highlightState,
      lineDash,
      lineDashOffset,
      seriesId,
      stroke: stroke3,
      strokeOpacity,
      strokeWidth,
      xKey,
      yLowKey,
      yHighKey
    };
  }
  updateDatumSelection(opts) {
    const { nodeData, datumSelection } = opts;
    const data = nodeData ?? [];
    if (!processedDataIsAnimatable5(this.processedData)) {
      return datumSelection.update(data);
    }
    return datumSelection.update(data, void 0, (datum) => this.getDatumId(datum));
  }
  getItemStyle(datumIndex, isHighlight, highlightState) {
    const { properties, dataModel, processedData } = this;
    const { itemStyler } = properties;
    const highlightStyle = this.getHighlightStyle(isHighlight, datumIndex, highlightState);
    let style2 = mergeDefaults(highlightStyle, this.getStyle(datumIndex === void 0, highlightState));
    if (itemStyler && dataModel != null && processedData != null && datumIndex != null) {
      const xValue = dataModel.resolveKeysById(this, `xValue`, processedData)[datumIndex];
      const overrides = this.cachedDatumCallback(
        createDatumId11(this.getDatumId({ xValue }), isHighlight ? "highlight" : "node"),
        () => {
          const params = this.makeItemStylerParams(datumIndex, isHighlight, style2);
          return this.callWithContext(itemStyler, params);
        }
      );
      if (overrides) {
        style2 = mergeDefaults(overrides, style2);
      }
    }
    return style2;
  }
  makeItemStylerParams(datumIndex, isHighlight, style2) {
    const { id: seriesId, properties, processedData } = this;
    const { xKey, yHighKey, yLowKey } = properties;
    const datum = processedData.dataSources.get(seriesId)?.data[datumIndex];
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const highlightStateString = this.getHighlightStateString(activeHighlight, isHighlight, datumIndex);
    const fill = this.filterItemStylerFillParams(style2.fill) ?? style2.fill;
    return {
      seriesId,
      datum,
      xKey,
      yHighKey,
      yLowKey,
      highlightState: highlightStateString,
      ...style2,
      fill
    };
  }
  updateDatumStyles(opts) {
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    opts.datumSelection.each((node, datum) => {
      if (!opts.datumSelection.isGarbage(node)) {
        const highlightState = this.getHighlightState(highlightedDatum, opts.isHighlight, datum.datumIndex);
        datum.style = this.getItemStyle(datum.datumIndex, opts.isHighlight, highlightState);
      }
    });
  }
  updateDatumNodes({
    datumSelection,
    isHighlight
  }) {
    const { contextNodeData } = this;
    if (!contextNodeData) {
      return;
    }
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    const categoryAlongX = this.getCategoryDirection() === "x" /* X */;
    const fillBBox = this.getShapeFillBBox();
    const series = this;
    datumSelection.each(function updateRangeBarNode(rect2, datum) {
      const style2 = datum.style ?? contextNodeData.styles[series.getHighlightState(highlightedDatum, isHighlight, datum.datumIndex)];
      rect2.setStyleProperties(style2, fillBBox);
      rect2.setStaticProperties(
        "overlay",
        style2.cornerRadius ?? 0,
        style2.cornerRadius ?? 0,
        style2.cornerRadius ?? 0,
        style2.cornerRadius ?? 0,
        categoryAlongX ? datum.width > 0 : datum.height > 0,
        datum.crisp,
        void 0
      );
    });
  }
  updateLabelSelection(opts) {
    const labelData = this.properties.label.enabled ? opts.labelData : [];
    return opts.labelSelection.update(labelData, (text2) => {
      text2.pointerEvents = PointerEvents6.None;
    });
  }
  updateLabelNodes(opts) {
    const { isHighlight = false } = opts;
    const params = {
      xKey: this.properties.xKey,
      xName: this.properties.xName ?? this.properties.xKey,
      yName: this.properties.yName,
      yLowKey: this.properties.yLowKey,
      yLowName: this.properties.yLowName ?? this.properties.yLowKey,
      yHighKey: this.properties.yHighKey,
      yHighName: this.properties.yHighName ?? this.properties.yHighKey,
      legendItemName: this.properties.legendItemName
    };
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    opts.labelSelection.each((textNode, datum) => {
      textNode.fillOpacity = this.getHighlightStyle(isHighlight, datum?.datumIndex).opacity ?? 1;
      updateLabelNode4(this, textNode, params, this.properties.label, datum, isHighlight, activeHighlight);
    });
  }
  getHighlightLabelData(labelData, highlightedItem) {
    if (highlightedItem.labels?.length) {
      return highlightedItem.labels;
    }
    return super.getHighlightLabelData(labelData, highlightedItem);
  }
  getTooltipContent(datumIndex) {
    const { id: seriesId, dataModel, processedData, properties } = this;
    const { xKey, xName, yName, yLowKey, yHighKey, yLowName, yHighName, tooltip, legendItemName } = properties;
    const xAxis = this.getCategoryAxis();
    const yAxis = this.getValueAxis();
    if (!dataModel || !processedData || !xAxis || !yAxis)
      return;
    const datum = processedData.dataSources.get(this.id)?.data[datumIndex];
    const xValue = dataModel.resolveKeysById(this, `xValue`, processedData)[datumIndex];
    const yHighValue = dataModel.resolveColumnById(this, `yHighValue`, processedData)[datumIndex];
    const yLowValue = dataModel.resolveColumnById(this, `yLowValue`, processedData)[datumIndex];
    const allowNullKeys = this.properties.allowNullKeys ?? false;
    if (xValue === void 0 && !allowNullKeys)
      return;
    const format = this.getItemStyle(datumIndex, false);
    const value = `${this.getAxisValueText(yAxis, "tooltip", yLowValue, datum, yLowKey, legendItemName)} - ${this.getAxisValueText(yAxis, "tooltip", yHighValue, datum, yHighKey, legendItemName)}`;
    return this.formatTooltipWithContext(
      tooltip,
      {
        heading: this.getAxisValueText(xAxis, "tooltip", xValue, datum, xKey, legendItemName),
        symbol: this.legendItemSymbol(),
        data: [
          {
            label: yName,
            fallbackLabel: `${yLowName ?? yLowKey} - ${yHighName ?? yHighKey}`,
            value,
            missing: module_support_exports.isTooltipValueMissing(yHighValue) && module_support_exports.isTooltipValueMissing(yLowValue)
          }
        ]
      },
      {
        seriesId,
        datum,
        title: yName,
        xKey,
        xName,
        yName,
        yLowKey,
        yHighKey,
        yLowName,
        yHighName,
        legendItemName,
        ...format
      }
    );
  }
  legendItemSymbol() {
    const { fill, stroke: stroke3, strokeWidth, fillOpacity, strokeOpacity, lineDash, lineDashOffset } = this.getStyle(
      false,
      HighlightState6.None
    );
    return {
      marker: {
        fill,
        stroke: stroke3,
        fillOpacity,
        strokeOpacity,
        strokeWidth,
        lineDash,
        lineDashOffset
      }
    };
  }
  getLegendData(legendType) {
    if (legendType !== "category") {
      return [];
    }
    const { id: seriesId, visible } = this;
    const { yName, yLowName, yHighName, yLowKey, yHighKey, legendItemName, showInLegend } = this.properties;
    const legendItemText = legendItemName ?? yName ?? `${yLowName ?? yLowKey} - ${yHighName ?? yHighKey}`;
    const itemId = `${yLowKey}-${yHighKey}`;
    return [
      {
        legendType: "category",
        id: seriesId,
        itemId,
        seriesId,
        enabled: visible,
        label: { text: `${legendItemText}` },
        symbol: this.legendItemSymbol(),
        legendItemName,
        hideInLegend: !showInLegend
      }
    ];
  }
  resetDatumAnimation(data) {
    resetBarSelectionsDirect2([data.datumSelection]);
  }
  animateEmptyUpdateReady({ datumSelection, labelSelection }) {
    const fns = prepareBarAnimationFunctions2(midpointStartingBarPosition2(this.isVertical(), "normal"), "unknown");
    motion3.fromToMotion(this.id, "datums", this.ctx.animationManager, [datumSelection], fns);
    seriesLabelFadeInAnimation4(
      this,
      "labels",
      this.ctx.animationManager,
      labelSelection,
      this.highlightLabelSelection
    );
  }
  animateWaitingUpdateReady(data) {
    const { datumSelection: datumSelections, labelSelection, contextData, previousContextData } = data;
    const dataDiff = module_support_exports.calculateDataDiff(
      this.id,
      datumSelections,
      this.getDatumId.bind(this),
      contextData,
      previousContextData,
      this.processedData,
      this.processedDataUpdated
    );
    this.ctx.animationManager.stopByAnimationGroupId(this.id);
    const mode = previousContextData == null ? "fade" : "normal";
    const fns = prepareBarAnimationFunctions2(midpointStartingBarPosition2(this.isVertical(), mode), "added");
    motion3.fromToMotion(
      this.id,
      "datums",
      this.ctx.animationManager,
      [datumSelections],
      fns,
      (_, datum) => this.getDatumId(datum),
      dataDiff
    );
    if (dataDiff?.changed || !areScalingEqual(contextData.groupScale, previousContextData?.groupScale)) {
      seriesLabelFadeInAnimation4(
        this,
        "labels",
        this.ctx.animationManager,
        labelSelection,
        this.highlightLabelSelection
      );
    }
  }
  getDatumId(datum) {
    return `${datum.xValue}`;
  }
  isLabelEnabled() {
    return this.properties.label.enabled;
  }
  computeFocusBounds({ datumIndex }) {
    return computeBarFocusBounds5(this, this.contextNodeData?.nodeData[datumIndex]);
  }
  hasItemStylers() {
    return this.properties.styler != null || this.properties.itemStyler != null || this.properties.label.itemStyler != null;
  }
};
RangeBarSeries.className = "RangeBarSeries";
RangeBarSeries.type = "range-bar";

// packages/ag-charts-enterprise/src/series/range-bar/rangeBarSeriesOptionsDef.ts
var { rangeBarSeriesThemeableOptionsDef: rangeBarSeriesThemeableOptionsDef2 } = module_support_exports;
var rangeBarSeriesOptionsDef = {
  ...commonSeriesOptionsDefs,
  ...rangeBarSeriesThemeableOptionsDef2,
  type: required(constant("range-bar")),
  xKey: required(string),
  yLowKey: required(string),
  yHighKey: required(string),
  xKeyAxis: string,
  yKeyAxis: string,
  xName: string,
  yName: string,
  yLowName: string,
  yHighName: string,
  legendItemName: string,
  segmentation: shapeSegmentation,
  width: positiveNumberNonZero,
  widthRatio: ratio
};
rangeBarSeriesOptionsDef.pickOutsideVisibleMinorAxis = undocumented(boolean);
rangeBarSeriesOptionsDef.focusPriority = undocumented(number);

// packages/ag-charts-enterprise/src/series/range-bar/rangeBarThemes.ts
var RANGE_BAR_SERIES_THEME = {
  series: {
    direction: "vertical",
    fill: {
      $applySwitch: [
        { $path: "type" },
        { $palette: "fill" },
        ["gradient", FILL_GRADIENT_LINEAR_DEFAULTS],
        ["image", FILL_IMAGE_DEFAULTS],
        ["pattern", FILL_PATTERN_DEFAULTS]
      ]
    },
    stroke: { $palette: "stroke" },
    strokeWidth: { $isUserOption: ["./stroke", 2, 0] },
    label: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: false,
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      fontWeight: { $ref: "fontWeight" },
      color: { $ref: "chartBackgroundColor" },
      placement: "inside",
      padding: { $isUserOption: ["./spacing", 0, 6] }
      // compatibility with old `padding` property (now named `spacing`).
    },
    highlight: MULTI_SERIES_HIGHLIGHT_STYLE,
    segmentation: SEGMENTATION_DEFAULTS
  },
  axes: {
    ["number" /* NUMBER */]: {
      crosshair: { enabled: true }
    }
  }
};

// packages/ag-charts-enterprise/src/series/range-bar/rangeBarModule.ts
var { predictCartesianNonPrimitiveAxis: predictCartesianNonPrimitiveAxis4 } = module_support_exports;
var RangeBarSeriesModule = {
  type: "series",
  name: "range-bar",
  chartType: "cartesian",
  enterprise: true,
  groupable: true,
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: rangeBarSeriesOptionsDef,
  matchingKeys: ["xKey", "yLowKey", "yHighKey", "normalizedTo"],
  predictAxis: predictCartesianNonPrimitiveAxis4,
  defaultAxes: DIRECTION_SWAP_AXES,
  axisKeys: { ["x" /* X */]: "xKeyAxis", ["y" /* Y */]: "yKeyAxis" },
  axisKeysFlipped: { ["x" /* X */]: "yKeyAxis", ["y" /* Y */]: "xKeyAxis" },
  themeTemplate: RANGE_BAR_SERIES_THEME,
  create: (ctx) => new RangeBarSeries(ctx)
};

// packages/ag-charts-enterprise/src/series/waterfall/waterfallSeriesProperties.ts
var { AbstractBarSeriesProperties: AbstractBarSeriesProperties5, makeSeriesTooltip: makeSeriesTooltip13, DropShadow: DropShadow5, Label: Label10 } = module_support_exports;
var WaterfallSeriesTotal = class extends BaseProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesTotal.prototype, "totalType", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesTotal.prototype, "index", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesTotal.prototype, "axisLabel", 2);
var WaterfallSeriesItemTooltip = class extends BaseProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesItemTooltip.prototype, "renderer", 2);
var WaterfallSeriesLabel = class extends Label10 {
  constructor() {
    super(...arguments);
    this.placement = "outside-end";
    this.spacing = 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesLabel.prototype, "placement", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesLabel.prototype, "spacing", 2);
var WaterfallSeriesItem = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.fill = "#c16068";
    this.stroke = "#c16068";
    this.fillOpacity = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.strokeWidth = 1;
    this.cornerRadius = 0;
    this.shadow = new DropShadow5().set({ enabled: false });
    this.label = new WaterfallSeriesLabel();
    this.tooltip = new WaterfallSeriesItemTooltip();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesItem.prototype, "name", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesItem.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesItem.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesItem.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesItem.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesItem.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesItem.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesItem.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesItem.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesItem.prototype, "itemStyler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesItem.prototype, "shadow", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesItem.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesItem.prototype, "tooltip", 2);
var WaterfallSeriesConnectorLine = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = true;
    this.stroke = "black";
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.strokeWidth = 2;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesConnectorLine.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesConnectorLine.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesConnectorLine.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesConnectorLine.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesConnectorLine.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesConnectorLine.prototype, "strokeWidth", 2);
var WaterfallSeriesItems = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.positive = new WaterfallSeriesItem();
    this.negative = new WaterfallSeriesItem();
    this.total = new WaterfallSeriesItem();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesItems.prototype, "positive", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesItems.prototype, "negative", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesItems.prototype, "total", 2);
var WaterfallSeriesProperties = class extends AbstractBarSeriesProperties5 {
  constructor() {
    super(...arguments);
    this.item = new WaterfallSeriesItems();
    this.totals = new PropertiesArray(WaterfallSeriesTotal);
    this.line = new WaterfallSeriesConnectorLine();
    this.tooltip = makeSeriesTooltip13();
  }
  getStyle(itemType) {
    const { fillOpacity, strokeWidth, strokeOpacity, fill, stroke: stroke3, lineDash, lineDashOffset, cornerRadius } = this.item[itemType === "subtotal" ? "total" : itemType];
    return {
      fill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset,
      cornerRadius,
      opacity: 1
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesProperties.prototype, "xKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesProperties.prototype, "yKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesProperties.prototype, "xName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesProperties.prototype, "yName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesProperties.prototype, "item", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesProperties.prototype, "totals", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesProperties.prototype, "line", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], WaterfallSeriesProperties.prototype, "tooltip", 2);

// packages/ag-charts-enterprise/src/series/waterfall/waterfallSeries.ts
var {
  adjustLabelPlacement: adjustLabelPlacement2,
  SeriesNodePickMode: SeriesNodePickMode9,
  fixNumericExtent: fixNumericExtent7,
  valueProperty: valueProperty11,
  keyProperty: keyProperty8,
  accumulativeValueProperty: accumulativeValueProperty2,
  trailingAccumulatedValueProperty: trailingAccumulatedValueProperty2,
  createDatumId: createDatumId12,
  checkCrisp: checkCrisp3,
  updateLabelNode: updateLabelNode5,
  prepareBarAnimationFunctions: prepareBarAnimationFunctions3,
  collapsedStartingBarPosition: collapsedStartingBarPosition2,
  resetBarSelectionsDirect: resetBarSelectionsDirect3,
  resetBarSelectionsFn: resetBarSelectionsFn3,
  seriesLabelFadeInAnimation: seriesLabelFadeInAnimation5,
  resetLabelFn: resetLabelFn4,
  animationValidation: animationValidation6,
  DEFAULT_CARTESIAN_DIRECTION_KEYS: DEFAULT_CARTESIAN_DIRECTION_KEYS3,
  DEFAULT_CARTESIAN_DIRECTION_NAMES: DEFAULT_CARTESIAN_DIRECTION_NAMES3,
  computeBarFocusBounds: computeBarFocusBounds6,
  Rect: Rect6,
  motion: motion4,
  getItemStylesPerItemId: getItemStylesPerItemId3,
  DataSet: DataSet2,
  processedDataIsAnimatable: processedDataIsAnimatable6,
  upsertNodeDatum: upsertNodeDatum5
} = module_support_exports;
var WaterfallSeries = class extends module_support_exports.AbstractBarSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      propertyKeys: DEFAULT_CARTESIAN_DIRECTION_KEYS3,
      propertyNames: DEFAULT_CARTESIAN_DIRECTION_NAMES3,
      categoryKey: void 0,
      pickModes: [SeriesNodePickMode9.NEAREST_NODE, SeriesNodePickMode9.EXACT_SHAPE_MATCH],
      pathsPerSeries: ["connector"],
      pathsZIndexSubOrderOffset: [-1, -1],
      animationResetFns: {
        datum: resetBarSelectionsFn3,
        label: resetLabelFn4
      }
    });
    this.properties = new WaterfallSeriesProperties();
    this.seriesItemTypes = /* @__PURE__ */ new Set(["positive", "negative", "total"]);
  }
  async processData(dataController) {
    const { xKey, yKey, totals } = this.properties;
    const { data } = this;
    if (!this.visible)
      return;
    const positiveNumber2 = (v) => isContinuous(v) && Number(v) >= 0;
    const negativeNumber = (v) => isContinuous(v) && Number(v) >= 0;
    const totalTypeValue = (v) => v === "total" || v === "subtotal";
    const propertyDefinition = { missingValue: void 0, invalidValue: void 0 };
    const dataWithTotals = [];
    const totalsMap = totals.reduce((result, total) => {
      const totalsAtIndex = result.get(total.index);
      if (totalsAtIndex) {
        totalsAtIndex.push(total);
      } else {
        result.set(total.index, [total]);
      }
      return result;
    }, /* @__PURE__ */ new Map());
    for (const [i, datum] of data?.data.entries() ?? []) {
      dataWithTotals.push(datum);
      const totalsAtIndex = totalsMap.get(i);
      if (totalsAtIndex) {
        for (const total of totalsAtIndex) {
          dataWithTotals.push({ ...total.toJson(), [xKey]: total.axisLabel });
        }
      }
    }
    const extraProps = [];
    if (!this.ctx.animationManager.isSkipped()) {
      extraProps.push(animationValidation6());
    }
    const xScale = this.getCategoryAxis()?.scale;
    const yScale = this.getValueAxis()?.scale;
    const { isContinuousX, xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale });
    const allowNullKey = this.properties.allowNullKeys ?? false;
    const { processedData } = await this.requestDataModel(
      dataController,
      DataSet2.wrap(dataWithTotals),
      {
        props: [
          keyProperty8(xKey, xScaleType, { id: `xValue`, allowNullKey }),
          accumulativeValueProperty2(yKey, yScaleType, {
            ...propertyDefinition,
            id: `yCurrent`
          }),
          accumulativeValueProperty2(yKey, yScaleType, {
            ...propertyDefinition,
            missingValue: 0,
            id: `yCurrentTotal`
          }),
          accumulativeValueProperty2(yKey, yScaleType, {
            ...propertyDefinition,
            id: `yCurrentPositive`,
            validation: positiveNumber2
          }),
          accumulativeValueProperty2(yKey, yScaleType, {
            ...propertyDefinition,
            id: `yCurrentNegative`,
            validation: negativeNumber
          }),
          trailingAccumulatedValueProperty2(yKey, yScaleType, {
            ...propertyDefinition,
            id: `yPrevious`
          }),
          valueProperty11(yKey, yScaleType, { id: `yRaw` }),
          // Raw value pass-through.
          valueProperty11("totalType", "category", {
            id: `totalTypeValue`,
            missingValue: void 0,
            validation: totalTypeValue
          }),
          ...isContinuousX ? [module_support_exports.SMALLEST_KEY_INTERVAL, module_support_exports.LARGEST_KEY_INTERVAL] : [],
          ...extraProps
        ]
      }
    );
    this.smallestDataInterval = processedData.reduced?.smallestKeyInterval;
    this.largestDataInterval = processedData.reduced?.largestKeyInterval;
    this.updateSeriesItemTypes();
    this.animationState.transition("updateData");
  }
  getSeriesDomain(direction) {
    const { processedData, dataModel } = this;
    if (!processedData || !dataModel)
      return { domain: [] };
    const {
      keys: [keys],
      values
    } = processedData.domain;
    if (direction === this.getCategoryDirection()) {
      const keyDef = dataModel.resolveProcessedDataDefById(this, `xValue`);
      if (keyDef?.def.type === "key" && keyDef?.def.valueType === "category") {
        const sortMetadata = dataModel.getKeySortMetadata(this, "xValue", processedData);
        return { domain: keys, sortMetadata };
      }
      const isDirectionY = direction === "y" /* Y */;
      const isReversed = this.getCategoryAxis().isReversed();
      return { domain: this.padBandExtent(keys, isReversed !== isDirectionY) };
    } else {
      const yCurrIndex = dataModel.resolveProcessedDataIndexById(this, "yCurrent");
      const yExtent = values[yCurrIndex];
      const fixedYExtent = [Math.min(0, yExtent[0]), Math.max(0, yExtent[1])];
      return { domain: fixNumericExtent7(fixedYExtent) };
    }
  }
  getSeriesRange() {
    return [Number.NaN, Number.NaN];
  }
  populateNodeData(ctx) {
    let trailingSubtotal = 0;
    const paramsScratch = {
      datumIndex: 0,
      datum: void 0,
      xDatum: void 0,
      value: void 0,
      cumulativeValue: void 0,
      trailingValue: void 0,
      datumType: void 0
    };
    for (const [datumIndex, datum] of ctx.rawData.entries()) {
      const datumType = ctx.totalTypeValues[datumIndex];
      const isSubtotal = this.isSubtotal(datumType);
      const isTotal = this.isTotal(datumType);
      const isTotalOrSubtotal = isTotal || isSubtotal;
      const xDatum = ctx.xValues[datumIndex];
      if (xDatum === void 0 && !this.properties.allowNullKeys)
        continue;
      const rawValue = ctx.yRawValues[datumIndex];
      const { cumulativeValue, trailingValue } = this.computeWaterfallValues(
        ctx,
        datumIndex,
        isTotal,
        isSubtotal,
        trailingSubtotal
      );
      if (isTotalOrSubtotal) {
        trailingSubtotal = cumulativeValue ?? 0;
      }
      const value = this.computeDisplayValue(isTotal, isSubtotal, rawValue, cumulativeValue, trailingValue);
      paramsScratch.datumIndex = datumIndex;
      paramsScratch.datum = datum;
      paramsScratch.xDatum = xDatum;
      paramsScratch.value = value;
      paramsScratch.cumulativeValue = cumulativeValue;
      paramsScratch.trailingValue = trailingValue;
      paramsScratch.datumType = datumType;
      const nodeDatum = upsertNodeDatum5(
        ctx,
        paramsScratch,
        (c, p) => this.createNodeDatum(c, p),
        (c, n, p) => this.updateNodeDatum(c, n, p)
      );
      if (nodeDatum) {
        const pathPoint = this.createPointDatum(
          ctx,
          nodeDatum,
          cumulativeValue,
          trailingValue,
          isTotalOrSubtotal
        );
        ctx.pointData.push(pathPoint);
      }
    }
  }
  finalizeNodeData(ctx) {
    if (ctx.nodeIndex < ctx.nodes.length) {
      ctx.nodes.length = ctx.nodeIndex;
    }
  }
  initializeResult(ctx) {
    return {
      itemId: this.properties.yKey,
      nodeData: ctx.nodes,
      labelData: ctx.nodes,
      pointData: [],
      scales: this.calculateScaling(),
      groupScale: this.getScaling(this.ctx.seriesStateManager.getGroupScale(this)),
      visible: this.visible,
      styles: getItemStylesPerItemId3(this.getItemStyle.bind(this), "total", "subtotal", "positive", "negative")
    };
  }
  assembleResult(ctx, result) {
    const connectorLinesEnabled = this.properties.line.enabled;
    if (ctx.yCurrValues != null && connectorLinesEnabled) {
      result.pointData = ctx.pointData;
    }
    return result;
  }
  createNodeDatumContext(xAxis, yAxis) {
    const { dataModel, processedData } = this;
    if (!dataModel || !processedData || processedData.type !== "ungrouped")
      return void 0;
    const categoryAxis = this.getCategoryAxis();
    const valueAxis = this.getValueAxis();
    if (!categoryAxis || !valueAxis)
      return void 0;
    const xScale = xAxis.scale;
    const yScale = yAxis.scale;
    const xValues = dataModel.resolveKeysById(this, `xValue`, processedData);
    const yRawValues = dataModel.resolveColumnById(this, `yRaw`, processedData);
    const totalTypeValues = dataModel.resolveColumnById(
      this,
      `totalTypeValue`,
      processedData
    );
    const yCurrValues = dataModel.resolveColumnById(this, "yCurrent", processedData);
    const yPrevValues = dataModel.resolveColumnById(this, "yPrevious", processedData);
    const yCurrTotalValues = dataModel.resolveColumnById(this, "yCurrentTotal", processedData);
    const rawData = processedData.dataSources.get(this.id)?.data ?? [];
    const { xKey, yKey, xName, yName, line } = this.properties;
    const { contextNodeData } = this;
    const animationEnabled = !this.ctx.animationManager.isSkipped();
    const canIncrementallyUpdate = contextNodeData?.nodeData != null && processedData.changeDescription != null;
    const { barWidth } = this.getBarDimensions();
    return {
      xAxis,
      yAxis,
      xScale,
      yScale,
      categoryAxis,
      valueAxis,
      barAlongX: this.getBarDirection() === "x" /* X */,
      barWidth,
      categoryAxisReversed: categoryAxis.isReversed(),
      valueAxisReversed: valueAxis.isReversed(),
      crisp: checkCrisp3(
        categoryAxis.scale,
        categoryAxis.visibleRange,
        this.smallestDataInterval,
        this.largestDataInterval
      ),
      animationEnabled,
      xKey,
      yKey,
      xName,
      yName,
      lineStrokeWidth: line.strokeWidth,
      yDomain: this.getSeriesDomain("y" /* Y */).domain,
      xValues,
      rawData,
      yRawValues,
      totalTypeValues,
      yCurrValues,
      yPrevValues,
      yCurrTotalValues,
      canIncrementallyUpdate,
      nodes: canIncrementallyUpdate ? contextNodeData.nodeData : [],
      nodeIndex: 0,
      pointData: []
    };
  }
  computeWaterfallValues(ctx, datumIndex, isTotal, isSubtotal, trailingSubtotal) {
    if (isTotal || isSubtotal) {
      return {
        cumulativeValue: ctx.yCurrTotalValues[datumIndex],
        trailingValue: isSubtotal ? trailingSubtotal : 0
      };
    }
    return {
      cumulativeValue: ctx.yCurrValues[datumIndex],
      trailingValue: ctx.yPrevValues[datumIndex]
    };
  }
  computeDisplayValue(isTotal, isSubtotal, rawValue, cumulativeValue, trailingValue) {
    if (isTotal) {
      return cumulativeValue;
    }
    if (isSubtotal) {
      return (cumulativeValue ?? 0) - (trailingValue ?? 0);
    }
    return rawValue;
  }
  /**
   * Creates a skeleton WaterfallNodeDatum with minimal required fields.
   * The node will be populated by updateNodeDatum.
   */
  createSkeletonNodeDatum(ctx, params) {
    const { xKey, yKey, crisp } = ctx;
    const { datumIndex, datum, xDatum, value, cumulativeValue, datumType } = params;
    const isPositive = (value ?? 0) >= 0;
    const seriesItemType = this.getSeriesItemType(isPositive, datumType);
    return {
      index: datumIndex,
      series: this,
      itemType: seriesItemType,
      datum,
      datumIndex,
      cumulativeValue: cumulativeValue ?? 0,
      xValue: xDatum,
      yValue: value,
      yKey,
      xKey,
      x: 0,
      y: 0,
      width: 0,
      height: 0,
      midPoint: { x: 0, y: 0 },
      crisp,
      label: { text: "", x: 0, y: 0, textAlign: "center", textBaseline: "middle" }
    };
  }
  /**
   * Updates an existing WaterfallNodeDatum in-place.
   * This is more efficient than recreating the entire node when only data values change.
   */
  updateNodeDatum(ctx, node, params) {
    const { xScale, yScale, barAlongX, barWidth, valueAxisReversed, xKey, yKey, xName, yName, yDomain, crisp } = ctx;
    const { datumIndex, datum, xDatum, value, cumulativeValue, trailingValue, datumType } = params;
    const mutableNode = node;
    const x = Math.round(xScale.convert(xDatum));
    if (!Number.isFinite(x))
      return;
    const isPositive = (value ?? 0) >= 0;
    const seriesItemType = this.getSeriesItemType(isPositive, datumType);
    const { strokeWidth, label } = this.getItemConfig(seriesItemType);
    const currY = Math.round(yScale.convert(cumulativeValue));
    const trailY = Math.round(yScale.convert(trailingValue));
    const y = isPositive ? currY : trailY;
    const bottomY = isPositive ? trailY : currY;
    const barHeight = Math.max(strokeWidth, Math.abs(bottomY - y));
    const rectX = barAlongX ? Math.min(y, bottomY) : x;
    const rectY = barAlongX ? x : Math.min(y, bottomY);
    const rectWidth = barAlongX ? barHeight : barWidth;
    const rectHeight = barAlongX ? barWidth : barHeight;
    mutableNode.index = datumIndex;
    mutableNode.itemType = seriesItemType;
    mutableNode.datum = datum;
    mutableNode.datumIndex = datumIndex;
    mutableNode.cumulativeValue = cumulativeValue ?? 0;
    mutableNode.xValue = xDatum;
    mutableNode.yValue = value;
    mutableNode.x = rectX;
    mutableNode.y = rectY;
    mutableNode.width = rectWidth;
    mutableNode.height = rectHeight;
    mutableNode.crisp = crisp;
    if (mutableNode.midPoint) {
      mutableNode.midPoint.x = rectX + rectWidth / 2;
      mutableNode.midPoint.y = rectY + rectHeight / 2;
    } else {
      mutableNode.midPoint = { x: rectX + rectWidth / 2, y: rectY + rectHeight / 2 };
    }
    if (label.enabled) {
      const itemType = seriesItemType === "subtotal" ? "total" : seriesItemType;
      const labelText = this.getLabelText(
        value,
        datum,
        yKey,
        "y",
        yDomain,
        label,
        {
          itemType,
          value,
          datum,
          xKey,
          yKey,
          xName,
          yName
        }
      );
      const spacing = label.spacing + (typeof label.padding === "number" ? label.padding : 0);
      const labelPlacement = adjustLabelPlacement2({
        isUpward: (value ?? -1) >= 0 !== valueAxisReversed,
        isVertical: !barAlongX,
        placement: label.placement,
        spacing,
        rect: { x: rectX, y: rectY, width: rectWidth, height: rectHeight }
      });
      mutableNode.label.text = labelText;
      mutableNode.label.x = labelPlacement.x;
      mutableNode.label.y = labelPlacement.y;
      mutableNode.label.textAlign = labelPlacement.textAlign;
      mutableNode.label.textBaseline = labelPlacement.textBaseline;
    } else {
      mutableNode.label.text = "";
    }
  }
  /**
   * Creates a WaterfallNodeDatum for a single data point.
   * Creates a skeleton node and uses updateNodeDatum to populate it.
   */
  createNodeDatum(ctx, params) {
    const node = this.createSkeletonNodeDatum(ctx, params);
    this.updateNodeDatum(ctx, node, params);
    return node;
  }
  createPointDatum(ctx, nodeDatum, cumulativeValue, trailingValue, isTotalOrSubtotal) {
    const { yScale, barAlongX, categoryAxisReversed, lineStrokeWidth } = ctx;
    const currY = Math.round(yScale.convert(cumulativeValue));
    const trailY = Math.round(yScale.convert(trailingValue));
    const pointY = isTotalOrSubtotal ? currY : trailY;
    const pixelAlignmentOffset = Math.floor(lineStrokeWidth) % 2 / 2;
    const startY = categoryAxisReversed ? currY : pointY;
    const stopY = categoryAxisReversed ? pointY : currY;
    const rect2 = { x: nodeDatum.x, y: nodeDatum.y, width: nodeDatum.width, height: nodeDatum.height };
    let startCoordinates;
    let stopCoordinates;
    if (barAlongX) {
      startCoordinates = {
        x: startY + pixelAlignmentOffset,
        y: rect2.y
      };
      stopCoordinates = {
        x: stopY + pixelAlignmentOffset,
        y: rect2.y + rect2.height
      };
    } else {
      startCoordinates = {
        x: rect2.x,
        y: startY + pixelAlignmentOffset
      };
      stopCoordinates = {
        x: rect2.x + rect2.width,
        y: stopY + pixelAlignmentOffset
      };
    }
    return {
      // lineTo
      x: categoryAxisReversed ? stopCoordinates.x : startCoordinates.x,
      y: categoryAxisReversed ? stopCoordinates.y : startCoordinates.y,
      // moveTo
      x2: categoryAxisReversed ? startCoordinates.x : stopCoordinates.x,
      y2: categoryAxisReversed ? startCoordinates.y : stopCoordinates.y,
      size: 0
    };
  }
  updateSeriesItemTypes() {
    const { dataModel, seriesItemTypes, processedData } = this;
    if (!dataModel || !processedData) {
      return;
    }
    seriesItemTypes.clear();
    const yPositiveIndex = dataModel.resolveProcessedDataIndexById(this, "yCurrentPositive");
    const yNegativeIndex = dataModel.resolveProcessedDataIndexById(this, "yCurrentNegative");
    const totalTypeIndex = dataModel.resolveProcessedDataIndexById(this, `totalTypeValue`);
    const positiveDomain = processedData.domain.values[yPositiveIndex] ?? [];
    const negativeDomain = processedData.domain.values[yNegativeIndex] ?? [];
    if (positiveDomain.length > 0) {
      seriesItemTypes.add("positive");
    }
    if (negativeDomain.length > 0) {
      seriesItemTypes.add("negative");
    }
    const itemTypes = processedData?.domain.values[totalTypeIndex];
    if (!itemTypes) {
      return;
    }
    for (const type of itemTypes) {
      if (type === "total" || type === "subtotal") {
        seriesItemTypes.add("total");
      }
    }
  }
  isSubtotal(datumType) {
    return datumType === "subtotal";
  }
  isTotal(datumType) {
    return datumType === "total";
  }
  nodeFactory() {
    return new Rect6();
  }
  getSeriesItemType(isPositive, datumType) {
    return datumType ?? (isPositive ? "positive" : "negative");
  }
  getItemConfig(seriesItemType) {
    switch (seriesItemType) {
      case "positive": {
        return this.properties.item.positive;
      }
      case "negative": {
        return this.properties.item.negative;
      }
      case "subtotal":
      case "total": {
        return this.properties.item.total;
      }
    }
  }
  updateDatumSelection(opts) {
    const { nodeData, datumSelection } = opts;
    const data = nodeData ?? [];
    if (!processedDataIsAnimatable6(this.processedData)) {
      return datumSelection.update(data);
    }
    return datumSelection.update(data, void 0, (datum) => createDatumId12(datum.datumIndex));
  }
  getItemStyle(nodeDatum, isHighlight, highlightState, itemType = "total") {
    const { properties } = this;
    const { datumIndex = 0, datum } = nodeDatum ?? {};
    const propertyItemId = itemType === "subtotal" ? "total" : itemType;
    const item = properties.item[propertyItemId];
    const highlightStyle = this.getHighlightStyle(isHighlight, datumIndex, highlightState);
    const baseStyle = mergeDefaults(highlightStyle, properties.getStyle(itemType));
    const { itemStyler } = item;
    let style2 = baseStyle;
    if (itemStyler != null && nodeDatum != null) {
      const overrides = this.cachedDatumCallback(
        createDatumId12(datumIndex, isHighlight ? "highlight" : "node"),
        () => {
          const params = this.makeItemStylerParams(itemType, datumIndex, datum, isHighlight, style2);
          return this.ctx.optionsGraphService.resolvePartial(
            ["series", `${this.declarationOrder}`, "item", propertyItemId],
            this.callWithContext(itemStyler, params)
          );
        }
      );
      if (overrides) {
        style2 = mergeDefaults(overrides, style2);
      }
    }
    return style2;
  }
  makeItemStylerParams(itemType, datumIndex, datum, isHighlight, style2) {
    const { id: seriesId, properties } = this;
    const { xKey, yKey } = properties;
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const highlightStateString = this.getHighlightStateString(activeHighlight, isHighlight, datumIndex);
    const fill = this.filterItemStylerFillParams(style2.fill) ?? style2.fill;
    return {
      seriesId,
      itemType,
      datum,
      xKey,
      yKey,
      highlightState: highlightStateString,
      ...style2,
      fill
    };
  }
  updateDatumStyles({
    datumSelection,
    isHighlight
  }) {
    datumSelection.each((_, datum) => {
      datum.style = this.getItemStyle(datum, isHighlight, void 0, datum.itemType);
    });
  }
  updateDatumNodes({
    datumSelection,
    isHighlight
  }) {
    const { contextNodeData } = this;
    if (!contextNodeData) {
      return;
    }
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    const categoryAlongX = this.getCategoryDirection() === "x" /* X */;
    const fillBBox = this.getShapeFillBBox();
    datumSelection.each((rect2, datum) => {
      const style2 = datum.style ?? contextNodeData.styles[datum.itemType][this.getHighlightState(highlightedDatum, isHighlight, datum.datumIndex)];
      rect2.setStyleProperties(style2, fillBBox);
      rect2.cornerRadius = style2.cornerRadius ?? 0;
      rect2.visible = categoryAlongX ? datum.width > 0 : datum.height > 0;
      rect2.crisp = datum.crisp;
    });
  }
  updateLabelSelection(opts) {
    const { labelData, labelSelection } = opts;
    if (labelData.length === 0) {
      return labelSelection.update([]);
    }
    const data = labelData.filter((labelDatum) => {
      const { label } = this.getItemConfig(labelDatum.itemType);
      return label.enabled;
    });
    return labelSelection.update(data);
  }
  updateLabelNodes({
    labelSelection,
    isHighlight
  }) {
    const params = {
      itemType: "positive",
      xKey: this.properties.xKey,
      xName: this.properties.xName ?? this.properties.xName,
      yKey: this.properties.yKey,
      yName: this.properties.yName ?? this.properties.yName
    };
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    labelSelection.each((textNode, datum) => {
      params.itemType = datum.itemType;
      const styleOpacity = this.getHighlightStyle(isHighlight, datum.datumIndex)?.opacity ?? 1;
      textNode.visible = true;
      textNode.fillOpacity = styleOpacity;
      const label = this.getItemConfig(datum.itemType).label;
      updateLabelNode5(this, textNode, params, label, datum.label, isHighlight, activeHighlight);
    });
  }
  getTooltipContent(datumIndex) {
    const { id: seriesId, dataModel, processedData, properties } = this;
    const { xKey, xName, yKey, yName, tooltip, legendItemName } = properties;
    const xAxis = this.getCategoryAxis();
    const yAxis = this.getValueAxis();
    if (!dataModel || !processedData || !xAxis || !yAxis)
      return;
    const datum = processedData.dataSources.get(this.id)?.data[datumIndex];
    const xValue = dataModel.resolveKeysById(this, `xValue`, processedData)[datumIndex];
    const yValue = dataModel.resolveColumnById(this, `yRaw`, processedData)[datumIndex];
    const yCurrTotalValues = dataModel.resolveColumnById(this, "yCurrentTotal", processedData);
    const totalTypeValues = dataModel.resolveColumnById(
      this,
      `totalTypeValue`,
      processedData
    );
    const allowNullKeys = this.properties.allowNullKeys ?? false;
    if (xValue === void 0 && !allowNullKeys)
      return;
    const datumType = totalTypeValues[datumIndex];
    const isPositive = (yValue ?? 0) >= 0;
    const seriesItemType = this.getSeriesItemType(isPositive, datumType);
    let total;
    if (this.isTotal(datumType)) {
      total = yCurrTotalValues[datumIndex];
    } else if (this.isSubtotal(datumType)) {
      total = yCurrTotalValues[datumIndex];
      for (let previousIndex = datumIndex - 1; previousIndex >= 0; previousIndex -= 1) {
        if (this.isSubtotal(totalTypeValues[previousIndex])) {
          total = total - yCurrTotalValues[previousIndex];
          break;
        }
      }
    } else {
      total = yValue;
    }
    const nodeDatum = this.contextNodeData?.nodeData?.[datumIndex];
    const format = this.getItemStyle(nodeDatum, false, void 0, nodeDatum?.itemType);
    return this.formatTooltipWithContext(
      tooltip,
      {
        heading: this.getAxisValueText(xAxis, "tooltip", xValue, datum, xKey, legendItemName),
        symbol: this.legendItemSymbol(seriesItemType),
        data: [
          {
            label: yName,
            fallbackLabel: yKey,
            value: this.getAxisValueText(yAxis, "tooltip", total, datum, yKey, legendItemName),
            missing: module_support_exports.isTooltipValueMissing(total)
          }
        ]
      },
      { seriesId, datum, title: yName, itemType: seriesItemType, xKey, xName, yKey, yName, ...format }
    );
  }
  legendItemSymbol(item) {
    const { fill, stroke: stroke3, fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.getItemConfig(item);
    return {
      marker: {
        fill,
        stroke: stroke3,
        fillOpacity,
        strokeOpacity,
        strokeWidth,
        lineDash,
        lineDashOffset
      }
    };
  }
  getLegendData(legendType) {
    if (legendType !== "category") {
      return [];
    }
    const { id, seriesItemTypes } = this;
    const legendData = [];
    const capitalise = (text2) => text2.charAt(0).toUpperCase() + text2.substring(1);
    const { showInLegend } = this.properties;
    for (const item of seriesItemTypes) {
      const { name } = this.getItemConfig(item);
      legendData.push({
        legendType: "category",
        id,
        itemId: createDatumId12(item),
        seriesId: id,
        enabled: true,
        label: { text: name ?? capitalise(item) },
        symbol: this.legendItemSymbol(item),
        hideInLegend: !showInLegend,
        isFixed: true
      });
    }
    return legendData;
  }
  toggleSeriesItem() {
  }
  resetDatumAnimation(data) {
    resetBarSelectionsDirect3([data.datumSelection]);
  }
  animateEmptyUpdateReady(opts) {
    const { datumSelection, labelSelection, contextData } = opts;
    const fns = prepareBarAnimationFunctions3(
      collapsedStartingBarPosition2(this.isVertical(), this.axes, "normal"),
      "unknown"
    );
    motion4.fromToMotion(this.id, "datums", this.ctx.animationManager, [datumSelection], fns);
    seriesLabelFadeInAnimation5(this, "labels", this.ctx.animationManager, labelSelection);
    const { pointData } = contextData;
    if (!pointData)
      return;
    if (this.isVertical()) {
      this.animateConnectorLinesVertical(opts);
    } else {
      this.animateConnectorLinesHorizontal(opts);
    }
  }
  animateConnectorLinesHorizontal(opts) {
    const { pointData = [] } = opts.contextData;
    const [lineNode] = opts.paths;
    const { path: linePath } = lineNode;
    this.updateLineNode(lineNode);
    const valueAxis = this.getValueAxis();
    const valueAxisReversed = valueAxis?.isReversed();
    const compare = valueAxisReversed ? (v, v2) => v < v2 : (v, v2) => v > v2;
    const startX = valueAxis?.scale.convert(0);
    const endX = pointData.reduce(
      (end3, point) => {
        if (compare(point.x, end3)) {
          end3 = point.x;
        }
        return end3;
      },
      valueAxisReversed ? Infinity : 0
    );
    const scale2 = (value, start1, end1, start2, end22) => {
      return (value - start1) / (end1 - start1) * (end22 - start2) + start2;
    };
    this.ctx.animationManager.animate({
      id: `${this.id}_connectors`,
      groupId: this.id,
      phase: "initial",
      from: startX,
      to: endX,
      ease: easeOut,
      collapsable: false,
      onUpdate(pointX) {
        linePath.clear(true);
        for (const [index, point] of pointData.entries()) {
          const x = scale2(pointX, startX, endX, startX, point.x);
          const x2 = scale2(pointX, startX, endX, startX, point.x2);
          if (index !== 0) {
            linePath.lineTo(x, point.y);
          }
          linePath.moveTo(x2, point.y2);
        }
        lineNode.checkPathDirty();
      },
      onStop: () => this.resetConnectorLinesPath(opts)
    });
  }
  animateConnectorLinesVertical(opts) {
    const { pointData = [] } = opts.contextData;
    const [lineNode] = opts.paths;
    const { path: linePath } = lineNode;
    this.updateLineNode(lineNode);
    const valueAxis = this.getValueAxis();
    const valueAxisReversed = valueAxis?.isReversed();
    const compare = valueAxisReversed ? (v, v2) => v > v2 : (v, v2) => v < v2;
    const startY = valueAxis?.scale.convert(0);
    const endY = pointData.reduce(
      (end3, point) => {
        if (compare(point.y, end3)) {
          end3 = point.y;
        }
        return end3;
      },
      valueAxisReversed ? 0 : Infinity
    );
    const scale2 = (value, start1, end1, start2, end22) => {
      return (value - start1) / (end1 - start1) * (end22 - start2) + start2;
    };
    this.ctx.animationManager.animate({
      id: `${this.id}_connectors`,
      groupId: this.id,
      phase: "initial",
      from: startY,
      to: endY,
      ease: easeOut,
      collapsable: false,
      onUpdate(pointY) {
        linePath.clear(true);
        for (const [index, point] of pointData.entries()) {
          const y = scale2(pointY, startY, endY, startY, point.y);
          const y2 = scale2(pointY, startY, endY, startY, point.y2);
          if (index !== 0) {
            linePath.lineTo(point.x, y);
          }
          linePath.moveTo(point.x2, y2);
        }
        lineNode.checkPathDirty();
      },
      onStop: () => this.resetConnectorLinesPath(opts)
    });
  }
  animateReadyResize(data) {
    super.animateReadyResize(data);
    this.resetConnectorLinesPath(data);
  }
  updatePaths(opts) {
    this.resetConnectorLinesPath({ contextData: opts.contextData, paths: opts.paths });
  }
  resetConnectorLinesPath({
    contextData,
    paths
  }) {
    if (paths.length === 0) {
      return;
    }
    const [lineNode] = paths;
    this.updateLineNode(lineNode);
    const { path: linePath } = lineNode;
    linePath.clear(true);
    const { pointData } = contextData;
    if (!pointData) {
      return;
    }
    for (const [index, point] of pointData.entries()) {
      if (index !== 0) {
        linePath.lineTo(point.x, point.y);
      }
      linePath.moveTo(point.x2, point.y2);
    }
    lineNode.checkPathDirty();
  }
  updateLineNode(lineNode) {
    const { stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this.properties.line;
    lineNode.setProperties({
      fill: void 0,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset,
      lineJoin: "round",
      pointerEvents: module_support_exports.PointerEvents.None
    });
  }
  isLabelEnabled() {
    const { positive, negative, total } = this.properties.item;
    return positive.label.enabled || negative.label.enabled || total.label.enabled;
  }
  computeFocusBounds({ datumIndex }) {
    return computeBarFocusBounds6(this, this.contextNodeData?.nodeData[datumIndex]);
  }
  hasItemStylers() {
    const { positive, negative, total } = this.properties.item;
    return positive.itemStyler != null || positive.label.itemStyler != null || negative.itemStyler != null || negative.label.itemStyler != null || total.itemStyler != null || total.label.itemStyler != null;
  }
};
WaterfallSeries.className = "WaterfallSeries";
WaterfallSeries.type = "waterfall";

// packages/ag-charts-enterprise/src/series/waterfall/waterfallSeriesOptionsDef.ts
var { waterfallSeriesThemeableOptionsDef: waterfallSeriesThemeableOptionsDef2 } = module_support_exports;
var waterfallSeriesOptionsDef = {
  ...waterfallSeriesThemeableOptionsDef2,
  ...commonSeriesOptionsDefs,
  type: required(constant("waterfall")),
  xKey: required(string),
  yKey: required(string),
  xKeyAxis: string,
  yKeyAxis: string,
  xName: string,
  yName: string,
  totals: arrayOfDefs(
    {
      totalType: required(union("total", "subtotal")),
      index: required(positiveNumber),
      axisLabel: required(string)
    },
    "a total definition options array"
  ),
  width: positiveNumberNonZero
};

// packages/ag-charts-enterprise/src/series/waterfall/waterfallThemes.ts
function itemTheme2(key, index) {
  return {
    fill: {
      $applySwitch: [
        { $path: "type" },
        {
          $if: [
            { $eq: [{ $palette: "type" }, "user-indexed"] },
            { $path: [`/${index}`, { $palette: "fill" }, { $palette: "fills" }] },
            { $palette: `${key}.fill` }
          ]
        },
        ["gradient", FILL_GRADIENT_LINEAR_KEYED_DEFAULTS(key)],
        ["image", FILL_IMAGE_DEFAULTS],
        ["pattern", FILL_PATTERN_KEYED_DEFAULTS(key)]
      ]
    },
    stroke: { $palette: `${key}.stroke` },
    strokeWidth: { $isUserOption: ["./stroke", 2, 0] },
    label: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: false,
      fontStyle: void 0,
      fontWeight: { $ref: "fontWeight" },
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      color: { $ref: "textColor" },
      formatter: void 0,
      placement: "outside-end",
      padding: { $isUserOption: ["./spacing", 0, 6] }
      // compatibility with old `padding` property (now named `spacing`).
    }
  };
}
var WATERFALL_SERIES_THEME = {
  series: {
    item: {
      positive: itemTheme2("altUp", 0),
      negative: itemTheme2("altDown", 1),
      total: itemTheme2("neutral", 2)
    },
    line: {
      stroke: { $palette: "neutral.stroke" },
      strokeOpacity: 1,
      lineDash: [0],
      lineDashOffset: 0,
      strokeWidth: 2
    },
    highlight: SINGLE_SERIES_HIGHLIGHT_STYLE
  },
  legend: {
    enabled: true,
    toggleSeries: false
  }
};

// packages/ag-charts-enterprise/src/series/waterfall/waterfallModule.ts
var WaterfallSeriesModule = {
  type: "series",
  name: "waterfall",
  chartType: "cartesian",
  enterprise: true,
  solo: true,
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: waterfallSeriesOptionsDef,
  defaultAxes: DIRECTION_SWAP_AXES,
  axisKeys: { ["x" /* X */]: "xKeyAxis", ["y" /* Y */]: "yKeyAxis" },
  axisKeysFlipped: { ["x" /* X */]: "yKeyAxis", ["y" /* Y */]: "xKeyAxis" },
  themeTemplate: WATERFALL_SERIES_THEME,
  create: (ctx) => new WaterfallSeries(ctx)
};

// packages/ag-charts-enterprise/src/features/navigator/navigatorOptionsDefs.ts
var navigatorHandleOptionsDef2 = {
  width: positiveNumber,
  height: positiveNumber,
  grip: boolean,
  fill: color,
  stroke: color,
  strokeWidth: positiveNumber,
  cornerRadius: positiveNumber
};
var commonIgnoredMiniChartProperties = [
  "cursor",
  "highlightStyle",
  "listeners",
  "nodeClickRange",
  "showInLegend",
  "showInMiniChart",
  "tooltip",
  "visible",
  "xName",
  "yName"
];
var barIgnoredMiniChartProperties = [
  ...commonIgnoredMiniChartProperties,
  "errorBar",
  "label",
  "legendItemName"
];
var boxPlotIngnoredMiniChartProperties = [
  ...commonIgnoredMiniChartProperties,
  "direction",
  "legendItemName",
  "minName",
  "q1Name",
  "medianName",
  "q3Name",
  "maxName"
];
var bubbleIgnoredMiniChartProperties = [
  ...commonIgnoredMiniChartProperties,
  "title",
  "label",
  "labelKey",
  "labelName",
  "sizeName"
];
var heatmapIgnoredMiniChartProperties = [
  ...commonIgnoredMiniChartProperties,
  "title",
  "label",
  "colorName",
  "textAlign",
  "verticalAlign",
  "itemPadding",
  "colorRange"
];
var histogramIgnoredMiniChartProperties = [
  ...commonIgnoredMiniChartProperties,
  "label"
];
var lineIgnoredMiniChartProperties = [
  ...commonIgnoredMiniChartProperties,
  "errorBar",
  "title",
  "label"
];
var rangeAreaIgnoredMiniChartProperties = [
  ...commonIgnoredMiniChartProperties,
  "label",
  "yLowName",
  "yHighName"
];
var rangeBarIgnoredMiniChartProperties = [
  ...commonIgnoredMiniChartProperties,
  "direction",
  "label",
  "yLowName",
  "yHighName"
];
var scatterIgnoredMiniChartProperties = [
  ...commonIgnoredMiniChartProperties,
  "errorBar",
  "title",
  "label",
  "labelKey",
  "labelName"
];
var waterfallIgnoredMiniChartProperties = [
  ...commonIgnoredMiniChartProperties,
  "direction"
];
var navigatorOptionsDef2 = {
  enabled: boolean,
  height: positiveNumber,
  spacing: positiveNumber,
  cornerRadius: number,
  mask: {
    fill: color,
    fillOpacity: ratio,
    stroke: color,
    strokeWidth: positiveNumber
  },
  minHandle: navigatorHandleOptionsDef2,
  maxHandle: navigatorHandleOptionsDef2,
  miniChart: {
    enabled: boolean,
    padding: {
      top: positiveNumber,
      bottom: positiveNumber
    },
    label: {
      enabled: boolean,
      avoidCollisions: boolean,
      spacing: positiveNumber,
      format: numberFormatValidator,
      formatter: callbackOf(textOrSegments),
      interval: {
        minSpacing: positiveNumber,
        maxSpacing: positiveNumber,
        values: array,
        step: number
      },
      ...fontOptionsDef
    },
    series: arrayOfDefs(
      typeUnion(
        {
          area: without(AreaSeriesModule.options, [...commonIgnoredMiniChartProperties, "type"]),
          bar: without(BarSeriesModule.options, [...barIgnoredMiniChartProperties, "type"]),
          "box-plot": without(BoxPlotSeriesModule.options, [...boxPlotIngnoredMiniChartProperties, "type"]),
          bubble: without(BubbleSeriesModule.options, [...bubbleIgnoredMiniChartProperties, "type"]),
          candlestick: without(CandlestickSeriesModule.options, [
            ...commonIgnoredMiniChartProperties,
            "type"
          ]),
          heatmap: without(HeatmapSeriesModule.options, [...heatmapIgnoredMiniChartProperties, "type"]),
          histogram: without(HistogramSeriesModule.options, [...histogramIgnoredMiniChartProperties, "type"]),
          line: without(LineSeriesModule.options, [...lineIgnoredMiniChartProperties, "type"]),
          ohlc: without(OhlcSeriesModule.options, [...commonIgnoredMiniChartProperties, "type"]),
          "range-area": without(RangeAreaSeriesModule.options, [
            ...rangeAreaIgnoredMiniChartProperties,
            "type"
          ]),
          "range-bar": without(RangeBarSeriesModule.options, [...rangeBarIgnoredMiniChartProperties, "type"]),
          scatter: without(ScatterSeriesModule.options, [...scatterIgnoredMiniChartProperties, "type"]),
          waterfall: without(WaterfallSeriesModule.options, [...waterfallIgnoredMiniChartProperties, "type"])
        },
        "miniChart series options"
      )
    )
  }
};

// packages/ag-charts-enterprise/src/features/navigator/navigatorTheme.ts
var validMiniChartSeriesTypes = [
  "area",
  "bar",
  "bubble",
  "candlestick",
  "heatmap",
  "histogram",
  "line",
  "ohlc",
  "range-area",
  "range-bar",
  "scatter",
  "waterfall"
];
var priceVolumePresetIgnoredMiniChartProperties = [
  "itemStyler",
  "simpleItemStyler",
  "direction",
  "fill",
  "fillGradientDefaults",
  "fillPatternDefaults",
  "fillImageDefaults",
  "fillOpacity",
  "shadow",
  "focusPriority",
  "highlight",
  "lineDash",
  "lineDashOffset",
  "strokeWidth"
];
function miniChartSeriesTheme(seriesPath, typePath) {
  return {
    $merge: [
      {
        $switch: [
          typePath,
          {},
          [
            ["area", "line", "range-area"],
            {
              marker: {
                enabled: {
                  $isUserOption: [
                    "/series/$index/marker/enabled",
                    { $path: ["/series/$index/marker/enabled", false] },
                    false
                  ]
                }
              }
            }
          ]
        ]
      },
      {
        $omit: [
          {
            $switch: [
              typePath,
              commonIgnoredMiniChartProperties,
              ["bar", barIgnoredMiniChartProperties],
              ["box-plot", boxPlotIngnoredMiniChartProperties],
              ["bubble", bubbleIgnoredMiniChartProperties],
              ["heatmap", heatmapIgnoredMiniChartProperties],
              ["histogram", histogramIgnoredMiniChartProperties],
              [
                "line",
                [...lineIgnoredMiniChartProperties, ...priceVolumePresetIgnoredMiniChartProperties]
              ],
              ["range-area", rangeAreaIgnoredMiniChartProperties],
              ["range-bar", rangeBarIgnoredMiniChartProperties],
              ["scatter", scatterIgnoredMiniChartProperties],
              ["waterfall", waterfallIgnoredMiniChartProperties]
            ]
          },
          seriesPath
        ]
      }
    ]
  };
}
var NAVIGATOR_THEME = {
  enabled: false,
  height: { $if: [{ $path: "./miniChart/enabled" }, 40, 18] },
  cornerRadius: 4,
  mask: {
    fill: { $ref: "foregroundColor" },
    fillOpacity: 0.1,
    stroke: { $ref: "borderColor" },
    strokeWidth: 1
  },
  minHandle: {
    fill: { $ref: "chartBackgroundColor" },
    stroke: { $ref: "borderColor" },
    strokeWidth: 1,
    width: 12,
    height: 24,
    cornerRadius: 4
  },
  maxHandle: {
    fill: { $ref: "chartBackgroundColor" },
    stroke: { $ref: "borderColor" },
    strokeWidth: 1,
    width: 12,
    height: 24,
    cornerRadius: 4
  },
  miniChart: {
    enabled: false,
    label: {
      color: { $ref: "textColor" },
      fontSize: { $rem: FONT_SIZE_RATIO.SMALLER },
      fontFamily: { $ref: "fontFamily" },
      fontWeight: { $ref: "fontWeight" },
      spacing: 5
    },
    padding: {
      top: 0,
      bottom: 0
    },
    series: {
      $apply: [
        miniChartSeriesTheme(
          { $path: "/series/$index" },
          {
            $path: [
              "/navigator/miniChart/series/$index/type",
              { $path: ["type", { $path: "/series/$index/type" }] }
            ]
          }
        ),
        {
          // TODO: this should be a $switch but switches can not resolve the case value yet
          $if: [
            {
              $or: validMiniChartSeriesTypes.map((type) => ({
                $eq: [{ $path: "/series/0/type" }, type]
              }))
            },
            {
              $map: [
                miniChartSeriesTheme({ $value: "$1" }, { $path: "/series/$index/type" }),
                { $path: "/series" }
              ]
            },
            void 0
          ]
        }
      ]
    }
  }
};

// packages/ag-charts-enterprise/src/features/navigator/navigatorModule.ts
var NavigatorModule = {
  type: "plugin",
  name: "navigator",
  chartType: "cartesian",
  enterprise: true,
  version: VERSION,
  // removable: false, // Toggling this module causes zoom state flakiness.
  options: navigatorOptionsDef2,
  themeTemplate: NAVIGATOR_THEME,
  create: (ctx) => new Navigator(ctx)
};

// packages/ag-charts-enterprise/src/features/ranges/rangesButtonProperties.ts
var RangesButtonProperties = class extends ToolbarButtonProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RangesButtonProperties.prototype, "value", 2);

// packages/ag-charts-enterprise/src/features/ranges/ranges.ts
var { userInteraction: userInteraction2, LayoutElement: LayoutElement4, Toolbar: Toolbar2 } = module_support_exports;
var Ranges = class extends AbstractModuleInstance {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.enabled = false;
    this.buttons = new PropertiesArray(RangesButtonProperties);
    this.verticalSpacing = 10;
    this.container = ctx.domManager.addChild("canvas-overlay", "range-buttons");
    this.container.role = "presentation";
    this.toolbar = new Toolbar2(this.ctx, "ariaLabelRangesToolbar", "horizontal");
    this.toolbar.addClass("ag-charts-range-buttons");
    this.container.append(this.toolbar.getElement());
    this.cleanup.register(
      this.toolbar.addToolbarListener("button-pressed", this.onButtonPress.bind(this)),
      ctx.layoutManager.registerElement(LayoutElement4.ToolbarBottom, this.onLayoutStart.bind(this)),
      ctx.eventsHub.on("zoom:change-complete", this.onZoomChanged.bind(this)),
      this.teardown.bind(this)
    );
  }
  teardown() {
    this.toolbar.getElement().remove();
    this.toolbar.destroy();
  }
  onLayoutStart({ layoutBox }) {
    const { buttons, ctx, enabled, toolbar: toolbar2, verticalSpacing } = this;
    if (!enabled || !ctx.zoomManager.isZoomEnabled()) {
      toolbar2.setHidden(true);
      return;
    }
    toolbar2.setHidden(false);
    toolbar2.updateButtons(buttons);
    const height2 = toolbar2.getBounds().height;
    toolbar2.setBounds({
      x: layoutBox.x,
      y: layoutBox.y + layoutBox.height - height2,
      width: layoutBox.width,
      height: height2
    });
    layoutBox.shrink({ bottom: height2 + verticalSpacing });
  }
  onZoomChanged() {
    this.toolbar.clearActiveButton();
  }
  onButtonPress({ button: { index } }) {
    const { zoomManager } = this.ctx;
    const button = this.buttons.at(index);
    if (!button)
      return;
    const { value } = button;
    const sourcing = userInteraction2(`zoom-range-button-${index}`);
    if (value == null) {
      zoomManager.resetZoom(sourcing);
    } else if (typeof value === "number") {
      zoomManager.extendToEnd(sourcing, "x" /* X */, value);
    } else if (Array.isArray(value)) {
      zoomManager.updateWith(sourcing, "x" /* X */, () => value);
    } else if (typeof value === "function") {
      zoomManager.updateWith(sourcing, "x" /* X */, value);
    }
    this.toolbar.toggleActiveButtonByIndex(index);
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], Ranges.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Ranges.prototype, "buttons", 2);

// packages/ag-charts-enterprise/src/features/ranges/rangesModule.ts
var DAY = 1e3 * 60 * 60 * 24;
var MONTH = DAY * 30;
var YEAR = DAY * 365;
var RangesModule = {
  type: "plugin",
  name: "ranges",
  chartType: "cartesian",
  enterprise: true,
  version: VERSION,
  options: {
    enabled: boolean,
    buttons: arrayOfDefs(
      {
        ...toolbarButtonOptionsDefs,
        value: or(number, and(arrayOf(or(number, date)), arrayLength(2, 2)), callback)
      },
      "range button options array"
    )
  },
  themeTemplate: {
    enabled: false,
    buttons: {
      $shallowSimple: [
        {
          label: "toolbarRange1Month",
          ariaLabel: "toolbarRange1MonthAria",
          value: MONTH
        },
        {
          label: "toolbarRange3Months",
          ariaLabel: "toolbarRange3MonthsAria",
          value: 3 * MONTH
        },
        {
          label: "toolbarRange6Months",
          ariaLabel: "toolbarRange6MonthsAria",
          value: 6 * MONTH
        },
        {
          label: "toolbarRangeYearToDate",
          ariaLabel: "toolbarRangeYearToDateAria",
          value: (_start, end3) => [
            (/* @__PURE__ */ new Date(`${new Date(end3).getFullYear()}-01-01`)).getTime(),
            void 0
          ]
        },
        {
          label: "toolbarRange1Year",
          ariaLabel: "toolbarRange1YearAria",
          value: YEAR
        },
        {
          label: "toolbarRangeAll",
          ariaLabel: "toolbarRangeAllAria",
          value: void 0
          // Reset zoom
        }
      ]
    }
  },
  create: (ctx) => new Ranges(ctx)
};

// packages/ag-charts-enterprise/src/features/scrollbar/scrollbarDOMProxy.ts
var { SliderWidget: SliderWidget3 } = module_support_exports;
var STEP_REPEAT_DELAY_MS = 400;
var STEP_REPEAT_INTERVAL_MS = 50;
var StepRepeater = class {
  constructor(applyStep) {
    this.applyStep = applyStep;
  }
  start(target) {
    this.setTarget(target);
    this.run(STEP_REPEAT_DELAY_MS);
  }
  updateTarget(target) {
    this.setTarget(target);
    if (!this.isActive()) {
      this.run(STEP_REPEAT_DELAY_MS);
    }
  }
  stop(resetTarget = true) {
    this.clearTimer();
    if (resetTarget) {
      this.target = void 0;
    }
  }
  setTarget(target) {
    this.target = clamp(0, target, 1);
  }
  run(delay) {
    if (this.target == null) {
      this.stop();
      return;
    }
    const finished = this.applyStep(this.target);
    if (finished) {
      this.stop();
      return;
    }
    this.schedule(delay);
  }
  schedule(delay) {
    if (this.isActive())
      return;
    this.timer = setTimeout(() => {
      this.timer = void 0;
      this.run(STEP_REPEAT_INTERVAL_MS);
    }, delay);
  }
  clearTimer() {
    if (this.timer != null) {
      clearTimeout(this.timer);
      this.timer = void 0;
    }
  }
  isActive() {
    return this.timer != null;
  }
};
var ScrollbarState = class {
  constructor() {
    this.min = 0;
    this.span = 1;
    this.thumbSpan = 1;
  }
  update(min, max, thumbSpan = this.thumbSpan) {
    const span = clamp(0, max - min, 1);
    this.span = span;
    this.thumbSpan = clamp(0, thumbSpan, 1);
    this.min = this.clampMin(min, span);
  }
  clampMin(min, span = this.span) {
    return clamp(0, min, 1 - span);
  }
  getThumbBounds(min = this.min, span = this.thumbSpan) {
    const start2 = this.clampMin(min, span);
    return { start: start2, end: start2 + span };
  }
  isWithinThumb(ratio2) {
    const { start: start2, end: end3 } = this.getThumbBounds();
    return ratio2 >= start2 && ratio2 <= end3;
  }
  getJumpRange(ratio2) {
    if (!this.canScroll())
      return;
    let min = this.clampMin(ratio2 - this.thumbSpan / 2, this.thumbSpan);
    min = this.clampMin(min);
    return { min, max: min + this.span };
  }
  getStepRange(ratio2) {
    if (!this.canScroll())
      return;
    const cursor = clamp(0, ratio2, 1);
    const { start: start2, end: end3 } = this.getThumbBounds();
    if (cursor >= start2 && cursor <= end3)
      return;
    const movingLeft = cursor < start2;
    const distance2 = movingLeft ? start2 - cursor : cursor - end3;
    const step = Math.min(this.span, distance2);
    const nextMin = this.clampMin(this.min + (movingLeft ? -step : step));
    return { min: nextMin, max: nextMin + this.span };
  }
  canScroll() {
    return this.span > 0 && this.span < 1;
  }
};
var ScrollbarDOMProxy = class {
  constructor(ctx, orientation, onChange, onHoverChange) {
    this.ctx = ctx;
    this.orientation = orientation;
    this.onChange = onChange;
    this.onHoverChange = onHoverChange;
    this.dragStartRatio = 0;
    this.interactionMode = "none";
    this.state = new ScrollbarState();
    this.repeater = new StepRepeater((target) => this.applyStepToward(target));
    this.container = ctx.proxyInteractionService.createProxyContainer({
      type: "group",
      domManagerId: `scrollbar-${orientation}`,
      classList: ["ag-charts-proxy-scrollbar", `ag-charts-proxy-scrollbar-${orientation}`],
      ariaLabel: void 0,
      role: "presentation"
    });
    const ariaLabelId = orientation === "horizontal" ? "ariaLabelScrollbarHorizontal" : "ariaLabelScrollbarVertical";
    this.slider = ctx.proxyInteractionService.createProxyElement({
      type: "slider",
      domIndex: 0,
      tabIndex: 0,
      ariaLabel: { id: ariaLabelId },
      role: "slider",
      parent: this.container,
      classList: ["ag-charts-proxy-scrollbar-slider"]
    });
    const element2 = this.slider.getElement();
    element2.ariaValueMin = "0";
    element2.ariaValueMax = "100";
    this.slider.step = SliderWidget3.STEP_HUNDRETH;
    this.slider.keyboardStep = SliderWidget3.STEP_ONE;
    this.slider.orientation = orientation;
    this.slider.setPreventsDefault(false);
    this.slider.addListener("change", () => this.onSliderChange());
    this.slider.addListener("keydown", (ev) => this.onSliderKeyDown(ev));
    this.slider.addListener("drag-start", (ev) => this.onDragStart(ev));
    this.slider.addListener("drag-move", (ev) => this.onDragMove(ev));
    this.slider.addListener("drag-end", (ev) => this.onDragEnd(ev));
    this.slider.addListener("mouseenter", (event) => this.handleHoverEvent(event));
    this.slider.addListener("mousemove", (event) => this.handleHoverEvent(event));
    this.slider.addListener("mouseleave", () => this.onMouseLeave());
    this.thumbFocus = ctx.proxyInteractionService.createProxyElement({
      type: "region",
      parent: this.container,
      classList: ["ag-charts-proxy-scrollbar-thumb-focus"],
      role: "presentation"
    });
    this.thumbFocus.setAriaHidden(true);
    this.thumbFocus.setPointerEvents("none");
  }
  destroy() {
    this.interactionBounds = void 0;
    this.repeater.stop();
    this.container.destroy();
  }
  updateBounds(bounds) {
    this.interactionBounds = void 0;
    this.container.setBounds(bounds);
    this.slider.setBounds({ x: 0, y: 0, width: bounds.width, height: bounds.height });
  }
  updateVisibility(visible) {
    this.container.setHidden(!visible);
  }
  updateMinMax(min, max, thumbSpan = this.state.thumbSpan, options) {
    this.state.update(min, max, thumbSpan);
    const aria = this.ctx.localeManager.t("ariaValuePanRange", {
      min: Math.round(min * 100) / 100,
      max: Math.round(max * 100) / 100
    });
    const element2 = this.slider.getElement();
    element2.ariaValueText = aria;
    const shouldUpdateSlider = !options?.skipSliderUpdate || Math.abs(this.slider.getValueRatio() - min) > 1e-9;
    if (shouldUpdateSlider) {
      this.slider.setValueRatio(min, { ariaValueText: aria });
    }
  }
  updateThumbBounds(thumb, track, cornerRadius) {
    const radius = Math.max(0, cornerRadius ?? 0);
    this.thumbFocus.getElement().style.borderRadius = `${radius}px`;
    this.thumbFocus.setBounds({
      x: thumb.x - track.x,
      y: thumb.y - track.y,
      width: thumb.width,
      height: thumb.height
    });
  }
  update(min, max, options) {
    this.onChange(min, max);
    this.updateMinMax(min, max, void 0, options);
  }
  onSliderChange() {
    const min = this.state.clampMin(this.slider.getValueRatio());
    const max = min + this.state.span;
    this.update(min, max, { skipSliderUpdate: true });
  }
  onSliderKeyDown(event) {
    const { code } = event.sourceEvent;
    const isVertical = this.orientation === "vertical";
    const decrement = isVertical && code === "ArrowUp" || !isVertical && code === "ArrowLeft";
    const increment = isVertical && code === "ArrowDown" || !isVertical && code === "ArrowRight";
    if (!decrement && !increment)
      return;
    event.sourceEvent.preventDefault();
    const element2 = this.slider.getElement();
    element2.step = this.slider.keyboardStep?.attributeValue ?? "1";
    if (decrement) {
      element2.stepDown();
    } else if (increment) {
      element2.stepUp();
    }
    this.onSliderChange();
  }
  onDragMove(event) {
    event.sourceEvent.preventDefault();
    if (this.interactionMode === "drag") {
      const { isHorizontal: isHorizontal2, size, start: start2 } = this.getInteractionBounds() ?? {};
      if (start2 == null || size == null)
        return;
      const delta5 = (isHorizontal2 ? event.originDeltaX : event.originDeltaY) / size;
      const min = this.state.clampMin(this.dragStartRatio + delta5);
      const max = min + this.state.span;
      this.update(min, max);
      return;
    }
    if (this.interactionMode !== "step")
      return;
    const pointer = this.getPointerInfo(event);
    if (pointer == null || !Number.isFinite(pointer.ratio))
      return;
    const { ratio: ratio2, inCrossBounds } = pointer;
    if (!inCrossBounds) {
      this.repeater.stop();
      return;
    }
    this.repeater.updateTarget(ratio2);
  }
  onDragEnd(event) {
    event.sourceEvent.preventDefault();
    this.interactionBounds = void 0;
    this.setInteraction("none");
    this.onHoverChange(false);
  }
  onDragStart(event) {
    event.sourceEvent.preventDefault();
    this.interactionBounds = void 0;
    const click = this.getClickInfo(event);
    if (!click?.inBounds)
      return;
    if (click.inThumb) {
      this.dragStartRatio = this.slider.getValueRatio();
      this.setInteraction("drag");
      return;
    }
    if (event.sourceEvent.shiftKey) {
      this.jumpTo(click.ratio);
      this.setInteraction("none");
      return;
    }
    this.beginStepRepeat(click.ratio);
  }
  onMouseLeave() {
    this.onHoverChange(false);
  }
  getClickInfo(event) {
    const ratio2 = this.getPointerRatio(event);
    if (ratio2 == null)
      return;
    const inBounds = ratio2 >= 0 && ratio2 <= 1;
    if (!inBounds)
      return { ratio: 0, inBounds: false, inThumb: false };
    return { ratio: ratio2, inBounds: true, inThumb: this.isWithinThumb(ratio2) };
  }
  getPointerRatio(event) {
    return this.getPointerInfo(event)?.ratio;
  }
  getPointerInfo(event) {
    if (event.device === "keyboard")
      return;
    const { isHorizontal: isHorizontal2, size, start: start2, crossStart, crossSize } = this.getInteractionBounds();
    const pos = isHorizontal2 ? event.clientX : event.clientY;
    const crossPos = isHorizontal2 ? event.clientY : event.clientX;
    const ratio2 = (pos - start2) / size;
    const inCrossBounds = crossPos >= crossStart && crossPos <= crossStart + crossSize;
    return { ratio: ratio2, inCrossBounds };
  }
  jumpTo(ratio2) {
    const next = this.state.getJumpRange(ratio2);
    if (!next)
      return;
    this.update(next.min, next.max);
  }
  applyStepToward(target) {
    const next = this.state.getStepRange(target);
    if (!next)
      return true;
    this.update(next.min, next.max);
    return false;
  }
  beginStepRepeat(ratio2) {
    this.setInteraction("step");
    this.repeater.start(ratio2);
  }
  setInteraction(mode) {
    this.interactionMode = mode;
    if (mode !== "step") {
      this.repeater.stop();
    }
  }
  getInteractionBounds() {
    if (this.interactionBounds) {
      return this.interactionBounds;
    }
    const { width: width2, height: height2, left, top } = this.container.getBoundingClientRect();
    const isHorizontal2 = this.orientation === "horizontal";
    const size = isHorizontal2 ? width2 : height2;
    const start2 = isHorizontal2 ? left : top;
    const crossStart = isHorizontal2 ? top : left;
    const crossSize = isHorizontal2 ? height2 : width2;
    this.interactionBounds = { isHorizontal: isHorizontal2, size, start: start2, crossStart, crossSize };
    return this.interactionBounds;
  }
  isWithinThumb(ratio2) {
    return this.state.isWithinThumb(ratio2);
  }
  handleHoverEvent(event) {
    if (this.interactionMode === "drag")
      return;
    const pointer = this.getPointerInfo(event);
    if (!pointer) {
      this.onHoverChange(false);
      return;
    }
    const hovered = this.isWithinThumb(pointer.ratio);
    this.onHoverChange(hovered);
  }
};

// packages/ag-charts-enterprise/src/features/scrollbar/scrollbarProperties.ts
var ScrollbarTrack = class extends ChangeDetectableProperties {
  constructor() {
    super(...arguments);
    this.enabled = false;
    this.fillOpacity = 1;
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.cornerRadius = 0;
    this.opacity = 1;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], ScrollbarTrack.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], ScrollbarTrack.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], ScrollbarTrack.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], ScrollbarTrack.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], ScrollbarTrack.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], ScrollbarTrack.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ScrollbarTrack.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ScrollbarTrack.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ScrollbarTrack.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ScrollbarTrack.prototype, "opacity", 2);
var ScrollbarThumbHoverStyle = class extends ChangeDetectableProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], ScrollbarThumbHoverStyle.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], ScrollbarThumbHoverStyle.prototype, "stroke", 2);
var ScrollbarThumb = class extends ScrollbarTrack {
  constructor() {
    super(...arguments);
    this.minSize = 20;
    this.hoverStyle = new ScrollbarThumbHoverStyle();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], ScrollbarThumb.prototype, "minSize", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ScrollbarThumb.prototype, "hoverStyle", 2);
var ScrollbarProperties = class extends ChangeDetectableProperties {
  constructor() {
    super(...arguments);
    this.enabled = false;
    this.thickness = 12;
    this.spacing = 4;
    this.tickSpacing = 0;
    this.placement = "outer";
    this.visible = "auto";
    this.track = new ScrollbarTrack();
    this.thumb = new ScrollbarThumb();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], ScrollbarProperties.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], ScrollbarProperties.prototype, "thickness", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], ScrollbarProperties.prototype, "spacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], ScrollbarProperties.prototype, "tickSpacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], ScrollbarProperties.prototype, "placement", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], ScrollbarProperties.prototype, "visible", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ScrollbarProperties.prototype, "track", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ScrollbarProperties.prototype, "thumb", 2);
var HorizontalScrollbarProperties = class extends ScrollbarProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], HorizontalScrollbarProperties.prototype, "position", 2);
var VerticalScrollbarProperties = class extends ScrollbarProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty,
  SceneChangeDetection()
], VerticalScrollbarProperties.prototype, "position", 2);

// packages/ag-charts-enterprise/src/features/scrollbar/scrollbar.ts
var { BBox: BBox21, Group: Group10, Rect: Rect7, LayoutElement: LayoutElement5, InteractionState: InteractionState6 } = module_support_exports;
var Scrollbar = class extends AbstractModuleInstance {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.track = new ScrollbarTrack();
    this.thumb = new ScrollbarThumb();
    this.horizontal = new HorizontalScrollbarProperties();
    this.vertical = new VerticalScrollbarProperties();
    this.state = {
      horizontal: this.createOrientationState("horizontal"),
      vertical: this.createOrientationState("vertical")
    };
    this.cleanup.register(
      ctx.scene.attachNode(this.state.horizontal.group),
      ctx.scene.attachNode(this.state.vertical.group),
      ctx.layoutManager.registerElement(LayoutElement5.Scrollbar, (e) => this.onLayoutStart(e)),
      ctx.eventsHub.on("layout:complete", (e) => this.onLayoutComplete(e)),
      ctx.eventsHub.on("zoom:change-complete", () => this.updateThumbs())
    );
  }
  createOrientationState(orientation) {
    const group = new Group10({ name: `scrollbar-${orientation}`, zIndex: 17 /* NAVIGATOR */ });
    const track = new Rect7();
    const thumb = new Rect7();
    group.append(track);
    group.append(thumb);
    const dom = new ScrollbarDOMProxy(
      this.ctx,
      orientation,
      (min, max) => this.handleUserChange(orientation, min, max),
      (hovered) => this.handleHoverChange(orientation, hovered)
    );
    const properties = this.resolveProperties(orientation);
    return {
      orientation,
      group,
      track,
      thumb,
      dom,
      properties,
      position: this.getDefaultPosition(orientation),
      positionHasAxis: false,
      hovered: false
    };
  }
  resolveProperties(orientation) {
    return orientation === "horizontal" ? this.horizontal : this.vertical;
  }
  getDefaultPosition(orientation) {
    return orientation === "horizontal" ? "bottom" : "left";
  }
  resolveAxis(orientation, configuredPosition) {
    const direction = orientation === "horizontal" ? "x" /* X */ : "y" /* Y */;
    const contexts = this.ctx.axisManager.getAxisContext(direction);
    if (contexts.length === 0) {
      return { position: this.getDefaultPosition(orientation), positionHasAxis: false };
    }
    if (configuredPosition == null) {
      const axis2 = contexts[0];
      return { axis: axis2, position: axis2.position ?? this.getDefaultPosition(orientation), positionHasAxis: true };
    }
    const axis = contexts.find((ctx) => ctx.position === configuredPosition);
    if (axis) {
      return { axis, position: configuredPosition, positionHasAxis: true };
    }
    return { axis: contexts[0], position: configuredPosition, positionHasAxis: false };
  }
  onLayoutStart({ scrollbars, layoutBox }) {
    for (const orientation of ["horizontal", "vertical"]) {
      const state = this.state[orientation];
      const properties = this.resolveProperties(orientation);
      const { min, max } = this.getZoomRange(state.orientation);
      const span = clamp(0, max - min, 1);
      const {
        axis: { axisId } = {},
        position,
        positionHasAxis
      } = this.resolveAxis(orientation, properties.position);
      state.properties = properties;
      state.axisId = axisId;
      state.position = position;
      state.positionHasAxis = positionHasAxis;
      const show = this.updateVisibility(state, span);
      if (!show || axisId == null)
        continue;
      const { thickness, spacing, placement, tickSpacing } = properties;
      if (positionHasAxis) {
        scrollbars[axisId] = {
          enabled: show,
          thickness,
          spacing,
          tickSpacing,
          placement
        };
      } else {
        layoutBox.shrink(spacing + thickness, position);
      }
      this.updateStyles(state);
    }
  }
  onLayoutComplete(event) {
    this.seriesRect = event.series.rect;
    for (const orientation of ["horizontal", "vertical"]) {
      const state = this.state[orientation];
      const {
        properties: { enabled, visible }
      } = state;
      if (!enabled || visible === "never") {
        continue;
      }
      const layoutRect = this.getLayoutRect(state, orientation, event);
      state.layoutRect = layoutRect;
      if (!layoutRect)
        continue;
      this.updateTrack(state, layoutRect);
      this.updateThumb(state, layoutRect);
    }
  }
  getLayoutRect(state, orientation, event) {
    const {
      properties: { thickness, spacing },
      position,
      positionHasAxis
    } = state;
    const axisLayout = state.axisId ? event.axes[state.axisId] : void 0;
    if (!axisLayout)
      return;
    const { x, y, width: width2, height: height2 } = event.series.rect;
    const isHorizontal2 = orientation === "horizontal";
    if (!positionHasAxis) {
      if (isHorizontal2) {
        const coord2 = position === "bottom" ? y + height2 + spacing : y - spacing - thickness;
        return new BBox21(x, coord2, width2, thickness);
      } else {
        const coord2 = position === "right" ? x + width2 + spacing : x - spacing - thickness;
        return new BBox21(coord2, y, thickness, height2);
      }
    }
    const { scrollbar: scrollbarLayout, translation } = axisLayout;
    if (!scrollbarLayout?.enabled)
      return;
    const coord = isHorizontal2 ? translation.y + scrollbarLayout.offset : translation.x + scrollbarLayout.offset;
    return isHorizontal2 ? new BBox21(x, coord, width2, thickness) : new BBox21(coord, y, thickness, height2);
  }
  updateStyles({ track, thumb, properties, hovered }) {
    track.setStyleProperties(properties.track);
    track.cornerRadius = properties.track.cornerRadius ?? 0;
    track.opacity = properties.track.opacity ?? 1;
    thumb.setStyleProperties(properties.thumb);
    thumb.cornerRadius = properties.thumb.cornerRadius ?? 0;
    thumb.opacity = properties.thumb.opacity ?? 1;
    const hoverStyle = properties.thumb.hoverStyle;
    thumb.fill = hovered ? hoverStyle?.fill ?? properties.thumb.fill : properties.thumb.fill;
    thumb.stroke = hovered ? hoverStyle?.stroke ?? properties.thumb.stroke : properties.thumb.stroke;
  }
  updateTrack(state, bounds) {
    state.track.x = bounds.x;
    state.track.y = bounds.y;
    state.track.width = bounds.width;
    state.track.height = bounds.height;
    state.dom.updateBounds(bounds);
  }
  updateThumb(state, track) {
    const { min, max } = this.getZoomRange(state.orientation);
    const span = clamp(0, max - min, 1);
    const show = this.updateVisibility(state, span);
    if (!show || track.width <= 0 || track.height <= 0) {
      return;
    }
    const minSize = state.properties.thumb.minSize ?? 0;
    let thumbSpan;
    if (state.orientation === "horizontal") {
      const thumbWidth = Math.min(Math.max(minSize, track.width * span), track.width);
      const start2 = clamp(track.x, track.x + track.width * min, track.x + track.width - thumbWidth);
      state.thumb.x = start2;
      state.thumb.y = track.y;
      state.thumb.width = thumbWidth;
      state.thumb.height = track.height;
      thumbSpan = clamp(0, thumbWidth / track.width, 1);
    } else {
      const thumbHeight = Math.min(Math.max(minSize, track.height * span), track.height);
      const start2 = clamp(track.y, track.y + track.height * min, track.y + track.height - thumbHeight);
      state.thumb.x = track.x;
      state.thumb.y = start2;
      state.thumb.width = track.width;
      state.thumb.height = thumbHeight;
      thumbSpan = clamp(0, thumbHeight / track.height, 1);
    }
    state.dom.updateThumbBounds(state.thumb, track, state.properties.thumb.cornerRadius);
    state.dom.updateMinMax(min, max, thumbSpan);
  }
  updateThumbs() {
    if (!this.seriesRect)
      return;
    for (const orientation of ["horizontal", "vertical"]) {
      const state = this.state[orientation];
      const layoutRect = state.layoutRect;
      if (!layoutRect || !state.properties.enabled || state.properties.visible === "never")
        continue;
      const trackBounds = orientation === "horizontal" ? new BBox21(this.seriesRect.x, layoutRect.y, this.seriesRect.width, state.properties.thickness) : new BBox21(layoutRect.x, this.seriesRect.y, state.properties.thickness, this.seriesRect.height);
      this.updateThumb(state, trackBounds);
    }
  }
  updateVisibility(state, span) {
    const show = state.properties.enabled && state.axisId != null && state.properties.visible !== "never" && (state.properties.visible === "always" || span < 1);
    state.group.visible = show;
    state.track.visible = show;
    state.thumb.visible = show;
    state.dom.updateVisibility(show);
    return show;
  }
  getZoomRange(orientation) {
    const zoom = this.ctx.zoomManager.getZoom();
    const isHorizontal2 = orientation === "horizontal";
    const range3 = isHorizontal2 ? zoom?.x : zoom?.y;
    if (!isHorizontal2 && range3 != null) {
      return {
        min: 1 - (range3.max ?? 1),
        max: 1 - (range3.min ?? 0)
      };
    }
    return {
      min: range3?.min ?? 0,
      max: range3?.max ?? 1
    };
  }
  handleUserChange(orientation, min, max) {
    if (!this.ctx.interactionManager.isState(InteractionState6.ZoomDraggable))
      return;
    const isHorizontal2 = orientation === "horizontal";
    if (!isHorizontal2) {
      [min, max] = [1 - max, 1 - min];
    }
    const zoom = isHorizontal2 ? { x: { min, max } } : { y: { min, max } };
    this.ctx.zoomManager.updateZoom(
      {
        source: "user-interaction",
        sourceDetail: "scrollbar"
      },
      zoom
    );
  }
  handleHoverChange(orientation, hovered) {
    const state = this.state[orientation];
    const nextHovered = hovered && state.group.visible;
    if (state.hovered === nextHovered)
      return;
    state.hovered = nextHovered;
    this.updateStyles(state);
    this.ctx.updateService.update(9 /* SCENE_RENDER */);
  }
  destroy() {
    super.destroy();
    this.state.horizontal.dom.destroy();
    this.state.vertical.dom.destroy();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], Scrollbar.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Scrollbar.prototype, "thickness", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Scrollbar.prototype, "spacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Scrollbar.prototype, "tickSpacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Scrollbar.prototype, "placement", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Scrollbar.prototype, "visible", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Scrollbar.prototype, "track", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Scrollbar.prototype, "thumb", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Scrollbar.prototype, "horizontal", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Scrollbar.prototype, "vertical", 2);

// packages/ag-charts-enterprise/src/features/scrollbar/scrollbarOptionsDefs.ts
var scrollbarTrackOptionsDef2 = {
  ...fillOptionsDef,
  ...strokeOptionsDef,
  ...lineDashOptionsDef,
  cornerRadius: positiveNumber,
  opacity: ratio
};
var scrollbarThumbOptionsDef2 = {
  ...scrollbarTrackOptionsDef2,
  minSize: positiveNumber,
  hoverStyle: {
    fill: fillOptionsDef.fill,
    stroke: strokeOptionsDef.stroke
  }
};
var scrollbarBaseOptionsDef2 = {
  enabled: boolean,
  thickness: positiveNumber,
  spacing: positiveNumber,
  tickSpacing: positiveNumber,
  visible: union("auto", "always", "never"),
  placement: union("outer", "inner"),
  track: scrollbarTrackOptionsDef2,
  thumb: scrollbarThumbOptionsDef2
};
var scrollbarHorizontalOrientationOptionsDef2 = {
  ...scrollbarBaseOptionsDef2,
  position: union("top", "bottom")
};
var scrollbarVerticalOrientationOptionsDef2 = {
  ...scrollbarBaseOptionsDef2,
  position: union("left", "right")
};
var scrollbarOptionsDef2 = {
  enabled: boolean,
  thickness: positiveNumber,
  spacing: positiveNumber,
  tickSpacing: positiveNumber,
  visible: union("auto", "always", "never"),
  placement: union("outer", "inner"),
  track: scrollbarTrackOptionsDef2,
  thumb: scrollbarThumbOptionsDef2,
  horizontal: scrollbarHorizontalOrientationOptionsDef2,
  vertical: scrollbarVerticalOrientationOptionsDef2
};

// packages/ag-charts-enterprise/src/features/scrollbar/scrollbarTheme.ts
var SCROLLBAR_ORIENTATION_THEME = {
  enabled: { $path: "../enabled" },
  thickness: { $path: "../thickness" },
  spacing: { $path: "../spacing" },
  tickSpacing: { $path: "../tickSpacing" },
  placement: { $path: "../placement" },
  visible: { $path: "../visible" },
  track: {
    fill: { $path: "../../track/fill" },
    stroke: { $path: "../../track/stroke" },
    fillOpacity: { $path: "../../track/fillOpacity" },
    strokeWidth: { $path: "../../track/strokeWidth" },
    lineDash: { $path: "../../track/lineDash" },
    lineDashOffset: { $path: "../../track/lineDashOffset" },
    opacity: { $path: "../../track/opacity" },
    cornerRadius: { $path: "../../track/cornerRadius" }
  },
  thumb: {
    fill: { $path: "../../thumb/fill" },
    stroke: { $path: "../../thumb/stroke" },
    fillOpacity: { $path: "../../thumb/fillOpacity" },
    strokeWidth: { $path: "../../thumb/strokeWidth" },
    lineDash: { $path: "../../thumb/lineDash" },
    lineDashOffset: { $path: "../../thumb/lineDashOffset" },
    opacity: { $path: "../../thumb/opacity" },
    cornerRadius: { $path: "../../thumb/cornerRadius" },
    minSize: { $path: "../../thumb/minSize" },
    hoverStyle: {
      fill: { $path: "../../../thumb/hoverStyle/fill" },
      stroke: { $path: "../../../thumb/hoverStyle/stroke" }
    }
  }
};
var SCROLLBAR_THEME = {
  enabled: false,
  thickness: 12,
  spacing: 16,
  tickSpacing: 0,
  placement: "outer",
  visible: "auto",
  track: {
    fill: { $foregroundBackgroundMix: 0.03 },
    stroke: { $foregroundBackgroundMix: 0.177 },
    strokeWidth: 1,
    lineDash: [0],
    lineDashOffset: 0,
    opacity: 1,
    cornerRadius: 6
  },
  thumb: {
    fill: { $foregroundBackgroundMix: 0.125 },
    stroke: { $foregroundBackgroundMix: 0.364 },
    strokeWidth: 1,
    lineDash: [0],
    lineDashOffset: 0,
    opacity: 1,
    cornerRadius: 6,
    minSize: 20,
    hoverStyle: {
      fill: { $mix: [{ $path: "../fill" }, { $ref: "foregroundColor" }, 0.075] },
      stroke: { $mix: [{ $path: "../stroke" }, { $ref: "foregroundColor" }, 0.075] }
    }
  },
  vertical: SCROLLBAR_ORIENTATION_THEME,
  horizontal: SCROLLBAR_ORIENTATION_THEME
};

// packages/ag-charts-enterprise/src/features/scrollbar/scrollbarModule.ts
var ScrollbarModule = {
  type: "plugin",
  name: "scrollbar",
  chartType: "cartesian",
  enterprise: true,
  version: VERSION,
  options: scrollbarOptionsDef2,
  themeTemplate: SCROLLBAR_THEME,
  create: (ctx) => new Scrollbar(ctx)
};

// packages/ag-charts-enterprise/src/features/status-bar/statusBar.ts
var { LayoutElement: LayoutElement6, Group: Group11, Label: Label11, Rect: Rect8, Text: Text4 } = module_support_exports;
var chartConfigurations = {
  ohlc: 2 /* Open */ | 4 /* Close */ | 8 /* Low */ | 16 /* High */ | 32 /* Volume */,
  candlestick: 2 /* Open */ | 4 /* Close */ | 8 /* Low */ | 16 /* High */ | 32 /* Volume */,
  "hollow-candlestick": 2 /* Open */ | 4 /* Close */ | 8 /* Low */ | 16 /* High */ | 32 /* Volume */,
  line: 64 /* UnlabelledClose */ | 32 /* Volume */,
  "step-line": 64 /* UnlabelledClose */ | 32 /* Volume */,
  hlc: 128 /* NeutralClose */ | 8 /* Low */ | 16 /* High */ | 32 /* Volume */,
  "high-low": 512 /* NeutralLow */ | 256 /* NeutralHigh */ | 32 /* Volume */
};
var itemIdMap = {
  up: "positive",
  down: "negative"
};
var neutralColorMap = {
  hlc: "altNeutral"
};
var StatusBarBackground = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.fill = "black";
    this.fillOpacity = 1;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], StatusBarBackground.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], StatusBarBackground.prototype, "fillOpacity", 2);
var StatusBar = class extends AbstractModuleInstance {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.enabled = false;
    this.openKey = void 0;
    this.highKey = void 0;
    this.lowKey = void 0;
    this.closeKey = void 0;
    this.volumeKey = void 0;
    this.title = new Label11();
    this.positive = new Label11();
    this.negative = new Label11();
    this.neutral = new Label11();
    this.altNeutral = new Label11();
    this.background = new StatusBarBackground();
    this.layoutStyle = "block";
    this.id = "status-bar";
    this.layer = new Group11({
      name: "StatusBar",
      zIndex: 14 /* STATUS_BAR */
    });
    this.labelGroup = this.layer.appendChild(new module_support_exports.TranslatableGroup());
    this.backgroundNode = this.labelGroup.appendChild(new Rect8());
    this.labels = [
      {
        label: "O",
        configuration: 2 /* Open */,
        title: this.labelGroup.appendChild(new Text4()),
        value: this.labelGroup.appendChild(new Text4()),
        id: "openValue",
        key: "openKey",
        domain: void 0,
        formatter: new Intl.NumberFormat("en-US", {
          minimumFractionDigits: 2,
          maximumFractionDigits: 2
        })
      },
      {
        label: "H",
        configuration: 16 /* High */,
        title: this.labelGroup.appendChild(new Text4()),
        value: this.labelGroup.appendChild(new Text4()),
        id: "highValue",
        key: "highKey",
        domain: void 0,
        formatter: new Intl.NumberFormat("en-US", {
          minimumFractionDigits: 2,
          maximumFractionDigits: 2
        })
      },
      {
        label: "H",
        configuration: 256 /* NeutralHigh */,
        title: this.labelGroup.appendChild(new Text4()),
        value: this.labelGroup.appendChild(new Text4()),
        style: "neutral",
        id: "highValue",
        key: "highKey",
        domain: void 0,
        formatter: new Intl.NumberFormat("en-US", {
          minimumFractionDigits: 2,
          maximumFractionDigits: 2
        })
      },
      {
        label: "L",
        configuration: 8 /* Low */,
        title: this.labelGroup.appendChild(new Text4()),
        value: this.labelGroup.appendChild(new Text4()),
        id: "lowValue",
        key: "lowKey",
        domain: void 0,
        formatter: new Intl.NumberFormat("en-US", {
          minimumFractionDigits: 2,
          maximumFractionDigits: 2
        })
      },
      {
        label: "L",
        configuration: 512 /* NeutralLow */,
        title: this.labelGroup.appendChild(new Text4()),
        value: this.labelGroup.appendChild(new Text4()),
        style: "neutral",
        id: "lowValue",
        key: "lowKey",
        domain: void 0,
        formatter: new Intl.NumberFormat("en-US", {
          minimumFractionDigits: 2,
          maximumFractionDigits: 2
        })
      },
      {
        label: "C",
        configuration: 4 /* Close */,
        title: this.labelGroup.appendChild(new Text4()),
        value: this.labelGroup.appendChild(new Text4()),
        id: "closeValue",
        key: "closeKey",
        domain: void 0,
        formatter: new Intl.NumberFormat("en-US", {
          minimumFractionDigits: 2,
          maximumFractionDigits: 2
        })
      },
      {
        label: "C",
        configuration: 128 /* NeutralClose */,
        title: this.labelGroup.appendChild(new Text4()),
        value: this.labelGroup.appendChild(new Text4()),
        id: "closeValue",
        key: "closeKey",
        style: "neutral",
        domain: void 0,
        formatter: new Intl.NumberFormat("en-US", {
          minimumFractionDigits: 2,
          maximumFractionDigits: 2
        })
      },
      {
        label: "",
        configuration: 64 /* UnlabelledClose */,
        title: this.labelGroup.appendChild(new Text4()),
        value: this.labelGroup.appendChild(new Text4()),
        style: "neutral",
        id: "closeValue",
        key: "closeKey",
        domain: void 0,
        formatter: new Intl.NumberFormat("en-US", {
          notation: "compact",
          minimumFractionDigits: 2,
          maximumFractionDigits: 2
        })
      },
      {
        label: "Vol",
        configuration: 32 /* Volume */,
        title: this.labelGroup.appendChild(new Text4()),
        value: this.labelGroup.appendChild(new Text4()),
        id: "volumeValue",
        key: "volumeKey",
        domain: void 0,
        formatter: new Intl.NumberFormat("en-US", {
          notation: "compact",
          minimumFractionDigits: 2,
          maximumFractionDigits: 2
        })
      }
    ];
    this.highlightManager = ctx.highlightManager;
    this.labelGroup.visible = false;
    this.cleanup.register(
      ctx.scene.attachNode(this.layer),
      ctx.layoutManager.registerElement(LayoutElement6.Overlay, (e) => this.startPerformLayout(e)),
      ctx.eventsHub.on("layout:complete", (e) => this.onLayoutComplete(e)),
      ctx.eventsHub.on("highlight:change", () => this.updateHighlight()),
      ctx.eventsHub.on("data:update", (data) => {
        this.chartData = data;
      })
    );
  }
  updateDomainsFromSeries() {
    if (!this.enabled)
      return;
    const series = this.ctx.chartService.series;
    if (series.length === 0)
      return;
    let priceDomain;
    let volumeDomain;
    for (const s of series) {
      const domainResult = s.getDomain("y" /* Y */);
      const yDomain = domainResult?.domain;
      if (!Array.isArray(yDomain) || yDomain.length < 2)
        continue;
      if (s.type === "bar") {
        volumeDomain = [yDomain[0], yDomain.at(-1)];
      } else {
        priceDomain = [yDomain[0], yDomain.at(-1)];
      }
    }
    for (const label of this.labels) {
      const key = this[label.key];
      if (key == null) {
        label.domain = void 0;
        continue;
      }
      label.domain = label.key === "volumeKey" ? volumeDomain : priceDomain;
    }
  }
  startPerformLayout({ layoutBox }) {
    this.labelGroup.translationX = 0;
    this.labelGroup.translationY = 0;
    if (!this.enabled) {
      this.labelGroup.visible = false;
      return;
    }
    this.updateDomainsFromSeries();
    const innerSpacing = 4;
    const outerSpacing = 12;
    const spacingAbove = 0;
    const spacingBelow = 8;
    this.labelGroup.translationY = layoutBox.y + spacingAbove;
    const maxFontSize = Math.max(this.title.fontSize, this.positive.fontSize, this.negative.fontSize);
    const lineHeight = calcLineHeight(maxFontSize);
    const labelConfigurations = chartConfigurations[this.getChartType()] ?? 0;
    let left = 0;
    let offsetTop;
    let textVAlign = "alphabetic";
    if (this.layoutStyle === "block") {
      layoutBox.shrink(spacingAbove + lineHeight + spacingBelow, "top");
      offsetTop = maxFontSize + (lineHeight - maxFontSize) / 2;
    } else {
      const { title } = this.ctx.chartService;
      textVAlign = "top";
      offsetTop = spacingAbove + title.padding;
      if (title.enabled) {
        const titleBox = title.node.getBBox();
        left = titleBox.x + titleBox.width + outerSpacing;
      } else {
        left = title.padding;
      }
    }
    for (const { label, configuration, title, value, domain, formatter: formatter2 } of this.labels) {
      if (domain == null || (labelConfigurations & configuration) === 0) {
        title.visible = false;
        value.visible = false;
        continue;
      }
      const positiveTextMeasurer = cachedTextMeasurer(this.positive);
      const negativeTextMeasurer = cachedTextMeasurer(this.negative);
      const maxValueWidth = Math.max(
        positiveTextMeasurer.textWidth(formatter2.format(domain[0])),
        positiveTextMeasurer.textWidth(formatter2.format(domain[1])),
        negativeTextMeasurer.textWidth(formatter2.format(domain[0])),
        negativeTextMeasurer.textWidth(formatter2.format(domain[1]))
      );
      title.visible = true;
      value.visible = true;
      const titleMetrics = cachedTextMeasurer(this.title).measureLines(label);
      title.setFont(this.title);
      title.fill = this.title.color;
      title.text = label;
      title.textBaseline = textVAlign;
      title.y = offsetTop;
      title.x = left;
      left += titleMetrics.width + innerSpacing;
      value.textBaseline = textVAlign;
      value.y = offsetTop;
      value.x = left;
      left += maxValueWidth + outerSpacing;
    }
    this.backgroundNode.x = 0;
    this.backgroundNode.y = 0;
    this.backgroundNode.width = left - outerSpacing;
    this.backgroundNode.height = lineHeight + spacingAbove + spacingBelow;
    this.backgroundNode.fill = this.background.fill;
    this.backgroundNode.fillOpacity = this.background.fillOpacity;
  }
  onLayoutComplete(opts) {
    this.labelGroup.translationX = opts.series.rect.x;
    this.updateHighlight();
  }
  updateHighlight() {
    if (!this.enabled)
      return;
    const activeHighlight = this.highlightManager.getActiveHighlight();
    const datum = activeHighlight?.datum ?? this.chartData?.data?.at(-1);
    if (datum == null) {
      this.labelGroup.visible = false;
      return;
    }
    this.labelGroup.visible = true;
    const itemId = activeHighlight?.itemId;
    let baseStyle = itemId == null ? void 0 : itemIdMap[itemId];
    if (baseStyle == null && this.openKey != null && this.closeKey != null) {
      if (datum[this.openKey] < datum[this.closeKey]) {
        baseStyle = "positive";
      } else {
        baseStyle = "negative";
      }
    }
    for (const { domain, value, key, formatter: formatter2, style: style2 } of this.labels) {
      if (domain == null)
        continue;
      let labelStyle = style2 ?? baseStyle ?? "neutral";
      if (labelStyle === "neutral") {
        labelStyle = neutralColorMap[this.getChartType()] ?? labelStyle;
      }
      const datumKey = this[key];
      const datumValue = datumKey == null ? void 0 : datum?.[datumKey];
      value.setFont(this[labelStyle]);
      value.fill = this[labelStyle].color;
      value.text = typeof datumValue === "number" ? formatter2.format(datumValue) : "";
    }
  }
  getChartType() {
    let chartType = this.ctx.chartService.publicApi?.getOptions()?.chartType;
    if (chartType == null || chartConfigurations[chartType] == null) {
      chartType = "candlestick";
    }
    return chartType;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], StatusBar.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], StatusBar.prototype, "openKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], StatusBar.prototype, "highKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], StatusBar.prototype, "lowKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], StatusBar.prototype, "closeKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], StatusBar.prototype, "volumeKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], StatusBar.prototype, "title", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], StatusBar.prototype, "positive", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], StatusBar.prototype, "negative", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], StatusBar.prototype, "neutral", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], StatusBar.prototype, "altNeutral", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], StatusBar.prototype, "background", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], StatusBar.prototype, "layoutStyle", 2);

// packages/ag-charts-enterprise/src/features/status-bar/statusBarModule.ts
var StatusBarModule = {
  type: "plugin",
  name: "statusBar",
  chartType: "cartesian",
  enterprise: true,
  version: VERSION,
  themeTemplate: {
    enabled: false,
    layoutStyle: DEFAULT_CAPTION_LAYOUT_STYLE,
    title: {
      color: { $ref: "textColor" },
      fontFamily: { $ref: "fontFamily" },
      fontSize: { $ref: "fontSize" },
      fontWeight: { $ref: "fontWeight" }
    },
    positive: {
      color: { $palette: "up.stroke" },
      fontFamily: { $ref: "fontFamily" },
      fontSize: { $ref: "fontSize" },
      fontWeight: { $ref: "fontWeight" }
    },
    negative: {
      color: { $palette: "down.stroke" },
      fontFamily: { $ref: "fontFamily" },
      fontSize: { $ref: "fontSize" },
      fontWeight: { $ref: "fontWeight" }
    },
    neutral: {
      color: { $palette: "neutral.stroke" },
      fontFamily: { $ref: "fontFamily" },
      fontSize: { $ref: "fontSize" },
      fontWeight: { $ref: "fontWeight" }
    },
    background: {
      fill: { $ref: "chartBackgroundColor" },
      fillOpacity: 0.5
    },
    altNeutral: {
      color: "gray",
      fontFamily: { $ref: "fontFamily" },
      fontSize: { $ref: "fontSize" },
      fontWeight: { $ref: "fontWeight" }
    }
  },
  create: (ctx) => new StatusBar(ctx)
};

// packages/ag-charts-enterprise/src/features/sync/chartSync.ts
var { CartesianAxis: CartesianAxis2, ContinuousScale: ContinuousScale4, TimeScale: TimeScale2, UnitTimeScale: UnitTimeScale2, TooltipManager: TooltipManager2 } = module_support_exports;
var debug5 = debugLogger_exports.create("sync");
function getDirectionKeys(series, primary, secondary) {
  const primaryKeys = series.getKeys(primary);
  const secondaryKeys = series.getKeys(secondary);
  if (series.shouldFlipXY?.()) {
    return [secondaryKeys, primaryKeys];
  }
  return [primaryKeys, secondaryKeys];
}
function syncedDirections(axes = "x") {
  switch (axes) {
    case "x":
      return ["x" /* X */];
    case "y":
      return ["y" /* Y */];
    case "xy":
      return ["x" /* X */, "y" /* Y */];
  }
}
function domainChanged(scale2, a, b) {
  if (TimeScale2.is(scale2) || UnitTimeScale2.is(scale2)) {
    return !arraysEqual(
      a.map((x) => x?.valueOf()),
      b.map((x) => x?.valueOf())
    );
  } else {
    return !arraysEqual(a, b);
  }
}
var ChartSync = class extends BaseProperties {
  constructor(moduleContext) {
    super();
    this.moduleContext = moduleContext;
    this.enabled = false;
    this.axes = "x";
    this.nodeInteraction = true;
    this.zoom = true;
    this.domainMode = "id";
    this.domainSync = new AsyncAwaitQueue();
  }
  updateSiblings(groupId) {
    const { syncManager } = this.moduleContext;
    for (const chart of syncManager.getGroupSiblings(groupId ?? this.groupId)) {
      debug5("ChartSync.updateSiblings()", chart.id, chart);
      this.updateChart(chart);
    }
  }
  updateChart(chart, updateType = 3 /* PROCESS_DOMAIN */) {
    debug5("ChartSync.updateChart()", chart.id, ChartUpdateType[updateType], chart);
    if (updateType === 3 /* PROCESS_DOMAIN */) {
      chart.ctx.updateService.update(updateType, { forceNodeDataRefresh: true });
    } else {
      chart.ctx.updateService.update(updateType);
    }
  }
  enabledZoomSync() {
    const { eventsHub } = this.moduleContext;
    this.disableZoomSync?.();
    this.disableZoomSync = eventsHub.on("zoom:change-complete", (e) => this.onZoom(e));
  }
  onZoom(e) {
    const { syncManager } = this.moduleContext;
    for (const chart of syncManager.getGroupSiblings(this.groupId)) {
      const syncModule = chart.modulesManager.getModule("sync");
      if (!syncModule?.zoom)
        continue;
      const zoomModule = chart.modulesManager.getModule("zoom");
      if (!zoomModule)
        continue;
      const zoom = this.prepareZoomUpdate();
      if (e.source !== "sync") {
        debug5("ChartsSyncManager.enabledZoomSync()", chart.id, zoom);
        zoomModule.updateSyncZoom(zoom);
      }
    }
  }
  enabledNodeInteractionSync() {
    this.disableNodeInteractionSync?.();
    const offHighlightChange = this.moduleContext.eventsHub.on(
      "highlight:change",
      this.onHighlightChange.bind(this)
    );
    const offActiveChangeListener = this.moduleContext.eventsHub.on(
      "active:load-memento",
      this.onActiveLoadMemento.bind(this)
    );
    this.disableNodeInteractionSync = () => {
      offHighlightChange();
      offActiveChangeListener();
    };
  }
  onHighlightChange(event) {
    const { syncManager } = this.moduleContext;
    if (event.callerId.endsWith("-sync"))
      return;
    debug5("ChartSync.onHighlightChange()", event);
    const series = event.currentHighlight?.series;
    const [mainDirection] = syncedDirections(this.axes);
    const secondaryDirection = mainDirection === "x" /* X */ ? "y" /* Y */ : "x" /* X */;
    const [primaryKeys, secondaryKeys] = series ? getDirectionKeys(series, mainDirection, secondaryDirection) : [];
    const datum = readDatum(event.currentHighlight);
    let eventValue = primaryKeys?.[0] ? datum?.[primaryKeys[0]] : void 0;
    let valueIsDate = false;
    if (isDate(eventValue)) {
      valueIsDate = true;
      eventValue = eventValue.getTime();
    }
    if (!event.currentHighlight?.datum) {
      for (const chart of syncManager.getGroupSiblings(this.groupId)) {
        const syncModule = chart.modulesManager.getModule("sync");
        if (!syncModule?.nodeInteraction)
          continue;
        chart.ctx.highlightManager.updateHighlight(`${chart.id}-sync`, void 0, true);
        chart.ctx.tooltipManager.removeTooltip(`${chart.id}-sync`, void 0, true);
      }
      return;
    }
    const useSecondaryDirectionKey = syncManager.getGroupSyncMode(this.groupId) === "multi-series";
    this.findMatchingHighlightNodes(
      mainDirection,
      secondaryDirection,
      useSecondaryDirectionKey ? secondaryKeys : [],
      valueIsDate,
      eventValue,
      event
    );
  }
  onActiveLoadMemento(event) {
    const { activeItem, chartId } = event;
    if (activeItem === void 0) {
      this.moduleContext.highlightManager.updateHighlight(`${chartId}-sync`, void 0, false);
      this.moduleContext.tooltipManager.removeTooltip(`${chartId}-sync`, void 0, false);
      for (const chart of this.moduleContext.syncManager.getGroupSiblings(this.groupId)) {
        chart.onSyncActiveClear();
      }
    }
  }
  findMatchingHighlightNodes(primaryDirection, secondaryDirection, secondaryKeys, valueIsDate, eventValue, event) {
    const { syncManager } = this.moduleContext;
    debug5("ChartSync.findMatchingHighlightNodes()", {
      mainDirection: primaryDirection,
      secondaryKeys
    });
    for (const chart of syncManager.getGroupSiblings(this.groupId)) {
      const syncModule = chart.modulesManager.getModule("sync");
      if (!syncModule?.nodeInteraction)
        continue;
      let dispatched = false;
      for (const axis of chart.axes) {
        if (!CartesianAxis2.is(axis) || axis.direction !== primaryDirection)
          continue;
        const matchingNodes = chart.series.filter((s) => {
          if (!s.visible)
            return false;
          if (secondaryKeys.length > 0) {
            const [, seriesKeys] = getDirectionKeys(s, primaryDirection, secondaryDirection);
            return secondaryKeys.every((key) => seriesKeys.includes(key));
          }
          return true;
        }).map(this.findMatchingNodes(axis, primaryDirection, valueIsDate, eventValue)).filter(isDefined);
        if (matchingNodes.length === 1 && matchingNodes[0]?.nodeDatum !== chart.ctx.highlightManager.getActiveHighlight()) {
          this.dispatchHighlightUpdate(chart, matchingNodes[0].nodeDatum);
          dispatched = true;
          break;
        }
      }
      if (!dispatched) {
        debug5("ChartSync.findMatchingHighlightNodes() - no matching nodes", chart.id, event);
        this.dispatchHighlightUpdate(chart);
      }
    }
  }
  findMatchingNodes(axis, mainDirection, valueIsDate, eventValue) {
    return (series) => {
      const seriesKeyAxis = series.getKeyAxis(axis.direction);
      if (seriesKeyAxis !== axis.id)
        return;
      const nodeData = series.contextNodeData?.nodeData ?? [];
      if (!nodeData?.length)
        return;
      const firstNode = nodeData[0];
      const mainDirectionKey = `${mainDirection}Key`;
      if (!isObjectWithStringProperty(firstNode, mainDirectionKey))
        return;
      const valueKey = firstNode[mainDirectionKey];
      const nodeDatum = nodeData.find((datum) => {
        const nodeValue = datum.datum[valueKey];
        return valueIsDate ? nodeValue.getTime() === eventValue : nodeValue === eventValue;
      });
      return nodeDatum ? { series, nodeDatum } : null;
    };
  }
  dispatchHighlightUpdate(chart, nodeDatum) {
    debug5("ChartSync.dispatchHighlightUpdate()", chart.id, nodeDatum);
    const delayed = nodeDatum == null;
    chart.ctx.highlightManager.updateHighlight(`${chart.id}-sync`, nodeDatum, delayed);
    const tooltipEnabled = nodeDatum?.series.tooltipEnabled ?? chart.tooltip.enabled;
    if (nodeDatum && tooltipEnabled) {
      const bbox = chart.seriesAreaBoundingBox;
      const canvasX = bbox.x + (nodeDatum.midPoint?.x ?? nodeDatum.point?.x ?? 0);
      const canvasY = bbox.y + (nodeDatum.midPoint?.y ?? nodeDatum.point?.y ?? 0);
      const tooltipMeta = TooltipManager2.makeTooltipMeta(
        { type: "pointermove", canvasX, canvasY },
        nodeDatum.series,
        nodeDatum,
        void 0
      );
      chart.ctx.tooltipManager.updateTooltip(
        `${chart.id}-sync`,
        tooltipMeta,
        chart.getTooltipContent(nodeDatum.series, nodeDatum.datumIndex, nodeDatum, "tooltip")
      );
    } else {
      chart.ctx.tooltipManager.removeTooltip(`${chart.id}-sync`, void 0, true);
    }
    this.updateChart(chart, 7 /* SERIES_UPDATE */);
  }
  async getSyncedDomain(axis) {
    if (!CartesianAxis2.is(axis) || this.axes !== "xy" && this.axes !== axis.direction) {
      return;
    }
    const { groupState, directionDomains, idDomains, positionDomains } = this.updateDomainState(axis);
    this.validateAxis(axis, groupState);
    await this.waitForDomainsToBeReady();
    if (this.domainMode === "position") {
      return this.calculateDerivedDomain(axis, positionDomains);
    }
    if (this.domainMode === "direction") {
      return this.calculateDerivedDomain(axis, directionDomains);
    }
    return this.calculateDerivedDomain(axis, idDomains);
  }
  updateDomainState(axis) {
    var _a, _b, _c, _d, _e;
    const { syncManager } = this.moduleContext;
    const chartId = syncManager.getChart().id;
    const axisId = axis.id;
    const groupState = syncManager.getGroupState(this.groupId);
    if (!groupState)
      throw new Error("AG Charts - no GroupState for groupId: " + this.groupId);
    const domainsByDirection = groupState.domains ?? (groupState.domains = {});
    const directionDomains = domainsByDirection[_a = axis.direction] ?? (domainsByDirection[_a] = { derived: [], sources: {}, dirty: true });
    const chartDirectionDomains = (_b = directionDomains.sources)[chartId] ?? (_b[chartId] = {});
    chartDirectionDomains[axisId] = axis.dataDomain.domain;
    directionDomains.dirty = true;
    const domainsById = groupState.domainsById ?? (groupState.domainsById = {});
    const idDomains = domainsById[axisId] ?? (domainsById[axisId] = { derived: [], sources: {}, dirty: true });
    const chartIdDomains = (_c = idDomains.sources)[chartId] ?? (_c[chartId] = {});
    chartIdDomains[axisId] = axis.dataDomain.domain;
    idDomains.dirty = true;
    const domainsByPosition = groupState.domainsByPosition ?? (groupState.domainsByPosition = {});
    const positionDomains = domainsByPosition[_d = axis.position] ?? (domainsByPosition[_d] = { derived: [], sources: {}, dirty: true });
    const chartPositionDomains = (_e = positionDomains.sources)[chartId] ?? (_e[chartId] = {});
    chartPositionDomains[axisId] = axis.dataDomain.domain;
    positionDomains.dirty = true;
    return { groupState, directionDomains, idDomains, positionDomains };
  }
  validateAxis(axis, groupState) {
    const multiSeries = this.moduleContext.syncManager.getGroupSyncMode(this.groupId) === "multi-series";
    if (!syncedDirections(this.axes).includes(axis.direction))
      return;
    if (multiSeries) {
      this.validateMultiSeries(axis, groupState);
    } else {
      this.validateSingleSeries(axis, groupState);
    }
  }
  validateMultiSeries(axis, groupState) {
    const { min, max, nice, reverse } = axis;
    const matchingKeys = new Set(axis.boundSeries.flatMap((s) => s.getKeys(axis.direction)));
    for (const member of groupState.members) {
      const { axes, modulesManager } = member;
      const syncModule = modulesManager.getModule("sync");
      const memberSyncDirections = syncedDirections(syncModule?.axes);
      const keyMatchedAxes = axes.filter((a) => memberSyncDirections.includes(a.direction)).filter((a) => a.boundSeries.some((s) => s.getKeys(a.direction).some((k) => matchingKeys.has(k))));
      if (keyMatchedAxes.length === 0)
        continue;
      const [firstAxis] = keyMatchedAxes;
      if (firstAxis.min !== min || firstAxis.max !== max || firstAxis.nice !== nice || firstAxis.reverse !== reverse) {
        logger_exports.warnOnce(
          "To allow synchronization, ensure that all synchronized axes with matching keys have matching min, max, nice, and reverse properties."
        );
        this.enabled = false;
        return;
      }
    }
  }
  validateSingleSeries(axis, groupState) {
    const members = groupState.members;
    const [{ axes: syncAxes }] = members;
    const { direction, min, max, nice, reverse } = axis;
    for (const nextAxis of syncAxes) {
      if (direction !== nextAxis.direction)
        continue;
      if (nice !== nextAxis.nice || reverse !== nextAxis.reverse || min !== nextAxis.min && (isFiniteNumber(min) || isFiniteNumber(nextAxis.min)) || max !== nextAxis.max && (isFiniteNumber(max) || isFiniteNumber(nextAxis.max))) {
        logger_exports.warnOnce(
          "To allow synchronization, ensure that all charts have matching min, max, nice, and reverse properties on the synchronized axes."
        );
        this.enabled = false;
        return;
      }
    }
  }
  calculateDerivedDomain(axis, domains) {
    if (!domains.dirty)
      return domains.derived;
    let previousDerived = domains.derived;
    const newDerivedBySource = Object.values(domains.sources).map((d) => Object.values(d));
    let newDerived;
    if (ContinuousScale4.is(axis.scale)) {
      newDerived = newDerivedBySource.flat(2);
    } else {
      newDerived = newDerivedBySource.flat().toSorted((a, b) => a.length > b.length ? -1 : 1).flat();
    }
    domains.derived = unique(newDerived);
    if (ContinuousScale4.is(axis.scale)) {
      previousDerived = findMinMax(previousDerived);
      domains.derived = findMinMax(domains.derived);
    }
    domains.dirty = false;
    if (domainChanged(axis.scale, previousDerived, domains.derived)) {
      debug5(axis.id, "updated", { before: previousDerived, after: domains.derived });
      this.updateSiblings();
    }
    return domains.derived;
  }
  removeAxis(axis) {
    if (!CartesianAxis2.is(axis) || this.axes !== "xy" && this.axes !== axis.direction) {
      return;
    }
    const { syncManager } = this.moduleContext;
    const syncGroup = syncManager.getGroupState(this.groupId);
    const chartId = syncManager.getChart().id;
    const axisId = axis.id;
    delete syncGroup?.domains?.[axis.direction]?.sources?.[chartId]?.[axisId];
    delete syncGroup?.domainsByPosition?.[axis.position]?.sources?.[chartId]?.[axisId];
    delete syncGroup?.domainsById?.[axisId]?.sources?.[chartId]?.[axisId];
  }
  async waitForDomainsToBeReady() {
    const { syncManager } = this.moduleContext;
    let count = 0;
    while (syncManager.getGroupMembers(this.groupId).some((c) => c.syncStatus === "init")) {
      debug5("ChartSync.waitForDomainsToBeReady() - waiting for all domains to be calculated", this.groupId);
      await this.domainSync.waitForCompletion();
      count++;
    }
    if (count > 0) {
      debug5("ChartSync.waitForDomainsToBeReady() - waited for", count, "iterations");
    }
    this.domainSync.notify();
  }
  prepareZoomUpdate() {
    const { zoomManager } = this.moduleContext;
    const zoom = zoomManager.getZoom();
    if (this.axes === "x") {
      delete zoom?.y;
    } else if (this.axes === "y") {
      delete zoom?.x;
    }
    return definedZoomState(zoom);
  }
  onEnabledChange() {
    const { syncManager, highlightManager } = this.moduleContext;
    if (this.enabled) {
      syncManager.subscribe(this.groupId);
      highlightManager.unhighlightDelay = 0;
    } else {
      syncManager.unsubscribe(this.groupId);
      highlightManager.unhighlightDelay = 100;
    }
    this.updateSiblings();
    this.onNodeInteractionChange();
    this.onZoomChange();
  }
  onGroupIdChange(newValue, oldValue) {
    if (!this.enabled || newValue === oldValue)
      return;
    const { syncManager } = this.moduleContext;
    syncManager.unsubscribe(oldValue);
    syncManager.subscribe(newValue);
    this.updateSiblings(oldValue);
    this.updateSiblings(newValue);
  }
  onAxesChange() {
    if (!this.enabled)
      return;
    const { syncManager } = this.moduleContext;
    this.updateChart(syncManager.getChart());
  }
  onNodeInteractionChange() {
    if (this.enabled && this.nodeInteraction) {
      this.enabledNodeInteractionSync();
    } else {
      this.disableNodeInteractionSync?.();
    }
  }
  onZoomChange() {
    if (this.enabled && this.zoom) {
      this.enabledZoomSync();
    } else {
      this.disableZoomSync?.();
    }
  }
  destroy() {
    const { syncManager } = this.moduleContext;
    syncManager.unsubscribe(this.groupId);
    this.updateSiblings();
    this.disableZoomSync?.();
  }
};
ChartSync.className = "Sync";
__decorateClass([
  addFakeTransformToInstanceProperty,
  ObserveChanges((target) => target.onEnabledChange())
], ChartSync.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ObserveChanges((target, newValue, oldValue) => target.onGroupIdChange(newValue, oldValue))
], ChartSync.prototype, "groupId", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ObserveChanges((target) => target.onAxesChange())
], ChartSync.prototype, "axes", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ObserveChanges((target) => target.onNodeInteractionChange())
], ChartSync.prototype, "nodeInteraction", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ObserveChanges((target) => target.onZoomChange())
], ChartSync.prototype, "zoom", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ObserveChanges((target) => target.onAxesChange())
], ChartSync.prototype, "domainMode", 2);

// packages/ag-charts-enterprise/src/features/sync/syncModule.ts
var SyncModule = {
  type: "plugin",
  name: "sync",
  chartType: "cartesian",
  enterprise: true,
  version: VERSION,
  options: {
    enabled: boolean,
    groupId: string,
    axes: union("x", "y", "xy"),
    nodeInteraction: boolean,
    zoom: boolean
  },
  themeTemplate: { enabled: false },
  create: (ctx) => new ChartSync(ctx)
};

// packages/ag-charts-enterprise/src/features/zoom/scenes/zoomRect.ts
var VALID_COLOR = "#2196f3";
var INVALID_COLOR = "#8a8a8a";
var ZoomRect = class extends module_support_exports.Rect {
  constructor() {
    super();
    this.fill = VALID_COLOR;
    this.fillOpacity = 0.2;
    this.zIndex = 5 /* ZOOM_SELECTION */;
  }
  updateValid() {
    this.fill = VALID_COLOR;
  }
  updateInvalid() {
    this.fill = INVALID_COLOR;
  }
};
ZoomRect.className = "ZoomRect";

// packages/ag-charts-enterprise/src/features/zoom/zoomAutoScale.ts
var ZoomAutoScalingProperties = class extends BaseProperties {
  constructor() {
    super();
    this.enabled = false;
    this.padding = 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ZoomAutoScalingProperties.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ZoomAutoScalingProperties.prototype, "padding", 2);
var ZoomAutoScaler = class {
  constructor(properties, zoomManager, deps, eventsHub, eventsCleanup) {
    this.properties = properties;
    this.zoomManager = zoomManager;
    this.deps = deps;
    this.manuallyAdjusted = false;
    eventsCleanup.register(
      eventsHub.on("zoom:save-memento", (e) => this.onSaveMemento(e)),
      eventsHub.on("zoom:load-memento", (e) => this.onLoadMemento(e)),
      eventsHub.on("zoom:change-request", (e) => this.onChangeRequest(e))
    );
  }
  get enabled() {
    return this.deps.enabled && this.properties.enabled && !this.manuallyAdjusted;
  }
  onManualAdjustment(direction) {
    if (direction === "y" /* Y */) {
      this.manuallyAdjusted = true;
    }
  }
  onChangeRequest(event) {
    const hasYAxisChange = this.hasYAxisChange(event);
    if (event.sourceDetail === "scrollbar" && hasYAxisChange) {
      this.manuallyAdjusted = true;
    }
    if (event.isReset && hasYAxisChange) {
      this.manuallyAdjusted = false;
    }
    if (this.enabled) {
      const constrainedZoom = this.autoScaleYZoom(event.state);
      if (constrainedZoom) {
        event.constrainChanges(constrainedZoom);
      }
    }
  }
  hasYAxisChange(event) {
    for (const id of event.changedAxes) {
      if (event.state[id]?.direction === "y" /* Y */) {
        return true;
      }
    }
    return false;
  }
  onSaveMemento(event) {
    event.memento.autoScaledAxes = this.enabled ? ["y"] : void 0;
  }
  onLoadMemento(event) {
    const { zoom, memento, navigatorModule, zoomModule } = event;
    if (!navigatorModule || zoomModule) {
      let yAutoScale = memento?.autoScaledAxes?.includes("y");
      if (memento?.rangeY) {
        yAutoScale ?? (yAutoScale = false);
        zoom.y = this.zoomManager.rangeToRatioDirection("y" /* Y */, memento.rangeY) ?? {
          min: 0,
          max: 1
        };
      } else if (memento?.ratioY) {
        yAutoScale ?? (yAutoScale = false);
        zoom.y = {
          min: memento.ratioY.start ?? 0,
          max: memento.ratioY.end ?? 1
        };
      } else {
        yAutoScale ?? (yAutoScale = true);
        const autoZoomY = yAutoScale ? this.getAutoScaleYZoom(zoom.x) : void 0;
        zoom.y = autoZoomY ?? { min: 0, max: 1 };
      }
      if (yAutoScale != void 0) {
        this.manuallyAdjusted = !yAutoScale;
      }
    }
  }
  getAutoScaleYZoom(zoomX) {
    if (!this.enabled)
      return;
    const { padding: padding2 } = this.properties;
    let yZoom;
    if (this.deps.enableIndependentAxes) {
      yZoom = this.primaryAxisZoom("y" /* Y */, zoomX, { padding: padding2 });
    } else {
      yZoom = this.combinedAxisZoom("y" /* Y */, zoomX, { padding: padding2 });
    }
    if (zoomX.min === 0 && zoomX.max === 1) {
      return yZoom == null ? void 0 : { min: 0, max: 1 };
    } else {
      return yZoom;
    }
  }
  autoScaleYZoom(changes) {
    const zoom = this.zoomManager.getZoom();
    if (zoom && changes) {
      const state = this.zoomManager.getAxisZooms();
      for (const dir of ["x" /* X */, "y" /* Y */]) {
        for (const id of strictObjectKeys(changes)) {
          if (state[id]?.direction === dir) {
            zoom[dir] = changes[id];
            break;
          }
        }
      }
    }
    if (zoom?.x == null)
      return;
    const zoomY = this.getAutoScaleYZoom(zoom.x);
    if (zoomY == null || objectsEqual(zoom.y, zoomY))
      return;
    return this.zoomManager.toCoreZoomState({ x: zoom.x, y: zoomY });
  }
  zoomBounds(xAxis, yAxis, zoom, padding2) {
    const xScale = xAxis.scale;
    const xScaleRange = xScale.range;
    xScale.range = [0, 1];
    const yScale = yAxis.scale;
    const yScaleRange = yScale.range;
    yScale.range = [0, 1];
    let min = 1;
    let minPadding = false;
    let max = 0;
    let maxPadding = false;
    for (const series of yAxis.boundSeries) {
      if (!series.visible)
        continue;
      const { connectsToYAxis } = series;
      const yValues = series.getRange("y" /* Y */, [zoom.min, zoom.max]);
      for (const yValue of yValues) {
        const y = yScale.convert(yValue);
        if (!Number.isFinite(y))
          continue;
        if (y < min) {
          min = y;
          minPadding = !connectsToYAxis || yValue < 0;
        }
        if (y > max) {
          max = y;
          maxPadding = !connectsToYAxis || yValue > 0;
        }
      }
    }
    if (isFiniteNumber(yAxis.min)) {
      min = 0;
    }
    if (isFiniteNumber(yAxis.max)) {
      max = 1;
    }
    xScale.range = xScaleRange;
    yScale.range = yScaleRange;
    if (min >= max)
      return;
    const totalPadding = (minPadding ? padding2 : 0) + (maxPadding ? padding2 : 0);
    const paddedDelta = Math.min((max - min) * (1 + totalPadding), 1);
    if (paddedDelta <= 0)
      return;
    if (minPadding && maxPadding) {
      const mid = (max + min) / 2;
      min = mid - paddedDelta / 2;
      max = mid + paddedDelta / 2;
    } else if (!minPadding && maxPadding) {
      max = min + paddedDelta;
    } else if (minPadding && !maxPadding) {
      min = max - paddedDelta;
    }
    if (min < 0) {
      max += -min;
      min = 0;
    } else if (max > 1) {
      min -= max - 1;
      max = 1;
    }
    return { min, max };
  }
  primaryAxisZoom(direction, zoom, { padding: padding2 = 0 } = {}) {
    const crossDirection = direction === "x" /* X */ ? "y" /* Y */ : "x" /* X */;
    const xAxis = this.zoomManager.getPrimaryAxis(crossDirection);
    const yAxis = this.zoomManager.getPrimaryAxis(direction);
    if (xAxis == null || yAxis == null)
      return;
    return this.zoomBounds(xAxis, yAxis, zoom, padding2);
  }
  combinedAxisZoom(direction, zoom, { padding: padding2 = 0 } = {}) {
    const axes = this.zoomManager.getAxes();
    const crossDirection = direction === "x" /* X */ ? "y" /* Y */ : "x" /* X */;
    const seriesXAxes = /* @__PURE__ */ new Map();
    for (const xAxis of axes) {
      if (xAxis.direction !== crossDirection)
        continue;
      for (const series of xAxis.boundSeries) {
        seriesXAxes.set(series, xAxis);
      }
    }
    let min = 1;
    let max = 0;
    for (const yAxis of axes) {
      if (yAxis.direction !== direction)
        continue;
      for (const series of yAxis.boundSeries) {
        const xAxis = seriesXAxes.get(series);
        if (xAxis == null)
          continue;
        const bounds = this.zoomBounds(xAxis, yAxis, zoom, padding2);
        if (bounds == null)
          return;
        min = Math.min(min, bounds.min);
        max = Math.max(max, bounds.max);
      }
    }
    const delta5 = 1e-6;
    if (min < delta5)
      min = 0;
    if (max > 1 - delta5)
      max = 1;
    if (min > max)
      return;
    return { min, max };
  }
};

// packages/ag-charts-enterprise/src/features/zoom/zoomUtils.ts
var UNIT_SIZE = UNIT_MAX - UNIT_MIN;
var DEFAULT_ANCHOR_POINT_X = "end";
var DEFAULT_ANCHOR_POINT_Y = "middle";
var ZOOM_VALID_CHECK_DEBOUNCE = 300;
var constrain = (value, min = UNIT_MIN, max = UNIT_MAX) => clamp(min, value, max);
function dx(zoom) {
  return zoom.x.max - zoom.x.min;
}
function dy(zoom) {
  return zoom.y.max - zoom.y.min;
}
function isZoomRangeEqual(left, right) {
  return isNumberEqual(left.min, right.min) && isNumberEqual(left.max, right.max);
}
function isZoomEqual(left, right) {
  return isZoomRangeEqual(left.x, right.x) && isZoomRangeEqual(left.y, right.y);
}
function isMaxZoom(zoom) {
  return isZoomEqual(zoom, definedZoomState());
}
function pointToRatio(bbox, x, y) {
  if (!bbox)
    return { x: 0, y: 0 };
  const constrainedX = constrain(x - bbox.x, 0, bbox.x + bbox.width);
  const constrainedY = constrain(y - bbox.y, 0, bbox.y + bbox.height);
  const rx = 1 / bbox.width * constrainedX;
  const ry = 1 - 1 / bbox.height * constrainedY;
  return { x: constrain(rx), y: constrain(ry) };
}
function translateZoom(zoom, x, y) {
  return {
    x: { min: zoom.x.min + x, max: zoom.x.max + x },
    y: { min: zoom.y.min + y, max: zoom.y.max + y }
  };
}
function scaleZoom(zoom, sx, sy) {
  return {
    x: { min: zoom.x.min, max: zoom.x.min + dx(zoom) * sx },
    y: { min: zoom.y.min, max: zoom.y.min + dy(zoom) * sy }
  };
}
function scaleZoomCenter(zoom, sx, sy) {
  const dx_ = dx(zoom);
  const dy_ = dy(zoom);
  const cx = zoom.x.min + dx_ / 2;
  const cy = zoom.y.min + dy_ / 2;
  return {
    x: { min: cx - dx_ * sx / 2, max: cx + dx_ * sx / 2 },
    y: { min: cy - dy_ * sy / 2, max: cy + dy_ * sy / 2 }
  };
}
function scaleZoomAxisWithAnchor(newState, oldState, anchor, origin3) {
  const { min, max } = oldState;
  const center2 = min + (max - min) / 2;
  const diff9 = newState.max - newState.min;
  switch (anchor) {
    case "start":
      return { min, max: oldState.min + diff9 };
    case "end":
      return { min: oldState.max - diff9, max };
    case "middle":
      return { min: center2 - diff9 / 2, max: center2 + diff9 / 2 };
    case "pointer":
      return scaleZoomAxisWithPoint(newState, oldState, origin3 ?? center2);
    default:
      return { min, max };
  }
}
function scaleZoomAxisWithPoint(newState, oldState, origin3) {
  const newDelta = newState.max - newState.min;
  const oldDelta = oldState.max - oldState.min;
  const scaledOrigin = origin3 * (1 - (oldDelta - newDelta));
  const translation = origin3 - scaledOrigin;
  const min = newState.min + translation;
  const max = newState.max + translation;
  return { min, max };
}
function multiplyZoom(zoom, nx, ny) {
  return {
    x: { min: zoom.x.min * nx, max: zoom.x.max * nx },
    y: { min: zoom.y.min * ny, max: zoom.y.max * ny }
  };
}
function constrainZoom(zoom) {
  return {
    x: constrainAxis(zoom.x),
    y: constrainAxis(zoom.y)
  };
}
function constrainAxis(axis) {
  const size = axis.max - axis.min;
  let min = axis.max > UNIT_MAX ? UNIT_MAX - size : axis.min;
  let max = axis.min < UNIT_MIN ? size : axis.max;
  min = Math.max(UNIT_MIN, min);
  max = Math.min(UNIT_MAX, max);
  return { min, max };
}
function canResetZoom(zoomManager) {
  const current = zoomManager.getCoreZoom();
  const restore = zoomManager.getRestoredZoom();
  return jsonDiff(current, restore) != null;
}

// packages/ag-charts-enterprise/src/features/zoom/zoomAxisDragger.ts
var ZoomAxisDragger = class {
  update(event, direction, anchor, bbox, zoom, axisZoom) {
    this.oldZoom ?? (this.oldZoom = definedZoomState(
      direction === "x" /* X */ ? { ...zoom, x: axisZoom } : { ...zoom, y: axisZoom }
    ));
    this.updateCoords(event.offsetX, event.offsetY);
    return this.updateZoom(direction, anchor, bbox);
  }
  stop() {
    this.coords = void 0;
    this.oldZoom = void 0;
  }
  updateCoords(x, y) {
    if (this.coords) {
      this.coords.x2 = x;
      this.coords.y2 = y;
    } else {
      this.coords = { x1: x, y1: y, x2: x, y2: y };
    }
  }
  updateZoom(direction, anchor, bbox) {
    const { coords, oldZoom } = this;
    let newZoom = definedZoomState(oldZoom);
    if (!coords || !oldZoom) {
      if (direction === "x" /* X */)
        return newZoom.x;
      return newZoom.y;
    }
    const origin3 = pointToRatio(bbox, coords.x1, coords.y1);
    const target = pointToRatio(bbox, coords.x2, coords.y2);
    if (direction === "x" /* X */) {
      const scaleX = (target.x - origin3.x) * dx(oldZoom);
      newZoom.x.max += scaleX;
      newZoom.x = scaleZoomAxisWithAnchor(newZoom.x, oldZoom.x, anchor, origin3.x);
      newZoom = constrainZoom(newZoom);
      return newZoom.x;
    }
    const scaleY = (target.y - origin3.y) * dy(oldZoom);
    newZoom.y.max -= scaleY;
    newZoom.y = scaleZoomAxisWithAnchor(newZoom.y, oldZoom.y, anchor, origin3.y);
    newZoom = constrainZoom(newZoom);
    return newZoom.y;
  }
};

// packages/ag-charts-enterprise/src/features/zoom/zoomContextMenu.ts
var { userInteraction: userInteraction3 } = module_support_exports;
var ZoomContextMenu = class {
  constructor(eventsHub, contextMenuRegistry, zoomManager, getModuleProperties, getRect, updateZoom, isZoomValid) {
    this.eventsHub = eventsHub;
    this.contextMenuRegistry = contextMenuRegistry;
    this.zoomManager = zoomManager;
    this.getModuleProperties = getModuleProperties;
    this.getRect = getRect;
    this.updateZoom = updateZoom;
    this.isZoomValid = isZoomValid;
  }
  registerActions(enabled) {
    const { contextMenuRegistry } = this;
    const action = enabled ? "show" : "hide";
    contextMenuRegistry.toggle("zoom-to-cursor", action);
    contextMenuRegistry.toggle("pan-to-cursor", action);
    contextMenuRegistry.toggle("reset-zoom", action);
    if (!enabled) {
      return;
    }
    contextMenuRegistry.builtins.items["zoom-to-cursor"].action = this.onZoomToHere.bind(this);
    contextMenuRegistry.builtins.items["pan-to-cursor"].action = this.onPanToHere.bind(this);
    contextMenuRegistry.builtins.items["reset-zoom"].action = this.onResetZoom.bind(this);
    const shouldEnableZoomToHere = (event) => {
      const rect2 = this.getRect();
      if (!rect2)
        return true;
      const origin3 = pointToRatio(rect2, event.x, event.y);
      return this.iterateFindNextZoomAtPoint(origin3) != null;
    };
    const shouldEnablePanToHere = () => {
      return !isMaxZoom(definedZoomState(this.zoomManager.getZoom()));
    };
    const removeListener = this.eventsHub.on("context-menu:setup", (event) => {
      contextMenuRegistry.builtins.items["zoom-to-cursor"].enabled = shouldEnableZoomToHere(event);
      contextMenuRegistry.builtins.items["pan-to-cursor"].enabled = shouldEnablePanToHere();
      contextMenuRegistry.builtins.items["reset-zoom"].enabled = canResetZoom(this.zoomManager);
    });
    return () => {
      removeListener();
      contextMenuRegistry.toggle("zoom-to-cursor", "hide");
      contextMenuRegistry.toggle("pan-to-cursor", "hide");
      contextMenuRegistry.toggle("reset-zoom", "hide");
    };
  }
  computeOrigin(event) {
    const rect2 = this.getRect();
    const { enabled } = this.getModuleProperties();
    if (!enabled || !rect2 || !event?.target || !(event instanceof MouseEvent))
      return;
    const relativeRect = { x: 0, y: 0, width: rect2.width, height: rect2.height };
    return pointToRatio(relativeRect, event.offsetX, event.offsetY);
  }
  onZoomToHere({ event }) {
    const origin3 = this.computeOrigin(event);
    if (!origin3)
      return;
    const zoom = this.iterateFindNextZoomAtPoint(origin3);
    if (zoom == null)
      return;
    this.updateZoom(userInteraction3("contextmenu-zoom-to-cursor"), zoom);
  }
  onPanToHere({ event }) {
    const origin3 = this.computeOrigin(event);
    if (!origin3)
      return;
    const zoom = definedZoomState(this.zoomManager.getZoom());
    const scaleX = dx(zoom);
    const scaleY = dy(zoom);
    const scaledOriginX = origin3.x * scaleX;
    const scaledOriginY = origin3.y * scaleY;
    const halfSize = UNIT_SIZE / 2;
    let newZoom = {
      x: { min: origin3.x - halfSize, max: origin3.x + halfSize },
      y: { min: origin3.y - halfSize, max: origin3.y + halfSize }
    };
    newZoom = scaleZoomCenter(newZoom, scaleX, scaleY);
    newZoom = translateZoom(newZoom, zoom.x.min - origin3.x + scaledOriginX, zoom.y.min - origin3.y + scaledOriginY);
    this.updateZoom(userInteraction3("contextmenu-pan-to-cursor"), constrainZoom(newZoom));
  }
  onResetZoom(_actionEvent) {
    this.zoomManager.resetZoom(userInteraction3("contextmenu-reset"));
  }
  iterateFindNextZoomAtPoint(origin3) {
    const { scrollingStep } = this.getModuleProperties();
    for (let i = scrollingStep; i <= 1 - scrollingStep; i += scrollingStep) {
      const zoom = this.getNextZoomAtPoint(origin3, i);
      if (this.isZoomValid(zoom)) {
        return zoom;
      }
    }
  }
  getNextZoomAtPoint(origin3, step) {
    const { isScalingX, isScalingY } = this.getModuleProperties();
    const zoom = definedZoomState(this.zoomManager.getZoom());
    const scaledOriginX = origin3.x * dx(zoom);
    const scaledOriginY = origin3.y * dy(zoom);
    const halfSize = UNIT_SIZE / 2;
    let newZoom = {
      x: { min: origin3.x - halfSize, max: origin3.x + halfSize },
      y: { min: origin3.y - halfSize, max: origin3.y + halfSize }
    };
    newZoom = scaleZoomCenter(
      newZoom,
      isScalingX ? dx(zoom) * step : UNIT_SIZE,
      isScalingY ? dy(zoom) * step : UNIT_SIZE
    );
    newZoom = translateZoom(newZoom, zoom.x.min - origin3.x + scaledOriginX, zoom.y.min - origin3.y + scaledOriginY);
    return constrainZoom(newZoom);
  }
};

// packages/ag-charts-enterprise/src/features/zoom/zoomDOMProxy.ts
var ZoomDOMProxy = class {
  constructor(axesHandlers) {
    this.axesHandlers = axesHandlers;
    this.axes = [];
    this.overlappingAxisIds = /* @__PURE__ */ new Set();
  }
  destroy() {
    for (const a of this.axes) {
      a.div.destroy();
    }
  }
  update(enabled, enableAxisDragging, enableAxisScrolling, ctx, seriesRect) {
    this.seriesRect = seriesRect;
    const disabled = !enabled || !enableAxisDragging && !enableAxisScrolling;
    for (const ax of this.axes) {
      ax.div.setHidden(disabled);
    }
    if (disabled)
      return;
    const { X, Y } = ChartAxisDirection;
    const axesCtx = [...ctx.axisManager.getAxisContext(X), ...ctx.axisManager.getAxisContext(Y)];
    const { removed, added } = this.diffAxisIds(axesCtx);
    if (removed.length > 0) {
      this.axes = this.axes.filter((entry) => {
        if (removed.includes(entry.axisId)) {
          entry.div.destroy();
          this.overlappingAxisIds.delete(entry.axisId);
          if (this.hoveredAxisId === entry.axisId)
            this.hoveredAxisId = void 0;
          if (this.activeAxisId === entry.axisId)
            this.activeAxisId = void 0;
          return false;
        }
        return true;
      });
    }
    for (const newAxisCtx of added) {
      const { axisId, direction } = newAxisCtx;
      this.axes.push(this.initAxis(ctx, axisId, this.axesHandlers, direction));
    }
    for (const axis of this.axes) {
      const axisCtx = axesCtx.find((ac) => ac.axisId === axis.axisId);
      const bbox = axisCtx.getCanvasBounds();
      axis.div.setHidden(boxEmpty(bbox));
      if (bbox == void 0) {
        axis.bounds = void 0;
      } else {
        axis.div.setBounds(bbox);
        axis.bounds = new module_support_exports.BBox(bbox.x, bbox.y, bbox.width, bbox.height);
      }
    }
    this.updateOverlappingAxisPointerEvents(enableAxisDragging, enableAxisScrolling);
  }
  setAxisCursor(cursor) {
    this.cursor = cursor;
    for (const axis of this.axes) {
      axis.div.setCursor(this.getCursor(axis.direction));
    }
  }
  toggleAxisDraggingCursor(direction, enabled) {
    for (const axis of this.axes) {
      if (axis.direction !== direction)
        continue;
      axis.div.setCursor(enabled ? this.getCursor(direction) : void 0);
    }
  }
  updateOverlappingAxisPointerEvents(enableAxisDragging, enableAxisScrolling) {
    this.overlappingAxisIds.clear();
    const shouldEnableInteraction = (enableAxisDragging || enableAxisScrolling) && this.seriesRect;
    for (const axis of this.axes) {
      if (!shouldEnableInteraction) {
        axis.div.setPointerEvents(void 0);
        continue;
      }
      const isOverlapping = Boolean(axis.bounds?.collidesBBox(this.seriesRect));
      if (isOverlapping) {
        this.overlappingAxisIds.add(axis.axisId);
        axis.div.setPointerEvents("none");
      } else {
        axis.div.setPointerEvents(void 0);
      }
    }
    this.cleanupAxisState();
  }
  cleanupAxisState() {
    if (this.hoveredAxisId && !this.overlappingAxisIds.has(this.hoveredAxisId)) {
      this.hoveredAxisId = void 0;
    }
    if (this.activeAxisId && !this.overlappingAxisIds.has(this.activeAxisId)) {
      this.activeAxisId = void 0;
    }
  }
  pickAxisAtPoint(point) {
    for (const axis of this.axes) {
      if (!this.overlappingAxisIds.has(axis.axisId))
        continue;
      if (axis.bounds?.containsPoint(point.canvasX, point.canvasY)) {
        return { axisId: axis.axisId, direction: axis.direction };
      }
    }
    return void 0;
  }
  setHoveredAxis(axisId) {
    if (this.overlappingAxisIds.has(axisId)) {
      this.hoveredAxisId = axisId;
    }
  }
  clearHoveredAxis() {
    if (!this.activeAxisId) {
      this.hoveredAxisId = void 0;
    }
  }
  beginDelegatedAxisDrag(axisId) {
    if (!this.overlappingAxisIds.has(axisId))
      return false;
    this.activeAxisId = axisId;
    this.hoveredAxisId = void 0;
    return true;
  }
  endDelegatedAxisDrag(axisId) {
    if (this.activeAxisId === axisId) {
      this.activeAxisId = void 0;
    }
    this.hoveredAxisId = void 0;
  }
  hasOverlappingAxes() {
    return this.overlappingAxisIds.size > 0;
  }
  getHoveredAxis() {
    if (!this.hoveredAxisId)
      return void 0;
    const axis = this.axes.find((a) => a.axisId === this.hoveredAxisId);
    return axis ? { axisId: axis.axisId, direction: axis.direction } : void 0;
  }
  getCursor(direction) {
    if (this.cursor)
      return this.cursor;
    return direction === "x" /* X */ ? "ew-resize" : "ns-resize";
  }
  initAxis(ctx, axisId, handlers, direction) {
    const where = "afterend";
    const div = ctx.proxyInteractionService.createProxyElement({ type: "region", domManagerId: axisId, where });
    div.setCursor(this.getCursor(direction));
    div.addListener("drag-start", (e) => {
      if (e.device === "touch") {
        e.sourceEvent.preventDefault();
      }
      this.activeAxisId = axisId;
      handlers.onAxisDragStart(direction);
    });
    div.addListener("drag-move", (event) => handlers.onAxisDragMove(axisId, direction, event));
    div.addListener("drag-end", () => {
      this.activeAxisId = void 0;
      this.hoveredAxisId = void 0;
      handlers.onAxisDragEnd();
    });
    div.addListener("dblclick", () => handlers.onAxisDoubleClick(axisId, direction));
    div.addListener("wheel", (event) => handlers.onAxisWheel(direction, event));
    return { axisId, div, direction };
  }
  diffAxisIds(axesCtx) {
    const myIds = this.axes.map((entry) => entry.axisId);
    const ctxIds = axesCtx.map((ctx) => ctx.axisId);
    const removed = myIds.filter((id) => !ctxIds.includes(id));
    const added = axesCtx.filter((ac) => !myIds.includes(ac.axisId));
    return { removed, added };
  }
};

// packages/ag-charts-enterprise/src/features/zoom/zoomOnDataChange.ts
var { userInteraction: userInteraction4 } = module_support_exports;
function shouldIgnoreDataUpdate(zoom) {
  return zoom.x.min === 0 && zoom.x.max === 1 && zoom.y.min === 0 && zoom.y.max === 1;
}
function shouldStickToEnd(properties, zoom) {
  return properties.stickToEnd && zoom.x.max === 1;
}
function toVisibleMinMax(axisId, domainMinMax, ratios) {
  const { domainMin, domainMax } = domainMinMax;
  const span = domainMax - domainMin;
  return {
    axisId,
    visibleMin: domainMin + span * ratios.min,
    visibleMax: domainMin + span * ratios.max
  };
}
function fromVisibleMinMax(domainMinMax, visibleMinMax) {
  const { domainMin, domainMax } = domainMinMax;
  const { visibleMin, visibleMax } = visibleMinMax;
  const span = domainMax - domainMin;
  return {
    direction: "x",
    min: clamp(0, (visibleMin - domainMin) / span, 1),
    max: clamp(0, (visibleMax - domainMin) / span, 1)
  };
}
var ZoomOnDataChangeProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.strategy = "preserveDomain";
    // TODO(olegat): change default to 'true'
    this.stickToEnd = false;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ZoomOnDataChangeProperties.prototype, "strategy", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ZoomOnDataChangeProperties.prototype, "stickToEnd", 2);
var ZoomOnDataChange = class {
  constructor(onConstrainChangesCallback, properties, ctx, eventsCleanup) {
    this.onConstrainChangesCallback = onConstrainChangesCallback;
    this.properties = properties;
    this.ctx = ctx;
    const onFirstDraw = () => {
      ctx.eventsHub.off("layout:complete", onFirstDraw);
      eventsCleanup.register(
        ctx.eventsHub.on("data:load", (e) => this.onDataLoad(e)),
        ctx.eventsHub.on("data:update", (e) => this.onDataUpdate(e))
      );
    };
    eventsCleanup.register(
      ctx.eventsHub.on("layout:complete", onFirstDraw),
      ctx.eventsHub.on("zoom:change-request", (e) => this.onZoomChangeRequest(e))
    );
  }
  destroy() {
  }
  onDataLoad(_e) {
    this.performUpdateStrategy();
  }
  onDataUpdate(_e) {
    this.performUpdateStrategy();
  }
  onZoomChangeRequest(e) {
    if (e.sourceDetail === "internal-requiredWidth") {
      this.desiredChanges = void 0;
    }
    const changes = this.popDesiredChanges();
    if (changes) {
      e.constrainChanges(changes);
      this.onConstrainChangesCallback(e);
    }
  }
  /**
   * Convert ambiguous axes-scale (number | Date | string) into a strictly numerical scale, so that we can use
   * interpolation to implement preserveDomain in an axes-scale agnostic way.
   */
  computeDomainMinMax(axisId) {
    const ctx = this.ctx.axisManager.getAxisIdContext(axisId);
    if (!ctx?.continuous || ctx.scale.domain.length === 0)
      return;
    const [min, max] = ctx.scale.getDomainMinMax();
    if (typeof min === "number" && typeof max === "number") {
      return { domainMin: min, domainMax: max };
    } else if (min instanceof Date && max instanceof Date) {
      return { domainMin: min.getTime(), domainMax: max.getTime() };
    } else {
      logger_exports.error(`Unexpected range types: start (${typeof min}), end (${typeof max})`);
    }
  }
  popDesiredChanges() {
    const { desiredChanges } = this;
    if (!desiredChanges)
      return;
    this.desiredChanges = void 0;
    switch (desiredChanges.type) {
      case "domain": {
        const changes = {};
        for (const entry of desiredChanges.domains) {
          const domainMinMax = this.computeDomainMinMax(entry.axisId);
          if (domainMinMax) {
            changes[entry.axisId] = fromVisibleMinMax(domainMinMax, entry);
          }
        }
        return changes;
      }
      case "stickToEnd": {
        const { axisId, difference } = desiredChanges;
        const domainMinMax = this.computeDomainMinMax(axisId);
        if (domainMinMax) {
          const visibleMinMax = {
            axisId,
            visibleMin: domainMinMax.domainMax - difference,
            visibleMax: domainMinMax.domainMax
          };
          return { [axisId]: fromVisibleMinMax(domainMinMax, visibleMinMax) };
        }
        break;
      }
      default:
        const unreachable = (a) => a;
        return unreachable(desiredChanges);
    }
  }
  performUpdateStrategy() {
    const zoom = definedZoomState(this.ctx.zoomManager.getZoom());
    if (shouldIgnoreDataUpdate(zoom)) {
      return;
    } else if (shouldStickToEnd(this.properties, zoom)) {
      return this.performStickToEnd();
    }
    switch (this.properties.strategy) {
      case "reset":
        return this.ctx.zoomManager.resetZoom(userInteraction4("onDataChange-reset"));
      case "preserveRatios":
        return;
      case "preserveDomain":
        return this.performPreserveDomain();
      default:
        const unreachable = (a) => a;
        return unreachable(this.properties.strategy);
    }
  }
  performPreserveDomain() {
    this.desiredChanges = { type: "domain", domains: [] };
    const xaxes = this.ctx.zoomManager.getAxes().filter((a) => a.direction === "x" /* X */);
    for (const { id: axisId } of xaxes) {
      const domainMinMax = this.computeDomainMinMax(axisId);
      if (domainMinMax) {
        const ratios = this.ctx.zoomManager.getAxisZoom(axisId);
        const entry = toVisibleMinMax(axisId, domainMinMax, ratios);
        this.desiredChanges.domains.push(entry);
      }
    }
  }
  performStickToEnd() {
    const axisId = this.ctx.zoomManager.getPrimaryAxisId("x" /* X */);
    if (!axisId)
      return;
    const domainMinMax = this.computeDomainMinMax(axisId);
    if (!domainMinMax)
      return;
    const ratios = this.ctx.zoomManager.getAxisZoom(axisId);
    if (!ratios)
      return;
    const { visibleMin, visibleMax } = toVisibleMinMax(axisId, domainMinMax, ratios);
    const difference = visibleMax - visibleMin;
    this.desiredChanges = { type: "stickToEnd", axisId, difference };
  }
};

// packages/ag-charts-enterprise/src/features/zoom/zoomPanner.ts
var maxZoomCoords = 16;
var decelerationValues = {
  off: 1,
  short: 0.01,
  long: 2e-3
};
var ZoomPanner = class {
  constructor() {
    this.deceleration = 1;
    this.zoomCoordsHistoryIndex = 0;
    this.coordsHistory = [];
  }
  get decelerationValue() {
    const { deceleration } = this;
    return Math.max(
      typeof deceleration === "number" ? deceleration : decelerationValues[deceleration] ?? 1,
      1e-4
    );
  }
  addListener(_type, fn) {
    this.onUpdate = fn;
    return () => {
      this.onUpdate = void 0;
    };
  }
  stopInteractions() {
    if (this.inertiaHandle != null) {
      cancelAnimationFrame(this.inertiaHandle);
      this.inertiaHandle = void 0;
    }
  }
  update(event) {
    this.updateCoords(event.currentX, event.currentY);
    const { x1 = 0, y1 = 0, x2 = 0, y2 = 0 } = this.coords ?? {};
    this.onUpdate?.({
      type: "update",
      deltaX: this.isPanningX() ? x1 - x2 : 0,
      deltaY: this.isPanningY() ? y1 - y2 : 0
    });
  }
  start(direction) {
    this.direction = direction;
    this.coordsMonitorTimeout = setInterval(this.recordCurrentZoomCoords.bind(this), 16);
  }
  stop() {
    const { coordsHistory } = this;
    let deltaX = 0;
    let deltaY = 0;
    let deltaT = 0;
    if (coordsHistory.length > 0) {
      const arrayIndex = this.zoomCoordsHistoryIndex % maxZoomCoords;
      let index1 = arrayIndex - 1;
      if (index1 < 0)
        index1 = coordsHistory.length - 1;
      let index0 = arrayIndex;
      if (index0 >= coordsHistory.length)
        index0 = 0;
      const coords1 = coordsHistory[index1];
      const coords0 = coordsHistory[index0];
      deltaX = this.isPanningX() ? coords1.x - coords0.x : 0;
      deltaY = this.isPanningY() ? coords1.y - coords0.y : 0;
      deltaT = coords1.t - coords0.t;
    }
    this.coords = void 0;
    this.direction = void 0;
    clearInterval(this.coordsMonitorTimeout);
    this.coordsMonitorTimeout = void 0;
    this.zoomCoordsHistoryIndex = 0;
    this.coordsHistory.length = 0;
    if (deltaT > 0 && this.decelerationValue < 1) {
      const xVelocity = deltaX / deltaT;
      const yVelocity = deltaY / deltaT;
      const velocity = Math.hypot(xVelocity, yVelocity);
      const angle2 = Math.atan2(yVelocity, xVelocity);
      const t0 = performance.now();
      this.inertiaHandle = getWindow().requestAnimationFrame((t) => {
        this.animateInertia(t, t, t0, velocity, angle2);
      });
    }
  }
  recordCurrentZoomCoords() {
    const { coords, coordsHistory, zoomCoordsHistoryIndex } = this;
    if (!coords)
      return;
    const { x2: x, y2: y } = coords;
    const t = Date.now();
    coordsHistory[zoomCoordsHistoryIndex % maxZoomCoords] = { x, y, t };
    this.zoomCoordsHistoryIndex += 1;
  }
  animateInertia(t, prevT, t0, velocity, angle2) {
    const friction = 1 - this.decelerationValue;
    const maxS = -velocity / Math.log(friction);
    const s0 = velocity * (friction ** (prevT - t0) - 1) / Math.log(friction);
    const s1 = velocity * (friction ** (t - t0) - 1) / Math.log(friction);
    this.onUpdate?.({
      type: "update",
      deltaX: this.isPanningX() ? -Math.cos(angle2) * (s1 - s0) : 0,
      deltaY: this.isPanningY() ? -Math.sin(angle2) * (s1 - s0) : 0
    });
    if (s1 >= maxS - 1)
      return;
    this.inertiaHandle = requestAnimationFrame((nextT) => {
      this.animateInertia(nextT, t, t0, velocity, angle2);
    });
  }
  updateCoords(x, y) {
    if (this.coords) {
      this.coords = { x1: this.coords.x2, y1: this.coords.y2, x2: x, y2: y };
    } else {
      this.coords = { x1: x, y1: y, x2: x, y2: y };
    }
  }
  isPanningX() {
    return this.direction == null || this.direction === "x" /* X */;
  }
  isPanningY() {
    return this.direction == null || this.direction === "y" /* Y */;
  }
  translateZooms(bbox, currentZooms, deltaX, deltaY) {
    const offset = pointToRatio(bbox, bbox.x + Math.abs(deltaX), bbox.y + bbox.height - Math.abs(deltaY));
    const offsetX = Math.sign(deltaX) * offset.x;
    const offsetY = -Math.sign(deltaY) * offset.y;
    const newZooms = {};
    for (const [axisId, currentZoom] of entries(currentZooms)) {
      if (currentZoom == null)
        continue;
      if (currentZoom.min === UNIT_MIN && currentZoom.max === UNIT_MAX) {
        continue;
      }
      const { direction } = currentZoom;
      let zoom = definedZoomState({ [direction]: currentZoom });
      zoom = constrainZoom(translateZoom(zoom, offsetX * dx(zoom), offsetY * dy(zoom)));
      const { min, max } = zoom[direction];
      newZooms[axisId] = { direction, min, max };
    }
    return newZooms;
  }
};

// packages/ag-charts-enterprise/src/features/zoom/zoomScrollPanner.ts
var DELTA_SCALE = 200;
var ZoomScrollPanner = class {
  update(event, step, bbox, zooms) {
    const deltaX = event.deltaX * step * DELTA_SCALE;
    return this.translateZooms(bbox, zooms, deltaX);
  }
  translateZooms(bbox, currentZooms, deltaX) {
    const newZooms = {};
    const offset = pointToRatio(bbox, bbox.x + Math.abs(deltaX), 0);
    const offsetX = deltaX < 0 ? -offset.x : offset.x;
    for (const [axisId, value] of entries(currentZooms)) {
      if (value?.direction !== "x" /* X */)
        continue;
      const { direction, min, max } = value;
      let zoom = definedZoomState({ x: { min, max } });
      zoom = constrainZoom(translateZoom(zoom, offsetX * dx(zoom), 0));
      newZooms[axisId] = { direction, min: zoom.x.min, max: zoom.x.max };
    }
    return newZooms;
  }
};

// packages/ag-charts-enterprise/src/features/zoom/zoomScroller.ts
var ZoomScroller = class {
  updateAxes(event, props, bbox, zooms) {
    const sourceEvent = event.sourceEvent;
    const newZooms = {};
    const { anchorPointX, anchorPointY, isScalingX, isScalingY, scrollingStep } = props;
    const origin3 = pointToRatio(
      bbox,
      sourceEvent.offsetX ?? sourceEvent.clientX,
      sourceEvent.offsetY ?? sourceEvent.clientY
    );
    for (const [axisId, value] of entries(zooms)) {
      if (value == null)
        continue;
      const { direction, min, max } = value;
      let newZoom = { min, max };
      const delta5 = scrollingStep * event.deltaY * (max - min);
      if (direction === "x" /* X */ && isScalingX) {
        newZoom.max += delta5;
        newZoom = scaleZoomAxisWithAnchor(newZoom, value, anchorPointX, origin3.x);
      } else if (direction === "y" /* Y */ && isScalingY) {
        newZoom.max += delta5;
        newZoom = scaleZoomAxisWithAnchor(newZoom, value, anchorPointY, origin3.y);
      } else {
        continue;
      }
      if (newZoom.max < newZoom.min)
        continue;
      const constrained = constrainAxis(newZoom);
      newZooms[axisId] = { direction, min: constrained.min, max: constrained.max };
    }
    return newZooms;
  }
  update(event, props, bbox, oldZoom) {
    const { anchorPointX, anchorPointY, isScalingX, isScalingY, scrollingStep } = props;
    const canvasX = event.offsetX + bbox.x;
    const canvasY = event.offsetY + bbox.y;
    const origin3 = pointToRatio(bbox, canvasX, canvasY);
    const dir = event.deltaY;
    let newZoom = definedZoomState(oldZoom);
    newZoom.x.max += isScalingX ? scrollingStep * dir * dx(oldZoom) : 0;
    newZoom.y.max += isScalingY ? scrollingStep * dir * dy(oldZoom) : 0;
    if (newZoom.x.max < newZoom.x.min || newZoom.y.max < newZoom.y.min)
      return;
    if (isScalingX) {
      newZoom.x = scaleZoomAxisWithAnchor(newZoom.x, oldZoom.x, anchorPointX, origin3.x);
    }
    if (isScalingY) {
      newZoom.y = scaleZoomAxisWithAnchor(newZoom.y, oldZoom.y, anchorPointY, origin3.y);
    }
    newZoom = constrainZoom(newZoom);
    return newZoom;
  }
  updateDelta(delta5, props, oldZoom) {
    const { anchorPointX, anchorPointY, isScalingX, isScalingY, scrollingStep } = props;
    let newZoom = definedZoomState(oldZoom);
    newZoom.x.max += isScalingX ? scrollingStep * -delta5 * dx(oldZoom) : 0;
    newZoom.y.max += isScalingY ? scrollingStep * -delta5 * dy(oldZoom) : 0;
    if (isScalingX) {
      newZoom.x = scaleZoomAxisWithAnchor(newZoom.x, oldZoom.x, anchorPointX);
    }
    if (isScalingY) {
      newZoom.y = scaleZoomAxisWithAnchor(newZoom.y, oldZoom.y, anchorPointY);
    }
    newZoom = constrainZoom(newZoom);
    return newZoom;
  }
};

// packages/ag-charts-enterprise/src/features/zoom/zoomSelector.ts
var ZoomSelector = class {
  constructor(rect2, getZoom, isZoomValid) {
    this.rect = rect2;
    this.getZoom = getZoom;
    this.isZoomValid = isZoomValid;
    this.rect.visible = false;
  }
  update(event, props, bbox) {
    const canvasX = event.currentX + (bbox?.x ?? 0);
    const canvasY = event.currentY + (bbox?.y ?? 0);
    this.rect.visible = true;
    this.updateCoords(canvasX, canvasY, props, bbox);
    this.updateRect(bbox);
  }
  stop(innerBBox, bbox, currentZoom) {
    let zoom = definedZoomState();
    if (!innerBBox || !bbox)
      return zoom;
    if (this.coords) {
      zoom = this.createZoomFromCoords(bbox, currentZoom);
    }
    const multiplyX = bbox.width / innerBBox.width;
    const multiplyY = bbox.height / innerBBox.height;
    zoom = constrainZoom(multiplyZoom(zoom, multiplyX, multiplyY));
    this.reset();
    if (this.isZoomValid(zoom)) {
      return zoom;
    }
  }
  reset() {
    this.coords = void 0;
    this.rect.visible = false;
  }
  didUpdate() {
    return this.rect.visible && this.rect.width > 0 && this.rect.height > 0;
  }
  updateCoords(x, y, props, bbox) {
    if (!this.coords) {
      this.coords = { x1: x, y1: y, x2: x, y2: y };
      return;
    }
    const { coords } = this;
    coords.x2 = x;
    coords.y2 = y;
    if (!bbox)
      return;
    const { isScalingX, isScalingY, keepAspectRatio } = props;
    const normal = this.getNormalisedDimensions();
    if (keepAspectRatio && isScalingX && isScalingY) {
      const aspectRatio = bbox.width / bbox.height;
      if (coords.y2 < coords.y1) {
        coords.y2 = Math.min(coords.y1 - normal.width / aspectRatio, coords.y1);
      } else {
        coords.y2 = Math.max(coords.y1 + normal.width / aspectRatio, coords.y1);
      }
    }
    if (!isScalingX) {
      coords.x1 = bbox.x;
      coords.x2 = bbox.x + bbox.width;
    }
    if (!isScalingY) {
      coords.y1 = bbox.y;
      coords.y2 = bbox.y + bbox.height;
    }
  }
  updateRect(bbox) {
    if (!bbox)
      return;
    const { rect: rect2 } = this;
    const normal = this.getNormalisedDimensions();
    const { width: width2, height: height2 } = normal;
    let { x, y } = normal;
    x = Math.max(x, bbox.x);
    x -= Math.max(0, x + width2 - (bbox.x + bbox.width));
    y = Math.max(y, bbox.y);
    y -= Math.max(0, y + height2 - (bbox.y + bbox.height));
    rect2.x = x;
    rect2.y = y;
    rect2.width = width2;
    rect2.height = height2;
    const zoom = this.createZoomFromCoords(bbox, this.getZoom());
    if (this.isZoomValid(zoom)) {
      rect2.updateValid();
    } else {
      rect2.updateInvalid();
    }
  }
  createZoomFromCoords(bbox, currentZoom) {
    const oldZoom = definedZoomState(currentZoom);
    const normal = this.getNormalisedDimensions();
    const origin3 = pointToRatio(bbox, normal.x, normal.y + normal.height);
    const xFactor = normal.width / bbox.width;
    const yFactor = normal.height / bbox.height;
    let newZoom = scaleZoom(oldZoom, xFactor, yFactor);
    const translateX = origin3.x * dx(oldZoom);
    const translateY = origin3.y * dy(oldZoom);
    newZoom = translateZoom(newZoom, translateX, translateY);
    newZoom = constrainZoom(newZoom);
    return newZoom;
  }
  getNormalisedDimensions() {
    const { x1 = 0, y1 = 0, x2 = 0, y2 = 0 } = this.coords ?? {};
    const x = Math.min(x1, x2);
    const y = Math.min(y1, y2);
    const width2 = x1 <= x2 ? x2 - x1 : x1 - x2;
    const height2 = y1 <= y2 ? y2 - y1 : y1 - y2;
    return { x, y, width: width2, height: height2 };
  }
};

// packages/ag-charts-enterprise/src/features/zoom/zoomToolbar.ts
var { userInteraction: userInteraction5, NativeWidget: NativeWidget3, Toolbar: Toolbar3 } = module_support_exports;
var ZoomButtonProperties = class extends ToolbarButtonProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ZoomButtonProperties.prototype, "value", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ZoomButtonProperties.prototype, "section", 2);
var ZoomToolbar = class extends BaseProperties {
  constructor(ctx, getModuleProperties, updateZoom, updateAxisZoom, resetZoom, isZoomValid) {
    super();
    this.ctx = ctx;
    this.getModuleProperties = getModuleProperties;
    this.updateZoom = updateZoom;
    this.updateAxisZoom = updateAxisZoom;
    this.resetZoom = resetZoom;
    this.isZoomValid = isZoomValid;
    this.enabled = false;
    this.buttons = new PropertiesArray(ZoomButtonProperties);
    this.visible = "hover";
    this.verticalSpacing = 10;
    this.detectionRange = 38;
    this.cleanup = new CleanupRegistry();
    this.toggleButtonsDebounced = debounce(this.toggleButtons.bind(this), ZOOM_VALID_CHECK_DEBOUNCE, {
      leading: true,
      trailing: true
    });
    this.container = new NativeWidget3(createElement("div"));
    this.container.addClass("ag-charts-zoom-buttons");
    ctx.domManager.addChild("canvas-overlay", "zoom-buttons", this.container.getElement());
    this.toolbar = new Toolbar3(ctx, "ariaLabelZoomToolbar", "horizontal");
    this.container.addChild(this.toolbar);
    this.toolbar.getElement().style.transform = `translateY(54px)`;
    this.toolbar.setHidden(!this.enabled);
    this.toggleVisibility(this.visible === "always");
    this.cleanup.register(
      this.toolbar.addToolbarListener("button-pressed", this.onButtonPress.bind(this)),
      this.toolbar.addToolbarListener("button-focused", this.onButtonFocus.bind(this)),
      ctx.widgets.containerWidget.addListener("mousemove", this.onHover.bind(this)),
      ctx.widgets.containerWidget.addListener("mouseleave", this.onLeave.bind(this)),
      ctx.eventsHub.on("layout:complete", this.onLayoutComplete.bind(this)),
      this.teardown.bind(this)
    );
  }
  destroy() {
    this.cleanup.flush();
  }
  toggleVisibleZoomed(maxZoom) {
    if (this.visible !== "zoomed")
      return;
    this.toggleVisibility(!maxZoom);
  }
  teardown() {
    this.ctx.domManager.removeChild("canvas-overlay", "zoom-buttons");
    this.container.destroy();
  }
  onLayoutComplete(event) {
    if (!this.enabled)
      return;
    const { buttons, container } = this;
    const { rect: rect2 } = event.series;
    for (const b of buttons) {
      if (b.tooltip == null && b.label == null) {
        const map = {
          "pan-end": "toolbarZoomPanEnd",
          "pan-left": "toolbarZoomPanLeft",
          "pan-right": "toolbarZoomPanRight",
          "pan-start": "toolbarZoomPanStart",
          "zoom-in": "toolbarZoomZoomIn",
          "zoom-out": "toolbarZoomZoomOut",
          reset: "toolbarZoomReset"
        };
        b.tooltip = map[b.value];
      }
    }
    this.toolbar.updateButtons(buttons);
    this.toggleButtonsDebounced();
    const height2 = container.getBounds().height;
    container.setBounds({ y: rect2.y + rect2.height - height2 });
  }
  onHover(event) {
    if (!this.enabled || this.visible !== "hover" || this.toolbar.isHidden())
      return;
    const {
      container,
      detectionRange,
      ctx: { scene }
    } = this;
    const {
      currentY,
      sourceEvent: { target }
    } = event;
    const element2 = container.getElement();
    const detectionY = element2.offsetTop - detectionRange;
    const visible = currentY > detectionY && currentY < scene.canvas.element.offsetHeight || target === element2;
    this.toggleVisibility(visible);
  }
  onLeave() {
    if (this.visible !== "hover")
      return;
    this.toggleVisibility(false);
  }
  toggleVisibility(visible, immediate = false) {
    const { container, toolbar: toolbar2, verticalSpacing } = this;
    toolbar2.toggleClass("ag-charts-zoom-buttons__toolbar--hidden", !visible);
    const element2 = toolbar2.getElement();
    element2.style.transitionDuration = immediate ? "0s" : "";
    element2.style.transform = visible ? "translateY(0)" : `translateY(${container.getBounds().height + verticalSpacing}px)`;
  }
  toggleButtons() {
    const zoom = definedZoomState(this.ctx.zoomManager.getZoom());
    if (this.previousZoom && isZoomEqual(this.previousZoom, zoom))
      return;
    this.previousZoom = zoom;
    for (const [index, button] of this.buttons.entries()) {
      let enabled = true;
      switch (button?.value) {
        case "pan-start":
          enabled = zoom.x.min > UNIT_MIN;
          break;
        case "pan-end":
          enabled = zoom.x.max < UNIT_MAX;
          break;
        case "pan-left":
          enabled = zoom.x.min > UNIT_MIN;
          break;
        case "pan-right":
          enabled = zoom.x.max < UNIT_MAX;
          break;
        case "zoom-out":
          enabled = !isMaxZoom(zoom);
          break;
        case "zoom-in":
          enabled = this.isZoomValid(
            this.getNextZoomStateUnified("zoom-in", zoom, this.getModuleProperties())
          );
          break;
        case "reset":
          enabled = canResetZoom(this.ctx.zoomManager);
          break;
      }
      this.toolbar.toggleButtonEnabledByIndex(index, enabled);
    }
  }
  onButtonPress({ button }) {
    if (!this.enabled || this.toolbar.isHidden())
      return;
    const props = this.getModuleProperties();
    if (props.independentAxes && button.value !== "reset") {
      const axisZooms = this.ctx.zoomManager.getAxisZooms();
      for (const [axisId, value] of entries(axisZooms)) {
        if (value == null)
          continue;
        const { direction, min, max } = value;
        this.onButtonPressAxis(button, props, axisId, direction, { min, max });
      }
    } else {
      this.onButtonPressUnified(button, props);
    }
  }
  onButtonFocus(_event) {
    this.toggleVisibility(true, true);
  }
  onButtonPressAxis(event, props, axisId, direction, zoom) {
    const { isScalingX, isScalingY, scrollingStep } = props;
    let newZoom = { ...zoom };
    const delta5 = zoom.max - zoom.min;
    switch (event.value) {
      case "pan-start":
        newZoom.max = delta5;
        newZoom.min = 0;
        break;
      case "pan-end":
        newZoom.min = newZoom.max - delta5;
        newZoom.max = UNIT_MAX;
        break;
      case "pan-left":
        newZoom.min -= delta5 * scrollingStep;
        newZoom.max -= delta5 * scrollingStep;
        break;
      case "pan-right":
        newZoom.min += delta5 * scrollingStep;
        newZoom.max += delta5 * scrollingStep;
        break;
      case "zoom-in":
      case "zoom-out": {
        const isDirectionX = direction === "x" /* X */;
        const isScalingDirection = isDirectionX && isScalingX || !isDirectionX && isScalingY;
        let scale2 = event.value === "zoom-in" ? 1 - scrollingStep : 1 + scrollingStep;
        if (!isScalingDirection)
          scale2 = 1;
        const placement = isDirectionX ? this.getAnchorPointX(props) : this.getAnchorPointY(props);
        newZoom.max = newZoom.min + (newZoom.max - newZoom.min) * scale2;
        newZoom = scaleZoomAxisWithAnchor(newZoom, zoom, placement);
        break;
      }
    }
    this.updateAxisZoom(userInteraction5(`zoom-button-${event.value}`), axisId, direction, constrainAxis(newZoom));
  }
  onButtonPressUnified(event, props) {
    const { scrollingStep } = props;
    const oldZoom = definedZoomState(this.ctx.zoomManager.getZoom());
    let zoom = definedZoomState(oldZoom);
    switch (event.value) {
      case "reset":
        this.resetZoom("zoom-button-reset");
        return;
      case "pan-start":
        zoom.x.max = dx(zoom);
        zoom.x.min = 0;
        break;
      case "pan-end":
        zoom.x.min = UNIT_MAX - dx(zoom);
        zoom.x.max = UNIT_MAX;
        break;
      case "pan-left":
        zoom = translateZoom(zoom, -dx(zoom) * scrollingStep, 0);
        break;
      case "pan-right":
        zoom = translateZoom(zoom, dx(zoom) * scrollingStep, 0);
        break;
      case "zoom-in":
      case "zoom-out": {
        zoom = this.getNextZoomStateUnified(event.value, oldZoom, props);
        break;
      }
    }
    this.updateZoom(userInteraction5(`zoom-button-${event.value}`), constrainZoom(zoom));
  }
  getNextZoomStateUnified(button, oldZoom, props) {
    const { isScalingX, isScalingY, scrollingStep } = props;
    const scale2 = button === "zoom-in" ? 1 - scrollingStep : 1 + scrollingStep;
    const zoom = scaleZoom(oldZoom, isScalingX ? scale2 : 1, isScalingY ? scale2 : 1);
    zoom.x = scaleZoomAxisWithAnchor(zoom.x, oldZoom.x, this.getAnchorPointX(props));
    zoom.y = scaleZoomAxisWithAnchor(zoom.y, oldZoom.y, this.getAnchorPointY(props));
    return zoom;
  }
  getAnchorPointX(props) {
    const anchorPointX = this.anchorPointX ?? props.anchorPointX;
    return anchorPointX === "pointer" ? DEFAULT_ANCHOR_POINT_X : anchorPointX;
  }
  getAnchorPointY(props) {
    const anchorPointY = this.anchorPointY ?? props.anchorPointY;
    return anchorPointY === "pointer" ? DEFAULT_ANCHOR_POINT_Y : anchorPointY;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty,
  ActionOnSet({
    changeValue(enabled) {
      this.toolbar?.setHidden(!enabled);
    }
  })
], ZoomToolbar.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ZoomToolbar.prototype, "buttons", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ActionOnSet({
    changeValue(visible, oldValue) {
      if (oldValue == null)
        return;
      const always = visible === "always";
      const zoomed = visible === "zoomed" && this.previousZoom != null && !isMaxZoom(this.previousZoom);
      this.toggleVisibility(always || zoomed);
    }
  })
], ZoomToolbar.prototype, "visible", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ZoomToolbar.prototype, "anchorPointX", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ZoomToolbar.prototype, "anchorPointY", 2);

// packages/ag-charts-enterprise/src/features/zoom/zoomTwoFingers.ts
var N = 1e6;
function clientToNormal({ min, max }, a, Rx, Rw) {
  if (Rw === 0)
    return 0;
  return N * ((a - Rx) / Rw * (max - min) + min);
}
function solveTwoUnknowns(x1, x2, a1, a2, Rx, Rw) {
  [x1, x2] = [Math.min(x1, x2), Math.max(x1, x2)];
  [a1, a2] = [Math.min(a1, a2), Math.max(a1, a2)];
  const t1 = N * (a1 - Rx) / Rw;
  const t2 = N * (a2 - Rx) / Rw;
  const c = (a1 - Rx) / (a2 - Rx);
  const min = (x1 - c * x2) / (N - t1 + c * (t2 - N));
  const max = (x2 + (t2 - N) * min) / t2;
  return { min, max };
}
function isRangeOverlapping(centerA, radiusA, centerB, radiusB) {
  if (radiusA === 0)
    radiusA = 30;
  if (radiusB === 0)
    radiusB = 30;
  const minA = centerA - radiusA;
  const maxA = centerA + radiusA;
  const minB = centerB - radiusB;
  const maxB = centerB + radiusB;
  return !(maxA < minB || maxB < minA);
}
var ZoomTwoFingers = class {
  constructor() {
    this.touchStart = {
      origins: [
        { identifier: 0, normalX: Number.NaN, normalY: Number.NaN },
        { identifier: 0, normalX: Number.NaN, normalY: Number.NaN }
      ]
    };
    this.initialZoom = { x: { min: 0, max: 1 }, y: { min: 0, max: 1 } };
    this.previous = { a1: Number.NaN, a2: Number.NaN, b1: Number.NaN, b2: Number.NaN };
  }
  start(event, target, zoom) {
    if (event.sourceEvent.targetTouches.length !== 2)
      return false;
    event.sourceEvent.preventDefault();
    const targetTouches = Array.from(event.sourceEvent.targetTouches);
    const { x: Rx, y: Ry, width: Rw, height: Rh } = target.getBoundingClientRect();
    this.initialZoom.x.min = zoom.x?.min ?? 0;
    this.initialZoom.x.max = zoom.x?.max ?? 1;
    this.initialZoom.y.min = zoom.y?.min ?? 0;
    this.initialZoom.y.max = zoom.y?.max ?? 1;
    for (const t of this.touchStart.origins) {
      t.identifier = 0;
    }
    this.previous.a1 = Number.NaN;
    this.previous.a2 = Number.NaN;
    this.previous.b1 = Number.NaN;
    this.previous.b2 = Number.NaN;
    for (const i of [0, 1]) {
      const a = targetTouches[i].clientX;
      const b = Ry + Rh - targetTouches[i].clientY;
      this.touchStart.origins[i].identifier = targetTouches[i].identifier;
      this.touchStart.origins[i].normalX = clientToNormal(this.initialZoom.x, a, Rx, Rw);
      this.touchStart.origins[i].normalY = clientToNormal(this.initialZoom.y, b, Ry, Rh);
    }
    const [tA, tB] = targetTouches;
    const [oA, oB] = this.touchStart.origins;
    const xOverlap = isRangeOverlapping(tA.clientX, tA.radiusX, tB.clientX, tB.radiusX);
    const yOverlap = isRangeOverlapping(tA.clientY, tA.radiusY, tB.clientY, tB.radiusY);
    if (yOverlap)
      oA.normalY = oB.normalY = (oA.normalY + oB.normalY) / 2;
    if (xOverlap)
      oA.normalX = oB.normalX = (oA.normalX + oB.normalX) / 2;
    return true;
  }
  update(event, target) {
    event.sourceEvent.preventDefault();
    const targetTouches = Array.from(event.sourceEvent.targetTouches);
    const { x: Rx, y: Ry, width: Rw, height: Rh } = target.getBoundingClientRect();
    const { origins } = this.touchStart;
    const touches = [0, 1].map((i) => targetTouches.find((t) => t.identifier === origins[i].identifier));
    const x1 = origins[0].normalX;
    const x2 = origins[1].normalX;
    const a1 = touches[0].clientX;
    const a2 = touches[1].clientX;
    const y1 = origins[0].normalY;
    const y2 = origins[1].normalY;
    const b1 = Ry + Rh - touches[0].clientY;
    const b2 = Ry + Rh - touches[1].clientY;
    return this.twitchTolerantZoomPan4(x1, x2, a1, a2, y1, y2, b1, b2, Rx, Ry, Rw, Rh);
  }
  end(event) {
    const identifiers = Array.from(event.sourceEvent.targetTouches).map((t) => t.identifier);
    return !identifiers.includes(this.touchStart.origins[0].identifier) || !identifiers.includes(this.touchStart.origins[1].identifier);
  }
  // Small touch deltas on an axis, which can defined as one fingers moving ±1 pixel and the other not moving, can
  // cause the canvas to flicker between two zoompan views.
  //
  // For example, consider two fingers moving upwards slowly on the Y-axis with the following events (Y=0 is the top
  // of the screen):
  //
  //   [0]:  { finger1: { clientY: 101 }, finger2: { clientY: 201 } }
  //   [1]:  { finger1: { clientY: 101 }, finger2: { clientY: 200 } }
  //   [2]:  { finger1: { clientY: 100 }, finger2: { clientY: 200 } }
  //
  // The following transitions cause these changes to the zoompan respectively.
  //
  //   [0] => [1] : yMin decreases, yMax increases
  //   [1] => [2] : yMin increases, yMax decreases
  //
  // At highly-zoomed views, this sudden shift in yMin/yMax in the [1] => [2] transition is very noticeable. When many
  // of these kind of a transitions occur, the chart flickers between pan states instead of smoothly panning. Note
  // however that, if we didn't receive event [1], our transition would like this:
  //
  //   [0] => [2] : yMin increases, yMax increases
  //
  // ... which is a smooth panning transition. Therefore to prevent flickering, we skip event [1].
  twitchTolerantZoomPan4(x1, x2, a1, a2, y1, y2, b1, b2, Rx, Ry, Rw, Rh) {
    const { initialZoom, previous } = this;
    const x = twitchTolerantZoomPan2(x1, x2, a1, a2, previous, "a1", "a2", Rx, Rw, initialZoom.x);
    const y = twitchTolerantZoomPan2(y1, y2, b1, b2, previous, "b1", "b2", Ry, Rh, initialZoom.y);
    return { x, y };
  }
};
function twitchTolerantZoomPan2(x1, x2, a1, a2, previous, previousKey1, previousKey2, Rx, Rw, initialZoom) {
  if (x1 == x2) {
    const xn1 = clientToNormal(initialZoom, a1, Rx, Rw);
    const xn2 = clientToNormal(initialZoom, a2, Rx, Rw);
    const xavg = (xn1 + xn2) / 2;
    const dzoom = (x1 - xavg) / N;
    return { min: initialZoom.min + dzoom, max: initialZoom.max + dzoom };
  } else {
    const a1prev = previous[previousKey1];
    const a2prev = previous[previousKey2];
    const dx2 = Math.abs(a1 - a1prev) + Math.abs(a2 - a2prev);
    if (dx2 <= 1) {
      a1 = a1prev;
      a2 = a2prev;
    } else {
      previous[previousKey1] = a1;
      previous[previousKey2] = a2;
    }
    return solveTwoUnknowns(x1, x2, a1, a2, Rx, Rw);
  }
}

// packages/ag-charts-enterprise/src/features/zoom/zoomWheelSequencer.ts
var ZoomWheelSequencer = class {
  constructor() {
    this.isFirstWheelEvent = true;
    this.debouncedWheelReset = debounce(() => {
      this.isFirstWheelEvent = true;
      this.wasFirstWheelEventZoomCapped = void 0;
    }, 100);
  }
  onWheel(event, callback2) {
    if (event.sourceEvent.cancelable === false) {
      return;
    }
    const result = callback2();
    if (result === "abort")
      return;
    const isZoomCapped = result === "capped";
    if (this.firstWheelEventDirection != null && this.firstWheelEventDirection !== event.deltaY < 0) {
      this.isFirstWheelEvent = true;
    }
    if (this.isFirstWheelEvent) {
      this.wasFirstWheelEventZoomCapped = isZoomCapped;
      this.firstWheelEventDirection = event.deltaY < 0;
      if (!isZoomCapped) {
        event.sourceEvent.preventDefault();
      }
    } else if (this.wasFirstWheelEventZoomCapped === false) {
      event.sourceEvent.preventDefault();
    }
    this.isFirstWheelEvent = false;
    this.debouncedWheelReset();
  }
};

// packages/ag-charts-enterprise/src/features/zoom/zoom.ts
var { userInteraction: userInteraction6, InteractionState: InteractionState7 } = module_support_exports;
var round3 = (value) => roundTo(value, 10);
var CURSOR_ID = "zoom-cursor";
var TOOLTIP_ID = "zoom-tooltip";
var Zoom = class extends AbstractModuleInstance {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.enabled = false;
    this.enableAxisDragging = true;
    this.enableAxisScrolling = true;
    this.enableDoubleClickToReset = true;
    this.enablePanning = true;
    this.enableScrolling = true;
    this.enableSelecting = false;
    this.enableTwoFingerZoom = true;
    this.panKey = "alt";
    this.axes = "x";
    this.scrollingStep = UNIT_SIZE / 10;
    this.keepAspectRatio = false;
    this.minVisibleItems = 2;
    this.anchorPointX = DEFAULT_ANCHOR_POINT_X;
    this.anchorPointY = DEFAULT_ANCHOR_POINT_Y;
    this.autoScaling = new ZoomAutoScalingProperties();
    this.axisDraggingMode = "zoom";
    this.buttons = new ZoomToolbar(
      this.ctx,
      this.getModuleProperties.bind(this),
      this.updateZoom.bind(this),
      this.updateAxisZoom.bind(this),
      this.resetZoom.bind(this),
      this.isZoomValid.bind(this)
    );
    this.onDataChange = new ZoomOnDataChangeProperties();
    // Zoom methods
    this.axisDragger = new ZoomAxisDragger();
    this.panner = new ZoomPanner();
    this.scroller = new ZoomScroller();
    this.scrollPanner = new ZoomScrollPanner();
    this.twoFingers = new ZoomTwoFingers();
    this.deceleration = "short";
    // State
    this.dragState = 0 /* None */;
    this.isState = (state) => this.ctx.interactionManager.isState(state);
    this.destroyContextMenuActions = void 0;
    this.wheelSequencer = new ZoomWheelSequencer();
    this.previousZoomValid = true;
    this.previousAxisZoomValid = {
      ["x" /* X */]: true,
      ["y" /* Y */]: true
    };
    this.toggleAxisDraggingCursorsDebounced = debounce(
      this.toggleAxisDraggingCursors.bind(this),
      ZOOM_VALID_CHECK_DEBOUNCE,
      {
        leading: true,
        trailing: true
      }
    );
    const selectionRect = new ZoomRect();
    this.selector = new ZoomSelector(selectionRect, this.getZoom.bind(this), this.isZoomValid.bind(this));
    this.contextMenu = new ZoomContextMenu(
      ctx.eventsHub,
      ctx.contextMenuRegistry,
      ctx.zoomManager,
      this.getModuleProperties.bind(this),
      () => this.paddedRect,
      this.updateZoom.bind(this),
      this.isZoomValid.bind(this)
    );
    const minVisibleItemsCallback = (event) => {
      if (this.minVisibleItems > 0) {
        const restrictions = event.stateAsDefinedZoom();
        event.constrainZoom(this.constrainZoom(restrictions));
      }
    };
    this.dataChangeHandler = new ZoomOnDataChange(
      minVisibleItemsCallback,
      this.onDataChange,
      this.ctx,
      this.cleanup
    );
    this.domProxy = new ZoomDOMProxy({
      onAxisDragStart: (direction) => this.onAxisDragStart(direction),
      onAxisDragMove: (id, direction, event) => this.onAxisDragMove(id, direction, event),
      onAxisDragEnd: () => this.onAxisDragEnd(),
      onAxisDoubleClick: (id) => this.onAxisDoubleClick(id),
      onAxisWheel: (direction, event) => this.onAxisWheel(direction, event)
    });
    if (ctx.widgets.seriesDragInterpreter) {
      this.cleanup.register(
        ctx.widgets.seriesDragInterpreter.events.on("dblclick", (event) => this.onSeriesAreaDoubleClick(event)),
        ctx.widgets.seriesDragInterpreter.events.on("drag-move", (event) => this.onSeriesAreaDragMove(event)),
        ctx.widgets.seriesDragInterpreter.events.on("drag-start", (event) => this.onSeriesAreaDragStart(event)),
        ctx.widgets.seriesDragInterpreter.events.on("drag-end", () => this.onSeriesAreaDragEnd())
      );
    }
    this.cleanup.register(
      ctx.scene.attachNode(selectionRect),
      ctx.eventsHub.on("series-area:hover", (event) => this.onSeriesAreaHoverEvent(event)),
      ctx.eventsHub.on("series-area:click", (event) => this.onSeriesAreaClickEvent(event)),
      ctx.eventsHub.on("series:keynav-zoom", (event) => this.onNavZoom(event)),
      ctx.widgets.seriesWidget.addListener("wheel", (event) => this.onWheel(event)),
      ctx.widgets.seriesWidget.addListener("touchstart", (event, current) => this.onTouchStart(event, current)),
      ctx.widgets.seriesWidget.addListener("touchmove", (event, current) => this.onTouchMove(event, current)),
      ctx.widgets.seriesWidget.addListener("touchend", (event) => this.onTouchEnd(event)),
      ctx.widgets.seriesWidget.addListener("touchcancel", (event) => this.onTouchEnd(event)),
      ctx.updateService.addListener("process-data", (event) => this.onProcessData(event)),
      ctx.eventsHub.on("layout:complete", (event) => this.onLayoutComplete(event)),
      ctx.eventsHub.on("zoom:change-request", (event) => this.onZoomChangeRequested(event)),
      ctx.eventsHub.on("zoom:pan-start", (event) => this.onZoomPanStart(event)),
      this.panner.addListener("update", (event) => this.onPanUpdate(event)),
      () => this.teardown()
    );
    this.autoScaler = new ZoomAutoScaler(this.autoScaling, ctx.zoomManager, this, ctx.eventsHub, this.cleanup);
  }
  teardown() {
    this.ctx.zoomManager.setZoomModuleEnabled(false);
    this.buttons.destroy();
    this.destroyContextMenuActions?.();
    this.domProxy.destroy();
    this.dataChangeHandler.destroy();
  }
  onEnabledChange(enabled) {
    this.ctx.zoomManager.setZoomModuleEnabled(enabled);
    if (this.contextMenu) {
      this.destroyContextMenuActions?.();
      this.destroyContextMenuActions = this.contextMenu.registerActions(enabled);
    }
  }
  isIgnoredTouch(event) {
    if (event?.device !== "touch") {
      return false;
    }
    if (this.ctx.chartService.touch.dragAction !== "drag") {
      return true;
    }
    if (this.enableSelecting) {
      return false;
    }
    if (!this.enablePanning) {
      return true;
    }
    return isMaxZoom(this.getZoom());
  }
  onSeriesAreaDoubleClick(event) {
    const { enabled, enableDoubleClickToReset } = this;
    if (!enabled || !enableDoubleClickToReset)
      return;
    if (event?.preventZoomDblClick || !this.isState(InteractionState7.ZoomClickable))
      return;
    this.resetZoom("zoom-seriesarea-dblclick");
  }
  onSeriesAreaHoverEvent(event) {
    if (!this.shouldHandleAxisHover(event)) {
      this.clearHoveredAxis();
      return;
    }
    const axis = this.domProxy.pickAxisAtPoint(event);
    if (axis) {
      this.domProxy.setHoveredAxis(axis.axisId);
      this.ctx.domManager.updateCursor(CURSOR_ID, this.domProxy.getCursor(axis.direction));
    } else {
      this.clearHoveredAxis();
    }
  }
  onSeriesAreaClickEvent(event) {
    if (!this.shouldHandleAxisClick(event))
      return;
    const axis = this.domProxy.pickAxisAtPoint(event);
    if (axis && event.sourceEvent?.type === "dblclick") {
      this.onAxisDoubleClick(axis.axisId);
    }
  }
  shouldHandleAxisHover(event) {
    const { enabled, enableAxisDragging, enableAxisScrolling, dragState } = this;
    return enabled && (enableAxisDragging || enableAxisScrolling) && !event.consumed && !this.activeAxis && dragState === 0 /* None */ && this.domProxy.hasOverlappingAxes();
  }
  shouldHandleAxisClick(event) {
    const { enabled, enableAxisDragging, enableAxisScrolling, enableDoubleClickToReset } = this;
    return enabled && !this.activeAxis && !event.consumed && (enableAxisDragging || enableAxisScrolling || enableDoubleClickToReset);
  }
  clearHoveredAxis() {
    if (this.activeAxis)
      return;
    this.domProxy.clearHoveredAxis();
    if (this.dragState === 0 /* None */) {
      this.ctx.domManager.updateCursor(CURSOR_ID);
    }
  }
  tryBeginAxisDelegation(event) {
    const hoveredAxis = this.domProxy.getHoveredAxis();
    if (!this.enabled || !this.enableAxisDragging || !hoveredAxis) {
      return false;
    }
    if (!this.domProxy.beginDelegatedAxisDrag(hoveredAxis.axisId)) {
      return false;
    }
    this.activeAxis = hoveredAxis;
    this.onAxisDragStart(hoveredAxis.direction);
    const cursor = this.dragState === 2 /* Pan */ ? "grabbing" : this.domProxy.getCursor(hoveredAxis.direction);
    this.ctx.domManager.updateCursor(CURSOR_ID, cursor);
    if (event.device === "touch") {
      event.sourceEvent.preventDefault();
    }
    return true;
  }
  onSeriesAreaDragStart(event) {
    const {
      enabled,
      enablePanning,
      enableSelecting,
      ctx: { domManager, zoomManager }
    } = this;
    if (!enabled || !this.isState(InteractionState7.ZoomDraggable) || this.dragState !== 0 /* None */ || this.isIgnoredTouch(event)) {
      return;
    }
    this.panner.stopInteractions();
    if (this.tryBeginAxisDelegation(event)) {
      return;
    }
    let newDragState = 0 /* None */;
    const panKeyPressed = this.isPanningKeyPressed(event.sourceEvent);
    if (enablePanning && (!enableSelecting || panKeyPressed)) {
      domManager.updateCursor(CURSOR_ID, "grabbing");
      newDragState = 2 /* Pan */;
      this.panner.start();
    } else if (enableSelecting && !panKeyPressed) {
      newDragState = 3 /* Select */;
    }
    if ((this.dragState = newDragState) !== 0 /* None */) {
      zoomManager.fireZoomPanStartEvent("zoom");
    }
  }
  onSeriesAreaDragMove(event) {
    const {
      dragState,
      enabled,
      paddedRect,
      panner,
      selector,
      ctx: { interactionManager, tooltipManager, updateService }
    } = this;
    if (this.activeAxis) {
      this.onAxisDragMove(this.activeAxis.axisId, this.activeAxis.direction, event);
      return;
    }
    if (!enabled || !paddedRect || !this.isState(InteractionState7.ZoomDraggable) || this.isIgnoredTouch(event)) {
      return;
    }
    interactionManager.pushState(module_support_exports.InteractionState.ZoomDrag);
    if (event.device === "touch") {
      event.sourceEvent.preventDefault();
    }
    switch (dragState) {
      case 2 /* Pan */:
        panner.update(event);
        break;
      case 3 /* Select */:
        selector.update(event, this.getModuleProperties(), paddedRect);
        break;
      case 0 /* None */:
        return;
    }
    tooltipManager.updateTooltip(TOOLTIP_ID);
    updateService.update(5 /* PERFORM_LAYOUT */, { skipAnimations: true });
  }
  onSeriesAreaDragEnd() {
    const {
      ctx: { interactionManager }
    } = this;
    if (this.activeAxis) {
      this.handleAxisDragEnd();
      return;
    }
    interactionManager.popState(module_support_exports.InteractionState.ZoomDrag);
    if (!this.enabled || this.dragState === 0 /* None */)
      return;
    this.handleRegularDragEnd();
    this.resetDragState();
  }
  handleAxisDragEnd() {
    this.onAxisDragEnd();
    this.domProxy.endDelegatedAxisDrag(this.activeAxis.axisId);
    this.activeAxis = void 0;
    this.clearHoveredAxis();
  }
  handleRegularDragEnd() {
    const { panner, selector } = this;
    switch (this.dragState) {
      case 2 /* Pan */:
        panner.stop();
        break;
      case 3 /* Select */:
        if (selector.didUpdate()) {
          const newZoom = selector.stop(this.seriesRect, this.paddedRect, this.getZoom());
          if (newZoom) {
            this.updateZoom(userInteraction6("zoom-seriesarea-selector"), newZoom);
          } else {
            this.ctx.updateService.update();
          }
        }
        break;
    }
  }
  resetDragState() {
    this.dragState = 0 /* None */;
    this.ctx.domManager.updateCursor(CURSOR_ID);
    this.ctx.tooltipManager.removeTooltip(TOOLTIP_ID);
  }
  onAxisDoubleClick(id) {
    const {
      enabled,
      enableDoubleClickToReset,
      ctx: { zoomManager }
    } = this;
    if (!enabled || !enableDoubleClickToReset || !this.isState(InteractionState7.ZoomClickable))
      return;
    this.previousAxisZoomValid = { ["x" /* X */]: true, ["y" /* Y */]: true };
    zoomManager.resetAxisZoom({ source: "user-interaction", sourceDetail: "zoom-axis-dblclick" }, id);
  }
  onAxisDragStart(direction) {
    const {
      axisDraggingMode,
      domProxy,
      enabled,
      enableAxisDragging,
      panner,
      ctx: { zoomManager }
    } = this;
    if (!enabled || !enableAxisDragging)
      return;
    panner.stopInteractions();
    if (axisDraggingMode === "pan") {
      domProxy.setAxisCursor("grabbing");
      this.dragState = 2 /* Pan */;
      this.panner.start(direction);
      zoomManager.fireZoomPanStartEvent("zoom");
    } else {
      this.dragState = 1 /* Axis */;
    }
  }
  onAxisDragMove(axisId, direction, event) {
    const {
      anchorPointX,
      anchorPointY,
      axisDragger,
      dragState,
      enabled,
      enableAxisDragging,
      seriesRect,
      shouldFlipXY,
      ctx: { interactionManager, tooltipManager, updateService, zoomManager }
    } = this;
    if (!enabled || !enableAxisDragging || !seriesRect)
      return;
    interactionManager.pushState(module_support_exports.InteractionState.ZoomDrag);
    if (event.device === "touch") {
      event.sourceEvent.preventDefault();
    }
    const zoom = this.getZoom();
    if (dragState === 2 /* Pan */) {
      this.panner.update({ currentX: event.offsetX, currentY: event.offsetY });
    } else {
      let anchor = direction === "x" /* X */ ? anchorPointX : anchorPointY;
      if (shouldFlipXY)
        anchor = direction === "x" /* X */ ? anchorPointY : anchorPointX;
      const axisZoom = zoomManager.getAxisZoom(axisId);
      const newZoom = axisDragger.update(event, direction, anchor, seriesRect, zoom, axisZoom);
      this.autoScaler.onManualAdjustment(direction);
      this.updateAxisZoom(
        userInteraction6("zoom-axis-drag"),
        axisId,
        direction,
        newZoom,
        { directional: true }
      );
    }
    tooltipManager.updateTooltip(TOOLTIP_ID);
    updateService.update(5 /* PERFORM_LAYOUT */, { skipAnimations: true });
  }
  onAxisDragEnd() {
    const {
      axisDraggingMode,
      axisDragger,
      dragState,
      domProxy,
      enabled,
      enableAxisDragging,
      ctx: { domManager, interactionManager, tooltipManager }
    } = this;
    interactionManager.popState(module_support_exports.InteractionState.ZoomDrag);
    if (!enabled || !enableAxisDragging || dragState === 0 /* None */)
      return;
    this.dragState = 0 /* None */;
    if (axisDraggingMode === "pan") {
      domProxy.setAxisCursor("grab");
      this.panner.stop();
    }
    axisDragger.stop();
    domManager.updateCursor(CURSOR_ID);
    tooltipManager.removeTooltip(TOOLTIP_ID);
  }
  onNavZoom(event) {
    const { enabled, enableScrolling, scroller } = this;
    const isDefaultState = this.ctx.interactionManager.isState(module_support_exports.InteractionState.Default);
    if (!isDefaultState || !enabled || !enableScrolling)
      return;
    event.widgetEvent.sourceEvent.preventDefault();
    this.updateZoom(
      userInteraction6(`keyboard(${event.delta})`),
      scroller.updateDelta(event.delta, this.getModuleProperties(), this.getZoom())
    );
  }
  onWheel(event) {
    const { enabled, enablePanning, enableScrolling, paddedRect } = this;
    if (!enabled || !enableScrolling || !paddedRect || !this.isState(InteractionState7.ZoomWheelable))
      return;
    const { deltaX, deltaY } = event.sourceEvent;
    const isHorizontalScrolling = deltaX != null && deltaY != null && Math.abs(deltaX) > Math.abs(deltaY);
    if (enablePanning && isHorizontalScrolling) {
      this.onWheelPanning(event);
    } else {
      this.onWheelScrolling(event);
    }
  }
  onWheelPanning(event) {
    const {
      scrollingStep,
      scrollPanner,
      seriesRect,
      ctx: { zoomManager }
    } = this;
    if (!seriesRect)
      return;
    event.sourceEvent.preventDefault();
    const newZooms = scrollPanner.update(event, scrollingStep, seriesRect, zoomManager.getAxisZooms());
    this.updateChanges(userInteraction6("zoom-seriesarea-wheel"), newZooms);
  }
  onWheelScrolling(event) {
    const zoom = this.getZoom();
    const isZoomCapped = event.deltaY > 0 && isMaxZoom(zoom);
    this.wheelSequencer.onWheel(event, () => this.handleWheelScrolling(event, isZoomCapped));
  }
  onAxisWheel(axisDirection, event) {
    if (!this.enableAxisScrolling)
      return;
    if (axisDirection !== "x" /* X */ && axisDirection !== "y" /* Y */) {
      return;
    }
    const isScalingX = axisDirection === "x" /* X */;
    const isScalingY = !isScalingX;
    const props = this.getModuleProperties({ isScalingX, isScalingY });
    const zoom = this.getZoom();
    const isZoomCapped = event.deltaY > 0 && zoom[axisDirection].min === UNIT_MIN && zoom[axisDirection].max === UNIT_MAX;
    this.autoScaler.onManualAdjustment(axisDirection);
    this.wheelSequencer.onWheel(event, () => this.handleWheelScrolling(event, isZoomCapped, props));
  }
  handleWheelScrolling(event, isZoomCapped, props = this.getModuleProperties()) {
    const {
      enableIndependentAxes,
      scroller,
      seriesRect,
      ctx: { zoomManager }
    } = this;
    if (!seriesRect)
      return "abort";
    let updated = true;
    const sourcing = userInteraction6("zoom-axis-wheel");
    if (enableIndependentAxes === true) {
      const newZooms = scroller.updateAxes(event, props, seriesRect, zoomManager.getAxisZooms());
      for (const [axisId, { direction, min, max }] of entries(newZooms)) {
        const constrainedZoom = direction === "x" /* X */ ? this.constrainZoom({ x: { min, max }, y: { min: UNIT_MAX, max: UNIT_MAX } }).x : { min, max };
        updated && (updated = this.updateAxisZoom(sourcing, axisId, direction, constrainedZoom));
      }
    } else {
      const newZoom = scroller.update(event, props, seriesRect, this.getZoom());
      if (newZoom == null)
        return "abort";
      updated = this.updateUnifiedZoom(sourcing, newZoom, { directional: true });
    }
    return isZoomCapped || event.deltaY < 0 && !updated ? "capped" : "uncapped";
  }
  onTouchStart(event, current) {
    if (!this.enableTwoFingerZoom || this.dragState !== 0 /* None */)
      return;
    if (this.twoFingers.start(event, current, this.getZoom())) {
      this.dragState = 4 /* TwoFingers */;
    }
  }
  onTouchMove(event, current) {
    if (!this.enableTwoFingerZoom || this.dragState !== 4 /* TwoFingers */)
      return;
    const newZoom = this.twoFingers.update(event, current);
    this.updateZoom(userInteraction6("zoom-seriesarea-twofingers"), constrainZoom(newZoom));
  }
  onTouchEnd(event) {
    if (!this.enableTwoFingerZoom || this.dragState !== 4 /* TwoFingers */)
      return;
    event.sourceEvent.preventDefault();
    if (this.twoFingers.end(event)) {
      this.dragState = 0 /* None */;
    }
  }
  onProcessData(event) {
    this.shouldFlipXY = event.series.shouldFlipXY;
  }
  onLayoutComplete(event) {
    this.domProxy.update(
      this.enabled,
      this.enableAxisDragging,
      this.enableAxisScrolling,
      this.ctx,
      event.series.rect
    );
    if (!this.enabled)
      return;
    this.seriesRect = event.series.rect;
    this.paddedRect = event.series.paddedRect;
    if (this.enableAxisDragging) {
      this.toggleAxisDraggingCursorsDebounced();
    }
  }
  onZoomChangeRequested(event) {
    if (event.sourceDetail !== "zoom-seriesarea-panner") {
      this.panner.stopInteractions();
    }
    const zoom = this.getZoom();
    this.buttons.toggleVisibleZoomed(isMaxZoom(zoom));
  }
  onZoomPanStart(event) {
    if (event.callerId === "zoom") {
      this.panner.stopInteractions();
    }
  }
  onPanUpdate(event) {
    const {
      panner,
      seriesRect,
      ctx: { tooltipManager, zoomManager }
    } = this;
    if (!seriesRect)
      return;
    const newZooms = panner.translateZooms(seriesRect, zoomManager.getAxisZooms(), event.deltaX, event.deltaY);
    this.updateChanges(userInteraction6("zoom-seriesarea-panner"), newZooms);
    tooltipManager.updateTooltip(TOOLTIP_ID);
  }
  isPanningKeyPressed(event) {
    switch (this.panKey) {
      case "alt":
        return event.altKey;
      case "ctrl":
        return event.ctrlKey;
      case "shift":
        return event.shiftKey;
      case "meta":
        return event.metaKey;
    }
  }
  isScalingX() {
    if (this.axes === "xy")
      return true;
    return this.shouldFlipXY ? this.axes === "y" : this.axes === "x";
  }
  isScalingY() {
    if (this.axes === "xy")
      return true;
    return this.shouldFlipXY ? this.axes === "x" : this.axes === "y";
  }
  getAnchorPointX() {
    return this.shouldFlipXY ? this.anchorPointY : this.anchorPointX;
  }
  getAnchorPointY() {
    return this.shouldFlipXY ? this.anchorPointX : this.anchorPointY;
  }
  constrainZoom(newZoom) {
    return this.ctx.zoomManager.constrainZoomToItemCount(newZoom, this.minVisibleItems, this.autoScaler.enabled);
  }
  isZoomValid(newZoom, options) {
    const {
      minVisibleItems,
      ctx: { zoomManager }
    } = this;
    if (minVisibleItems === 0) {
      this.previousZoomValid = true;
      return true;
    }
    const zoom = this.getZoom();
    const zoomedInX = round3(dx(newZoom)) < round3(dx(zoom));
    const zoomedInY = round3(dy(newZoom)) < round3(dy(zoom));
    if (!zoomedInX && !zoomedInY) {
      this.previousZoomValid = true;
      return true;
    }
    if (!this.previousZoomValid && options?.directional) {
      return false;
    }
    const includeYVisibleRange = options?.includeYVisibleRange ?? false;
    const autoScaleYAxis = this.autoScaler.enabled;
    const valid = zoomManager.isVisibleItemsCountAtLeast(newZoom, minVisibleItems, {
      includeYVisibleRange,
      autoScaleYAxis
    });
    this.previousZoomValid = options?.directional ? valid : true;
    return valid;
  }
  isAxisZoomValid(direction, axisZoom, options) {
    const {
      minVisibleItems,
      ctx: { zoomManager }
    } = this;
    const zoom = this.getZoom();
    const deltaAxis = axisZoom.max - axisZoom.min;
    const deltaOld = zoom[direction].max - zoom[direction].min;
    const newZoom = { ...zoom, [direction]: axisZoom };
    if (deltaAxis >= deltaOld) {
      this.previousAxisZoomValid[direction] = true;
      return true;
    }
    if (!this.previousAxisZoomValid[direction] && options?.directional) {
      return false;
    }
    const opts = { includeYVisibleRange: false, autoScaleYAxis: this.autoScaler.enabled };
    const valid = zoomManager.isVisibleItemsCountAtLeast(newZoom, minVisibleItems, opts);
    this.previousAxisZoomValid[direction] = options?.directional ? valid : true;
    return valid;
  }
  resetZoom(sourceDetail) {
    this.previousZoomValid = true;
    this.previousAxisZoomValid = { ["x" /* X */]: true, ["y" /* Y */]: true };
    this.ctx.zoomManager.resetZoom({ source: "user-interaction", sourceDetail });
  }
  updateSyncZoom(zoom) {
    this.updateZoom({ source: "sync", sourceDetail: "internal-updateSyncZoom" }, zoom);
  }
  updateChanges(sourcing, changes) {
    const partialZoom = this.ctx.zoomManager.toZoomState(changes) ?? {};
    const currentZoom = definedZoomState(this.ctx.zoomManager.getZoom());
    this.updateZoom(sourcing, {
      x: partialZoom.x ?? currentZoom.x,
      y: partialZoom.y ?? currentZoom.y
    });
  }
  updateZoom(sourcing, zoom) {
    if (this.enableIndependentAxes) {
      this.updatePrimaryAxisZooms(sourcing, zoom);
    } else {
      this.updateUnifiedZoom(sourcing, zoom);
    }
  }
  updateUnifiedZoom(sourcing, zoom, validOptions) {
    zoom = this.constrainZoom(zoom);
    if (!this.isZoomValid(zoom, validOptions)) {
      this.ctx.updateService.update(9 /* SCENE_RENDER */, { skipAnimations: true });
      return false;
    }
    this.ctx.zoomManager.updateZoom(sourcing, zoom);
    return true;
  }
  updatePrimaryAxisZooms(sourcing, zoom) {
    this.updatePrimaryAxisZoom(sourcing, zoom, "x" /* X */);
    this.updatePrimaryAxisZoom(sourcing, zoom, "y" /* Y */);
  }
  updatePrimaryAxisZoom(sourcing, zoom, direction) {
    const axisId = this.ctx.zoomManager.getPrimaryAxisId(direction);
    if (axisId == null)
      return;
    this.updateAxisZoom(sourcing, axisId, direction, zoom[direction]);
  }
  updateAxisZoom(sourcing, axisId, direction, axisZoom, validOptions) {
    const {
      enableIndependentAxes,
      ctx: { zoomManager }
    } = this;
    if (!axisZoom)
      return false;
    const zoom = this.getZoom();
    if (enableIndependentAxes !== true) {
      zoom[direction] = axisZoom;
      return this.updateUnifiedZoom(sourcing, zoom, validOptions);
    }
    if (!this.isAxisZoomValid(direction, axisZoom, validOptions))
      return false;
    const { source, sourceDetail } = sourcing;
    zoomManager.updateChanges({ source, sourceDetail, changes: { [axisId]: axisZoom }, isReset: false });
    return true;
  }
  updateAxisCursor(opts) {
    if (!this.domProxy)
      return;
    const {
      enableAxisDragging = this.enableAxisDragging,
      enableAxisScrolling = this.enableAxisScrolling,
      axisDraggingMode = this.axisDraggingMode
    } = opts;
    if (enableAxisDragging) {
      this.domProxy.setAxisCursor(axisDraggingMode === "pan" ? "grab" : void 0);
    } else if (enableAxisScrolling) {
      this.domProxy.setAxisCursor("default");
    } else {
      this.domProxy.setAxisCursor(void 0);
    }
  }
  toggleAxisDraggingCursors() {
    const { anchorPointX, anchorPointY, domProxy } = this;
    const zoom = this.getZoom();
    let showCursorX = dx(zoom) !== UNIT_SIZE;
    let showCursorY = dy(zoom) !== UNIT_SIZE;
    if (!showCursorX) {
      const checkZoomX = scaleZoom(zoom, 0.999, 1);
      checkZoomX.x = scaleZoomAxisWithAnchor(checkZoomX.x, zoom.x, anchorPointX);
      showCursorX = this.isZoomValid(checkZoomX, { includeYVisibleRange: true });
    }
    if (!showCursorY) {
      const checkZoomY = scaleZoom(zoom, 1, 0.999);
      checkZoomY.y = scaleZoomAxisWithAnchor(checkZoomY.y, zoom.y, anchorPointY);
      showCursorY = this.isZoomValid(checkZoomY, { includeYVisibleRange: true });
    }
    domProxy.toggleAxisDraggingCursor("x" /* X */, showCursorX);
    domProxy.toggleAxisDraggingCursor("y" /* Y */, showCursorY);
  }
  getZoom() {
    return definedZoomState(this.ctx.zoomManager.getZoom());
  }
  getModuleProperties(overrides) {
    return {
      anchorPointX: overrides?.anchorPointX ?? this.getAnchorPointX(),
      anchorPointY: overrides?.anchorPointY ?? this.getAnchorPointY(),
      enabled: overrides?.enabled ?? this.enabled,
      independentAxes: overrides?.independentAxes ?? this.enableIndependentAxes === true,
      isScalingX: overrides?.isScalingX ?? this.isScalingX(),
      isScalingY: overrides?.isScalingY ?? this.isScalingY(),
      keepAspectRatio: overrides?.keepAspectRatio ?? this.keepAspectRatio,
      scrollingStep: overrides?.scrollingStep ?? this.scrollingStep
    };
  }
};
__decorateClass([
  ActionOnSet({
    newValue(enabled) {
      this.onEnabledChange(enabled);
    }
  }),
  addFakeTransformToInstanceProperty
], Zoom.prototype, "enabled", 2);
__decorateClass([
  ActionOnSet({
    changeValue(newValue) {
      this.updateAxisCursor({ enableAxisDragging: newValue });
    }
  }),
  addFakeTransformToInstanceProperty
], Zoom.prototype, "enableAxisDragging", 2);
__decorateClass([
  ActionOnSet({
    changeValue(newValue) {
      this.updateAxisCursor({ enableAxisScrolling: newValue });
    }
  }),
  addFakeTransformToInstanceProperty
], Zoom.prototype, "enableAxisScrolling", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Zoom.prototype, "enableDoubleClickToReset", 2);
__decorateClass([
  ActionOnSet({
    changeValue(newValue) {
      this.ctx.zoomManager.setIndependentAxes(Boolean(newValue));
    }
  }),
  addFakeTransformToInstanceProperty
], Zoom.prototype, "enableIndependentAxes", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Zoom.prototype, "enablePanning", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Zoom.prototype, "enableScrolling", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Zoom.prototype, "enableSelecting", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Zoom.prototype, "enableTwoFingerZoom", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Zoom.prototype, "panKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Zoom.prototype, "axes", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Zoom.prototype, "scrollingStep", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Zoom.prototype, "keepAspectRatio", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Zoom.prototype, "minVisibleItems", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Zoom.prototype, "anchorPointX", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Zoom.prototype, "anchorPointY", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Zoom.prototype, "autoScaling", 2);
__decorateClass([
  ActionOnSet({
    changeValue(newValue) {
      this.updateAxisCursor({ axisDraggingMode: newValue });
    }
  }),
  addFakeTransformToInstanceProperty
], Zoom.prototype, "axisDraggingMode", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Zoom.prototype, "buttons", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Zoom.prototype, "onDataChange", 2);
__decorateClass([
  ProxyProperty("panner.deceleration"),
  addFakeTransformToInstanceProperty
], Zoom.prototype, "deceleration", 2);

// packages/ag-charts-enterprise/src/features/zoom/zoomModule.ts
var zoomAnchorPoint = union("pointer", "start", "middle", "end");
var ZoomModule = {
  type: "plugin",
  name: "zoom",
  enterprise: true,
  version: VERSION,
  options: {
    enabled: boolean,
    enableAxisDragging: boolean,
    enableAxisScrolling: boolean,
    enableDoubleClickToReset: boolean,
    enablePanning: boolean,
    enableScrolling: boolean,
    enableSelecting: boolean,
    enableTwoFingerZoom: boolean,
    keepAspectRatio: boolean,
    anchorPointX: zoomAnchorPoint,
    anchorPointY: zoomAnchorPoint,
    axisDraggingMode: union("pan", "zoom"),
    axes: union("x", "y", "xy"),
    deceleration: or(union("off", "short", "long"), ratio),
    minVisibleItems: positiveNumber,
    panKey: union("alt", "ctrl", "meta", "shift"),
    scrollingStep: ratio,
    autoScaling: {
      enabled: boolean,
      padding: ratio
    },
    onDataChange: {
      strategy: strictUnion()("reset", "preserveDomain", "preserveRatios"),
      stickToEnd: boolean
    },
    buttons: {
      enabled: boolean,
      buttons: arrayOfDefs(
        {
          ...toolbarButtonOptionsDefs,
          value: union("reset", "zoom-in", "zoom-out", "pan-left", "pan-right", "pan-start", "pan-end"),
          section: string
        },
        "zoom button options array"
      ),
      visible: union("always", "zoomed", "hover")
    }
  },
  themeTemplate: {
    enabled: false,
    enableAxisDragging: true,
    enableAxisScrolling: true,
    enableDoubleClickToReset: true,
    enablePanning: true,
    enableScrolling: true,
    enableSelecting: false,
    enableTwoFingerZoom: true,
    deceleration: "short",
    minVisibleItems: 2,
    panKey: "alt",
    scrollingStep: 0.1,
    autoScaling: {
      enabled: {
        $and: [
          { $eq: [{ $path: "../axes" }, "x"] },
          { $not: { $eq: [{ $path: "/series/0/direction" }, "horizontal"] } }
        ]
      },
      padding: 0.05
    },
    onDataChange: {
      strategy: "preserveDomain",
      stickToEnd: false
      // TODO(olegat): change default to 'true'
    },
    anchorPointX: "end",
    anchorPointY: "middle",
    axes: "x",
    buttons: {
      enabled: { $path: "../enabled" },
      visible: "hover",
      buttons: {
        $shallowSimple: [
          { icon: "zoom-out", value: "zoom-out", section: "scale" },
          { icon: "zoom-in", value: "zoom-in", section: "scale" },
          { icon: "pan-left", value: "pan-left", section: "pan" },
          { icon: "pan-right", value: "pan-right", section: "pan" },
          { icon: "reset", value: "reset", section: "reset" }
        ]
      }
    }
  },
  create: (ctx) => new Zoom(ctx)
};
ZoomModule.options.enableIndependentAxes = undocumented(boolean);
ZoomModule.options.buttons.anchorPointX = undocumented(zoomAnchorPoint);
ZoomModule.options.buttons.anchorPointY = undocumented(zoomAnchorPoint);

// packages/ag-charts-enterprise/src/utils/formatter.ts
function formatWithContext(ctx, formatter2, params) {
  return callWithContext(ctx.chartService, formatter2, params);
}

// packages/ag-charts-enterprise/src/gradient-legend/axisTicks.ts
var { AxisInterval: AxisInterval2, AxisLabel: AxisLabel3, LinearScale: LinearScale2, BBox: BBox22, TranslatableGroup: TranslatableGroup5, Selection: Selection7, Text: Text5 } = module_support_exports;
var _AxisTicks = class _AxisTicks {
  constructor(ctx, dataProvider) {
    this.ctx = ctx;
    this.dataProvider = dataProvider;
    this.id = createId(this);
    this.axisGroup = new TranslatableGroup5({ name: `${this.id}-AxisTicks`, zIndex: 3 /* AXIS */ });
    this.labelSelection = Selection7.select(this.axisGroup, Text5);
    this.interval = new AxisInterval2();
    this.label = new AxisLabel3();
    this.scale = new LinearScale2();
    this.placement = "bottom";
    this.translationX = 0;
    this.translationY = 0;
    this.padding = 0;
  }
  get horizontal() {
    return this.placement.startsWith("top") || this.placement.startsWith("bottom");
  }
  attachAxis(axisNode) {
    axisNode.appendChild(this.axisGroup);
  }
  calculateLayout() {
    const { placement, translationX, translationY, horizontal, label } = this;
    function unreachable(_a) {
      return void 0;
    }
    let textBaseline;
    let textAlign;
    switch (placement) {
      case "top":
      case "top-right":
      case "top-left":
        textBaseline = "bottom";
        textAlign = "center";
        label.mirrored = false;
        label.parallel = true;
        break;
      case "bottom":
      case "bottom-right":
      case "bottom-left":
        textBaseline = "top";
        textAlign = "center";
        label.mirrored = false;
        label.parallel = true;
        break;
      case "right":
      case "right-top":
      case "right-bottom":
      case "left":
      case "left-top":
      case "left-bottom":
        textBaseline = "middle";
        textAlign = "left";
        label.mirrored = true;
        label.parallel = false;
        break;
      default:
        unreachable(placement);
    }
    const boxes = [];
    const tickGenerationResult = this.generateTicks();
    const { ticks } = tickGenerationResult;
    this.labelSelection.update(ticks, void 0, (datum) => datum.tickId);
    this.axisGroup.setProperties({ translationX, translationY });
    this.labelSelection.each((node, datum) => {
      node.fontFamily = label.fontFamily;
      node.fontSize = label.fontSize;
      node.fontStyle = label.fontStyle;
      node.fontWeight = label.fontWeight;
      node.fill = label.color;
      node.textBaseline = textBaseline;
      node.textAlign = textAlign;
      node.text = datum.tickLabel;
      node.x = horizontal ? datum.translation : 0;
      node.y = horizontal ? 0 : datum.translation;
      boxes.push(node.getBBox());
    });
    return boxes.length > 0 ? BBox22.merge(boxes).translate(translationX, translationY) : void 0;
  }
  tickFormatter(domain, _ticks, _primary, fractionDigits) {
    const { ctx } = this;
    const { formatManager } = ctx;
    const boundSeries = this.dataProvider.data.flatMap((d) => d.series);
    return (value, index) => {
      const formatParams = {
        type: "number",
        value,
        datum: void 0,
        seriesId: void 0,
        legendItemName: void 0,
        key: void 0,
        source: "gradient-legend",
        property: "color",
        domain,
        boundSeries,
        fractionDigits,
        visibleDomain: void 0
      };
      return this.label.formatValue((fn, params) => formatWithContext(ctx, fn, params), formatParams, index) ?? formatManager.format((fn, params) => formatWithContext(ctx, fn, params), formatParams) ?? formatManager.defaultFormat(formatParams);
    };
  }
  inRange(x, tolerance = 1e-3) {
    const [min, max] = findMinMax(this.scale.range);
    return x >= min - tolerance && x <= max + tolerance;
  }
  generateTicks() {
    const { minSpacing, maxSpacing } = this.interval;
    const { maxTickCount, minTickCount, tickCount } = estimateTickCount(
      findRangeExtent(this.scale.range),
      1,
      minSpacing,
      maxSpacing,
      _AxisTicks.DefaultTickCount,
      _AxisTicks.DefaultMinSpacing
    );
    const tickData = this.getTicksData({
      nice: [true, true],
      interval: this.interval.step,
      tickCount,
      minTickCount,
      maxTickCount
    });
    if (this.placement === "bottom" || this.placement === "top") {
      const measurer3 = cachedTextMeasurer(this.label);
      const { domain } = this.scale;
      const reversed = domain[0] > domain[1];
      const direction = reversed ? -1 : 1;
      let lastTickPosition = -Infinity * direction;
      tickData.ticks = tickData.ticks.filter((data) => {
        if (Math.sign(data.translation - lastTickPosition) !== direction)
          return false;
        const { width: labelWidth } = isArray(data.tickLabel) ? measureTextSegments(data.tickLabel, this.label) : measurer3.measureLines(toTextString(data.tickLabel));
        lastTickPosition = data.translation + labelWidth * direction;
        return true;
      });
    }
    return tickData;
  }
  getTicksData(tickParams) {
    const ticks = [];
    const domain = tickParams.nice ? this.scale.niceDomain(tickParams) : this.scale.domain;
    const rawTicks = this.scale.ticks(tickParams, domain)?.ticks ?? [];
    const fractionDigits = rawTicks.reduce((max, tick) => Math.max(max, countFractionDigits(tick)), 0);
    const idGenerator = createIdsGenerator();
    const tickFormatter = this.tickFormatter(domain, rawTicks, false, fractionDigits);
    for (let index = 0; index < rawTicks.length; index++) {
      const tick = rawTicks[index];
      const translation = this.scale.convert(tick);
      if (!this.inRange(translation))
        continue;
      const tickLabel = tickFormatter(tick, index);
      if (tickLabel == null || tickLabel === "")
        continue;
      const tickId = idGenerator(toPlainText(tickLabel));
      ticks.push({ tick, tickId, tickLabel, translation });
    }
    return { rawTicks, fractionDigits, ticks };
  }
};
_AxisTicks.className = "AxisTicks";
_AxisTicks.DefaultTickCount = 5;
_AxisTicks.DefaultMinSpacing = 10;
var AxisTicks = _AxisTicks;

// packages/ag-charts-enterprise/src/gradient-legend/gradientLegend.ts
var { LayoutElement: LayoutElement7, Group: Group12, Rect: Rect9, Marker: Marker3, TranslatableGroup: TranslatableGroup6, BBox: BBox23 } = module_support_exports;
var GradientBar = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.thickness = 16;
    this.preferredLength = 100;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], GradientBar.prototype, "thickness", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], GradientBar.prototype, "preferredLength", 2);
var GradientLegendScale = class extends BaseProperties {
  constructor(axisTicks) {
    super();
    this.axisTicks = axisTicks;
  }
};
__decorateClass([
  ProxyProperty("axisTicks.label")
], GradientLegendScale.prototype, "label", 2);
__decorateClass([
  ProxyProperty("axisTicks.interval")
], GradientLegendScale.prototype, "interval", 2);
__decorateClass([
  ProxyProperty("axisTicks.padding")
], GradientLegendScale.prototype, "padding", 2);
var GradientLegend = class extends BaseProperties {
  constructor(ctx) {
    super();
    this.ctx = ctx;
    this.id = createId(this);
    this.legendGroup = new TranslatableGroup6({ name: "legend", zIndex: 16 /* LEGEND */ });
    this.containerNode = this.legendGroup.appendChild(new Rect9({ name: "legend-container" }));
    this.gradientRect = new Rect9();
    this.arrow = new Marker3({ shape: "triangle" });
    this.ticksGroup = new Group12({ name: "legend-axis-group" });
    this.cleanup = new CleanupRegistry();
    this.enabled = false;
    this.position = "bottom";
    this.reverseOrder = false;
    this.gradient = new GradientBar();
    this.spacing = 20;
    this.border = new Border(this.containerNode);
    this.cornerRadius = 0;
    this.fillOpacity = 1;
    this.padding = 4;
    this.data = [];
    this.highlightManager = ctx.highlightManager;
    this.axisTicks = new AxisTicks(ctx, this);
    this.axisTicks.attachAxis(this.ticksGroup);
    this.scale = new GradientLegendScale(this.axisTicks);
    this.legendGroup.append([this.gradientRect, this.arrow, this.ticksGroup]);
    this.cleanup.register(
      ctx.eventsHub.on("highlight:change", () => this.onChartHoverChange()),
      ctx.layoutManager.registerElement(LayoutElement7.Legend, (e) => this.onStartLayout(e)),
      () => this.legendGroup.remove()
    );
  }
  isVertical() {
    const { placement } = expandLegendPosition(this.position);
    return placement.startsWith("right") || placement.startsWith("left");
  }
  destroy() {
    this.cleanup.flush();
  }
  attachLegend(scene) {
    scene.appendChild(this.legendGroup);
  }
  onStartLayout({ layoutBox }) {
    const [data] = this.data;
    if (!this.enabled || !data?.enabled || data.legendType !== "gradient") {
      this.legendGroup.visible = false;
      return;
    }
    const { colorRange } = this.normalizeColorArrays(data);
    const { strokeWidth, padding: padding2 } = this.getContainerStyles();
    const gradientRectBBox = this.updateGradientRect(layoutBox, colorRange);
    const axisBBox = this.updateAxis(data, gradientRectBBox) ?? new BBox23(0, 0, 0, 0);
    const legendBBox = BBox23.merge([gradientRectBBox, axisBBox]);
    legendBBox.grow(padding2).grow(strokeWidth);
    const { left, top } = this.getMeasurements(layoutBox, legendBBox);
    this.updateContainer(legendBBox);
    this.updateArrow();
    this.legendGroup.visible = true;
    this.legendGroup.translationX = left;
    this.legendGroup.translationY = top;
  }
  normalizeColorArrays(data) {
    let colorDomain = data.colorDomain.slice();
    const colorRange = data.colorRange.slice();
    if (colorDomain.length === colorRange.length) {
      return { colorDomain, colorRange };
    }
    if (colorDomain.length > colorRange.length) {
      colorRange.splice(colorDomain.length);
    }
    const [d0, d1] = colorDomain;
    const count = colorRange.length;
    colorDomain = colorRange.map((_, i) => {
      if (i === 0) {
        return d0;
      } else if (i === count - 1) {
        return d1;
      }
      return d0 + (d1 - d0) * i / (count - 1);
    });
    return { colorDomain, colorRange };
  }
  updateGradientRect(shrinkRect, colorRange) {
    const { gradientRect, gradient: gradient2 } = this;
    const { preferredLength, thickness } = gradient2;
    const gradientRectBBox = new BBox23(0, 0, 0, 0);
    const colorCount = Math.max(colorRange.length - 1, 1);
    let angle2;
    if (this.isVertical()) {
      angle2 = 0;
      gradientRectBBox.width = thickness;
      gradientRectBBox.height = Math.min(shrinkRect.height, preferredLength);
    } else {
      angle2 = 90;
      gradientRectBBox.width = Math.min(shrinkRect.width, preferredLength);
      gradientRectBBox.height = thickness;
    }
    gradientRect.x = gradientRectBBox.x;
    gradientRect.y = gradientRectBBox.y;
    gradientRect.width = gradientRectBBox.width;
    gradientRect.height = gradientRectBBox.height;
    gradientRect.fill = {
      type: "gradient",
      gradient: "linear",
      colorSpace: "oklch",
      colorStops: colorRange.map((color2, i) => ({
        stop: i / colorCount,
        color: color2
      })),
      rotation: angle2
    };
    return gradientRectBBox;
  }
  updateAxis(data, gradientRectBBox) {
    const { axisTicks, gradient: gradient2, scale: scale2 } = this;
    const { placement } = expandLegendPosition(this.position);
    const vertical = this.isVertical();
    const positiveAxis = this.reverseOrder !== vertical;
    axisTicks.placement = placement;
    const offset = gradient2.thickness + (scale2.padding ?? 0);
    axisTicks.translationX = vertical ? offset : gradientRectBBox.x;
    axisTicks.translationY = vertical ? gradientRectBBox.y : offset;
    axisTicks.scale.domain = positiveAxis ? data.colorDomain.slice().reverse() : data.colorDomain;
    axisTicks.scale.range = vertical ? [gradientRectBBox.x, gradientRectBBox.height] : [gradientRectBBox.y, gradientRectBBox.width];
    return axisTicks.calculateLayout();
  }
  updateContainer(bbox) {
    const containerStyles = this.getContainerStyles();
    this.containerNode.setStyleProperties(containerStyles);
    this.containerNode.cornerRadius = containerStyles.cornerRadius;
    this.containerNode.x = bbox.x;
    this.containerNode.y = bbox.y;
    this.containerNode.width = bbox.width;
    this.containerNode.height = bbox.height;
  }
  updateArrow() {
    const highlighted = this.highlightManager.getActiveHighlight();
    const { arrow } = this;
    if (highlighted?.colorValue == null) {
      arrow.visible = false;
      return;
    }
    const { scale: scale2, label } = this.axisTicks;
    const size = label.fontSize ?? 0;
    const t = scale2.convert(highlighted.colorValue);
    let { x, y } = this.gradientRect;
    let rotation = Math.PI;
    if (this.isVertical()) {
      x -= size / 2;
      y += t;
      rotation /= 2;
    } else {
      x += t;
      y -= size / 2;
    }
    arrow.visible = true;
    arrow.fill = label.color;
    arrow.rotation = rotation;
    arrow.size = size;
    arrow.translationX = x;
    arrow.translationY = y;
  }
  getMeasurements(shrinkRect, legendBBox) {
    const unreachable = (_a) => {
      return void 0;
    };
    let { x: left, y: top } = shrinkRect;
    const { width: width2, height: height2 } = legendBBox;
    const { placement, floating, xOffset, yOffset } = expandLegendPosition(this.position);
    const containerStyles = this.getContainerStyles();
    left += containerStyles.strokeWidth + containerStyles.padding.left;
    top += containerStyles.strokeWidth + containerStyles.padding.top;
    switch (placement) {
      case "left":
        top += shrinkRect.height / 2 - height2 / 2;
        break;
      case "right":
        left += shrinkRect.width - width2;
        top += shrinkRect.height / 2 - height2 / 2;
        break;
      case "top":
        left += shrinkRect.width / 2 - width2 / 2;
        break;
      case "bottom":
        left += shrinkRect.width / 2 - width2 / 2;
        top += shrinkRect.height - height2;
        break;
      case "right-top":
      case "top-right":
        left += shrinkRect.width - width2;
        break;
      case "right-bottom":
      case "bottom-right":
        left += shrinkRect.width - width2;
        top += shrinkRect.height - height2;
        break;
      case "left-bottom":
      case "bottom-left":
        top += shrinkRect.height - height2;
        break;
      case "left-top":
      case "top-left":
        break;
      default:
        unreachable(placement);
    }
    if (!floating) {
      switch (placement) {
        case "left":
        case "left-top":
        case "left-bottom":
          shrinkRect.shrink(width2 + this.spacing, "left");
          break;
        case "right":
        case "right-top":
        case "right-bottom":
          shrinkRect.shrink(width2 + this.spacing, "right");
          break;
        case "top":
        case "top-left":
        case "top-right":
          shrinkRect.shrink(height2 + this.spacing, "top");
          break;
        case "bottom":
        case "bottom-left":
        case "bottom-right":
          shrinkRect.shrink(height2 + this.spacing, "bottom");
          break;
        default:
          unreachable(placement);
      }
    }
    left += xOffset;
    top += yOffset;
    return { top, left };
  }
  getContainerStyles() {
    const { stroke: stroke3, strokeOpacity, strokeWidth } = this.border;
    const { cornerRadius, fill, fillOpacity, padding: padding2 } = this;
    const isPaddingNumber = typeof padding2 === "number";
    return {
      cornerRadius,
      fill,
      fillOpacity,
      padding: {
        top: isPaddingNumber ? padding2 : padding2.top ?? 0,
        right: isPaddingNumber ? padding2 : padding2.right ?? 0,
        bottom: isPaddingNumber ? padding2 : padding2.bottom ?? 0,
        left: isPaddingNumber ? padding2 : padding2.left ?? 0
      },
      stroke: stroke3,
      strokeOpacity,
      strokeWidth: this.border.enabled ? strokeWidth : 0
    };
  }
  onChartHoverChange() {
    if (!this.enabled)
      return;
    this.updateArrow();
  }
};
GradientLegend.className = "GradientLegend";
__decorateClass([
  addFakeTransformToInstanceProperty
], GradientLegend.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], GradientLegend.prototype, "position", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], GradientLegend.prototype, "reverseOrder", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], GradientLegend.prototype, "gradient", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], GradientLegend.prototype, "spacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], GradientLegend.prototype, "border", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], GradientLegend.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], GradientLegend.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], GradientLegend.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], GradientLegend.prototype, "padding", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], GradientLegend.prototype, "scale", 2);

// packages/ag-charts-enterprise/src/gradient-legend/gradientLegendModule.ts
var GradientLegendModule = {
  type: "plugin",
  name: "gradientLegend",
  enterprise: true,
  version: VERSION,
  // removable: 'standalone-only',
  options: {
    enabled: boolean,
    position: legendPositionValidator,
    spacing: positiveNumber,
    reverseOrder: boolean,
    border: borderOptionsDef,
    cornerRadius: number,
    padding,
    fill: colorUnion,
    fillOpacity: ratio,
    gradient: {
      preferredLength: positiveNumber,
      thickness: positiveNumber
    },
    scale: {
      label: {
        ...fontOptionsDef,
        minSpacing: positiveNumber,
        format: numberFormatValidator,
        formatter: callback
      },
      padding: positiveNumber,
      interval: {
        step: number,
        values: array,
        minSpacing: and(positiveNumber, lessThan("maxSpacing")),
        maxSpacing: and(positiveNumber, greaterThan("minSpacing"))
      }
    }
  },
  themeTemplate: {
    ...LEGEND_CONTAINER_THEME,
    enabled: false,
    position: "bottom",
    spacing: 20,
    scale: {
      padding: 13,
      label: {
        color: { $ref: "textColor" },
        fontSize: { $ref: "fontSize" },
        fontFamily: { $ref: "fontFamily" },
        fontWeight: { $ref: "fontWeight" },
        minSpacing: 5
      },
      interval: {
        minSpacing: 15
      }
    },
    gradient: {
      preferredLength: 100,
      thickness: 16
    },
    reverseOrder: false,
    fill: {
      $applySwitch: [
        { $path: "type" },
        { $ref: "chartBackgroundColour" },
        ["gradient", FILL_GRADIENT_BLANK_DEFAULTS],
        ["pattern", FILL_PATTERN_BLANK_DEFAULTS],
        ["image", FILL_IMAGE_BLANK_DEFAULTS]
      ]
    }
  },
  create: (ctx) => {
    const moduleInstance = new GradientLegend(ctx);
    moduleInstance.attachLegend(ctx.scene);
    return moduleInstance;
  }
};

// packages/ag-charts-enterprise/src/axes/ordinal/ordinalTimeAxis.ts
var {
  OrdinalTimeScale: OrdinalTimeScale2,
  ApproximateOrdinalTimeScale: ApproximateOrdinalTimeScale2,
  APPROXIMATE_THRESHOLD: APPROXIMATE_THRESHOLD4,
  TimeAxisParentLevel: TimeAxisParentLevel2,
  minimumTimeAxisDatumGranularity: minimumTimeAxisDatumGranularity2
} = module_support_exports;
var OrdinalTimeAxis = class extends module_support_exports.DiscreteTimeAxis {
  constructor(moduleCtx) {
    const accurateScale = new OrdinalTimeScale2();
    super(moduleCtx, accurateScale);
    this.parentLevel = new TimeAxisParentLevel2();
    this.accurateScale = accurateScale;
    this.approximateScale = new ApproximateOrdinalTimeScale2();
    this.approximateScale.setSourceScale(accurateScale);
    Object.defineProperty(this, "scale", {
      get: () => this.getActiveScale(),
      configurable: true
    });
  }
  get primaryLabel() {
    return this.parentLevel.enabled ? this.parentLevel.label : void 0;
  }
  get primaryTick() {
    return this.parentLevel.enabled ? this.parentLevel.tick : void 0;
  }
  /**
   * Returns the active scale based on visible range and data uniformity.
   * Use approximate scale when data is uniform and visible datum count is large.
   */
  getActiveScale() {
    const visibleBandCount = this.accurateScale.bandCount(this.visibleRange);
    const isUniform = this.accurateScale.getUniformityCache(this.visibleRange)?.isUniform ?? false;
    if (isUniform && visibleBandCount >= APPROXIMATE_THRESHOLD4) {
      return this.approximateScale;
    }
    return this.accurateScale;
  }
  processData() {
    super.processData();
    const { boundSeries, direction } = this;
    this.minimumTimeGranularity = minimumTimeAxisDatumGranularity2(boundSeries, direction, void 0, void 0);
  }
  tickFormatParams(domain, ticks, _fractionDigits, timeInterval3) {
    timeInterval3 ?? (timeInterval3 = lowestGranularityUnitForTicks(ticks));
    const truncateDate = dateTruncationForDomain(domain);
    const unit = intervalUnit(timeInterval3);
    const step = intervalStep(timeInterval3);
    const epoch = intervalEpoch(timeInterval3);
    return { type: "date", unit, step, epoch, truncateDate };
  }
  datumFormatParams(value, params, _fractionDigits, timeInterval3, style2) {
    if (typeof value === "number")
      value = new Date(value);
    if (timeInterval3 == null) {
      const { minimumTimeGranularity } = this;
      const datumGranularity = lowestGranularityUnitForValue(value);
      if (minimumTimeGranularity != null && intervalMilliseconds(minimumTimeGranularity) < intervalMilliseconds(datumGranularity)) {
        timeInterval3 = minimumTimeGranularity;
      } else {
        timeInterval3 = datumGranularity;
      }
    }
    const { datum, seriesId, legendItemName, key, source, property, domain, boundSeries } = params;
    const unit = intervalUnit(timeInterval3);
    const step = intervalStep(timeInterval3);
    const epoch = intervalEpoch(timeInterval3);
    return {
      type: "date",
      value,
      datum,
      seriesId,
      legendItemName,
      key,
      source,
      property,
      domain,
      boundSeries,
      unit,
      step,
      epoch,
      style: style2
    };
  }
};
OrdinalTimeAxis.className = "OrdinalTimeAxis";
OrdinalTimeAxis.type = "ordinal-time";
__decorateClass([
  addFakeTransformToInstanceProperty
], OrdinalTimeAxis.prototype, "parentLevel", 2);

// packages/ag-charts-enterprise/src/axes/ordinal/ordinalTimeAxisModule.ts
var OrdinalTimeAxisModule = {
  type: "axis",
  name: "ordinal-time",
  chartType: "cartesian",
  enterprise: true,
  version: VERSION,
  options: module_support_exports.ordinalTimeAxisOptionsDefs,
  themeTemplate: {
    groupPaddingInner: 0,
    label: { autoRotate: false, minSpacing: 40 },
    gridLine: { enabled: false },
    interval: { placement: "between" }
  },
  create: (ctx) => new OrdinalTimeAxis(ctx)
};

// packages/ag-charts-enterprise/src/module-bundles/cartesian-axes.ts
var AllCartesianAxesModule2 = [
  AllCartesianAxesModule,
  OrdinalTimeAxisModule
].flat();

// packages/ag-charts-enterprise/src/series/funnel/funnelThemes.ts
var isHorizontal = { $eq: [{ $path: ["/series/0/direction", void 0] }, "horizontal"] };
var labelOptions = { $clone: { $omit: [["placement", "spacing"], { $path: "/series/0/stageLabel" }] } };
var FUNNEL_SERIES_AXES = {
  y: {
    type: {
      $if: [isHorizontal, "number" /* NUMBER */, "category" /* CATEGORY */]
    },
    position: {
      $if: [
        isHorizontal,
        "left" /* LEFT */,
        {
          $if: [
            { $eq: [{ $path: ["/series/0/stageLabel/placement", void 0] }, "after"] },
            "right" /* RIGHT */,
            "left" /* LEFT */
          ]
        }
      ]
    },
    label: {
      $if: [isHorizontal, void 0, labelOptions]
    }
  },
  x: {
    type: {
      $if: [isHorizontal, "category" /* CATEGORY */, "number" /* NUMBER */]
    },
    position: {
      $if: [
        isHorizontal,
        {
          $if: [
            { $eq: [{ $path: ["/series/0/stageLabel/placement", void 0] }, "before"] },
            "top" /* TOP */,
            "bottom" /* BOTTOM */
          ]
        },
        "bottom" /* BOTTOM */
      ]
    },
    label: {
      $if: [isHorizontal, labelOptions, void 0]
    }
  }
};
var FUNNEL_SERIES_THEME = {
  series: {
    direction: "vertical",
    strokeWidth: { $isUserOption: ["./strokes/0", 2, 0] },
    spacingRatio: 0.25,
    fills: {
      $applyCycle: [
        { $size: { $path: ["./data", { $path: "/data" }] } },
        [{ $path: ["/0", void 0, { $palette: "fills" }] }],
        {
          $applySwitch: [
            { $path: ["/type", void 0, { $value: "$1" }] },
            { $value: "$1" },
            ["gradient", FILL_GRADIENT_LINEAR_SINGLE_DEFAULTS],
            ["pattern", FILL_PATTERN_SINGLE_DEFAULTS],
            ["image", FILL_IMAGE_DEFAULTS]
          ]
        }
      ]
    },
    strokes: {
      $applyCycle: [
        { $size: { $path: ["./data", { $path: "/data" }] } },
        [{ $path: ["/0", void 0, { $palette: "strokes" }] }]
      ]
    },
    label: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: true,
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      fontWeight: { $ref: "fontWeight" },
      color: { $ref: "chartBackgroundColor" }
    },
    dropOff: {
      enabled: true,
      fillOpacity: 0.2,
      strokeWidth: { $isUserOption: ["./stroke", 2, 0] }
    },
    shadow: {
      enabled: false,
      color: DEFAULT_SHADOW_COLOUR,
      xOffset: 3,
      yOffset: 3,
      blur: 5
    },
    highlight: {
      unhighlightedItem: {
        opacity: 0.6
      }
    }
  },
  axes: {
    ["number" /* NUMBER */]: {
      nice: false,
      gridLine: {
        enabled: false
      },
      crosshair: {
        enabled: false
      },
      label: {
        enabled: false
      }
    },
    ["category" /* CATEGORY */]: {
      line: {
        enabled: false
      }
    }
  }
};

// packages/ag-charts-enterprise/src/series/funnel/funnelUtil.ts
var { NODE_UPDATE_STATE_TO_PHASE_MAPPING: NODE_UPDATE_STATE_TO_PHASE_MAPPING2 } = module_support_exports;
function connectorStartingPosition(datum, _prevDatum, isVertical, _mode) {
  const { x0, y0, x1, y1, x2, y2, x3, y3, opacity } = datum;
  if (isVertical) {
    return {
      x0: (x0 + x3) / 2,
      y0: (y0 + y3) / 2,
      x1: (x1 + x2) / 2,
      y1: (y1 + y2) / 2,
      x2: (x1 + x2) / 2,
      y2: (y1 + y2) / 2,
      x3: (x0 + x3) / 2,
      y3: (y0 + y3) / 2,
      opacity
    };
  } else {
    return {
      x0: (x0 + x1) / 2,
      y0: (y0 + y1) / 2,
      x1: (x0 + x1) / 2,
      y1: (y0 + y1) / 2,
      x2: (x2 + x3) / 2,
      y2: (y2 + y3) / 2,
      x3: (x2 + x3) / 2,
      y3: (y2 + y3) / 2,
      opacity
    };
  }
}
function prepareConnectorAnimationFunctions(isVertical, mode) {
  const isRemoved = (datum) => datum == null;
  const fromFn = (connector, datum, status) => {
    if (status === "updated" && isRemoved(datum)) {
      status = "removed";
    } else if (status === "updated" && isRemoved(connector.previousDatum)) {
      status = "added";
    }
    let source;
    if (status === "added" && connector.previousDatum == null && mode === "fade") {
      source = { ...resetConnectorSelectionsFn(connector, datum), opacity: 0 };
    } else if (status === "unknown" || status === "added") {
      source = connectorStartingPosition(datum, connector.previousDatum, isVertical, mode);
    } else {
      source = {
        x0: connector.x0,
        y0: connector.y0,
        x1: connector.x1,
        y1: connector.y1,
        x2: connector.x2,
        y2: connector.y2,
        x3: connector.x3,
        y3: connector.y3,
        opacity: connector.opacity
      };
    }
    const phase = NODE_UPDATE_STATE_TO_PHASE_MAPPING2[status];
    return { ...source, phase };
  };
  const toFn = (connector, datum, status) => {
    let source;
    if (status === "removed" && connector.datum == null && mode === "fade") {
      source = { ...resetConnectorSelectionsFn(connector, datum), opacity: 0 };
    } else if (status === "removed" || isRemoved(datum)) {
      source = connectorStartingPosition(datum, connector.previousDatum, isVertical, mode);
    } else {
      source = resetConnectorSelectionsFn(connector, datum);
    }
    return source;
  };
  return { fromFn, toFn };
}
function resetConnectorSelectionsFn(_node, datum) {
  const { x0, y0, x1, y1, x2, y2, x3, y3, opacity } = datum;
  return { x0, y0, x1, y1, x2, y2, x3, y3, opacity };
}

// packages/ag-charts-enterprise/src/series/funnel/baseFunnelSeries.ts
var {
  SeriesNodePickMode: SeriesNodePickMode10,
  valueProperty: valueProperty12,
  keyProperty: keyProperty9,
  updateLabelNode: updateLabelNode6,
  SMALLEST_KEY_INTERVAL: SMALLEST_KEY_INTERVAL5,
  LARGEST_KEY_INTERVAL: LARGEST_KEY_INTERVAL3,
  diff: diff6,
  fixNumericExtent: fixNumericExtent8,
  seriesLabelFadeInAnimation: seriesLabelFadeInAnimation6,
  resetMotion: resetMotion3,
  resetLabelFn: resetLabelFn5,
  animationValidation: animationValidation7,
  computeBarFocusBounds: computeBarFocusBounds7,
  Group: Group13,
  Selection: Selection8,
  PointerEvents: PointerEvents7,
  motion: motion5,
  checkCrisp: checkCrisp4,
  createDatumId: createDatumId13
} = module_support_exports;
var FunnelSeriesNodeEvent = class extends module_support_exports.SeriesNodeEvent {
  constructor(type, nativeEvent, datum, series) {
    super(type, nativeEvent, datum, series);
    this.xKey = series.properties.stageKey;
    this.yKey = series.properties.valueKey;
  }
};
var BaseFunnelSeries = class extends module_support_exports.AbstractBarSeries {
  constructor({
    moduleCtx,
    animationResetFns
  }) {
    super({
      moduleCtx,
      pickModes: [SeriesNodePickMode10.AXIS_ALIGNED, SeriesNodePickMode10.EXACT_SHAPE_MATCH],
      propertyKeys: {
        x: ["stageKey"],
        y: ["valueKey"]
      },
      propertyNames: {
        x: [],
        y: []
      },
      categoryKey: "xValue",
      datumSelectionGarbageCollection: false,
      animationResetFns: {
        datum: animationResetFns.datum,
        label: resetLabelFn5
      }
    });
    // @ts-expect-error xKey/yKey renamed
    this.NodeEvent = FunnelSeriesNodeEvent;
    this.connectorNodeGroup = this.contentGroup.appendChild(
      new Group13({
        name: `${this.id}-series-connectorNodes`,
        zIndex: 0 /* BACKGROUND */
      })
    );
    this.connectorSelection = Selection8.select(
      this.connectorNodeGroup,
      () => this.connectionFactory()
    );
    this.connectorNodeGroup.pointerEvents = PointerEvents7.None;
  }
  get pickModeAxis() {
    return "main-category";
  }
  setZIndex(zIndex) {
    super.setZIndex(zIndex);
    this.connectorNodeGroup.zIndex = [0 /* BACKGROUND */, zIndex];
    return true;
  }
  isVertical() {
    return !super.isVertical();
  }
  connectionFactory() {
    return new FunnelConnector();
  }
  getKeyAxis(direction) {
    if (direction === "x" /* X */)
      return this.properties.xKeyAxis;
    if (direction === "y" /* Y */)
      return this.properties.yKeyAxis;
  }
  async processData(dataController) {
    const { stageKey, valueKey } = this.properties;
    const { visible, id: seriesId } = this;
    const validation = (_value, _datum, index) => visible && this.ctx.legendManager.getItemEnabled({ seriesId, itemId: index });
    const xScale = this.getCategoryAxis()?.scale;
    const yScale = this.getValueAxis()?.scale;
    const { isContinuousX, xScaleType, yScaleType } = this.getScaleInformation({ xScale, yScale });
    const extraProps = [];
    if (this.needsDataModelDiff() && this.processedData) {
      extraProps.push(diff6(this.id, this.processedData));
    }
    if (!this.ctx.animationManager.isSkipped()) {
      extraProps.push(animationValidation7());
    }
    const visibleProps = this.visible ? {} : { forceValue: 0 };
    const allowNullKey = this.properties.allowNullKeys ?? false;
    const { processedData } = await this.requestDataModel(dataController, this.data, {
      props: [
        keyProperty9(stageKey, xScaleType, { id: "xValue", allowNullKey }),
        valueProperty12(valueKey, yScaleType, { id: `yValue`, ...visibleProps, validation, invalidValue: 0 }),
        ...isContinuousX ? [SMALLEST_KEY_INTERVAL5, LARGEST_KEY_INTERVAL3] : [],
        ...extraProps
      ],
      groupByKeys: false
    });
    this.smallestDataInterval = processedData.reduced?.smallestKeyInterval;
    this.largestDataInterval = processedData.reduced?.largestKeyInterval;
    this.animationState.transition("updateData");
  }
  getSeriesDomain(direction) {
    const {
      processedData,
      dataModel,
      id: seriesId,
      ctx: { legendManager }
    } = this;
    if (!processedData || !dataModel)
      return { domain: [] };
    const {
      keys: [keys]
    } = processedData.domain;
    if (direction === this.getCategoryDirection()) {
      const keyDef = dataModel.resolveProcessedDataDefById(this, `xValue`);
      if (keyDef?.def.type === "key" && keyDef?.def.valueType === "category") {
        if (!this.hasData)
          return { domain: [] };
        const domain = keys.filter((_key, index) => legendManager.getItemEnabled({ seriesId, itemId: index }));
        const sortMetadata = dataModel.getKeySortMetadata(this, "xValue", processedData);
        return { domain, sortMetadata };
      }
      return { domain: this.padBandExtent(keys) };
    } else {
      const yExtent = this.domainForClippedRange(direction, ["yValue"], "xValue");
      const maxExtent = Math.max(...yExtent);
      const fixedYExtent = [-maxExtent, maxExtent];
      return { domain: fixNumericExtent8(fixedYExtent) };
    }
  }
  getSeriesRange(_direction, _visibleRange) {
    return [Number.NaN, Number.NaN];
  }
  createNodeData() {
    const {
      hasData,
      data,
      dataModel,
      processedData,
      id: seriesId,
      ctx: { legendManager }
    } = this;
    const xAxis = this.getCategoryAxis();
    const yAxis = this.getValueAxis();
    if (!(hasData && data && xAxis && yAxis && dataModel && processedData?.type === "ungrouped")) {
      return;
    }
    const xScale = xAxis.scale;
    const yScale = yAxis.scale;
    const barAlongX = this.getBarDirection() === "x" /* X */;
    const { stageKey, valueKey } = this.properties;
    const itemId = `${valueKey}`;
    const context = {
      itemId,
      nodeData: [],
      labelData: [],
      connectorData: [],
      scales: this.calculateScaling(),
      groupScale: this.getScaling(this.ctx.seriesStateManager.getGroupScale(this)),
      visible: this.visible
    };
    const isVisible = this.visible;
    if (!isVisible)
      return context;
    const xValues = dataModel.resolveKeysById(this, "xValue", processedData);
    const yValues = dataModel.resolveColumnById(this, `yValue`, processedData);
    const { groupOffset, barOffset, barWidth } = this.getBarDimensions();
    const crisp = checkCrisp4(
      xAxis?.scale,
      xAxis?.visibleRange,
      this.smallestDataInterval,
      this.largestDataInterval
    );
    let previousConnection;
    const rawData = processedData.dataSources.get(this.id)?.data ?? [];
    for (const [datumIndex, datum] of rawData.entries()) {
      const visible = isVisible && legendManager.getItemEnabled({ seriesId, itemId: datumIndex });
      const xDatum = xValues[datumIndex];
      if (xDatum === void 0 && !this.properties.allowNullKeys)
        continue;
      const xConverted = xScale.convert(xDatum);
      if (!Number.isFinite(xConverted))
        continue;
      const x = Math.round(xConverted) + groupOffset + barOffset;
      const yDatum = yValues[datumIndex];
      const yNegative = Math.round(yScale.convert(-yDatum));
      const yPositive = Math.round(yScale.convert(yDatum));
      const style2 = this.getItemStyle({ datum, datumIndex }, false);
      const barHeight = Math.max(style2.strokeWidth ?? 0, Math.abs(yPositive - yNegative));
      const rect2 = {
        x: barAlongX ? Math.min(yPositive, yNegative) : x,
        y: barAlongX ? x : Math.min(yPositive, yNegative),
        width: barAlongX ? barHeight : barWidth,
        height: barAlongX ? barWidth : barHeight
      };
      const nodeMidPoint = {
        x: rect2.x + rect2.width / 2,
        y: rect2.y + rect2.height / 2
      };
      const labelData = this.createLabelData({
        datumIndex,
        rect: rect2,
        barAlongX,
        yDatum,
        datum,
        visible
      });
      const nodeDatum = {
        index: datumIndex,
        series: this,
        datum,
        datumIndex,
        xValue: xDatum,
        yValue: yDatum,
        xKey: stageKey,
        yKey: valueKey,
        x: rect2.x,
        y: rect2.y,
        width: rect2.width,
        height: rect2.height,
        midPoint: nodeMidPoint,
        crisp,
        label: labelData,
        visible
      };
      context.nodeData.push(nodeDatum);
      if (labelData != null) {
        context.labelData.push(labelData);
      }
      if (previousConnection != null) {
        const prevRect = previousConnection.rect;
        const startNodeDatum = previousConnection.nodeDatum;
        const startDatumIndex = previousConnection.datumIndex;
        if (barAlongX) {
          context.connectorData.push({
            datum: startNodeDatum,
            datumIndex: startDatumIndex,
            x0: prevRect.x,
            y0: prevRect.y + prevRect.height,
            x1: prevRect.x + prevRect.width,
            y1: prevRect.y + prevRect.height,
            x2: rect2.x + rect2.width,
            y2: rect2.y,
            x3: rect2.x,
            y3: rect2.y,
            opacity: 1
          });
        } else {
          context.connectorData.push({
            datum: startNodeDatum,
            datumIndex: startDatumIndex,
            x0: prevRect.x + prevRect.width,
            y0: prevRect.y,
            x1: rect2.x,
            y1: rect2.y,
            x2: rect2.x,
            y2: rect2.y + rect2.height,
            x3: prevRect.x + prevRect.width,
            y3: prevRect.y + prevRect.height,
            opacity: 1
          });
        }
      }
      if (visible) {
        previousConnection = {
          itemId,
          rect: rect2,
          nodeDatum,
          datumIndex
        };
      }
    }
    return context;
  }
  updateNodes(seriesHighlighted, nodeRefresh) {
    super.updateNodes(seriesHighlighted, nodeRefresh);
    const { connectorSelection } = this;
    const connectorData = this.contextNodeData?.connectorData ?? [];
    this.connectorSelection = this.updateConnectorSelection({ connectorSelection, connectorData });
    this.updateConnectorNodes({ connectorSelection });
  }
  updateDatumSelection(opts) {
    const { nodeData, datumSelection } = opts;
    const data = nodeData ?? [];
    return datumSelection.update(data, void 0, (datum) => this.getDatumId(datum));
  }
  updateConnectorSelection(opts) {
    const { connectorData, connectorSelection } = opts;
    return connectorSelection.update(
      this.connectorEnabled() ? connectorData : [],
      void 0,
      (connector) => this.getDatumId(connector.datum)
    );
  }
  updateConnectorNodes(opts) {
    const fillBBox = this.getShapeFillBBox();
    opts.connectorSelection.each((connector, datum) => {
      const { fill, fillOpacity, stroke: stroke3, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.connectorStyle(datum.datumIndex);
      connector.setProperties(resetConnectorSelectionsFn(connector, datum));
      connector.setStyleProperties(
        {
          fill,
          stroke: stroke3,
          fillOpacity,
          strokeOpacity,
          strokeWidth,
          lineDash,
          lineDashOffset
        },
        fillBBox
      );
    });
  }
  updateLabelSelection(opts) {
    const labelData = this.properties.label.enabled ? opts.labelData : [];
    return opts.labelSelection.update(labelData, (text2) => {
      text2.pointerEvents = PointerEvents7.None;
    });
  }
  updateLabelNodes(opts) {
    const params = {
      stageKey: this.properties.stageKey,
      valueKey: this.properties.valueKey
    };
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const { isHighlight = false, labelSelection } = opts;
    labelSelection.each((textNode, datum) => {
      const highlightStyle = this.getHighlightStyle(isHighlight, datum.datumIndex);
      textNode.visible = datum.visible || isHighlight;
      textNode.fillOpacity = highlightStyle.opacity ?? 1;
      textNode.opacity = highlightStyle.opacity ?? 1;
      updateLabelNode6(this, textNode, params, this.properties.label, datum, isHighlight, activeHighlight);
    });
  }
  getHighlightLabelData(_labelData, highlightedItem) {
    if (highlightedItem.label) {
      return [{ ...highlightedItem.label }];
    }
    return void 0;
  }
  getTooltipContent(datumIndex) {
    const { id: seriesId, dataModel, processedData, properties } = this;
    const { stageKey, valueKey, tooltip, legendItemName } = properties;
    const xAxis = this.getCategoryAxis();
    const yAxis = this.getValueAxis();
    if (!dataModel || !processedData || !xAxis || !yAxis)
      return;
    const datum = processedData.dataSources.get(this.id)?.data[datumIndex];
    const xValue = dataModel.resolveKeysById(this, "xValue", processedData)[datumIndex];
    const yValue = dataModel.resolveColumnById(this, `yValue`, processedData)[datumIndex];
    const allowNullKeys = this.properties.allowNullKeys ?? false;
    if (xValue === void 0 && !allowNullKeys)
      return;
    return this.formatTooltipWithContext(
      tooltip,
      {
        symbol: this.legendItemSymbol(datumIndex),
        data: [
          {
            label: this.getAxisValueText(xAxis, "tooltip", xValue, datum, stageKey, legendItemName),
            value: this.getAxisValueText(yAxis, "tooltip", yValue, datum, valueKey, legendItemName)
          }
        ]
      },
      { seriesId, datum, title: stageKey, stageKey, valueKey, ...this.tooltipStyle(datum, datumIndex) }
    );
  }
  resetAllAnimation(data) {
    super.resetAllAnimation(data);
    resetMotion3([this.connectorSelection], resetConnectorSelectionsFn);
  }
  animateEmptyUpdateReady({ labelSelection }) {
    const { connectorSelection } = this;
    const isVertical = this.isVertical();
    const mode = "normal";
    const connectorFns = prepareConnectorAnimationFunctions(isVertical, mode);
    motion5.fromToMotion(this.id, "connectors", this.ctx.animationManager, [connectorSelection], connectorFns);
    seriesLabelFadeInAnimation6(this, "labels", this.ctx.animationManager, labelSelection);
  }
  animateWaitingUpdateReady(data) {
    const { labelSelection: labelSelections } = data;
    this.ctx.animationManager.stopByAnimationGroupId(this.id);
    seriesLabelFadeInAnimation6(this, "labels", this.ctx.animationManager, labelSelections);
  }
  getDatumId(datum) {
    return createDatumId13(datum.xValue);
  }
  isLabelEnabled() {
    return this.properties.label.enabled;
  }
  computeFocusBounds({ datumIndex }) {
    return computeBarFocusBounds7(this, this.contextNodeData?.nodeData[datumIndex]);
  }
  legendItemSymbol(datumIndex) {
    const { strokeWidth, fillOpacity, strokeOpacity, lineDash, lineDashOffset, fill, stroke: stroke3 } = this.properties.getStyle(datumIndex);
    return {
      marker: {
        fill,
        fillOpacity,
        stroke: stroke3,
        strokeWidth,
        strokeOpacity,
        lineDash,
        lineDashOffset
      }
    };
  }
  getLegendData(legendType) {
    const {
      id: seriesId,
      processedData,
      dataModel,
      ctx: { legendManager },
      visible
    } = this;
    if (!dataModel || !processedData || legendType !== "category") {
      return [];
    }
    const { showInLegend } = this.properties;
    const xValues = dataModel.resolveKeysById(this, "xValue", processedData);
    return (processedData.dataSources.get(this.id)?.data ?? []).map((datum, datumIndex) => {
      const stageValue = xValues[datumIndex];
      const allowNullKeys = this.properties.allowNullKeys ?? false;
      if (stageValue == null && !allowNullKeys)
        return;
      return {
        legendType: "category",
        id: seriesId,
        datum,
        itemId: datumIndex,
        seriesId,
        enabled: visible && legendManager.getItemEnabled({ seriesId, itemId: datumIndex }),
        label: { text: String(stageValue) },
        symbol: this.legendItemSymbol(datumIndex),
        skipAnimations: true,
        hideInLegend: !showInLegend
      };
    }).filter((datum) => datum != null);
  }
  hasItemStylers() {
    return this.properties.itemStyler != null || this.properties.label.itemStyler != null;
  }
};

// packages/ag-charts-enterprise/src/series/cone-funnel/coneFunnelProperties.ts
var { Label: Label12, AbstractBarSeriesProperties: AbstractBarSeriesProperties6, makeSeriesTooltip: makeSeriesTooltip14, AxisLabel: AxisLabel4 } = module_support_exports;
var ConeFunnelSeriesLabel = class extends Label12 {
  constructor() {
    super(...arguments);
    this.spacing = 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ConeFunnelSeriesLabel.prototype, "placement", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ConeFunnelSeriesLabel.prototype, "spacing", 2);
var ConeFunnelSeriesStageLabel = class extends AxisLabel4 {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ConeFunnelSeriesStageLabel.prototype, "placement", 2);
var ConeFunnelProperties = class extends AbstractBarSeriesProperties6 {
  constructor() {
    super(...arguments);
    this.fills = [];
    this.fillOpacity = 1;
    this.strokes = [];
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.label = new ConeFunnelSeriesLabel();
    this.stageLabel = new ConeFunnelSeriesStageLabel();
    this.tooltip = makeSeriesTooltip14();
  }
  getStyle(index) {
    const { fills, strokes, fillOpacity, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this;
    return {
      fill: fills[index],
      fillOpacity,
      stroke: strokes[index],
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset,
      opacity: 1
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], ConeFunnelProperties.prototype, "stageKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ConeFunnelProperties.prototype, "valueKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ConeFunnelProperties.prototype, "fills", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ConeFunnelProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ConeFunnelProperties.prototype, "strokes", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ConeFunnelProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ConeFunnelProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ConeFunnelProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ConeFunnelProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ConeFunnelProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ConeFunnelProperties.prototype, "stageLabel", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], ConeFunnelProperties.prototype, "tooltip", 2);

// packages/ag-charts-enterprise/src/series/cone-funnel/coneFunnelUtil.ts
function resetLineSelectionsFn(_node, { x, y, width: width2, height: height2, opacity }) {
  return { x1: x, y1: y, x2: x + width2, y2: y + height2, opacity: opacity ?? 1 };
}

// packages/ag-charts-enterprise/src/series/cone-funnel/coneFunnelSeries.ts
var { Line: Line4 } = module_support_exports;
var ConeFunnelSeries = class extends BaseFunnelSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      animationResetFns: {
        datum: resetLineSelectionsFn
      }
    });
    this.properties = new ConeFunnelProperties();
  }
  get hasData() {
    const {
      id: seriesId,
      ctx: { legendManager }
    } = this;
    const visibleItems = this.data?.data.reduce(
      (accum, _, datumIndex) => accum + (legendManager.getItemEnabled({ seriesId, itemId: datumIndex }) ? 1 : 0),
      0
    );
    return visibleItems != null && visibleItems > 1;
  }
  getBandScalePadding() {
    return { inner: 1, outer: 0 };
  }
  connectorEnabled() {
    return true;
  }
  getItemStyle({ datumIndex }, _isHighlight) {
    return this.properties.getStyle(datumIndex);
  }
  connectorStyle(index) {
    return this.properties.getStyle(index);
  }
  nodeFactory() {
    return new Line4();
  }
  createLabelData({
    datumIndex,
    rect: rect2,
    barAlongX,
    yDatum,
    datum,
    visible
  }) {
    const { stageKey, valueKey, label } = this.properties;
    const { spacing, placement } = label;
    if (!label.enabled)
      return;
    let x;
    let y;
    let textAlign;
    let textBaseline;
    if (barAlongX) {
      x = rect2.x + rect2.width / 2;
      textAlign = "center";
      switch (placement) {
        case "before":
          y = rect2.y - spacing;
          textBaseline = "bottom";
          break;
        case "after":
          y = rect2.y + rect2.height + spacing;
          textBaseline = "top";
          break;
        default:
          y = rect2.y + rect2.height / 2;
          textBaseline = "middle";
      }
    } else {
      y = rect2.y + rect2.height / 2;
      textBaseline = "middle";
      switch (placement) {
        case "before":
          x = rect2.x - spacing;
          textAlign = "right";
          break;
        case "after":
          x = rect2.x + rect2.width + spacing;
          textAlign = "left";
          break;
        default:
          x = rect2.x + rect2.width / 2;
          textAlign = "center";
      }
    }
    const yDomain = this.getSeriesDomain("y" /* Y */).domain;
    const text2 = this.getLabelText(
      yDatum,
      datum,
      valueKey,
      "y",
      yDomain,
      label,
      { itemId: valueKey, value: yDatum, datum, stageKey, valueKey }
    );
    return {
      x,
      y,
      textAlign,
      textBaseline,
      text: text2,
      itemId: valueKey,
      datum,
      datumIndex,
      series: this,
      visible
    };
  }
  updateDatumNodes(opts) {
    const highlightStyle = this.getHighlightStyle(opts.isHighlight);
    opts.datumSelection.each((line, datum) => {
      line.setProperties(resetLineSelectionsFn(line, datum));
      line.stroke = highlightStyle?.stroke;
      line.strokeWidth = highlightStyle?.strokeWidth ?? 0;
      line.strokeOpacity = highlightStyle?.strokeOpacity ?? 1;
      line.lineDash = highlightStyle?.lineDash;
      line.lineDashOffset = highlightStyle?.lineDashOffset ?? 0;
      line.opacity = highlightStyle?.opacity ?? 1;
    });
  }
  tooltipStyle(_datum, datumIndex) {
    const { fill, stroke: stroke3, fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.properties.getStyle(datumIndex);
    return {
      fill,
      fillOpacity,
      stroke: stroke3,
      strokeOpacity,
      strokeWidth,
      lineDash,
      lineDashOffset
    };
  }
  hasItemStylers() {
    return this.properties.label.itemStyler != null;
  }
};
ConeFunnelSeries.className = "ConeFunnelSeries";
ConeFunnelSeries.type = "cone-funnel";

// packages/ag-charts-enterprise/src/series/cone-funnel/coneFunnelSeriesOptionsDef.ts
var { coneFunnelSeriesThemeableOptionsDef: coneFunnelSeriesThemeableOptionsDef2 } = module_support_exports;
var coneFunnelSeriesOptionsDef = {
  ...without(commonSeriesOptionsDefs, ["showInLegend"]),
  ...coneFunnelSeriesThemeableOptionsDef2,
  type: required(constant("cone-funnel")),
  stageKey: required(string),
  valueKey: required(string)
};

// packages/ag-charts-enterprise/src/series/cone-funnel/coneFunnelThemes.ts
var CONE_FUNNEL_SERIES_THEME = {
  series: {
    direction: "vertical",
    fills: {
      $applyCycle: [
        { $size: { $path: ["./data", { $path: "/data" }] } },
        {
          $if: [
            { $eq: [{ $palette: "type" }, "inbuilt"] },
            { $palette: "secondSequentialColors" },
            SAFE_RANGE2_OPERATION
          ]
        },
        {
          $applySwitch: [
            { $path: ["/type", void 0, { $value: "$1" }] },
            { $value: "$1" },
            ["gradient", FILL_GRADIENT_LINEAR_SINGLE_DEFAULTS],
            ["pattern", FILL_PATTERN_SINGLE_DEFAULTS],
            ["image", FILL_IMAGE_DEFAULTS]
          ]
        }
      ]
    },
    strokes: {
      $applyCycle: [
        { $size: { $path: ["./data", { $path: "/data" }] } },
        {
          $if: [
            { $eq: [{ $palette: "type" }, "inbuilt"] },
            { $palette: "secondSequentialColors" },
            SAFE_RANGE2_OPERATION
          ]
        }
      ]
    },
    strokeWidth: { $isUserOption: ["./strokes/0", 2, 0] },
    label: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: true,
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      fontWeight: { $ref: "fontWeight" },
      color: { $ref: "textColor" },
      placement: "before",
      spacing: 4
    },
    tooltip: {
      range: { $path: ["/tooltip/range", "nearest"] }
    },
    highlight: {
      highlightedItem: {
        stroke: `rgba(0, 0, 0, 0.4)`,
        strokeWidth: 2
      }
    }
  },
  seriesArea: {
    padding: {
      top: 20,
      bottom: 20
    }
  },
  axes: {
    ["number" /* NUMBER */]: {
      nice: false,
      gridLine: {
        enabled: false
      },
      crosshair: {
        enabled: false
      },
      label: {
        enabled: false
      }
    },
    ["category" /* CATEGORY */]: {
      line: {
        enabled: false
      }
    }
  }
};

// packages/ag-charts-enterprise/src/series/cone-funnel/coneFunnelModule.ts
var ConeFunnelSeriesModule = {
  type: "series",
  name: "cone-funnel",
  chartType: "cartesian",
  enterprise: true,
  solo: true,
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: coneFunnelSeriesOptionsDef,
  defaultAxes: FUNNEL_SERIES_AXES,
  themeTemplate: CONE_FUNNEL_SERIES_THEME,
  create: (ctx) => new ConeFunnelSeries(ctx)
};

// packages/ag-charts-enterprise/src/series/funnel/funnelProperties.ts
var { Label: Label13, DropShadow: DropShadow6, AbstractBarSeriesProperties: AbstractBarSeriesProperties7, makeSeriesTooltip: makeSeriesTooltip15, AxisLabel: AxisLabel5 } = module_support_exports;
var FunnelSeriesLabel = class extends Label13 {
};
var FunnelSeriesStageLabel = class extends AxisLabel5 {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelSeriesStageLabel.prototype, "placement", 2);
var FunnelDropOff = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = true;
    this.fill = void 0;
    this.fillOpacity = 1;
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
  }
  getStyle() {
    const { fill, stroke: stroke3, fillOpacity, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this;
    return {
      fill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset,
      opacity: 1
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelDropOff.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelDropOff.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelDropOff.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelDropOff.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelDropOff.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelDropOff.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelDropOff.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelDropOff.prototype, "lineDashOffset", 2);
var FunnelProperties = class extends AbstractBarSeriesProperties7 {
  constructor() {
    super(...arguments);
    this.fills = [];
    this.fillOpacity = 1;
    this.strokes = [];
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.spacingRatio = 0;
    this.dropOff = new FunnelDropOff();
    this.shadow = new DropShadow6().set({ enabled: false });
    this.label = new FunnelSeriesLabel();
    this.stageLabel = new FunnelSeriesStageLabel();
    this.tooltip = makeSeriesTooltip15();
  }
  getStyle(index) {
    const { fills, strokes, fillOpacity, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this;
    return {
      fill: fills[index],
      fillOpacity,
      stroke: strokes[index],
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset,
      opacity: 1
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelProperties.prototype, "stageKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelProperties.prototype, "valueKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelProperties.prototype, "fills", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelProperties.prototype, "strokes", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelProperties.prototype, "spacingRatio", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelProperties.prototype, "itemStyler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelProperties.prototype, "dropOff", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelProperties.prototype, "shadow", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelProperties.prototype, "stageLabel", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], FunnelProperties.prototype, "tooltip", 2);

// packages/ag-charts-enterprise/src/series/funnel/funnelSeries.ts
var { resetBarSelectionsFn: resetBarSelectionsFn4, prepareBarAnimationFunctions: prepareBarAnimationFunctions4, midpointStartingBarPosition: midpointStartingBarPosition3, createDatumId: createDatumId14, Rect: Rect10, motion: motion6 } = module_support_exports;
var FunnelSeries = class extends BaseFunnelSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      animationResetFns: {
        datum: resetBarSelectionsFn4
      }
    });
    this.properties = new FunnelProperties();
  }
  getBandScalePadding() {
    return { inner: this.properties.spacingRatio, outer: 0 };
  }
  connectorEnabled() {
    return this.properties.dropOff.enabled;
  }
  connectorStyle(index) {
    return mergeDefaults(this.properties.dropOff.getStyle(), this.properties.getStyle(index));
  }
  nodeFactory() {
    return new Rect10();
  }
  createLabelData({
    datumIndex,
    rect: rect2,
    yDatum,
    datum,
    visible
  }) {
    const { valueKey, stageKey, label } = this.properties;
    if (!label.enabled)
      return;
    const yDomain = this.getSeriesDomain("y" /* Y */).domain;
    const text2 = this.getLabelText(
      yDatum,
      datum,
      valueKey,
      "y",
      yDomain,
      label,
      { itemId: valueKey, value: yDatum, datum, stageKey, valueKey }
    );
    return {
      x: rect2.x + rect2.width / 2,
      y: rect2.y + rect2.height / 2,
      textAlign: "center",
      textBaseline: "middle",
      text: text2,
      itemId: stageKey,
      datum,
      datumIndex,
      series: this,
      visible
    };
  }
  getItemStyle({ datum, datumIndex }, isHighlight) {
    const { id: seriesId, properties } = this;
    const { stageKey, valueKey, itemStyler } = properties;
    const highlightStyle = this.getHighlightStyle(isHighlight, datumIndex);
    const baseStyle = mergeDefaults(highlightStyle, properties.getStyle(datumIndex));
    let style2 = baseStyle;
    if (itemStyler != null) {
      const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
      const overrides = this.cachedDatumCallback(
        createDatumId14(datumIndex, isHighlight ? "highlight" : "node"),
        () => {
          const highlightStateString = this.getHighlightStateString(activeHighlight, isHighlight, datumIndex);
          return this.callWithContext(itemStyler, {
            seriesId,
            datum,
            highlightState: highlightStateString,
            stageKey,
            valueKey,
            ...style2
          });
        }
      );
      if (overrides) {
        style2 = mergeDefaults(overrides, style2);
      }
    }
    return style2;
  }
  updateDatumNodes({
    datumSelection,
    isHighlight
  }) {
    const { contextNodeData } = this;
    if (!contextNodeData) {
      return;
    }
    const { shadow } = this.properties;
    const categoryAlongX = this.getCategoryDirection() === "x" /* X */;
    const fillBBox = this.getShapeFillBBox();
    datumSelection.each((rect2, datum) => {
      const style2 = this.getItemStyle(datum, isHighlight);
      rect2.setStyleProperties(style2, fillBBox);
      rect2.visible = categoryAlongX ? datum.width > 0 : datum.height > 0;
      rect2.crisp = datum.crisp;
      rect2.fillShadow = shadow;
    });
  }
  tooltipStyle(datum, datumIndex) {
    return this.getItemStyle({ datum, datumIndex }, false);
  }
  animateEmptyUpdateReady(params) {
    super.animateEmptyUpdateReady(params);
    const { datumSelection } = params;
    const isVertical = this.isVertical();
    const mode = "normal";
    const barFns = prepareBarAnimationFunctions4(midpointStartingBarPosition3(isVertical, mode), "unknown");
    motion6.fromToMotion(this.id, "datums", this.ctx.animationManager, [datumSelection], barFns);
  }
  animateWaitingUpdateReady(data) {
    super.animateWaitingUpdateReady(data);
    const { datumSelection: datumSelections } = data;
    const { processedData } = this;
    const dataDiff = processedData?.reduced?.diff?.[this.id];
    const fns = prepareBarAnimationFunctions4(midpointStartingBarPosition3(this.isVertical(), "fade"), "added");
    motion6.fromToMotion(
      this.id,
      "datums",
      this.ctx.animationManager,
      [datumSelections],
      fns,
      (_, datum) => datum.xValue,
      dataDiff
    );
  }
  hasItemStylers() {
    return this.properties.itemStyler != null || this.properties.label.itemStyler != null;
  }
};
FunnelSeries.className = "FunnelSeries";
FunnelSeries.type = "funnel";

// packages/ag-charts-enterprise/src/series/funnel/funnelSeriesOptionsDef.ts
var { funnelSeriesThemeableOptionsDef: funnelSeriesThemeableOptionsDef2 } = module_support_exports;
var funnelSeriesOptionsDef = {
  ...funnelSeriesThemeableOptionsDef2,
  ...without(commonSeriesOptionsDefs, ["showInLegend"]),
  type: required(constant("funnel")),
  stageKey: required(string),
  valueKey: required(string)
};

// packages/ag-charts-enterprise/src/series/funnel/funnelModule.ts
var FunnelSeriesModule = {
  type: "series",
  name: "funnel",
  chartType: "cartesian",
  enterprise: true,
  solo: true,
  version: VERSION,
  dependencies: [CartesianChartModule],
  options: funnelSeriesOptionsDef,
  defaultAxes: FUNNEL_SERIES_AXES,
  themeTemplate: FUNNEL_SERIES_THEME,
  create: (ctx) => new FunnelSeries(ctx)
};

// packages/ag-charts-enterprise/src/module-bundles/cartesian-series.ts
var AllCartesianSeriesModule2 = [
  AllCartesianSeriesModule,
  BoxPlotSeriesModule,
  CandlestickSeriesModule,
  ConeFunnelSeriesModule,
  FunnelSeriesModule,
  HeatmapSeriesModule,
  OhlcSeriesModule,
  RangeAreaSeriesModule,
  RangeBarSeriesModule,
  WaterfallSeriesModule
].flat();

// packages/ag-charts-enterprise/src/module-bundles/cartesian.ts
var AllCartesianModule2 = [
  AllCartesianAxesModule2,
  AllCartesianSeriesModule2,
  AnimationModule,
  AnnotationsModule,
  BandHighlightModule,
  ChartToolbarModule,
  ContextMenuModule,
  CrosshairModule,
  DataSourceModule,
  ErrorBarsModule,
  FlashOnUpdateModule,
  GradientLegendModule,
  NavigatorModule,
  RangesModule,
  ScrollbarModule,
  StatusBarModule,
  SyncModule,
  ZoomModule
].flat();

// packages/ag-charts-enterprise/src/preset/priceVolumePresetTheme.ts
var {
  DEFAULT_ANNOTATION_HANDLE_FILL: DEFAULT_ANNOTATION_HANDLE_FILL2,
  DEFAULT_ANNOTATION_STATISTICS_COLOR: DEFAULT_ANNOTATION_STATISTICS_COLOR2,
  DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE: DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE2,
  DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL: DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL2,
  DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE: DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE2,
  DEFAULT_ANNOTATION_STATISTICS_FILL: DEFAULT_ANNOTATION_STATISTICS_FILL2,
  DEFAULT_ANNOTATION_STATISTICS_STROKE: DEFAULT_ANNOTATION_STATISTICS_STROKE2,
  DEFAULT_FIBONACCI_STROKES: DEFAULT_FIBONACCI_STROKES2,
  DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL2,
  DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR2,
  DEFAULT_TEXTBOX_COLOR: DEFAULT_TEXTBOX_COLOR2,
  DEFAULT_TEXTBOX_FILL: DEFAULT_TEXTBOX_FILL2,
  DEFAULT_TEXTBOX_STROKE: DEFAULT_TEXTBOX_STROKE2,
  DEFAULT_TEXT_ANNOTATION_COLOR: DEFAULT_TEXT_ANNOTATION_COLOR2
} = main_exports;
var stroke2 = {
  stroke: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR2
};
var handle2 = {
  fill: DEFAULT_ANNOTATION_HANDLE_FILL2
};
var axisLabel2 = {
  color: "white",
  fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR2
};
var lineText2 = {
  color: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR2
};
var font2 = {
  color: DEFAULT_TEXT_ANNOTATION_COLOR2,
  fontSize: { $rem: FONT_SIZE_RATIO.LARGE },
  fontFamily: { $ref: "fontFamily" }
};
var measurerStatistics2 = {
  ...font2,
  fontSize: { $ref: "fontSize" },
  color: DEFAULT_ANNOTATION_STATISTICS_COLOR2,
  fill: DEFAULT_ANNOTATION_STATISTICS_FILL2,
  stroke: DEFAULT_ANNOTATION_STATISTICS_STROKE2,
  strokeWidth: 1,
  divider: {
    stroke: DEFAULT_ANNOTATION_STATISTICS_DIVIDER_STROKE2,
    strokeWidth: 1,
    strokeOpacity: 0.5
  }
};
var measurer2 = {
  ...stroke2,
  background: {
    fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL2,
    fillOpacity: 0.2
  },
  handle: { ...handle2 },
  text: { ...lineText2 },
  statistics: { ...measurerStatistics2 }
};
var annotationsTheme2 = {
  // Lines
  line: {
    ...stroke2,
    handle: { ...handle2 },
    text: { ...lineText2 }
  },
  "horizontal-line": {
    ...stroke2,
    handle: { ...handle2 },
    axisLabel: { ...axisLabel2 },
    text: { ...lineText2 }
  },
  "vertical-line": {
    ...stroke2,
    handle: { ...handle2 },
    axisLabel: { ...axisLabel2 },
    text: { ...lineText2 }
  },
  // Channels
  "disjoint-channel": {
    ...stroke2,
    background: {
      fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL2,
      fillOpacity: 0.2
    },
    handle: { ...handle2 },
    text: { ...lineText2 }
  },
  "parallel-channel": {
    ...stroke2,
    background: {
      fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL2,
      fillOpacity: 0.2
    },
    handle: { ...handle2 },
    text: { ...lineText2 }
  },
  // Fibonnaccis
  "fibonacci-retracement": {
    ...stroke2,
    strokes: DEFAULT_FIBONACCI_STROKES2,
    rangeStroke: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR2,
    handle: { ...handle2 },
    text: { ...lineText2, position: "center" },
    label: {
      ...font2,
      color: void 0,
      fontSize: { $rem: FONT_SIZE_RATIO.SMALLER }
    }
  },
  "fibonacci-retracement-trend-based": {
    ...stroke2,
    strokes: DEFAULT_FIBONACCI_STROKES2,
    rangeStroke: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR2,
    handle: { ...handle2 },
    text: { ...lineText2, position: "center" },
    label: {
      ...font2,
      color: void 0,
      fontSize: { $rem: FONT_SIZE_RATIO.SMALLER }
    }
  },
  // Texts
  callout: {
    ...stroke2,
    ...font2,
    color: { $ref: "textColor" },
    handle: { ...handle2 },
    fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL2,
    fillOpacity: 0.2
  },
  comment: {
    ...font2,
    color: "white",
    fontWeight: 700,
    handle: { ...handle2 },
    fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR2
  },
  note: {
    ...font2,
    color: DEFAULT_TEXTBOX_COLOR2,
    fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR2,
    stroke: { $ref: "chartBackgroundColor" },
    strokeWidth: 1,
    strokeOpacity: 1,
    handle: { ...handle2 },
    background: {
      fill: DEFAULT_TEXTBOX_FILL2,
      stroke: DEFAULT_TEXTBOX_STROKE2,
      strokeWidth: 1
    }
  },
  text: {
    ...font2,
    handle: { ...handle2 }
  },
  // Shapes
  arrow: {
    ...stroke2,
    handle: { ...handle2 },
    text: { ...lineText2 }
  },
  "arrow-up": {
    fill: { $palette: "up.fill" },
    handle: { ...handle2, stroke: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR2 }
  },
  "arrow-down": {
    fill: { $palette: "down.fill" },
    handle: { ...handle2, stroke: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_COLOR2 }
  },
  // Measurers
  "date-range": {
    ...measurer2
  },
  "price-range": {
    ...measurer2
  },
  "date-price-range": {
    ...measurer2
  },
  "quick-date-price-range": {
    up: {
      ...stroke2,
      fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL2,
      fillOpacity: 0.2,
      handle: { ...handle2 },
      statistics: {
        ...measurerStatistics2,
        color: "#fff",
        fill: DEFAULT_FINANCIAL_CHARTS_ANNOTATION_BACKGROUND_FILL2,
        strokeWidth: 0,
        divider: {
          stroke: "#fff",
          strokeWidth: 1,
          strokeOpacity: 0.5
        }
      }
    },
    down: {
      ...stroke2,
      stroke: DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE2,
      fill: DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL2,
      fillOpacity: 0.2,
      handle: {
        ...handle2,
        stroke: DEFAULT_ANNOTATION_STATISTICS_DOWN_STROKE2
      },
      statistics: {
        ...measurerStatistics2,
        color: "#fff",
        fill: DEFAULT_ANNOTATION_STATISTICS_DOWN_FILL2,
        strokeWidth: 0,
        divider: {
          stroke: "#fff",
          strokeWidth: 1,
          strokeOpacity: 0.5
        }
      }
    }
  },
  axesButtons: {
    enabled: true
  }
};

// packages/ag-charts-enterprise/src/preset/priceVolumePreset.ts
var chartTypes2 = ["ohlc", "line", "step-line", "hlc", "high-low", "candlestick", "hollow-candlestick"];
var toolbarButtons = [
  {
    icon: "trend-line-drawing",
    tooltip: "toolbarAnnotationsLineAnnotations",
    value: "line-menu"
  },
  {
    icon: "fibonacci-retracement-drawing",
    tooltip: "toolbarAnnotationsFibonacciAnnotations",
    value: "fibonacci-menu"
  },
  {
    icon: "text-annotation",
    tooltip: "toolbarAnnotationsTextAnnotations",
    value: "text-menu"
  },
  {
    icon: "arrow-drawing",
    tooltip: "toolbarAnnotationsShapeAnnotations",
    value: "shape-menu"
  },
  {
    icon: "measurer-drawing",
    tooltip: "toolbarAnnotationsMeasurerAnnotations",
    value: "measurer-menu"
  },
  {
    icon: "delete",
    tooltip: "toolbarAnnotationsClearAll",
    value: "clear"
  }
];
function priceVolume(opts, _presetTheme, getTheme) {
  const {
    dateKey = "date",
    highKey = "high",
    openKey = "open",
    lowKey = "low",
    closeKey = "close",
    volumeKey = "volume",
    chartType = "candlestick",
    navigator = false,
    volume = true,
    rangeButtons = true,
    statusBar = true,
    toolbar: toolbar2 = true,
    zoom = true,
    sync = false,
    theme,
    data,
    formatter: formatter2,
    ...unusedOpts
  } = opts;
  const priceSeries = createPriceSeries(chartType, dateKey, highKey, lowKey, openKey, closeKey);
  const volumeSeries = createVolumeSeries(getTheme, dateKey, openKey, closeKey, volume, volumeKey);
  const miniChart = volume ? {
    miniChart: {
      enabled: navigator,
      series: [
        {
          type: "line",
          xKey: dateKey,
          yKey: volumeKey,
          stroke: SAFE_STROKE_FILL_OPERATION,
          marker: { enabled: false }
        }
      ]
    },
    height: 40,
    minHandle: {
      height: 46
    },
    maxHandle: {
      height: 46
    }
  } : null;
  const navigatorOpts = {
    navigator: {
      enabled: navigator,
      ...miniChart
    }
  };
  const annotationOpts = {
    annotations: {
      enabled: toolbar2,
      optionsToolbar: {
        enabled: toolbar2
      },
      // @ts-expect-error undocumented option
      snap: true,
      toolbar: {
        enabled: toolbar2,
        buttons: toolbarButtons,
        padding: 0
      },
      data,
      xKey: dateKey,
      volumeKey: volume ? volumeKey : void 0
    }
  };
  const statusBarOpts = statusBar ? {
    statusBar: {
      enabled: true,
      highKey,
      openKey,
      lowKey,
      closeKey,
      volumeKey: volume ? volumeKey : void 0
    }
  } : null;
  const zoomOpts = {
    zoom: {
      enabled: zoom,
      autoScaling: {
        enabled: true
      },
      onDataChange: {
        stickToEnd: true
      },
      // @ts-expect-error undocumented option
      enableIndependentAxes: true
    }
  };
  const toolbarOpts = {
    ranges: {
      enabled: rangeButtons
    }
  };
  const syncGroup = sync ? {
    sync: {
      enabled: sync,
      nodeInteraction: true,
      zoom: true
    }
  } : null;
  const volumeAxis = volume ? {
    yVolume: {
      type: "number",
      position: "left",
      label: { enabled: false },
      crosshair: { enabled: false },
      gridLine: { enabled: false },
      nice: false,
      // @ts-expect-error undocumented option
      layoutConstraints: {
        stacked: false,
        width: 20,
        unit: "percent",
        align: "end"
      }
    }
  } : {};
  return {
    theme: {
      baseTheme: typeof theme === "string" ? theme : "ag-financial",
      ...mergeDefaults(typeof theme === "object" ? theme : null, {
        overrides: {
          common: {
            title: { padding: 4 },
            padding: {
              top: 6,
              right: 8,
              bottom: 6
            },
            chartToolbar: {
              enabled: toolbar2
            },
            annotations: { ...annotationsTheme2 },
            axes: {
              number: {
                interval: { maxSpacing: 45 },
                label: { format: ".2f" }
              },
              category: {
                gridLine: { enabled: true }
              },
              time: {
                gridLine: { enabled: true }
              },
              "unit-time": {
                gridLine: { enabled: true }
              },
              "ordinal-time": {
                gridLine: { enabled: true }
              }
            }
          },
          bar: {
            series: {
              fillOpacity: 0.5,
              highlight: { unhighlightedItem: { opacity: 1 }, unhighlightedSeries: { opacity: 1 } }
            }
          },
          line: {
            series: {
              marker: { enabled: false },
              highlight: { unhighlightedSeries: { opacity: 1 } },
              ...inlineSwitch(chartType, {
                hlc: {
                  stroke: { $palette: "altNeutral.stroke" },
                  strokeWidth: 2
                },
                line: {
                  stroke: { $palette: "neutral.stroke" }
                },
                "step-line": {
                  stroke: { $palette: "neutral.stroke" },
                  interpolation: { type: "step" }
                }
              })
            }
          },
          candlestick: {
            series: {
              highlight: { unhighlightedItem: { opacity: 1 }, unhighlightedSeries: { opacity: 1 } },
              ...inlineSwitch(chartType, {
                "hollow-candlestick": {
                  item: {
                    up: { fill: "transparent" }
                  }
                }
              })
            }
          },
          ohlc: {
            series: {
              highlight: { unhighlightedItem: { opacity: 1 }, unhighlightedSeries: { opacity: 1 } }
            }
          },
          "range-area": {
            series: {
              fillOpacity: 0.3,
              strokeWidth: 2,
              highlight: {
                bringToFront: false,
                unhighlightedItem: { opacity: 1 },
                unhighlightedSeries: { opacity: 1 }
              },
              ...inlineSwitch(chartType, {
                hlc: {
                  fill: {
                    $if: [
                      { $eq: [{ $value: "$index" }, 1] },
                      { $palette: "up.fill" },
                      { $palette: "down.fill" }
                    ]
                  },
                  stroke: {
                    $if: [
                      { $eq: [{ $value: "$index" }, 1] },
                      { $palette: "up.stroke" },
                      { $palette: "down.stroke" }
                    ]
                  }
                }
              })
            }
          },
          "range-bar": {
            series: {
              highlight: {
                unhighlightedItem: { opacity: 1 },
                unhighlightedSeries: { opacity: 1 }
              },
              ...inlineSwitch(chartType, {
                "high-low": {
                  fill: { $palette: "neutral.fill" },
                  stroke: { $palette: "neutral.stroke" }
                }
              })
            }
          }
        }
      })
    },
    animation: { enabled: false },
    legend: { enabled: false },
    series: [...volumeSeries, ...priceSeries],
    axes: {
      y: {
        type: "number",
        position: "right",
        crosshair: {
          enabled: true,
          snap: false
        },
        // @ts-expect-error undocumented option
        layoutConstraints: {
          stacked: false,
          width: 100,
          unit: "percent",
          align: "start"
        }
      },
      ...volumeAxis,
      x: {
        type: "ordinal-time",
        position: "bottom",
        line: {
          enabled: false
        },
        label: {
          enabled: true
        },
        crosshair: {
          enabled: true
        }
      }
    },
    tooltip: { enabled: false },
    data,
    formatter: formatter2,
    ...annotationOpts,
    ...navigatorOpts,
    ...statusBarOpts,
    ...zoomOpts,
    ...toolbarOpts,
    ...syncGroup,
    ...unusedOpts
  };
}
function createVolumeSeries(getTheme, xKey, openKey, closeKey, volume, volumeKey) {
  if (!volume)
    return [];
  return [
    {
      type: "bar",
      xKey,
      yKey: volumeKey,
      yKeyAxis: "yVolume",
      tooltip: { enabled: false },
      // @ts-expect-error undocumented options: simpleItemStyler, focusPriority
      simpleItemStyler(datum) {
        const { up, down } = getTheme().palette;
        return { fill: datum[openKey] < datum[closeKey] ? up?.fill : down?.fill };
      },
      focusPriority: 1,
      highlight: { unhighlightedSeries: { opacity: 1 } }
    }
  ];
}
var RANGE_AREA_TYPE = "range-area";
function createPriceSeries(chartType, xKey, highKey, lowKey, openKey, closeKey) {
  const keys = {
    xKey,
    openKey,
    closeKey,
    highKey,
    lowKey
  };
  const singleKeys = {
    xKey,
    yKey: closeKey
  };
  const common = {
    pickOutsideVisibleMinorAxis: true
  };
  switch (chartType ?? "candlestick") {
    case "ohlc":
      return createPriceSeriesOHLC(common, keys);
    case "line":
    case "step-line":
      return createPriceSeriesLine(common, singleKeys);
    case "hlc":
      return createPriceSeriesHLC(common, singleKeys, keys);
    case "high-low":
      return createPriceSeriesHighLow(common, keys);
    case "candlestick":
    case "hollow-candlestick":
      return createPriceSeriesCandlestick(common, keys);
    default:
      logger_exports.warnOnce(`unknown chart type: ${chartType}; expected one of: ${chartTypes2.join(", ")}`);
      return createPriceSeriesCandlestick(common, keys);
  }
}
function createPriceSeriesOHLC(common, keys) {
  return [
    {
      type: "ohlc",
      // @ts-expect-error undocumented option
      focusPriority: 0,
      ...common,
      ...keys
    }
  ];
}
function createPriceSeriesLine(common, singleKeys) {
  return [
    {
      type: "line",
      // @ts-expect-error undocumented option
      focusPriority: 0,
      ...common,
      ...singleKeys
    }
  ];
}
function createPriceSeriesHLC(common, singleKeys, { xKey, highKey, closeKey, lowKey }) {
  return [
    {
      type: RANGE_AREA_TYPE,
      // @ts-expect-error undocumented option
      focusPriority: 0,
      ...common,
      xKey,
      yHighKey: highKey,
      yLowKey: closeKey
    },
    {
      type: RANGE_AREA_TYPE,
      // @ts-expect-error undocumented option
      focusPriority: 0,
      ...common,
      xKey,
      yHighKey: closeKey,
      yLowKey: lowKey
    },
    {
      type: "line",
      ...common,
      ...singleKeys
    }
  ];
}
function createPriceSeriesHighLow(common, { xKey, highKey, lowKey }) {
  return [
    {
      type: "range-bar",
      ...common,
      xKey,
      yHighKey: highKey,
      yLowKey: lowKey,
      tooltip: { range: "nearest" },
      // @ts-expect-error undocumented option
      focusPriority: 0
    }
  ];
}
function createPriceSeriesCandlestick(common, keys) {
  return [
    {
      type: "candlestick",
      // @ts-expect-error undocumented option
      focusPriority: 0,
      ...common,
      ...keys
    }
  ];
}
function inlineSwitch(caseName, switchCases) {
  return switchCases[caseName] ?? switchCases.default;
}

// packages/ag-charts-enterprise/src/preset/priceVolumePresetModules.ts
var priceVolumeOptionsDef = {
  chartType: union("candlestick", "hollow-candlestick", "ohlc", "line", "step-line", "hlc", "high-low"),
  dateKey: string,
  openKey: string,
  highKey: string,
  lowKey: string,
  closeKey: string,
  volumeKey: string,
  navigator: boolean,
  volume: boolean,
  rangeButtons: boolean,
  statusBar: boolean,
  toolbar: boolean,
  zoom: boolean,
  sync: boolean,
  // Valid pass-through options
  theme: defined,
  container: defined,
  width: defined,
  height: defined,
  minWidth: defined,
  minHeight: defined,
  listeners: defined,
  initialState: defined,
  title: defined,
  data: array,
  formatter: defined
};
var commonGaugeOptions = {
  // Valid pass-through options
  theme: defined,
  container: defined,
  animation: defined,
  background: defined,
  contextMenu: defined,
  context: () => true,
  listeners: defined,
  locale: defined,
  width: defined,
  height: defined,
  minWidth: defined,
  minHeight: defined,
  title: defined,
  subtitle: defined,
  footnote: defined,
  padding: defined,
  tooltip: {
    ...tooltipOptionsDefs,
    ...commonChartOptionsDefs.tooltip
  }
};
commonGaugeOptions.overrideDevicePixelRatio = undocumented(positiveNumber);
var PriceVolumePresetModule = {
  type: "preset",
  name: "price-volume",
  enterprise: true,
  dependencies: [ChartToolbarModule, StatusBarModule],
  version: VERSION,
  options: priceVolumeOptionsDef,
  create: priceVolume
};

// packages/ag-charts-enterprise/src/module-bundles/financial.ts
var FinancialChartModule = [
  PriceVolumePresetModule,
  BarSeriesModule,
  LineSeriesModule,
  CandlestickSeriesModule,
  OhlcSeriesModule,
  RangeBarSeriesModule,
  RangeAreaSeriesModule,
  AnimationModule,
  AnnotationsModule,
  BandHighlightModule,
  ChartToolbarModule,
  ContextMenuModule,
  CrosshairModule,
  DataSourceModule,
  ErrorBarsModule,
  GradientLegendModule,
  NavigatorModule,
  RangesModule,
  SyncModule,
  ZoomModule,
  OrdinalTimeAxisModule,
  TimeAxisModule,
  NumberAxisModule
];

// packages/ag-charts-enterprise/src/preset/gaugePreset.ts
function tooltipOptions(opts) {
  const { enabled, mode, showArrow, range: range3, position, pagination, delay, wrapping, interaction, renderer, ...rest } = opts;
  const seriesTooltipOptions = {
    enabled,
    showArrow,
    range: range3,
    position,
    interaction,
    renderer,
    ...rest
  };
  const chartTooltipOptions = {
    mode,
    pagination,
    delay,
    wrapping,
    ...rest
  };
  return { chartTooltipOptions, seriesTooltipOptions };
}
function radialGaugeOptions(opts) {
  const {
    animation,
    background,
    container,
    contextMenu,
    context,
    footnote,
    foreground,
    height: height2,
    listeners,
    locale,
    minHeight,
    minWidth,
    overrideDevicePixelRatio,
    padding: padding2,
    subtitle,
    theme,
    title,
    width: width2,
    type,
    cursor,
    nodeClickRange,
    tooltip: tooltipInput,
    value,
    scale: scale2 = {},
    startAngle,
    endAngle,
    highlight: highlight5,
    segmentation,
    bar,
    needle,
    targets,
    outerRadius,
    innerRadius,
    outerRadiusRatio,
    innerRadiusRatio,
    cornerRadius,
    cornerMode,
    label,
    secondaryLabel,
    spacing,
    ...seriesRest
  } = opts;
  const hasTooltip = tooltipInput != null;
  const tooltip = tooltipInput ?? {};
  const { chartTooltipOptions, seriesTooltipOptions } = tooltipOptions(tooltip);
  const seriesOpts = {
    ...seriesRest,
    type,
    cursor,
    context,
    nodeClickRange,
    value,
    scale: scale2,
    startAngle,
    endAngle,
    highlight: highlight5,
    segmentation,
    bar,
    targets,
    outerRadius,
    innerRadius,
    outerRadiusRatio,
    innerRadiusRatio,
    cornerRadius,
    cornerMode,
    label,
    secondaryLabel,
    spacing
  };
  if (hasTooltip) {
    seriesOpts.tooltip = seriesTooltipOptions;
  }
  if (needle != null) {
    seriesOpts.needle = { enabled: true, ...needle };
  }
  return {
    animation,
    background,
    container,
    contextMenu,
    context,
    footnote,
    foreground,
    height: height2,
    listeners,
    locale,
    minHeight,
    minWidth,
    overrideDevicePixelRatio,
    padding: padding2,
    subtitle,
    theme,
    title,
    width: width2,
    ...hasTooltip ? { tooltip: chartTooltipOptions } : {},
    series: [seriesOpts]
  };
}
function linearGaugeOptions(opts) {
  const {
    animation,
    background,
    container,
    contextMenu,
    context,
    footnote,
    foreground,
    height: height2,
    listeners,
    locale,
    minHeight,
    minWidth,
    overrideDevicePixelRatio,
    padding: padding2,
    subtitle,
    theme,
    title,
    width: width2,
    type,
    cursor,
    nodeClickRange,
    tooltip: tooltipInput,
    value,
    scale: scale2 = {},
    direction = "vertical",
    thickness,
    highlight: highlight5,
    segmentation,
    bar,
    targets,
    cornerRadius,
    cornerMode,
    label,
    ...seriesRest
  } = opts;
  const hasTooltip = tooltipInput != null;
  const tooltip = tooltipInput ?? {};
  const { chartTooltipOptions, seriesTooltipOptions } = tooltipOptions(tooltip);
  const seriesOpts = {
    ...seriesRest,
    type,
    cursor,
    nodeClickRange,
    value,
    scale: scale2,
    direction,
    thickness,
    highlight: highlight5,
    segmentation,
    bar,
    targets,
    cornerRadius,
    cornerMode,
    label
  };
  if (hasTooltip) {
    seriesOpts.tooltip = seriesTooltipOptions;
  }
  return {
    animation,
    background,
    container,
    contextMenu,
    context,
    footnote,
    foreground,
    height: height2,
    listeners,
    locale,
    minHeight,
    minWidth,
    overrideDevicePixelRatio,
    padding: padding2,
    subtitle,
    theme,
    title,
    width: width2,
    ...hasTooltip ? { tooltip: chartTooltipOptions } : {},
    series: [seriesOpts]
  };
}
function applyThemeDefaults(opts, presetTheme) {
  if (presetTheme == null)
    return opts;
  const { targets: targetsTheme, ...gaugeTheme } = presetTheme;
  opts = mergeDefaults(opts, gaugeTheme);
  if (opts.targets != null && targetsTheme != null) {
    if (opts.type === "radial-gauge") {
      opts.targets = mergeArrayDefaults(opts.targets, targetsTheme);
    } else {
      opts.targets = mergeArrayDefaults(opts.targets, targetsTheme);
    }
  }
  return opts;
}
function createGauge(opts, presetTheme) {
  switch (opts.type) {
    case "radial-gauge":
      return radialGaugeOptions(applyThemeDefaults(opts, presetTheme));
    case "linear-gauge":
      return linearGaugeOptions(applyThemeDefaults(opts, presetTheme));
    default:
      return { series: [] };
  }
}

// packages/ag-charts-enterprise/src/preset/gaugePresetModule.ts
var commonGaugeOptions2 = {
  // Valid pass-through options
  theme: defined,
  container: defined,
  animation: defined,
  background: defined,
  contextMenu: defined,
  context: () => true,
  listeners: defined,
  locale: defined,
  width: defined,
  height: defined,
  minWidth: defined,
  minHeight: defined,
  title: defined,
  subtitle: defined,
  footnote: defined,
  padding: defined,
  tooltip: {
    ...tooltipOptionsDefs,
    ...commonChartOptionsDefs.tooltip
  }
};
commonGaugeOptions2.overrideDevicePixelRatio = undocumented(positiveNumber);
commonGaugeOptions2.foreground = undocumented(defined);
var GaugePresetModule = {
  type: "preset",
  name: "gauge-preset",
  enterprise: true,
  version: VERSION,
  dependencies: [StandaloneChartModule],
  options: typeUnion(
    {
      "linear-gauge": {
        ...without(linearGaugeSeriesOptionsDef, ["type"]),
        ...commonGaugeOptions2
      },
      "radial-gauge": {
        ...without(radialGaugeSeriesOptionsDef, ["type"]),
        ...commonGaugeOptions2
      }
    },
    "gauge options"
  ),
  create: createGauge
};

// packages/ag-charts-enterprise/src/series/gauge-util/datumUnion.ts
var DatumUnion = class {
  *[Symbol.iterator]() {
    const { node, datum } = this;
    if (node && datum)
      yield { node, datum };
  }
  nodes() {
    return this.node ? [this.node] : [];
  }
  update(datumSelection, group, ctor, nodeUpdater) {
    const nodes = datumSelection.nodes();
    if (nodes.length === 0) {
      this.node?.remove();
      this.node = void 0;
    } else {
      if (this.node === void 0) {
        this.node = new ctor();
        this.node.fillOpacity = 0;
        this.node.strokeOpacity = 0;
        group.appendChild(this.node);
      }
      const first2 = nodes[0];
      const last = nodes.toReversed().find((n) => n.datum.datum.value > n.datum.datum.segmentStart) ?? nodes.at(-1);
      this.node.datum = this.datum = first2.datum;
      nodeUpdater(this.node, first2, last);
    }
  }
};

// packages/ag-charts-enterprise/src/series/gauge-util/label.ts
var fadeInFns = {
  fromFn: () => ({ opacity: 0, phase: "initial" }),
  toFn: () => ({ opacity: 1 })
};
function formatLabel(value, scale2) {
  if (value == null)
    return "";
  const { min, max } = scale2;
  const minLog10 = min === 0 ? 0 : Math.ceil(Math.log10(Math.abs(min)));
  const maxLog10 = max === 0 ? 0 : Math.ceil(Math.log10(Math.abs(max)));
  const dp = Math.max(2 - Math.max(minLog10, maxLog10), 0);
  return value.toFixed(dp);
}
function getLabelText(seriesId, ctx, datum, valueOverride) {
  if (datum.text != null)
    return datum.text;
  const value = valueOverride ?? datum.value;
  let labelFormat;
  if (datum?.formatter != null) {
    labelFormat = formatWithContext(ctx, datum.formatter, { seriesId, datum: void 0, value });
  }
  return labelFormat == null || isArray(labelFormat) ? labelFormat : String(labelFormat);
}

// packages/ag-charts-enterprise/src/series/gauge-util/lineMarker.ts
function lineMarker({ path, x, y, size }) {
  path.moveTo(x, y - size / 2);
  path.lineTo(x, y + size / 2);
}

// packages/ag-charts-enterprise/src/series/gauge-util/pick.ts
function pickGaugeNearestDatum(self, point) {
  const it = iterate(self.datumUnion.nodes(), self.targetSelection.nodes());
  return self.pickNodeNearestDistantObject(point, it);
}
function pickGaugeFocus(self, opts) {
  const others = [
    { data: self.contextNodeData?.nodeData, selection: self.datumUnion },
    { data: self.contextNodeData?.targetData, selection: self.targetSelection }
  ].filter((v) => v.data && v.data.length > 0);
  const otherIndex = clamp(0, opts.otherIndex + opts.otherIndexDelta, others.length - 1);
  if (others.length === 0)
    return;
  const { data, selection } = others[otherIndex];
  if (data == null || data.length === 0)
    return;
  const datumIndex = clamp(0, opts.datumIndex, data.length - 1);
  const datum = data[datumIndex];
  for (const node of selection) {
    if (node.datum === datum) {
      const bounds = node.node;
      return { bounds, clipFocusBox: true, datum, datumIndex, otherIndex };
    }
  }
}
function findGaugeNodeDatum(self, itemId) {
  return module_support_exports.findNodeDatumInArray(itemId, self.contextNodeData?.nodeData) ?? module_support_exports.findNodeDatumInArray(itemId, self.contextNodeData?.targetData);
}

// packages/ag-charts-enterprise/src/series/gauge-util/segmentation.ts
var GaugeSegmentationIntervalProperties = class extends BaseProperties {
  getSegments(scale2, maxTicks) {
    const { values, step, count } = this;
    const d0 = Math.min(...scale2.domain);
    const d1 = Math.max(...scale2.domain);
    let ticks;
    if (values != null) {
      const segments = values.filter((v) => v > d0 && v < d1).sort((a, b) => a - b);
      ticks = [d0, ...segments, d1];
    } else if (step != null) {
      const segments = [];
      for (let i = d0; i < d1; i += step) {
        segments.push(i);
      }
      segments.push(d1);
      ticks = segments;
    } else if (count == null) {
      const segments = scale2.ticks({
        nice: [true, true],
        interval: void 0,
        tickCount: void 0,
        minTickCount: 0,
        maxTickCount: Infinity
      })?.ticks?.filter((v) => v > d0 && v < d1);
      ticks = segments == null ? void 0 : [d0, ...segments, d1];
    } else {
      const segments = count + 1;
      ticks = Array.from({ length: segments + 1 }, (_, i) => i / segments * (d1 - d0) + d0);
    }
    if (ticks != null && ticks.length > maxTicks) {
      logger_exports.warnOnce(
        `the configured segmentation results in more than 1 item per pixel, ignoring. Supply a segmentation configuration that results in larger segments or omit this configuration`
      );
      ticks = void 0;
    }
    ticks ?? (ticks = [d0, d1]);
    return ticks;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], GaugeSegmentationIntervalProperties.prototype, "values", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], GaugeSegmentationIntervalProperties.prototype, "step", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], GaugeSegmentationIntervalProperties.prototype, "count", 2);
var GaugeSegmentationProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = false;
    this.interval = new GaugeSegmentationIntervalProperties();
    this.spacing = 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], GaugeSegmentationProperties.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], GaugeSegmentationProperties.prototype, "interval", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], GaugeSegmentationProperties.prototype, "spacing", 2);

// packages/ag-charts-enterprise/src/series/linear-gauge/linearGaugeSeriesProperties.ts
var { makeSeriesTooltip: makeSeriesTooltip16, SeriesProperties: SeriesProperties5, Label: Label14, AxisLabel: AxisLabel6, getColorStops: getColorStops2 } = module_support_exports;
var LinearGaugeDefaultTargetLabelProperties = class extends Label14 {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeDefaultTargetLabelProperties.prototype, "spacing", 2);
var LinearGaugeTargetProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.value = 0;
    this.label = new LinearGaugeDefaultTargetLabelProperties();
  }
  getStyle(defaultTarget) {
    const {
      fill = defaultTarget.fill ?? "black",
      fillOpacity = defaultTarget.fillOpacity ?? 1,
      stroke: stroke3 = defaultTarget.stroke ?? "black",
      strokeWidth = defaultTarget.strokeWidth ?? 0,
      strokeOpacity = defaultTarget.strokeOpacity ?? 1,
      lineDash = defaultTarget.lineDash ?? [0],
      lineDashOffset = defaultTarget.lineDashOffset ?? 0
    } = this;
    return {
      fill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeTargetProperties.prototype, "text", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeTargetProperties.prototype, "value", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeTargetProperties.prototype, "shape", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeTargetProperties.prototype, "placement", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeTargetProperties.prototype, "spacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeTargetProperties.prototype, "size", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeTargetProperties.prototype, "rotation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeTargetProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeTargetProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeTargetProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeTargetProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeTargetProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeTargetProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeTargetProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeTargetProperties.prototype, "label", 2);
var LinearGaugeBarProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = true;
    this.thicknessRatio = 1;
    this.fills = new PropertiesArray(module_support_exports.StopProperties);
    this.fillMode = "continuous";
    this.fillOpacity = 1;
    this.stroke = "black";
    this.strokeWidth = 0;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
  }
  getStyle(defaultColorRange, horizontal, scale2) {
    const { fill, fills, fillMode, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this;
    const barFill = fill ?? createLinearGradient(fills, fillMode, defaultColorRange, scale2, horizontal);
    return {
      fill: barFill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeBarProperties.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeBarProperties.prototype, "thickness", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeBarProperties.prototype, "thicknessRatio", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeBarProperties.prototype, "fills", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeBarProperties.prototype, "fillMode", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeBarProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeBarProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeBarProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeBarProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeBarProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeBarProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeBarProperties.prototype, "lineDashOffset", 2);
var LinearGaugeScaleIntervalProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.values = void 0;
    this.step = void 0;
    this.minSpacing = 0;
    this.maxSpacing = 1e3;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeScaleIntervalProperties.prototype, "values", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeScaleIntervalProperties.prototype, "step", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeScaleIntervalProperties.prototype, "minSpacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeScaleIntervalProperties.prototype, "maxSpacing", 2);
var LinearGaugeScaleLabelProperties = class extends AxisLabel6 {
  constructor() {
    super(...arguments);
    this.placement = void 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeScaleLabelProperties.prototype, "placement", 2);
var LinearGaugeScaleProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.min = 0;
    this.max = 1;
    this.fills = new PropertiesArray(module_support_exports.StopProperties);
    this.fillMode = "continuous";
    this.fillOpacity = 1;
    this.stroke = "black";
    this.strokeWidth = 0;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.defaultFill = "black";
    this.interval = new LinearGaugeScaleIntervalProperties();
    this.label = new LinearGaugeScaleLabelProperties();
  }
  getStyle(barEnabled, defaultColorRange, horizontal, scale2) {
    const {
      fill,
      fills,
      defaultFill,
      fillMode,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset
    } = this;
    const scaleFill = fill ?? (barEnabled && fills.length === 0 ? defaultFill : void 0) ?? createLinearGradient(fills, fillMode, defaultColorRange, scale2, horizontal);
    return {
      fill: scaleFill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeScaleProperties.prototype, "min", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeScaleProperties.prototype, "max", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeScaleProperties.prototype, "fills", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeScaleProperties.prototype, "fillMode", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeScaleProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeScaleProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeScaleProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeScaleProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeScaleProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeScaleProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeScaleProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeScaleProperties.prototype, "defaultFill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeScaleProperties.prototype, "interval", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeScaleProperties.prototype, "label", 2);
var LinearGaugeLabelProperties = class extends AutoSizedLabel {
  constructor() {
    super(...arguments);
    this.placement = "inside-center";
    this.avoidCollisions = true;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeLabelProperties.prototype, "text", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeLabelProperties.prototype, "placement", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeLabelProperties.prototype, "avoidCollisions", 2);
var LinearGaugeSeriesProperties = class extends SeriesProperties5 {
  constructor() {
    super(...arguments);
    this.value = 0;
    this.segmentation = new GaugeSegmentationProperties();
    this.defaultColorRange = [];
    this.targets = new PropertiesArray(LinearGaugeTargetProperties);
    this.defaultTarget = new LinearGaugeTargetProperties();
    this.defaultScale = new LinearGaugeScaleProperties();
    this.direction = "vertical";
    this.thickness = 1;
    this.cornerRadius = 0;
    this.cornerMode = "container";
    this.margin = 0;
    this.scale = new LinearGaugeScaleProperties();
    this.bar = new LinearGaugeBarProperties();
    this.label = new LinearGaugeLabelProperties();
    this.tooltip = makeSeriesTooltip16();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeSeriesProperties.prototype, "value", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeSeriesProperties.prototype, "segmentation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeSeriesProperties.prototype, "defaultColorRange", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeSeriesProperties.prototype, "targets", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeSeriesProperties.prototype, "defaultTarget", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeSeriesProperties.prototype, "defaultScale", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeSeriesProperties.prototype, "direction", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeSeriesProperties.prototype, "thickness", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeSeriesProperties.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeSeriesProperties.prototype, "cornerMode", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeSeriesProperties.prototype, "margin", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeSeriesProperties.prototype, "scale", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeSeriesProperties.prototype, "bar", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeSeriesProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], LinearGaugeSeriesProperties.prototype, "tooltip", 2);
function createLinearGradient(fills, fillMode, defaultColorRange, scale2, horizontal) {
  const colorStops = getColorStops2(fills, defaultColorRange, scale2.domain, fillMode);
  return {
    type: "gradient",
    gradient: "linear",
    colorSpace: "oklch",
    colorStops,
    rotation: horizontal ? 90 : 0,
    bounds: "series"
  };
}

// packages/ag-charts-enterprise/src/series/linear-gauge/linearGaugeUtil.ts
var { BBox: BBox24 } = module_support_exports;
function datumRect(datum) {
  const { x0, y0, x1, y1, horizontalInset, verticalInset } = datum;
  const x = Math.min(x0, x1) + horizontalInset;
  const y = Math.min(y0, y1) + verticalInset;
  const width2 = Math.max(Math.abs(x1 - x0) - 2 * horizontalInset, 0);
  const height2 = Math.max(Math.abs(y1 - y0) - 2 * verticalInset, 0);
  return { x, y, width: width2, height: height2 };
}
function clipBBoxVisibility(datum, clipBBox) {
  if (clipBBox == null)
    return true;
  const rect2 = datumRect(datum);
  const delta5 = 1e-6;
  const x0 = rect2.x + delta5;
  const y0 = rect2.y + delta5;
  const x1 = rect2.x + rect2.width - delta5;
  const y1 = rect2.y + rect2.height - delta5;
  const clipX0 = clipBBox.x;
  const clipX1 = clipBBox.x + clipBBox.width;
  const clipY0 = clipBBox.y;
  const clipY1 = clipBBox.y + clipBBox.height;
  return Math.max(x0, clipX0) <= Math.min(x1, clipX1) && Math.max(y0, clipY0) <= Math.min(y1, clipY1);
}
function hasClipBBox(datum) {
  const { clipX0, clipX1, clipY0, clipY1 } = datum;
  return clipX0 != null && clipX1 != null || clipY0 != null && clipY1 != null;
}
function computeClipBBox(datum) {
  if (!hasClipBBox(datum))
    return;
  const { x0, y0, x1, y1 } = datum;
  const { x, y, width: width2, height: height2 } = datumRect(datum);
  let { clipX0, clipX1, clipY0, clipY1 } = datum;
  if (clipX0 == null || clipX1 == null) {
    clipX0 = x0;
    clipX1 = x1;
  }
  if (clipY0 == null || clipY1 == null) {
    clipY0 = y0;
    clipY1 = y1;
  }
  const clipX = Math.min(clipX0, clipX1);
  const clipY = Math.min(clipY0, clipY1);
  const clipWidth = Math.abs(clipX1 - clipX0);
  const clipHeight = Math.abs(clipY1 - clipY0);
  clipX0 = Math.max(x, clipX);
  clipY0 = Math.max(y, clipY);
  clipX1 = Math.min(x + width2, clipX + clipWidth);
  clipY1 = Math.min(y + height2, clipY + clipHeight);
  return new BBox24(
    Math.min(clipX0, clipX1),
    Math.min(clipY0, clipY1),
    Math.abs(clipX1 - clipX0),
    Math.abs(clipY1 - clipY0)
  );
}
function prepareLinearGaugeSeriesAnimationFunctions(initialLoad, horizontal) {
  const phase = initialLoad ? "initial" : "update";
  const node = {
    fromFn(sect, datum) {
      const previousDatum = sect.previousDatum;
      let { x0, y0, x1, y1, clipX0, clipY0, clipX1, clipY1 } = previousDatum ?? datum;
      const { horizontalInset, verticalInset } = datum;
      const previousHadClipBBox = previousDatum != null && hasClipBBox(previousDatum);
      const nextHasClipBBox = hasClipBBox(datum);
      if (previousHadClipBBox && nextHasClipBBox) {
      } else if (!previousHadClipBBox && nextHasClipBBox) {
        ({ x0, y0, x1, y1, clipX0, clipY0, clipX1, clipY1 } = datum);
        if (initialLoad) {
          if (horizontal) {
            clipX1 = datum.clipX0;
          } else {
            clipY1 = datum.clipY0;
          }
        }
      } else if (previousHadClipBBox && !nextHasClipBBox) {
        ({ x0, y0, x1, y1 } = datum);
        clipX0 = void 0;
        clipY0 = void 0;
        clipX1 = void 0;
        clipY1 = void 0;
      } else if (initialLoad) {
        if (horizontal) {
          x1 = x0;
        } else {
          y1 = y0;
        }
      }
      return { x0, y0, x1, y1, clipX0, clipY0, clipX1, clipY1, horizontalInset, verticalInset, phase };
    },
    toFn(_sect, datum) {
      const { x0, y0, x1, y1, clipX0, clipY0, clipX1, clipY1, horizontalInset, verticalInset } = datum;
      return { x0, y0, x1, y1, clipX0, clipY0, clipX1, clipY1, horizontalInset, verticalInset };
    },
    applyFn(rect2, params) {
      rect2.setProperties(resetLinearGaugeSeriesResetRectFunction(rect2, params));
    }
  };
  return { node };
}
function resetLinearGaugeSeriesResetRectFunction(_node, datum) {
  const { x, y, width: width2, height: height2 } = datumRect(datum);
  const clipBBox = computeClipBBox(datum);
  const visible = clipBBoxVisibility(datum, clipBBox);
  return { x, y, width: width2, height: height2, clipBBox, visible };
}
var horizontalTextAligns = {
  ["Before" /* Before */]: "right",
  ["Center" /* Center */]: "center",
  ["After" /* After */]: "left"
};
var verticalTextBaselines = {
  ["Before" /* Before */]: "top",
  ["Center" /* Center */]: "middle",
  ["After" /* After */]: "bottom"
};
var horizontalAlignFactors = {
  ["Before" /* Before */]: -1,
  ["Center" /* Center */]: -0.5,
  ["After" /* After */]: 0
};
var verticalAlignFactors3 = {
  ["Before" /* Before */]: 0,
  ["Center" /* Center */]: -0.5,
  ["After" /* After */]: -1
};
function formatLinearGaugeLabels(series, ctx, selection, opts, bboxes, datumOverrides) {
  const { seriesRect, gaugeRect, barRect } = bboxes;
  const { padding: padding2, horizontal } = opts;
  selection.each((label, labelDatum) => {
    const labelText = getLabelText(series.id, ctx, labelDatum, datumOverrides?.label);
    let boundingWidth;
    let boundingHeight;
    if (labelDatum.placement === "outside-start") {
      if (horizontal) {
        boundingWidth = gaugeRect.x;
        boundingHeight = seriesRect.height;
      } else {
        boundingWidth = seriesRect.width;
        boundingHeight = seriesRect.height - (gaugeRect.y + gaugeRect.height);
      }
    } else if (labelDatum.placement === "outside-end") {
      if (horizontal) {
        boundingWidth = seriesRect.width - (gaugeRect.x + gaugeRect.width);
        boundingHeight = seriesRect.height;
      } else {
        boundingWidth = seriesRect.width;
        boundingHeight = gaugeRect.y;
      }
    } else if (labelDatum.avoidCollisions) {
      boundingWidth = gaugeRect.width;
      boundingHeight = gaugeRect.height;
    }
    let layout;
    if (labelText == null) {
      return;
    } else if (boundingWidth != null && boundingHeight != null) {
      const sizeFittingHeight = () => ({
        width: boundingWidth,
        height: boundingHeight,
        meta: null
      });
      const labelMeta = formatSingleLabel(toPlainText(labelText), labelDatum, { padding: padding2 }, sizeFittingHeight);
      layout = labelMeta?.[0];
    } else {
      const measurer3 = cachedTextMeasurer(labelDatum);
      const { width: width2, height: height2 } = isArray(labelText) ? measureTextSegments(labelText, labelDatum) : measurer3.measureLines(toTextString(labelText));
      layout = {
        text: labelText,
        fontSize: labelDatum.fontSize,
        lineHeight: labelDatum.lineHeight ?? measurer3.lineHeight(),
        width: width2,
        height: height2
      };
    }
    if (layout == null) {
      label.visible = false;
      return;
    }
    const scale0 = horizontal ? gaugeRect.x : gaugeRect.y + gaugeRect.height;
    const scale1 = horizontal ? gaugeRect.x + gaugeRect.width : gaugeRect.y;
    const bar0 = horizontal ? barRect.x : barRect.y + barRect.height;
    const bar1 = horizontal ? barRect.x + barRect.width : barRect.y;
    const offset = labelDatum.spacing * (horizontal ? 1 : -1);
    let bounds0;
    let bounds1;
    let s;
    let align2;
    switch (labelDatum.placement) {
      case "outside-start":
        bounds0 = -Infinity;
        bounds1 = Infinity;
        s = scale0 - offset;
        align2 = "Before" /* Before */;
        break;
      case "outside-end":
        bounds0 = -Infinity;
        bounds1 = Infinity;
        s = scale1 + offset;
        align2 = "After" /* After */;
        break;
      case "inside-start":
        bounds0 = scale0;
        bounds1 = bar1;
        s = scale0 + offset;
        align2 = "After" /* After */;
        break;
      case "inside-end":
        bounds0 = bar1;
        bounds1 = scale1;
        s = scale1 - offset;
        align2 = "Before" /* Before */;
        break;
      case "inside-center":
        bounds0 = scale0;
        bounds1 = scale1;
        s = (scale0 + scale1) / 2;
        align2 = "Center" /* Center */;
        break;
      case "bar-inside":
        bounds0 = bar0;
        bounds1 = bar1;
        s = (bar0 + bar1) / 2;
        align2 = "Center" /* Center */;
        break;
      case "bar-inside-end":
        bounds0 = bar0;
        bounds1 = bar1;
        s = bar1 - offset;
        align2 = "Before" /* Before */;
        break;
      case "bar-outside-end":
        bounds0 = bar1;
        bounds1 = scale1;
        s = bar1 + offset;
        align2 = "After" /* After */;
        break;
      case "bar-end":
        bounds0 = -Infinity;
        bounds1 = Infinity;
        s = bar1;
        align2 = "Center" /* Center */;
        break;
    }
    const x = horizontal ? s : gaugeRect.x + gaugeRect.width / 2;
    const y = horizontal ? gaugeRect.y + gaugeRect.height / 2 : s;
    let s0;
    let s1;
    if (horizontal) {
      s0 = x + horizontalAlignFactors[align2] * layout.width;
      s1 = s0 + layout.width;
    } else {
      s0 = y + verticalAlignFactors3[align2] * layout.height;
      s1 = s0 + layout.height;
    }
    const inside = Math.min(s0, s1) >= Math.min(bounds0, bounds1) && Math.max(s0, s1) <= Math.max(bounds0, bounds1);
    if (labelDatum.avoidCollisions && !inside) {
      label.visible = false;
      return;
    }
    label.visible = true;
    label.text = layout.text;
    label.fontSize = layout.fontSize;
    label.lineHeight = layout.lineHeight;
    label.textAlign = horizontal ? horizontalTextAligns[align2] : "center";
    label.textBaseline = horizontal ? "middle" : verticalTextBaselines[align2];
    label.x = x;
    label.y = y;
  });
}

// packages/ag-charts-enterprise/src/series/linear-gauge/linearGaugeSeries.ts
var {
  fromToMotion: fromToMotion5,
  resetMotion: resetMotion4,
  SeriesNodePickMode: SeriesNodePickMode11,
  createDatumId: createDatumId15,
  BBox: BBox25,
  Group: Group14,
  PointerEvents: PointerEvents8,
  Selection: Selection9,
  Rect: Rect11,
  Text: Text6,
  TransformableText: TransformableText4,
  Marker: Marker4,
  LinearScale: LinearScale3,
  generateTicks: generateTicks2,
  NiceMode: NiceMode2
} = module_support_exports;
var horizontalTargetPlacementRotation = {
  before: 180,
  middle: 0,
  after: 0
};
var verticalTargetPlacementRotation = {
  before: 90,
  middle: 0,
  after: -90
};
var LinearGaugeSeries = class extends module_support_exports.Series {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      pickModes: [SeriesNodePickMode11.EXACT_SHAPE_MATCH, SeriesNodePickMode11.NEAREST_NODE]
    });
    this.properties = new LinearGaugeSeriesProperties();
    this.seriesRect = BBox25.NaN;
    this.gaugeRect = BBox25.NaN;
    this.scale = new LinearScale3();
    this.originX = 0;
    this.originY = 0;
    this.scaleGroup = this.contentGroup.appendChild(new Group14({ name: "scaleGroup" }));
    this.itemGroup = this.contentGroup.appendChild(new Group14({ name: "itemGroup" }));
    this.itemTargetGroup = this.contentGroup.appendChild(new Group14({ name: "itemTargetGroup" }));
    this.itemTargetLabelGroup = this.contentGroup.appendChild(new Group14({ name: "itemTargetLabelGroup" }));
    this.itemLabelGroup = this.contentGroup.appendChild(new Group14({ name: "itemLabelGroup" }));
    this.highlightTargetGroup = this.highlightGroup.appendChild(
      new Group14({ name: "itemTargetLabelGroup" })
    );
    this.tickGroup = this.contentGroup.appendChild(new Group14({ name: "tickGroup" }));
    this.scaleSelection = Selection9.select(
      this.scaleGroup,
      () => this.nodeFactory()
    );
    this.datumSelection = Selection9.select(
      this.itemGroup,
      () => this.nodeFactory()
    );
    this.targetSelection = Selection9.select(
      this.itemTargetGroup,
      () => this.markerFactory()
    );
    this.targetLabelSelection = Selection9.select(this.itemTargetLabelGroup, Text6);
    this.labelSelection = Selection9.select(
      this.itemLabelGroup,
      Text6
    );
    this.highlightTargetSelection = Selection9.select(this.highlightTargetGroup, () => this.markerFactory());
    this.tickSelection = Selection9.select(this.tickGroup, TransformableText4);
    this.datumUnion = new DatumUnion();
    this.animationState = new StateMachine("empty", {
      empty: {
        update: {
          target: "ready",
          action: () => this.animateEmptyUpdateReady()
        },
        reset: "empty",
        skip: "ready"
      },
      ready: {
        updateData: "waiting",
        clear: "clearing",
        resize: () => this.animateReadyResize(),
        reset: "empty",
        skip: "ready"
      },
      waiting: {
        update: {
          target: "ready",
          action: () => this.animateWaitingUpdateReady()
        },
        reset: "empty",
        skip: "ready"
      },
      clearing: {
        update: {
          target: "empty"
        },
        reset: "empty",
        skip: "ready"
      }
    });
    this.scaleGroup.pointerEvents = PointerEvents8.None;
    this.tickGroup.pointerEvents = PointerEvents8.None;
  }
  get range() {
    return this.horizontal ? [0, this.gaugeRect.width] : [0, this.gaugeRect.height];
  }
  get horizontal() {
    return this.properties.direction === "horizontal";
  }
  get hasData() {
    return true;
  }
  nodeFactory() {
    const rect2 = new Rect11();
    rect2.crisp = true;
    return rect2;
  }
  markerFactory() {
    return new Marker4();
  }
  processData() {
    this.nodeDataRefresh = true;
    this.animationState.transition("updateData");
  }
  formatLabel(value) {
    return formatLabel(value, this.properties.scale);
  }
  getShapeFillBBox() {
    const { properties, originX, originY, horizontal, scale: scale2 } = this;
    const { thickness } = properties;
    const length2 = findRangeExtent(scale2.range);
    const bbox = new BBox25(originX, originY, horizontal ? length2 : thickness, horizontal ? thickness : length2);
    return {
      axis: bbox,
      series: bbox
    };
  }
  getTargets() {
    const { properties } = this;
    const defaultTarget = properties.defaultTarget;
    return Array.from(properties.targets).map((target) => {
      const {
        text: text2 = defaultTarget.text,
        value = defaultTarget.value ?? 0,
        shape = defaultTarget.shape ?? "triangle",
        rotation = defaultTarget.rotation ?? 0,
        placement = defaultTarget.placement ?? "middle",
        spacing = defaultTarget.spacing ?? 0,
        size = defaultTarget.size ?? 0
      } = target;
      const {
        enabled: labelEnabled = defaultTarget.label.enabled,
        color: labelColor = defaultTarget.label.color ?? "black",
        fontStyle: labelFontStyle = defaultTarget.label.fontStyle ?? "normal",
        fontWeight: labelFontWeight = defaultTarget.label.fontWeight ?? "normal",
        fontSize: labelFontSize = defaultTarget.label.fontSize,
        fontFamily: labelFontFamily = defaultTarget.label.fontFamily,
        spacing: labelSpacing = defaultTarget.label.spacing ?? 0
      } = target.label;
      return {
        text: text2,
        value,
        shape,
        placement,
        spacing,
        size,
        rotation,
        label: {
          enabled: labelEnabled,
          color: labelColor,
          fontStyle: labelFontStyle,
          fontWeight: labelFontWeight,
          fontSize: labelFontSize,
          fontFamily: labelFontFamily,
          spacing: labelSpacing
        },
        style: target.getStyle(defaultTarget)
      };
    });
  }
  getTargetPoint(target) {
    const { properties, originX, originY, horizontal, scale: scale2, gaugeRect } = this;
    const { thickness } = properties;
    const { value, placement, spacing, size } = target;
    const mainOffset = scale2.convert(value);
    let crossOffset;
    switch (placement) {
      case "before":
        crossOffset = -(spacing + size / 2);
        break;
      case "after":
        crossOffset = thickness + spacing + size / 2;
        break;
      default:
        crossOffset = thickness / 2;
        break;
    }
    return {
      x: originX + gaugeRect.x + (horizontal ? mainOffset : crossOffset),
      y: originY + gaugeRect.y + (horizontal ? crossOffset : mainOffset)
    };
  }
  getTargetLabel(target) {
    const { size, placement, label } = target;
    const { spacing, color: fill, fontStyle, fontWeight: fontWeight2, fontSize, fontFamily } = label;
    const lineHeight = void 0;
    const offset = size / 2 + spacing;
    let textAlign;
    let textBaseline;
    let offsetX = 0;
    let offsetY = 0;
    if (this.horizontal) {
      textAlign = "center";
      if (placement === "after") {
        textBaseline = "top";
        offsetY = offset;
      } else {
        textBaseline = "bottom";
        offsetY = -offset;
      }
    } else {
      textBaseline = "middle";
      if (placement === "before") {
        textAlign = "right";
        offsetX = -offset;
      } else {
        textAlign = "left";
        offsetX = offset;
      }
    }
    return {
      offsetX,
      offsetY,
      fill,
      textAlign,
      textBaseline,
      fontStyle,
      fontWeight: fontWeight2,
      fontSize,
      fontFamily,
      lineHeight
    };
  }
  labelDatum(label, value) {
    const {
      placement,
      avoidCollisions,
      spacing,
      text: text2,
      color: fill,
      fontSize,
      minimumFontSize,
      fontStyle,
      fontWeight: fontWeight2,
      fontFamily,
      lineHeight,
      wrapping,
      overflowStrategy,
      formatter: formatter2 = (params) => this.formatLabel(params.value)
    } = label;
    return {
      placement,
      avoidCollisions,
      spacing,
      text: text2,
      value,
      fill,
      fontSize,
      minimumFontSize,
      fontStyle,
      fontWeight: fontWeight2,
      fontFamily,
      lineHeight,
      wrapping,
      overflowStrategy,
      formatter: formatter2
    };
  }
  verticalLabelInset() {
    const { label } = this.properties;
    const measurer3 = cachedTextMeasurer(label);
    const lines = label.text?.split("\n");
    const labelSize = (label.lineHeight ?? measurer3.lineHeight()) * (lines?.length ?? 1);
    return label.spacing + labelSize;
  }
  horizontalLabelInset() {
    const { scale: scale2, properties } = this;
    const { scale: scaleProps, label } = properties;
    const lines = label.text?.split("\n");
    const measurer3 = cachedTextMeasurer(label);
    const ticks = scaleProps.interval.values ?? scale2.ticks({
      nice: [false, false],
      interval: scaleProps.interval.step,
      minTickCount: 0,
      maxTickCount: 6,
      tickCount: 5
    })?.ticks ?? [];
    const linesOrTicks = lines ?? ticks?.map((tick) => getLabelText(this.id, this.ctx, this.labelDatum(label, tick)) ?? "");
    const labelSize = linesOrTicks.reduce((accum, text2) => {
      const { width: width2 } = isArray(text2) ? measureTextSegments(text2, label) : measurer3.measureLines(toTextString(text2));
      return Math.max(accum, width2);
    }, 0);
    return label.spacing + labelSize;
  }
  tickFormatter(domain, ticks) {
    const { format, formatter: formatter2 } = this.properties.scale.label;
    let tickFormatter;
    if (format != null) {
      tickFormatter = tickFormat(ticks, typeof format === "string" ? format : void 0);
    }
    return (value, index) => {
      let r = void 0;
      if (formatter2) {
        r ?? (r = formatWithContext(this.ctx, formatter2, { value, index, domain, boundSeries: void 0 }));
      }
      r ?? (r = tickFormatter?.(value));
      return r ?? this.formatLabel(value);
    };
  }
  createNodeData() {
    const { id: seriesId, properties, horizontal, scale: scale2, seriesRect } = this;
    const {
      value,
      segmentation,
      thickness,
      cornerRadius,
      cornerMode,
      bar,
      scale: scaleProps,
      label,
      defaultColorRange,
      defaultScale
    } = properties;
    scale2.domain = [scaleProps.min, scaleProps.max];
    scale2.range = horizontal ? [0, seriesRect.width] : [seriesRect.height, 0];
    let axisRotation;
    let sideFlag;
    if (horizontal) {
      sideFlag = 1;
      axisRotation = Math.PI / -2;
    } else if (scaleProps.label.placement === "before") {
      sideFlag = 1;
      axisRotation = 0;
    } else {
      sideFlag = -1;
      axisRotation = 0;
    }
    let x0;
    let x1;
    let y0;
    let y1;
    if (horizontal) {
      x0 = 0;
      x1 = seriesRect.width;
      y0 = (seriesRect.height - thickness) / 2;
      y1 = y0 + thickness;
      if (label.placement === "outside-start") {
        x0 += this.horizontalLabelInset();
      } else if (label.placement === "outside-end") {
        x1 -= this.horizontalLabelInset();
      }
    } else {
      x0 = (seriesRect.width - thickness) / 2;
      x1 = x0 + thickness;
      y1 = 0;
      y0 = seriesRect.height;
      if (label.placement === "outside-start") {
        y0 -= this.verticalLabelInset();
      } else if (label.placement === "outside-end") {
        y1 += this.verticalLabelInset();
      }
    }
    this.gaugeRect = new BBox25(Math.min(x0, x1), Math.min(y0, y1), Math.abs(x1 - x0), Math.abs(y1 - y0));
    const originX = 0;
    const originY = 0;
    scale2.domain = [scaleProps.min, scaleProps.max];
    scale2.range = horizontal ? [x0, x1] : [y0, y1];
    const scaleLabel = mergeDefaults({ parallel: horizontal }, scaleProps.label, defaultScale.label);
    const {
      tickData: { ticks: tickData }
    } = generateTicks2({
      scale: scale2,
      label: scaleLabel,
      interval: scaleProps.interval,
      tickFormatter: (domain, ticks) => this.tickFormatter(domain, ticks),
      domain: scale2.domain,
      range: this.range,
      reverse: false,
      primaryTickCount: void 0,
      defaultTickMinSpacing: 0,
      visibleRange: [0, 1],
      niceMode: [NiceMode2.Off, NiceMode2.Off],
      labelOffset: 0,
      axisRotation,
      sideFlag
    });
    const isReversed = false;
    const targets = this.getTargets();
    const nodeData = [];
    const targetData = [];
    const labelData = [];
    const scaleData = [];
    const [m0, m1] = scale2.range;
    const mainAxisSize = Math.abs(m1 - m0);
    const containerX = horizontal ? scale2.convert(value) : x1;
    const containerY = horizontal ? y1 : scale2.convert(value);
    const inset = segmentation.enabled ? segmentation.spacing / 2 : 0;
    const horizontalInset = horizontal ? inset : 0;
    const verticalInset = horizontal ? 0 : inset;
    const barThickness = Math.min(bar.thickness ?? Math.round(bar.thicknessRatio * thickness), thickness);
    const barInset = -(thickness - barThickness) / 2;
    const barXInset = horizontal ? 0 : barInset;
    const barYInset = horizontal ? barInset : 0;
    const cornersOnAllItems = cornerMode === "item";
    const maxTicks = Math.ceil(mainAxisSize);
    let segments = segmentation.enabled ? segmentation.interval.getSegments(scale2, maxTicks) : void 0;
    const barStyle = bar.getStyle(defaultColorRange, horizontal, scale2);
    const scaleStyle = scaleProps.getStyle(bar.enabled, defaultColorRange, horizontal, scale2);
    if (segments == null && cornersOnAllItems) {
      const segmentStart = Math.min(...scale2.domain);
      const segmentEnd = Math.max(...scale2.domain);
      const datum = { value, segmentStart, segmentEnd };
      if (bar.enabled) {
        const barAppliedCornerRadius = Math.min(cornerRadius, barThickness / 2, mainAxisSize / 2);
        const barCornerInset = barAppliedCornerRadius * (isReversed ? -1 : 1);
        const barCornerXInset = horizontal ? barCornerInset : 0;
        const barCornerYInset = horizontal ? 0 : barCornerInset;
        nodeData.push({
          series: this,
          itemId: `value`,
          datum,
          datumIndex: { type: 0 /* Node */ },
          type: 0 /* Node */,
          x0: originX + x0 - barCornerXInset - barXInset,
          y0: originY + y0 - barCornerYInset - barYInset,
          x1: originX + containerX + barCornerXInset + barXInset,
          y1: originY + containerY + barCornerYInset + barYInset,
          clipX0: void 0,
          clipY0: void 0,
          clipX1: void 0,
          clipY1: void 0,
          topLeftCornerRadius: cornerRadius,
          topRightCornerRadius: cornerRadius,
          bottomRightCornerRadius: cornerRadius,
          bottomLeftCornerRadius: cornerRadius,
          horizontalInset,
          verticalInset,
          style: barStyle
        });
      }
      const scaleAppliedCornerRadius = Math.min(cornerRadius, thickness / 2, mainAxisSize / 2);
      const scaleCornerInset = scaleAppliedCornerRadius * (isReversed ? -1 : 1);
      const scaleCornerXInset = horizontal ? scaleCornerInset : 0;
      const scaleCornerYInset = horizontal ? 0 : scaleCornerInset;
      scaleData.push({
        series: this,
        itemId: `scale`,
        datum,
        datumIndex: { type: 0 /* Node */ },
        type: 0 /* Node */,
        x0: originX + x0 - scaleCornerXInset,
        y0: originY + y0 - scaleCornerYInset,
        x1: originX + x1 + scaleCornerXInset,
        y1: originY + y1 + scaleCornerYInset,
        clipX0: void 0,
        clipY0: void 0,
        clipX1: void 0,
        clipY1: void 0,
        topLeftCornerRadius: cornerRadius,
        topRightCornerRadius: cornerRadius,
        bottomRightCornerRadius: cornerRadius,
        bottomLeftCornerRadius: cornerRadius,
        horizontalInset,
        verticalInset,
        style: scaleStyle
      });
    } else {
      segments ?? (segments = scale2.domain);
      const clipX0 = originX + x0 - barXInset;
      const clipY0 = originY + y0 - barYInset;
      const clipX1 = originX + containerX + barXInset;
      const clipY1 = originY + containerY + barYInset;
      for (let i = 0; i < segments.length - 1; i += 1) {
        const segmentStart = segments[i + 0];
        const segmentEnd = segments[i + 1];
        const datum = { value, segmentStart, segmentEnd };
        const isStart = i === 0;
        const isEnd = i === segments.length - 2;
        const itemStart = scale2.convert(segmentStart);
        const itemEnd = scale2.convert(segmentEnd);
        const startCornerRadius = cornersOnAllItems || isStart ? cornerRadius : 0;
        const endCornerRadius = cornersOnAllItems || isEnd ? cornerRadius : 0;
        const topLeftCornerRadius = horizontal ? startCornerRadius : endCornerRadius;
        const topRightCornerRadius = endCornerRadius;
        const bottomRightCornerRadius = horizontal ? endCornerRadius : startCornerRadius;
        const bottomLeftCornerRadius = startCornerRadius;
        if (bar.enabled) {
          nodeData.push({
            series: this,
            itemId: `value-${i}`,
            datum,
            datumIndex: { type: 0 /* Node */ },
            type: 0 /* Node */,
            x0: originX + (horizontal ? itemStart : x0),
            y0: originY + (horizontal ? y0 : itemStart),
            x1: originX + (horizontal ? itemEnd : x1),
            y1: originY + (horizontal ? y1 : itemEnd),
            clipX0,
            clipY0,
            clipX1,
            clipY1,
            topLeftCornerRadius,
            topRightCornerRadius,
            bottomRightCornerRadius,
            bottomLeftCornerRadius,
            horizontalInset,
            verticalInset,
            style: barStyle
          });
        }
        scaleData.push({
          series: this,
          itemId: `scale-${i}`,
          datum,
          datumIndex: { type: 0 /* Node */ },
          type: 0 /* Node */,
          x0: originX + (horizontal ? itemStart : x0),
          y0: originY + (horizontal ? y0 : itemStart),
          x1: originX + (horizontal ? itemEnd : x1),
          y1: originY + (horizontal ? y1 : itemEnd),
          clipX0: void 0,
          clipY0: void 0,
          clipX1: void 0,
          clipY1: void 0,
          topLeftCornerRadius,
          topRightCornerRadius,
          bottomRightCornerRadius,
          bottomLeftCornerRadius,
          horizontalInset,
          verticalInset,
          style: scaleStyle
        });
      }
    }
    for (const dataArray of [scaleData, nodeData]) {
      for (const datum of dataArray) {
        const dx0 = datum.clipX0 ?? datum.x0;
        const dx1 = datum.clipX1 ?? datum.x1;
        const dy0 = datum.clipY0 ?? datum.y0;
        const dy1 = datum.clipY1 ?? datum.y1;
        datum.midPoint = { x: (dx0 + dx1) / 2, y: (dy0 + dy1) / 2 };
      }
    }
    if (label.enabled) {
      labelData.push(this.labelDatum(label, value));
    }
    const targetPlacementRotation2 = horizontal ? horizontalTargetPlacementRotation : verticalTargetPlacementRotation;
    for (let i = 0; i < targets.length; i += 1) {
      const target = targets[i];
      const { value: targetValue, text: text2, shape, size, style: style2 } = target;
      const targetPoint = this.getTargetPoint(target);
      const targetRotation = toRadians(target.rotation + targetPlacementRotation2[target.placement]);
      targetData.push({
        series: this,
        itemId: `target-${i}`,
        midPoint: targetPoint,
        datum: { value: targetValue },
        datumIndex: { type: 1 /* Target */, index: i },
        type: 1 /* Target */,
        value: targetValue,
        text: text2,
        x: targetPoint.x,
        y: targetPoint.y,
        shape,
        size,
        rotation: targetRotation,
        label: this.getTargetLabel(target),
        style: style2
      });
    }
    return {
      itemId: seriesId,
      nodeData,
      tickData,
      targetData,
      labelData,
      scaleData
    };
  }
  findNodeDatum(itemId) {
    return findGaugeNodeDatum(this, itemId);
  }
  updateSelections(resize) {
    if (this.nodeDataRefresh || resize) {
      this.contextNodeData = this.createNodeData();
      this.nodeDataRefresh = false;
    }
  }
  highlightDatum(node) {
    if (node?.series === this && node.type === 1 /* Target */) {
      return node;
    }
  }
  update({ seriesRect }) {
    const {
      datumSelection,
      labelSelection,
      targetSelection,
      targetLabelSelection,
      scaleSelection,
      highlightTargetSelection,
      tickSelection
    } = this;
    this.seriesRect = seriesRect ?? BBox25.NaN;
    const resize = this.checkResize(seriesRect);
    this.updateSelections(resize);
    this.contentGroup.visible = this.visible;
    this.contentGroup.opacity = this.getOpacity();
    const nodeData = this.contextNodeData?.nodeData ?? [];
    const labelData = this.contextNodeData?.labelData ?? [];
    const targetData = this.contextNodeData?.targetData ?? [];
    const scaleData = this.contextNodeData?.scaleData ?? [];
    const tickData = this.contextNodeData?.tickData ?? [];
    const highlightTargetDatum = this.highlightDatum(this.ctx.highlightManager.getActiveHighlight());
    this.scaleSelection = this.updateScaleSelection({ scaleData, scaleSelection });
    this.updateScaleNodes({ scaleSelection });
    this.targetSelection = this.updateTargetSelection({ targetData, targetSelection });
    this.updateTargetNodes({ targetSelection, isHighlight: false });
    this.targetLabelSelection = this.updateTargetLabelSelection({ targetData, targetLabelSelection });
    this.updateTargetLabelNodes({ targetLabelSelection });
    this.datumSelection = this.updateDatumSelection({ nodeData, datumSelection });
    this.updateDatumNodes({ datumSelection });
    this.labelSelection = this.updateLabelSelection({ labelData, labelSelection });
    this.updateLabelNodes({ labelSelection });
    this.highlightTargetSelection = this.updateTargetSelection({
      targetData: highlightTargetDatum == null ? [] : [highlightTargetDatum],
      targetSelection: highlightTargetSelection
    });
    this.updateTargetNodes({ targetSelection: highlightTargetSelection, isHighlight: true });
    this.tickSelection = this.updateTickSelection({ tickData, tickSelection });
    this.updateTickNodes({ tickSelection });
    if (resize) {
      this.animationState.transition("resize");
    }
    this.animationState.transition("update");
  }
  updateDatumSelection(opts) {
    return opts.datumSelection.update(opts.nodeData, void 0, (datum) => {
      return createDatumId15(opts.nodeData.length, datum.itemId);
    });
  }
  updateDatumNodes(opts) {
    const { datumSelection } = opts;
    const { ctx } = this;
    const animationDisabled = ctx.animationManager.isSkipped();
    const fillBBox = this.getShapeFillBBox();
    datumSelection.each((rect2, datum) => {
      const { topLeftCornerRadius, topRightCornerRadius, bottomRightCornerRadius, bottomLeftCornerRadius } = datum;
      rect2.setStyleProperties(datum.style, fillBBox);
      rect2.topLeftCornerRadius = topLeftCornerRadius;
      rect2.topRightCornerRadius = topRightCornerRadius;
      rect2.bottomRightCornerRadius = bottomRightCornerRadius;
      rect2.bottomLeftCornerRadius = bottomLeftCornerRadius;
      rect2.pointerEvents = this.properties.bar.enabled ? module_support_exports.PointerEvents.All : module_support_exports.PointerEvents.None;
      if (animationDisabled || rect2.previousDatum == null) {
        rect2.setProperties(resetLinearGaugeSeriesResetRectFunction(rect2, datum));
      }
    });
    const { horizontal } = this;
    this.datumUnion.update(datumSelection, this.itemGroup, module_support_exports.Rect, (node, first2, last) => {
      const left = Math.min(first2.x, last.x);
      const right = Math.max(first2.x + first2.width, last.x + last.width);
      const top = Math.min(first2.y, last.y);
      const bottom = Math.max(first2.y + first2.height, last.y + last.height);
      const width2 = right - left;
      const height2 = bottom - top;
      node.pointerEvents = module_support_exports.PointerEvents.None;
      node.x = left;
      node.y = top;
      node.width = width2;
      node.height = height2;
      node.topLeftCornerRadius = horizontal ? first2.topLeftCornerRadius : last.topLeftCornerRadius;
      node.topRightCornerRadius = last.topRightCornerRadius;
      node.bottomRightCornerRadius = horizontal ? last.bottomRightCornerRadius : first2.bottomRightCornerRadius;
      node.bottomLeftCornerRadius = first2.bottomLeftCornerRadius;
      const firstClipBBox = first2.clipBBox;
      const lastClipBBox = last.clipBBox ?? firstClipBBox;
      if (firstClipBBox && lastClipBBox) {
        node.clipBBox = BBox25.merge([firstClipBBox, lastClipBBox]).intersection(
          horizontal ? new BBox25(left, -Infinity, width2, Infinity) : new BBox25(-Infinity, top, Infinity, height2)
        );
      } else {
        node.clipBBox = void 0;
      }
    });
  }
  updateScaleSelection(opts) {
    return opts.scaleSelection.update(opts.scaleData, void 0, (datum) => {
      return createDatumId15(opts.scaleData.length, datum.itemId);
    });
  }
  updateScaleNodes(opts) {
    const { scaleSelection } = opts;
    const fillBBox = this.getShapeFillBBox();
    scaleSelection.each((rect2, datum) => {
      const { topLeftCornerRadius, topRightCornerRadius, bottomRightCornerRadius, bottomLeftCornerRadius } = datum;
      rect2.setStyleProperties(datum.style, fillBBox);
      rect2.setProperties(resetLinearGaugeSeriesResetRectFunction(rect2, datum));
      rect2.topLeftCornerRadius = topLeftCornerRadius;
      rect2.topRightCornerRadius = topRightCornerRadius;
      rect2.bottomRightCornerRadius = bottomRightCornerRadius;
      rect2.bottomLeftCornerRadius = bottomLeftCornerRadius;
      rect2.setProperties(resetLinearGaugeSeriesResetRectFunction(rect2, datum));
    });
  }
  updateTargetSelection(opts) {
    return opts.targetSelection.update(opts.targetData, void 0, (target) => target.itemId);
  }
  updateTargetNodes(opts) {
    const { targetSelection, isHighlight } = opts;
    targetSelection.each((target, datum) => {
      const { x, y, shape, size, rotation } = datum;
      const style2 = this.getTargetStyle(isHighlight, datum);
      target.setStyleProperties(style2);
      target.size = size;
      target.shape = shape === "line" ? lineMarker : shape;
      target.translationX = x;
      target.translationY = y;
      target.rotation = rotation;
    });
  }
  getTargetStyle(isHighlight, { datumIndex, style: style2 }) {
    const highlightStyle = this.getHighlightStyle(isHighlight, datumIndex);
    return mergeDefaults(highlightStyle, {
      ...style2,
      opacity: 1
    });
  }
  updateTargetLabelSelection(opts) {
    return opts.targetLabelSelection.update(opts.targetData);
  }
  updateTargetLabelNodes(opts) {
    const { targetLabelSelection } = opts;
    targetLabelSelection.each((label, target) => {
      const { x, y, text: text2 } = target;
      const { offsetX, offsetY, fill, fontStyle, fontWeight: fontWeight2, fontSize, fontFamily, textAlign, textBaseline } = target.label;
      label.visible = true;
      label.x = x + offsetX;
      label.y = y + offsetY;
      label.text = text2;
      label.fill = fill;
      label.fontStyle = fontStyle;
      label.fontWeight = fontWeight2;
      label.fontSize = fontSize;
      label.fontFamily = fontFamily;
      label.textAlign = textAlign;
      label.textBaseline = textBaseline;
    });
  }
  updateTickSelection(opts) {
    return opts.tickSelection.update(opts.tickData, void 0, (datum) => datum.tickId);
  }
  updateTickNodes(opts) {
    const { gaugeRect, properties } = this;
    const defaultScale = properties.defaultScale;
    const {
      enabled,
      color: color2,
      fontFamily = defaultScale.label.fontFamily,
      fontSize = defaultScale.label.fontSize,
      fontStyle,
      fontWeight: fontWeight2 = defaultScale.label.fontWeight,
      spacing
    } = properties.scale.label;
    let { placement } = properties.scale.label;
    const rotation = toRadians(properties.scale.label.rotation ?? 0);
    let textAlign;
    let textBaseline;
    let textX;
    let textY;
    if (this.horizontal) {
      placement ?? (placement = "after");
      textAlign = "center";
      textBaseline = placement === "before" ? "bottom" : "top";
      textY = this.originY + gaugeRect.y + (placement === "before" ? -spacing : gaugeRect.height + spacing);
    } else {
      placement ?? (placement = "before");
      textAlign = placement === "before" ? "end" : "start";
      textBaseline = "middle";
      textX = this.originX + gaugeRect.x + (placement === "before" ? -spacing : gaugeRect.width + spacing);
    }
    opts.tickSelection.each((label, datum) => {
      if (!enabled) {
        label.visible = false;
        return;
      }
      const x = textX ?? datum.translation;
      const y = textY ?? datum.translation;
      label.visible = true;
      label.text = datum.tickLabel;
      label.fill = color2;
      label.fontFamily = fontFamily;
      label.fontSize = fontSize;
      label.fontStyle = fontStyle;
      label.fontWeight = fontWeight2;
      label.textBaseline = textBaseline;
      label.textAlign = textAlign;
      label.x = x;
      label.y = y;
      label.rotationCenterX = x;
      label.rotationCenterY = y;
      label.rotation = rotation;
    });
  }
  updateLabelSelection(opts) {
    return opts.labelSelection.update(opts.labelData, void 0, (_datum) => "primary");
  }
  updateLabelNodes(opts) {
    const { labelSelection } = opts;
    const animationDisabled = this.ctx.animationManager.isSkipped();
    labelSelection.each((label, datum) => {
      label.fill = datum.fill;
      label.fontStyle = datum.fontStyle;
      label.fontWeight = datum.fontWeight;
      label.fontFamily = datum.fontFamily;
    });
    if (animationDisabled || this.labelsHaveExplicitText()) {
      this.formatLabelText();
    }
  }
  labelsHaveExplicitText() {
    for (const { datum } of this.labelSelection) {
      if (datum.text == null) {
        return false;
      }
    }
    return true;
  }
  formatLabelText(datum) {
    const { labelSelection, horizontal, scale: scale2, seriesRect, gaugeRect } = this;
    const { x, y, width: width2, height: height2 } = gaugeRect;
    const value = datum?.label ?? this.properties.value;
    let barRect;
    if (horizontal) {
      const xValue = scale2.convert(value);
      barRect = new BBox25(x, y, xValue - x, height2);
    } else {
      const yValue = scale2.convert(value);
      barRect = new BBox25(x, yValue, width2, height2 - yValue);
    }
    const bboxes = { seriesRect, gaugeRect, barRect };
    const { margin: padding2 } = this.properties;
    formatLinearGaugeLabels(this, this.ctx, labelSelection, { padding: padding2, horizontal }, bboxes, datum);
  }
  resetAllAnimation() {
    this.ctx.animationManager.stopByAnimationGroupId(this.id);
    resetMotion4([this.datumSelection], resetLinearGaugeSeriesResetRectFunction);
    this.formatLabelText();
  }
  resetAnimation(phase) {
    if (phase === "initial") {
      this.animationState.transition("reset");
    } else if (phase === "ready") {
      this.animationState.transition("skip");
    }
  }
  animateLabelText(params = {}) {
    const { animationManager } = this.ctx;
    let labelFrom = 0;
    let labelTo = 0;
    this.labelSelection.each((label, datum) => {
      label.opacity = 1;
      labelFrom = label.previousDatum?.value ?? params.from ?? datum.value;
      labelTo = datum.value;
    });
    if (this.labelsHaveExplicitText()) {
    } else if (labelFrom === labelTo) {
      this.formatLabelText({ label: labelTo });
    } else {
      const animationId = `${this.id}_labels`;
      animationManager.animate({
        id: animationId,
        groupId: "label",
        from: { label: labelFrom },
        to: { label: labelTo },
        phase: params.phase ?? "update",
        ease: easeOut,
        onUpdate: (datum) => this.formatLabelText(datum),
        onStop: () => this.formatLabelText({ label: labelTo })
      });
    }
  }
  animateEmptyUpdateReady() {
    const { animationManager } = this.ctx;
    const { node } = prepareLinearGaugeSeriesAnimationFunctions(true, this.horizontal);
    fromToMotion5(this.id, "node", animationManager, [this.datumSelection], node, (_sector, datum) => datum.itemId);
    fromToMotion5(this.id, "label", animationManager, [this.labelSelection], fadeInFns, () => "primary");
    this.animateLabelText({ from: 0, phase: "initial" });
  }
  animateWaitingUpdateReady() {
    const { animationManager } = this.ctx;
    const { node } = prepareLinearGaugeSeriesAnimationFunctions(false, this.horizontal);
    fromToMotion5(this.id, "node", animationManager, [this.datumSelection], node, (_sector, datum) => datum.itemId);
    this.animateLabelText();
  }
  animateReadyResize() {
    this.resetAllAnimation();
  }
  getSeriesDomain() {
    return { domain: [0, 1] };
  }
  dataCount() {
    return Number.NaN;
  }
  getSeriesRange() {
    return [Number.NaN, Number.NaN];
  }
  getLegendData() {
    return [];
  }
  getTooltipContent(datumIndex) {
    const { id: seriesId, properties } = this;
    const { tooltip } = properties;
    if (datumIndex == null)
      return;
    let value;
    let text2;
    let fallbackLabel;
    if (datumIndex.type === 0 /* Node */) {
      value = properties.value;
      text2 = properties.label.text;
      fallbackLabel = this.ctx.localeManager.t("ariaLabelGaugeValue");
    } else {
      ({ value, text: text2 } = properties.targets[datumIndex.index]);
      fallbackLabel = this.ctx.localeManager.t("ariaLabelGaugeTarget");
    }
    if (value == null)
      return;
    return this.formatTooltipWithContext(
      tooltip,
      {
        data: [{ label: text2, fallbackLabel, value: this.formatLabel(value) }]
      },
      { seriesId, title: void 0, datum: void 0, value }
    );
  }
  pickNodeClosestDatum(point) {
    return pickGaugeNearestDatum(this, point);
  }
  pickFocus(opts) {
    return pickGaugeFocus(this, opts);
  }
  getCaptionText() {
    return this.formatLabel(this.properties.value);
  }
  getCategoryValue(_datumIndex) {
    return;
  }
  datumIndexForCategoryValue(_categoryValue) {
    return;
  }
  hasItemStylers() {
    return this.properties.label.itemStyler != null;
  }
};
LinearGaugeSeries.className = "LinearGaugeSeries";
LinearGaugeSeries.type = "linear-gauge";

// packages/ag-charts-enterprise/src/series/linear-gauge/linearGaugeModule.ts
var themeTemplate9 = {
  minWidth: 200,
  minHeight: 200,
  tooltip: {
    enabled: false
  },
  series: {
    thickness: 50,
    defaultColorRange: {
      $if: [
        { $eq: [{ $palette: "type" }, "inbuilt"] },
        { $interpolate: [{ $palette: "secondDivergingColors" }, 5] },
        SAFE_RANGE2_OPERATION
      ]
    },
    scale: {
      // @ts-expect-error undocumented option
      defaultFill: { $path: ["/1", { $palette: "fill" }, { $palette: "hierarchyColors" }] },
      // TODO: mix backgroundColor and foregroundColor?
      stroke: { $path: ["/2", SAFE_STROKE_FILL_OPERATION, { $palette: "hierarchyColors" }] },
      // TODO: mix backgroundColor and foregroundColor?
      strokeWidth: { $isUserOption: ["./stroke", 2, 0] },
      label: {
        spacing: 11
      }
    },
    bar: {
      strokeWidth: { $isUserOption: ["./stroke", 2, 0] }
    },
    segmentation: {
      enabled: false,
      interval: {},
      spacing: 1
    },
    defaultTarget: {
      fill: { $ref: "foregroundColor" },
      stroke: { $ref: "foregroundColor" },
      size: 10,
      shape: "triangle",
      placement: "after",
      spacing: 5,
      label: {
        enabled: true,
        fontWeight: { $ref: "fontWeight" },
        fontSize: { $ref: "fontSize" },
        fontFamily: { $ref: "fontFamily" },
        color: { $ref: "textColor" },
        spacing: 5
      }
    },
    defaultScale: {
      label: {
        fontWeight: { $ref: "fontWeight" },
        fontSize: { $ref: "fontSize" },
        fontFamily: { $ref: "fontFamily" },
        color: { $ref: "textColor" }
      }
    },
    label: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: false,
      placement: "inside-start",
      fontFamily: { $ref: "fontFamily" },
      fontWeight: { $ref: "fontWeight" },
      fontSize: { $rem: 2 },
      minimumFontSize: 12 /* SMALL */,
      spacing: 18,
      color: { $ref: "chartBackgroundColor" }
    },
    margin: 4,
    tooltip: {
      range: { $path: ["/tooltip/range", 10] }
    }
  }
};
var LinearGaugeModule = {
  type: "series",
  name: "linear-gauge",
  chartType: "standalone",
  enterprise: true,
  dependencies: [GaugePresetModule],
  version: VERSION,
  options: linearGaugeSeriesOptionsDef,
  themeTemplate: themeTemplate9,
  create: (ctx) => new LinearGaugeSeries(ctx)
};

// packages/ag-charts-enterprise/src/axes/angle-number/linearAngleScale.ts
var { LinearScale: LinearScale4 } = module_support_exports;
var LinearAngleScale = class _LinearAngleScale extends LinearScale4 {
  constructor() {
    super(...arguments);
    this.arcLength = 0;
  }
  static getNiceStepAndTickCount(ticks, domain) {
    const [start2, stop] = domain;
    let step = LinearScale4.getTickStep(start2, stop, ticks);
    const maxTickCount = Number.isNaN(ticks.maxTickCount) ? Infinity : ticks.maxTickCount;
    const expectedTickCount = Math.abs(stop - start2) / step;
    let niceTickCount = Math.pow(2, Math.ceil(Math.log(expectedTickCount) / Math.log(2)));
    if (niceTickCount > maxTickCount) {
      niceTickCount /= 2;
      step *= 2;
    }
    return { count: niceTickCount, step };
  }
  ticks(ticks, domain = this.domain) {
    const { arcLength } = this;
    if (!domain || domain.length < 2 || domain.some((d) => !Number.isFinite(d)) || arcLength <= 0) {
      return { ticks: [], count: 0 };
    }
    const { nice, interval } = ticks;
    const [d0, d1] = domain;
    if (interval) {
      const step2 = Math.abs(interval);
      const availableRange = this.getPixelRange();
      if (!isDenseInterval((d1 - d0) / step2, availableRange)) {
        const result2 = range(d0, d1, step2);
        return { ticks: result2.ticks, count: result2.count };
      }
    }
    let step;
    if (nice && this.hasNiceRange()) {
      const linearNiceDomain = super.niceDomain(ticks, domain);
      step = _LinearAngleScale.getNiceStepAndTickCount(ticks, linearNiceDomain).step;
    } else {
      step = LinearScale4.getTickStep(d0, d1, ticks);
    }
    const result = range(d0, d1, step);
    return { ticks: result.ticks, count: result.count };
  }
  hasNiceRange() {
    const sortedRange = this.range.slice().sort((a, b) => a - b);
    const niceRanges = [Math.PI, 2 * Math.PI];
    return niceRanges.some((r) => isNumberEqual(r, sortedRange[1] - sortedRange[0]));
  }
  niceDomain(ticks, domain = this.domain) {
    const linearNiceDomain = super.niceDomain(ticks, domain);
    if (!this.hasNiceRange())
      return linearNiceDomain;
    const reversed = linearNiceDomain[0] > linearNiceDomain[1];
    const start2 = reversed ? linearNiceDomain[1] : linearNiceDomain[0];
    const { step, count } = _LinearAngleScale.getNiceStepAndTickCount(ticks, linearNiceDomain);
    const s = 1 / step;
    const stop = step >= 1 ? Math.ceil(start2 / step + count) * step : Math.ceil((start2 + count * step) * s) / s;
    return reversed ? [stop, start2] : [start2, stop];
  }
  getPixelRange() {
    return this.arcLength;
  }
};

// packages/ag-charts-enterprise/src/series/radial-gauge/radialGaugeNeedle.ts
var { SvgPath: SvgPath2, Rotatable: Rotatable2, Translatable: Translatable2, Scalable: Scalable3 } = module_support_exports;
var RadialGaugeNeedle = class extends Rotatable2(Scalable3(Translatable2(SvgPath2))) {
  constructor() {
    super(...arguments);
    this.scalingCenterX = 0.5;
    this.scalingCenterY = 0.5;
    this.rotationCenterX = 0.5;
    this.rotationCenterY = 0.5;
  }
};
RadialGaugeNeedle.defaultPathData = "M0.50245 0.53745C0.481767 0.53745 0.465 0.520683 0.465 0.5C0.465 0.479317 0.481767 0.46255 0.50245 0.46255L1 0.500012L0.50245 0.53745Z";

// packages/ag-charts-enterprise/src/series/radial-gauge/radialGaugeSeriesProperties.ts
var { getColorStops: getColorStops3 } = module_support_exports;
var { makeSeriesTooltip: makeSeriesTooltip17, SeriesProperties: SeriesProperties6, AxisLabel: AxisLabel7, Label: Label15 } = module_support_exports;
var RadialGaugeDefaultTargetLabelProperties = class extends Label15 {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeDefaultTargetLabelProperties.prototype, "spacing", 2);
var RadialGaugeTargetProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.label = new RadialGaugeDefaultTargetLabelProperties();
  }
  getStyle() {
    const {
      fill = "black",
      fillOpacity = 1,
      stroke: stroke3 = "black",
      strokeWidth = 0,
      strokeOpacity = 1,
      lineDash = [0],
      lineDashOffset = 0
    } = this;
    return {
      fill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeTargetProperties.prototype, "text", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeTargetProperties.prototype, "value", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeTargetProperties.prototype, "shape", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeTargetProperties.prototype, "placement", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeTargetProperties.prototype, "spacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeTargetProperties.prototype, "size", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeTargetProperties.prototype, "rotation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeTargetProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeTargetProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeTargetProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeTargetProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeTargetProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeTargetProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeTargetProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeTargetProperties.prototype, "label", 2);
var RadialGaugeBarProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = true;
    this.fills = new PropertiesArray(module_support_exports.StopProperties);
    this.fillMode = "continuous";
    this.fillOpacity = 1;
    this.stroke = "black";
    this.strokeWidth = 0;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
  }
  getStyle(defaultColorRange, scale2) {
    const {
      enabled,
      fill,
      fills,
      fillMode,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset
    } = this;
    const barFill = enabled ? fill ?? createConicGradient(fills, fillMode, defaultColorRange, scale2) : "none";
    return {
      fill: barFill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeBarProperties.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeBarProperties.prototype, "fills", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeBarProperties.prototype, "fillMode", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeBarProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeBarProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeBarProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeBarProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeBarProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeBarProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeBarProperties.prototype, "lineDashOffset", 2);
var RadialGaugeScaleIntervalProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.values = void 0;
    this.step = void 0;
    this.minSpacing = 0;
    this.maxSpacing = 1e3;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeScaleIntervalProperties.prototype, "values", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeScaleIntervalProperties.prototype, "step", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeScaleIntervalProperties.prototype, "minSpacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeScaleIntervalProperties.prototype, "maxSpacing", 2);
var RadialGaugeScaleLabelProperties = class extends AxisLabel7 {
};
var RadialGaugeScaleProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.min = 0;
    this.max = 1;
    this.fills = new PropertiesArray(module_support_exports.StopProperties);
    this.fillMode = "continuous";
    this.fillOpacity = 1;
    this.stroke = "black";
    this.strokeWidth = 0;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.defaultFill = "black";
    this.interval = new RadialGaugeScaleIntervalProperties();
    this.label = new RadialGaugeScaleLabelProperties();
  }
  getStyle(barEnabled, defaultColorRange, scale2) {
    const {
      fill,
      fills,
      defaultFill,
      fillMode,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset
    } = this;
    const scaleFill = fill ?? (barEnabled && fills.length === 0 ? defaultFill : void 0) ?? createConicGradient(fills, fillMode, defaultColorRange, scale2);
    return {
      fill: scaleFill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeScaleProperties.prototype, "min", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeScaleProperties.prototype, "max", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeScaleProperties.prototype, "fills", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeScaleProperties.prototype, "fillMode", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeScaleProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeScaleProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeScaleProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeScaleProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeScaleProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeScaleProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeScaleProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeScaleProperties.prototype, "defaultFill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeScaleProperties.prototype, "interval", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeScaleProperties.prototype, "label", 2);
var RadialGaugeNeedleProperties = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.enabled = true;
    this.spacing = 0;
    this.fill = "black";
    this.fillOpacity = 1;
    this.stroke = "black";
    this.strokeWidth = 0;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeNeedleProperties.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeNeedleProperties.prototype, "radiusRatio", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeNeedleProperties.prototype, "spacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeNeedleProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeNeedleProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeNeedleProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeNeedleProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeNeedleProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeNeedleProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeNeedleProperties.prototype, "lineDashOffset", 2);
var RadialGaugeLabelProperties = class extends AutoSizedLabel {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeLabelProperties.prototype, "text", 2);
var RadialGaugeSecondaryLabelProperties = class extends AutoSizedSecondaryLabel {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSecondaryLabelProperties.prototype, "text", 2);
var RadialGaugeSeriesProperties = class extends SeriesProperties6 {
  constructor() {
    super(...arguments);
    this.startAngle = 0;
    this.endAngle = 0;
    this.segmentation = new GaugeSegmentationProperties();
    this.defaultColorRange = [];
    this.targets = new PropertiesArray(RadialGaugeTargetProperties);
    this.defaultTarget = new RadialGaugeTargetProperties();
    this.outerRadiusRatio = 1;
    this.innerRadiusRatio = 1;
    this.cornerRadius = 0;
    this.cornerMode = "container";
    this.spacing = 0;
    this.scale = new RadialGaugeScaleProperties();
    this.bar = new RadialGaugeBarProperties();
    this.needle = new RadialGaugeNeedleProperties();
    this.label = new RadialGaugeLabelProperties();
    this.secondaryLabel = new RadialGaugeSecondaryLabelProperties();
    this.tooltip = makeSeriesTooltip17();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "value", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "startAngle", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "endAngle", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "segmentation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "defaultColorRange", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "targets", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "defaultTarget", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "outerRadiusRatio", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "innerRadiusRatio", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "outerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "innerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "cornerMode", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "spacing", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "scale", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "bar", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "needle", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "secondaryLabel", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialGaugeSeriesProperties.prototype, "tooltip", 2);
function createConicGradient(fills, fillMode, defaultColorRange, scale2) {
  const { domain, range: range3 } = scale2;
  const [startAngle, endAngle] = range3;
  const conicAngle = normalizeAngle360((startAngle + endAngle) / 2 + Math.PI);
  const sweepAngle = normalizeAngle360Inclusive(endAngle - startAngle);
  const colorStops = getColorStops3(fills, defaultColorRange, domain, fillMode).map(
    ({ color: color2, stop }) => {
      stop = Math.min(Math.max(stop, 0), 1);
      const angle2 = startAngle + sweepAngle * stop;
      stop = (angle2 - conicAngle) / (2 * Math.PI);
      stop = (stop % 1 + 1) % 1;
      return { stop, color: color2 };
    }
  );
  return {
    type: "gradient",
    gradient: "conic",
    colorSpace: "oklch",
    colorStops,
    bounds: "series",
    rotation: toDegrees(conicAngle) + 90
  };
}

// packages/ag-charts-enterprise/src/series/radial-gauge/radialGaugeUtil.ts
var { SectorBox: SectorBox2 } = module_support_exports;
function computeClipSector(datum) {
  const { startAngle, endAngle, clipStartAngle, clipEndAngle, innerRadius, outerRadius } = datum;
  if (clipStartAngle == null || clipEndAngle == null)
    return;
  return new SectorBox2(
    Math.max(clipStartAngle, startAngle),
    Math.min(clipEndAngle, endAngle),
    innerRadius,
    outerRadius
  );
}
function clipSectorVisibility(startAngle, endAngle, clipSector) {
  return Math.max(startAngle, clipSector.startAngle) <= Math.min(endAngle, clipSector.endAngle);
}
function hasClipSector(datum) {
  return datum.clipStartAngle != null && datum.clipEndAngle != null;
}
function datumClipSector(datum, zero) {
  const { clipStartAngle, clipEndAngle, innerRadius, outerRadius } = datum;
  return new SectorBox2(clipStartAngle, zero ? clipStartAngle : clipEndAngle, innerRadius, outerRadius);
}
function prepareRadialGaugeSeriesAnimationFunctions(initialLoad, initialStartAngle) {
  const phase = initialLoad ? "initial" : "update";
  const node = {
    fromFn(sect, datum) {
      const previousDatum = sect.previousDatum;
      let { startAngle, endAngle } = previousDatum ?? datum;
      const previousClipSector = previousDatum != null && hasClipSector(previousDatum) ? datumClipSector(previousDatum, initialLoad) : void 0;
      const nextClipSector = hasClipSector(datum) ? datumClipSector(datum, initialLoad) : void 0;
      let clipSector;
      if (previousClipSector != null && nextClipSector != null) {
        clipSector = previousClipSector;
      } else if (previousClipSector == null && nextClipSector != null) {
        clipSector = nextClipSector;
        startAngle = datum.startAngle;
        endAngle = datum.endAngle;
      } else if (previousClipSector != null && nextClipSector == null) {
        clipSector = void 0;
        startAngle = datum.startAngle;
        endAngle = datum.endAngle;
      } else if (initialLoad) {
        endAngle = startAngle;
      }
      return { startAngle, endAngle, clipSector, phase };
    },
    toFn(_sect, datum) {
      const { startAngle, endAngle } = datum;
      let clipSector;
      if (hasClipSector(datum)) {
        clipSector = datumClipSector(datum, false);
      }
      return { startAngle, endAngle, clipSector };
    },
    applyFn(sect, params) {
      const { startAngle, endAngle } = params;
      let { clipSector } = params;
      if (clipSector != null) {
        clipSector = new SectorBox2(
          Math.max(startAngle, clipSector.startAngle),
          Math.min(endAngle, clipSector.endAngle),
          clipSector.innerRadius,
          clipSector.outerRadius
        );
      }
      const visible = clipSector == null || clipSectorVisibility(startAngle, endAngle, clipSector);
      sect.startAngle = startAngle;
      sect.endAngle = endAngle;
      sect.clipSector = clipSector;
      sect.visible = visible;
    }
  };
  const needle = {
    fromFn(needleNode) {
      let { angle: rotation } = needleNode.previousDatum ?? needleNode.datum;
      if (initialLoad) {
        rotation = initialStartAngle;
      }
      return { rotation, phase };
    },
    toFn(_needleNode, datum) {
      const { angle: rotation } = datum;
      return { rotation };
    }
  };
  return { node, needle };
}
function resetRadialGaugeSeriesResetSectorFunction(_node, datum) {
  const { startAngle, endAngle } = datum;
  const clipSector = computeClipSector(datum);
  const visible = clipSector == null || clipSectorVisibility(startAngle, endAngle, clipSector);
  return { startAngle, endAngle, clipSector, visible };
}
function resetRadialGaugeSeriesResetNeedleFunction(_node, datum) {
  const { angle: angle2 } = datum;
  return { rotation: angle2 };
}
var verticalAlignFactors4 = {
  top: 0,
  middle: 0.5,
  bottom: 1
};
function formatRadialGaugeLabels(series, ctx, selection, opts, innerRadius, datumOverrides) {
  const { padding: padding2, textAlign, verticalAlign } = opts;
  let labelDatum;
  let secondaryLabelDatum;
  selection.each((_node, datum) => {
    if (datum.label === "primary" /* Primary */) {
      labelDatum = datum;
    } else if (datum.label === "secondary" /* Secondary */) {
      secondaryLabelDatum = datum;
    }
  });
  if (labelDatum == null)
    return;
  const labelText = getLabelText(series.id, ctx, labelDatum, datumOverrides?.label);
  if (labelText == null)
    return;
  const secondaryLabelText = secondaryLabelDatum == null ? void 0 : getLabelText(series.id, ctx, secondaryLabelDatum, datumOverrides?.secondaryLabel);
  const params = { padding: padding2 };
  const horizontalFactor = textAlign === "center" ? 2 : 1;
  const verticalFactor = verticalAlign === "middle" ? 2 : 1;
  const sizeFittingHeight = (height3) => ({
    width: Math.sqrt(Math.max(innerRadius ** 2 - (height3 / verticalFactor) ** 2, 0)) * horizontalFactor,
    height: Math.min(height3, verticalFactor * innerRadius),
    meta: null
  });
  let labelLayout;
  let secondaryLabelLayout;
  let height2;
  if (secondaryLabelDatum != null && secondaryLabelText != null) {
    const layout = formatStackedLabels(
      toPlainText(labelText),
      labelDatum,
      toPlainText(secondaryLabelText),
      secondaryLabelDatum,
      params,
      sizeFittingHeight
    );
    labelLayout = layout?.label;
    secondaryLabelLayout = layout?.secondaryLabel;
    height2 = layout?.height ?? 0;
  } else {
    const layout = formatSingleLabel(toPlainText(labelText), labelDatum, params, sizeFittingHeight);
    labelLayout = layout?.[0];
    secondaryLabelLayout = void 0;
    height2 = layout?.[0].height ?? 0;
  }
  const rectYOffset = height2 * verticalAlignFactors4[verticalAlign];
  selection.each((label, datum) => {
    let layout;
    if (datum.label === "primary" /* Primary */) {
      layout = labelLayout;
    } else if (datum.label === "secondary" /* Secondary */) {
      layout = secondaryLabelLayout;
    }
    if (layout == null) {
      label.visible = false;
      return;
    }
    label.visible = true;
    label.text = layout.text;
    label.fontSize = layout.fontSize;
    label.lineHeight = layout.lineHeight;
    label.textAlign = textAlign;
    label.textBaseline = "middle";
    const rectOriginInLabelRect = datum.label === "primary" /* Primary */ ? layout.height / 2 : height2 - layout.height / 2;
    label.y = datum.centerY + rectOriginInLabelRect - rectYOffset;
    label.x = datum.centerX;
  });
}

// packages/ag-charts-enterprise/src/series/radial-gauge/radialGaugeSeries.ts
var {
  fromToMotion: fromToMotion6,
  resetMotion: resetMotion5,
  SeriesNodePickMode: SeriesNodePickMode12,
  createDatumId: createDatumId16,
  sectorBox: sectorBox2,
  BBox: BBox26,
  Group: Group15,
  PointerEvents: PointerEvents9,
  Selection: Selection10,
  Sector: Sector4,
  SectorBox: SectorBox3,
  Transformable: Transformable5,
  TransformableText: TransformableText5,
  Text: Text7,
  Marker: Marker5
} = module_support_exports;
var targetPlacementRotation = {
  inside: 90,
  middle: 0,
  outside: -90
};
var outsideLabelPlacements = [
  { textAlign: "left", textBaseline: "top" },
  { textAlign: "right", textBaseline: "top" },
  { textAlign: "right", textBaseline: "bottom" },
  { textAlign: "left", textBaseline: "bottom" }
];
var insideLabelPlacements = [
  { textAlign: "right", textBaseline: "bottom" },
  { textAlign: "left", textBaseline: "bottom" },
  { textAlign: "left", textBaseline: "top" },
  { textAlign: "right", textBaseline: "top" }
];
var RadialGaugeSeries = class extends module_support_exports.Series {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      pickModes: [SeriesNodePickMode12.EXACT_SHAPE_MATCH, SeriesNodePickMode12.NEAREST_NODE]
    });
    this.centerX = 0;
    this.centerY = 0;
    this.radius = 0;
    this.textAlign = "center";
    this.verticalAlign = "middle";
    this.properties = new RadialGaugeSeriesProperties();
    this.scale = new LinearAngleScale();
    this.scaleGroup = this.contentGroup.appendChild(new Group15({ name: "scaleGroup" }));
    this.itemGroup = this.contentGroup.appendChild(new Group15({ name: "itemGroup" }));
    this.itemNeedleGroup = this.contentGroup.appendChild(new Group15({ name: "itemNeedleGroup" }));
    this.itemTargetGroup = this.contentGroup.appendChild(new Group15({ name: "itemTargetGroup" }));
    this.itemTargetLabelGroup = this.contentGroup.appendChild(new Group15({ name: "itemTargetLabelGroup" }));
    this.itemLabelGroup = this.contentGroup.appendChild(new Group15({ name: "itemLabelGroup" }));
    this.highlightTargetGroup = this.highlightGroup.appendChild(
      new Group15({ name: "itemTargetLabelGroup" })
    );
    this.tickGroup = this.contentGroup.appendChild(new Group15({ name: "tickGroup" }));
    this.scaleSelection = Selection10.select(
      this.scaleGroup,
      () => this.nodeFactory()
    );
    this.datumSelection = Selection10.select(
      this.itemGroup,
      () => this.nodeFactory()
    );
    this.needleSelection = Selection10.select(
      this.itemNeedleGroup,
      RadialGaugeNeedle
    );
    this.targetSelection = Selection10.select(
      this.itemTargetGroup,
      () => this.markerFactory()
    );
    this.targetLabelSelection = Selection10.select(this.itemTargetLabelGroup, Text7);
    this.labelSelection = Selection10.select(
      this.itemLabelGroup,
      Text7
    );
    this.highlightTargetSelection = Selection10.select(this.highlightTargetGroup, () => this.markerFactory());
    this.tickSelection = Selection10.select(this.tickGroup, module_support_exports.TransformableText);
    this.datumUnion = new DatumUnion();
    this.animationState = new StateMachine("empty", {
      empty: {
        update: {
          target: "ready",
          action: () => this.animateEmptyUpdateReady()
        },
        reset: "empty",
        skip: "ready"
      },
      ready: {
        updateData: "waiting",
        clear: "clearing",
        resize: () => this.animateReadyResize(),
        reset: "empty",
        skip: "ready"
      },
      waiting: {
        update: {
          target: "ready",
          action: () => this.animateWaitingUpdateReady()
        },
        reset: "empty",
        skip: "ready"
      },
      clearing: {
        update: {
          target: "empty"
        },
        reset: "empty",
        skip: "ready"
      }
    });
    this.scaleGroup.pointerEvents = PointerEvents9.None;
    this.tickGroup.pointerEvents = PointerEvents9.None;
    this.itemNeedleGroup.pointerEvents = PointerEvents9.None;
    this.itemLabelGroup.pointerEvents = PointerEvents9.None;
  }
  get hasData() {
    return this.properties.value != null;
  }
  nodeFactory() {
    return new Sector4();
  }
  markerFactory() {
    const marker = new Marker5();
    marker.size = 1;
    return marker;
  }
  processData() {
    this.nodeDataRefresh = true;
    this.animationState.transition("updateData");
  }
  formatLabel(value) {
    const { min, max } = this.properties.scale;
    return formatLabel(value, { min, max });
  }
  layoutScale() {
    const { scale: scale2, properties } = this;
    const { seriesRectWidth, seriesRectHeight } = this.nodeDataDependencies;
    const { scale: scaleProps, outerRadius } = this.properties;
    const { min, max, label, interval } = scaleProps;
    const startAngle = toRadians(properties.startAngle - 90);
    const endAngle = toRadians(properties.endAngle - 90);
    const sweepAngle = normalizeAngle360Inclusive(endAngle - startAngle);
    const largerThanHalf = sweepAngle > Math.PI;
    const containsTop = largerThanHalf || isBetweenAngles(1.5 * Math.PI, startAngle, endAngle);
    const containsRight = largerThanHalf || isBetweenAngles(0 * Math.PI, startAngle, endAngle);
    const containsBottom = largerThanHalf || isBetweenAngles(0.5 * Math.PI, startAngle, endAngle);
    const containsLeft = largerThanHalf || isBetweenAngles(1 * Math.PI, startAngle, endAngle);
    let textAlign;
    if (containsLeft && !containsRight) {
      textAlign = "right";
    } else if (!containsLeft && containsRight) {
      textAlign = "left";
    } else {
      textAlign = "center";
    }
    let verticalAlign;
    if (containsTop && !containsBottom) {
      verticalAlign = "bottom";
    } else if (!containsTop && containsBottom) {
      verticalAlign = "top";
    } else {
      verticalAlign = "middle";
    }
    const unitBox = sectorBox2({
      startAngle,
      endAngle,
      innerRadius: 0,
      outerRadius: 0.5
    });
    const centerXOffset = -(unitBox.x + unitBox.width / 2) * 2;
    const centerYOffset = -(unitBox.y + unitBox.height / 2) * 2;
    const unitBoxSize = Math.min(seriesRectWidth / unitBox.width, seriesRectHeight / unitBox.height);
    scale2.domain = [min, max];
    scale2.range = [startAngle, endAngle];
    scale2.arcLength = unitBoxSize / 2;
    const { maxSpacing, minSpacing } = interval;
    const { arcLength } = scale2;
    const minTickCount = maxSpacing ? Math.floor(arcLength / maxSpacing) : 1;
    const maxTickCount = minSpacing ? Math.floor(arcLength / minSpacing) : Infinity;
    const preferredTickCount = Math.floor(4 / Math.PI * Math.abs(scale2.range[0] - scale2.range[1]));
    const tickCount = Math.max(minTickCount, Math.min(maxTickCount, preferredTickCount));
    const ticks = interval.values ?? scale2.ticks({
      nice: [false, false],
      interval: interval.step,
      minTickCount,
      maxTickCount,
      tickCount
    })?.ticks ?? [];
    const tickFormatter = tickFormat(ticks, typeof label.format === "string" ? label.format : void 0);
    const tickData = [];
    for (const [index, value] of ticks.entries()) {
      let text2;
      if (label.formatter) {
        text2 = formatWithContext(this.ctx, label.formatter, {
          value,
          index,
          domain: scale2.domain,
          boundSeries: void 0
        });
      }
      text2 ?? (text2 = tickFormatter?.(value));
      if (text2 == null)
        continue;
      tickData.push({ index, value, text: text2 });
    }
    const baseRadius = 0.5 * unitBoxSize;
    const labelInset = label.enabled && outerRadius == null && tickData.length > 0 ? this.getTickLabelInset({
      tickData,
      radius: baseRadius,
      centerXOffset,
      centerYOffset,
      seriesRectWidth,
      seriesRectHeight,
      spacing: label.spacing,
      rotation: toRadians(label.rotation ?? 0)
    }) : 0;
    const radiusBounds = Math.max(
      baseRadius - labelInset,
      // seriesRect may have negative size
      0
    );
    const radius = outerRadius ?? radiusBounds;
    this.centerX = seriesRectWidth / 2 + centerXOffset * radius;
    this.centerY = seriesRectHeight / 2 + centerYOffset * radius;
    this.radius = radius;
    this.textAlign = textAlign;
    this.verticalAlign = verticalAlign;
    return tickData;
  }
  getShapeFillBBox() {
    const { centerX, centerY, radius } = this;
    const bbox = new BBox26(centerX - radius, centerY - radius, 2 * radius, 2 * radius);
    return {
      series: bbox,
      axis: bbox
    };
  }
  getTargets() {
    const { properties } = this;
    const defaultTarget = properties.defaultTarget;
    return properties.targets.map((target) => {
      const {
        text: text2 = defaultTarget.text,
        value = defaultTarget.value ?? 0,
        shape = defaultTarget.shape ?? "triangle",
        rotation = defaultTarget.rotation ?? 0,
        placement = defaultTarget.placement ?? "middle",
        spacing = defaultTarget.spacing ?? 0,
        size = defaultTarget.size ?? 0
      } = target;
      const {
        enabled: labelEnabled = defaultTarget.label.enabled,
        color: labelColor = defaultTarget.label.color ?? "black",
        fontStyle: labelFontStyle = defaultTarget.label.fontStyle ?? "normal",
        fontWeight: labelFontWeight = defaultTarget.label.fontWeight ?? "normal",
        fontSize: labelFontSize = defaultTarget.label.fontSize,
        fontFamily: labelFontFamily = defaultTarget.label.fontFamily,
        spacing: labelSpacing = defaultTarget.label.spacing ?? 0
      } = target.label;
      return {
        text: text2,
        value,
        shape,
        placement,
        spacing,
        size,
        rotation,
        label: {
          enabled: labelEnabled,
          color: labelColor,
          fontStyle: labelFontStyle,
          fontWeight: labelFontWeight,
          fontSize: labelFontSize,
          fontFamily: labelFontFamily,
          spacing: labelSpacing
        },
        style: target.getStyle()
      };
    });
  }
  getTargetRadius(target) {
    const { radius, properties } = this;
    const { innerRadiusRatio, outerRadiusRatio } = properties;
    const { placement, spacing, size } = target;
    const outerRadius = radius * outerRadiusRatio;
    const innerRadius = radius * innerRadiusRatio;
    switch (placement) {
      case "inside":
        return Math.max(innerRadius - spacing - size / 2, 0);
      case "outside":
        return outerRadius + spacing + size / 2;
      default:
        return (innerRadius + outerRadius) / 2;
    }
  }
  getTargetLabel(target) {
    const { scale: scale2 } = this;
    const { value, size, placement, label } = target;
    const { spacing, color: fill, fontStyle, fontWeight: fontWeight2, fontSize, fontFamily } = label;
    const angle2 = scale2.convert(value);
    const quadrant = Math.trunc(normalizeAngle360(angle2) / (Math.PI / 2));
    const offset = size / 2 + spacing;
    let textAlign;
    let textBaseline;
    let offsetX;
    let offsetY;
    switch (placement) {
      case "outside":
        ({ textAlign, textBaseline } = outsideLabelPlacements[quadrant]);
        offsetX = offset * Math.cos(angle2);
        offsetY = offset * Math.sin(angle2);
        break;
      case "inside":
        ({ textAlign, textBaseline } = insideLabelPlacements[quadrant]);
        offsetX = -offset * Math.cos(angle2);
        offsetY = -offset * Math.sin(angle2);
        break;
      default:
        textAlign = "center";
        textBaseline = "bottom";
        offsetX = 0;
        offsetY = -offset;
        break;
    }
    return {
      offsetX,
      offsetY,
      fill,
      textAlign,
      textBaseline,
      fontStyle,
      fontWeight: fontWeight2,
      fontSize,
      fontFamily,
      lineHeight: void 0
    };
  }
  createNodeData() {
    const tickData = this.layoutScale();
    const { id: seriesId, scale: scale2, properties, radius, centerX, centerY } = this;
    const {
      value,
      innerRadiusRatio,
      outerRadiusRatio,
      segmentation,
      cornerRadius,
      cornerMode,
      needle,
      bar,
      scale: scaleProps,
      label,
      secondaryLabel
    } = properties;
    const {
      outerRadius = radius * outerRadiusRatio,
      innerRadius = radius * innerRadiusRatio,
      defaultColorRange
    } = properties;
    const targets = this.getTargets();
    const nodeData = [];
    const targetData = [];
    const needleData = [];
    const labelData = [];
    const scaleData = [];
    const cornersOnAllItems = cornerMode === "item";
    const containerStartAngle = scale2.convert(scale2.domain[0]);
    const containerEndAngle = scale2.convert(value);
    const maxTicks = Math.ceil(normalizeAngle360Inclusive(containerEndAngle - containerStartAngle) * radius);
    let segments = segmentation.enabled ? segmentation.interval.getSegments(scale2, maxTicks) : void 0;
    const barStyle = bar.getStyle(defaultColorRange, scale2);
    const scaleStyle = scaleProps.getStyle(bar.enabled, defaultColorRange, scale2);
    if (segments == null && cornersOnAllItems) {
      const segmentStart = Math.min(...scale2.domain);
      const segmentEnd = Math.max(...scale2.domain);
      const datum = { value, segmentStart, segmentEnd };
      const appliedCornerRadius = Math.min(cornerRadius, (outerRadius - innerRadius) / 2);
      const angleInset = appliedCornerRadius / ((innerRadius + outerRadius) / 2);
      nodeData.push({
        series: this,
        itemId: `value`,
        datum,
        datumIndex: { type: 0 /* Node */ },
        type: 0 /* Node */,
        centerX,
        centerY,
        outerRadius,
        innerRadius,
        startAngle: containerStartAngle - angleInset,
        endAngle: containerEndAngle + angleInset,
        clipStartAngle: void 0,
        clipEndAngle: void 0,
        startCornerRadius: cornerRadius,
        endCornerRadius: cornerRadius,
        style: barStyle
      });
      scaleData.push({
        series: this,
        itemId: `scale`,
        datum,
        datumIndex: { type: 0 /* Node */ },
        type: 0 /* Node */,
        centerX,
        centerY,
        outerRadius,
        innerRadius,
        startAngle: scale2.range[0] - angleInset,
        endAngle: scale2.range[1] + angleInset,
        clipStartAngle: void 0,
        clipEndAngle: void 0,
        startCornerRadius: cornerRadius,
        endCornerRadius: cornerRadius,
        style: scaleStyle
      });
    } else {
      segments ?? (segments = scale2.domain);
      for (let i = 0; i < segments.length - 1; i++) {
        const segmentStart = segments[i];
        const segmentEnd = segments[i + 1];
        const datum = { value, segmentStart, segmentEnd };
        const isStart = i === 0;
        const isEnd = i === segments.length - 2;
        const itemStartAngle = scale2.convert(segmentStart);
        const itemEndAngle = scale2.convert(segmentEnd);
        nodeData.push({
          series: this,
          itemId: `value-${i}`,
          datum,
          datumIndex: { type: 0 /* Node */ },
          type: 0 /* Node */,
          centerX,
          centerY,
          outerRadius,
          innerRadius,
          startAngle: itemStartAngle,
          endAngle: itemEndAngle,
          clipStartAngle: containerStartAngle,
          clipEndAngle: containerEndAngle,
          startCornerRadius: cornersOnAllItems || isStart ? cornerRadius : 0,
          endCornerRadius: cornersOnAllItems || isEnd ? cornerRadius : 0,
          style: barStyle
        });
        scaleData.push({
          series: this,
          itemId: `scale-${i}`,
          datum,
          datumIndex: { type: 0 /* Node */ },
          type: 0 /* Node */,
          centerX,
          centerY,
          outerRadius,
          innerRadius,
          startAngle: itemStartAngle,
          endAngle: itemEndAngle,
          clipStartAngle: void 0,
          clipEndAngle: void 0,
          startCornerRadius: cornersOnAllItems || isStart ? cornerRadius : 0,
          endCornerRadius: cornersOnAllItems || isEnd ? cornerRadius : 0,
          style: scaleStyle
        });
      }
    }
    if (!needle.enabled && label.enabled) {
      const {
        text: text2,
        color: fill,
        fontSize,
        minimumFontSize,
        fontStyle,
        fontWeight: fontWeight2,
        fontFamily,
        lineHeight,
        formatter: formatter2 = (params) => this.formatLabel(params.value)
      } = label;
      labelData.push({
        label: "primary" /* Primary */,
        centerX,
        centerY,
        text: text2,
        value,
        fill,
        fontSize,
        minimumFontSize,
        fontStyle,
        fontWeight: fontWeight2,
        fontFamily,
        lineHeight,
        formatter: formatter2
      });
    }
    if (!needle.enabled && secondaryLabel.enabled) {
      const {
        text: text2,
        color: fill,
        fontSize,
        minimumFontSize,
        fontStyle,
        fontWeight: fontWeight2,
        fontFamily,
        lineHeight,
        formatter: formatter2
      } = secondaryLabel;
      labelData.push({
        label: "secondary" /* Secondary */,
        centerX,
        centerY,
        text: text2,
        value,
        fill,
        fontSize,
        minimumFontSize,
        fontStyle,
        fontWeight: fontWeight2,
        fontFamily,
        lineHeight,
        formatter: formatter2
      });
    }
    if (needle.enabled) {
      let needleRadius = needle.radiusRatio == null ? innerRadius : radius * needle.radiusRatio;
      needleRadius = Math.max(needleRadius - needle.spacing, 0);
      const needleAngle = scale2.convert(value);
      needleData.push({
        centerX,
        centerY,
        radius: needleRadius,
        angle: needleAngle,
        series: this
      });
    }
    for (let i = 0; i < targets.length; i += 1) {
      const target = targets[i];
      const { value: targetValue, text: text2, size, shape, style: style2 } = target;
      if (targetValue < Math.min(...scale2.domain) || targetValue > Math.max(...scale2.domain)) {
        continue;
      }
      const targetRadius = this.getTargetRadius(target);
      const targetAngle = scale2.convert(targetValue);
      const targetRotation = toRadians(target.rotation + targetPlacementRotation[target.placement]);
      targetData.push({
        series: this,
        itemId: `target-${i}`,
        midPoint: {
          x: targetRadius * Math.cos(targetAngle) + centerX,
          y: targetRadius * Math.sin(targetAngle) + centerY
        },
        datum: { value: targetValue },
        datumIndex: { type: 1 /* Target */, index: i },
        type: 1 /* Target */,
        value: targetValue,
        text: text2,
        centerX,
        centerY,
        shape,
        radius: targetRadius,
        angle: targetAngle,
        rotation: targetRotation,
        size,
        label: this.getTargetLabel(target),
        style: style2
      });
    }
    return {
      itemId: seriesId,
      nodeData,
      needleData,
      targetData,
      labelData,
      scaleData,
      tickData
    };
  }
  findNodeDatum(itemId) {
    return findGaugeNodeDatum(this, itemId);
  }
  updateSelections(resize) {
    if (this.nodeDataRefresh || resize) {
      this.contextNodeData = this.createNodeData();
      this.nodeDataRefresh = false;
    }
  }
  highlightDatum(node) {
    if (node?.series === this && node.type === 1 /* Target */) {
      return node;
    }
  }
  update({ seriesRect }) {
    const {
      datumSelection,
      labelSelection,
      needleSelection,
      targetSelection,
      targetLabelSelection,
      scaleSelection,
      highlightTargetSelection,
      tickSelection
    } = this;
    const resize = this.checkResize(seriesRect);
    this.updateSelections(resize);
    this.contentGroup.visible = this.visible;
    this.contentGroup.opacity = this.getOpacity();
    const nodeData = this.contextNodeData?.nodeData ?? [];
    const labelData = this.contextNodeData?.labelData ?? [];
    const needleData = this.contextNodeData?.needleData ?? [];
    const targetData = this.contextNodeData?.targetData ?? [];
    const scaleData = this.contextNodeData?.scaleData ?? [];
    const tickData = this.contextNodeData?.tickData ?? [];
    const highlightTargetDatum = this.highlightDatum(this.ctx.highlightManager.getActiveHighlight());
    this.scaleSelection = this.updateScaleSelection({ scaleData, scaleSelection });
    this.updateScaleNodes({ scaleSelection });
    this.needleSelection = this.updateNeedleSelection({ needleData, needleSelection });
    this.updateNeedleNodes({ needleSelection });
    this.targetSelection = this.updateTargetSelection({ targetData, targetSelection });
    this.updateTargetStyles({ targetSelection, isHighlight: false });
    this.updateTargetNodes({ targetSelection });
    this.targetLabelSelection = this.updateTargetLabelSelection({ targetData, targetLabelSelection });
    this.updateTargetLabelNodes({ targetLabelSelection });
    this.datumSelection = this.updateDatumSelection({ nodeData, datumSelection });
    this.updateDatumNodes({ datumSelection });
    this.labelSelection = this.updateLabelSelection({ labelData, labelSelection });
    this.updateLabelNodes({ labelSelection });
    this.highlightTargetSelection = this.updateTargetSelection({
      targetData: highlightTargetDatum == null ? [] : [highlightTargetDatum],
      targetSelection: highlightTargetSelection
    });
    this.updateTargetStyles({ targetSelection: highlightTargetSelection, isHighlight: true });
    this.updateTargetNodes({ targetSelection: highlightTargetSelection });
    this.tickSelection = this.updateTickSelection({ tickData, tickSelection });
    this.updateTickNodes({ tickSelection });
    if (resize) {
      this.animationState.transition("resize");
    }
    this.animationState.transition("update");
  }
  updateDatumSelection(opts) {
    return opts.datumSelection.update(opts.nodeData, void 0, (datum) => {
      return createDatumId16(opts.nodeData.length, datum.itemId);
    });
  }
  updateDatumNodes(opts) {
    const { datumSelection } = opts;
    const { ctx, properties } = this;
    const { segmentation } = properties;
    const sectorSpacing = segmentation.spacing ?? 0;
    const animationDisabled = ctx.animationManager.isSkipped();
    const fillBBox = this.getShapeFillBBox();
    datumSelection.each((sector, datum) => {
      const { centerX, centerY, innerRadius, outerRadius, startCornerRadius, endCornerRadius } = datum;
      sector.centerX = centerX;
      sector.centerY = centerY;
      sector.innerRadius = innerRadius;
      sector.outerRadius = outerRadius;
      sector.pointerEvents = this.properties.bar.enabled ? module_support_exports.PointerEvents.All : module_support_exports.PointerEvents.None;
      sector.setStyleProperties(datum.style, fillBBox);
      sector.startOuterCornerRadius = startCornerRadius;
      sector.startInnerCornerRadius = startCornerRadius;
      sector.endOuterCornerRadius = endCornerRadius;
      sector.endInnerCornerRadius = endCornerRadius;
      sector.radialEdgeInset = (sectorSpacing + sector.strokeWidth) / 2;
      sector.concentricEdgeInset = sector.strokeWidth / 2;
      datum.midPoint = sector.getBBox().computeCenter();
      if (animationDisabled || sector.previousDatum == null) {
        sector.setProperties(resetRadialGaugeSeriesResetSectorFunction(sector, datum));
      }
    });
    this.datumUnion.update(datumSelection, this.itemGroup, module_support_exports.Sector, (node, first2, last) => {
      node.clipSector ?? (node.clipSector = new SectorBox3(Number.NaN, Number.NaN, Number.NaN, Number.NaN));
      node.centerX = first2.centerX;
      node.centerY = first2.centerY;
      node.outerRadius = node.clipSector.outerRadius = first2.outerRadius;
      node.innerRadius = node.clipSector.innerRadius = first2.innerRadius;
      node.startAngle = node.clipSector.startAngle = first2.startAngle;
      node.startInnerCornerRadius = first2.startInnerCornerRadius;
      node.startOuterCornerRadius = first2.startOuterCornerRadius;
      node.endAngle = last.endAngle;
      node.clipSector.endAngle = last.clipSector?.endAngle ?? last.endAngle;
      node.endInnerCornerRadius = last.endInnerCornerRadius;
      node.endOuterCornerRadius = last.endOuterCornerRadius;
      node.pointerEvents = module_support_exports.PointerEvents.None;
    });
  }
  updateScaleSelection(opts) {
    return opts.scaleSelection.update(opts.scaleData, void 0, (datum) => {
      return createDatumId16(opts.scaleData.length, datum.itemId);
    });
  }
  updateScaleNodes(opts) {
    const { scaleSelection } = opts;
    const { segmentation } = this.properties;
    const sectorSpacing = segmentation.spacing ?? 0;
    const fillBBox = this.getShapeFillBBox();
    scaleSelection.each((sector, datum) => {
      const { centerX, centerY, innerRadius, outerRadius, startCornerRadius, endCornerRadius } = datum;
      sector.centerX = centerX;
      sector.centerY = centerY;
      sector.innerRadius = innerRadius;
      sector.outerRadius = outerRadius;
      sector.setStyleProperties(datum.style, fillBBox);
      sector.startOuterCornerRadius = startCornerRadius;
      sector.startInnerCornerRadius = startCornerRadius;
      sector.endOuterCornerRadius = endCornerRadius;
      sector.endInnerCornerRadius = endCornerRadius;
      sector.radialEdgeInset = (sectorSpacing + sector.strokeWidth) / 2;
      sector.concentricEdgeInset = sector.strokeWidth / 2;
      sector.setProperties(resetRadialGaugeSeriesResetSectorFunction(sector, datum));
    });
  }
  updateNeedleSelection(opts) {
    return opts.needleSelection.update(opts.needleData, void 0, () => createDatumId16(0));
  }
  updateNeedleNodes(opts) {
    const { needleSelection } = opts;
    const { fill, fillOpacity, stroke: stroke3, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this.properties.needle;
    const animationDisabled = this.ctx.animationManager.isSkipped();
    needleSelection.each((needle, datum) => {
      const { centerX, centerY, radius } = datum;
      const scale2 = radius * 2;
      needle.d = RadialGaugeNeedle.defaultPathData;
      needle.setStyleProperties({
        fill,
        fillOpacity,
        stroke: stroke3,
        strokeOpacity,
        strokeWidth: strokeWidth / scale2,
        lineDash: lineDash.map((d) => d / scale2),
        lineDashOffset: lineDashOffset / scale2
      });
      needle.translationX = centerX;
      needle.translationY = centerY;
      needle.scalingX = scale2;
      needle.scalingY = scale2;
      if (animationDisabled) {
        needle.setProperties(resetRadialGaugeSeriesResetNeedleFunction(needle, datum));
      }
    });
  }
  updateTargetSelection(opts) {
    return opts.targetSelection.update(opts.targetData, void 0, (target) => target.itemId);
  }
  updateTargetStyles({
    targetSelection,
    isHighlight
  }) {
    targetSelection.each((_, datum) => {
      datum.style = this.getTargetStyle(isHighlight, datum);
    });
  }
  updateTargetNodes({
    targetSelection
  }) {
    targetSelection.each((target, datum) => {
      const { centerX, centerY, angle: angle2, radius, shape, size, rotation } = datum;
      target.setStyleProperties(datum.style);
      target.size = size;
      target.shape = shape === "line" ? lineMarker : shape;
      target.translationX = centerX + radius * Math.cos(angle2);
      target.translationY = centerY + radius * Math.sin(angle2);
      target.rotation = angle2 + rotation;
    });
  }
  getTargetStyle(isHighlight, { datumIndex, style: style2 }) {
    const highlightStyle = this.getHighlightStyle(isHighlight, datumIndex);
    return mergeDefaults(highlightStyle, {
      ...style2,
      opacity: 1
    });
  }
  updateTargetLabelSelection(opts) {
    return opts.targetLabelSelection.update(opts.targetData, void 0, (target) => target.itemId);
  }
  updateTargetLabelNodes(opts) {
    const { targetLabelSelection } = opts;
    targetLabelSelection.each((label, target) => {
      const { centerX, centerY, radius, angle: angle2, text: text2 } = target;
      const { offsetX, offsetY, fill, fontStyle, fontWeight: fontWeight2, fontSize, fontFamily, textAlign, textBaseline } = target.label;
      if (text2 == null) {
        label.visible = false;
        return;
      }
      label.visible = true;
      label.x = centerX + radius * Math.cos(angle2) + offsetX;
      label.y = centerY + radius * Math.sin(angle2) + offsetY;
      label.text = text2;
      label.fill = fill;
      label.fontStyle = fontStyle;
      label.fontWeight = fontWeight2;
      label.fontSize = fontSize;
      label.fontFamily = fontFamily;
      label.textAlign = textAlign;
      label.textBaseline = textBaseline;
    });
  }
  updateLabelSelection(opts) {
    return opts.labelSelection.update(opts.labelData, void 0, (datum) => datum.label);
  }
  updateLabelNodes(opts) {
    const { labelSelection } = opts;
    const animationDisabled = this.ctx.animationManager.isSkipped();
    labelSelection.each((label, datum) => {
      label.fill = datum.fill;
      label.fontStyle = datum.fontStyle;
      label.fontWeight = datum.fontWeight;
      label.fontFamily = datum.fontFamily;
    });
    if (animationDisabled || this.labelsHaveExplicitText()) {
      this.formatLabelText();
    }
  }
  updateTickSelection(opts) {
    return opts.tickSelection.update(opts.tickData, void 0, (datum) => datum.index);
  }
  updateTickNodes(opts) {
    const { scale: scale2, radius, centerX, centerY, properties } = this;
    const { enabled, color: color2, fontFamily, fontSize, fontStyle, fontWeight: fontWeight2, spacing } = properties.scale.label;
    const rotation = toRadians(properties.scale.label.rotation ?? 0);
    opts.tickSelection.each((label, datum) => {
      if (!enabled) {
        label.visible = false;
        return;
      }
      label.visible = true;
      label.text = datum.text;
      label.fill = color2;
      label.fontFamily = fontFamily;
      label.fontSize = fontSize;
      label.fontStyle = fontStyle;
      label.fontWeight = fontWeight2;
      const angle2 = scale2.convert(datum.value);
      const { textAlign, textBaseline } = this.getTickLabelAlign(angle2);
      const x0 = centerX + (radius + spacing) * Math.cos(angle2);
      const y0 = centerY + (radius + spacing) * Math.sin(angle2);
      label.textAlign = textAlign;
      label.textBaseline = textBaseline;
      label.x = x0;
      label.y = y0;
      label.rotationCenterX = x0;
      label.rotationCenterY = y0;
      label.rotation = rotation;
    });
  }
  getTickLabelAlign(tickAngle) {
    const cos = Math.cos(tickAngle);
    const sin = Math.sin(tickAngle);
    let textAlign;
    let textBaseline;
    const isCos0 = isNumberEqual(cos, 0);
    const isSin0 = isNumberEqual(sin, 0);
    const isCosPositive = cos > 0 && !isCos0;
    const isSinPositive = sin > 0 && !isSin0;
    textAlign = "right";
    if (isCos0) {
      textAlign = "center";
    } else if (isCosPositive) {
      textAlign = "left";
    }
    textBaseline = "bottom";
    if (isSin0) {
      textBaseline = "middle";
    } else if (isSinPositive) {
      textBaseline = "top";
    }
    return { textAlign, textBaseline };
  }
  getTickLabelInset(params) {
    const { tickData, radius, centerXOffset, centerYOffset, seriesRectWidth, seriesRectHeight, spacing, rotation } = params;
    const { label } = this.properties.scale;
    const centerX = seriesRectWidth / 2 + centerXOffset * radius;
    const centerY = seriesRectHeight / 2 + centerYOffset * radius;
    const tempText = new TransformableText5();
    tempText.fontFamily = label.fontFamily;
    tempText.fontSize = label.fontSize;
    tempText.fontStyle = label.fontStyle;
    tempText.fontWeight = label.fontWeight;
    tempText.rotation = rotation;
    const minComponent = 1e-6;
    let inset = 0;
    for (const datum of tickData) {
      const angle2 = this.scale.convert(datum.value);
      const cos = Math.cos(angle2);
      const sin = Math.sin(angle2);
      const x = centerX + (radius + spacing) * cos;
      const y = centerY + (radius + spacing) * sin;
      const { textAlign, textBaseline } = this.getTickLabelAlign(angle2);
      tempText.text = datum.text;
      tempText.x = x;
      tempText.y = y;
      tempText.textAlign = textAlign;
      tempText.textBaseline = textBaseline;
      tempText.rotationCenterX = x;
      tempText.rotationCenterY = y;
      const box = rotation ? Transformable5.toCanvas(tempText) : tempText.getBBox();
      if (box == null)
        continue;
      const minX = box.x;
      const maxX = box.x + box.width;
      const minY = box.y;
      const maxY = box.y + box.height;
      const overflowLeft = Math.max(0, -minX);
      const overflowRight = Math.max(0, maxX - seriesRectWidth);
      const overflowTop = Math.max(0, -minY);
      const overflowBottom = Math.max(0, maxY - seriesRectHeight);
      const dxPerRadius = centerXOffset + cos;
      if (Math.abs(dxPerRadius) > minComponent) {
        if (overflowRight > 0 && dxPerRadius > 0) {
          inset = Math.max(inset, overflowRight / dxPerRadius);
        } else if (overflowLeft > 0 && dxPerRadius < 0) {
          inset = Math.max(inset, overflowLeft / -dxPerRadius);
        }
      }
      const dyPerRadius = centerYOffset + sin;
      if (Math.abs(dyPerRadius) > minComponent) {
        if (overflowBottom > 0 && dyPerRadius > 0) {
          inset = Math.max(inset, overflowBottom / dyPerRadius);
        } else if (overflowTop > 0 && dyPerRadius < 0) {
          inset = Math.max(inset, overflowTop / -dyPerRadius);
        }
      }
    }
    return inset;
  }
  labelsHaveExplicitText() {
    for (const { datum } of this.labelSelection) {
      if (datum.text == null) {
        return false;
      }
    }
    return true;
  }
  formatLabelText(datum) {
    const { labelSelection, radius, textAlign, verticalAlign } = this;
    const { spacing: padding2, innerRadiusRatio } = this.properties;
    formatRadialGaugeLabels(
      this,
      this.ctx,
      labelSelection,
      { padding: padding2, textAlign, verticalAlign },
      radius * innerRadiusRatio,
      datum
    );
  }
  resetAllAnimation() {
    this.ctx.animationManager.stopByAnimationGroupId(this.id);
    resetMotion5([this.datumSelection], resetRadialGaugeSeriesResetSectorFunction);
    resetMotion5([this.needleSelection], resetRadialGaugeSeriesResetNeedleFunction);
    this.formatLabelText();
  }
  resetAnimation(phase) {
    if (phase === "initial") {
      this.animationState.transition("reset");
    } else if (phase === "ready") {
      this.animationState.transition("skip");
    }
  }
  animateLabelText(params = {}) {
    const { animationManager } = this.ctx;
    let labelFrom;
    let labelTo;
    let secondaryLabelFrom;
    let secondaryLabelTo;
    this.labelSelection.each((label, datum) => {
      label.opacity = 1;
      if (datum.label === "primary" /* Primary */) {
        labelFrom = label.previousDatum?.value ?? params.from ?? datum.value;
        labelTo = datum.value;
      } else if (datum.label === "secondary" /* Secondary */) {
        secondaryLabelFrom = label.previousDatum?.value ?? params.from ?? datum.value;
        secondaryLabelTo = datum.value;
      }
    });
    if (this.labelsHaveExplicitText()) {
    } else if (labelTo == null || secondaryLabelTo == null) {
      this.formatLabelText();
    } else if (labelFrom === labelTo && secondaryLabelFrom === secondaryLabelTo) {
      this.formatLabelText({ label: labelTo, secondaryLabel: secondaryLabelTo });
    } else {
      const animationId = `${this.id}_labels`;
      animationManager.animate({
        id: animationId,
        groupId: "label",
        from: { label: labelFrom, secondaryLabel: secondaryLabelFrom },
        to: { label: labelTo, secondaryLabel: secondaryLabelTo },
        phase: params.phase ?? "update",
        onUpdate: (datum) => this.formatLabelText(datum),
        onStop: () => this.formatLabelText({ label: labelTo, secondaryLabel: secondaryLabelTo })
      });
    }
  }
  animateEmptyUpdateReady() {
    const { animationManager } = this.ctx;
    const { node, needle } = prepareRadialGaugeSeriesAnimationFunctions(true, this.scale.range[0]);
    fromToMotion6(this.id, "node", animationManager, [this.datumSelection], node, (_sector, datum) => datum.itemId);
    fromToMotion6(this.id, "needle", animationManager, [this.needleSelection], needle, () => "needle");
    fromToMotion6(
      this.id,
      "label",
      animationManager,
      [this.labelSelection],
      fadeInFns,
      (_label, datum) => datum.label
    );
    this.animateLabelText({
      from: this.properties.scale.min,
      phase: "initial"
    });
  }
  animateWaitingUpdateReady() {
    const { animationManager } = this.ctx;
    const { node, needle } = prepareRadialGaugeSeriesAnimationFunctions(false, this.scale.range[0]);
    fromToMotion6(this.id, "node", animationManager, [this.datumSelection], node, (_sector, datum) => datum.itemId);
    fromToMotion6(this.id, "needle", animationManager, [this.needleSelection], needle, () => "needle");
    this.animateLabelText();
  }
  animateReadyResize() {
    this.resetAllAnimation();
  }
  dataCount() {
    return Number.NaN;
  }
  getSeriesDomain() {
    return { domain: [Number.NaN, Number.NaN] };
  }
  getSeriesRange() {
    return [Number.NaN, Number.NaN];
  }
  getLegendData() {
    return [];
  }
  getTooltipContent(datumIndex) {
    const { id: seriesId, properties } = this;
    const { tooltip } = properties;
    let value;
    let text2;
    let fallbackLabel;
    if (datumIndex.type === 0 /* Node */) {
      value = properties.value;
      text2 = properties.label.text;
      fallbackLabel = this.ctx.localeManager.t("ariaLabelGaugeValue");
    } else {
      ({ value, text: text2 } = properties.targets[datumIndex.index]);
      fallbackLabel = this.ctx.localeManager.t("ariaLabelGaugeTarget");
    }
    if (value == null)
      return;
    return this.formatTooltipWithContext(
      tooltip,
      {
        data: [{ label: text2, fallbackLabel, value: this.formatLabel(value) }]
      },
      { seriesId, title: void 0, datum: void 0, value }
    );
  }
  pickNodeClosestDatum(point) {
    return pickGaugeNearestDatum(this, point);
  }
  pickFocus(opts) {
    return pickGaugeFocus(this, opts);
  }
  getCaptionText() {
    const { value } = this.properties;
    const description = [];
    description.push(this.formatLabel(value));
    this.labelSelection.each((_label, datum) => {
      const text2 = getLabelText(this.id, this.ctx, datum);
      if (text2 != null) {
        description.push(toPlainText(text2));
      }
    });
    return description.join(". ");
  }
  getCategoryValue(_datumIndex) {
    return;
  }
  datumIndexForCategoryValue(_categoryValue) {
    return;
  }
  hasItemStylers() {
    return this.properties.label.itemStyler != null;
  }
};
RadialGaugeSeries.className = "RadialGaugeSeries";
RadialGaugeSeries.type = "radial-gauge";

// packages/ag-charts-enterprise/src/series/radial-gauge/radialGaugeModule.ts
var RadialGaugeModule = {
  type: "series",
  name: "radial-gauge",
  chartType: "standalone",
  enterprise: true,
  dependencies: [GaugePresetModule],
  version: VERSION,
  options: radialGaugeSeriesOptionsDef,
  themeTemplate: {
    minWidth: 200,
    minHeight: 200,
    tooltip: {
      enabled: false
    },
    series: {
      outerRadiusRatio: 1,
      innerRadiusRatio: 0.8,
      startAngle: 270,
      endAngle: 270 + 180,
      defaultColorRange: {
        $if: [
          { $eq: [{ $palette: "type" }, "inbuilt"] },
          { $interpolate: [{ $palette: "secondDivergingColors" }, 5] },
          SAFE_RANGE2_OPERATION
        ]
      },
      scale: {
        defaultFill: { $path: ["/1", { $palette: "fill" }, { $palette: "hierarchyColors" }] },
        // TODO: mix backgroundColor and foregroundColor?
        stroke: { $path: ["/2", SAFE_STROKE_FILL_OPERATION, { $palette: "hierarchyColors" }] },
        // TODO: mix backgroundColor and foregroundColor?
        strokeWidth: { $isUserOption: ["./stroke", 2, 0] },
        label: {
          fontWeight: { $ref: "fontWeight" },
          fontSize: { $ref: "fontSize" },
          fontFamily: { $ref: "fontFamily" },
          color: { $ref: "textColor" },
          spacing: 12
        }
      },
      bar: {
        strokeWidth: { $isUserOption: ["./stroke", 2, 0] }
      },
      segmentation: {
        enabled: false,
        interval: {},
        spacing: 2
      },
      defaultTarget: {
        fill: { $ref: "foregroundColor" },
        stroke: { $ref: "foregroundColor" },
        size: 10,
        shape: "triangle",
        placement: "outside",
        spacing: 5,
        label: {
          enabled: true,
          fontWeight: { $ref: "fontWeight" },
          fontSize: { $ref: "fontSize" },
          fontFamily: { $ref: "fontFamily" },
          color: { $ref: "textColor" },
          spacing: 5
        }
      },
      needle: {
        enabled: false,
        fill: { $ref: "foregroundColor" },
        spacing: 10
      },
      label: {
        ...LABEL_BOXING_DEFAULTS,
        enabled: true,
        fontWeight: { $ref: "fontWeight" },
        fontSize: 56,
        minimumFontSize: 18 / 56,
        fontFamily: { $ref: "fontFamily" },
        color: { $ref: "textColor" }
      },
      secondaryLabel: {
        ...LABEL_BOXING_DEFAULTS,
        enabled: true,
        fontWeight: { $ref: "fontWeight" },
        fontSize: { $rem: FONT_SIZE_RATIO.LARGE },
        minimumFontSize: { $ref: "fontSize" },
        fontFamily: { $ref: "fontFamily" },
        color: { $ref: "subtleTextColor" }
      },
      tooltip: {
        range: { $path: ["/tooltip/range", 10] }
      }
    }
  },
  create: (ctx) => new RadialGaugeSeries(ctx)
};

// packages/ag-charts-enterprise/src/module-bundles/gauge.ts
var AllGaugeModule = [LinearGaugeModule, RadialGaugeModule];

// packages/ag-charts-enterprise/src/utils/polar.ts
function walkPairsOutward(items, step, visitPair) {
  const middleIndex = Math.floor(items.length / 2);
  return walkPairsByStep(items, step, middleIndex, step, visitPair) || walkPairsByStep(items, items.length - step, middleIndex, -step, visitPair);
}
function walkPairsByStep(items, startIndex, endIndex, step, visitPair) {
  let previous = items[0];
  for (let i = startIndex; step > 0 ? i <= endIndex : i > endIndex; i += step) {
    const current = items[i];
    if (visitPair(previous, current)) {
      return true;
    }
    previous = current;
  }
  return false;
}

// packages/ag-charts-enterprise/src/axes/angle-number/angleAxisInterval.ts
var { AxisInterval: AxisInterval3 } = module_support_exports;
var AngleAxisInterval = class extends AxisInterval3 {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], AngleAxisInterval.prototype, "minSpacing", 2);

// packages/ag-charts-enterprise/src/axes/polar-crosslines/polarCrossLine.ts
var { Group: Group16, LabelStyle: LabelStyle2 } = module_support_exports;
var PolarCrossLineLabel = class extends LabelStyle2 {
  constructor() {
    super(...arguments);
    this.padding = 5;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], PolarCrossLineLabel.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PolarCrossLineLabel.prototype, "padding", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PolarCrossLineLabel.prototype, "text", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PolarCrossLineLabel.prototype, "parallel", 2);
var PolarCrossLine = class extends BaseProperties {
  constructor() {
    super(...arguments);
    this.id = createId(this);
    this.defaultColorRange = [];
    this.shape = "polygon";
    this.label = new PolarCrossLineLabel();
    this.scale = void 0;
    this.clippedRange = [-Infinity, Infinity];
    this.gridLength = 0;
    this.sideFlag = -1;
    this.parallelFlipRotation = 0;
    this.regularFlipRotation = 0;
    this.direction = "angle" /* Angle */;
    this.axisInnerRadius = 0;
    this.axisOuterRadius = 0;
    this.lineGroup = new Group16({ name: this.id });
    this.rangeGroup = new Group16({ name: this.id });
    this.labelGroup = new Group16({ name: this.id });
    this._isRange = void 0;
  }
  assignCrossLineGroup(isRange, crossLineRange) {
    if (isRange !== this._isRange) {
      if (isRange) {
        this.rangeGroup.appendChild(crossLineRange);
      } else {
        this.lineGroup.appendChild(crossLineRange);
      }
    }
    this._isRange = isRange;
  }
  setSectorNodeProps(node) {
    node.fill = this.fill;
    node.fillOpacity = this.fillOpacity ?? 1;
    node.stroke = this.stroke;
    node.strokeOpacity = this.strokeOpacity ?? 1;
    node.strokeWidth = this.strokeWidth ?? 1;
    node.lineDash = this.lineDash;
  }
  setLabelNodeProps(node, x, y, baseline, rotation) {
    const { label } = this;
    node.x = x;
    node.y = y;
    node.text = label.text;
    node.textAlign = "center";
    node.textBaseline = baseline;
    node.rotation = rotation;
    node.rotationCenterX = x;
    node.rotationCenterY = y;
    node.fill = label.color;
    node.setFont(label);
    node.setBoxing(label);
    node.visible = true;
  }
};
PolarCrossLine.className = "PolarCrossLine";
__decorateClass([
  addFakeTransformToInstanceProperty
], PolarCrossLine.prototype, "enabled", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PolarCrossLine.prototype, "type", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PolarCrossLine.prototype, "range", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PolarCrossLine.prototype, "value", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PolarCrossLine.prototype, "defaultColorRange", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PolarCrossLine.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PolarCrossLine.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PolarCrossLine.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PolarCrossLine.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PolarCrossLine.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PolarCrossLine.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PolarCrossLine.prototype, "shape", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], PolarCrossLine.prototype, "label", 2);

// packages/ag-charts-enterprise/src/axes/polar-crosslines/angleCrossLine.ts
var { getCrossLineValue: getCrossLineValue2, validateCrossLineValue: validateCrossLineValue2, Group: Group17, Path: Path9, Sector: Sector5, RotatableText: RotatableText2, ContinuousScale: ContinuousScale5 } = module_support_exports;
var AngleCrossLine = class extends PolarCrossLine {
  constructor() {
    super();
    this.direction = "angle" /* Angle */;
    this.polygonNode = new Path9();
    this.sectorNode = new Sector5();
    this.lineNode = new Path9();
    this.crossLineRange = new Group17();
    this.labelNode = new RotatableText2();
    this.ticks = [];
    this.crossLineRange.append(this.polygonNode);
    this.crossLineRange.append(this.sectorNode);
    this.crossLineRange.append(this.lineNode);
    this.labelGroup.append(this.labelNode);
  }
  visibilityCheck() {
    if (!ContinuousScale5.is(this.scale)) {
      return true;
    }
    const [d0, d1] = this.scale.domain;
    const value = getCrossLineValue2(this);
    if (this.type === "range") {
      const [start2, end3] = value;
      return start2 >= d0 && start2 <= d1 && end3 >= start2 && end3 <= d1;
    } else {
      return value >= d0 && value <= d1;
    }
  }
  update(visible) {
    const { scale: scale2 } = this;
    if (!scale2 || !validateCrossLineValue2(this, scale2) || !this.visibilityCheck()) {
      this.rangeGroup.visible = false;
      this.lineGroup.visible = false;
      this.labelGroup.visible = false;
      return;
    }
    this.rangeGroup.visible = visible;
    this.lineGroup.visible = visible;
    this.labelGroup.visible = visible;
    this.updateLineNode(visible);
    this.updatePolygonNode(visible);
    this.updateSectorNode(visible);
    this.updateLabelNode(visible);
  }
  updateLineNode(visible) {
    const { scale: scale2, type, value, lineNode: line } = this;
    if (!visible || type !== "line" || !scale2) {
      line.visible = false;
      return;
    }
    const angle2 = scale2.convert(value);
    if (Number.isNaN(angle2)) {
      line.visible = false;
      return;
    }
    const { axisInnerRadius, axisOuterRadius } = this;
    line.visible = true;
    line.stroke = this.stroke;
    line.strokeOpacity = this.strokeOpacity ?? 1;
    line.strokeWidth = this.strokeWidth ?? 1;
    line.fill = void 0;
    line.lineDash = this.lineDash;
    const x = axisOuterRadius * Math.cos(angle2);
    const y = axisOuterRadius * Math.sin(angle2);
    const x0 = axisInnerRadius * Math.cos(angle2);
    const y0 = axisInnerRadius * Math.sin(angle2);
    line.path.clear(true);
    line.path.moveTo(x0, y0);
    line.path.lineTo(x, y);
    this.assignCrossLineGroup(false, this.crossLineRange);
  }
  updatePolygonNode(visible) {
    const { polygonNode: polygon, range: range3, scale: scale2, shape, type, ticks } = this;
    if (!visible || type !== "range" || shape !== "polygon" || !scale2 || !range3) {
      polygon.visible = false;
      return;
    }
    const { axisInnerRadius, axisOuterRadius } = this;
    const startIndex = ticks.indexOf(range3[0]);
    const endIndex = ticks.indexOf(range3[1]);
    const stops = startIndex <= endIndex ? ticks.slice(startIndex, endIndex + 1) : ticks.slice(startIndex).concat(ticks.slice(0, endIndex + 1));
    const angles = stops.map((value) => scale2.convert(value));
    polygon.visible = true;
    this.setSectorNodeProps(polygon);
    const { path } = polygon;
    path.clear(true);
    for (const [index, angle2] of angles.entries()) {
      const x = axisOuterRadius * Math.cos(angle2);
      const y = axisOuterRadius * Math.sin(angle2);
      if (index === 0) {
        path.moveTo(x, y);
      } else {
        path.lineTo(x, y);
      }
    }
    if (axisInnerRadius === 0) {
      path.lineTo(0, 0);
    } else {
      const reversedAngles = angles.slice().reverse();
      for (const angle2 of reversedAngles) {
        const x = axisInnerRadius * Math.cos(angle2);
        const y = axisInnerRadius * Math.sin(angle2);
        path.lineTo(x, y);
      }
    }
    polygon.path.closePath();
    this.assignCrossLineGroup(true, this.crossLineRange);
  }
  updateSectorNode(visible) {
    const { sectorNode: sector, range: range3, scale: scale2, shape, type } = this;
    if (!visible || type !== "range" || shape !== "circle" || !scale2 || !range3) {
      sector.visible = false;
      return;
    }
    const { axisInnerRadius, axisOuterRadius } = this;
    const angles = range3.map((value) => scale2.convert(value));
    const step = scale2.step ?? 0;
    const padding2 = scale2 instanceof module_support_exports.BandScale ? step / 2 : 0;
    sector.visible = true;
    this.setSectorNodeProps(sector);
    sector.centerX = 0;
    sector.centerY = 0;
    sector.innerRadius = axisInnerRadius;
    sector.outerRadius = axisOuterRadius;
    sector.startAngle = angles[0] - padding2;
    sector.endAngle = angles[1] + padding2;
    this.assignCrossLineGroup(true, this.crossLineRange);
  }
  updateLabelNode(visible) {
    const { label, labelNode: node, range: range3, scale: scale2, type, ticks } = this;
    if (!visible || label.enabled === false || !label.text || !scale2 || type === "range" && !range3) {
      node.visible = false;
      return;
    }
    node.visible = true;
    const { axisInnerRadius, axisOuterRadius } = this;
    let labelX;
    let labelY;
    let rotation;
    let textBaseline;
    if (type === "line") {
      const angle2 = normalizeAngle360(scale2.convert(this.value));
      const angle270 = 1.5 * Math.PI;
      const isRightSide = isNumberEqual(angle2, angle270) || angle2 > angle270 || angle2 < Math.PI / 2;
      const midX = (axisInnerRadius + axisOuterRadius) / 2 * Math.cos(angle2);
      const midY = (axisInnerRadius + axisOuterRadius) / 2 * Math.sin(angle2);
      labelX = midX + label.padding * Math.cos(angle2 + Math.PI / 2);
      labelY = midY + label.padding * Math.sin(angle2 + Math.PI / 2);
      textBaseline = isRightSide ? "top" : "bottom";
      rotation = isRightSide ? angle2 : angle2 - Math.PI;
    } else {
      const [startAngle, endAngle] = range3.map((value) => normalizeAngle360(scale2.convert(value)));
      let angle2 = (startAngle + endAngle) / 2;
      if (startAngle > endAngle) {
        angle2 -= Math.PI;
      }
      angle2 = normalizeAngle360(angle2);
      const isBottomSide = (isNumberEqual(angle2, 0) || angle2 > 0) && angle2 < Math.PI;
      let distance2;
      if (this.shape === "circle" || ticks.length < 3) {
        distance2 = axisOuterRadius - label.padding;
      } else {
        distance2 = axisOuterRadius * Math.cos(Math.PI / ticks.length) - label.padding;
      }
      labelX = distance2 * Math.cos(angle2);
      labelY = distance2 * Math.sin(angle2);
      textBaseline = isBottomSide ? "bottom" : "top";
      rotation = isBottomSide ? angle2 - Math.PI / 2 : angle2 + Math.PI / 2;
    }
    this.setLabelNodeProps(node, labelX, labelY, textBaseline, rotation);
  }
};
AngleCrossLine.className = "AngleCrossLine";

// packages/ag-charts-enterprise/src/axes/angle/angleAxis.ts
var { Path: Path10, RotatableText: RotatableText3, Transformable: Transformable6, BBox: BBox27, Selection: Selection11, Line: Line5 } = module_support_exports;
var AngleAxisLabel = class extends module_support_exports.AxisLabel {
  constructor() {
    super(...arguments);
    this.orientation = "fixed";
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], AngleAxisLabel.prototype, "orientation", 2);
var AngleAxis = class extends module_support_exports.PolarAxis {
  constructor(moduleCtx, scale2) {
    super(moduleCtx, scale2);
    this.startAngle = 0;
    this.endAngle = void 0;
    this.tickLineGroupSelection = Selection11.select(
      this.tickLineGroup,
      Line5,
      false
    );
    this.gridLineGroupSelection = Selection11.select(
      this.gridLineGroup,
      Line5,
      false
    );
    this.labelData = [];
    this.tickData = [];
    this.radiusLineGroup = this.axisGroup.appendChild(new module_support_exports.TransformableGroup());
    this.radiusLine = this.radiusLineGroup.appendChild(new Path10());
    this.includeInvisibleDomains = true;
  }
  get direction() {
    return "angle" /* Angle */;
  }
  createLabel() {
    return new AngleAxisLabel();
  }
  calculateRotations() {
    const rotation = toRadians(this.startAngle);
    const parallelFlipRotation = normalizeAngle360(rotation);
    const regularFlipRotation = normalizeAngle360(rotation - Math.PI / 2);
    return { rotation, parallelFlipRotation, regularFlipRotation };
  }
  calculateTickLayout(domain) {
    const { nice, scale: scale2 } = this;
    const ticksParams = {
      nice: [nice, nice],
      interval: void 0,
      tickCount: void 0,
      minTickCount: 0,
      maxTickCount: Infinity
    };
    const niceDomain = nice ? scale2.niceDomain(ticksParams, domain) : domain;
    const tickData = this.generateAngleTicks(niceDomain);
    this.tickData = tickData;
    const ticks = tickData.map((t) => t.value);
    const fractionDigits = ticks.reduce(
      (f, t) => Math.max(typeof t === "number" ? countFractionDigits(t) : 0, f),
      0
    );
    return {
      niceDomain,
      tickDomain: niceDomain,
      ticks,
      rawTickCount: void 0,
      fractionDigits,
      timeInterval: void 0,
      bbox: this.getBBox()
    };
  }
  update() {
    super.update();
    this.updateRadiusLine();
    this.updateGridLines();
    this.updateTickLines();
  }
  normalizedAngles() {
    const startAngle = normalizeAngle360(-Math.PI / 2 + toRadians(this.startAngle));
    const sweep = this.endAngle == null ? 2 * Math.PI : normalizeAngle360Inclusive(toRadians(this.endAngle) - toRadians(this.startAngle));
    const endAngle = startAngle + sweep;
    return [startAngle, endAngle];
  }
  computeRange() {
    this.range = this.normalizedAngles();
  }
  updateSelections() {
    const data = this.tickData;
    this.gridLineGroupSelection.update(this.gridLength && this.gridLine.enabled ? data : []);
    this.tickLineGroupSelection.update(this.tick.enabled ? data : []);
    this.tickLabelGroupSelection.update(this.label.enabled ? data : []);
    this.gridLineGroupSelection.cleanup();
    this.tickLineGroupSelection.cleanup();
    this.tickLabelGroupSelection.cleanup();
  }
  updatePosition() {
    super.updatePosition();
    const { translation, radiusLineGroup } = this;
    const translationX = Math.floor(translation.x);
    const translationY = Math.floor(translation.y);
    radiusLineGroup.translationX = translationX;
    radiusLineGroup.translationY = translationY;
  }
  updateRadiusLine() {
    const node = this.radiusLine;
    const { path } = node;
    path.clear(true);
    const { points, closePath } = this.getAxisLinePoints();
    for (const { x, y, moveTo: moveTo2, arc, radius = 0, startAngle = 0, endAngle = 0 } of points) {
      if (arc) {
        path.arc(x, y, radius, startAngle, endAngle);
      } else if (moveTo2) {
        path.moveTo(x, y);
      } else {
        path.lineTo(x, y);
      }
    }
    if (closePath) {
      path.closePath();
    }
    node.visible = this.line.enabled;
    node.stroke = this.line.stroke;
    node.strokeWidth = this.line.width;
    node.fill = void 0;
  }
  getAxisLinePoints() {
    const { scale: scale2, shape, gridLength: radius } = this;
    const [startAngle, endAngle] = this.range;
    const isFullCircle = isNumberEqual(endAngle - startAngle, 2 * Math.PI);
    const points = [];
    if (shape === "circle") {
      if (isFullCircle) {
        points.push(
          { x: radius, y: 0, moveTo: true },
          {
            x: 0,
            y: 0,
            radius,
            startAngle: 0,
            endAngle: 2 * Math.PI,
            arc: true,
            moveTo: false
          }
        );
      } else {
        points.push(
          {
            x: radius * Math.cos(startAngle),
            y: radius * Math.sin(startAngle),
            moveTo: true
          },
          {
            x: 0,
            y: 0,
            radius,
            startAngle: normalizeAngle360(startAngle),
            endAngle: normalizeAngle360(endAngle),
            arc: true,
            moveTo: false
          }
        );
      }
    } else if (shape === "polygon") {
      const angles = scale2.ticks({
        nice: [this.nice, this.nice],
        interval: void 0,
        tickCount: void 0,
        minTickCount: 0,
        maxTickCount: Infinity
      })?.ticks?.map((value) => scale2.convert(value));
      if (angles && angles.length > 2) {
        for (const [i, angle2] of angles.entries()) {
          const x = radius * Math.cos(angle2);
          const y = radius * Math.sin(angle2);
          const moveTo2 = i === 0;
          points.push({ x, y, moveTo: moveTo2 });
        }
      }
    }
    return { points, closePath: isFullCircle };
  }
  updateGridLines() {
    const {
      scale: scale2,
      gridLength: radius,
      gridLine: { style: style2, width: width2 },
      innerRadiusRatio
    } = this;
    if (!(style2 && radius > 0)) {
      return;
    }
    const innerRadius = radius * innerRadiusRatio;
    const styleCount = style2.length;
    this.gridLineGroupSelection.each((line, datum, index) => {
      const { value } = datum;
      const { stroke: stroke3, lineDash } = style2[index % styleCount];
      const angle2 = scale2.convert(value);
      line.x1 = innerRadius * Math.cos(angle2);
      line.y1 = innerRadius * Math.sin(angle2);
      line.x2 = radius * Math.cos(angle2);
      line.y2 = radius * Math.sin(angle2);
      line.stroke = stroke3;
      line.strokeWidth = width2;
      line.lineDash = lineDash;
      line.fill = void 0;
    });
    this.gridLineGroupSelection.cleanup();
  }
  updateLabels() {
    const { label, tickLabelGroupSelection } = this;
    tickLabelGroupSelection.each((node, _, index) => {
      const labelDatum = this.labelData[index];
      if (!labelDatum || labelDatum.hidden) {
        node.visible = false;
        return;
      }
      node.text = labelDatum.text;
      node.setFont(label);
      node.fill = label.color;
      node.x = labelDatum.x;
      node.y = labelDatum.y;
      node.setAlign(labelDatum);
      node.setBoxing(label);
      node.visible = true;
      if (labelDatum.rotation) {
        node.rotation = labelDatum.rotation;
        node.rotationCenterX = labelDatum.x;
        node.rotationCenterY = labelDatum.y;
      } else {
        node.rotation = 0;
      }
    });
  }
  updateTickLines() {
    const { scale: scale2, gridLength: radius, tick, tickLineGroupSelection } = this;
    tickLineGroupSelection.each((line, datum) => {
      const { value } = datum;
      const angle2 = scale2.convert(value);
      const cos = Math.cos(angle2);
      const sin = Math.sin(angle2);
      line.x1 = radius * cos;
      line.y1 = radius * sin;
      line.x2 = (radius + tick.size) * cos;
      line.y2 = (radius + tick.size) * sin;
      line.stroke = tick.stroke;
      line.strokeWidth = tick.width;
    });
  }
  createLabelNodeData(ticks, options, seriesRect) {
    const { label, gridLength: radius, scale: scale2, tick } = this;
    if (!label.enabled) {
      return [];
    }
    const tempText = new RotatableText3();
    const seriesLeft = seriesRect.x - this.translation.x;
    const seriesRight = seriesRect.x + seriesRect.width - this.translation.x;
    const { fractionDigits } = this.layout.label;
    const axisTickFormatter2 = this.tickFormatter(this.scale.domain, this.tickData, false, fractionDigits);
    const labelData = ticks.map((datum, index) => {
      const { value } = datum;
      const distance2 = radius + label.spacing + tick.size;
      const angle2 = scale2.convert(value);
      const cos = Math.cos(angle2);
      const sin = Math.sin(angle2);
      const x = distance2 * cos;
      const y = distance2 * sin;
      const { textAlign, textBaseline } = this.getLabelAlign(angle2);
      const isLastTickOverFirst = index === ticks.length - 1 && value !== ticks[0] && isNumberEqual(normalizeAngle360(angle2), normalizeAngle360(scale2.convert(ticks[0])));
      const rotation = this.getLabelRotation(angle2);
      let text2 = axisTickFormatter2(value, index);
      tempText.text = text2;
      tempText.x = x;
      tempText.y = y;
      tempText.setFont(label);
      tempText.textAlign = textAlign;
      tempText.textBaseline = textBaseline;
      tempText.rotation = rotation;
      if (rotation) {
        tempText.rotationCenterX = x;
        tempText.rotationCenterY = y;
      }
      let box = rotation ? Transformable6.toCanvas(tempText) : tempText.getBBox();
      if (box && options.hideWhenNecessary && !rotation) {
        const overflowLeft = seriesLeft - box.x;
        const overflowRight = box.x + box.width - seriesRight;
        const pixelError = 1;
        if (overflowLeft > pixelError || overflowRight > pixelError) {
          const availWidth = box.width - Math.max(overflowLeft, overflowRight);
          const wrapOptions = { maxWidth: availWidth, font: label, textWrap: "never" };
          text2 = wrapTextOrSegments(text2, wrapOptions);
          tempText.text = text2;
          box = tempText.getBBox();
        }
      }
      return {
        text: text2,
        x,
        y,
        textAlign,
        textBaseline,
        hidden: text2 === "" || (datum.hidden ?? isLastTickOverFirst),
        rotation,
        box
      };
    });
    if (label.avoidCollisions) {
      this.avoidLabelCollisions(labelData);
    }
    return labelData;
  }
  computeLabelsBBox(options, seriesRect) {
    this.labelData = this.createLabelNodeData(this.tickData, options, seriesRect);
    const textBoxes = this.labelData.map(({ box }) => box).filter((box) => box != null);
    if (!this.label.enabled || textBoxes.length === 0) {
      return null;
    }
    return BBox27.merge(textBoxes);
  }
  getLabelOrientation() {
    const { label } = this;
    return label instanceof AngleAxisLabel ? label.orientation : "fixed";
  }
  getLabelRotation(tickAngle) {
    let rotation = toRadians(this.label.rotation ?? 0);
    tickAngle = normalizeAngle360(tickAngle);
    const orientation = this.getLabelOrientation();
    if (orientation === "parallel") {
      rotation += tickAngle;
      if (tickAngle >= 0 && tickAngle < Math.PI) {
        rotation -= Math.PI / 2;
      } else {
        rotation += Math.PI / 2;
      }
    } else if (orientation === "perpendicular") {
      rotation += tickAngle;
      if (tickAngle >= Math.PI / 2 && tickAngle < 1.5 * Math.PI) {
        rotation += Math.PI;
      }
    }
    return rotation;
  }
  getLabelAlign(tickAngle) {
    const cos = Math.cos(tickAngle);
    const sin = Math.sin(tickAngle);
    let textAlign;
    let textBaseline;
    const orientation = this.getLabelOrientation();
    const isCos0 = isNumberEqual(cos, 0);
    const isSin0 = isNumberEqual(sin, 0);
    const isCos1 = isNumberEqual(cos, 1);
    const isSinMinus1 = isNumberEqual(sin, -1);
    const isCosPositive = cos > 0 && !isCos0;
    const isSinPositive = sin > 0 && !isSin0;
    if (orientation === "parallel") {
      textAlign = "center";
      textBaseline = isCos1 && isSin0 || isSinPositive ? "top" : "bottom";
    } else if (orientation === "perpendicular") {
      textAlign = isSinMinus1 || isCosPositive ? "left" : "right";
      textBaseline = "middle";
    } else {
      textAlign = "right";
      if (isCos0) {
        textAlign = "center";
      } else if (isCosPositive) {
        textAlign = "left";
      }
      textBaseline = "bottom";
      if (isSin0) {
        textBaseline = "middle";
      } else if (isSinPositive) {
        textBaseline = "top";
      }
    }
    return { textAlign, textBaseline };
  }
  updateCrossLines() {
    const { shape, gridLength: radius, innerRadiusRatio } = this;
    for (const crossLine of this.crossLines) {
      if (crossLine instanceof AngleCrossLine) {
        crossLine.ticks = this.tickData.map((t) => t.value);
        crossLine.shape = shape;
        crossLine.axisOuterRadius = radius;
        crossLine.axisInnerRadius = radius * innerRadiusRatio;
      }
    }
    super.updateCrossLines();
  }
};
AngleAxis.CrossLineConstructor = AngleCrossLine;
__decorateClass([
  addFakeTransformToInstanceProperty
], AngleAxis.prototype, "startAngle", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AngleAxis.prototype, "endAngle", 2);

// packages/ag-charts-enterprise/src/axes/angle-category/angleCategoryAxis.ts
var { CategoryScale: CategoryScale2 } = module_support_exports;
var AngleCategoryAxis = class extends AngleAxis {
  constructor(moduleCtx) {
    super(moduleCtx, new CategoryScale2());
    this.groupPaddingInner = 0;
    this.paddingInner = 0;
    this.interval = new AngleAxisInterval();
  }
  hasDefinedDomain() {
    return false;
  }
  generateAngleTicks(domain) {
    const { scale: scale2, gridLength: radius } = this;
    const { values, minSpacing } = this.interval;
    const tickParams = {
      nice: [this.nice, this.nice],
      interval: void 0,
      tickCount: void 0,
      minTickCount: 0,
      maxTickCount: Infinity
    };
    const ticks = values ?? scale2.ticks(tickParams, domain)?.ticks ?? [];
    if (ticks.length < 2 || minSpacing == null) {
      return ticks.map((value) => {
        return { value, visible: true };
      });
    }
    const startTick = ticks[0];
    const startAngle = scale2.convert(startTick);
    const startX = radius * Math.cos(startAngle);
    const startY = radius * Math.sin(startAngle);
    for (let step = 1; step < ticks.length - 1; step++) {
      const nextTick = ticks[step];
      const nextAngle = scale2.convert(nextTick);
      if (nextAngle - startAngle > Math.PI) {
        break;
      }
      const nextX = radius * Math.cos(nextAngle);
      const nextY = radius * Math.sin(nextAngle);
      const spacing = Math.hypot(nextX - startX, nextY - startY);
      if (spacing > minSpacing) {
        const visibleTicks = /* @__PURE__ */ new Set([startTick]);
        walkPairsOutward(ticks, step, (_, next) => {
          visibleTicks.add(next);
        });
        return ticks.map((value) => {
          const visible = visibleTicks.has(value);
          return { value, visible };
        });
      }
    }
    return [{ value: startTick, visible: true }];
  }
  avoidLabelCollisions(labelData) {
    const { minSpacing } = this.label;
    if (labelData.length < 3)
      return;
    const labelsCollide = (prev, next) => {
      if (prev.hidden || next.hidden) {
        return false;
      } else if (minSpacing == null) {
        return prev.box.collidesBBox(next.box);
      }
      const prevBox = prev.box.clone().grow(minSpacing / 2);
      const nextBox = next.box.clone().grow(minSpacing / 2);
      return prevBox.collidesBBox(nextBox);
    };
    const firstLabel = labelData[0];
    const lastLabel = labelData.at(-1);
    const visibleLabels = /* @__PURE__ */ new Set([firstLabel]);
    const lastLabelIsOverFirst = isNumberEqual(firstLabel.x, lastLabel.x) && isNumberEqual(firstLabel.y, lastLabel.y);
    const maxStep = Math.floor(labelData.length / 2);
    for (let step = 1; step <= maxStep; step++) {
      const labels = lastLabelIsOverFirst ? labelData.slice(0, -1) : labelData;
      const collisionDetected = walkPairsOutward(labels, step, labelsCollide);
      if (!collisionDetected) {
        walkPairsOutward(labels, step, (_, next) => {
          visibleLabels.add(next);
        });
        break;
      }
    }
    for (const datum of labelData) {
      if (!visibleLabels.has(datum)) {
        datum.hidden = true;
        datum.box = void 0;
      }
    }
  }
  tickFormatParams() {
    return { type: "category" };
  }
  datumFormatParams(value, params) {
    const { datum, seriesId, legendItemName, key, source, property, domain, boundSeries } = params;
    return { type: "category", value, datum, seriesId, legendItemName, key, source, property, domain, boundSeries };
  }
};
AngleCategoryAxis.className = "AngleCategoryAxis";
AngleCategoryAxis.type = "angle-category";
__decorateClass([
  addFakeTransformToInstanceProperty
], AngleCategoryAxis.prototype, "groupPaddingInner", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AngleCategoryAxis.prototype, "paddingInner", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AngleCategoryAxis.prototype, "interval", 2);

// packages/ag-charts-enterprise/src/axes/angle-category/angleCategoryAxisModule.ts
var AngleCategoryAxisModule = {
  type: "axis",
  name: "angle-category",
  chartType: "polar",
  enterprise: true,
  version: VERSION,
  options: module_support_exports.angleCategoryAxisOptionsDefs,
  themeTemplate: {
    label: { spacing: 5 },
    gridLine: { enabled: false },
    shape: { $findFirstSiblingNotOperation: void 0 }
  },
  create: (ctx) => new AngleCategoryAxis(ctx)
};

// packages/ag-charts-enterprise/src/axes/angle-number/angleNumberAxis.ts
var AngleNumberAxis = class extends AngleAxis {
  constructor(moduleCtx) {
    super(moduleCtx, new LinearAngleScale());
    this.shape = "circle";
    this.interval = new AngleAxisInterval();
  }
  hasDefinedDomain() {
    const { min, max } = this;
    return min != null && max != null && min < max;
  }
  normaliseDataDomain(d) {
    const { min, max, preferredMin, preferredMax } = this;
    const { extent: extent2, clipped } = normalisedExtentWithMetadata(
      d.domain,
      min,
      max,
      preferredMin,
      preferredMax,
      void 0,
      d.sortMetadata?.sortOrder
    );
    return { domain: extent2, clipped };
  }
  getDomainExtentsNice() {
    return [this.min == null && this.nice, this.max == null && this.nice];
  }
  updateScale() {
    super.updateScale();
    this.scale.arcLength = this.getRangeArcLength();
  }
  getRangeArcLength() {
    const { range: requestedRange } = this;
    const min = Math.min(...requestedRange);
    const max = Math.max(...requestedRange);
    const rotation = angleBetween(min, max) || 2 * Math.PI;
    const radius = this.gridLength;
    return rotation * radius;
  }
  generateAngleTicks(domain) {
    const { scale: scale2, range: requestedRange, nice } = this;
    const { values, step, minSpacing, maxSpacing } = this.interval;
    let rawTicks;
    if (values == null) {
      const { arcLength } = scale2;
      const minTickCount = maxSpacing ? Math.floor(arcLength / maxSpacing) : 1;
      const maxTickCount = minSpacing ? Math.floor(arcLength / minSpacing) : Infinity;
      const preferredTickCount = Math.floor(4 / Math.PI * Math.abs(requestedRange[0] - requestedRange[1]));
      const tickCount = Math.max(minTickCount, Math.min(maxTickCount, preferredTickCount));
      const tickParams = {
        nice: [nice, nice],
        interval: step,
        tickCount,
        minTickCount,
        maxTickCount
      };
      rawTicks = scale2.ticks(tickParams, domain)?.ticks ?? [];
    } else {
      const [d0, d1] = findMinMax(domain.map(Number));
      rawTicks = values.filter((value) => value >= d0 && value <= d1).sort((a, b) => a - b);
    }
    return rawTicks.map((value) => ({ value, visible: true }));
  }
  avoidLabelCollisions(labelData) {
    const { minSpacing } = this.label;
    const labelsCollide = (prev, next) => {
      if (prev.hidden || next.hidden) {
        return false;
      } else if (minSpacing == null) {
        return prev.box.collidesBBox(next.box);
      }
      const prevBox = prev.box.clone().grow(minSpacing / 2);
      const nextBox = next.box.clone().grow(minSpacing / 2);
      return prevBox.collidesBBox(nextBox);
    };
    const firstLabel = labelData[0];
    const lastLabel = labelData.at(-1);
    if (firstLabel !== lastLabel && isNumberEqual(firstLabel.x, lastLabel.x) && isNumberEqual(firstLabel.y, lastLabel.y)) {
      lastLabel.hidden = true;
    }
    for (let step = 1; step < labelData.length; step *= 2) {
      let collisionDetected = false;
      for (let i = step; i < labelData.length; i += step) {
        const next = labelData[i];
        const prev = labelData[i - step];
        if (labelsCollide(prev, next)) {
          collisionDetected = true;
          break;
        }
      }
      if (!collisionDetected) {
        for (const [i, datum] of labelData.entries()) {
          if (i % step > 0) {
            datum.hidden = true;
            datum.box = void 0;
          }
        }
        return;
      }
    }
    for (const [i, datum] of labelData.entries()) {
      if (i > 0) {
        datum.hidden = true;
        datum.box = void 0;
      }
    }
  }
  tickFormatParams(_domain, _ticks, fractionDigits) {
    return { type: "number", visibleDomain: void 0, fractionDigits };
  }
  datumFormatParams(value, params, fractionDigits) {
    const { datum, seriesId, legendItemName, key, source, property, domain, boundSeries } = params;
    return {
      type: "number",
      value,
      datum,
      seriesId,
      legendItemName,
      key,
      source,
      property,
      domain,
      boundSeries,
      fractionDigits,
      visibleDomain: void 0
    };
  }
};
AngleNumberAxis.className = "AngleNumberAxis";
AngleNumberAxis.type = "angle-number";
__decorateClass([
  addFakeTransformToInstanceProperty
], AngleNumberAxis.prototype, "min", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AngleNumberAxis.prototype, "max", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AngleNumberAxis.prototype, "preferredMin", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AngleNumberAxis.prototype, "preferredMax", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], AngleNumberAxis.prototype, "interval", 2);

// packages/ag-charts-enterprise/src/axes/angle-number/angleNumberAxisModule.ts
var AngleNumberAxisModule = {
  type: "axis",
  name: "angle-number",
  chartType: "polar",
  enterprise: true,
  version: VERSION,
  options: module_support_exports.angleNumberAxisOptionsDefs,
  themeTemplate: {
    label: { spacing: 5 },
    gridLine: { enabled: false }
  },
  create: (ctx) => new AngleNumberAxis(ctx)
};

// packages/ag-charts-enterprise/src/axes/polar-crosslines/radiusCrossLine.ts
var { validateCrossLineValue: validateCrossLineValue3, Group: Group18, Path: Path11, Sector: Sector6, RotatableText: RotatableText4 } = module_support_exports;
var RadiusCrossLineLabel = class extends PolarCrossLineLabel {
  constructor() {
    super(...arguments);
    this.positionAngle = void 0;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RadiusCrossLineLabel.prototype, "positionAngle", 2);
var RadiusCrossLine = class extends PolarCrossLine {
  constructor() {
    super();
    this.direction = "radius" /* Radius */;
    this.label = new RadiusCrossLineLabel();
    this.polygonNode = new Path11();
    this.sectorNode = new Sector6();
    this.crossLineRange = new Group18();
    this.labelNode = new RotatableText4();
    this.outerRadius = 0;
    this.innerRadius = 0;
    this.crossLineRange.append(this.polygonNode);
    this.crossLineRange.append(this.sectorNode);
    this.labelGroup.append(this.labelNode);
  }
  update(visible) {
    const { scale: scale2 } = this;
    if (!scale2 || !validateCrossLineValue3(this, scale2)) {
      this.rangeGroup.visible = false;
      this.lineGroup.visible = false;
      this.labelGroup.visible = false;
      return;
    }
    this.updateRadii();
    const { innerRadius, outerRadius } = this;
    visible && (visible = innerRadius >= this.axisInnerRadius && outerRadius <= this.axisOuterRadius);
    this.rangeGroup.visible = visible;
    this.lineGroup.visible = visible;
    this.labelGroup.visible = visible;
    this.updatePolygonNode(visible);
    this.updateSectorNode(visible);
    this.updateLabelNode(visible);
    this.assignCrossLineGroup(this.type === "range", this.crossLineRange);
  }
  updateRadii() {
    const { range: range3, scale: scale2, type, axisInnerRadius, axisOuterRadius } = this;
    if (!scale2)
      return { innerRadius: 0, outerRadius: 0 };
    const getRadius = (value) => axisOuterRadius + axisInnerRadius - value;
    let outerRadius, innerRadius;
    if (type === "line") {
      outerRadius = getRadius(scale2.convert(this.value));
      innerRadius = outerRadius;
    } else {
      const bandwidth = Math.abs(scale2?.bandwidth ?? 0);
      const convertedRange = range3.map((r) => scale2.convert(r));
      outerRadius = getRadius(Math.max(...convertedRange));
      innerRadius = getRadius(Math.min(...convertedRange)) + bandwidth;
    }
    this.outerRadius = outerRadius;
    this.innerRadius = innerRadius;
  }
  drawPolygon(radius, angles, polygon) {
    for (const [index, angle2] of angles.entries()) {
      const x = radius * Math.cos(angle2);
      const y = radius * Math.sin(angle2);
      if (index === 0) {
        polygon.path.moveTo(x, y);
      } else {
        polygon.path.lineTo(x, y);
      }
    }
    polygon.path.closePath();
  }
  updatePolygonNode(visible) {
    const { gridAngles, polygonNode: polygon, scale: scale2, shape, type, innerRadius, outerRadius } = this;
    if (!visible || shape !== "polygon" || !scale2 || !gridAngles) {
      polygon.visible = false;
      return;
    }
    polygon.visible = true;
    const padding2 = this.getPadding();
    polygon.path.clear(true);
    this.drawPolygon(outerRadius - padding2, gridAngles, polygon);
    const reversedAngles = gridAngles.slice().reverse();
    const innerPolygonRadius = type === "line" ? outerRadius - padding2 : innerRadius + padding2;
    this.drawPolygon(innerPolygonRadius, reversedAngles, polygon);
    this.setSectorNodeProps(polygon);
  }
  updateSectorNode(visible) {
    const { axisInnerRadius, axisOuterRadius, scale: scale2, sectorNode: sector, shape, innerRadius, outerRadius } = this;
    if (!visible || shape !== "circle" || !scale2) {
      sector.visible = false;
      return;
    }
    sector.visible = true;
    sector.startAngle = 0;
    sector.endAngle = 2 * Math.PI;
    const padding2 = this.getPadding();
    const r0 = clamp(axisInnerRadius, innerRadius + padding2, axisOuterRadius);
    const r1 = clamp(axisInnerRadius, outerRadius - padding2, axisOuterRadius);
    sector.innerRadius = Math.min(r0, r1);
    sector.outerRadius = Math.max(r0, r1);
    this.setSectorNodeProps(sector);
  }
  updateLabelNode(visible) {
    const { innerRadius, label, labelNode: node, scale: scale2, shape, type } = this;
    if (!visible || label.enabled === false || !label.text || !scale2) {
      node.visible = false;
      return;
    }
    const angle2 = normalizeAngle360FromDegrees((label.positionAngle ?? 0) - 90);
    const isBottomSide = (isNumberEqual(angle2, 0) || angle2 > 0) && angle2 < Math.PI;
    const rotation = isBottomSide ? angle2 - Math.PI / 2 : angle2 + Math.PI / 2;
    let distance2;
    const angles = this.gridAngles ?? [];
    if (type === "line") {
      distance2 = innerRadius + label.padding;
    } else if (shape === "circle" || angles.length < 3) {
      distance2 = innerRadius - label.padding;
    } else {
      distance2 = innerRadius * Math.cos(Math.PI / angles.length) - label.padding;
    }
    const labelX = distance2 * Math.cos(angle2);
    const labelY = distance2 * Math.sin(angle2);
    let textBaseline;
    if (type === "line") {
      textBaseline = isBottomSide ? "top" : "bottom";
    } else {
      textBaseline = isBottomSide ? "bottom" : "top";
    }
    this.setLabelNodeProps(node, labelX, labelY, textBaseline, rotation);
  }
  getPadding() {
    const { scale: scale2 } = this;
    if (!scale2)
      return 0;
    const bandwidth = Math.abs(scale2.bandwidth ?? 0);
    const step = Math.abs(scale2.step ?? 0);
    return scale2 instanceof module_support_exports.BandScale ? (step - bandwidth) / 2 : 0;
  }
};
RadiusCrossLine.className = "RadiusCrossLine";

// packages/ag-charts-enterprise/src/axes/radius/radiusAxis.ts
var { Caption: Caption2, Group: Group19, TransformableGroup: TransformableGroup2, Path: Path12, Line: Line6, Selection: Selection12, generateTicks: generateTicks3, AxisGroupZIndexMap: AxisGroupZIndexMap2 } = module_support_exports;
var RadiusAxisLabel = class extends module_support_exports.AxisLabel {
  constructor() {
    super(...arguments);
    this.autoRotateAngle = 335;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RadiusAxisLabel.prototype, "autoRotate", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadiusAxisLabel.prototype, "autoRotateAngle", 2);
var RadiusAxis = class extends module_support_exports.PolarAxis {
  constructor(moduleCtx, scale2) {
    super(moduleCtx, scale2);
    this.positionAngle = 0;
    this.gridLineGroupSelection = Selection12.select(
      this.gridLineGroup,
      Line6,
      false
    );
    this.generatedTicks = void 0;
    this.headingLabelGroup = this.axisGroup.appendChild(
      new TransformableGroup2({ name: `${this.id}-Axis-heading` })
    );
    this.lineNodeGroup = this.axisGroup.appendChild(
      new TransformableGroup2({ name: `${this.id}-Axis-line` })
    );
    this.lineNode = this.lineNodeGroup.appendChild(
      new Line6({
        name: `${this.id}-Axis-line`,
        zIndex: AxisGroupZIndexMap2.AxisLine
      })
    );
    this.gridPathGroup = this.gridGroup.appendChild(
      new Group19({
        name: `${this.id}-gridPaths`,
        zIndex: 2 /* AXIS_GRID */
      })
    );
    this.gridPathSelection = Selection12.select(this.gridPathGroup, Path12);
    this.headingLabelGroup.appendChild(this.title.caption.node);
    this.cleanup.register(this.title.caption.registerInteraction(this.moduleCtx, "afterend"));
  }
  get direction() {
    return "radius" /* Radius */;
  }
  getAxisTransform() {
    const maxRadius = this.scale.range[0];
    const { translation, positionAngle, innerRadiusRatio } = this;
    const innerRadius = maxRadius * innerRadiusRatio;
    const rotation = toRadians(positionAngle);
    return {
      translationX: translation.x,
      translationY: translation.y - maxRadius - innerRadius,
      rotation,
      rotationCenterX: 0,
      rotationCenterY: maxRadius + innerRadius
    };
  }
  update() {
    super.update();
    this.updateTitle();
    this.updateGridLines();
    const { enabled, stroke: stroke3, width: width2 } = this.line;
    this.lineNode.setProperties({
      stroke: stroke3,
      strokeWidth: enabled ? width2 : 0,
      x1: 0,
      y1: this.range[0],
      x2: 0,
      y2: this.range[1]
    });
  }
  updatePosition() {
    super.updatePosition();
    const axisTransform = this.getAxisTransform();
    this.tickLineGroup.setProperties(axisTransform);
    this.tickLabelGroup.setProperties(axisTransform);
    this.lineNodeGroup.setProperties(axisTransform);
    this.headingLabelGroup.setProperties(axisTransform);
  }
  calculateRotations() {
    const rotation = 0;
    const parallelFlipRotation = 0;
    const regularFlipRotation = -Math.PI / 2;
    return { rotation, parallelFlipRotation, regularFlipRotation };
  }
  calculateTickLayout(domain, niceMode, _visibleRange) {
    const visibleRange = [0, 1];
    const sideFlag = this.label.getSideFlag();
    const labelX = sideFlag * (this.getTickSize() + this.label.spacing + this.seriesAreaPadding);
    const { range: range3, reverse, defaultTickMinSpacing } = this;
    const tickGenerationResult = generateTicks3({
      scale: this.scale,
      label: this.label,
      interval: this.interval,
      tickFormatter: (...args) => this.tickFormatter(...args),
      domain,
      range: range3,
      reverse,
      niceMode,
      visibleRange,
      defaultTickMinSpacing,
      labelOffset: labelX,
      sideFlag,
      axisRotation: 0,
      sizeLimit: void 0,
      primaryTickCount: void 0
    });
    const { tickData } = tickGenerationResult;
    const { ticks, rawTicks, rawTickCount, tickDomain, fractionDigits, niceDomain = domain } = tickData;
    const labels = ticks.map((d) => this.getTickLabelProps(d, tickGenerationResult));
    this.generatedTicks = { ticks, labels };
    return { ticks: rawTicks, tickDomain, niceDomain, rawTickCount, fractionDigits, timeInterval: void 0 };
  }
  updateSelections() {
    const { generatedTicks } = this;
    if (!generatedTicks)
      return;
    const { ticks, labels } = generatedTicks;
    this.gridLineGroupSelection.update(this.gridLength ? ticks : []);
    this.tickLabelGroupSelection.update(labels);
    this.gridPathSelection.update(this.gridLine.enabled ? this.prepareGridPathTickData(ticks) : []);
    this.gridLineGroupSelection.cleanup();
    this.tickLabelGroupSelection.cleanup();
    this.gridPathSelection.cleanup();
  }
  // TODO - abstract out
  updateLabels() {
    if (!this.label.enabled)
      return;
    const axisLabelPositionFn = module_support_exports.resetAxisLabelSelectionFn();
    this.tickLabelGroupSelection.each((node, datum) => {
      node.fill = datum.color;
      node.text = datum.text;
      node.textBaseline = datum.textBaseline;
      node.textAlign = datum.textAlign ?? "center";
      node.setFont(datum);
      node.setBoxing(datum);
      node.setProperties(axisLabelPositionFn(node, datum));
    });
  }
  updateGridLines() {
    const {
      gridLine: { style: style2, width: width2 },
      shape,
      generatedTicks
    } = this;
    if (!style2 || !generatedTicks) {
      return;
    }
    const styleCount = style2.length;
    const setStyle = (node, index) => {
      const { stroke: stroke3, lineDash } = style2[index % styleCount];
      node.stroke = stroke3;
      node.strokeWidth = width2;
      node.lineDash = lineDash;
      node.fill = void 0;
    };
    const [startAngle, endAngle] = this.gridRange ?? [0, 2 * Math.PI];
    const isFullCircle = isNumberEqual(endAngle - startAngle, 2 * Math.PI);
    const drawCircleShape = (node, value) => {
      const { path } = node;
      path.clear(true);
      const radius = this.getTickRadius(value);
      if (isFullCircle) {
        path.moveTo(radius, 0);
        path.arc(0, 0, radius, 0, 2 * Math.PI);
      } else {
        path.moveTo(radius * Math.cos(startAngle), radius * Math.sin(startAngle));
        path.arc(0, 0, radius, normalizeAngle360(startAngle), normalizeAngle360(endAngle));
      }
      if (isFullCircle) {
        path.closePath();
      }
    };
    const drawPolygonShape = (node, value) => {
      const { path } = node;
      const angles = this.gridAngles;
      path.clear(true);
      if (!angles || angles.length < 3) {
        return;
      }
      const radius = this.getTickRadius(value);
      for (const [idx, angle2] of angles.entries()) {
        const x = radius * Math.cos(angle2);
        const y = radius * Math.sin(angle2);
        if (idx === 0) {
          path.moveTo(x, y);
        } else {
          path.lineTo(x, y);
        }
        for (const [innerIdx, innerAngle] of angles.entries()) {
          const x2 = radius * Math.cos(innerAngle);
          const y2 = radius * Math.sin(innerAngle);
          if (innerIdx === 0) {
            path.moveTo(x2, y2);
          } else {
            path.lineTo(x2, y2);
          }
        }
        path.closePath();
      }
      path.closePath();
    };
    const drawFn = shape === "circle" ? drawCircleShape : drawPolygonShape;
    this.gridPathSelection.each((node, value, index) => {
      setStyle(node, index);
      drawFn(node, value);
    });
  }
  updateTitle() {
    const identityFormatter = (params) => params.defaultValue;
    const { title, range: requestedRange } = this;
    const { formatter: formatter2 = identityFormatter } = this.title;
    title.caption.enabled = title.enabled;
    title.caption.fontFamily = title.fontFamily;
    title.caption.fontSize = title.fontSize;
    title.caption.fontStyle = title.fontStyle;
    title.caption.fontWeight = title.fontWeight;
    title.caption.color = title.color;
    title.caption.wrapping = title.wrapping;
    let titleVisible = false;
    const titleNode = title.caption.node;
    if (title.enabled) {
      titleVisible = true;
      titleNode.rotation = Math.PI / 2;
      titleNode.x = Math.floor((requestedRange[0] + requestedRange[1]) / 2);
      titleNode.y = -Caption2.SMALL_PADDING;
      titleNode.textAlign = "center";
      titleNode.textBaseline = "bottom";
      titleNode.text = this.cachedCallWithContext(formatter2, this.getTitleFormatterParams(this.scale.domain));
    }
    titleNode.visible = titleVisible;
  }
  updateCrossLines() {
    for (const crossLine of this.crossLines) {
      if (crossLine instanceof RadiusCrossLine) {
        const { shape, gridAngles, range: range3, innerRadiusRatio } = this;
        const radius = range3[0];
        crossLine.shape = shape;
        crossLine.gridAngles = gridAngles;
        crossLine.axisOuterRadius = radius;
        crossLine.axisInnerRadius = radius * innerRadiusRatio;
      }
    }
    super.updateCrossLines();
  }
  createLabel() {
    return new RadiusAxisLabel();
  }
  // TODO - abstract out (shared with cartesian axis)
  getTickLabelProps(datum, tickGenerationResult) {
    const { label } = this;
    const { rotation, textBaseline, textAlign } = tickGenerationResult;
    const range3 = this.scale.range;
    const text2 = datum.tickLabel ?? "";
    const sideFlag = label.getSideFlag();
    const labelX = sideFlag * (this.getTickSize() + label.spacing + this.seriesAreaPadding);
    const visible = text2 !== "" && text2 != null;
    const combinedRotation = rotation;
    return {
      ...this.getLabelStyles({ value: datum.tick, formattedValue: datum.tickLabel }),
      tickId: datum.tickId,
      rotation: combinedRotation,
      text: text2,
      textAlign,
      textBaseline,
      visible,
      x: labelX,
      y: datum.translation,
      rotationCenterX: labelX,
      rotationCenterY: datum.translation,
      range: range3
    };
  }
};
RadiusAxis.CrossLineConstructor = RadiusCrossLine;
__decorateClass([
  addFakeTransformToInstanceProperty
], RadiusAxis.prototype, "positionAngle", 2);

// packages/ag-charts-enterprise/src/axes/radius-category/radiusCategoryAxis.ts
var { CategoryScale: CategoryScale3 } = module_support_exports;
var RadiusCategoryAxis = class extends RadiusAxis {
  constructor(moduleCtx) {
    super(moduleCtx, new CategoryScale3());
    this.shape = "circle";
    this.groupPaddingInner = 0;
    this.paddingInner = 0;
    this.paddingOuter = 0;
  }
  hasDefinedDomain() {
    return false;
  }
  normaliseDataDomain(d) {
    return { domain: d.domain, clipped: false };
  }
  prepareGridPathTickData(data) {
    return data.slice().reverse();
  }
  getTickRadius(tickDatum) {
    const { scale: scale2, innerRadiusRatio } = this;
    const maxRadius = scale2.range[0];
    const minRadius = maxRadius * innerRadiusRatio;
    if (CategoryScale3.is(scale2)) {
      const ticks = scale2.domain;
      const index = ticks.length - 1 - ticks.indexOf(tickDatum.tick);
      return index === 0 ? minRadius : scale2.inset + scale2.step * (index - 0.5) + scale2.bandwidth / 2;
    } else {
      const tickRange = (maxRadius - minRadius) / scale2.domain.length;
      return maxRadius - tickDatum.translation + minRadius - tickRange / 2;
    }
  }
  tickFormatParams() {
    return { type: "category" };
  }
  datumFormatParams(value, params) {
    const { datum, seriesId, legendItemName, key, source, property, domain, boundSeries } = params;
    return { type: "category", value, datum, seriesId, legendItemName, key, source, property, domain, boundSeries };
  }
};
RadiusCategoryAxis.className = "RadiusCategoryAxis";
RadiusCategoryAxis.type = "radius-category";
__decorateClass([
  addFakeTransformToInstanceProperty
], RadiusCategoryAxis.prototype, "groupPaddingInner", 2);
__decorateClass([
  ProxyPropertyOnWrite("scale", "paddingInner"),
  addFakeTransformToInstanceProperty
], RadiusCategoryAxis.prototype, "paddingInner", 2);
__decorateClass([
  ProxyPropertyOnWrite("scale", "paddingOuter"),
  addFakeTransformToInstanceProperty
], RadiusCategoryAxis.prototype, "paddingOuter", 2);

// packages/ag-charts-enterprise/src/axes/radius-category/radiusCategoryAxisModule.ts
var RadiusCategoryAxisModule = {
  type: "axis",
  name: "radius-category",
  chartType: "polar",
  enterprise: true,
  version: VERSION,
  options: module_support_exports.radiusCategoryAxisOptionsDefs,
  themeTemplate: {
    positionAngle: 0,
    line: { enabled: false },
    label: { minSpacing: 5 }
  },
  create: (ctx) => new RadiusCategoryAxis(ctx)
};

// packages/ag-charts-enterprise/src/axes/radius-number/radiusNumberAxis.ts
var { LinearScale: LinearScale5 } = module_support_exports;
var RadiusNumberAxis = class extends RadiusAxis {
  constructor(moduleCtx) {
    super(moduleCtx, new LinearScale5());
    this.shape = "polygon";
  }
  hasDefinedDomain() {
    const { min, max } = this;
    return min != null && max != null && min < max;
  }
  prepareGridPathTickData(data) {
    const { scale: scale2 } = this;
    const domainTop = scale2.domain[1];
    return data.filter(({ tick }) => tick !== domainTop).sort((a, b) => b.tick - a.tick);
  }
  getTickRadius(tickDatum) {
    const { scale: scale2 } = this;
    const maxRadius = scale2.range[0];
    const minRadius = maxRadius * this.innerRadiusRatio;
    return maxRadius - tickDatum.translation + minRadius;
  }
  normaliseDataDomain(d) {
    const { min, max, preferredMin, preferredMax } = this;
    const { extent: extent2, clipped } = normalisedExtentWithMetadata(
      d.domain,
      min,
      max,
      preferredMin,
      preferredMax,
      void 0,
      d.sortMetadata?.sortOrder
    );
    return { domain: extent2, clipped };
  }
  getDomainExtentsNice() {
    return [this.min == null && this.nice, this.max == null && this.nice];
  }
  tickFormatParams(_domain, _ticks, fractionDigits) {
    return { type: "number", visibleDomain: void 0, fractionDigits };
  }
  datumFormatParams(value, params, fractionDigits) {
    const { datum, seriesId, legendItemName, key, source, property, domain, boundSeries } = params;
    return {
      type: "number",
      value,
      datum,
      seriesId,
      legendItemName,
      key,
      source,
      property,
      domain,
      boundSeries,
      fractionDigits,
      visibleDomain: void 0
    };
  }
};
RadiusNumberAxis.className = "RadiusNumberAxis";
RadiusNumberAxis.type = "radius-number";
__decorateClass([
  addFakeTransformToInstanceProperty
], RadiusNumberAxis.prototype, "min", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadiusNumberAxis.prototype, "max", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadiusNumberAxis.prototype, "preferredMin", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadiusNumberAxis.prototype, "preferredMax", 2);

// packages/ag-charts-enterprise/src/axes/radius-number/radiusNumberAxisModule.ts
var RadiusNumberAxisModule = {
  type: "axis",
  name: "radius-number",
  chartType: "polar",
  enterprise: true,
  version: VERSION,
  options: module_support_exports.radiusNumberAxisOptionsDefs,
  themeTemplate: {
    positionAngle: 0,
    line: { enabled: false },
    shape: { $findFirstSiblingNotOperation: void 0 },
    label: { minSpacing: 5 }
  },
  create: (ctx) => new RadiusNumberAxis(ctx)
};

// packages/ag-charts-enterprise/src/series/util/radialUtil.ts
var { createDatumId: createDatumId17, toHighlightString: toHighlightString5 } = module_support_exports;
function makeStylerParams(series, highlightStateEnum) {
  const { id: seriesId } = series;
  const {
    angleKey,
    cornerRadius,
    fill,
    fillOpacity,
    lineDash,
    lineDashOffset,
    radiusKey,
    stackGroup,
    stroke: stroke3,
    strokeOpacity,
    strokeWidth
  } = series.properties;
  const highlightState = toHighlightString5(highlightStateEnum ?? module_support_exports.HighlightState.None);
  return {
    angleKey,
    cornerRadius,
    fill,
    fillOpacity,
    highlightState,
    lineDash,
    lineDashOffset,
    radiusKey,
    seriesId,
    stackGroup,
    stroke: stroke3,
    strokeOpacity,
    strokeWidth
  };
}
function getStyle(series, ignoreStylerCallback, highlightState) {
  const { styler } = series.properties;
  let stylerResult = {};
  if (!ignoreStylerCallback && styler) {
    const stylerParams = makeStylerParams(series, highlightState);
    stylerResult = series.ctx.optionsGraphService.resolvePartial(
      ["series", `${series.declarationOrder}`],
      series.cachedCallWithContext(styler, stylerParams) ?? {},
      { pick: false }
    ) ?? {};
  }
  return {
    cornerRadius: stylerResult.cornerRadius ?? series.properties.cornerRadius,
    fill: stylerResult.fill ?? series.properties.fill,
    fillOpacity: stylerResult.fillOpacity ?? series.properties.fillOpacity,
    lineDash: stylerResult.lineDash ?? series.properties.lineDash,
    lineDashOffset: stylerResult.lineDashOffset ?? series.properties.lineDashOffset,
    stroke: stylerResult.stroke ?? series.properties.stroke,
    strokeOpacity: stylerResult.strokeOpacity ?? series.properties.strokeOpacity,
    strokeWidth: stylerResult.strokeWidth ?? series.properties.strokeWidth,
    opacity: 1
  };
}
function makeItemStylerParams(series, nodeDatum, isHighlight, style2) {
  const { id: seriesId, properties } = series;
  const { angleKey, radiusKey } = properties;
  const activeHighlight = series.ctx.highlightManager?.getActiveHighlight();
  const highlightStateString = series.getHighlightStateString(activeHighlight, isHighlight, nodeDatum.datumIndex);
  const fill = series.filterItemStylerFillParams(style2.fill) ?? style2.fill;
  return {
    seriesId,
    datum: nodeDatum.datum,
    highlightState: highlightStateString,
    angleKey,
    radiusKey,
    ...style2,
    fill
  };
}
function getItemStyle(series, nodeDatum, isHighlight, highlightState) {
  const { properties } = series;
  const { itemStyler } = properties;
  const highlightStyle = series.getHighlightStyle(isHighlight, nodeDatum?.datumIndex, highlightState);
  const baseStyle = mergeDefaults(highlightStyle, getStyle(series, nodeDatum === void 0, highlightState));
  let style2 = baseStyle;
  if (itemStyler != null && nodeDatum != null) {
    const overrides = series.cachedDatumCallback(
      createDatumId17(series.getDatumId(nodeDatum), isHighlight ? "highlight" : "node"),
      () => {
        const params = makeItemStylerParams(series, nodeDatum, isHighlight, style2);
        return series.callWithContext(itemStyler, params);
      }
    );
    if (overrides) {
      style2 = mergeDefaults(overrides, style2);
    }
  }
  return style2;
}

// packages/ag-charts-enterprise/src/series/radial-column/radialColumnSeriesBase.ts
var {
  DEFAULT_POLAR_DIRECTION_KEYS: DEFAULT_POLAR_DIRECTION_KEYS2,
  DEFAULT_POLAR_DIRECTION_NAMES: DEFAULT_POLAR_DIRECTION_NAMES2,
  PolarAxis: PolarAxis2,
  diff: diff7,
  fixNumericExtent: fixNumericExtent9,
  groupAccumulativeValueProperty: groupAccumulativeValueProperty3,
  keyProperty: keyProperty10,
  normaliseGroupTo: normaliseGroupTo2,
  resetLabelFn: resetLabelFn6,
  seriesLabelFadeInAnimation: seriesLabelFadeInAnimation7,
  seriesLabelFadeOutAnimation: seriesLabelFadeOutAnimation2,
  valueProperty: valueProperty13,
  animationValidation: animationValidation8,
  createDatumId: createDatumId18,
  SeriesNodePickMode: SeriesNodePickMode13,
  CategoryScale: CategoryScale4,
  motion: motion7,
  updateLabelNode: updateLabelNode7,
  getItemStyles: getItemStyles4
} = module_support_exports;
var RadialColumnSeriesNodeEvent = class extends module_support_exports.SeriesNodeEvent {
  constructor(type, nativeEvent, datum, series) {
    super(type, nativeEvent, datum, series);
    this.angleKey = series.properties.angleKey;
    this.radiusKey = series.properties.radiusKey;
  }
};
var RadialColumnSeriesBase = class extends module_support_exports.PolarSeries {
  constructor(moduleCtx, {
    animationResetFns
  }) {
    super({
      moduleCtx,
      categoryKey: "angleValue",
      propertyKeys: DEFAULT_POLAR_DIRECTION_KEYS2,
      propertyNames: DEFAULT_POLAR_DIRECTION_NAMES2,
      canHaveAxes: true,
      pickModes: [SeriesNodePickMode13.NEAREST_NODE, SeriesNodePickMode13.EXACT_SHAPE_MATCH],
      animationResetFns: {
        ...animationResetFns,
        label: resetLabelFn6
      }
    });
    this.NodeEvent = RadialColumnSeriesNodeEvent;
    this.groupScale = new CategoryScale4();
    this.circleCache = { r: 0, cx: 0, cy: 0 };
  }
  getSeriesDomain(direction) {
    const { dataModel, processedData } = this;
    if (!processedData || !dataModel)
      return { domain: [] };
    if (direction === "angle" /* Angle */) {
      return dataModel.getDomain(this, "angleValue", "key", processedData);
    } else {
      const yExtent = dataModel.getDomain(this, "radiusValue-end", "value", processedData).domain;
      const fixedYExtent = Number.isFinite(yExtent[1] - yExtent[0]) ? [Math.min(yExtent[0], 0), Math.max(yExtent[1], 0)] : [];
      return { domain: fixNumericExtent9(fixedYExtent) };
    }
  }
  async processData(dataController) {
    const { angleKey, radiusKey, normalizedTo } = this.properties;
    const animationEnabled = !this.ctx.animationManager.isSkipped();
    const stackGroupId = this.getStackId();
    const stackGroupTrailingId = `${stackGroupId}-trailing`;
    const extraProps = [];
    if (isDefined(normalizedTo)) {
      extraProps.push(normaliseGroupTo2([stackGroupId, stackGroupTrailingId], Math.abs(normalizedTo)));
    }
    if (this.needsDataModelDiff() && this.processedData) {
      extraProps.push(diff7(this.id, this.processedData));
    }
    if (animationEnabled) {
      extraProps.push(animationValidation8());
    }
    const visibleProps = this.visible ? {} : { forceValue: 0 };
    const radiusScaleType = this.axes["radius" /* Radius */]?.scale.type;
    const angleScaleType = this.axes["angle" /* Angle */]?.scale.type;
    const allowNullKey = this.properties.allowNullKeys ?? false;
    await this.requestDataModel(dataController, this.data, {
      props: [
        keyProperty10(angleKey, angleScaleType, { id: "angleValue", allowNullKey }),
        valueProperty13(radiusKey, radiusScaleType, {
          id: "radiusValue-raw",
          invalidValue: null,
          ...visibleProps
        }),
        ...groupAccumulativeValueProperty3(
          radiusKey,
          "normal",
          {
            id: `radiusValue-end`,
            rangeId: `radiusValue-range`,
            invalidValue: null,
            groupId: stackGroupId,
            separateNegative: true,
            ...visibleProps
          },
          radiusScaleType
        ),
        ...groupAccumulativeValueProperty3(
          radiusKey,
          "trailing",
          {
            id: `radiusValue-start`,
            invalidValue: null,
            groupId: stackGroupTrailingId,
            separateNegative: true,
            ...visibleProps
          },
          radiusScaleType
        ),
        ...extraProps
      ],
      groupByKeys: true,
      groupByData: false
    });
    this.animationState.transition("updateData");
  }
  didCircleChange() {
    const r = this.radius;
    const cx = this.centerX;
    const cy = this.centerY;
    const cache = this.circleCache;
    if (r !== cache.r || cx !== cache.cx || cy !== cache.cy) {
      this.circleCache = { r, cx, cy };
      return true;
    }
    return false;
  }
  isRadiusAxisReversed() {
    return this.axes["radius" /* Radius */]?.isReversed();
  }
  maybeRefreshNodeData() {
    const circleChanged = this.didCircleChange();
    if (!circleChanged && !this.nodeDataRefresh)
      return;
    this.contextNodeData = this.createNodeData();
    this.nodeData = this.contextNodeData?.nodeData ?? [];
    this.nodeDataRefresh = false;
  }
  getAxisInnerRadius() {
    const radiusAxis = this.axes["radius" /* Radius */];
    return radiusAxis instanceof PolarAxis2 ? this.radius * radiusAxis.innerRadiusRatio : 0;
  }
  createNodeData() {
    const { processedData, dataModel, groupScale } = this;
    if (!dataModel || processedData?.type !== "grouped")
      return;
    const angleAxis = this.axes["angle" /* Angle */];
    const radiusAxis = this.axes["radius" /* Radius */];
    const angleScale = angleAxis?.scale;
    const radiusScale = radiusAxis?.scale;
    if (!angleScale || !radiusScale) {
      return;
    }
    const angleValues = dataModel.resolveKeysById(this, `angleValue`, processedData);
    const radiusStartValues = dataModel.resolveColumnById(this, `radiusValue-start`, processedData);
    const radiusEndValues = dataModel.resolveColumnById(this, `radiusValue-end`, processedData);
    const radiusRawValues = dataModel.resolveColumnById(this, `radiusValue-raw`, processedData);
    let groupPaddingInner = 0;
    let groupPaddingOuter = 0;
    if (angleAxis instanceof AngleCategoryAxis) {
      groupPaddingInner = angleAxis.groupPaddingInner;
      groupPaddingOuter = angleAxis.paddingInner;
    }
    const groupAngleStep = angleScale.bandwidth ?? 0;
    const paddedGroupAngleStep = groupAngleStep * (1 - groupPaddingOuter);
    const { index: groupIndex, visibleGroupCount } = this.ctx.seriesStateManager.getVisiblePeerGroupIndex(this);
    groupScale.domain = Array.from({ length: visibleGroupCount }).map((_, i) => String(i));
    groupScale.range = [-paddedGroupAngleStep / 2, paddedGroupAngleStep / 2];
    groupScale.paddingInner = visibleGroupCount > 1 ? groupPaddingInner : 0;
    const radiusAxisReversed = this.isRadiusAxisReversed();
    const axisInnerRadius = this.getAxisInnerRadius();
    const axisOuterRadius = this.radius;
    const axisTotalRadius = axisOuterRadius + axisInnerRadius;
    const { angleKey, radiusKey, angleName, radiusName, legendItemName, label } = this.properties;
    const radiusDomain = this.getSeriesDomain("radius" /* Radius */).domain;
    const getLabelNodeDatum = (datum, radiusDatum, x, y) => {
      const labelText = this.getLabelText(
        radiusDatum,
        datum,
        radiusKey,
        "radius",
        radiusDomain,
        label,
        { value: radiusDatum, datum, angleKey, radiusKey, angleName, radiusName, legendItemName }
      );
      if (labelText) {
        return { x, y, text: labelText, textAlign: "center", textBaseline: "middle" };
      }
    };
    const nodeData = [];
    const styles = getItemStyles4(
      (nodeDatum, isHighlight, highlightState) => getItemStyle(this, nodeDatum, isHighlight, highlightState)
    );
    const context = {
      itemId: radiusKey,
      nodeData,
      labelData: nodeData,
      styles
    };
    if (!this.visible)
      return context;
    const { dataSources } = processedData;
    const rawData = dataSources.get(this.id)?.data ?? [];
    for (const { datumIndex } of dataModel.forEachGroupDatum(this, processedData)) {
      const datum = rawData[datumIndex];
      const angleDatum = angleValues[datumIndex];
      if (angleDatum === void 0 && !this.properties.allowNullKeys)
        return;
      const radiusDatum = radiusRawValues[datumIndex];
      const isPositive = radiusDatum >= 0 && !Object.is(radiusDatum, -0);
      const innerRadiusDatum = radiusStartValues[datumIndex];
      const outerRadiusDatum = radiusEndValues[datumIndex];
      const negative = isPositive === radiusAxisReversed;
      if (innerRadiusDatum === void 0 || outerRadiusDatum === void 0)
        return;
      let startAngle;
      let endAngle;
      let angle2;
      if (rawData.length === 1) {
        startAngle = -0.5 * Math.PI;
        endAngle = 1.5 * Math.PI;
        angle2 = startAngle;
      } else {
        const groupAngle = angleScale.convert(angleDatum);
        startAngle = normalizeAngle360(groupAngle + groupScale.convert(String(groupIndex)));
        endAngle = normalizeAngle360(startAngle + groupScale.bandwidth);
        angle2 = startAngle + groupScale.bandwidth / 2;
      }
      const innerRadius = axisTotalRadius - radiusScale.convert(innerRadiusDatum);
      const outerRadius = axisTotalRadius - radiusScale.convert(outerRadiusDatum);
      const midRadius = (innerRadius + outerRadius) / 2;
      const x = Math.cos(angle2) * midRadius;
      const y = Math.sin(angle2) * midRadius;
      const labelNodeDatum = this.properties.label.enabled ? getLabelNodeDatum(datum, radiusDatum, x, y) : void 0;
      const columnWidth = this.getColumnWidth(startAngle, endAngle);
      nodeData.push({
        series: this,
        datum,
        datumIndex,
        point: { x, y, size: 0 },
        midPoint: { x, y },
        label: labelNodeDatum,
        angleValue: angleDatum,
        radiusValue: radiusDatum,
        negative,
        innerRadius,
        outerRadius,
        stackInnerRadius: innerRadius,
        stackOuterRadius: outerRadius,
        startAngle,
        endAngle,
        midAngle: angle2,
        axisInnerRadius,
        axisOuterRadius,
        columnWidth,
        index: datumIndex
      });
    }
    return {
      itemId: radiusKey,
      nodeData,
      labelData: nodeData,
      styles
    };
  }
  getColumnWidth(_startAngle, _endAngle) {
    return Number.NaN;
  }
  update({ seriesRect }) {
    const resize = this.checkResize(seriesRect);
    this.maybeRefreshNodeData();
    this.contentGroup.translationX = this.centerX;
    this.contentGroup.translationY = this.centerY;
    this.highlightGroup.translationX = this.centerX;
    this.highlightGroup.translationY = this.centerY;
    if (this.labelGroup) {
      this.labelGroup.translationX = this.centerX;
      this.labelGroup.translationY = this.centerY;
    }
    this.updateSectorSelection(this.itemSelection, false);
    this.updateSectorSelection(this.highlightSelection, true);
    this.updateLabels();
    if (resize) {
      this.animationState.transition("resize");
    }
    this.animationState.transition("update");
  }
  updateSectorSelection(selection, isHighlight) {
    const { contextNodeData } = this;
    if (!contextNodeData) {
      return;
    }
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    let selectionData = [];
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    if (isHighlight) {
      if (activeHighlight?.datum && activeHighlight.series === this) {
        selectionData.push(activeHighlight);
      }
    } else {
      selectionData = this.nodeData;
    }
    const radiusAxisReversed = this.isRadiusAxisReversed();
    const axisInnerRadius = radiusAxisReversed ? this.radius : this.getAxisInnerRadius();
    const axisOuterRadius = radiusAxisReversed ? this.getAxisInnerRadius() : this.radius;
    const fillBBox = this.getShapeFillBBox();
    const hasItemStylers = this.hasItemStylers();
    selection.update(selectionData, void 0, (datum) => this.getDatumId(datum)).each((node, nodeDatum) => {
      const { midPoint } = nodeDatum;
      if (hasItemStylers) {
        const highlightState = this.getHighlightState(activeHighlight, isHighlight, nodeDatum.datumIndex);
        nodeDatum.style = getItemStyle(this, nodeDatum, isHighlight, highlightState);
      }
      const style2 = nodeDatum.style ?? contextNodeData.styles[this.getHighlightState(highlightedDatum, isHighlight, nodeDatum.datumIndex)];
      const fill = style2.fill;
      const itemBounds = isGradientFill(fill) && fill.bounds === "item";
      const fillParams = itemBounds ? { centerX: midPoint?.x ?? 0, centerY: midPoint?.y ?? 0 } : { centerX: 0, centerY: 0, innerRadius: axisInnerRadius, outerRadius: axisOuterRadius };
      this.updateItemPath(node, nodeDatum, isHighlight);
      node.setStyleProperties(style2, fillBBox, fillParams);
      node.cornerRadius = style2.cornerRadius ?? 0;
      node.lineJoin = "round";
    });
  }
  updateLabels() {
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const highlightDatum = activeHighlight?.series === this && activeHighlight?.datum ? activeHighlight : void 0;
    const highlightData = highlightDatum ? [highlightDatum] : [];
    this.labelSelection.update(this.nodeData).each((node, datum) => {
      updateLabelNode7(this, node, this.properties, this.properties.label, datum.label, false, activeHighlight);
      node.fillOpacity = this.getHighlightStyle(false, datum.datumIndex).opacity ?? 1;
    });
    this.highlightLabelSelection.update(highlightData, void 0, (datum) => this.getDatumId(datum)).each((node, datum) => {
      updateLabelNode7(this, node, this.properties, this.properties.label, datum.label, true, activeHighlight);
      node.fillOpacity = this.getHighlightStyle(true, datum.datumIndex).opacity ?? 1;
    });
  }
  animateEmptyUpdateReady() {
    const { labelSelection } = this;
    const fns = this.getColumnTransitionFunctions();
    motion7.fromToMotion(this.id, "datums", this.ctx.animationManager, [this.itemSelection], fns);
    seriesLabelFadeInAnimation7(
      this,
      "labels",
      this.ctx.animationManager,
      labelSelection,
      this.highlightLabelSelection
    );
  }
  animateClearingUpdateEmpty() {
    const { itemSelection } = this;
    const { animationManager } = this.ctx;
    const fns = this.getColumnTransitionFunctions();
    motion7.fromToMotion(this.id, "datums", animationManager, [itemSelection], fns);
    seriesLabelFadeOutAnimation2(
      this,
      "labels",
      animationManager,
      this.labelSelection,
      this.highlightLabelSelection
    );
  }
  getTooltipContent(datumIndex) {
    const { id: seriesId, dataModel, processedData, axes, properties } = this;
    const { angleKey, angleName, radiusKey, radiusName, legendItemName, tooltip } = properties;
    const angleAxis = axes["angle" /* Angle */];
    const radiusAxis = axes["radius" /* Radius */];
    const nodeDatum = this.nodeData?.[datumIndex];
    if (!dataModel || !processedData || !angleAxis || !radiusAxis || !nodeDatum)
      return;
    const datum = processedData.dataSources.get(this.id)?.data[datumIndex];
    const angleValue = dataModel.resolveKeysById(this, `angleValue`, processedData)[datumIndex];
    const radiusValue = dataModel.resolveColumnById(this, `radiusValue-raw`, processedData)[datumIndex];
    if (angleValue === void 0 && !this.properties.allowNullKeys)
      return;
    const format = getItemStyle(this, nodeDatum, false);
    return this.formatTooltipWithContext(
      tooltip,
      {
        heading: this.getAxisValueText(angleAxis, "tooltip", angleValue, datum, angleKey, void 0),
        symbol: this.legendItemSymbol(),
        data: [
          {
            label: radiusName,
            fallbackLabel: radiusKey,
            value: this.getAxisValueText(radiusAxis, "tooltip", radiusValue, datum, radiusKey, void 0),
            missing: module_support_exports.isTooltipValueMissing(radiusValue)
          }
        ]
      },
      {
        seriesId,
        datum,
        title: angleName,
        angleKey,
        angleName,
        radiusKey,
        radiusName,
        legendItemName,
        ...format
      }
    );
  }
  pickNodeClosestDatum(point) {
    return this.pickNodeNearestDistantObject(point, this.itemSelection.nodes());
  }
  legendItemSymbol() {
    const { fill, stroke: stroke3, fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = getStyle(
      this,
      false,
      module_support_exports.HighlightState.None
    );
    const markerStyle = {
      fill: fill ?? "rgba(0, 0, 0, 0)",
      stroke: stroke3 ?? "rgba(0, 0, 0, 0)",
      fillOpacity,
      strokeOpacity,
      strokeWidth,
      lineDash,
      lineDashOffset
    };
    if (isGradientFill(markerStyle.fill)) {
      markerStyle.fill = { ...markerStyle.fill, gradient: "linear", rotation: 0, reverse: false };
    }
    return {
      marker: markerStyle
    };
  }
  getLegendData(legendType) {
    if (legendType !== "category") {
      return [];
    }
    const { id: seriesId, visible } = this;
    const { radiusKey, radiusName, legendItemName, showInLegend } = this.properties;
    return [
      {
        legendType: "category",
        id: seriesId,
        itemId: radiusKey,
        seriesId,
        enabled: visible,
        label: {
          text: legendItemName ?? radiusName ?? radiusKey
        },
        symbol: this.legendItemSymbol(),
        legendItemName,
        hideInLegend: !showInLegend
      }
    ];
  }
  getDatumId(datum) {
    return createDatumId18(datum.angleValue);
  }
  computeLabelsBBox() {
    return null;
  }
};

// packages/ag-charts-enterprise/src/series/radial-column/radialColumnSeriesBaseProperties.ts
var { SeriesProperties: SeriesProperties7, makeSeriesTooltip: makeSeriesTooltip18, Label: Label16 } = module_support_exports;
var RadialColumnSeriesBaseProperties = class extends SeriesProperties7 {
  constructor() {
    super(...arguments);
    this.angleKeyAxis = "angle";
    this.radiusKeyAxis = "radius";
    this.fill = "black";
    this.fillOpacity = 1;
    this.stroke = "black";
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.cornerRadius = 0;
    this.rotation = 0;
    this.label = new Label16();
    this.tooltip = makeSeriesTooltip18();
  }
  getStyle() {
    const { fill, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset, cornerRadius } = this;
    return {
      fill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset,
      cornerRadius,
      opacity: 1
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "angleKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "angleName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "radiusKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "radiusName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "angleKeyAxis", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "radiusKeyAxis", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "legendItemName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "styler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "itemStyler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "rotation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "stackGroup", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "normalizedTo", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesBaseProperties.prototype, "tooltip", 2);

// packages/ag-charts-enterprise/src/series/radial-column/radialColumnUtil.ts
var { motion: motion8 } = module_support_exports;
function createAngleMotionCalculator() {
  const angles = {
    startAngle: /* @__PURE__ */ new Map(),
    endAngle: /* @__PURE__ */ new Map()
  };
  const angleKeys = ["startAngle", "endAngle"];
  const calculate = (node, datum, status) => {
    for (const key of angleKeys) {
      const map = angles[key];
      let from4 = (status === "removed" || status === "updated" ? node : datum)[key];
      let to2 = (status === "removed" ? node : datum)[key];
      if (Number.isNaN(to2)) {
        to2 = node.previousDatum?.[key] ?? Number.NaN;
      }
      const diff9 = from4 - to2;
      if (Math.abs(diff9) > Math.PI) {
        from4 -= Math.sign(diff9) * 2 * Math.PI;
      }
      map.set(datum, { from: from4, to: to2 });
    }
  };
  const getAngles = (datum, fromToKey) => {
    return {
      startAngle: angles.startAngle.get(datum)[fromToKey],
      endAngle: angles.endAngle.get(datum)[fromToKey]
    };
  };
  const from3 = (datum) => getAngles(datum, "from");
  const to = (datum) => getAngles(datum, "to");
  return { calculate, from: from3, to };
}
function fixRadialColumnAnimationStatus(node, datum, status) {
  if (status === "updated") {
    if (node.previousDatum == null || Number.isNaN(node.previousDatum.startAngle) || Number.isNaN(node.previousDatum.endAngle)) {
      return "added";
    }
    if (Number.isNaN(datum.startAngle) || Number.isNaN(datum.endAngle)) {
      return "removed";
    }
  }
  if (status === "added" && node.previousDatum != null) {
    return "updated";
  }
  return status;
}
function prepareRadialColumnAnimationFunctions(axisZeroRadius) {
  const angles = createAngleMotionCalculator();
  const fromFn = (node, datum, status) => {
    status = fixRadialColumnAnimationStatus(node, datum, status);
    angles.calculate(node, datum, status);
    const { startAngle, endAngle } = angles.from(datum);
    let innerRadius;
    let outerRadius;
    let columnWidth;
    let axisInnerRadius;
    let axisOuterRadius;
    if (status === "removed" || status === "updated") {
      innerRadius = node.innerRadius;
      outerRadius = node.outerRadius;
      columnWidth = node.columnWidth;
      axisInnerRadius = node.axisInnerRadius;
      axisOuterRadius = node.axisOuterRadius;
    } else {
      innerRadius = axisZeroRadius;
      outerRadius = axisZeroRadius;
      columnWidth = datum.columnWidth;
      axisInnerRadius = datum.axisInnerRadius;
      axisOuterRadius = datum.axisOuterRadius;
    }
    const phase = motion8.NODE_UPDATE_STATE_TO_PHASE_MAPPING[status];
    return {
      innerRadius,
      outerRadius,
      columnWidth,
      axisInnerRadius,
      axisOuterRadius,
      startAngle,
      endAngle,
      phase
    };
  };
  const toFn = (node, datum, status) => {
    const { startAngle, endAngle } = angles.to(datum);
    let innerRadius;
    let outerRadius;
    let columnWidth;
    let axisInnerRadius;
    let axisOuterRadius;
    if (status === "removed") {
      innerRadius = node.innerRadius;
      outerRadius = node.innerRadius;
      columnWidth = node.columnWidth;
      axisInnerRadius = node.axisInnerRadius;
      axisOuterRadius = node.axisOuterRadius;
    } else {
      innerRadius = Number.isNaN(datum.innerRadius) ? axisZeroRadius : datum.innerRadius;
      outerRadius = Number.isNaN(datum.outerRadius) ? axisZeroRadius : datum.outerRadius;
      columnWidth = Number.isNaN(datum.columnWidth) ? node.columnWidth : datum.columnWidth;
      axisInnerRadius = datum.axisInnerRadius;
      axisOuterRadius = datum.axisOuterRadius;
    }
    return { innerRadius, outerRadius, columnWidth, axisInnerRadius, axisOuterRadius, startAngle, endAngle };
  };
  return { toFn, fromFn };
}
function resetRadialColumnSelectionFn(_node, {
  innerRadius,
  outerRadius,
  columnWidth,
  axisInnerRadius,
  axisOuterRadius,
  startAngle,
  endAngle
}) {
  return { innerRadius, outerRadius, columnWidth, axisInnerRadius, axisOuterRadius, startAngle, endAngle };
}

// packages/ag-charts-enterprise/src/series/nightingale/nightingaleUtil.ts
var { SectorBox: SectorBox4, motion: motion9 } = module_support_exports;
function getRadii(datum) {
  const { negative, innerRadius, outerRadius, stackInnerRadius, stackOuterRadius } = datum;
  return {
    innerRadius: negative ? stackOuterRadius : stackInnerRadius,
    outerRadius: negative ? stackInnerRadius : stackOuterRadius,
    clipInnerRadius: negative ? outerRadius : innerRadius,
    clipOuterRadius: negative ? innerRadius : outerRadius
  };
}
function prepareNightingaleAnimationFunctions(axisZeroRadius) {
  const angles = createAngleMotionCalculator();
  const fromFn = (sect, datum, status) => {
    status = fixRadialColumnAnimationStatus(sect, datum, status);
    angles.calculate(sect, datum, status);
    const { startAngle, endAngle } = angles.from(datum);
    let innerRadius;
    let outerRadius;
    let clipSector;
    if (status === "removed" || status === "updated") {
      innerRadius = sect.innerRadius;
      outerRadius = sect.outerRadius;
      clipSector = sect.clipSector;
    } else {
      innerRadius = axisZeroRadius;
      outerRadius = axisZeroRadius;
    }
    clipSector ?? (clipSector = new SectorBox4(startAngle, endAngle, innerRadius, outerRadius));
    const phase = motion9.NODE_UPDATE_STATE_TO_PHASE_MAPPING[status];
    return { innerRadius, outerRadius, startAngle, endAngle, clipSector, phase };
  };
  const toFn = (_sect, datum, status) => {
    const { startAngle, endAngle } = angles.to(datum);
    let innerRadius;
    let outerRadius;
    let clipSector;
    if (status === "removed") {
      innerRadius = axisZeroRadius;
      outerRadius = axisZeroRadius;
      clipSector = new SectorBox4(startAngle, endAngle, innerRadius, outerRadius);
    } else {
      let clipInnerRadius, clipOuterRadius;
      ({ innerRadius, outerRadius, clipInnerRadius, clipOuterRadius } = getRadii(datum));
      if (Number.isNaN(innerRadius))
        innerRadius = axisZeroRadius;
      if (Number.isNaN(outerRadius))
        outerRadius = axisZeroRadius;
      if (Number.isNaN(clipInnerRadius))
        clipInnerRadius = axisZeroRadius;
      if (Number.isNaN(clipOuterRadius))
        clipOuterRadius = axisZeroRadius;
      clipSector = new SectorBox4(startAngle, endAngle, clipInnerRadius, clipOuterRadius);
    }
    return { innerRadius, outerRadius, startAngle, endAngle, clipSector };
  };
  return { toFn, fromFn };
}
function resetNightingaleSelectionFn(_sect, datum) {
  const { startAngle, endAngle } = datum;
  const { innerRadius, outerRadius, clipInnerRadius, clipOuterRadius } = getRadii(datum);
  const clipSector = new SectorBox4(startAngle, endAngle, clipInnerRadius, clipOuterRadius);
  return { innerRadius, outerRadius, startAngle, endAngle, clipSector };
}

// packages/ag-charts-enterprise/src/series/nightingale/nightingaleSeries.ts
var { Sector: Sector7, SectorBox: SectorBox5 } = module_support_exports;
var NightingaleSeries = class extends RadialColumnSeriesBase {
  // TODO: Enable once the options contract has been revisited
  // @TempValidate
  // sectorSpacing = 1;
  constructor(moduleCtx) {
    super(moduleCtx, { animationResetFns: { item: resetNightingaleSelectionFn } });
    this.properties = new RadialColumnSeriesBaseProperties();
  }
  setZIndex(zIndex) {
    super.setZIndex(zIndex);
    this.contentGroup.zIndex = [0, 1 /* FOREGROUND */, zIndex];
    this.highlightGroup.zIndex = [0, 2 /* HIGHLIGHT */, zIndex];
    this.labelGroup.zIndex = [0, 3 /* LABEL */, zIndex];
    return true;
  }
  getStackId() {
    const groupIndex = this.seriesGrouping?.groupIndex ?? this.id;
    return `nightingale-stack-${groupIndex}-yValues`;
  }
  nodeFactory() {
    return new Sector7();
  }
  updateItemPath(node, datum, highlight5) {
    const { negative } = datum;
    node.centerX = 0;
    node.centerY = 0;
    node.startOuterCornerRadius = negative ? 0 : this.properties.cornerRadius;
    node.endOuterCornerRadius = negative ? 0 : this.properties.cornerRadius;
    node.startInnerCornerRadius = negative ? this.properties.cornerRadius : 0;
    node.endInnerCornerRadius = negative ? this.properties.cornerRadius : 0;
    if (highlight5) {
      const { startAngle, endAngle } = datum;
      const { innerRadius, outerRadius, clipInnerRadius, clipOuterRadius } = getRadii(datum);
      node.innerRadius = innerRadius;
      node.outerRadius = outerRadius;
      node.startAngle = startAngle;
      node.endAngle = endAngle;
      node.clipSector = new SectorBox5(startAngle, endAngle, clipInnerRadius, clipOuterRadius);
    }
  }
  getColumnTransitionFunctions() {
    const axisZeroRadius = this.isRadiusAxisReversed() ? this.radius : this.getAxisInnerRadius();
    return prepareNightingaleAnimationFunctions(axisZeroRadius);
  }
  hasItemStylers() {
    return this.properties.itemStyler != null || this.properties.styler != null || this.properties.label.itemStyler != null;
  }
};
NightingaleSeries.className = "NightingaleSeries";
NightingaleSeries.type = "nightingale";

// packages/ag-charts-enterprise/src/series/nightingale/nightingaleSeriesOptionsDef.ts
var { nightingaleSeriesThemeableOptionsDef: nightingaleSeriesThemeableOptionsDef2 } = module_support_exports;
var nightingaleSeriesOptionsDef = {
  ...commonSeriesOptionsDefs,
  ...nightingaleSeriesThemeableOptionsDef2,
  type: required(constant("nightingale")),
  angleKey: required(string),
  radiusKey: required(string),
  angleName: string,
  radiusName: string,
  legendItemName: string,
  grouped: boolean,
  stacked: boolean,
  stackGroup: string,
  normalizedTo: number
};
nightingaleSeriesOptionsDef.angleKeyAxis = undocumented(string);
nightingaleSeriesOptionsDef.radiusKeyAxis = undocumented(string);

// packages/ag-charts-enterprise/src/series/nightingale/nightingaleThemes.ts
var NIGHTINGALE_SERIES_THEME = {
  series: {
    fill: {
      $applySwitch: [
        { $path: "type" },
        { $palette: "fill" },
        ["gradient", FILL_GRADIENT_RADIAL_SERIES_DEFAULTS],
        ["image", FILL_IMAGE_DEFAULTS],
        ["pattern", FILL_PATTERN_DEFAULTS]
      ]
    },
    stroke: {
      $if: [{ $eq: [{ $palette: "type" }, "inbuilt"] }, { $ref: "chartBackgroundColor" }, { $palette: "stroke" }]
    },
    strokeWidth: 1,
    label: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: false,
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      fontWeight: { $ref: "fontWeight" },
      color: { $ref: "textColor" }
    },
    highlight: { ...MULTI_SERIES_HIGHLIGHT_STYLE, bringToFront: false }
  },
  axes: {
    ["angle-category" /* ANGLE_CATEGORY */]: {
      shape: { $findFirstSiblingNotOperation: "circle" /* CIRCLE */ },
      groupPaddingInner: 0,
      paddingInner: 0,
      label: {
        spacing: 10
      }
    },
    ["radius-number" /* RADIUS_NUMBER */]: {
      shape: { $findFirstSiblingNotOperation: "circle" /* CIRCLE */ }
    }
  }
};

// packages/ag-charts-enterprise/src/series/nightingale/nightingaleModule.ts
var NightingaleSeriesModule = {
  type: "series",
  name: "nightingale",
  chartType: "polar",
  enterprise: true,
  stackable: true,
  groupable: true,
  stackedByDefault: true,
  version: VERSION,
  dependencies: [PolarChartModule],
  options: nightingaleSeriesOptionsDef,
  defaultAxes: { angle: { type: "angle-category" /* ANGLE_CATEGORY */ }, radius: { type: "radius-number" /* RADIUS_NUMBER */ } },
  axisKeys: { ["x" /* X */]: "xKeyAxis", ["y" /* Y */]: "yKeyAxis" },
  themeTemplate: NIGHTINGALE_SERIES_THEME,
  create: (ctx) => new NightingaleSeries(ctx)
};

// packages/ag-charts-enterprise/src/series/radar/radarThemes.ts
var BASE_RADAR_SERIES_THEME = {
  series: {
    stroke: { $palette: "stroke" },
    label: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: false,
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      fontWeight: { $ref: "fontWeight" },
      color: { $ref: "textColor" }
    },
    marker: {
      enabled: true,
      fill: {
        $applySwitch: [
          { $path: "type" },
          { $palette: "fill" },
          ["gradient", FILL_GRADIENT_RADIAL_REVERSED_DEFAULTS],
          ["image", FILL_IMAGE_DEFAULTS],
          ["pattern", FILL_PATTERN_DEFAULTS]
        ]
      },
      stroke: { $palette: "stroke" },
      fillOpacity: 1,
      shape: "circle",
      size: 6,
      strokeOpacity: 1,
      strokeWidth: { $isUserOption: ["./stroke", 1, 0] }
    },
    highlight: MARKER_SERIES_HIGHLIGHT_STYLE,
    tooltip: {
      range: { $path: ["/tooltip/range", "nearest"] }
    }
  },
  axes: {
    ["angle-category" /* ANGLE_CATEGORY */]: {
      label: {
        spacing: 10
      }
    }
  }
};
var RADAR_LINE_SERIES_THEME = mergeDefaults(
  {
    series: {
      stroke: SAFE_STROKE_FILL_OPERATION,
      strokeWidth: 2
    }
  },
  BASE_RADAR_SERIES_THEME
);
var RADAR_AREA_SERIES_THEME = mergeDefaults(
  {
    series: {
      fill: {
        $applySwitch: [
          { $path: "type" },
          { $palette: "fill" },
          ["gradient", FILL_GRADIENT_LINEAR_DEFAULTS],
          ["image", FILL_IMAGE_DEFAULTS],
          ["pattern", FILL_PATTERN_DEFAULTS]
        ]
      },
      fillOpacity: 0.8,
      strokeWidth: 2,
      marker: {
        enabled: false
      }
    }
  },
  BASE_RADAR_SERIES_THEME
);

// packages/ag-charts-enterprise/src/series/radar/radarSeriesProperties.ts
var { Label: Label17, SeriesMarker: SeriesMarker3, SeriesProperties: SeriesProperties8, makeSeriesTooltip: makeSeriesTooltip19 } = module_support_exports;
var RadarSeriesProperties = class extends SeriesProperties8 {
  constructor() {
    super(...arguments);
    this.angleKeyAxis = "angle";
    this.radiusKeyAxis = "radius";
    this.stroke = "black";
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.rotation = 0;
    this.marker = new SeriesMarker3();
    this.label = new Label17();
    this.tooltip = makeSeriesTooltip19();
    this.connectMissingData = false;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarSeriesProperties.prototype, "angleKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarSeriesProperties.prototype, "radiusKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarSeriesProperties.prototype, "angleName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarSeriesProperties.prototype, "radiusName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarSeriesProperties.prototype, "angleKeyAxis", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarSeriesProperties.prototype, "radiusKeyAxis", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarSeriesProperties.prototype, "legendItemName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarSeriesProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarSeriesProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarSeriesProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarSeriesProperties.prototype, "rotation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarSeriesProperties.prototype, "styler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarSeriesProperties.prototype, "marker", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarSeriesProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarSeriesProperties.prototype, "tooltip", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarSeriesProperties.prototype, "connectMissingData", 2);

// packages/ag-charts-enterprise/src/series/radar/radarSeries.ts
var {
  DEFAULT_POLAR_DIRECTION_KEYS: DEFAULT_POLAR_DIRECTION_KEYS3,
  DEFAULT_POLAR_DIRECTION_NAMES: DEFAULT_POLAR_DIRECTION_NAMES3,
  PolarAxis: PolarAxis3,
  SeriesNodePickMode: SeriesNodePickMode14,
  keyProperty: keyProperty11,
  valueProperty: valueProperty14,
  fixNumericExtent: fixNumericExtent10,
  seriesLabelFadeInAnimation: seriesLabelFadeInAnimation8,
  markerFadeInAnimation: markerFadeInAnimation3,
  resetMarkerFn: resetMarkerFn3,
  resetLabelFn: resetLabelFn7,
  animationValidation: animationValidation9,
  computeMarkerFocusBounds: computeMarkerFocusBounds3,
  BBox: BBox28,
  Group: Group20,
  Path: Path13,
  Selection: Selection13,
  Text: Text8,
  Marker: Marker6,
  updateLabelNode: updateLabelNode8,
  getMarkerStyles: getMarkerStyles3
} = module_support_exports;
var RadarSeriesNodeEvent = class extends module_support_exports.SeriesNodeEvent {
  constructor(type, nativeEvent, datum, series) {
    super(type, nativeEvent, datum, series);
    this.angleKey = series.properties.angleKey;
    this.radiusKey = series.properties.radiusKey;
  }
};
var RadarSeries = class extends module_support_exports.PolarSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      categoryKey: "angleValue",
      propertyKeys: DEFAULT_POLAR_DIRECTION_KEYS3,
      propertyNames: DEFAULT_POLAR_DIRECTION_NAMES3,
      pickModes: [SeriesNodePickMode14.NEAREST_NODE, SeriesNodePickMode14.EXACT_SHAPE_MATCH],
      canHaveAxes: true,
      animationResetFns: {
        item: resetMarkerFn3,
        label: resetLabelFn7
      },
      clipFocusBox: false
    });
    this.NodeEvent = RadarSeriesNodeEvent;
    this.lineGroup = this.contentGroup.appendChild(new Group20({ name: "radar-line" }));
    this.lineSelection = Selection13.select(
      this.lineGroup,
      Path13
    );
    this.resetInvalidToZero = false;
    this.circleCache = { r: 0, cx: 0, cy: 0 };
    this.lineGroup.zIndex = 0;
    this.itemGroup.zIndex = 1;
  }
  renderToOffscreenCanvas() {
    const hasMarkers = (this.nodeData?.length ?? 0) > 0;
    return hasMarkers && this.getDrawingMode(false) === "cutout" || super.renderToOffscreenCanvas();
  }
  nodeFactory() {
    return new Marker6();
  }
  getSeriesDomain(direction) {
    const { dataModel, processedData } = this;
    if (!processedData || !dataModel)
      return { domain: [] };
    if (direction === "angle" /* Angle */) {
      const domain = dataModel.getDomain(this, `angleValue`, "key", processedData).domain;
      const sortMetadata = dataModel.getKeySortMetadata(this, "angleValue", processedData);
      return { domain, sortMetadata };
    } else {
      const domain = dataModel.getDomain(this, `radiusValue`, "value", processedData).domain;
      const ext = extent(domain.length === 0 ? domain : [0].concat(domain));
      return { domain: fixNumericExtent10(ext) };
    }
  }
  async processData(dataController) {
    const { angleKey, radiusKey } = this.properties;
    const extraProps = [];
    if (!this.ctx.animationManager.isSkipped()) {
      extraProps.push(animationValidation9());
    }
    const radiusScaleType = this.axes["radius" /* Radius */]?.scale.type;
    const angleScaleType = this.axes["angle" /* Angle */]?.scale.type;
    const allowNullKey = this.properties.allowNullKeys ?? false;
    await this.requestDataModel(dataController, this.data, {
      props: [
        keyProperty11(angleKey, angleScaleType, { id: "angleValue", allowNullKey }),
        valueProperty14(radiusKey, radiusScaleType, { id: "radiusValue", invalidValue: void 0 }),
        ...extraProps
      ]
    });
    this.animationState.transition("updateData");
  }
  didCircleChange() {
    const r = this.radius;
    const cx = this.centerX;
    const cy = this.centerY;
    const cache = this.circleCache;
    if (!(r === cache.r && cx === cache.cx && cy === cache.cy)) {
      this.circleCache = { r, cx, cy };
      return true;
    }
    return false;
  }
  getAxisInnerRadius() {
    const radiusAxis = this.axes["radius" /* Radius */];
    return radiusAxis instanceof PolarAxis3 ? this.radius * radiusAxis.innerRadiusRatio : 0;
  }
  maybeRefreshNodeData() {
    const didCircleChange = this.didCircleChange();
    if (!didCircleChange && !this.nodeDataRefresh)
      return;
    this.contextNodeData = this.createNodeData();
    this.nodeData = this.contextNodeData?.nodeData ?? [];
    this.nodeDataRefresh = false;
  }
  createNodeData() {
    const { processedData, dataModel } = this;
    if (!processedData || !dataModel)
      return;
    const { angleKey, radiusKey, angleName, radiusName, legendItemName, marker, label } = this.properties;
    const angleScale = this.axes["angle" /* Angle */]?.scale;
    const radiusScale = this.axes["radius" /* Radius */]?.scale;
    if (!angleScale || !radiusScale) {
      return;
    }
    const angleValues = dataModel.resolveKeysById(this, `angleValue`, processedData);
    const radiusValues = dataModel.resolveColumnById(this, `radiusValue`, processedData);
    const axisInnerRadius = this.getAxisInnerRadius();
    const radiusDomain = this.getSeriesDomain("radius" /* Radius */).domain;
    const rawData = processedData.dataSources.get(this.id)?.data ?? [];
    const allowNullKeys = this.properties.allowNullKeys ?? false;
    const nodeData = [];
    for (let datumIndex = 0; datumIndex < rawData.length; datumIndex++) {
      const datum = rawData[datumIndex];
      const angleDatum = angleValues[datumIndex];
      if (angleDatum === void 0 && !allowNullKeys) {
        continue;
      }
      const radiusDatum = radiusValues[datumIndex];
      const angle2 = angleScale.convert(angleDatum);
      const radius = this.radius + axisInnerRadius - radiusScale.convert(radiusDatum);
      const cos = Math.cos(angle2);
      const sin = Math.sin(angle2);
      const x = cos * radius;
      const y = sin * radius;
      let labelNodeDatum;
      if (label.enabled) {
        const labelText = this.getLabelText(
          radiusDatum,
          datum,
          radiusKey,
          "radius",
          radiusDomain,
          label,
          { value: radiusDatum, datum, angleKey, radiusKey, angleName, radiusName, legendItemName }
        );
        if (labelText) {
          let textAlign = "right";
          if (isNumberEqual(cos, 0)) {
            textAlign = "center";
          } else if (cos > 0) {
            textAlign = "left";
          }
          let textBaseline = "bottom";
          if (isNumberEqual(sin, 0)) {
            textBaseline = "middle";
          } else if (sin > 0) {
            textBaseline = "top";
          }
          labelNodeDatum = {
            x: x + cos * marker.size,
            y: y + sin * marker.size,
            text: labelText,
            textAlign,
            textBaseline
          };
        }
      }
      nodeData.push({
        series: this,
        datum,
        datumIndex,
        index: datumIndex,
        point: { x, y, size: marker.size },
        midPoint: { x, y },
        label: labelNodeDatum,
        angleValue: angleDatum,
        radiusValue: radiusDatum,
        missing: !isFiniteNumber(angle2) || !isFiniteNumber(radius)
      });
    }
    return {
      itemId: radiusKey,
      nodeData,
      labelData: nodeData,
      styles: getMarkerStyles3(this, this.properties, marker)
    };
  }
  update({ seriesRect }) {
    const resize = this.checkResize(seriesRect);
    const animationEnabled = !this.ctx.animationManager.isSkipped();
    const { series } = this.ctx.highlightManager?.getActiveHighlight() ?? {};
    this.highlightGroup.visible = (animationEnabled || this.visible) && series === this;
    this.maybeRefreshNodeData();
    this.contentGroup.translationX = this.centerX;
    this.contentGroup.translationY = this.centerY;
    this.highlightGroup.translationX = this.centerX;
    this.highlightGroup.translationY = this.centerY;
    if (this.labelGroup) {
      this.labelGroup.translationX = this.centerX;
      this.labelGroup.translationY = this.centerY;
    }
    this.updatePathSelections();
    this.updateMarkerSelection();
    this.updateHighlightSelection();
    this.updatePathNodes();
    if (this.hasItemStylers()) {
      this.updateDatumStyles(this.itemSelection, false);
      this.updateDatumStyles(this.highlightSelection, true);
    }
    const drawingMode = this.ctx.chartService.highlight?.drawingMode ?? "overlay";
    this.updateMarkers(this.itemSelection, false, "overlay");
    this.updateMarkers(this.highlightSelection, true, drawingMode);
    this.updateLabels();
    if (resize) {
      this.animationState.transition("resize");
    }
    this.animationState.transition("update");
  }
  updatePathSelections() {
    const pathData = this.visible ? [true] : [];
    this.lineSelection.update(pathData);
  }
  updateMarkerSelection() {
    const { marker, styler } = this.properties;
    if (marker.isDirty()) {
      this.itemSelection.clear();
      this.itemSelection.cleanup();
      this.itemSelection = Selection13.select(this.itemGroup, () => this.nodeFactory(), false);
    }
    const markersEnabled = styler == null ? marker.enabled : this.getStyle().marker.enabled;
    const data = this.visible && marker.shape && markersEnabled ? this.nodeData : [];
    this.itemSelection.update(data);
  }
  updateHighlightSelection() {
    const { marker, styler } = this.properties;
    if (marker.isDirty()) {
      this.highlightSelection.clear();
      this.highlightSelection.cleanup();
      this.highlightSelection = Selection13.select(this.highlightGroup, () => this.nodeFactory(), false);
    }
    const markersEnabled = styler == null ? marker.enabled : this.getStyle().marker.enabled;
    const highlighted = this.ctx.highlightManager?.getActiveHighlight();
    const data = this.visible && marker.shape && markersEnabled && highlighted?.datum ? [{ ...highlighted }] : [];
    this.highlightSelection.update(data);
  }
  getMarkerFill(highlightedStyle) {
    return highlightedStyle?.fill ?? this.getStyle().marker.fill;
  }
  getDatumStylerProperties(datum) {
    const { id: seriesId, properties } = this;
    const { angleKey, radiusKey } = properties;
    return {
      seriesId,
      datum,
      angleKey,
      radiusKey
    };
  }
  updateDatumStyles(selection, isHighlight) {
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    selection.each((_, datum) => {
      const highlightState = this.getHighlightState(highlightedDatum, isHighlight, datum.datumIndex);
      const stylerStyle = this.getStyle(highlightState);
      const { stroke: stroke3, strokeWidth, strokeOpacity } = stylerStyle;
      datum.style = this.getMarkerStyle(
        this.properties.marker,
        datum,
        this.getDatumStylerProperties(datum.datum),
        { isHighlight, highlightState },
        stylerStyle.marker,
        {
          stroke: stroke3,
          strokeWidth,
          strokeOpacity
        }
      );
    });
  }
  updateMarkers(selection, isHighlight, drawingMode) {
    const fillBBox = this.getShapeFillBBox();
    const { contextNodeData } = this;
    if (!contextNodeData) {
      return;
    }
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    drawingMode = this.getDrawingMode(isHighlight, drawingMode);
    selection.each((node, datum) => {
      const style2 = datum.style ?? contextNodeData.styles[this.getHighlightState(highlightedDatum, isHighlight, datum.datumIndex)];
      this.applyMarkerStyle(style2, node, datum.point, fillBBox);
      node.drawingMode = drawingMode;
    });
  }
  updateLabels() {
    const { properties } = this;
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const highlightData = activeHighlight?.series === this && activeHighlight?.datum ? [{ ...activeHighlight }] : [];
    this.labelSelection.update(this.nodeData).each((node, datum) => {
      if (datum.label) {
        const isHighlight = false;
        node.fillOpacity = this.getHighlightStyle(isHighlight, datum.datumIndex).opacity ?? 1;
        updateLabelNode8(this, node, properties, properties.label, datum.label, isHighlight, activeHighlight);
      }
    });
    this.highlightLabelSelection.update(highlightData).each((node, datum) => {
      if (datum.label) {
        const isHighlight = true;
        node.fillOpacity = this.getHighlightStyle(isHighlight, datum.datumIndex).opacity ?? 1;
        updateLabelNode8(this, node, properties, properties.label, datum.label, isHighlight, activeHighlight);
      }
    });
  }
  getTooltipContent(datumIndex) {
    const { id: seriesId, dataModel, processedData, axes, properties } = this;
    const { angleKey, angleName, radiusKey, radiusName, legendItemName, tooltip, marker } = properties;
    const angleAxis = axes["angle" /* Angle */];
    const radiusAxis = axes["radius" /* Radius */];
    if (!dataModel || !processedData || !angleAxis || !radiusAxis)
      return;
    const datum = processedData.dataSources.get(this.id)?.data[datumIndex];
    const angleValue = dataModel.resolveKeysById(this, `angleValue`, processedData)[datumIndex];
    const radiusValue = dataModel.resolveColumnById(this, `radiusValue`, processedData)[datumIndex];
    const allowNullKeys = this.properties.allowNullKeys ?? false;
    if (angleValue === void 0 && !allowNullKeys)
      return;
    const activeStyle = this.getMarkerStyle(marker, { datum, datumIndex }, this.getDatumStylerProperties(datum), {
      isHighlight: false
    });
    return this.formatTooltipWithContext(
      tooltip,
      {
        heading: this.getAxisValueText(
          angleAxis,
          "tooltip",
          angleValue,
          datum,
          angleKey,
          void 0,
          allowNullKeys
        ),
        symbol: this.legendItemSymbol(),
        data: [
          {
            label: radiusName,
            fallbackLabel: radiusKey,
            value: this.getAxisValueText(radiusAxis, "tooltip", radiusValue, datum, radiusKey, void 0),
            missing: module_support_exports.isTooltipValueMissing(radiusValue)
          }
        ]
      },
      {
        seriesId,
        datum,
        title: angleName,
        angleKey,
        radiusKey,
        angleName,
        radiusName,
        legendItemName,
        ...activeStyle
      }
    );
  }
  legendItemSymbol() {
    const { stroke: stroke3, strokeWidth, strokeOpacity, lineDash, marker } = this.getStyle();
    const markerStyle = {
      shape: marker.shape,
      enabled: marker.enabled || strokeWidth <= 0,
      fill: this.getMarkerFill() ?? marker.stroke ?? stroke3 ?? "rgba(0, 0, 0, 0)",
      stroke: marker.stroke ?? stroke3 ?? "rgba(0, 0, 0, 0)",
      fillOpacity: marker.fillOpacity,
      strokeOpacity: marker.strokeOpacity,
      strokeWidth: marker.strokeWidth,
      lineDash: marker.lineDash,
      lineDashOffset: marker.lineDashOffset
    };
    return {
      marker: markerStyle,
      line: {
        enabled: true,
        stroke: stroke3,
        strokeOpacity,
        strokeWidth,
        lineDash
      }
    };
  }
  getLegendData(legendType) {
    if (legendType !== "category") {
      return [];
    }
    const {
      id: seriesId,
      ctx: { legendManager },
      visible
    } = this;
    const { radiusKey, radiusName, legendItemName, showInLegend } = this.properties;
    return [
      {
        legendType: "category",
        id: seriesId,
        itemId: radiusKey,
        seriesId,
        enabled: visible && legendManager.getItemEnabled({ seriesId, itemId: radiusKey }),
        label: {
          text: legendItemName ?? radiusName ?? radiusKey
        },
        symbol: this.legendItemSymbol(),
        legendItemName,
        hideInLegend: !showInLegend
      }
    ];
  }
  pickNodeClosestDatum(hitPoint) {
    const { nodeData, centerX: cx, centerY: cy } = this;
    const { x, y } = hitPoint;
    const radius = this.radius;
    const distanceFromCenter = Math.hypot(x - cx, y - cy);
    if (distanceFromCenter > radius + this.maxChartMarkerSize) {
      return;
    }
    let minDistance = Infinity;
    let closestDatum;
    for (const datum of nodeData) {
      const { point: { x: datumX = Number.NaN, y: datumY = Number.NaN } = {} } = datum;
      if (Number.isNaN(datumX) || Number.isNaN(datumY)) {
        continue;
      }
      const distance2 = Math.hypot(hitPoint.x - datumX - cx, hitPoint.y - datumY - cy);
      if (distance2 < minDistance) {
        minDistance = distance2;
        closestDatum = datum;
      }
    }
    if (closestDatum) {
      const distance2 = Math.max(minDistance - (closestDatum.point?.size ?? 0) / 2, 0);
      return { datum: closestDatum, distance: distance2 };
    }
  }
  computeLabelsBBox() {
    const { label } = this.properties;
    this.maybeRefreshNodeData();
    const textBoxes = [];
    const tempText = new Text8();
    for (const nodeDatum of this.nodeData) {
      if (!label.enabled || !nodeDatum.label) {
        continue;
      }
      tempText.text = nodeDatum.label.text;
      tempText.x = nodeDatum.label.x;
      tempText.y = nodeDatum.label.y;
      tempText.setFont(label);
      tempText.setAlign(nodeDatum.label);
      const box = tempText.getBBox();
      textBoxes.push(box);
    }
    if (textBoxes.length === 0) {
      return null;
    }
    return BBox28.merge(textBoxes);
  }
  getLineNode() {
    return this.lineSelection?.at(0);
  }
  beforePathAnimation() {
    this.updatePathNodes();
  }
  getPathNodesStyle() {
    const highlightDatum = this.ctx.highlightManager?.getActiveHighlight();
    const highlightState = this.getHighlightState(highlightDatum);
    const highlightStyle = this.getHighlightStyle(void 0, void 0, highlightState);
    const stylerStyle = this.getStyle(highlightState);
    return mergeDefaults(highlightStyle, stylerStyle);
  }
  getLinePoints() {
    const { nodeData, resetInvalidToZero } = this;
    const { connectMissingData } = this.properties;
    if (nodeData.length === 0) {
      return [];
    }
    const radiusAxis = this.axes["radius" /* Radius */];
    const angleAxis = this.axes["angle" /* Angle */];
    const reversedAngleAxis = angleAxis?.isReversed();
    const reversedRadiusAxis = radiusAxis?.isReversed();
    const data = reversedRadiusAxis && !reversedAngleAxis ? [...nodeData].reverse() : nodeData;
    const points = [];
    let prevPointInvalid = false;
    let firstValid;
    for (const [index, datum] of data.entries()) {
      let { x, y } = datum.point;
      const isPointInvalid = Number.isNaN(x) || Number.isNaN(y);
      if (!isPointInvalid) {
        firstValid ?? (firstValid = datum);
      }
      if (isPointInvalid && !connectMissingData) {
        x = 0;
        y = 0;
      }
      const moveTo2 = index === 0 || !resetInvalidToZero && !connectMissingData && (isPointInvalid || prevPointInvalid);
      points.push({ x, y, moveTo: moveTo2 });
      prevPointInvalid = isPointInvalid;
    }
    if (firstValid !== void 0) {
      points.push({ x: firstValid.point.x, y: firstValid.point.y, moveTo: false });
    }
    return points;
  }
  animateSinglePath(pathNode, points, ratio2) {
    const { path } = pathNode;
    path.clear(true);
    const axisInnerRadius = this.getAxisInnerRadius();
    const radiusAxis = this.axes["radius" /* Radius */];
    const reversedRadiusAxis = radiusAxis?.isReversed();
    const radiusZero = reversedRadiusAxis ? this.radius + axisInnerRadius - radiusAxis?.scale.convert(0) : axisInnerRadius;
    for (const point of points) {
      const { x: x1, y: y1, arc, radius = 0, startAngle = 0, endAngle = 0, moveTo: moveTo2 } = point;
      const angle2 = Math.atan2(y1, x1);
      const x0 = radiusZero * Math.cos(angle2);
      const y0 = radiusZero * Math.sin(angle2);
      const t = ratio2;
      const x = x0 * (1 - t) + x1 * t;
      const y = y0 * (1 - t) + y1 * t;
      if (arc) {
        path.arc(x1, y1, radius, startAngle, endAngle);
      } else if (moveTo2) {
        path.moveTo(x, y);
      } else {
        path.lineTo(x, y);
      }
    }
    pathNode.checkPathDirty();
  }
  animatePaths(ratio2) {
    const linePoints = this.getLinePoints();
    const lineNode = this.getLineNode();
    if (!lineNode)
      return;
    this.animateSinglePath(lineNode, linePoints, ratio2);
  }
  animateEmptyUpdateReady() {
    const { itemSelection, labelSelection } = this;
    const { animationManager } = this.ctx;
    this.beforePathAnimation();
    animationManager.animate({
      id: `${this.id}_'path`,
      groupId: this.id,
      from: 0,
      to: 1,
      phase: "initial",
      collapsable: false,
      onUpdate: (ratio2) => this.animatePaths(ratio2),
      onStop: () => this.animatePaths(1)
    });
    markerFadeInAnimation3(this, animationManager, "added", this.getAnimationDrawingModes(), itemSelection);
    seriesLabelFadeInAnimation8(this, "labels", animationManager, labelSelection, this.highlightLabelSelection);
  }
  animateWaitingUpdateReady(data) {
    super.animateWaitingUpdateReady(data);
    this.resetPaths();
  }
  animateReadyResize(data) {
    super.animateReadyResize(data);
    this.resetPaths();
  }
  resetPaths() {
    const lineNode = this.getLineNode();
    if (lineNode) {
      const { path: linePath } = lineNode;
      const linePoints = this.getLinePoints();
      const stylerStyle = this.getStyle();
      lineNode.fill = void 0;
      lineNode.stroke = stylerStyle.stroke;
      lineNode.strokeWidth = stylerStyle.strokeWidth;
      lineNode.strokeOpacity = stylerStyle.strokeOpacity;
      lineNode.lineDash = stylerStyle.lineDash;
      lineNode.lineDashOffset = stylerStyle.lineDashOffset;
      linePath.clear(true);
      for (const { x, y, moveTo: moveTo2 } of linePoints) {
        if (moveTo2) {
          linePath.moveTo(x, y);
        } else {
          linePath.lineTo(x, y);
        }
      }
      lineNode.checkPathDirty();
      return stylerStyle;
    }
  }
  getStylerResult(stylerResult, highlightState) {
    const { styler } = this.properties;
    if (styler) {
      const stylerParams = this.makeStylerParams(highlightState);
      const cbResult = this.cachedCallWithContext(styler, stylerParams) ?? {};
      const resolved = this.ctx.optionsGraphService.resolvePartial(
        ["series", `${this.declarationOrder}`],
        cbResult,
        { pick: false }
      );
      if (resolved) {
        stylerResult = resolved;
      }
    }
    return stylerResult;
  }
  getFormattedMarkerStyle(datum) {
    const { angleKey, radiusKey } = this.properties;
    return this.getMarkerStyle(this.properties.marker, datum, { angleKey, radiusKey }, { isHighlight: true });
  }
  computeFocusBounds(opts) {
    return computeMarkerFocusBounds3(this, opts);
  }
  hasItemStylers() {
    return this.properties.styler != null || this.properties.marker.itemStyler != null || this.properties.label.itemStyler != null;
  }
};
RadarSeries.className = "RadarSeries";

// packages/ag-charts-enterprise/src/series/radar-area/radarAreaSeriesProperties.ts
var RadarAreaSeriesProperties = class extends RadarSeriesProperties {
  constructor() {
    super(...arguments);
    this.fill = "black";
    this.fillOpacity = 1;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarAreaSeriesProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadarAreaSeriesProperties.prototype, "fillOpacity", 2);

// packages/ag-charts-enterprise/src/series/radar-area/radarAreaSeries.ts
var { Group: Group21, HighlightState: HighlightState7, Path: Path14, PointerEvents: PointerEvents10, Selection: Selection14, toHighlightString: toHighlightString6 } = module_support_exports;
var RadarAreaSeries = class extends RadarSeries {
  constructor(moduleCtx) {
    super(moduleCtx);
    this.properties = new RadarAreaSeriesProperties();
    this.areaGroup = this.contentGroup.appendChild(new Group21({ name: "radar-area" }));
    this.areaSelection = Selection14.select(
      this.areaGroup,
      Path14
    );
    this.resetInvalidToZero = true;
    this.areaGroup.zIndex = -1;
  }
  updatePathSelections() {
    const pathData = this.visible ? [true] : [];
    this.areaSelection.update(pathData);
    super.updatePathSelections();
  }
  getAreaNode() {
    return this.areaSelection.at(0);
  }
  getMarkerFill(highlightedStyle) {
    if (highlightedStyle?.fill != null)
      return highlightedStyle.fill;
    const stylerStyle = this.getStyle();
    return stylerStyle.marker.fill ?? stylerStyle.fill;
  }
  updatePathNodes() {
    const styles = this.getPathNodesStyle();
    const { fill, fillOpacity, strokeWidth, stroke: stroke3, strokeOpacity, lineDash, lineDashOffset, opacity } = styles;
    const lineNode = this.getLineNode();
    if (lineNode) {
      lineNode.setProperties({
        fill: void 0,
        lineJoin: "round",
        lineCap: "round",
        pointerEvents: PointerEvents10.None,
        opacity,
        stroke: stroke3,
        strokeWidth,
        strokeOpacity,
        lineDash,
        lineDashOffset
      });
    }
    const areaNode = this.getAreaNode();
    if (areaNode) {
      areaNode.setStyleProperties({ fill, fillOpacity, stroke: void 0 }, this.getShapeFillBBox());
      areaNode.setProperties({
        lineJoin: "round",
        pointerEvents: PointerEvents10.None,
        opacity
      });
    }
  }
  animatePaths(ratio2) {
    super.animatePaths(ratio2);
    const areaNode = this.getAreaNode();
    if (areaNode) {
      this.animateSinglePath(areaNode, this.getAreaPoints(), ratio2);
    }
  }
  getAreaPoints() {
    const points = this.getLinePoints();
    const getPolarAxis = (direction) => {
      const axis = this.axes[direction];
      return axis instanceof module_support_exports.PolarAxis ? axis : void 0;
    };
    const radiusAxis = getPolarAxis("radius" /* Radius */);
    const angleAxis = getPolarAxis("angle" /* Angle */);
    const reversedRadiusAxis = radiusAxis?.isReversed();
    if (!reversedRadiusAxis) {
      return points;
    }
    const zeroLinePoints = angleAxis?.getAxisLinePoints()?.points ?? [];
    return points.concat(...zeroLinePoints);
  }
  resetPaths() {
    const superStyle = super.resetPaths();
    const areaNode = this.getAreaNode();
    if (areaNode) {
      const { path: areaPath } = areaNode;
      const areaPoints = this.getAreaPoints();
      const stylerStyle = superStyle ?? this.getStyle();
      const fillBBox = this.getShapeFillBBox();
      areaNode.setStyleProperties(
        {
          fill: stylerStyle.fill,
          stroke: void 0,
          fillOpacity: stylerStyle.fillOpacity,
          lineDash: stylerStyle.lineDash,
          lineDashOffset: stylerStyle.lineDashOffset
        },
        fillBBox
      );
      areaNode.lineJoin = areaNode.lineCap = "round";
      areaPath.clear(true);
      for (const { x, y, moveTo: moveTo2, arc, radius = 0, startAngle = 0, endAngle = 0 } of areaPoints) {
        if (arc) {
          areaPath.arc(x, y, radius, startAngle, endAngle);
        } else if (moveTo2) {
          areaPath.moveTo(x, y);
        } else {
          areaPath.lineTo(x, y);
        }
      }
      areaPath.closePath();
      areaNode.checkPathDirty();
      return stylerStyle;
    }
  }
  makeStylerParams(highlightStateEnum) {
    const { properties } = this;
    const highlightState = toHighlightString6(highlightStateEnum ?? HighlightState7.None);
    return {
      marker: {
        fill: properties.marker.fill,
        fillOpacity: properties.marker.fillOpacity,
        size: properties.marker.size,
        shape: properties.marker.shape,
        stroke: properties.marker.stroke,
        strokeOpacity: properties.marker.strokeOpacity,
        strokeWidth: properties.marker.strokeWidth,
        lineDash: properties.marker.lineDash,
        lineDashOffset: properties.marker.lineDashOffset
      },
      highlightState,
      fill: properties.fill,
      fillOpacity: properties.fillOpacity,
      lineDash: properties.lineDash,
      lineDashOffset: properties.lineDashOffset,
      seriesId: this.id,
      stroke: properties.stroke,
      strokeOpacity: properties.strokeOpacity,
      strokeWidth: properties.strokeWidth,
      angleKey: properties.angleKey,
      radiusKey: properties.radiusKey
    };
  }
  getStyle(highlightState) {
    const { marker, fill, fillOpacity, lineDash, lineDashOffset, stroke: stroke3, strokeOpacity, strokeWidth } = this.properties;
    const { size, shape, fill: markerFill = "transparent", fillOpacity: markerFillOpacity } = marker;
    const stylerResult = this.getStylerResult({}, highlightState);
    stylerResult.marker ?? (stylerResult.marker = {});
    return {
      fill: stylerResult.fill ?? fill,
      fillOpacity: stylerResult.fillOpacity ?? fillOpacity,
      lineDash: stylerResult.lineDash ?? lineDash,
      lineDashOffset: stylerResult.lineDashOffset ?? lineDashOffset,
      stroke: stylerResult.stroke ?? stroke3,
      strokeOpacity: stylerResult.strokeOpacity ?? strokeOpacity,
      strokeWidth: stylerResult.strokeWidth ?? strokeWidth,
      marker: {
        enabled: stylerResult.marker.enabled ?? marker.enabled,
        fill: stylerResult.marker.fill ?? markerFill,
        fillOpacity: stylerResult.marker.fillOpacity ?? markerFillOpacity,
        shape: stylerResult.marker.shape ?? shape,
        size: stylerResult.marker.size ?? size,
        lineDash: stylerResult.marker.lineDash ?? marker.lineDash ?? lineDash,
        lineDashOffset: stylerResult.marker.lineDashOffset ?? marker.lineDashOffset ?? lineDashOffset,
        stroke: stylerResult.marker.stroke ?? marker.stroke ?? stroke3,
        strokeOpacity: stylerResult.marker.strokeOpacity ?? marker.strokeOpacity ?? strokeOpacity,
        strokeWidth: stylerResult.marker.strokeWidth ?? marker.strokeWidth ?? strokeWidth
      }
    };
  }
};
RadarAreaSeries.className = "RadarAreaSeries";
RadarAreaSeries.type = "radar-area";

// packages/ag-charts-enterprise/src/series/radar-area/radarAreaSeriesOptionsDef.ts
var { radarAreaSeriesThemeableOptionsDef: radarAreaSeriesThemeableOptionsDef2 } = module_support_exports;
var radarAreaSeriesOptionsDef = {
  ...commonSeriesOptionsDefs,
  ...radarAreaSeriesThemeableOptionsDef2,
  type: required(constant("radar-area")),
  angleKey: required(string),
  radiusKey: required(string),
  angleName: string,
  radiusName: string,
  legendItemName: string
};
radarAreaSeriesOptionsDef.angleKeyAxis = undocumented(string);
radarAreaSeriesOptionsDef.radiusKeyAxis = undocumented(string);

// packages/ag-charts-enterprise/src/series/radar-area/radarAreaModule.ts
var RadarAreaSeriesModule = {
  type: "series",
  name: "radar-area",
  chartType: "polar",
  enterprise: true,
  version: VERSION,
  dependencies: [PolarChartModule],
  options: radarAreaSeriesOptionsDef,
  defaultAxes: { angle: { type: "angle-category" /* ANGLE_CATEGORY */ }, radius: { type: "radius-number" /* RADIUS_NUMBER */ } },
  axisKeys: { ["angle" /* Angle */]: "angleKeyAxis", ["radius" /* Radius */]: "radiusKeyAxis" },
  themeTemplate: RADAR_AREA_SERIES_THEME,
  create: (ctx) => new RadarAreaSeries(ctx)
};

// packages/ag-charts-enterprise/src/series/radar-line/radarLineSeries.ts
var { HighlightState: HighlightState8, PointerEvents: PointerEvents11, toHighlightString: toHighlightString7 } = module_support_exports;
var RadarLineSeries = class extends RadarSeries {
  constructor() {
    super(...arguments);
    this.properties = new RadarSeriesProperties();
  }
  updatePathSelections() {
    this.lineSelection.update(this.visible ? [true] : []);
  }
  updatePathNodes() {
    const lineNode = this.getLineNode();
    if (!lineNode)
      return;
    const style2 = this.getPathNodesStyle();
    const { strokeWidth, stroke: stroke3, strokeOpacity, lineDash, lineDashOffset, opacity } = style2;
    lineNode.setProperties({
      fill: void 0,
      lineJoin: "round",
      lineCap: "round",
      pointerEvents: PointerEvents11.None,
      opacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset
    });
  }
  makeStylerParams(highlightStateEnum) {
    const { properties } = this;
    const highlightState = toHighlightString7(highlightStateEnum ?? HighlightState8.None);
    return {
      marker: {
        fill: properties.marker.fill,
        fillOpacity: properties.marker.fillOpacity,
        size: properties.marker.size,
        shape: properties.marker.shape,
        stroke: properties.marker.stroke,
        strokeOpacity: properties.marker.strokeOpacity,
        strokeWidth: properties.marker.strokeWidth,
        lineDash: properties.marker.lineDash,
        lineDashOffset: properties.marker.lineDashOffset
      },
      highlightState,
      lineDash: properties.lineDash,
      lineDashOffset: properties.lineDashOffset,
      seriesId: this.id,
      stroke: properties.stroke,
      strokeOpacity: properties.strokeOpacity,
      strokeWidth: properties.strokeWidth,
      angleKey: properties.angleKey,
      radiusKey: properties.radiusKey
    };
  }
  getStyle(highlightState) {
    const { marker, lineDash, lineDashOffset, stroke: stroke3, strokeOpacity, strokeWidth } = this.properties;
    const { size, shape, fill = "transparent", fillOpacity } = marker;
    const stylerResult = this.getStylerResult({}, highlightState);
    stylerResult.marker ?? (stylerResult.marker = {});
    return {
      lineDash: stylerResult.lineDash ?? lineDash,
      lineDashOffset: stylerResult.lineDashOffset ?? lineDashOffset,
      stroke: stylerResult.stroke ?? stroke3,
      strokeOpacity: stylerResult.strokeOpacity ?? strokeOpacity,
      strokeWidth: stylerResult.strokeWidth ?? strokeWidth,
      marker: {
        enabled: stylerResult.marker.enabled ?? marker.enabled,
        fill: stylerResult.marker.fill ?? fill,
        fillOpacity: stylerResult.marker.fillOpacity ?? fillOpacity,
        shape: stylerResult.marker.shape ?? shape,
        size: stylerResult.marker.size ?? size,
        lineDash: stylerResult.marker.lineDash ?? marker.lineDash ?? lineDash,
        lineDashOffset: stylerResult.marker.lineDashOffset ?? marker.lineDashOffset ?? lineDashOffset,
        stroke: stylerResult.marker.stroke ?? marker.stroke ?? stroke3,
        strokeOpacity: stylerResult.marker.strokeOpacity ?? marker.strokeOpacity ?? strokeOpacity,
        strokeWidth: stylerResult.marker.strokeWidth ?? marker.strokeWidth ?? strokeWidth
      }
    };
  }
};
RadarLineSeries.className = "RadarLineSeries";
RadarLineSeries.type = "radar-line";

// packages/ag-charts-enterprise/src/series/radar-line/radarLineSeriesOptionsDef.ts
var { radarLineSeriesThemeableOptionsDef: radarLineSeriesThemeableOptionsDef2 } = module_support_exports;
var radarLineSeriesOptionsDef = {
  ...commonSeriesOptionsDefs,
  ...radarLineSeriesThemeableOptionsDef2,
  type: required(constant("radar-line")),
  angleKey: required(string),
  radiusKey: required(string),
  angleName: string,
  radiusName: string,
  legendItemName: string
};
radarLineSeriesOptionsDef.angleKeyAxis = undocumented(string);
radarLineSeriesOptionsDef.radiusKeyAxis = undocumented(string);

// packages/ag-charts-enterprise/src/series/radar-line/radarLineModule.ts
var RadarLineSeriesModule = {
  type: "series",
  name: "radar-line",
  chartType: "polar",
  enterprise: true,
  version: VERSION,
  dependencies: [PolarChartModule],
  options: radarLineSeriesOptionsDef,
  defaultAxes: { angle: { type: "angle-category" /* ANGLE_CATEGORY */ }, radius: { type: "radius-number" /* RADIUS_NUMBER */ } },
  axisKeys: { ["angle" /* Angle */]: "angleKeyAxis", ["radius" /* Radius */]: "radiusKeyAxis" },
  themeTemplate: RADAR_LINE_SERIES_THEME,
  create: (ctx) => new RadarLineSeries(ctx)
};

// packages/ag-charts-enterprise/src/series/radial-bar/radialBarSeriesProperties.ts
var { SeriesProperties: SeriesProperties9, makeSeriesTooltip: makeSeriesTooltip20, Label: Label18 } = module_support_exports;
var RadialBarSeriesProperties = class extends SeriesProperties9 {
  constructor() {
    super(...arguments);
    this.angleKeyAxis = "angle";
    this.radiusKeyAxis = "radius";
    this.fill = "black";
    this.fillOpacity = 1;
    this.stroke = "black";
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.cornerRadius = 0;
    this.rotation = 0;
    this.label = new Label18();
    this.tooltip = makeSeriesTooltip20();
  }
  getStyle() {
    const { fill, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset, cornerRadius } = this;
    return {
      fill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset,
      cornerRadius,
      opacity: 1
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "angleKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "radiusKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "angleName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "radiusName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "angleKeyAxis", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "radiusKeyAxis", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "legendItemName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "cornerRadius", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "styler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "itemStyler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "rotation", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "stackGroup", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "normalizedTo", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialBarSeriesProperties.prototype, "tooltip", 2);

// packages/ag-charts-enterprise/src/series/radial-bar/radialBarUtil.ts
var { SectorBox: SectorBox6, motion: motion10 } = module_support_exports;
function fixRadialBarAnimationStatus(node, datum, status) {
  if (status === "updated") {
    if (node.previousDatum == null || Number.isNaN(node.previousDatum.innerRadius) || Number.isNaN(node.previousDatum.outerRadius)) {
      return "added";
    }
    if (Number.isNaN(datum.innerRadius) || Number.isNaN(datum.outerRadius)) {
      return "removed";
    }
  }
  if (status === "added" && node.previousDatum != null) {
    return "updated";
  }
  return status;
}
function prepareRadialBarSeriesAnimationFunctions(axisZeroAngle) {
  const fromFn = (sect, datum, status) => {
    status = fixRadialBarAnimationStatus(sect, datum, status);
    let startAngle;
    let endAngle;
    let innerRadius;
    let outerRadius;
    let clipSector;
    if (status === "removed" || status === "updated") {
      startAngle = sect.startAngle;
      endAngle = sect.endAngle;
      innerRadius = sect.innerRadius;
      outerRadius = sect.outerRadius;
      clipSector = sect.clipSector;
    } else {
      startAngle = axisZeroAngle;
      endAngle = axisZeroAngle;
      innerRadius = datum.innerRadius;
      outerRadius = datum.outerRadius;
    }
    clipSector ?? (clipSector = new SectorBox6(startAngle, endAngle, innerRadius, outerRadius));
    const phase = motion10.NODE_UPDATE_STATE_TO_PHASE_MAPPING[status];
    return { startAngle, endAngle, innerRadius, outerRadius, clipSector, phase };
  };
  const toFn = (sect, datum, status) => {
    let startAngle;
    let endAngle;
    let innerRadius;
    let outerRadius;
    let clipSector;
    if (status === "removed") {
      startAngle = axisZeroAngle;
      endAngle = axisZeroAngle;
      innerRadius = datum.innerRadius;
      outerRadius = datum.outerRadius;
      clipSector = new SectorBox6(startAngle, endAngle, innerRadius, outerRadius);
    } else {
      startAngle = datum.startAngle;
      endAngle = datum.endAngle;
      innerRadius = Number.isNaN(datum.innerRadius) ? sect.innerRadius : datum.innerRadius;
      outerRadius = Number.isNaN(datum.outerRadius) ? sect.outerRadius : datum.outerRadius;
      clipSector = datum.clipSector;
    }
    return { startAngle, endAngle, innerRadius, outerRadius, clipSector };
  };
  return { toFn, fromFn };
}
function resetRadialBarSelectionsFn(_node, datum) {
  return {
    centerX: 0,
    centerY: 0,
    innerRadius: datum.innerRadius,
    outerRadius: datum.outerRadius,
    startAngle: datum.startAngle,
    endAngle: datum.endAngle,
    clipSector: datum.clipSector
  };
}

// packages/ag-charts-enterprise/src/series/radial-bar/radialBarSeries.ts
var {
  DEFAULT_POLAR_DIRECTION_KEYS: DEFAULT_POLAR_DIRECTION_KEYS4,
  DEFAULT_POLAR_DIRECTION_NAMES: DEFAULT_POLAR_DIRECTION_NAMES4,
  PolarAxis: PolarAxis4,
  diff: diff8,
  groupAccumulativeValueProperty: groupAccumulativeValueProperty4,
  keyProperty: keyProperty12,
  normaliseGroupTo: normaliseGroupTo3,
  valueProperty: valueProperty15,
  fixNumericExtent: fixNumericExtent11,
  resetLabelFn: resetLabelFn8,
  seriesLabelFadeInAnimation: seriesLabelFadeInAnimation9,
  seriesLabelFadeOutAnimation: seriesLabelFadeOutAnimation3,
  animationValidation: animationValidation10,
  createDatumId: createDatumId19,
  CategoryScale: CategoryScale5,
  Sector: Sector8,
  SectorBox: SectorBox7,
  motion: motion11,
  updateLabelNode: updateLabelNode9,
  getItemStyles: getItemStyles5
} = module_support_exports;
var RadialBarSeriesNodeEvent = class extends module_support_exports.SeriesNodeEvent {
  constructor(type, nativeEvent, datum, series) {
    super(type, nativeEvent, datum, series);
    this.angleKey = series.properties.angleKey;
    this.radiusKey = series.properties.radiusKey;
  }
};
var RadialBarSeries = class extends module_support_exports.PolarSeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      categoryKey: "radiusValue",
      propertyKeys: DEFAULT_POLAR_DIRECTION_KEYS4,
      propertyNames: DEFAULT_POLAR_DIRECTION_NAMES4,
      canHaveAxes: true,
      animationResetFns: {
        item: resetRadialBarSelectionsFn,
        label: resetLabelFn8
      }
    });
    this.properties = new RadialBarSeriesProperties();
    this.NodeEvent = RadialBarSeriesNodeEvent;
    this.groupScale = new CategoryScale5();
    this.circleCache = { r: 0, cx: 0, cy: 0 };
  }
  nodeFactory() {
    return new Sector8();
  }
  getSeriesDomain(direction) {
    const { dataModel, processedData } = this;
    if (!processedData || !dataModel)
      return { domain: [] };
    if (direction === "angle" /* Angle */) {
      const xExtent = dataModel.getDomain(this, "angleValue-end", "value", processedData).domain;
      const fixedXExtent = [Math.min(xExtent[0], 0), Math.max(xExtent[1], 0)];
      return { domain: fixNumericExtent11(fixedXExtent) };
    } else {
      return dataModel.getDomain(this, "radiusValue", "key", processedData);
    }
  }
  async processData(dataController) {
    const { angleKey, radiusKey, normalizedTo } = this.properties;
    const animationEnabled = !this.ctx.animationManager.isSkipped();
    const stackGroupId = this.getStackId();
    const stackGroupTrailingId = `${stackGroupId}-trailing`;
    const extraProps = [];
    if (isDefined(normalizedTo)) {
      extraProps.push(normaliseGroupTo3([stackGroupId, stackGroupTrailingId], Math.abs(normalizedTo)));
    }
    if (this.needsDataModelDiff() && this.processedData) {
      extraProps.push(diff8(this.id, this.processedData));
    }
    if (animationEnabled) {
      extraProps.push(animationValidation10());
    }
    const visibleProps = this.visible ? {} : { forceValue: 0 };
    const radiusScaleType = this.axes["radius" /* Radius */]?.scale.type;
    const angleScaleType = this.axes["angle" /* Angle */]?.scale.type;
    const allowNullKey = this.properties.allowNullKeys ?? false;
    await this.requestDataModel(dataController, this.data, {
      props: [
        keyProperty12(radiusKey, radiusScaleType, { id: "radiusValue", allowNullKey }),
        valueProperty15(angleKey, angleScaleType, {
          id: "angleValue-raw",
          invalidValue: null,
          ...visibleProps
        }),
        ...groupAccumulativeValueProperty4(
          angleKey,
          "normal",
          {
            id: `angleValue-end`,
            rangeId: `angleValue-range`,
            invalidValue: null,
            groupId: stackGroupId,
            separateNegative: true,
            ...visibleProps
          },
          angleScaleType
        ),
        ...groupAccumulativeValueProperty4(
          angleKey,
          "trailing",
          {
            id: `angleValue-start`,
            invalidValue: null,
            groupId: stackGroupTrailingId,
            separateNegative: true,
            ...visibleProps
          },
          angleScaleType
        ),
        ...extraProps
      ],
      groupByKeys: true,
      groupByData: false
    });
    this.animationState.transition("updateData");
  }
  didCircleChange() {
    const r = this.radius;
    const cx = this.centerX;
    const cy = this.centerY;
    const cache = this.circleCache;
    if (!(r === cache.r && cx === cache.cx && cy === cache.cy)) {
      this.circleCache = { r, cx, cy };
      return true;
    }
    return false;
  }
  maybeRefreshNodeData() {
    const circleChanged = this.didCircleChange();
    if (!circleChanged && !this.nodeDataRefresh)
      return;
    this.contextNodeData = this.createNodeData();
    this.nodeData = this.contextNodeData?.nodeData ?? [];
    this.nodeDataRefresh = false;
  }
  getAxisInnerRadius() {
    const radiusAxis = this.axes["radius" /* Radius */];
    return radiusAxis instanceof PolarAxis4 ? this.radius * radiusAxis.innerRadiusRatio : 0;
  }
  createNodeData() {
    const { processedData, dataModel } = this;
    if (!dataModel || processedData?.type !== "grouped")
      return;
    const angleAxis = this.axes["angle" /* Angle */];
    const radiusAxis = this.axes["radius" /* Radius */];
    const angleScale = angleAxis?.scale;
    const radiusScale = radiusAxis?.scale;
    if (!angleScale || !radiusScale) {
      return;
    }
    const radiusValues = dataModel.resolveKeysById(this, "radiusValue", processedData);
    const angleStartValues = dataModel.resolveColumnById(this, `angleValue-start`, processedData);
    const angleEndValues = dataModel.resolveColumnById(this, `angleValue-end`, processedData);
    const angleRawValues = dataModel.resolveColumnById(this, `angleValue-raw`, processedData);
    const angleRangeIndex = dataModel.resolveProcessedDataIndexById(this, `angleValue-range`);
    let groupPaddingInner = 0;
    if (radiusAxis instanceof RadiusCategoryAxis) {
      groupPaddingInner = radiusAxis.groupPaddingInner;
    }
    const { groupScale } = this;
    const { index: groupIndex, visibleGroupCount } = this.ctx.seriesStateManager.getVisiblePeerGroupIndex(this);
    groupScale.domain = Array.from({ length: visibleGroupCount }).map((_, i) => String(i));
    groupScale.range = [0, Math.abs(radiusScale.bandwidth ?? 0)];
    groupScale.paddingInner = visibleGroupCount > 1 ? groupPaddingInner : 0;
    const barWidth = groupScale.bandwidth >= 1 ? groupScale.bandwidth : groupScale.rawBandwidth;
    const angleAxisReversed = angleAxis.isReversed();
    const radiusAxisReversed = radiusAxis.isReversed();
    const axisInnerRadius = radiusAxisReversed ? this.radius : this.getAxisInnerRadius();
    const axisOuterRadius = radiusAxisReversed ? this.getAxisInnerRadius() : this.radius;
    const axisTotalRadius = axisOuterRadius + axisInnerRadius;
    const angleDomain = this.getSeriesDomain("angle" /* Angle */).domain;
    const { angleKey, radiusKey, angleName, radiusName, legendItemName, label } = this.properties;
    const getLabelNodeDatum = (datum, angleDatum, x, y) => {
      const labelText = this.getLabelText(
        angleDatum,
        datum,
        angleKey,
        "angle",
        angleDomain,
        label,
        { value: angleDatum, datum, angleKey, radiusKey, angleName, radiusName, legendItemName }
      );
      if (labelText) {
        return { x, y, text: labelText, textAlign: "center", textBaseline: "middle" };
      }
    };
    const nodeData = [];
    const styles = getItemStyles5(
      (nodeDatum, isHighlight, highlightState) => getItemStyle(this, nodeDatum, isHighlight, highlightState)
    );
    const context = {
      itemId: radiusKey,
      nodeData,
      labelData: nodeData,
      styles
    };
    if (!this.visible)
      return context;
    const { dataSources } = processedData;
    const rawData = dataSources.get(this.id)?.data ?? [];
    for (const { datumIndex, group } of dataModel.forEachGroupDatum(this, processedData)) {
      const datum = rawData[datumIndex];
      const radiusDatum = radiusValues[datumIndex];
      if (radiusDatum === void 0 && !this.properties.allowNullKeys)
        return;
      const angleDatum = angleRawValues[datumIndex];
      const angleStartDatum = angleStartValues[datumIndex];
      const angleEndDatum = angleEndValues[datumIndex];
      const isPositive = angleDatum >= 0 && !Object.is(angleDatum, -0);
      const angleRange = group.aggregation[angleRangeIndex][isPositive ? 1 : 0];
      const reversed = isPositive === angleAxisReversed;
      let startAngle = angleScale.convert(angleStartDatum, { clamp: true });
      let endAngle = angleScale.convert(angleEndDatum, { clamp: true });
      let rangeStartAngle = angleScale.convert(0, { clamp: true });
      let rangeEndAngle = angleScale.convert(angleRange, { clamp: true });
      if (reversed) {
        [rangeStartAngle, rangeEndAngle] = [rangeEndAngle, rangeStartAngle];
        [startAngle, endAngle] = [endAngle, startAngle];
      }
      const dataRadius = axisTotalRadius - radiusScale.convert(radiusDatum);
      const innerRadius = dataRadius + groupScale.convert(String(groupIndex));
      const outerRadius = innerRadius + barWidth;
      const midRadius = (innerRadius + outerRadius) / 2;
      const midAngle = startAngle + angleBetween(startAngle, endAngle) / 2;
      const x = Math.cos(midAngle) * midRadius;
      const y = Math.sin(midAngle) * midRadius;
      const labelNodeDatum = this.properties.label.enabled ? getLabelNodeDatum(datum, angleDatum, x, y) : void 0;
      const clipSector = new SectorBox7(startAngle, endAngle, innerRadius, outerRadius);
      nodeData.push({
        series: this,
        datum,
        datumIndex,
        point: { x, y, size: 0 },
        midPoint: { x, y },
        label: labelNodeDatum,
        angleValue: angleDatum,
        radiusValue: radiusDatum,
        innerRadius,
        outerRadius,
        startAngle: rangeStartAngle,
        endAngle: rangeEndAngle,
        clipSector,
        reversed,
        index: datumIndex
      });
    }
    return context;
  }
  update({ seriesRect }) {
    const resize = this.checkResize(seriesRect);
    this.maybeRefreshNodeData();
    this.contentGroup.translationX = this.centerX;
    this.contentGroup.translationY = this.centerY;
    this.highlightGroup.translationX = this.centerX;
    this.highlightGroup.translationY = this.centerY;
    if (this.labelGroup) {
      this.labelGroup.translationX = this.centerX;
      this.labelGroup.translationY = this.centerY;
    }
    this.updateSectorSelection(this.itemSelection, false);
    this.updateSectorSelection(this.highlightSelection, true);
    this.updateLabels();
    if (resize) {
      this.animationState.transition("resize");
    }
    this.animationState.transition("update");
  }
  updateSectorSelection(selection, isHighlight) {
    let selectionData = [];
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    if (isHighlight) {
      if (activeHighlight?.datum && activeHighlight.series === this) {
        selectionData.push(activeHighlight);
      }
    } else {
      selectionData = this.nodeData;
    }
    const { contextNodeData } = this;
    if (!contextNodeData) {
      return;
    }
    const highlightedDatum = this.ctx.highlightManager.getActiveHighlight();
    const fillBBox = this.getShapeFillBBox();
    const hasItemStylers = this.hasItemStylers();
    selection.update(selectionData, void 0, (datum) => this.getDatumId(datum)).each((node, nodeDatum) => {
      const datum = readDatum(nodeDatum);
      if (datum == null)
        return;
      if (hasItemStylers) {
        const highlightState = this.getHighlightState(activeHighlight, isHighlight, nodeDatum.datumIndex);
        nodeDatum.style = getItemStyle(this, nodeDatum, isHighlight, highlightState);
      }
      const style2 = nodeDatum.style ?? contextNodeData.styles[this.getHighlightState(highlightedDatum, isHighlight, nodeDatum.datumIndex)];
      const cornerRadius = style2.cornerRadius;
      const fill = style2.fill;
      const fillParams = isGradientFill(fill) && fill.bounds !== "item" ? { centerX: 0, centerY: 0 } : void 0;
      node.setStyleProperties(style2, fillBBox, fillParams);
      node.lineJoin = "round";
      node.inset = node.stroke == null ? 0 : node.strokeWidth / 2;
      node.startInnerCornerRadius = datum.reversed ? cornerRadius : 0;
      node.startOuterCornerRadius = datum.reversed ? cornerRadius : 0;
      node.endInnerCornerRadius = datum.reversed ? 0 : cornerRadius;
      node.endOuterCornerRadius = datum.reversed ? 0 : cornerRadius;
      if (isHighlight) {
        node.startAngle = nodeDatum.startAngle;
        node.endAngle = nodeDatum.endAngle;
        node.clipSector = nodeDatum.clipSector;
        node.innerRadius = nodeDatum.innerRadius;
        node.outerRadius = nodeDatum.outerRadius;
      }
    });
  }
  updateLabels() {
    const { properties } = this;
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const highlightDatum = activeHighlight?.series === this && activeHighlight?.datum ? activeHighlight : void 0;
    const highlightData = highlightDatum ? [highlightDatum] : [];
    this.labelSelection.update(this.nodeData).each((node, datum) => {
      const isHighlight = false;
      updateLabelNode9(this, node, properties, properties.label, datum.label, isHighlight, activeHighlight);
      node.fillOpacity = this.getHighlightStyle(isHighlight, datum.datumIndex).opacity ?? 1;
    });
    this.highlightLabelSelection.update(highlightData, void 0, (datum) => this.getDatumId(datum)).each((node, datum) => {
      const isHighlight = true;
      updateLabelNode9(this, node, properties, properties.label, datum.label, isHighlight, activeHighlight);
      node.fillOpacity = this.getHighlightStyle(isHighlight, datum.datumIndex).opacity ?? 1;
    });
  }
  getBarTransitionFunctions() {
    const angleScale = this.axes["angle" /* Angle */]?.scale;
    let axisZeroAngle = 0;
    if (!angleScale) {
      return prepareRadialBarSeriesAnimationFunctions(axisZeroAngle);
    }
    const d0 = Math.min(angleScale.domain[0], angleScale.domain[1]);
    const d1 = Math.max(angleScale.domain[0], angleScale.domain[1]);
    if (d0 <= 0 && d1 >= 0) {
      axisZeroAngle = angleScale.convert(0);
    }
    return prepareRadialBarSeriesAnimationFunctions(axisZeroAngle);
  }
  animateEmptyUpdateReady() {
    const { labelSelection } = this;
    const fns = this.getBarTransitionFunctions();
    motion11.fromToMotion(this.id, "datums", this.ctx.animationManager, [this.itemSelection], fns);
    seriesLabelFadeInAnimation9(
      this,
      "labels",
      this.ctx.animationManager,
      labelSelection,
      this.highlightLabelSelection
    );
  }
  animateClearingUpdateEmpty() {
    const { itemSelection } = this;
    const { animationManager } = this.ctx;
    const fns = this.getBarTransitionFunctions();
    motion11.fromToMotion(this.id, "datums", animationManager, [itemSelection], fns);
    seriesLabelFadeOutAnimation3(
      this,
      "labels",
      animationManager,
      this.labelSelection,
      this.highlightLabelSelection
    );
  }
  getTooltipContent(datumIndex) {
    const { id: seriesId, dataModel, processedData, axes, properties } = this;
    const { angleKey, angleName, radiusKey, radiusName, legendItemName, tooltip } = properties;
    const angleAxis = axes["angle" /* Angle */];
    const radiusAxis = axes["radius" /* Radius */];
    const nodeDatum = this.nodeData?.[datumIndex];
    if (!dataModel || !processedData || !angleAxis || !radiusAxis || !nodeDatum)
      return;
    const datum = processedData.dataSources.get(this.id)?.data[datumIndex];
    const radiusValue = dataModel.resolveKeysById(this, `radiusValue`, processedData)[datumIndex];
    const angleValue = dataModel.resolveColumnById(this, `angleValue-raw`, processedData)[datumIndex];
    if (radiusValue === void 0 && !this.properties.allowNullKeys)
      return;
    const format = getItemStyle(this, nodeDatum, false);
    return this.formatTooltipWithContext(
      tooltip,
      {
        heading: this.getAxisValueText(radiusAxis, "tooltip", radiusValue, datum, radiusKey, void 0),
        symbol: this.legendItemSymbol(),
        data: [
          {
            label: angleName,
            fallbackLabel: angleKey,
            value: this.getAxisValueText(angleAxis, "tooltip", angleValue, datum, angleKey, void 0),
            missing: module_support_exports.isTooltipValueMissing(angleValue)
          }
        ]
      },
      {
        seriesId,
        datum,
        title: angleName,
        angleKey,
        angleName,
        radiusKey,
        radiusName,
        legendItemName,
        ...format
      }
    );
  }
  pickNodeClosestDatum(point) {
    return this.pickNodeNearestDistantObject(point, this.itemSelection.nodes());
  }
  legendItemSymbol() {
    const { fill, stroke: stroke3, fillOpacity, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = getStyle(
      this,
      false,
      module_support_exports.HighlightState.None
    );
    const markerStyle = {
      fill: fill ?? "rgba(0, 0, 0, 0)",
      stroke: stroke3 ?? "rgba(0, 0, 0, 0)",
      fillOpacity,
      strokeOpacity,
      strokeWidth,
      lineDash,
      lineDashOffset
    };
    if (isGradientFill(markerStyle.fill)) {
      markerStyle.fill = { ...markerStyle.fill, gradient: "linear", rotation: 0, reverse: false };
    }
    return {
      marker: markerStyle
    };
  }
  getLegendData(legendType) {
    if (legendType !== "category") {
      return [];
    }
    const { id: seriesId, visible } = this;
    const { angleKey, angleName, legendItemName, showInLegend } = this.properties;
    return [
      {
        legendType: "category",
        id: seriesId,
        itemId: angleKey,
        seriesId,
        enabled: visible,
        label: {
          text: legendItemName ?? angleName ?? angleKey
        },
        symbol: this.legendItemSymbol(),
        legendItemName,
        hideInLegend: !showInLegend
      }
    ];
  }
  getDatumId(datum) {
    return createDatumId19(datum.radiusValue);
  }
  computeLabelsBBox() {
    return null;
  }
  getStackId() {
    const groupIndex = this.seriesGrouping?.groupIndex ?? this.id;
    return `radialBar-stack-${groupIndex}-xValues`;
  }
  hasItemStylers() {
    return this.properties.itemStyler != null || this.properties.styler != null || this.properties.label.itemStyler != null;
  }
};
RadialBarSeries.className = "RadialBarSeries";
RadialBarSeries.type = "radial-bar";

// packages/ag-charts-enterprise/src/series/radial-bar/radialBarSeriesOptionsDef.ts
var { radialBarSeriesThemeableOptionsDef: radialBarSeriesThemeableOptionsDef2 } = module_support_exports;
var radialBarSeriesOptionsDef = {
  ...commonSeriesOptionsDefs,
  ...radialBarSeriesThemeableOptionsDef2,
  type: required(constant("radial-bar")),
  angleKey: required(string),
  radiusKey: required(string),
  angleName: string,
  radiusName: string,
  legendItemName: string,
  grouped: boolean,
  stacked: boolean,
  stackGroup: string,
  normalizedTo: number
};
radialBarSeriesOptionsDef.angleKeyAxis = undocumented(string);
radialBarSeriesOptionsDef.radiusKeyAxis = undocumented(string);

// packages/ag-charts-enterprise/src/series/radial-bar/radialBarThemes.ts
var RADIAL_BAR_SERIES_THEME = {
  series: {
    fill: {
      $applySwitch: [
        { $path: "type" },
        { $palette: "fill" },
        ["gradient", FILL_GRADIENT_CONIC_SERIES_DEFAULTS],
        ["image", FILL_IMAGE_DEFAULTS],
        ["pattern", FILL_PATTERN_DEFAULTS]
      ]
    },
    stroke: { $palette: "stroke" },
    strokeWidth: { $isUserOption: ["./stroke", 1, 0] },
    label: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: false,
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      fontWeight: { $ref: "fontWeight" },
      color: { $ref: "chartBackgroundColor" }
    },
    highlight: MULTI_SERIES_HIGHLIGHT_STYLE
  },
  axes: {
    ["radius-category" /* RADIUS_CATEGORY */]: {
      innerRadiusRatio: 0.2,
      groupPaddingInner: 0.2,
      paddingInner: 0.2,
      paddingOuter: 0.1
    }
  }
};

// packages/ag-charts-enterprise/src/series/radial-bar/radialBarModule.ts
var RadialBarSeriesModule = {
  type: "series",
  name: "radial-bar",
  chartType: "polar",
  enterprise: true,
  stackable: true,
  groupable: true,
  version: VERSION,
  dependencies: [PolarChartModule],
  options: radialBarSeriesOptionsDef,
  defaultAxes: { angle: { type: "angle-number" /* ANGLE_NUMBER */ }, radius: { type: "radius-category" /* RADIUS_CATEGORY */ } },
  axisKeys: { ["angle" /* Angle */]: "angleKeyAxis", ["radius" /* Radius */]: "radiusKeyAxis" },
  themeTemplate: RADIAL_BAR_SERIES_THEME,
  create: (ctx) => new RadialBarSeries(ctx)
};

// packages/ag-charts-enterprise/src/series/radial-column/radialColumnSeriesProperties.ts
var RadialColumnSeriesProperties = class extends RadialColumnSeriesBaseProperties {
};
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesProperties.prototype, "columnWidthRatio", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], RadialColumnSeriesProperties.prototype, "maxColumnWidthRatio", 2);

// packages/ag-charts-enterprise/src/series/radial-column/radialColumnSeries.ts
var { PolarAxis: PolarAxis5, RadialColumnShape: RadialColumnShape2, getRadialColumnWidth: getRadialColumnWidth2 } = module_support_exports;
var RadialColumnSeries = class extends RadialColumnSeriesBase {
  constructor(moduleCtx) {
    super(moduleCtx, {
      animationResetFns: {
        item: resetRadialColumnSelectionFn
      }
    });
    this.properties = new RadialColumnSeriesProperties();
  }
  getStackId() {
    const groupIndex = this.seriesGrouping?.groupIndex ?? this.id;
    return `radarColumn-stack-${groupIndex}-yValues`;
  }
  nodeFactory() {
    return new RadialColumnShape2();
  }
  getColumnTransitionFunctions() {
    const axisZeroRadius = this.isRadiusAxisReversed() ? this.radius : this.getAxisInnerRadius();
    return prepareRadialColumnAnimationFunctions(axisZeroRadius);
  }
  isRadiusAxisCircle() {
    const radiusAxis = this.axes["radius" /* Radius */];
    return radiusAxis instanceof PolarAxis5 ? radiusAxis.shape === "circle" : false;
  }
  updateItemPath(node, datum, highlight5) {
    node.isBeveled = this.isRadiusAxisCircle();
    if (highlight5) {
      node.innerRadius = datum.innerRadius;
      node.outerRadius = datum.outerRadius;
      node.startAngle = datum.startAngle;
      node.endAngle = datum.endAngle;
      node.columnWidth = datum.columnWidth;
      node.axisInnerRadius = datum.axisInnerRadius;
      node.axisOuterRadius = datum.axisOuterRadius;
    }
  }
  getColumnWidth(startAngle, endAngle) {
    const { columnWidthRatio = 0.5, maxColumnWidthRatio = 0.5 } = this.properties;
    return getRadialColumnWidth2(startAngle, endAngle, this.radius, columnWidthRatio, maxColumnWidthRatio);
  }
  hasItemStylers() {
    return this.properties.itemStyler != null || this.properties.styler != null || this.properties.label.itemStyler != null;
  }
};
RadialColumnSeries.className = "RadialColumnSeries";
RadialColumnSeries.type = "radial-column";

// packages/ag-charts-enterprise/src/series/radial-column/radialColumnSeriesOptionsDef.ts
var { radialColumnSeriesThemeableOptionsDef: radialColumnSeriesThemeableOptionsDef2 } = module_support_exports;
var radialColumnSeriesOptionsDef = {
  ...commonSeriesOptionsDefs,
  ...radialColumnSeriesThemeableOptionsDef2,
  type: required(constant("radial-column")),
  angleKey: required(string),
  radiusKey: required(string),
  angleName: string,
  radiusName: string,
  legendItemName: string,
  grouped: boolean,
  stacked: boolean,
  stackGroup: string,
  normalizedTo: number
};
radialColumnSeriesOptionsDef.angleKeyAxis = undocumented(string);
radialColumnSeriesOptionsDef.radiusKeyAxis = undocumented(string);

// packages/ag-charts-enterprise/src/series/radial-column/radialColumnThemes.ts
var RADIAL_COLUMN_SERIES_THEME = {
  series: {
    fill: {
      $applySwitch: [
        { $path: "type" },
        { $palette: "fill" },
        ["gradient", FILL_GRADIENT_RADIAL_SERIES_DEFAULTS],
        ["image", FILL_IMAGE_DEFAULTS],
        ["pattern", FILL_PATTERN_DEFAULTS]
      ]
    },
    stroke: { $palette: "stroke" },
    columnWidthRatio: 0.5,
    maxColumnWidthRatio: 0.5,
    strokeWidth: { $isUserOption: ["./stroke", 1, 0] },
    label: {
      ...LABEL_BOXING_DEFAULTS,
      enabled: false,
      fontSize: { $ref: "fontSize" },
      fontFamily: { $ref: "fontFamily" },
      fontWeight: { $ref: "fontWeight" },
      color: { $ref: "textColor" }
    },
    highlight: MULTI_SERIES_HIGHLIGHT_STYLE
  },
  axes: {
    ["angle-category" /* ANGLE_CATEGORY */]: {
      shape: { $findFirstSiblingNotOperation: "circle" /* CIRCLE */ },
      groupPaddingInner: 0,
      paddingInner: 0,
      label: {
        spacing: 10
      }
    },
    ["radius-number" /* RADIUS_NUMBER */]: {
      shape: { $findFirstSiblingNotOperation: "circle" /* CIRCLE */ },
      innerRadiusRatio: 0.5
    }
  }
};

// packages/ag-charts-enterprise/src/series/radial-column/radialColumnModule.ts
var RadialColumnSeriesModule = {
  type: "series",
  name: "radial-column",
  chartType: "polar",
  enterprise: true,
  stackable: true,
  groupable: true,
  version: VERSION,
  dependencies: [PolarChartModule],
  options: radialColumnSeriesOptionsDef,
  defaultAxes: { angle: { type: "angle-category" /* ANGLE_CATEGORY */ }, radius: { type: "radius-number" /* RADIUS_NUMBER */ } },
  axisKeys: { ["angle" /* Angle */]: "angleKeyAxis", ["radius" /* Radius */]: "radiusKeyAxis" },
  themeTemplate: RADIAL_COLUMN_SERIES_THEME,
  create: (ctx) => new RadialColumnSeries(ctx)
};

// packages/ag-charts-enterprise/src/module-bundles/polar.ts
var AllPolarModule2 = [
  AllPolarModule,
  AngleNumberAxisModule,
  AngleCategoryAxisModule,
  RadiusNumberAxisModule,
  RadiusCategoryAxisModule,
  NightingaleSeriesModule,
  RadarAreaSeriesModule,
  RadarLineSeriesModule,
  RadialBarSeriesModule,
  RadialColumnSeriesModule,
  AnimationModule,
  ContextMenuModule,
  DataSourceModule,
  GradientLegendModule
].flat();

// packages/ag-charts-enterprise/src/charts/topologyChart.ts
var { Chart: Chart3, MercatorScale: MercatorScale2 } = module_support_exports;
function isTopologySeries(series) {
  return series.type === "map-shape" || series.type === "map-line" || series.type === "map-marker" || series.type === "map-shape-background" || series.type === "map-line-background";
}
var TopologyChart = class extends Chart3 {
  constructor(options, resources) {
    super(options, resources);
    this.xAxis = { id: createId(module_support_exports.Axis), direction: "x" /* X */ };
    this.yAxis = { id: createId(module_support_exports.Axis), direction: "y" /* Y */ };
    this.ctx.zoomManager.setAxes([this.xAxis, this.yAxis]);
  }
  getChartType() {
    return "topology";
  }
  updateData() {
    super.updateData();
    const options = this.getOptions();
    if (this.topology !== options.topology) {
      this.topology = options.topology;
    }
    const { topology } = this;
    for (const series of this.series) {
      if (isTopologySeries(series)) {
        series.setChartTopology(topology);
      }
    }
  }
  performLayout(ctx) {
    const { seriesRoot, annotationRoot } = this;
    const seriesRect = ctx.layoutBox.clone().shrink(this.seriesArea.getPadding());
    this.seriesRect = seriesRect;
    this.animationRect = seriesRect;
    const mapSeries = this.series;
    const combinedBbox = mapSeries.reduce((combined, series) => {
      if (!series.visible)
        return combined;
      const bbox = series.topologyBounds;
      if (bbox == null)
        return combined;
      if (combined == null)
        return bbox;
      return combined.merge(bbox);
    }, void 0);
    let scale2;
    if (combinedBbox != null) {
      const { lon0, lat0, lon1, lat1 } = combinedBbox;
      const domain = [
        [lon0, lat0],
        [lon1, lat1]
      ];
      const bounds = MercatorScale2.bounds(domain);
      const { width: width2, height: height2 } = seriesRect;
      const viewBoxScale = Math.min(width2 / bounds.width, height2 / bounds.height);
      const viewBoxWidth = bounds.width * viewBoxScale;
      const viewBoxHeight = bounds.height * viewBoxScale;
      const viewBoxOriginX = (width2 - viewBoxWidth) / 2;
      const viewBoxOriginY = (height2 - viewBoxHeight) / 2;
      const x0 = viewBoxOriginX;
      const y0 = viewBoxOriginY;
      const x1 = viewBoxOriginX + viewBoxWidth;
      const y1 = viewBoxOriginY + viewBoxHeight;
      const xZoom = this.ctx.zoomManager.getAxisZoom(this.xAxis.id);
      const yZoom = this.ctx.zoomManager.getAxisZoom(this.yAxis.id);
      const xSpan = (x1 - x0) / (xZoom.max - xZoom.min);
      const xStart = x0 - xSpan * xZoom.min;
      const ySpan = (y1 - y0) / (1 - yZoom.min - (1 - yZoom.max));
      const yStart = y0 - ySpan * (1 - yZoom.max);
      scale2 = new MercatorScale2(domain, [
        [xStart, yStart],
        [xStart + xSpan, yStart + ySpan]
      ]);
    }
    for (const series of mapSeries) {
      series.scale = scale2;
    }
    const seriesVisible = this.series.some((s) => s.visible);
    seriesRoot.visible = seriesVisible;
    for (const group of [seriesRoot, annotationRoot]) {
      group.translationX = Math.floor(seriesRect.x);
      group.translationY = Math.floor(seriesRect.y);
      group.setClipRect(seriesRect.clone());
    }
    this.ctx.layoutManager.emitLayoutComplete(ctx, {
      series: { visible: seriesVisible, rect: seriesRect, paddedRect: ctx.layoutBox }
    });
  }
};
TopologyChart.className = "TopologyChart";
TopologyChart.type = "topology";
__decorateClass([
  addFakeTransformToInstanceProperty
], TopologyChart.prototype, "topology", 2);

// packages/ag-charts-enterprise/src/charts/topologyChartModule.ts
var { topologyChartOptionsDefs: topologyChartOptionsDefs2 } = module_support_exports;
var TopologyChartModule = {
  type: "chart",
  name: "topology",
  enterprise: true,
  version: VERSION,
  options: topologyChartOptionsDefs2,
  create(options, resources) {
    return new TopologyChart(options, resources);
  }
};

// packages/ag-charts-enterprise/src/series/map-util/mapThemeDefaults.ts
var MAP_THEME_DEFAULTS = {
  zoom: {
    axes: "xy",
    anchorPointX: "pointer",
    anchorPointY: "pointer",
    buttons: {
      // @ts-expect-error undocumented options
      anchorPointX: "middle",
      anchorPointY: "middle"
    }
  },
  legend: {
    enabled: false
  }
};
function applyMapPalette(object2) {
  const clone2 = deepClone(object2);
  jsonWalk(clone2, (value) => {
    if (typeof value === "object" && "$palette" in value) {
      value["$mapPalette"] = value["$palette"];
      delete value["$palette"];
    }
  });
  return clone2;
}

// packages/ag-charts-enterprise/src/series/map-util/lineStringUtil.ts
var delta4 = 1e-9;
function lineSegmentDistanceToPointSquared(a, b, x, y) {
  const [ax, ay] = a;
  const [bx, by] = b;
  const abx = bx - ax;
  const aby = by - ay;
  const l = abx * abx + aby * aby;
  let x0;
  let y0;
  if (Math.abs(l) < delta4) {
    x0 = ax;
    y0 = ay;
  } else {
    let t = ((x - ax) * abx + (y - ay) * aby) / l;
    t = Math.max(0, Math.min(1, t));
    x0 = ax + t * (bx - ax);
    y0 = ay + t * (by - ay);
  }
  const dx2 = x - x0;
  const dy2 = y - y0;
  return dx2 * dx2 + dy2 * dy2;
}
function lineStringDistance(lineString, x, y) {
  let minDistanceSquared = Infinity;
  let p0 = lineString.at(-1);
  for (const p1 of lineString) {
    minDistanceSquared = Math.min(minDistanceSquared, lineSegmentDistanceToPointSquared(p0, p1, x, y));
    p0 = p1;
  }
  return Math.sqrt(minDistanceSquared);
}
function lineStringLength(lineSegment) {
  let [x0, y0] = lineSegment[0];
  let totalDistance = 0;
  for (let i = 1; i < lineSegment.length; i += 1) {
    const [x1, y1] = lineSegment[i];
    const distance2 = Math.hypot(x1 - x0, y1 - y0);
    totalDistance += distance2;
    x0 = x1;
    y0 = y1;
  }
  return totalDistance;
}
function lineStringCenter(lineSegment) {
  if (lineSegment.length === 0)
    return;
  const targetDistance = lineStringLength(lineSegment) / 2;
  let [x0, y0] = lineSegment[0];
  let totalDistance = 0;
  for (let i = 1; i < lineSegment.length; i += 1) {
    const [x1, y1] = lineSegment[i];
    const segmentDistance = Math.hypot(x1 - x0, y1 - y0);
    const nextDistance = totalDistance + segmentDistance;
    if (nextDistance > targetDistance) {
      const ratio2 = (targetDistance - totalDistance) / segmentDistance;
      const point = [x0 + (x1 - x0) * ratio2, y0 + (y1 - y0) * ratio2];
      const angle2 = Math.atan2(y1 - y0, x1 - x0);
      return { point, angle: angle2 };
    }
    totalDistance = nextDistance;
    x0 = x1;
    y0 = y1;
  }
}

// packages/ag-charts-enterprise/src/series/map-util/lonLatBbox.ts
var LonLatBBox = class _LonLatBBox {
  constructor(lon0, lat0, lon1, lat1) {
    this.lon0 = lon0;
    this.lat0 = lat0;
    this.lon1 = lon1;
    this.lat1 = lat1;
  }
  extend(lon0, lat0, lon1, lat1) {
    this.lon0 = Math.min(this.lon0, lon0);
    this.lat0 = Math.min(this.lat0, lat0);
    this.lon1 = Math.max(this.lon1, lon1);
    this.lat1 = Math.max(this.lat1, lat1);
    return this;
  }
  merge(other) {
    return this.extend(other.lon0, other.lat0, other.lon1, other.lat1);
  }
  static extend(into, lon0, lat0, lon1, lat1) {
    return into ? into.extend(lon0, lat0, lon1, lat1) : new _LonLatBBox(lon0, lat0, lon1, lat1);
  }
};

// packages/ag-charts-enterprise/src/series/map-util/polygonUtil.ts
function polygonBbox(polygon, into) {
  for (const coordinates of polygon) {
    const [lon, lat] = coordinates;
    into = LonLatBBox.extend(into, lon, lat, lon, lat);
  }
  return into;
}
function polygonCentroid(polygon) {
  if (polygon.length === 0)
    return;
  let x = 0;
  let y = 0;
  let k = 0;
  let [x0, y0] = polygon.at(-1);
  for (const [x1, y1] of polygon) {
    const c = x0 * y1 - x1 * y0;
    k += c;
    x += (x0 + x1) * c;
    y += (y0 + y1) * c;
    x0 = x1;
    y0 = y1;
  }
  k *= 3;
  return [x / k, y / k];
}
function polygonDistance(polygons, x, y) {
  let inside = false;
  let minDistanceSquared = Infinity;
  for (const polygon of polygons) {
    let p0 = polygon.at(-1);
    let [x0, y0] = p0;
    for (const p1 of polygon) {
      const [x1, y1] = p1;
      if (y1 > y !== y0 > y && x < (x0 - x1) * (y - y1) / (y0 - y1) + x1) {
        inside = !inside;
      }
      minDistanceSquared = Math.min(minDistanceSquared, lineSegmentDistanceToPointSquared(p0, p1, x, y));
      p0 = p1;
      x0 = x1;
      y0 = y1;
    }
  }
  return (inside ? -1 : 1) * Math.sqrt(minDistanceSquared);
}

// packages/ag-charts-enterprise/src/series/map-util/geoGeometry.ts
var { Path: Path15, ExtendedPath2D: ExtendedPath2D6, BBox: BBox29 } = module_support_exports;
var GeoGeometry = class extends Path15 {
  constructor() {
    super(...arguments);
    this.projectedGeometry = void 0;
    this.renderMode = 3 /* All */;
    // Keep non-filled shapes separate so we don't fill them
    this.strokePath = new ExtendedPath2D6();
  }
  computeBBox() {
    if (this.dirtyPath || this.isDirtyPath()) {
      this.updatePath();
      this.dirtyPath = false;
    }
    return this.bbox?.clone();
  }
  updatePath() {
    const { projectedGeometry } = this;
    this.strokePath.clear();
    this.path.clear();
    this.bbox = projectedGeometry == null ? void 0 : this.drawGeometry(projectedGeometry, void 0);
  }
  drawPath(ctx) {
    super.drawPath(ctx);
    this.renderStroke(ctx, this.strokePath.getPath2D());
  }
  containsPoint(x, y) {
    const { projectedGeometry } = this;
    if (projectedGeometry == null)
      return false;
    if (!this.getBBox().containsPoint(x, y))
      return false;
    return this.geometryDistance(projectedGeometry, x, y) <= 0;
  }
  distanceSquared(x, y) {
    const { projectedGeometry } = this;
    if (projectedGeometry == null)
      return Infinity;
    const distance2 = this.geometryDistance(projectedGeometry, x, y);
    return distance2 > 0 ? distance2 * distance2 : 0;
  }
  geometryDistance(geometry, x, y) {
    const { renderMode, strokeWidth } = this;
    const drawPolygons = (renderMode & 1 /* Polygons */) !== 0;
    const drawLines = (renderMode & 2 /* Lines */) !== 0;
    const minStrokeDistance = Math.max(strokeWidth / 2, 1) + 1;
    switch (geometry.type) {
      case "GeometryCollection":
        return geometry.geometries.reduce(
          (minDistance, g) => Math.min(minDistance, this.geometryDistance(g, x, y)),
          Infinity
        );
      case "MultiPolygon":
        return drawPolygons ? geometry.coordinates.reduce(
          (minDistance, polygon) => Math.min(minDistance, Math.max(polygonDistance(polygon, x, y), 0)),
          Infinity
        ) : Infinity;
      case "Polygon":
        return drawPolygons ? Math.max(polygonDistance(geometry.coordinates, x, y), 0) : Infinity;
      case "MultiLineString":
        return drawLines ? geometry.coordinates.reduce((minDistance, lineString) => {
          return Math.min(
            minDistance,
            Math.max(lineStringDistance(lineString, x, y) - minStrokeDistance, 0)
          );
        }, Infinity) : Infinity;
      case "LineString":
        return drawLines ? Math.max(lineStringDistance(geometry.coordinates, x, y) - minStrokeDistance, 0) : Infinity;
      case "MultiPoint":
      case "Point":
      default:
        return Infinity;
    }
  }
  shouldDrawPolygons() {
    return (this.renderMode & 1 /* Polygons */) !== 0;
  }
  shouldDrawLines() {
    return (this.renderMode & 2 /* Lines */) !== 0;
  }
  drawGeometryCollection(geometries, bbox) {
    for (const g of geometries) {
      bbox = this.drawGeometry(g, bbox);
    }
    return bbox;
  }
  drawMultiPolygon(coordinates, bbox) {
    if (!this.shouldDrawPolygons())
      return bbox;
    for (const polygon of coordinates) {
      bbox = this.drawPolygon(this.path, polygon, bbox);
    }
    return bbox;
  }
  drawSinglePolygon(coordinates, bbox) {
    if (!this.shouldDrawPolygons())
      return bbox;
    return this.drawPolygon(this.path, coordinates, bbox);
  }
  drawMultiLineString(coordinates, bbox) {
    if (!this.shouldDrawLines())
      return bbox;
    for (const lineString of coordinates) {
      bbox = this.drawLineString(this.strokePath, lineString, bbox, false);
    }
    return bbox;
  }
  drawSingleLineString(coordinates, bbox) {
    if (!this.shouldDrawLines())
      return bbox;
    return this.drawLineString(this.strokePath, coordinates, bbox, false);
  }
  drawGeometry(geometry, bbox) {
    switch (geometry.type) {
      case "GeometryCollection":
        return this.drawGeometryCollection(geometry.geometries, bbox);
      case "MultiPolygon":
        return this.drawMultiPolygon(geometry.coordinates, bbox);
      case "Polygon":
        return this.drawSinglePolygon(geometry.coordinates, bbox);
      case "MultiLineString":
        return this.drawMultiLineString(geometry.coordinates, bbox);
      case "LineString":
        return this.drawSingleLineString(geometry.coordinates, bbox);
      case "Point":
      case "MultiPoint":
        return bbox;
    }
  }
  drawPolygon(path, polygons, bbox) {
    if (polygons.length < 1)
      return bbox;
    bbox = this.drawLineString(path, polygons[0], bbox, true);
    for (let i = 1; i < polygons.length; i += 1) {
      const enclave = polygons[i];
      this.drawLineString(path, enclave, void 0, true);
    }
    return bbox;
  }
  drawLineString(path, coordinates, bbox, isClosed) {
    if (coordinates.length < 2)
      return bbox;
    const end3 = isClosed ? coordinates.length - 1 : coordinates.length;
    for (let i = 0; i < end3; i += 1) {
      const [x, y] = coordinates[i];
      if (i === 0) {
        path.moveTo(x, y);
      } else {
        path.lineTo(x, y);
      }
      if (bbox == null) {
        bbox = new BBox29(x, y, 0, 0);
      } else {
        const { x: x0, y: y0 } = bbox;
        const x1 = x0 + bbox.width;
        const y1 = y0 + bbox.height;
        bbox.x = Math.min(x0, x);
        bbox.y = Math.min(y0, y);
        bbox.width = Math.max(x1, x) - bbox.x;
        bbox.height = Math.max(y1, y) - bbox.y;
      }
    }
    if (isClosed) {
      path.closePath();
    }
    return bbox;
  }
};
__decorateClass([
  SceneObjectChangeDetection({ equals: objectsEqual })
], GeoGeometry.prototype, "projectedGeometry", 2);
__decorateClass([
  SceneChangeDetection()
], GeoGeometry.prototype, "renderMode", 2);

// packages/ag-charts-enterprise/src/series/map-util/geometryUtil.ts
function calculatePolygonArea(polygon) {
  const bbox = polygonBbox(polygon[0], void 0);
  if (bbox == null)
    return 0;
  return Math.abs(bbox.lat1 - bbox.lat0) * Math.abs(bbox.lon1 - bbox.lon0);
}
function findLargestByMetric(items, metric) {
  let maxValue;
  let maxItem;
  for (const item of items) {
    const value = metric(item);
    if (value == null)
      continue;
    if (maxValue == null || value > maxValue) {
      maxValue = value;
      maxItem = item;
    }
  }
  return maxItem;
}
function geometryBbox(geometry, into) {
  if (geometry.bbox != null) {
    const [lon0, lat0, lon1, lat1] = geometry.bbox;
    into = LonLatBBox.extend(into, lon0, lat0, lon1, lat1);
    return into;
  }
  switch (geometry.type) {
    case "GeometryCollection":
      for (const g of geometry.geometries) {
        into = geometryBbox(g, into);
      }
      break;
    case "MultiPolygon":
      for (const c of geometry.coordinates) {
        if (c.length > 0) {
          into = polygonBbox(c[0], into);
        }
      }
      break;
    case "Polygon":
      if (geometry.coordinates.length > 0) {
        into = polygonBbox(geometry.coordinates[0], into);
      }
      break;
    case "MultiLineString":
      for (const c of geometry.coordinates) {
        into = polygonBbox(c, into);
      }
      break;
    case "LineString":
      into = polygonBbox(geometry.coordinates, into);
      break;
    case "MultiPoint":
      for (const p of geometry.coordinates) {
        const [lon, lat] = p;
        into = LonLatBBox.extend(into, lon, lat, lon, lat);
      }
      break;
    case "Point": {
      const [lon, lat] = geometry.coordinates;
      into = LonLatBBox.extend(into, lon, lat, lon, lat);
      break;
    }
  }
  return into;
}
function largestPolygon(geometry) {
  switch (geometry.type) {
    case "Polygon":
      return geometry.coordinates;
    case "MultiPolygon":
      return findLargestByMetric(geometry.coordinates, calculatePolygonArea);
    case "GeometryCollection": {
      const polygons = geometry.geometries.map(largestPolygon).filter((p) => p != null);
      return findLargestByMetric(polygons, calculatePolygonArea);
    }
    case "MultiLineString":
    case "LineString":
    case "MultiPoint":
    case "Point":
      return;
  }
}
function largestLineString(geometry) {
  switch (geometry.type) {
    case "LineString":
      return geometry.coordinates;
    case "MultiLineString":
      return findLargestByMetric(geometry.coordinates, lineStringLength);
    case "GeometryCollection": {
      const lineStrings = geometry.geometries.map(largestLineString).filter((l) => l != null);
      return findLargestByMetric(lineStrings, lineStringLength);
    }
    case "MultiPolygon":
    case "Polygon":
    case "MultiPoint":
    case "Point":
      return;
  }
}
function containsType(geometry, type) {
  if (geometry == null)
    return false;
  switch (geometry.type) {
    case "GeometryCollection":
      return geometry.geometries.some((g) => containsType(g, type));
    case "MultiPolygon":
    case "Polygon":
      return (type & 1 /* Polygon */) !== 0;
    case "MultiLineString":
    case "LineString":
      return (type & 2 /* LineString */) !== 0;
    case "MultiPoint":
    case "Point":
      return (type & 4 /* Point */) !== 0;
  }
}
function projectGeometry(geometry, scale2) {
  switch (geometry.type) {
    case "GeometryCollection":
      return {
        type: "GeometryCollection",
        geometries: geometry.geometries.map((g) => projectGeometry(g, scale2))
      };
    case "Polygon":
      return {
        type: "Polygon",
        coordinates: projectPolygon(geometry.coordinates, scale2)
      };
    case "MultiPolygon":
      return {
        type: "MultiPolygon",
        coordinates: projectMultiPolygon(geometry.coordinates, scale2)
      };
    case "MultiLineString":
      return {
        type: "MultiLineString",
        coordinates: projectPolygon(geometry.coordinates, scale2)
      };
    case "LineString":
      return {
        type: "LineString",
        coordinates: projectLineString(geometry.coordinates, scale2)
      };
    case "MultiPoint":
      return {
        type: "MultiPoint",
        coordinates: projectLineString(geometry.coordinates, scale2)
      };
    case "Point":
      return {
        type: "Point",
        coordinates: scale2.convert(geometry.coordinates)
      };
  }
}
function projectMultiPolygon(multiPolygon, scale2) {
  return multiPolygon.map((polygon) => projectPolygon(polygon, scale2));
}
function projectPolygon(polygon, scale2) {
  return polygon.map((lineString) => projectLineString(lineString, scale2));
}
function projectLineString(lineString, scale2) {
  return lineString.map((lonLat) => scale2.convert(lonLat));
}

// packages/ag-charts-enterprise/src/series/map-util/topologySeries.ts
var TopologySeriesProperties = class extends module_support_exports.SeriesProperties {
};
var TopologySeries = class extends module_support_exports.DataModelSeries {
  constructor(options) {
    super(options);
    this.cleanup.register(
      this.ctx.eventsHub.on("data:update", () => {
      }),
      this.ctx.eventsHub.on("legend:item-click", (event) => {
        this.onLegendItemClick(event);
      }),
      this.ctx.eventsHub.on("legend:item-double-click", (event) => {
        this.onLegendItemDoubleClick(event);
      })
    );
  }
  getSeriesDomain() {
    return { domain: [Number.NaN, Number.NaN] };
  }
  getSeriesRange() {
    return [Number.NaN, Number.NaN];
  }
  getHighlightedDatum() {
    let highlightedDatum = this.ctx.highlightManager?.getActiveHighlight();
    const { legendItemName } = this.properties;
    const matchingLegendItemName = legendItemName != null && highlightedDatum?.datum == null && legendItemName === highlightedDatum?.legendItemName;
    if (highlightedDatum != null && (highlightedDatum.series !== this && !matchingLegendItemName || highlightedDatum.datum == null)) {
      highlightedDatum = void 0;
    }
    return highlightedDatum;
  }
};

// packages/ag-charts-enterprise/src/series/map-line-background/mapLineBackgroundSeriesProperties.ts
var { SeriesProperties: SeriesProperties10, makeSeriesTooltip: makeSeriesTooltip21 } = module_support_exports;
var MapLineBackgroundSeriesProperties = class extends SeriesProperties10 {
  constructor() {
    super(...arguments);
    this.topology = void 0;
    this.stroke = "black";
    this.strokeOpacity = 1;
    this.strokeWidth = 0;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.tooltip = makeSeriesTooltip21();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineBackgroundSeriesProperties.prototype, "topology", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineBackgroundSeriesProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineBackgroundSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineBackgroundSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineBackgroundSeriesProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineBackgroundSeriesProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineBackgroundSeriesProperties.prototype, "tooltip", 2);

// packages/ag-charts-enterprise/src/series/map-line-background/mapLineBackgroundSeries.ts
var { createDatumId: createDatumId20, Group: Group22, Selection: Selection15, PointerEvents: PointerEvents12 } = module_support_exports;
var MapLineBackgroundSeries = class extends TopologySeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      categoryKey: void 0,
      pickModes: []
    });
    this.properties = new MapLineBackgroundSeriesProperties();
    this._chartTopology = void 0;
    this.itemGroup = this.contentGroup.appendChild(new Group22({ name: "itemGroup" }));
    this.datumSelection = Selection15.select(
      this.itemGroup,
      () => this.nodeFactory()
    );
    this.itemGroup.pointerEvents = PointerEvents12.None;
  }
  getNodeData() {
    return this.contextNodeData?.nodeData;
  }
  get topology() {
    return this.properties.topology ?? this._chartTopology;
  }
  get focusable() {
    return false;
  }
  setOptionsData() {
  }
  setChartData() {
  }
  get hasData() {
    return false;
  }
  renderToOffscreenCanvas() {
    return true;
  }
  setChartTopology(topology) {
    this._chartTopology = topology;
    if (this.topology === topology) {
      this.nodeDataRefresh = true;
    }
  }
  setZIndex(zIndex) {
    super.setZIndex(zIndex);
    this.contentGroup.zIndex = [0 /* ShapeLineBackground */, zIndex, 0];
    this.highlightGroup.zIndex = [0 /* ShapeLineBackground */, zIndex, 1];
    return true;
  }
  nodeFactory() {
    const geoGeometry = new GeoGeometry();
    geoGeometry.renderMode = 2 /* Lines */;
    geoGeometry.lineJoin = "round";
    geoGeometry.lineCap = "round";
    geoGeometry.pointerEvents = PointerEvents12.None;
    return geoGeometry;
  }
  processData() {
    const { topology } = this;
    this.topologyBounds = topology?.features.reduce((current, feature) => {
      const geometry = feature.geometry;
      if (geometry == null)
        return current;
      return geometryBbox(geometry, current);
    }, void 0);
    if (topology == null) {
      logger_exports.warnOnce(`no topology was provided for [MapShapeBackgroundSeries]; nothing will be rendered.`);
    }
  }
  createNodeData() {
    const { id: seriesId, topology, scale: scale2, properties } = this;
    if (topology == null)
      return;
    const { stroke: stroke3, strokeOpacity, lineDash, lineDashOffset, strokeWidth } = properties;
    const nodeData = [];
    const labelData = [];
    for (const [index, feature] of topology.features.entries()) {
      const { geometry } = feature;
      const projectedGeometry = geometry != null && scale2 != null ? projectGeometry(geometry, scale2) : void 0;
      if (projectedGeometry == null)
        continue;
      nodeData.push({
        series: this,
        datum: feature,
        datumIndex: 0,
        index,
        projectedGeometry,
        style: { stroke: stroke3, strokeOpacity, lineDash, lineDashOffset, strokeWidth }
      });
    }
    return {
      itemId: seriesId,
      nodeData,
      labelData
    };
  }
  updateSelections() {
    if (this.nodeDataRefresh) {
      this.contextNodeData = this.createNodeData();
      this.nodeDataRefresh = false;
    }
  }
  update() {
    const { datumSelection } = this;
    this.updateSelections();
    this.contentGroup.visible = this.visible;
    this.labelGroup.visible = this.visible;
    const { nodeData = [] } = this.contextNodeData ?? {};
    this.datumSelection = this.updateDatumSelection({ nodeData, datumSelection });
    this.updateDatumNodes({ datumSelection });
  }
  updateDatumSelection(opts) {
    return opts.datumSelection.update(opts.nodeData, void 0, (datum) => createDatumId20(datum.index));
  }
  updateDatumNodes(opts) {
    const { datumSelection } = opts;
    datumSelection.each((geoGeometry, datum) => {
      const { projectedGeometry } = datum;
      if (projectedGeometry == null) {
        geoGeometry.visible = false;
        geoGeometry.projectedGeometry = void 0;
        return;
      }
      geoGeometry.visible = true;
      geoGeometry.projectedGeometry = projectedGeometry;
      geoGeometry.setProperties(datum.style);
    });
  }
  resetAnimation() {
  }
  getLegendData() {
    return [];
  }
  getTooltipContent(_seriesDatum) {
    return;
  }
  computeFocusBounds(_opts) {
    return void 0;
  }
  hasItemStylers() {
    return false;
  }
};
MapLineBackgroundSeries.className = "MapLineBackgroundSeries";
MapLineBackgroundSeries.type = "map-line-background";

// packages/ag-charts-enterprise/src/series/map-line-background/mapLineBackgroundSeriesOptionsDef.ts
var { mapLineBackgroundSeriesThemeableOptionsDef: mapLineBackgroundSeriesThemeableOptionsDef2 } = module_support_exports;
var mapLineBackgroundSeriesOptionsDef = {
  ...mapLineBackgroundSeriesThemeableOptionsDef2,
  type: required(constant("map-line-background")),
  topology: geoJson
};

// packages/ag-charts-enterprise/src/series/map-line-background/mapLineBackgroundModule.ts
var MapLineBackgroundSeriesModule = {
  type: "series",
  name: "map-line-background",
  chartType: "topology",
  enterprise: true,
  version: VERSION,
  dependencies: [TopologyChartModule],
  options: mapLineBackgroundSeriesOptionsDef,
  themeTemplate: {
    ...MAP_THEME_DEFAULTS,
    series: {
      stroke: { $path: ["/1", { $mapPalette: "stroke" }, { $mapPalette: "secondHierarchyColors" }] },
      strokeWidth: 1,
      lineDash: [0],
      lineDashOffset: 0
    }
  },
  create: (ctx) => new MapLineBackgroundSeries(ctx)
};

// packages/ag-charts-enterprise/src/series/map-util/mapUtil.ts
function prepareMapMarkerAnimationFunctions() {
  const fromFn = (marker, _datum, status) => {
    if (status === "removed") {
      return { scalingX: 1, scalingY: 1 };
    } else if (marker.previousDatum == null) {
      return { scalingX: 0, scalingY: 0 };
    }
    return { scalingX: marker.scalingX, scalingY: marker.scalingY };
  };
  const toFn = (_marker, _datum, status) => {
    if (status === "removed") {
      return { scalingX: 0, scalingY: 0 };
    }
    return { scalingX: 1, scalingY: 1 };
  };
  return { fromFn, toFn };
}
function findFocusedGeoGeometry(series, opts) {
  const datum = series.contextNodeData?.nodeData[opts.datumIndex];
  if (datum === void 0)
    return void 0;
  for (const node of series.datumSelection.nodes()) {
    if (node.datum === datum) {
      return node;
    }
  }
  return void 0;
}

// packages/ag-charts-enterprise/src/series/map-line/mapLineSeriesProperties.ts
var { SeriesProperties: SeriesProperties11, makeSeriesTooltip: makeSeriesTooltip22, Label: Label19 } = module_support_exports;
var MapLineSeriesProperties = class extends SeriesProperties11 {
  constructor() {
    super(...arguments);
    this.topology = void 0;
    this.idKey = "";
    this.topologyIdKey = "name";
    this.idName = void 0;
    this.labelKey = void 0;
    this.labelName = void 0;
    this.colorRange = void 0;
    this.maxStrokeWidth = void 0;
    this.stroke = "black";
    this.strokeOpacity = 1;
    this.strokeWidth = 0;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.label = new Label19();
    this.tooltip = makeSeriesTooltip22();
  }
  getStyle() {
    const { stroke: stroke3, strokeOpacity, strokeWidth, lineDash, lineDashOffset } = this;
    return {
      stroke: stroke3,
      strokeOpacity,
      strokeWidth,
      lineDash,
      lineDashOffset,
      opacity: 1
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "topology", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "title", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "legendItemName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "idKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "topologyIdKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "idName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "labelKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "labelName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "sizeKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "sizeName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "colorKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "colorName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "sizeDomain", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "colorRange", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "maxStrokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "itemStyler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapLineSeriesProperties.prototype, "tooltip", 2);

// packages/ag-charts-enterprise/src/series/map-line/mapLineSeries.ts
var {
  getMissCount: getMissCount3,
  getLabelStyles: getLabelStyles7,
  createDatumId: createDatumId21,
  SeriesNodePickMode: SeriesNodePickMode15,
  valueProperty: valueProperty16,
  ColorScale: ColorScale3,
  LinearScale: LinearScale6,
  Selection: Selection16,
  Text: Text9,
  Transformable: Transformable7
} = module_support_exports;
var MapLineSeries = class extends TopologySeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      categoryKey: void 0,
      propertyKeys: {
        size: ["colorKey"],
        color: ["colorKey"],
        label: ["labelKey"]
      },
      propertyNames: {
        size: ["sizeName"],
        color: ["colorName"],
        label: ["labelName"]
      },
      pickModes: [SeriesNodePickMode15.EXACT_SHAPE_MATCH, SeriesNodePickMode15.NEAREST_NODE],
      usesPlacedLabels: true
    });
    this.properties = new MapLineSeriesProperties();
    this._chartTopology = void 0;
    this.colorScale = new ColorScale3();
    this.sizeScale = new LinearScale6();
    this.datumSelection = Selection16.select(
      this.contentGroup,
      () => this.nodeFactory()
    );
    this.labelSelection = Selection16.select(this.labelGroup, Text9);
    this.highlightDatumSelection = Selection16.select(
      this.highlightNodeGroup,
      () => this.nodeFactory()
    );
    this.highlightLabelSelection = Selection16.select(this.highlightLabelGroup, Text9);
    this.placedLabelData = [];
    this._previousDatumMidPoint = void 0;
  }
  getNodeData() {
    return this.contextNodeData?.nodeData;
  }
  get topology() {
    return this.properties.topology ?? this._chartTopology;
  }
  get hasData() {
    return super.hasData && this.topology != null;
  }
  renderToOffscreenCanvas() {
    return true;
  }
  setZIndex(zIndex) {
    super.setZIndex(zIndex);
    this.contentGroup.zIndex = [1 /* ShapeLine */, zIndex];
    this.highlightGroup.zIndex = [4 /* ShapeLineHighlight */, zIndex];
    return true;
  }
  setChartTopology(topology) {
    this._chartTopology = topology;
    if (this.topology === topology) {
      this.nodeDataRefresh = true;
    }
  }
  isLabelEnabled() {
    return this.properties.labelKey != null && this.properties.label.enabled;
  }
  nodeFactory() {
    const geoGeometry = new GeoGeometry();
    geoGeometry.renderMode = 2 /* Lines */;
    geoGeometry.lineJoin = "round";
    geoGeometry.lineCap = "round";
    return geoGeometry;
  }
  async processData(dataController) {
    if (this.data == null)
      return;
    const { data, topology, sizeScale, colorScale } = this;
    const { topologyIdKey, idKey, sizeKey, colorKey, labelKey, sizeDomain, colorRange } = this.properties;
    const featureById = /* @__PURE__ */ new Map();
    for (const feature of topology?.features.values() ?? []) {
      const property = feature.properties?.[topologyIdKey];
      if (property == null || !containsType(feature.geometry, 2 /* LineString */))
        continue;
      featureById.set(property, feature);
    }
    const sizeScaleType = this.sizeScale.type;
    const colorScaleType = this.colorScale.type;
    const mercatorScaleType = this.scale?.type;
    const { dataModel, processedData } = await this.requestDataModel(dataController, data, {
      props: [
        valueProperty16(idKey, mercatorScaleType, { id: "idValue", includeProperty: false }),
        valueProperty16(idKey, mercatorScaleType, {
          id: "featureValue",
          includeProperty: false,
          processor: () => (datum) => featureById.get(datum)
        }),
        ...labelKey == null ? [] : [valueProperty16(labelKey, "category", { id: "labelValue" })],
        ...sizeKey == null ? [] : [valueProperty16(sizeKey, sizeScaleType, { id: "sizeValue" })],
        ...colorKey == null ? [] : [valueProperty16(colorKey, colorScaleType, { id: "colorValue" })]
      ]
    });
    const featureValues = dataModel.resolveColumnById(this, `featureValue`, processedData);
    this.topologyBounds = featureValues.reduce((current, feature) => {
      const geometry = feature?.geometry;
      if (geometry == null)
        return current;
      return geometryBbox(geometry, current);
    }, void 0);
    if (sizeKey != null) {
      const sizeIdx = dataModel.resolveProcessedDataIndexById(this, `sizeValue`);
      const processedSize = processedData.domain.values[sizeIdx] ?? [];
      sizeScale.domain = sizeDomain ?? processedSize;
    }
    if (colorRange != null && this.isColorScaleValid()) {
      const colorKeyIdx = dataModel.resolveProcessedDataIndexById(this, "colorValue");
      colorScale.domain = processedData.domain.values[colorKeyIdx];
      colorScale.range = colorRange;
      colorScale.update();
    }
    if (topology == null) {
      logger_exports.warnOnce(`no topology was provided for [MapLineSeries]; nothing will be rendered.`);
    }
  }
  isColorScaleValid() {
    const { colorKey } = this.properties;
    if (!colorKey) {
      return false;
    }
    const { dataModel, processedData } = this;
    if (!dataModel || !processedData) {
      return false;
    }
    const colorIdx = dataModel.resolveProcessedDataIndexById(this, "colorValue");
    const dataCount = processedData.input.count;
    const missCount = getMissCount3(this, processedData.defs.values[colorIdx].missing);
    const colorDataMissing = dataCount === 0 || dataCount === missCount;
    return !colorDataMissing;
  }
  getLabelDatum(datum, datumIndex, idValue, labelValue, projectedGeometry, measurer3) {
    if (labelValue == null || projectedGeometry == null || idValue == null)
      return;
    const lineString = largestLineString(projectedGeometry);
    if (lineString == null)
      return;
    const { idKey, idName, sizeKey, sizeName, colorKey, colorName, labelKey, labelName, label } = this.properties;
    if (labelKey == null || !label.enabled)
      return;
    const labelText = this.getLabelText(
      labelValue,
      datum,
      labelKey,
      "label",
      [],
      label,
      {
        value: labelValue,
        datum,
        idKey,
        idName,
        sizeKey,
        sizeName,
        colorKey,
        colorName,
        labelKey,
        labelName
      }
    );
    if (labelText == null)
      return;
    const labelSize = measurer3.measureLines(String(labelText));
    const labelCenter = lineStringCenter(lineString);
    if (labelCenter == null)
      return;
    const [x, y] = labelCenter.point;
    const { width: width2, height: height2 } = labelSize;
    return {
      point: { x, y, size: 0 },
      label: { width: width2, height: height2, text: labelText },
      anchor: void 0,
      placement: void 0,
      datumIndex,
      idValue
    };
  }
  resolveColumn(key, columnId, processedData) {
    if (key == null || this.dataModel == null)
      return void 0;
    return this.dataModel.resolveColumnById(this, columnId, processedData);
  }
  resolveLineDataColumns(processedData) {
    const { sizeKey, colorKey, labelKey } = this.properties;
    return {
      idValues: this.dataModel.resolveColumnById(this, "idValue", processedData),
      featureValues: this.dataModel.resolveColumnById(this, "featureValue", processedData),
      labelValues: this.resolveColumn(labelKey, "labelValue", processedData),
      sizeValues: this.resolveColumn(sizeKey, "sizeValue", processedData),
      colorValues: this.resolveColumn(colorKey, "colorValue", processedData)
    };
  }
  prepareProjectedLineGeometries(idValues, featureValues, processedData) {
    const projectedGeometries = /* @__PURE__ */ new Map();
    for (const [datumIndex] of processedData.dataSources.get(this.id)?.data.entries() ?? []) {
      const id = idValues[datumIndex];
      const geometry = featureValues[datumIndex]?.geometry;
      const projectedGeometry = geometry != null && this.scale != null ? projectGeometry(geometry, this.scale) : void 0;
      if (id != null && projectedGeometry != null) {
        projectedGeometries.set(id, projectedGeometry);
      }
    }
    return projectedGeometries;
  }
  warnMissingGeometries(missingGeometries) {
    if (missingGeometries.length === 0)
      return;
    const missingGeometriesCap = 10;
    if (missingGeometries.length > missingGeometriesCap) {
      const excessItems = missingGeometries.length - missingGeometriesCap;
      missingGeometries.length = missingGeometriesCap;
      missingGeometries.push(`(+${excessItems} more)`);
    }
    logger_exports.warnOnce(`some data items do not have matches in the provided topology`, missingGeometries);
  }
  createNodeData() {
    const { id: seriesId, dataModel, processedData, sizeScale, properties } = this;
    const { label, legendItemName, colorKey } = properties;
    if (dataModel == null || processedData == null)
      return;
    if (!this.visible) {
      return { itemId: seriesId, nodeData: [], labelData: [] };
    }
    const columns = this.resolveLineDataColumns(processedData);
    const maxStrokeWidth = properties.maxStrokeWidth ?? properties.strokeWidth;
    sizeScale.range = [Math.min(properties.strokeWidth, maxStrokeWidth), maxStrokeWidth];
    const measurer3 = cachedTextMeasurer(label);
    const projectedGeometries = this.prepareProjectedLineGeometries(
      columns.idValues,
      columns.featureValues,
      processedData
    );
    const nodeData = [];
    const labelData = [];
    const missingGeometries = [];
    const rawData = processedData.dataSources.get(this.id)?.data ?? [];
    for (const [datumIndex, datum] of rawData.entries()) {
      const dataValues = {
        idValue: columns.idValues[datumIndex],
        colorValue: columns.colorValues?.[datumIndex],
        sizeValue: columns.sizeValues?.[datumIndex],
        labelValue: columns.labelValues?.[datumIndex]
      };
      const projectedGeometry = projectedGeometries.get(dataValues.idValue);
      if (projectedGeometry == null) {
        missingGeometries.push(dataValues.idValue);
      }
      if (colorKey != null && dataValues.colorValue == null) {
        continue;
      }
      const labelDatum = this.getLabelDatum(
        datum,
        datumIndex,
        dataValues.idValue,
        dataValues.labelValue,
        projectedGeometry,
        measurer3
      );
      if (labelDatum != null) {
        labelData.push(labelDatum);
      }
      nodeData.push({
        series: this,
        datum,
        datumIndex,
        ...dataValues,
        projectedGeometry,
        legendItemName,
        style: this.getItemStyle(
          { datumIndex, datum, colorValue: dataValues.colorValue, sizeValue: dataValues.sizeValue },
          false
        )
      });
    }
    this.warnMissingGeometries(missingGeometries);
    return {
      itemId: seriesId,
      nodeData,
      labelData
    };
  }
  updateSelections() {
    if (this.nodeDataRefresh) {
      this.contextNodeData = this.createNodeData();
      this.nodeDataRefresh = false;
    }
  }
  update() {
    const { datumSelection, highlightDatumSelection } = this;
    this.updateSelections();
    this.contentGroup.visible = this.visible;
    this.labelGroup.visible = this.visible;
    const drawingMode = this.ctx.chartService.highlight?.drawingMode ?? "overlay";
    const highlightedDatum = this.getHighlightedDatum();
    const nodeData = this.contextNodeData?.nodeData ?? [];
    this.datumSelection = this.updateDatumSelection({ nodeData, datumSelection });
    this.updateDatumStyles({ datumSelection, isHighlight: false });
    this.updateDatumNodes({ datumSelection, isHighlight: false, drawingMode: "overlay" });
    this.highlightDatumSelection = this.updateDatumSelection({
      nodeData: highlightedDatum == null ? [] : [highlightedDatum],
      datumSelection: highlightDatumSelection
    });
    this.updateDatumStyles({ datumSelection: highlightDatumSelection, isHighlight: true });
    this.updateDatumNodes({ datumSelection: highlightDatumSelection, isHighlight: true, drawingMode });
    this.updateLabelNodes({ labelSelection: this.labelSelection, isHighlight: false });
    this.updateHighlightLabelSelection(highlightedDatum);
  }
  updateDatumSelection(opts) {
    return opts.datumSelection.update(opts.nodeData, void 0, (datum) => createDatumId21(datum.idValue));
  }
  getItemStyle({ datumIndex = 0, datum, colorValue, sizeValue }, isHighlight) {
    const { properties, colorScale, sizeScale } = this;
    const { colorRange, itemStyler } = properties;
    const baseStyle = properties.getStyle();
    if (colorValue != null) {
      baseStyle.stroke = this.isColorScaleValid() ? colorScale.convert(colorValue) : colorRange?.[0] ?? properties.stroke;
    }
    const highlightStyle = this.getHighlightStyle(isHighlight, datumIndex);
    const style2 = mergeDefaults(highlightStyle, baseStyle);
    if (sizeValue != null) {
      style2.strokeWidth = sizeScale.convert(sizeValue, { clamp: true });
    }
    let overrides;
    if (itemStyler != null) {
      overrides = this.cachedDatumCallback(createDatumId21(datumIndex, isHighlight ? "highlight" : "node"), () => {
        const params = this.makeItemStylerParams(datum, datumIndex, isHighlight, style2);
        return this.callWithContext(itemStyler, params);
      });
    }
    return overrides ? mergeDefaults(style2, overrides) : style2;
  }
  makeItemStylerParams(datum, datumIndex, isHighlight, style2) {
    const { id: seriesId } = this;
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const highlightState = this.getHighlightStateString(activeHighlight, isHighlight, datumIndex);
    return {
      seriesId,
      datum,
      highlightState,
      ...style2
    };
  }
  updateDatumStyles({
    datumSelection,
    isHighlight
  }) {
    datumSelection.each((_, nodeDatum) => {
      nodeDatum.style = this.getItemStyle(nodeDatum, isHighlight);
    });
  }
  updateDatumNodes({
    datumSelection,
    drawingMode
  }) {
    datumSelection.each((geoGeometry, nodeDatum) => {
      const { projectedGeometry, style: style2 } = nodeDatum;
      if (projectedGeometry == null) {
        geoGeometry.visible = false;
        geoGeometry.projectedGeometry = void 0;
        return;
      }
      geoGeometry.visible = true;
      geoGeometry.projectedGeometry = projectedGeometry;
      geoGeometry.setProperties(style2);
      geoGeometry.drawingMode = drawingMode;
    });
  }
  updatePlacedLabelData(labelData) {
    this.placedLabelData = labelData;
    this.labelSelection = this.labelSelection.update(labelData, (text2) => {
      text2.pointerEvents = module_support_exports.PointerEvents.None;
    });
    this.updateLabelNodes({ labelSelection: this.labelSelection, isHighlight: false });
    this.updateHighlightLabelSelection();
  }
  updateLabelNodes({
    isHighlight,
    labelSelection
  }) {
    const { properties } = this;
    const activeHighlight = this.getHighlightedDatum();
    labelSelection.each((label, placedLabel) => {
      const { x, y, width: width2, height: height2, text: text2, datum: labelDatum } = placedLabel;
      const style2 = getLabelStyles7(this, void 0, properties, properties.label, isHighlight, activeHighlight);
      const { color: fill, fontStyle, fontWeight: fontWeight2, fontSize, fontFamily } = style2;
      label.visible = true;
      label.x = x + width2 / 2;
      label.y = y + height2 / 2;
      label.text = text2;
      label.fill = fill;
      label.fontStyle = fontStyle;
      label.fontWeight = fontWeight2;
      label.fontSize = fontSize;
      label.fontFamily = fontFamily;
      label.textAlign = "center";
      label.textBaseline = "middle";
      const datumIndex = labelDatum?.datumIndex;
      label.fillOpacity = this.getHighlightStyle(isHighlight, datumIndex).opacity ?? 1;
      label.setBoxing(style2);
    });
  }
  updateHighlightLabelSelection(highlightedDatum = this.getHighlightedDatum()) {
    const highlightId = highlightedDatum?.idValue;
    const highlightLabels = highlightId == null || !this.isLabelEnabled() ? [] : this.placedLabelData.filter((label) => label.datum.idValue === highlightId);
    this.highlightLabelSelection = this.highlightLabelSelection.update(highlightLabels);
    if (highlightLabels.length === 0) {
      this.highlightLabelSelection.cleanup();
    }
    this.updateLabelNodes({ labelSelection: this.highlightLabelSelection, isHighlight: true });
  }
  resetAnimation() {
  }
  getLabelData() {
    if (!this.isLabelEnabled())
      return [];
    return this.contextNodeData?.labelData ?? [];
  }
  pickNodeClosestDatum({ x, y }) {
    let minDistanceSquared = Infinity;
    let minDatum;
    this.datumSelection.each((node, datum) => {
      const distanceSquared2 = node.distanceSquared(x, y);
      if (distanceSquared2 < minDistanceSquared) {
        minDistanceSquared = distanceSquared2;
        minDatum = datum;
      }
    });
    return minDatum == null ? void 0 : { datum: minDatum, distance: Math.sqrt(minDistanceSquared) };
  }
  datumMidPoint(datum) {
    const { _previousDatumMidPoint } = this;
    if (_previousDatumMidPoint?.datum === datum) {
      return _previousDatumMidPoint.point;
    }
    const projectedGeometry = datum.projectedGeometry;
    const lineString = projectedGeometry == null ? void 0 : largestLineString(projectedGeometry);
    const center2 = lineString == null ? void 0 : lineStringCenter(lineString)?.point;
    const point = center2 == null ? void 0 : { x: center2[0], y: center2[1] };
    this._previousDatumMidPoint = { datum, point };
    return point;
  }
  legendItemSymbol(datumIndex) {
    const { dataModel, processedData, properties } = this;
    const { strokeWidth, strokeOpacity, lineDash } = properties;
    let { stroke: stroke3 } = properties;
    if (datumIndex != null && this.isColorScaleValid()) {
      const colorValues = dataModel.resolveColumnById(this, "colorValue", processedData);
      const colorValue = colorValues[datumIndex];
      if (colorValue != null) {
        stroke3 = this.colorScale.convert(colorValue);
      }
    }
    return {
      marker: {
        fill: void 0,
        fillOpacity: 0,
        stroke: void 0,
        strokeWidth: 0,
        strokeOpacity: 0,
        lineDash: [0],
        lineDashOffset: 0,
        enabled: false
      },
      line: {
        enabled: true,
        stroke: stroke3,
        strokeWidth,
        strokeOpacity,
        lineDash
      }
    };
  }
  getLegendData(legendType) {
    const { processedData, dataModel } = this;
    if (processedData == null || dataModel == null)
      return [];
    const { id: seriesId, visible } = this;
    const { title, legendItemName, idKey, idName, colorKey, colorRange, showInLegend } = this.properties;
    if (legendType === "gradient" && colorKey != null && colorRange != null) {
      const colorDomain = processedData.domain.values[dataModel.resolveProcessedDataIndexById(this, "colorValue")];
      const legendDatum = {
        legendType: "gradient",
        enabled: visible,
        seriesId,
        series: this.getFormatterContext("color"),
        colorRange,
        colorDomain
      };
      return [legendDatum];
    } else if (legendType === "category") {
      const legendDatum = {
        legendType: "category",
        id: seriesId,
        itemId: seriesId,
        seriesId,
        enabled: visible,
        label: { text: legendItemName ?? title ?? idName ?? idKey },
        symbol: this.legendItemSymbol(),
        legendItemName,
        hideInLegend: !showInLegend
      };
      return [legendDatum];
    } else {
      return [];
    }
  }
  getTooltipContent(datumIndex) {
    const {
      id: seriesId,
      dataModel,
      processedData,
      properties,
      ctx: { formatManager }
    } = this;
    const {
      idKey,
      idName,
      colorKey,
      colorName,
      sizeKey,
      sizeName,
      labelKey,
      labelName,
      title,
      legendItemName,
      tooltip
    } = properties;
    if (!dataModel || !processedData)
      return;
    const datum = processedData.dataSources.get(this.id)?.data[datumIndex];
    const idValues = dataModel.resolveColumnById(this, `idValue`, processedData);
    const sizeValue = sizeKey == null ? void 0 : dataModel.resolveColumnById(this, `sizeValue`, processedData)[datumIndex];
    const colorValue = colorKey == null ? void 0 : dataModel.resolveColumnById(this, `colorValue`, processedData)[datumIndex];
    if (colorKey != null && colorValue == null) {
      return;
    }
    const data = [];
    if (this.isLabelEnabled() && labelKey != null && labelKey !== idKey) {
      const labelValue = dataModel.resolveColumnById(this, `labelValue`, processedData)[datumIndex];
      const content = formatManager.format(this.callWithContext.bind(this), {
        type: "category",
        value: labelValue,
        datum,
        seriesId,
        legendItemName,
        key: labelKey,
        source: "tooltip",
        property: "label",
        domain: [],
        boundSeries: this.getFormatterContext("label")
      });
      data.push({ label: labelName, fallbackLabel: labelKey, value: content ?? labelValue });
    }
    if (sizeValue != null && sizeKey != null) {
      const domain = dataModel.getDomain(this, `sizeValue`, "value", processedData).domain;
      const content = formatManager.format(this.callWithContext.bind(this), {
        type: "number",
        value: sizeValue,
        datum,
        seriesId,
        legendItemName,
        key: sizeKey,
        source: "tooltip",
        property: "size",
        domain,
        boundSeries: this.getFormatterContext("size"),
        fractionDigits: void 0,
        visibleDomain: void 0
      });
      data.push({ label: sizeName, fallbackLabel: sizeKey, value: content ?? String(sizeValue) });
    }
    if (colorValue != null && colorKey != null) {
      const domain = dataModel.getDomain(this, `colorValue`, "value", processedData).domain;
      const content = formatManager.format(this.callWithContext.bind(this), {
        type: "number",
        value: colorValue,
        datum,
        seriesId,
        legendItemName,
        key: colorKey,
        source: "tooltip",
        property: "color",
        domain,
        boundSeries: this.getFormatterContext("color"),
        fractionDigits: void 0,
        visibleDomain: void 0
      });
      data.push({ label: colorName, fallbackLabel: colorKey, value: content ?? String(colorValue) });
    }
    const format = this.getItemStyle({ datumIndex, datum, colorValue, sizeValue }, false);
    return this.formatTooltipWithContext(
      tooltip,
      {
        heading: idValues[datumIndex],
        title: title ?? legendItemName,
        symbol: this.legendItemSymbol(datumIndex),
        data
      },
      {
        seriesId,
        datum,
        title,
        idKey,
        idName,
        colorKey,
        colorName,
        sizeKey,
        sizeName,
        labelKey,
        labelName,
        ...format
      }
    );
  }
  computeFocusBounds(opts) {
    const geometry = findFocusedGeoGeometry(this, opts);
    return geometry ? Transformable7.toCanvas(this.contentGroup, geometry.getBBox()) : void 0;
  }
  hasItemStylers() {
    return this.properties.itemStyler != null || this.properties.label.itemStyler != null;
  }
};
MapLineSeries.className = "MapLineSeries";
MapLineSeries.type = "map-line";

// packages/ag-charts-enterprise/src/series/map-line/mapLineSeriesOptionsDef.ts
var { mapLineSeriesThemeableOptionsDef: mapLineSeriesThemeableOptionsDef2 } = module_support_exports;
var mapLineSeriesOptionsDef = {
  ...without(commonSeriesOptionsDefs, ["highlightStyle", "highlight"]),
  ...mapLineSeriesThemeableOptionsDef2,
  type: required(constant("map-line")),
  idKey: required(string),
  sizeKey: string,
  colorKey: string,
  labelKey: string,
  idName: string,
  sizeName: string,
  colorName: string,
  labelName: string,
  topology: geoJson,
  topologyIdKey: string,
  legendItemName: string,
  title: string
};
mapLineSeriesOptionsDef.colorRange = undocumented(and(arrayOf(color), arrayLength(1)));

// packages/ag-charts-enterprise/src/series/map-line/mapLineModule.ts
var MapLineSeriesModule = {
  type: "series",
  name: "map-line",
  chartType: "topology",
  enterprise: true,
  version: VERSION,
  dependencies: [TopologyChartModule],
  options: mapLineSeriesOptionsDef,
  themeTemplate: {
    ...MAP_THEME_DEFAULTS,
    series: {
      stroke: applyMapPalette(SAFE_STROKE_FILL_OPERATION),
      colorRange: {
        $if: [
          { $eq: [{ $mapPalette: "type" }, "inbuilt"] },
          { $mapPalette: "divergingColors" },
          applyMapPalette(SAFE_RANGE2_OPERATION)
        ]
      },
      strokeWidth: 1,
      maxStrokeWidth: 3,
      lineDash: [0],
      lineDashOffset: 0,
      label: {
        ...LABEL_BOXING_DEFAULTS,
        enabled: true,
        fontSize: { $ref: "fontSize" },
        fontFamily: { $ref: "fontFamily" },
        fontWeight: { $ref: "fontWeight" },
        color: { $ref: "textColor" }
      },
      highlight: applyMapPalette(MULTI_SERIES_HIGHLIGHT_STYLE)
    },
    tooltip: {
      range: "exact"
    }
  },
  create: (ctx) => new MapLineSeries(ctx)
};

// packages/ag-charts-enterprise/src/series/map-util/polygonPointSearch.ts
function polygonPointSearch(polygons, precision, valueFn) {
  const bbox = polygonBbox(polygons[0], void 0);
  if (bbox == null)
    return;
  const boundingXCenter = (bbox.lon0 + bbox.lon1) / 2;
  const boundingYCenter = (bbox.lat0 + bbox.lat1) / 2;
  const boundingWidth = Math.abs(bbox.lon1 - bbox.lon0);
  const boundingHeight = Math.abs(bbox.lat1 - bbox.lat0);
  const centroid = polygonCentroid(polygons[0]);
  const [cx, cy] = centroid;
  const centroidDistanceToPolygon = -polygonDistance(polygons, cx, cy);
  let bestResult;
  const cellValue = (distanceToPolygon, distanceToCentroid) => {
    const centroidDriftFactor = 0.5;
    const centroidDrift = Math.max(distanceToCentroid - centroidDistanceToPolygon, 0);
    return distanceToPolygon - centroidDriftFactor * centroidDrift;
  };
  const createLabelPlacement = (x2, y2, stride) => {
    const { distance: distance3, maxDistance } = valueFn(polygons, x2, y2, stride);
    const distanceToCentroid = Math.hypot(cx - x2, cy - y2);
    const maxXTowardsCentroid = Math.min(Math.max(cx, x2 - stride / 2), x2 + stride / 2);
    const maxYTowardsCentroid = Math.min(Math.max(cy, y2 - stride / 2), y2 + stride / 2);
    const minDistanceToCentroid = Math.hypot(cx - maxXTowardsCentroid, cy - maxYTowardsCentroid);
    const value = cellValue(distance3, distanceToCentroid);
    const maxValue = cellValue(maxDistance, minDistanceToCentroid);
    return { distance: distance3, maxDistance, value, maxValue, x: x2, y: y2, stride };
  };
  const appendLabelPlacement = (into, x2, y2, stride) => {
    const labelPlacement = createLabelPlacement(x2, y2, stride);
    if (labelPlacement.maxDistance >= 0) {
      into.push(labelPlacement);
    }
  };
  const initialStride = Math.min(boundingWidth, boundingHeight) / 2;
  let queue = {
    value: createLabelPlacement(boundingXCenter, boundingYCenter, initialStride),
    next: null
  };
  while (queue != null) {
    const item = queue.value;
    const { distance: distance3, value, maxValue, x: x2, y: y2, stride } = item;
    queue = queue.next;
    if (distance3 > 0 && (bestResult == null || value > bestResult.value)) {
      bestResult = item;
    }
    if (bestResult != null && maxValue - bestResult.value <= precision) {
      continue;
    }
    const nextStride = stride / 2;
    const newLabelPlacements = [];
    appendLabelPlacement(newLabelPlacements, x2 - nextStride, y2 - nextStride, nextStride);
    appendLabelPlacement(newLabelPlacements, x2 + nextStride, y2 - nextStride, nextStride);
    appendLabelPlacement(newLabelPlacements, x2 - nextStride, y2 + nextStride, nextStride);
    appendLabelPlacement(newLabelPlacements, x2 + nextStride, y2 + nextStride, nextStride);
    newLabelPlacements.sort(labelPlacementCmp);
    queue = insertListItemsSorted(queue, newLabelPlacements, labelPlacementCmp);
  }
  if (bestResult == null)
    return;
  const { distance: distance2, x, y } = bestResult;
  return { x, y, distance: distance2 };
}
var labelPlacementCmp = (a, b) => b.maxValue - a.maxValue;

// packages/ag-charts-enterprise/src/series/map-util/markerUtil.ts
function polygonMarkerCenter(polygons, precision) {
  const result = polygonPointSearch(polygons, precision, (p, x2, y2, stride) => {
    const distance2 = -polygonDistance(p, x2, y2);
    const maxDistance = distance2 + stride * Math.SQRT2;
    return { distance: distance2, maxDistance };
  });
  if (result == null)
    return;
  const { x, y } = result;
  return [x, y];
}
function markerPositions(geometry, precision) {
  let center2;
  switch (geometry.type) {
    case "GeometryCollection":
      return geometry.geometries.flatMap((g) => markerPositions(g, precision));
    case "MultiPoint":
      return geometry.coordinates;
    case "Point":
      return [geometry.coordinates];
    case "MultiPolygon": {
      const polygon = largestPolygon(geometry);
      center2 = polygon == null ? void 0 : polygonMarkerCenter(polygon, precision);
      break;
    }
    case "Polygon": {
      const polygon = geometry.coordinates;
      center2 = polygon == null ? void 0 : polygonMarkerCenter(polygon, precision);
      break;
    }
    case "MultiLineString": {
      const lineString = largestLineString(geometry);
      center2 = lineString == null ? void 0 : lineStringCenter(lineString)?.point;
      break;
    }
    case "LineString": {
      const lineString = geometry.coordinates;
      center2 = lineStringCenter(lineString)?.point;
      break;
    }
  }
  return center2 == null ? [] : [center2];
}

// packages/ag-charts-enterprise/src/series/map-util/shapeFillBBox.ts
var { BBox: BBox30 } = module_support_exports;
function getTopologyShapeFillBBox(scale2) {
  if (!scale2)
    return;
  const { range: range3 } = scale2;
  const x = range3[0][0];
  const y = range3[0][1];
  const width2 = range3[1][0] - x;
  const height2 = range3[1][1] - y;
  const bbox = new BBox30(x, y, width2, height2);
  return {
    series: bbox,
    axis: bbox
  };
}

// packages/ag-charts-enterprise/src/series/map-marker/mapMarkerSeriesProperties.ts
var { SeriesProperties: SeriesProperties12, makeSeriesTooltip: makeSeriesTooltip23, Label: Label20 } = module_support_exports;
var MapMarkerSeriesLabel = class extends Label20 {
  constructor() {
    super(...arguments);
    this.placement = "bottom";
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesLabel.prototype, "placement", 2);
var MapMarkerSeriesProperties = class extends SeriesProperties12 {
  constructor() {
    super(...arguments);
    this.topology = void 0;
    this.idKey = void 0;
    this.topologyIdKey = "name";
    this.idName = void 0;
    this.latitudeKey = void 0;
    this.latitudeName = void 0;
    this.longitudeKey = void 0;
    this.longitudeName = void 0;
    this.labelKey = void 0;
    this.labelName = void 0;
    this.colorRange = void 0;
    this.shape = "circle";
    this.size = 6;
    this.fill = "black";
    this.fillOpacity = 1;
    this.stroke = "black";
    this.strokeWidth = 1;
    this.strokeOpacity = 1;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.label = new MapMarkerSeriesLabel();
    this.tooltip = makeSeriesTooltip23();
  }
  getStyle() {
    const { size, shape, fill, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this;
    return {
      size,
      shape,
      fill,
      fillOpacity,
      opacity: 1,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "topology", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "title", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "legendItemName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "idKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "topologyIdKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "idName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "latitudeKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "latitudeName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "longitudeKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "longitudeName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "labelKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "labelName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "sizeKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "sizeName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "colorKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "colorName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "colorRange", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "shape", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "size", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "maxSize", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "sizeDomain", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "itemStyler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapMarkerSeriesProperties.prototype, "tooltip", 2);

// packages/ag-charts-enterprise/src/series/map-marker/mapMarkerSeries.ts
var {
  fromToMotion: fromToMotion7,
  getMissCount: getMissCount4,
  createDatumId: createDatumId22,
  SeriesNodePickMode: SeriesNodePickMode16,
  valueProperty: valueProperty17,
  computeMarkerFocusBounds: computeMarkerFocusBounds4,
  ColorScale: ColorScale4,
  LinearScale: LinearScale7,
  Group: Group23,
  Selection: Selection17,
  Text: Text10,
  Marker: Marker7,
  getLabelStyles: getLabelStyles8
} = module_support_exports;
var MapMarkerSeries = class extends TopologySeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      categoryKey: void 0,
      propertyKeys: {
        size: ["colorKey"],
        color: ["colorKey"],
        label: ["labelKey"]
      },
      propertyNames: {
        size: ["sizeName"],
        color: ["colorName"],
        label: ["labelName"]
      },
      pickModes: [SeriesNodePickMode16.EXACT_SHAPE_MATCH, SeriesNodePickMode16.NEAREST_NODE],
      usesPlacedLabels: true
    });
    this.properties = new MapMarkerSeriesProperties();
    this._chartTopology = void 0;
    this.colorScale = new ColorScale4();
    this.sizeScale = new LinearScale7();
    this.markerGroup = this.contentGroup.appendChild(new Group23({ name: "markerGroup" }));
    this.labelSelection = Selection17.select(this.labelGroup, Text10, false);
    this.highlightLabelSelection = Selection17.select(this.highlightLabelGroup, Text10, false);
    this.markerSelection = Selection17.select(
      this.markerGroup,
      Marker7,
      false
    );
    this.highlightMarkerSelection = Selection17.select(this.highlightNodeGroup, Marker7);
    this.placedLabelData = [];
    this.animationState = new StateMachine(
      "empty",
      {
        empty: {
          update: {
            target: "ready",
            action: () => this.animateMarkers()
          },
          reset: "empty",
          skip: "ready"
        },
        ready: {
          updateData: "waiting",
          clear: "clearing",
          resize: () => this.resetAllAnimation(),
          reset: "empty",
          skip: "ready"
        },
        waiting: {
          update: {
            target: "ready",
            action: () => this.animateMarkers()
          },
          // chart.ts transitions to updateData on zoom change
          resize: {
            target: "ready",
            action: () => this.resetAllAnimation()
          },
          reset: "empty",
          skip: "ready"
        },
        clearing: {
          update: {
            target: "empty",
            action: () => this.resetAllAnimation()
          },
          reset: "empty",
          skip: "ready"
        }
      },
      () => this.checkProcessedDataAnimatable()
    );
  }
  getNodeData() {
    return this.contextNodeData?.nodeData;
  }
  get topology() {
    return this.properties.topology ?? this._chartTopology;
  }
  get hasData() {
    const hasLatLon = this.properties.latitudeKey != null && this.properties.longitudeKey != null;
    return super.hasData && (this.topology != null || hasLatLon);
  }
  renderToOffscreenCanvas() {
    return true;
  }
  setChartTopology(topology) {
    this._chartTopology = topology;
    if (this.topology === topology) {
      this.nodeDataRefresh = true;
    }
  }
  setZIndex(zIndex) {
    super.setZIndex(zIndex);
    this.contentGroup.zIndex = [2 /* Marker */, zIndex];
    this.highlightGroup.zIndex = [3 /* MarkerHighlight */, zIndex];
    return true;
  }
  isLabelEnabled() {
    return this.properties.labelKey != null && this.properties.label.enabled;
  }
  async processData(dataController) {
    if (this.data == null)
      return;
    const { data, sizeScale, colorScale } = this;
    const { topologyIdKey, idKey, latitudeKey, longitudeKey, sizeKey, colorKey, labelKey, sizeDomain, colorRange } = this.properties;
    const featureById = this.buildFeatureMap(topologyIdKey);
    const sizeScaleType = this.sizeScale.type;
    const colorScaleType = this.colorScale.type;
    const mercatorScaleType = this.scale?.type;
    const hasLatLon = latitudeKey != null && longitudeKey != null;
    const { dataModel, processedData } = await this.requestDataModel(dataController, data, {
      props: [
        ...idKey == null ? [] : [
          valueProperty17(idKey, mercatorScaleType, { id: "idValue", includeProperty: false }),
          valueProperty17(idKey, mercatorScaleType, {
            id: "featureValue",
            includeProperty: false,
            processor: () => (datum) => featureById.get(datum)
          })
        ],
        ...hasLatLon ? [
          valueProperty17(latitudeKey, mercatorScaleType, { id: "latValue" }),
          valueProperty17(longitudeKey, mercatorScaleType, { id: "lonValue" })
        ] : [],
        ...labelKey ? [valueProperty17(labelKey, "category", { id: "labelValue" })] : [],
        ...sizeKey ? [valueProperty17(sizeKey, sizeScaleType, { id: "sizeValue" })] : [],
        ...colorKey ? [valueProperty17(colorKey, colorScaleType, { id: "colorValue" })] : []
      ]
    });
    const featureValues = idKey == null ? void 0 : dataModel.resolveColumnById(this, `featureValue`, processedData);
    const latValues = hasLatLon ? dataModel.resolveColumnById(this, `latValue`, processedData) : void 0;
    const lonValues = hasLatLon ? dataModel.resolveColumnById(this, `lonValue`, processedData) : void 0;
    this.topologyBounds = processedData.dataSources.get(this.id)?.data.reduce((current, _datum, datumIndex) => {
      const feature = featureValues?.[datumIndex];
      const geometry = feature?.geometry;
      if (geometry != null) {
        current = geometryBbox(geometry, current);
      }
      if (latValues != null && lonValues != null) {
        const lon = lonValues[datumIndex];
        const lat = latValues[datumIndex];
        current = LonLatBBox.extend(current, lon, lat, lon, lat);
      }
      return current;
    }, void 0);
    if (sizeKey != null) {
      const sizeIdx = dataModel.resolveProcessedDataIndexById(this, `sizeValue`);
      const processedSize = processedData.domain.values[sizeIdx] ?? [];
      sizeScale.domain = sizeDomain ?? processedSize;
    }
    if (colorRange != null && this.isColorScaleValid()) {
      const colorKeyIdx = dataModel.resolveProcessedDataIndexById(this, "colorValue");
      colorScale.domain = processedData.domain.values[colorKeyIdx];
      colorScale.range = colorRange;
      colorScale.update();
    }
    this.animationState.transition("updateData");
  }
  isColorScaleValid() {
    const { colorKey } = this.properties;
    if (!colorKey) {
      return false;
    }
    const { dataModel, processedData } = this;
    if (!dataModel || !processedData) {
      return false;
    }
    const colorIdx = dataModel.resolveProcessedDataIndexById(this, "colorValue");
    const dataCount = processedData.input.count;
    const missCount = getMissCount4(this, processedData.defs.values[colorIdx].missing);
    const colorDataMissing = dataCount === 0 || dataCount === missCount;
    return !colorDataMissing;
  }
  getLabelDatum(node, labelValue, measurer3) {
    if (labelValue == null)
      return;
    const {
      idKey,
      idName,
      latitudeKey,
      latitudeName,
      longitudeKey,
      longitudeName,
      sizeKey,
      sizeName,
      colorKey,
      colorName,
      labelKey,
      labelName,
      label,
      shape
    } = this.properties;
    if (labelKey == null || !label.enabled)
      return;
    const { datum, datumIndex, index, idValue, lonValue, latValue, point } = node;
    const { placement } = label;
    const labelText = this.getLabelText(
      labelValue,
      datum,
      labelKey,
      "label",
      [],
      label,
      {
        value: labelValue,
        datum,
        idKey,
        idName,
        latitudeKey,
        latitudeName,
        longitudeKey,
        longitudeName,
        sizeKey,
        sizeName,
        colorKey,
        colorName,
        labelKey,
        labelName
      }
    );
    if (labelText == null)
      return;
    const { width: width2, height: height2 } = measurer3.measureLines(String(labelText));
    const anchor = Marker7.anchor(shape);
    return {
      point: { x: point.x, y: point.y, size: point.size },
      label: { width: width2, height: height2, text: labelText },
      anchor,
      placement,
      datumIndex,
      datumId: createDatumId22(index, idValue, lonValue, latValue)
    };
  }
  resolveColumn(key, columnId, processedData) {
    if (key == null || this.dataModel == null)
      return void 0;
    return this.dataModel.resolveColumnById(this, columnId, processedData);
  }
  resolveDataColumns(processedData) {
    const { idKey, latitudeKey, longitudeKey, sizeKey, colorKey, labelKey } = this.properties;
    const hasLatLon = latitudeKey != null && longitudeKey != null;
    return {
      idValues: this.resolveColumn(idKey, "idValue", processedData),
      featureValues: this.resolveColumn(idKey, "featureValue", processedData),
      latValues: hasLatLon ? this.resolveColumn(latitudeKey, "latValue", processedData) : void 0,
      lonValues: hasLatLon ? this.resolveColumn(longitudeKey, "lonValue", processedData) : void 0,
      labelValues: this.resolveColumn(labelKey, "labelValue", processedData),
      sizeValues: this.resolveColumn(sizeKey, "sizeValue", processedData),
      colorValues: this.resolveColumn(colorKey, "colorValue", processedData)
    };
  }
  prepareProjectedGeometries(idValues, featureValues, processedData) {
    if (idValues == null || featureValues == null || this.scale == null)
      return void 0;
    const projectedGeometries = /* @__PURE__ */ new Map();
    for (const [datumIndex] of processedData.dataSources.get(this.id)?.data.entries() ?? []) {
      const id = idValues[datumIndex];
      const geometry = featureValues[datumIndex]?.geometry;
      const projectedGeometry = geometry == null ? void 0 : projectGeometry(geometry, this.scale);
      if (id != null && projectedGeometry != null) {
        projectedGeometries.set(id, projectedGeometry);
      }
    }
    return projectedGeometries;
  }
  calculateMarkerSize(sizeValue) {
    return sizeValue == null ? this.properties.size : this.sizeScale.convert(sizeValue, { clamp: true });
  }
  buildNodeDatum(datum, datumIndex, index, point, dataValues) {
    return {
      series: this,
      datum,
      datumIndex,
      index,
      ...dataValues,
      point,
      midPoint: { x: point.x, y: point.y },
      legendItemName: this.properties.legendItemName,
      style: this.getMarkerItemStyle(
        { datumIndex, datum, colorValue: dataValues.colorValue, sizeValue: dataValues.sizeValue },
        false
      )
    };
  }
  createNodeFromLatLon(datum, datumIndex, lonValue, latValue, dataValues, size, measurer3) {
    if (this.scale == null) {
      throw new Error("Scale is required for createNodeFromLatLon");
    }
    const [x, y] = this.scale.convert([lonValue, latValue]);
    const point = { x, y, size };
    const node = this.buildNodeDatum(datum, datumIndex, -1, point, dataValues);
    const label = this.getLabelDatum(node, dataValues.labelValue, measurer3) ?? void 0;
    return { node, label };
  }
  createNodesFromGeometry(datum, datumIndex, geometry, dataValues, size, measurer3) {
    const nodes = [];
    const labels = [];
    for (const [index, [x, y]] of markerPositions(geometry, 1).entries()) {
      const point = { x, y, size };
      const node = this.buildNodeDatum(datum, datumIndex, index, point, dataValues);
      nodes.push(node);
      const label = this.getLabelDatum(node, dataValues.labelValue, measurer3);
      if (label) {
        labels.push(label);
      }
    }
    return { nodes, labels };
  }
  warnMissingGeometries(missingGeometries) {
    if (missingGeometries.length === 0)
      return;
    const missingGeometriesCap = 10;
    if (missingGeometries.length > missingGeometriesCap) {
      const excessItems = missingGeometries.length - missingGeometriesCap;
      missingGeometries.length = missingGeometriesCap;
      missingGeometries.push(`(+${excessItems} more)`);
    }
    logger_exports.warnOnce(`some data items do not have matches in the provided topology`, missingGeometries);
  }
  buildFeatureMap(topologyIdKey) {
    const featureById = /* @__PURE__ */ new Map();
    for (const feature of this.topology?.features.values() ?? []) {
      const property = feature.properties?.[topologyIdKey];
      if (property != null) {
        featureById.set(property, feature);
      }
    }
    return featureById;
  }
  createNodeData() {
    const { id: seriesId, dataModel, processedData, sizeScale, properties, scale: scale2 } = this;
    const { label } = properties;
    if (dataModel == null || processedData == null || scale2 == null)
      return;
    if (!this.visible) {
      return { itemId: seriesId, nodeData: [], labelData: [] };
    }
    const columns = this.resolveDataColumns(processedData);
    const markerMaxSize = properties.maxSize ?? properties.size;
    sizeScale.range = [Math.min(properties.size, markerMaxSize), markerMaxSize];
    const measurer3 = cachedTextMeasurer(label);
    const projectedGeometries = this.prepareProjectedGeometries(
      columns.idValues,
      columns.featureValues,
      processedData
    );
    const nodeData = [];
    const labelData = [];
    const missingGeometries = [];
    const rawData = processedData.dataSources.get(this.id)?.data ?? [];
    for (const [datumIndex, datum] of rawData.entries()) {
      const dataValues = {
        idValue: columns.idValues?.[datumIndex],
        lonValue: columns.lonValues?.[datumIndex],
        latValue: columns.latValues?.[datumIndex],
        colorValue: columns.colorValues?.[datumIndex],
        sizeValue: columns.sizeValues?.[datumIndex],
        labelValue: columns.labelValues?.[datumIndex]
      };
      const size = this.calculateMarkerSize(dataValues.sizeValue);
      const projectedGeometry = dataValues.idValue == null ? void 0 : projectedGeometries?.get(dataValues.idValue);
      if (dataValues.idValue != null && projectedGeometries != null && projectedGeometry == null) {
        missingGeometries.push(dataValues.idValue);
      }
      if (dataValues.lonValue != null && dataValues.latValue != null) {
        const result = this.createNodeFromLatLon(
          datum,
          datumIndex,
          dataValues.lonValue,
          dataValues.latValue,
          dataValues,
          size,
          measurer3
        );
        nodeData.push(result.node);
        if (result.label)
          labelData.push(result.label);
      } else if (projectedGeometry != null) {
        const result = this.createNodesFromGeometry(
          datum,
          datumIndex,
          projectedGeometry,
          dataValues,
          size,
          measurer3
        );
        nodeData.push(...result.nodes);
        labelData.push(...result.labels);
      }
    }
    this.warnMissingGeometries(missingGeometries);
    return {
      itemId: seriesId,
      nodeData,
      labelData
    };
  }
  updateSelections() {
    if (this.nodeDataRefresh) {
      this.contextNodeData = this.createNodeData();
      this.nodeDataRefresh = false;
    }
  }
  checkScaleChange() {
    if (this.previousScale === this.scale)
      return false;
    this.previousScale = this.scale;
    return true;
  }
  update({ seriesRect }) {
    const resize = this.checkResize(seriesRect);
    const scaleChange = this.checkScaleChange();
    const { markerSelection, highlightMarkerSelection } = this;
    const drawingMode = this.ctx.chartService.highlight?.drawingMode ?? "overlay";
    this.updateSelections();
    this.contentGroup.visible = this.visible;
    this.labelGroup.visible = this.visible;
    const highlightedDatum = this.getHighlightedDatum();
    const nodeData = this.contextNodeData?.nodeData ?? [];
    this.markerSelection = this.updateMarkerSelection({ markerData: nodeData, markerSelection });
    this.updateMarkerNodes({ markerSelection, isHighlight: false, highlightedDatum, drawingMode: "overlay" });
    this.highlightMarkerSelection = this.updateMarkerSelection({
      markerData: highlightedDatum == null ? [] : [highlightedDatum],
      markerSelection: highlightMarkerSelection
    });
    this.updateMarkerNodes({
      markerSelection: highlightMarkerSelection,
      isHighlight: true,
      highlightedDatum,
      drawingMode
    });
    this.updateLabelNodes({ labelSelection: this.labelSelection, isHighlight: false });
    this.updateHighlightLabelSelection(highlightedDatum);
    if (scaleChange || resize) {
      this.animationState.transition("resize");
    }
    this.animationState.transition("update");
  }
  updatePlacedLabelData(labelData) {
    this.placedLabelData = labelData;
    this.labelSelection = this.labelSelection.update(labelData, (text2) => {
      text2.pointerEvents = module_support_exports.PointerEvents.None;
    });
    this.updateLabelNodes({ labelSelection: this.labelSelection, isHighlight: false });
    this.updateHighlightLabelSelection();
  }
  updateLabelNodes({
    isHighlight,
    labelSelection
  }) {
    const { properties } = this;
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    labelSelection.each((label, placedLabel) => {
      const { x, y, width: width2, height: height2, text: text2, datum: labelDatum } = placedLabel;
      const style2 = getLabelStyles8(
        this,
        void 0,
        properties,
        properties.label,
        isHighlight,
        activeHighlight
      );
      const { color: fill, fontStyle, fontWeight: fontWeight2, fontSize, fontFamily } = style2;
      label.visible = true;
      label.x = x + width2 / 2;
      label.y = y + height2 / 2;
      label.text = text2;
      label.fill = fill;
      label.fontStyle = fontStyle;
      label.fontWeight = fontWeight2;
      label.fontSize = fontSize;
      label.fontFamily = fontFamily;
      label.textAlign = "center";
      label.textBaseline = "middle";
      const datumIndex = labelDatum?.datumIndex;
      label.fillOpacity = this.getHighlightStyle(isHighlight, datumIndex).opacity ?? 1;
      label.setBoxing(style2);
    });
  }
  getHighlightedLabelId(highlightedDatum = this.getHighlightedDatum()) {
    if (highlightedDatum == null)
      return void 0;
    return createDatumId22(
      highlightedDatum.index,
      highlightedDatum.idValue,
      highlightedDatum.lonValue,
      highlightedDatum.latValue
    );
  }
  updateHighlightLabelSelection(highlightedDatum = this.getHighlightedDatum()) {
    const highlightId = this.getHighlightedLabelId(highlightedDatum);
    const highlightLabels = highlightId == null || !this.isLabelEnabled() ? [] : this.placedLabelData.filter((label) => label.datum.datumId === highlightId);
    this.highlightLabelSelection = this.highlightLabelSelection.update(highlightLabels);
    if (highlightLabels.length === 0) {
      this.highlightLabelSelection.cleanup();
      this.highlightLabelGroup.visible = false;
      return;
    }
    this.highlightLabelGroup.visible = true;
    this.updateLabelNodes({
      labelSelection: this.highlightLabelSelection,
      isHighlight: true
    });
  }
  updateMarkerSelection(opts) {
    const { markerData, markerSelection } = opts;
    return markerSelection.update(
      markerData,
      void 0,
      (datum) => createDatumId22(datum.index, datum.idValue, datum.lonValue, datum.latValue)
    );
  }
  getMarkerItemStyle({ datumIndex, datum, colorValue, sizeValue }, isHighlight) {
    const { properties, colorScale, sizeScale } = this;
    const { colorRange, itemStyler } = properties;
    const highlightStyle = this.getHighlightStyle(isHighlight, datumIndex);
    const baseStyle = mergeDefaults(highlightStyle, properties.getStyle());
    if (!isHighlight && colorValue != null) {
      baseStyle.fill = this.isColorScaleValid() ? colorScale.convert(colorValue) : colorRange?.[0] ?? baseStyle.fill;
    }
    if (sizeValue != null) {
      baseStyle.size = sizeScale.convert(sizeValue, { clamp: true });
    }
    let style2 = baseStyle;
    if (itemStyler != null && datumIndex != null) {
      const overrides = this.cachedDatumCallback(
        createDatumId22(datumIndex, isHighlight ? "highlight" : "node"),
        () => {
          const params = this.makeItemStylerParams(datum, datumIndex, isHighlight, style2);
          return this.callWithContext(itemStyler, params);
        }
      );
      if (overrides) {
        style2 = mergeDefaults(overrides, baseStyle);
      }
    }
    return style2;
  }
  makeItemStylerParams(datum, datumIndex, isHighlight, style2) {
    const { id: seriesId } = this;
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const highlightState = this.getHighlightStateString(activeHighlight, isHighlight, datumIndex);
    const fill = this.filterItemStylerFillParams(style2.fill) ?? style2.fill;
    return {
      seriesId,
      datum,
      highlightState,
      ...style2,
      fill
    };
  }
  updateMarkerNodes(opts) {
    const { markerSelection, isHighlight, highlightedDatum, drawingMode } = opts;
    const fillBBox = getTopologyShapeFillBBox(this.scale);
    markerSelection.each((marker, markerDatum) => {
      const { datum, point } = markerDatum;
      const style2 = this.getMarkerItemStyle(markerDatum, isHighlight);
      marker.shape = style2.shape;
      marker.size = style2.size;
      marker.setStyleProperties(style2, fillBBox);
      marker.x = point.x;
      marker.y = point.y;
      marker.scalingCenterX = point.x;
      marker.scalingCenterY = point.y;
      marker.zIndex = !isHighlight && highlightedDatum != null && datum === highlightedDatum.datum ? 1 : 0;
      marker.drawingMode = drawingMode;
    });
  }
  isProcessedDataAnimatable() {
    return true;
  }
  resetAnimation(phase) {
    if (phase === "initial") {
      this.animationState.transition("reset");
    } else if (phase === "ready") {
      this.animationState.transition("skip");
    }
  }
  resetAllAnimation() {
    this.ctx.animationManager.stopByAnimationGroupId(this.id);
    this.ctx.animationManager.skipCurrentBatch();
    this.labelSelection.cleanup();
    this.markerSelection.cleanup();
    this.highlightMarkerSelection.cleanup();
    this.highlightLabelSelection.cleanup();
    this.highlightLabelGroup.visible = false;
    this.placedLabelData = [];
  }
  animateMarkers() {
    const { animationManager } = this.ctx;
    const fns = prepareMapMarkerAnimationFunctions();
    fromToMotion7(this.id, "markers", animationManager, [this.markerSelection, this.highlightMarkerSelection], fns);
  }
  getLabelData() {
    if (!this.isLabelEnabled())
      return [];
    return this.contextNodeData?.labelData ?? [];
  }
  pickNodeClosestDatum(p) {
    const { x: x0, y: y0 } = p;
    let minDistanceSquared = Infinity;
    let minDatum;
    for (const datum of this.contextNodeData?.nodeData ?? []) {
      const { x, y, size } = datum.point;
      const dx2 = Math.max(Math.abs(x - x0) - size, 0);
      const dy2 = Math.max(Math.abs(y - y0) - size, 0);
      const distanceSquared2 = dx2 * dx2 + dy2 * dy2;
      if (distanceSquared2 < minDistanceSquared) {
        minDistanceSquared = distanceSquared2;
        minDatum = datum;
      }
    }
    return minDatum == null ? void 0 : { datum: minDatum, distance: Math.sqrt(minDistanceSquared) };
  }
  legendItemSymbol(datumIndex) {
    const { dataModel, processedData, properties } = this;
    const { shape, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = properties;
    let { fill } = properties;
    if (datumIndex != null && this.isColorScaleValid()) {
      const colorValues = dataModel.resolveColumnById(this, "colorValue", processedData);
      const colorValue = colorValues[datumIndex];
      fill = this.colorScale.convert(colorValue);
    }
    return {
      marker: {
        shape,
        fill,
        fillOpacity,
        stroke: stroke3,
        strokeWidth,
        strokeOpacity,
        lineDash,
        lineDashOffset
      }
    };
  }
  getLegendData(legendType) {
    const { processedData, dataModel } = this;
    if (processedData == null || dataModel == null)
      return [];
    const { id: seriesId, visible } = this;
    const { title, legendItemName, idName, idKey, colorKey, colorRange, showInLegend } = this.properties;
    if (legendType === "gradient" && colorKey != null && colorRange != null) {
      const colorDomain = processedData.domain.values[dataModel.resolveProcessedDataIndexById(this, "colorValue")];
      const legendDatum = {
        legendType: "gradient",
        enabled: visible,
        seriesId,
        series: this.getFormatterContext("color"),
        colorRange,
        colorDomain
      };
      return [legendDatum];
    } else if (legendType === "category") {
      const legendDatum = {
        legendType: "category",
        id: seriesId,
        itemId: seriesId,
        seriesId,
        enabled: visible,
        label: { text: legendItemName ?? title ?? idName ?? idKey ?? seriesId },
        symbol: this.legendItemSymbol(),
        legendItemName,
        hideInLegend: !showInLegend
      };
      return [legendDatum];
    } else {
      return [];
    }
  }
  getTooltipContent(datumIndex) {
    const {
      id: seriesId,
      dataModel,
      processedData,
      properties,
      ctx: { formatManager }
    } = this;
    const {
      idKey,
      idName,
      latitudeKey,
      latitudeName,
      longitudeKey,
      longitudeName,
      colorKey,
      colorName,
      sizeKey,
      sizeName,
      labelKey,
      labelName,
      title,
      legendItemName,
      tooltip
    } = properties;
    if (!dataModel || !processedData)
      return;
    const datum = processedData.dataSources.get(this.id)?.data[datumIndex];
    const sizeValue = sizeKey == null ? void 0 : dataModel.resolveColumnById(this, `sizeValue`, processedData)[datumIndex];
    const colorValue = colorKey == null ? void 0 : dataModel.resolveColumnById(this, `colorValue`, processedData)[datumIndex];
    const data = [];
    if (this.isLabelEnabled() && labelKey != null && labelKey !== idKey) {
      const labelValue = dataModel.resolveColumnById(this, `labelValue`, processedData)[datumIndex];
      const content = formatManager.format(this.callWithContext.bind(this), {
        type: "category",
        value: labelValue,
        datum,
        seriesId,
        legendItemName,
        key: labelKey,
        source: "tooltip",
        property: "label",
        domain: [],
        boundSeries: this.getFormatterContext("label")
      });
      data.push({ label: labelName, fallbackLabel: labelKey, value: content ?? labelValue });
    }
    if (sizeKey != null && sizeValue != null) {
      const domain = dataModel.getDomain(this, `sizeValue`, "value", processedData).domain;
      const content = formatManager.format(this.callWithContext.bind(this), {
        type: "number",
        value: sizeValue,
        datum,
        seriesId,
        legendItemName,
        key: sizeKey,
        source: "tooltip",
        property: "size",
        domain,
        boundSeries: this.getFormatterContext("size"),
        fractionDigits: void 0,
        visibleDomain: void 0
      });
      data.push({ label: sizeName, fallbackLabel: sizeKey, value: content ?? String(sizeValue) });
    }
    if (colorKey != null && colorValue != null) {
      const domain = dataModel.getDomain(this, `colorValue`, "value", processedData).domain;
      const content = formatManager.format(this.callWithContext.bind(this), {
        type: "number",
        value: colorValue,
        datum,
        seriesId,
        legendItemName,
        key: colorKey,
        source: "tooltip",
        property: "color",
        domain,
        boundSeries: this.getFormatterContext("color"),
        fractionDigits: void 0,
        visibleDomain: void 0
      });
      data.push({ label: colorName, fallbackLabel: colorKey, value: content ?? String(colorValue) });
    }
    let heading;
    if (idKey != null) {
      heading = dataModel.resolveColumnById(this, `idValue`, processedData)[datumIndex];
    } else if (latitudeKey != null && longitudeKey != null) {
      const latValue = dataModel.resolveColumnById(this, `latValue`, processedData)[datumIndex];
      const lonValue = dataModel.resolveColumnById(this, `lonValue`, processedData)[datumIndex];
      heading = `${Math.abs(latValue).toFixed(4)}\xB0 ${latValue >= 0 ? "N" : "S"}, ${Math.abs(lonValue).toFixed(4)}\xB0 ${lonValue >= 0 ? "W" : "E"}`;
    }
    const format = this.getMarkerItemStyle({ datumIndex, datum, colorValue, sizeValue }, false);
    return this.formatTooltipWithContext(
      tooltip,
      {
        heading,
        title: title ?? legendItemName,
        symbol: this.legendItemSymbol(datumIndex),
        data
      },
      {
        seriesId,
        datum,
        title,
        idKey,
        idName,
        latitudeKey,
        latitudeName,
        longitudeKey,
        longitudeName,
        colorKey,
        colorName,
        sizeKey,
        sizeName,
        labelKey,
        labelName,
        ...format
      }
    );
  }
  getFormattedMarkerStyle(markerDatum) {
    const format = this.getMarkerItemStyle(markerDatum, false);
    return { size: format.size, shape: format.shape };
  }
  computeFocusBounds(opts) {
    return computeMarkerFocusBounds4(this, opts);
  }
  hasItemStylers() {
    return this.properties.itemStyler != null || this.properties.label.itemStyler != null;
  }
};
MapMarkerSeries.className = "MapMarkerSeries";
MapMarkerSeries.type = "map-marker";

// packages/ag-charts-enterprise/src/series/map-marker/mapMarkerSeriesOptionsDef.ts
var { mapMarkerSeriesThemeableOptionsDef: mapMarkerSeriesThemeableOptionsDef2 } = module_support_exports;
var mapMarkerSeriesOptionsDef = {
  ...without(commonSeriesOptionsDefs, ["highlightStyle", "highlight"]),
  ...mapMarkerSeriesThemeableOptionsDef2,
  type: required(constant("map-marker")),
  idKey: string,
  latitudeKey: string,
  longitudeKey: string,
  sizeKey: string,
  colorKey: string,
  labelKey: string,
  idName: string,
  latitudeName: string,
  longitudeName: string,
  sizeName: string,
  colorName: string,
  labelName: string,
  topology: geoJson,
  topologyIdKey: string,
  legendItemName: string,
  title: string
};

// packages/ag-charts-enterprise/src/series/map-marker/mapMarkerModule.ts
var MapMarkerSeriesModule = {
  type: "series",
  name: "map-marker",
  chartType: "topology",
  enterprise: true,
  version: VERSION,
  dependencies: [TopologyChartModule],
  options: mapMarkerSeriesOptionsDef,
  themeTemplate: {
    ...MAP_THEME_DEFAULTS,
    series: {
      shape: "circle",
      maxSize: 30,
      fill: applyMapPalette({
        $applySwitch: [
          { $path: "type" },
          { $mapPalette: "fill" },
          ["gradient", FILL_GRADIENT_RADIAL_REVERSED_DEFAULTS],
          ["image", FILL_IMAGE_DEFAULTS],
          ["pattern", FILL_PATTERN_DEFAULTS]
        ]
      }),
      stroke: { $mapPalette: "stroke" },
      colorRange: {
        $if: [
          { $eq: [{ $mapPalette: "type" }, "inbuilt"] },
          { $mapPalette: "divergingColors" },
          applyMapPalette(SAFE_RANGE2_OPERATION)
        ]
      },
      fillOpacity: 0.5,
      label: {
        ...LABEL_BOXING_DEFAULTS,
        enabled: false,
        fontSize: { $ref: "fontSize" },
        fontFamily: { $ref: "fontFamily" },
        fontWeight: { $ref: "fontWeight" },
        color: { $ref: "textColor" }
      },
      highlight: applyMapPalette(MULTI_SERIES_HIGHLIGHT_STYLE)
    },
    tooltip: {
      range: "exact"
    }
  },
  create: (ctx) => new MapMarkerSeries(ctx),
  validate(options, optionsDefs2, path) {
    const result = validate(options, optionsDefs2, path);
    const { cleared, invalid } = result;
    if (cleared?.idKey == null && (cleared?.latitudeKey == null || cleared?.longitudeKey == null)) {
      const extendPath2 = (key) => path ? `${path}.${key}` : key;
      const message = `Either \`${extendPath2("idKey")}\` or both \`${extendPath2("latitudeKey")}\` and \`${extendPath2("longitudeKey")}\` are required.`;
      invalid.push(new ValidationError("required", message, null, path));
    }
    return result;
  }
};

// packages/ag-charts-enterprise/src/series/map-shape-background/mapShapeBackgroundSeriesProperties.ts
var { SeriesProperties: SeriesProperties13, makeSeriesTooltip: makeSeriesTooltip24 } = module_support_exports;
var MapShapeBackgroundSeriesProperties = class extends SeriesProperties13 {
  constructor() {
    super(...arguments);
    this.topology = void 0;
    this.fill = "black";
    this.fillOpacity = 1;
    this.stroke = "black";
    this.strokeOpacity = 1;
    this.strokeWidth = 0;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.tooltip = makeSeriesTooltip24();
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeBackgroundSeriesProperties.prototype, "topology", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeBackgroundSeriesProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeBackgroundSeriesProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeBackgroundSeriesProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeBackgroundSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeBackgroundSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeBackgroundSeriesProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeBackgroundSeriesProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeBackgroundSeriesProperties.prototype, "tooltip", 2);

// packages/ag-charts-enterprise/src/series/map-shape-background/mapShapeBackgroundSeries.ts
var { createDatumId: createDatumId23, Selection: Selection18, Group: Group24, PointerEvents: PointerEvents13 } = module_support_exports;
var MapShapeBackgroundSeries = class extends TopologySeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      categoryKey: void 0,
      pickModes: []
    });
    this.properties = new MapShapeBackgroundSeriesProperties();
    this._chartTopology = void 0;
    this.itemGroup = this.contentGroup.appendChild(new Group24({ name: "itemGroup" }));
    this.datumSelection = Selection18.select(
      this.itemGroup,
      () => this.nodeFactory()
    );
    this.itemGroup.pointerEvents = PointerEvents13.None;
  }
  get topology() {
    return this.properties.topology ?? this._chartTopology;
  }
  get focusable() {
    return false;
  }
  setOptionsData() {
  }
  setChartData() {
  }
  getNodeData() {
    return;
  }
  get hasData() {
    return false;
  }
  renderToOffscreenCanvas() {
    return true;
  }
  setChartTopology(topology) {
    this._chartTopology = topology;
    if (this.topology === topology) {
      this.nodeDataRefresh = true;
    }
  }
  setZIndex(zIndex) {
    super.setZIndex(zIndex);
    this.contentGroup.zIndex = [0 /* ShapeLineBackground */, zIndex, 0];
    this.highlightGroup.zIndex = [0 /* ShapeLineBackground */, zIndex, 1];
    return true;
  }
  nodeFactory() {
    const geoGeometry = new GeoGeometry();
    geoGeometry.renderMode = 1 /* Polygons */;
    geoGeometry.lineJoin = "round";
    geoGeometry.pointerEvents = PointerEvents13.None;
    return geoGeometry;
  }
  processData() {
    const { topology } = this;
    this.topologyBounds = topology?.features.reduce((current, feature) => {
      const geometry = feature.geometry;
      if (geometry == null)
        return current;
      return geometryBbox(geometry, current);
    }, void 0);
    if (topology == null) {
      logger_exports.warnOnce(`no topology was provided for [MapShapeBackgroundSeries]; nothing will be rendered.`);
    }
  }
  createNodeData() {
    const { id: seriesId, topology, scale: scale2, properties } = this;
    if (topology == null)
      return;
    const { fill, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = properties;
    const nodeData = [];
    const labelData = [];
    for (const [index, feature] of topology.features.entries()) {
      const { geometry } = feature;
      const projectedGeometry = geometry != null && scale2 != null ? projectGeometry(geometry, scale2) : void 0;
      if (projectedGeometry == null)
        continue;
      nodeData.push({
        series: this,
        datum: feature,
        datumIndex: 0,
        index,
        projectedGeometry,
        style: { fill, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset }
      });
    }
    return {
      itemId: seriesId,
      nodeData,
      labelData
    };
  }
  updateSelections() {
    if (this.nodeDataRefresh) {
      this.contextNodeData = this.createNodeData();
      this.nodeDataRefresh = false;
    }
  }
  update() {
    const { datumSelection } = this;
    this.updateSelections();
    this.contentGroup.visible = this.visible;
    this.labelGroup.visible = this.visible;
    const { nodeData = [] } = this.contextNodeData ?? {};
    this.datumSelection = this.updateDatumSelection({ nodeData, datumSelection });
    this.updateDatumNodes({ datumSelection });
  }
  updateDatumSelection(opts) {
    return opts.datumSelection.update(opts.nodeData, void 0, (datum) => createDatumId23(datum.index));
  }
  updateDatumNodes(opts) {
    const { datumSelection } = opts;
    datumSelection.each((geoGeometry, datum) => {
      const { projectedGeometry } = datum;
      if (projectedGeometry == null) {
        geoGeometry.visible = false;
        geoGeometry.projectedGeometry = void 0;
        return;
      }
      geoGeometry.visible = true;
      geoGeometry.projectedGeometry = projectedGeometry;
      geoGeometry.setProperties(datum.style);
    });
  }
  resetAnimation() {
  }
  getLegendData() {
    return [];
  }
  getTooltipContent(_seriesDatum) {
    return;
  }
  pickFocus() {
    return void 0;
  }
  computeFocusBounds(_opts) {
    return void 0;
  }
  hasItemStylers() {
    return false;
  }
};
MapShapeBackgroundSeries.className = "MapShapeBackgroundSeries";
MapShapeBackgroundSeries.type = "map-shape-background";

// packages/ag-charts-enterprise/src/series/map-shape-background/mapShapeBackgroundSeriesOptionsDef.ts
var { mapShapeBackgroundSeriesThemeableOptionsDef: mapShapeBackgroundSeriesThemeableOptionsDef2 } = module_support_exports;
var mapShapeBackgroundSeriesOptionsDef = {
  ...mapShapeBackgroundSeriesThemeableOptionsDef2,
  ...commonSeriesOptionsDefs,
  type: required(constant("map-shape-background")),
  topology: geoJson
};

// packages/ag-charts-enterprise/src/series/map-shape-background/mapShapeBackgroundModule.ts
var MapShapeBackgroundSeriesModule = {
  type: "series",
  name: "map-shape-background",
  chartType: "topology",
  enterprise: true,
  version: VERSION,
  dependencies: [TopologyChartModule],
  options: mapShapeBackgroundSeriesOptionsDef,
  themeTemplate: {
    ...MAP_THEME_DEFAULTS,
    series: {
      fill: applyMapPalette({
        $applySwitch: [
          { $path: "type" },
          { $path: ["/1", { $mapPalette: "fill" }, { $mapPalette: "hierarchyColors" }] },
          ["gradient", FILL_GRADIENT_LINEAR_HIERARCHY_DEFAULTS],
          ["image", FILL_IMAGE_DEFAULTS],
          ["pattern", FILL_PATTERN_HIERARCHY_DEFAULTS]
        ]
      }),
      stroke: { $ref: "chartBackgroundColor" },
      strokeWidth: 1
    }
  },
  create: (ctx) => new MapShapeBackgroundSeries(ctx)
};

// packages/ag-charts-enterprise/src/series/map-util/polygonLabelUtil.ts
function preferredLabelCenter(polygons, { aspectRatio, precision }) {
  const result = polygonPointSearch(polygons, precision, (p, cx, cy, stride) => {
    const width2 = maxWidthOfRectConstrainedByCenterAndAspectRatioToPolygon(p, cx, cy, aspectRatio);
    const maxWidth2 = width2 + 2 * stride * aspectRatio;
    const distance3 = width2 * Math.SQRT2;
    const maxDistance = maxWidth2 * Math.SQRT2;
    return { distance: distance3, maxDistance };
  });
  if (result == null)
    return;
  const { x, y, distance: distance2 } = result;
  const maxWidth = distance2 / Math.SQRT2;
  return { x, y, maxWidth };
}
function maxWidthOfRectConstrainedByCenterAndAspectRatioToLineSegment(a, b, cx, cy, aspectRatio) {
  const [ax, ay] = a;
  const [bx, by] = b;
  const positiveM = 1 / aspectRatio;
  const abx = bx - ax;
  const aby = by - ay;
  const [topPointX, topPointY] = ay <= by ? a : b;
  const [leftPointX, leftPointY] = ax <= bx ? a : b;
  const [bottomPointX, bottomPointY] = ay <= by ? b : a;
  const [rightPointX, rightPointY] = ax <= bx ? b : a;
  let maxWidth = Infinity;
  if (abx === 0) {
    for (let i = 0; i <= 1; i += 1) {
      const m = i === 0 ? positiveM : -positiveM;
      const y = m * (ax - cx) + cy;
      if (y >= topPointY && y <= bottomPointY) {
        const height2 = Math.abs(cy - y) * 2;
        const width2 = height2 * aspectRatio;
        maxWidth = Math.min(maxWidth, width2);
      }
    }
  } else {
    const abm = aby / abx;
    for (let i = 0; i <= 1; i += 1) {
      const m = i === 0 ? positiveM : -positiveM;
      const x = (abm * ax - ay - m * cx + cy) / (abm - m);
      if (x >= leftPointX && x <= rightPointX) {
        const width2 = Math.abs(cx - x) * 2;
        maxWidth = Math.min(maxWidth, width2);
      }
    }
  }
  const positiveMRecip = aspectRatio;
  const centerToTopMRecip = Math.abs((topPointX - cx) / (topPointY - cy));
  const centerToBottomMRecip = Math.abs((bottomPointX - cx) / (bottomPointY - cy));
  if (bottomPointY < cy && centerToBottomMRecip < positiveMRecip) {
    const height2 = Math.abs(cy - bottomPointY) * 2;
    const width2 = height2 * aspectRatio;
    maxWidth = Math.min(maxWidth, width2);
  } else if (topPointY > cy && centerToTopMRecip < positiveMRecip) {
    const height2 = Math.abs(cy - topPointY) * 2;
    const width2 = height2 * aspectRatio;
    maxWidth = Math.min(maxWidth, width2);
  }
  const centerToLeftM = Math.abs((leftPointY - cy) / (leftPointX - cx));
  const centerToRightM = Math.abs((rightPointY - cy) / (rightPointX - cx));
  if (rightPointX < cx && centerToRightM < positiveM) {
    const width2 = Math.abs(cx - rightPointX) * 2;
    maxWidth = Math.min(maxWidth, width2);
  } else if (leftPointX > cx && centerToLeftM < positiveM) {
    const width2 = Math.abs(cx - leftPointX) * 2;
    maxWidth = Math.min(maxWidth, width2);
  }
  return maxWidth;
}
function maxWidthOfRectConstrainedByCenterAndAspectRatioToPolygon(polygons, cx, cy, aspectRatio) {
  let inside = false;
  let minWidth = Infinity;
  for (const polygon of polygons) {
    let p0 = polygon.at(-1);
    let [x0, y0] = p0;
    for (const p1 of polygon) {
      const [x1, y1] = p1;
      if (y1 > cy !== y0 > cy && cx < (x0 - x1) * (cy - y1) / (y0 - y1) + x1) {
        inside = !inside;
      }
      const width2 = maxWidthOfRectConstrainedByCenterAndAspectRatioToLineSegment(p0, p1, cx, cy, aspectRatio);
      minWidth = Math.min(minWidth, width2);
      p0 = p1;
      x0 = x1;
      y0 = y1;
    }
  }
  return (inside ? 1 : -1) * minWidth;
}
function applyX(into, cx, x) {
  if (x >= cx) {
    into.maxX = Math.min(into.maxX, x - cx);
  }
  if (x <= cx) {
    into.minX = Math.max(into.minX, x - cx);
  }
}
function xExtentsOfRectConstrainedByCenterAndHeightToLineSegment(into, a, b, cx, cy, height2) {
  const ry0 = cy - height2 / 2;
  const ry1 = cy + height2 / 2;
  const [ax, ay] = a;
  const [bx, by] = b;
  const abx = bx - ax;
  const aby = by - ay;
  const [leftPointX, leftPointY] = ax <= bx ? a : b;
  const [rightPointX, rightPointY] = ax <= bx ? b : a;
  if (abx !== 0) {
    const abm = aby / abx;
    for (let i = 0; i <= 1; i += 1) {
      const y = i === 0 ? ry0 : ry1;
      const x = (y - ay) / abm + ax;
      if (x >= leftPointX && x <= rightPointX) {
        applyX(into, cx, x);
      }
    }
  } else if (Math.max(ry0, Math.min(ay, by)) <= Math.min(ry1, Math.max(ay, by))) {
    applyX(into, cx, ax);
  }
  if (rightPointX < cx && rightPointY >= ry0 && rightPointY <= ry1) {
    applyX(into, cx, rightPointX);
  } else if (leftPointX > cx && leftPointY >= ry0 && leftPointY <= ry1) {
    applyX(into, cx, leftPointX);
  }
  return into;
}
function maxWidthInPolygonForRectOfHeight(polygons, cx, cy, height2) {
  const result = {
    minX: -Infinity,
    maxX: Infinity
  };
  for (const polygon of polygons) {
    let p0 = polygon.at(-1);
    for (const p1 of polygon) {
      xExtentsOfRectConstrainedByCenterAndHeightToLineSegment(result, p0, p1, cx, cy, height2);
      p0 = p1;
    }
  }
  const { minX, maxX } = result;
  if (Number.isFinite(minX) && Number.isFinite(maxX)) {
    return { x: cx + (minX + maxX) / 2, width: maxX - minX };
  } else {
    return { x: cx, width: 0 };
  }
}

// packages/ag-charts-enterprise/src/series/map-shape/mapShapeSeriesProperties.ts
var { SeriesProperties: SeriesProperties14, makeSeriesTooltip: makeSeriesTooltip25 } = module_support_exports;
var MapShapeSeriesProperties = class extends SeriesProperties14 {
  constructor() {
    super(...arguments);
    this.topology = void 0;
    this.idKey = "";
    this.idName = void 0;
    this.topologyIdKey = "name";
    this.labelKey = void 0;
    this.labelName = void 0;
    this.colorRange = void 0;
    this.fill = "black";
    this.fillOpacity = 1;
    this.stroke = "black";
    this.strokeOpacity = 1;
    this.strokeWidth = 0;
    this.lineDash = [0];
    this.lineDashOffset = 0;
    this.padding = 0;
    this.label = new AutoSizedSecondaryLabel();
    this.tooltip = makeSeriesTooltip25();
  }
  getStyle() {
    const { fill, fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = this;
    return {
      fill,
      fillOpacity,
      stroke: stroke3,
      strokeWidth,
      strokeOpacity,
      lineDash,
      lineDashOffset,
      opacity: 1
    };
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "topology", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "title", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "legendItemName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "idKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "idName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "topologyIdKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "labelKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "labelName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "colorKey", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "colorName", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "colorRange", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "fillOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "stroke", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "strokeOpacity", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "strokeWidth", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "lineDash", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "lineDashOffset", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "padding", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "itemStyler", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "label", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], MapShapeSeriesProperties.prototype, "tooltip", 2);

// packages/ag-charts-enterprise/src/series/map-shape/mapShapeSeries.ts
var {
  getMissCount: getMissCount5,
  createDatumId: createDatumId24,
  SeriesNodePickMode: SeriesNodePickMode17,
  valueProperty: valueProperty18,
  ColorScale: ColorScale5,
  Group: Group25,
  Selection: Selection19,
  Text: Text11,
  PointerEvents: PointerEvents14,
  getLabelStyles: getLabelStyles9
} = module_support_exports;
var fixedScale = module_support_exports.MercatorScale.fixedScale();
var MapShapeSeries = class extends TopologySeries {
  constructor(moduleCtx) {
    super({
      moduleCtx,
      categoryKey: void 0,
      propertyKeys: {
        color: ["colorKey"],
        label: ["labelKey"]
      },
      propertyNames: {
        color: ["colorName"],
        label: ["labelName"]
      },
      pickModes: [SeriesNodePickMode17.EXACT_SHAPE_MATCH, SeriesNodePickMode17.NEAREST_NODE]
    });
    this.properties = new MapShapeSeriesProperties();
    this._chartTopology = void 0;
    this.colorScale = new ColorScale5();
    this.itemGroup = this.contentGroup.appendChild(new Group25({ name: "itemGroup" }));
    this.itemLabelGroup = this.contentGroup.appendChild(new Group25({ name: "itemLabelGroup" }));
    this.datumSelection = Selection19.select(
      this.itemGroup,
      () => this.nodeFactory()
    );
    this.labelSelection = Selection19.select(
      this.itemLabelGroup,
      Text11
    );
    this.highlightDatumSelection = Selection19.select(
      this.highlightNodeGroup,
      () => this.nodeFactory()
    );
    this.highlightLabelSelection = Selection19.select(this.highlightLabelGroup, Text11);
    this.previousLabelLayouts = void 0;
    this._previousDatumMidPoint = void 0;
    this.itemLabelGroup.pointerEvents = PointerEvents14.None;
  }
  getNodeData() {
    return this.contextNodeData?.nodeData;
  }
  get topology() {
    return this.properties.topology ?? this._chartTopology;
  }
  get hasData() {
    return super.hasData && this.topology != null;
  }
  renderToOffscreenCanvas() {
    return true;
  }
  setChartTopology(topology) {
    this._chartTopology = topology;
    if (this.topology === topology) {
      this.nodeDataRefresh = true;
    }
  }
  setZIndex(zIndex) {
    super.setZIndex(zIndex);
    this.contentGroup.zIndex = [1 /* ShapeLine */, zIndex];
    this.highlightGroup.zIndex = [4 /* ShapeLineHighlight */, zIndex];
    return true;
  }
  isLabelEnabled() {
    return this.properties.labelKey != null && this.properties.label.enabled;
  }
  nodeFactory() {
    const geoGeometry = new GeoGeometry();
    geoGeometry.renderMode = 1 /* Polygons */;
    geoGeometry.lineJoin = "round";
    return geoGeometry;
  }
  async processData(dataController) {
    if (this.data == null)
      return;
    const { data, topology, colorScale } = this;
    const { topologyIdKey, idKey, colorKey, labelKey, colorRange } = this.properties;
    const featureById = /* @__PURE__ */ new Map();
    for (const feature of topology?.features.values() ?? []) {
      const property = feature.properties?.[topologyIdKey];
      if (property == null || !containsType(feature.geometry, 1 /* Polygon */))
        continue;
      featureById.set(property, feature);
    }
    const colorScaleType = this.colorScale.type;
    const mercatorScaleType = this.scale?.type;
    const { dataModel, processedData } = await this.requestDataModel(dataController, data, {
      props: [
        valueProperty18(idKey, mercatorScaleType, { id: "idValue", includeProperty: false }),
        valueProperty18(idKey, mercatorScaleType, {
          id: "featureValue",
          includeProperty: false,
          processor: () => (datum) => featureById.get(datum)
        }),
        ...labelKey ? [valueProperty18(labelKey, "category", { id: "labelValue" })] : [],
        ...colorKey ? [valueProperty18(colorKey, colorScaleType, { id: "colorValue" })] : []
      ]
    });
    const featureValues = dataModel.resolveColumnById(this, `featureValue`, processedData);
    this.topologyBounds = featureValues.reduce((current, feature) => {
      const geometry = feature?.geometry;
      if (geometry == null)
        return current;
      return geometryBbox(geometry, current);
    }, void 0);
    if (colorRange != null && this.isColorScaleValid()) {
      const colorKeyIdx = dataModel.resolveProcessedDataIndexById(this, "colorValue");
      colorScale.domain = processedData.domain.values[colorKeyIdx];
      colorScale.range = colorRange;
      colorScale.update();
    }
    if (topology == null) {
      logger_exports.warnOnce(`no topology was provided for [MapShapeSeries]; nothing will be rendered.`);
    }
  }
  isColorScaleValid() {
    const { colorKey } = this.properties;
    if (!colorKey) {
      return false;
    }
    const { dataModel, processedData } = this;
    if (!dataModel || !processedData) {
      return false;
    }
    const colorIdx = dataModel.resolveProcessedDataIndexById(this, "colorValue");
    const dataCount = processedData.input.count;
    const missCount = getMissCount5(this, processedData.defs.values[colorIdx].missing);
    const colorDataMissing = dataCount === 0 || dataCount === missCount;
    return !colorDataMissing;
  }
  getLabelLayout(datum, labelValue, measurer3, geometry, previousLabelLayout) {
    if (labelValue == null || geometry == null)
      return;
    const { idKey, idName, colorKey, colorName, labelKey, labelName, padding: padding2, label } = this.properties;
    if (labelKey == null || !label.enabled)
      return;
    const labelText = this.getLabelText(
      labelValue,
      datum,
      labelKey,
      "label",
      [],
      label,
      {
        value: labelValue,
        datum,
        idKey,
        idName,
        colorKey,
        colorName,
        labelKey,
        labelName
      }
    );
    if (labelText == null)
      return;
    const baseSize = isArray(labelText) ? measureTextSegments(labelText, label) : measurer3.measureLines(String(labelText));
    const aspectRatio = (baseSize.width + 2 * padding2) / (baseSize.height + 2 * padding2);
    if (previousLabelLayout?.geometry === geometry && previousLabelLayout?.labelText === labelText && previousLabelLayout?.aspectRatio === aspectRatio) {
      return previousLabelLayout;
    }
    const fixedGeometry = projectGeometry(geometry, fixedScale);
    const fixedPolygon = largestPolygon(fixedGeometry);
    if (fixedPolygon == null)
      return;
    const labelPlacement = preferredLabelCenter(fixedPolygon, {
      aspectRatio,
      precision: 1e-3
    });
    if (labelPlacement == null)
      return;
    const { x, y, maxWidth } = labelPlacement;
    return { geometry, labelText, aspectRatio, x, y, maxWidth, fixedPolygon };
  }
  getLabelDatum(labelLayout, scaling, datumIndex, idValue) {
    const { scale: scale2 } = this;
    if (scale2 == null)
      return;
    const { padding: padding2, label } = this.properties;
    const { labelText, aspectRatio, x: untruncatedX, y, maxWidth, fixedPolygon } = labelLayout;
    const maxSizeWithoutTruncation = {
      width: Math.ceil(maxWidth * scaling),
      height: Math.ceil(maxWidth * scaling / aspectRatio),
      meta: untruncatedX
    };
    const labelFormatting = formatSingleLabel(
      toPlainText(labelText),
      label,
      { padding: padding2 },
      (height2, allowTruncation) => {
        if (!allowTruncation) {
          return maxSizeWithoutTruncation;
        }
        const result = maxWidthInPolygonForRectOfHeight(fixedPolygon, untruncatedX, y, height2 / scaling);
        return {
          width: result.width * scaling,
          height: height2,
          meta: result.x
        };
      }
    );
    if (labelFormatting == null)
      return;
    const [{ text: text2, fontSize, lineHeight, width: width2 }, formattingX] = labelFormatting;
    const x = width2 < maxSizeWithoutTruncation.width ? untruncatedX : formattingX;
    const position = this.scale.convert(fixedScale.invert([x, y]));
    return {
      x: position[0],
      y: position[1],
      text: text2,
      fontSize,
      lineHeight,
      datumIndex,
      idValue,
      datumId: createDatumId24(idValue)
    };
  }
  resolveColumn(key, columnId, processedData) {
    if (key == null || this.dataModel == null)
      return void 0;
    return this.dataModel.resolveColumnById(this, columnId, processedData);
  }
  resolveShapeDataColumns(processedData) {
    const { colorKey, labelKey } = this.properties;
    return {
      idValues: this.dataModel.resolveColumnById(this, "idValue", processedData),
      featureValues: this.dataModel.resolveColumnById(this, "featureValue", processedData),
      labelValues: this.resolveColumn(labelKey, "labelValue", processedData),
      colorValues: this.resolveColumn(colorKey, "colorValue", processedData)
    };
  }
  warnMissingGeometries(missingGeometries) {
    if (missingGeometries.length === 0)
      return;
    const missingGeometriesCap = 10;
    if (missingGeometries.length > missingGeometriesCap) {
      const excessItems = missingGeometries.length - missingGeometriesCap;
      missingGeometries.length = missingGeometriesCap;
      missingGeometries.push(`(+${excessItems} more)`);
    }
    logger_exports.warnOnce(`some data items do not have matches in the provided topology`, missingGeometries);
  }
  createNodeData() {
    const { id: seriesId, dataModel, processedData, properties, scale: scale2, previousLabelLayouts } = this;
    const { label, legendItemName, colorKey } = properties;
    if (dataModel == null || processedData == null)
      return;
    if (!this.visible) {
      return { itemId: seriesId, nodeData: [], labelData: [] };
    }
    const scaling = scale2 == null ? Number.NaN : (scale2.range[1][0] - scale2.range[0][0]) / scale2.bounds.width;
    const columns = this.resolveShapeDataColumns(processedData);
    const measurer3 = cachedTextMeasurer(label);
    const labelLayouts = /* @__PURE__ */ new Map();
    this.previousLabelLayouts = labelLayouts;
    const nodeData = [];
    const labelData = [];
    const missingGeometries = [];
    const rawData = processedData.dataSources.get(this.id)?.data ?? [];
    for (const [datumIndex, datum] of rawData.entries()) {
      const dataValues = {
        idValue: columns.idValues[datumIndex],
        colorValue: columns.colorValues?.[datumIndex],
        labelValue: columns.labelValues?.[datumIndex]
      };
      const geometry = columns.featureValues[datumIndex]?.geometry ?? void 0;
      if (geometry == null) {
        missingGeometries.push(dataValues.idValue);
      }
      if (colorKey != null && dataValues.colorValue == null) {
        continue;
      }
      const labelLayout = this.getLabelLayout(
        datum,
        dataValues.labelValue,
        measurer3,
        geometry,
        previousLabelLayouts?.get(dataValues.idValue)
      );
      if (labelLayout != null) {
        labelLayouts.set(dataValues.idValue, labelLayout);
      }
      const labelDatum = labelLayout != null && scale2 != null ? this.getLabelDatum(labelLayout, scaling, datumIndex, dataValues.idValue) : void 0;
      if (labelDatum != null) {
        labelData.push(labelDatum);
      }
      const projectedGeometry = geometry != null && scale2 != null ? projectGeometry(geometry, scale2) : void 0;
      nodeData.push({
        series: this,
        datum,
        datumIndex,
        ...dataValues,
        projectedGeometry,
        legendItemName,
        style: this.getItemStyle({ datum, datumIndex, colorValue: dataValues.colorValue }, false)
      });
    }
    this.warnMissingGeometries(missingGeometries);
    return {
      itemId: seriesId,
      nodeData,
      labelData
    };
  }
  updateSelections() {
    if (this.nodeDataRefresh) {
      this.contextNodeData = this.createNodeData();
      this.nodeDataRefresh = false;
    }
  }
  update() {
    const { datumSelection, labelSelection, highlightDatumSelection } = this;
    this.updateSelections();
    this.contentGroup.visible = this.visible;
    this.labelGroup.visible = this.visible;
    const drawingMode = this.ctx.chartService.highlight?.drawingMode ?? "overlay";
    const highlightedDatum = this.getHighlightedDatum();
    const nodeData = this.contextNodeData?.nodeData ?? [];
    const labelData = this.contextNodeData?.labelData ?? [];
    this.datumSelection = this.updateDatumSelection({ nodeData, datumSelection });
    this.updateDatumStyles({ datumSelection, isHighlight: false });
    this.updateDatumNodes({ datumSelection, drawingMode: "overlay" });
    this.labelSelection = this.updateLabelSelection({ labelData, labelSelection });
    const highlightLabelData = this.getHighlightLabelData(labelData, highlightedDatum);
    this.highlightLabelSelection = this.updateLabelSelection({
      labelData: highlightLabelData,
      labelSelection: this.highlightLabelSelection
    });
    this.updateLabelNodes({ labelSelection: this.labelSelection, isHighlight: false });
    this.updateLabelNodes({ labelSelection: this.highlightLabelSelection, isHighlight: true });
    this.highlightDatumSelection = this.updateDatumSelection({
      nodeData: highlightedDatum == null ? [] : [highlightedDatum],
      datumSelection: highlightDatumSelection
    });
    this.updateDatumStyles({ datumSelection: highlightDatumSelection, isHighlight: true });
    this.updateDatumNodes({ datumSelection: highlightDatumSelection, drawingMode });
  }
  getHighlightLabelData(labelData, highlightedDatum) {
    if (labelData.length === 0)
      return [];
    const highlightId = createDatumId24(highlightedDatum?.idValue);
    return labelData.filter(
      (labelDatum) => labelDatum.datumId === highlightId && labelDatum.datumIndex === highlightedDatum?.datumIndex
    );
  }
  updateDatumSelection(opts) {
    return opts.datumSelection.update(opts.nodeData, void 0, (datum) => createDatumId24(datum.idValue));
  }
  getItemStyle({ datumIndex, datum, colorValue }, isHighlight) {
    const { properties, colorScale } = this;
    const { colorRange, itemStyler } = properties;
    const baseStyle = properties.getStyle();
    if (colorValue != null) {
      const fillOverride = this.isColorScaleValid() ? colorScale.convert(colorValue) : colorRange?.[0];
      if (fillOverride != null) {
        baseStyle.fill = fillOverride;
      }
    }
    const highlightStyle = this.getHighlightStyle(isHighlight, datumIndex);
    let style2 = mergeDefaults(highlightStyle, baseStyle);
    if (itemStyler != null && datumIndex != null) {
      const overrides = this.cachedDatumCallback(
        createDatumId24(datumIndex, isHighlight ? "highlight" : "node"),
        () => {
          const params = this.makeItemStylerParams(datum, datumIndex, isHighlight, style2);
          return this.ctx.optionsGraphService.resolvePartial(
            ["series", `${this.declarationOrder}`],
            this.callWithContext(itemStyler, params)
          );
        }
      );
      if (overrides) {
        style2 = mergeDefaults(overrides, style2);
      }
    }
    return style2;
  }
  makeItemStylerParams(datum, datumIndex, isHighlight, style2) {
    const { id: seriesId } = this;
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    const highlightState = this.getHighlightStateString(activeHighlight, isHighlight, datumIndex);
    const fill = this.filterItemStylerFillParams(style2.fill) ?? style2.fill;
    return {
      seriesId,
      datum,
      highlightState,
      ...style2,
      fill
    };
  }
  updateDatumStyles({
    datumSelection,
    isHighlight
  }) {
    datumSelection.each((_, nodeDatum) => {
      nodeDatum.style = this.getItemStyle(nodeDatum, isHighlight);
    });
  }
  updateDatumNodes({
    datumSelection,
    drawingMode
  }) {
    const fillBBox = getTopologyShapeFillBBox(this.scale);
    datumSelection.each((geoGeometry, nodeDatum) => {
      const { projectedGeometry } = nodeDatum;
      if (projectedGeometry == null) {
        geoGeometry.visible = false;
        geoGeometry.projectedGeometry = void 0;
        return;
      }
      geoGeometry.visible = true;
      geoGeometry.projectedGeometry = projectedGeometry;
      geoGeometry.setStyleProperties(nodeDatum.style, fillBBox);
      geoGeometry.drawingMode = drawingMode;
    });
  }
  updateLabelSelection(opts) {
    const labels = this.isLabelEnabled() ? opts.labelData : [];
    return opts.labelSelection.update(labels);
  }
  updateLabelNodes({
    isHighlight,
    labelSelection
  }) {
    const { properties } = this;
    const activeHighlight = this.ctx.highlightManager?.getActiveHighlight();
    labelSelection.each((label, labelDatum) => {
      const { x, y, text: text2, fontSize, lineHeight, datumIndex } = labelDatum;
      const style2 = getLabelStyles9(
        this,
        void 0,
        properties,
        properties.label,
        isHighlight,
        activeHighlight
      );
      const { color: fill, fontStyle, fontWeight: fontWeight2, fontFamily } = style2;
      label.visible = true;
      label.x = x;
      label.y = y;
      label.text = text2;
      label.fill = fill;
      label.fontStyle = fontStyle;
      label.fontWeight = fontWeight2;
      label.fontSize = fontSize;
      label.lineHeight = lineHeight;
      label.fontFamily = fontFamily;
      label.textAlign = "center";
      label.textBaseline = "middle";
      label.fillOpacity = this.getHighlightStyle(isHighlight, datumIndex).opacity ?? 1;
      label.setBoxing(style2);
    });
  }
  resetAnimation() {
  }
  pickNodeClosestDatum({ x, y }) {
    let minDistanceSquared = Infinity;
    let minDatum;
    this.datumSelection.each((node, datum) => {
      const distanceSquared2 = node.distanceSquared(x, y);
      if (distanceSquared2 < minDistanceSquared) {
        minDistanceSquared = distanceSquared2;
        minDatum = datum;
      }
    });
    return minDatum == null ? void 0 : { datum: minDatum, distance: Math.sqrt(minDistanceSquared) };
  }
  datumMidPoint(datum) {
    const { _previousDatumMidPoint } = this;
    if (_previousDatumMidPoint?.datum === datum) {
      return _previousDatumMidPoint.point;
    }
    const projectedGeometry = datum.projectedGeometry;
    const polygon = projectedGeometry == null ? void 0 : largestPolygon(projectedGeometry);
    const center2 = polygon == null ? void 0 : polygonMarkerCenter(polygon, 2);
    const point = center2 == null ? void 0 : { x: center2[0], y: center2[1] };
    this._previousDatumMidPoint = { datum, point };
    return point;
  }
  legendItemSymbol(datumIndex) {
    const { dataModel, processedData, properties } = this;
    const { fillOpacity, stroke: stroke3, strokeWidth, strokeOpacity, lineDash, lineDashOffset } = properties;
    let { fill } = properties;
    if (datumIndex != null && this.isColorScaleValid()) {
      const colorValues = dataModel.resolveColumnById(this, "colorValue", processedData);
      const colorValue = colorValues[datumIndex];
      if (colorValue != null) {
        fill = this.colorScale.convert(colorValue);
      }
    }
    return {
      marker: {
        fill,
        fillOpacity,
        stroke: stroke3,
        strokeWidth,
        strokeOpacity,
        lineDash,
        lineDashOffset
      }
    };
  }
  getLegendData(legendType) {
    const { processedData, dataModel } = this;
    if (processedData == null || dataModel == null)
      return [];
    const { id: seriesId, visible } = this;
    const { title, legendItemName, idKey, idName, colorKey, colorRange, showInLegend } = this.properties;
    if (legendType === "gradient" && colorKey != null && colorRange != null) {
      const colorDomain = processedData.domain.values[dataModel.resolveProcessedDataIndexById(this, "colorValue")];
      const legendDatum = {
        legendType: "gradient",
        enabled: visible,
        seriesId,
        series: this.getFormatterContext("color"),
        colorRange,
        colorDomain
      };
      return [legendDatum];
    } else if (legendType === "category") {
      const legendDatum = {
        legendType: "category",
        id: seriesId,
        itemId: seriesId,
        seriesId,
        enabled: visible,
        label: { text: legendItemName ?? title ?? idName ?? idKey },
        symbol: this.legendItemSymbol(),
        legendItemName,
        hideInLegend: !showInLegend
      };
      return [legendDatum];
    } else {
      return [];
    }
  }
  getTooltipContent(datumIndex) {
    const {
      id: seriesId,
      dataModel,
      processedData,
      properties,
      ctx: { formatManager }
    } = this;
    const { idKey, idName, colorKey, colorName, labelKey, labelName, legendItemName, title, tooltip } = properties;
    if (!dataModel || !processedData)
      return;
    const datum = processedData.dataSources.get(this.id)?.data[datumIndex];
    const idValue = dataModel.resolveColumnById(this, `idValue`, processedData)[datumIndex];
    const colorValue = colorKey == null ? void 0 : dataModel.resolveColumnById(this, `colorValue`, processedData)[datumIndex];
    if (colorKey != null && colorValue == null) {
      return;
    }
    const data = [];
    if (this.isLabelEnabled() && labelKey != null && labelKey !== idKey) {
      const labelValue = dataModel.resolveColumnById(this, `labelValue`, processedData)[datumIndex];
      const content = formatManager.format(this.callWithContext.bind(this), {
        type: "category",
        value: labelValue,
        datum,
        seriesId,
        legendItemName,
        key: labelKey,
        source: "tooltip",
        property: "label",
        domain: [],
        boundSeries: this.getFormatterContext("label")
      });
      data.push({ label: labelName, fallbackLabel: labelKey, value: content ?? labelValue });
    }
    if (colorValue != null) {
      const domain = dataModel.getDomain(this, `colorValue`, "value", processedData).domain;
      const content = formatManager.format(this.callWithContext.bind(this), {
        type: "number",
        value: colorValue,
        datum,
        seriesId,
        legendItemName,
        key: colorKey,
        source: "tooltip",
        property: "color",
        domain,
        boundSeries: this.getFormatterContext("color"),
        fractionDigits: void 0,
        visibleDomain: void 0
      });
      data.push({ label: colorName, fallbackLabel: colorKey, value: content ?? String(colorValue) });
    }
    const format = this.getItemStyle({ datum, datumIndex, colorValue }, false);
    return this.formatTooltipWithContext(
      tooltip,
      {
        heading: idValue,
        title: title ?? legendItemName,
        symbol: this.legendItemSymbol(datumIndex),
        data
      },
      { seriesId, datum, title, idKey, idName, colorKey, colorName, labelKey, labelName, ...format }
    );
  }
  computeFocusBounds(opts) {
    return findFocusedGeoGeometry(this, opts);
  }
  hasItemStylers() {
    return this.properties.itemStyler != null || this.properties.label.itemStyler != null;
  }
};
MapShapeSeries.className = "MapShapeSeries";
MapShapeSeries.type = "map-shape";

// packages/ag-charts-enterprise/src/series/map-shape/mapShapeSeriesOptionsDef.ts
var { mapShapeSeriesThemeableOptionsDef: mapShapeSeriesThemeableOptionsDef2 } = module_support_exports;
var mapShapeSeriesOptionsDef = {
  ...without(commonSeriesOptionsDefs, ["highlightStyle", "highlight"]),
  ...mapShapeSeriesThemeableOptionsDef2,
  type: required(constant("map-shape")),
  idKey: required(string),
  colorKey: string,
  labelKey: string,
  idName: string,
  colorName: string,
  labelName: string,
  topology: geoJson,
  topologyIdKey: string,
  legendItemName: string,
  title: string
};

// packages/ag-charts-enterprise/src/series/map-shape/mapShapeModule.ts
var MapShapeSeriesModule = {
  type: "series",
  name: "map-shape",
  chartType: "topology",
  enterprise: true,
  version: VERSION,
  dependencies: [TopologyChartModule],
  options: mapShapeSeriesOptionsDef,
  themeTemplate: {
    ...MAP_THEME_DEFAULTS,
    series: {
      fill: applyMapPalette({
        $applySwitch: [
          { $path: "type" },
          { $mapPalette: "fill" },
          ["gradient", FILL_GRADIENT_LINEAR_DEFAULTS],
          ["image", FILL_IMAGE_DEFAULTS],
          ["pattern", FILL_PATTERN_DEFAULTS]
        ]
      }),
      stroke: { $ref: "chartBackgroundColor" },
      colorRange: {
        $if: [
          { $eq: [{ $mapPalette: "type" }, "inbuilt"] },
          { $mapPalette: "divergingColors" },
          applyMapPalette(SAFE_RANGE2_OPERATION)
        ]
      },
      fillOpacity: 1,
      strokeWidth: 1,
      lineDash: [0],
      lineDashOffset: 0,
      padding: 2,
      label: {
        ...LABEL_BOXING_DEFAULTS,
        enabled: true,
        color: { $ref: "chartBackgroundColor" },
        fontFamily: { $ref: "fontFamily" },
        fontSize: { $ref: "fontSize" },
        fontWeight: "bold",
        overflowStrategy: "hide"
      },
      highlight: applyMapPalette(MULTI_SERIES_HIGHLIGHT_STYLE)
    },
    tooltip: {
      range: "exact"
    }
  },
  create: (ctx) => new MapShapeSeries(ctx)
};

// packages/ag-charts-enterprise/src/module-bundles/topology.ts
var AllMapSeriesModule = [
  MapLineSeriesModule,
  MapLineBackgroundSeriesModule,
  MapMarkerSeriesModule,
  MapShapeSeriesModule,
  MapShapeBackgroundSeriesModule
];

// packages/ag-charts-enterprise/src/module-bundles/all.ts
var AllEnterpriseModule = [
  AllCommunityModule,
  AllCartesianModule2,
  AllPolarModule2,
  AllMapSeriesModule,
  AllGaugeModule,
  FinancialChartModule,
  ChordSeriesModule,
  PyramidSeriesModule,
  SankeySeriesModule,
  SunburstSeriesModule,
  TreemapSeriesModule
].flat();

// packages/ag-charts-enterprise/src/features/image/image.ts
var Image3 = class extends BaseProperties {
  constructor() {
    super();
    this.opacity = 1;
    this.loadedSynchronously = true;
    this.containerWidth = 0;
    this.containerHeight = 0;
    this.onLoad = void 0;
    this.onImageLoad = () => {
      if (this.loadedSynchronously) {
        return;
      }
      this.node.visible = false;
      this.performLayout(this.containerWidth, this.containerHeight);
      this.onLoad?.();
    };
    this.imageElement = createElement("img");
    this.imageElement.onload = this.onImageLoad;
    this.node = new module_support_exports.Image(this.imageElement);
  }
  get complete() {
    return this.imageElement.width > 0 && this.imageElement.height > 0;
  }
  performLayout(containerWidth, containerHeight) {
    this.containerWidth = containerWidth;
    this.containerHeight = containerHeight;
    const container = { width: containerWidth, height: containerHeight };
    const placement = calculatePlacement(this.imageElement.width, this.imageElement.height, container, this);
    this.node.setProperties(
      this.complete ? {
        visible: true,
        opacity: this.opacity,
        ...placement
      } : { visible: false }
    );
    return placement;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty
], Image3.prototype, "top", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Image3.prototype, "right", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Image3.prototype, "bottom", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Image3.prototype, "left", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Image3.prototype, "width", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Image3.prototype, "height", 2);
__decorateClass([
  addFakeTransformToInstanceProperty
], Image3.prototype, "opacity", 2);
__decorateClass([
  ProxyProperty("imageElement.src"),
  ObserveChanges((target) => target.loadedSynchronously = target.complete)
], Image3.prototype, "url", 2);

// packages/ag-charts-enterprise/src/features/background/background.ts
var Background3 = class extends module_support_exports.Background {
  constructor() {
    super(...arguments);
    this.image = new Image3();
  }
  onLayoutComplete(event) {
    super.onLayoutComplete(event);
    if (this.image) {
      const { width: width2, height: height2 } = event.chart;
      this.image.performLayout(width2, height2);
    }
  }
  onImageLoad() {
    this.ctx.updateService.update(9 /* SCENE_RENDER */);
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty,
  ActionOnSet({
    newValue(image) {
      this.node.appendChild(image.node);
      image.onLoad = () => this.onImageLoad();
    },
    oldValue(image) {
      image.node.remove();
      image.onLoad = void 0;
    }
  })
], Background3.prototype, "image", 2);

// packages/ag-charts-enterprise/src/features/foreground/foreground.ts
var Foreground = class extends module_support_exports.Background {
  constructor() {
    super(...arguments);
    this.image = new Image3();
    this.fill = "transparent";
    this.fillOpacity = void 0;
  }
  createNode() {
    return new module_support_exports.Group({ name: "foreground", zIndex: 18 /* FOREGROUND */ });
  }
  onLayoutComplete(event) {
    super.onLayoutComplete(event);
    const { width: width2, height: height2 } = event.chart;
    const placement = this.image.performLayout(width2, height2);
    if (this.text) {
      this.updateTextNode(placement);
    }
  }
  onImageLoad() {
    this.ctx.updateService.update(9 /* SCENE_RENDER */);
  }
  updateTextNode(placement) {
    const { textNode } = this;
    textNode.fontWeight = "bold";
    textNode.fontFamily = "Impact, sans-serif";
    textNode.fontSize = 19;
    textNode.opacity = 0.7;
    textNode.fill = "#9b9b9b";
    textNode.textBaseline = "top";
    const { width: width2 } = textNode.getBBox();
    const textPadding = 10;
    textNode.x = placement.x + placement.width / 2 - width2 / 2;
    textNode.y = placement.y + placement.height + textPadding;
  }
};
__decorateClass([
  addFakeTransformToInstanceProperty,
  ActionOnSet({
    newValue(image) {
      this.node.appendChild(image.node);
      image.onLoad = () => this.onImageLoad();
    },
    oldValue(image) {
      image.node.remove();
      image.onLoad = void 0;
    }
  })
], Foreground.prototype, "image", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ProxyPropertyOnWrite("rectNode", "fill")
], Foreground.prototype, "fill", 2);
__decorateClass([
  addFakeTransformToInstanceProperty,
  ProxyPropertyOnWrite("rectNode", "fillOpacity")
], Foreground.prototype, "fillOpacity", 2);

// packages/ag-charts-enterprise/src/license/md5.ts
var MD5 = class {
  constructor() {
    this.ieCompatibility = false;
  }
  init() {
    this.ieCompatibility = this.md5("hello") != "5d41402abc4b2a76b9719d911017c592";
  }
  md5cycle(x, k) {
    let a = x[0], b = x[1], c = x[2], d = x[3];
    a = this.ff(a, b, c, d, k[0], 7, -680876936);
    d = this.ff(d, a, b, c, k[1], 12, -389564586);
    c = this.ff(c, d, a, b, k[2], 17, 606105819);
    b = this.ff(b, c, d, a, k[3], 22, -1044525330);
    a = this.ff(a, b, c, d, k[4], 7, -176418897);
    d = this.ff(d, a, b, c, k[5], 12, 1200080426);
    c = this.ff(c, d, a, b, k[6], 17, -1473231341);
    b = this.ff(b, c, d, a, k[7], 22, -45705983);
    a = this.ff(a, b, c, d, k[8], 7, 1770035416);
    d = this.ff(d, a, b, c, k[9], 12, -1958414417);
    c = this.ff(c, d, a, b, k[10], 17, -42063);
    b = this.ff(b, c, d, a, k[11], 22, -1990404162);
    a = this.ff(a, b, c, d, k[12], 7, 1804603682);
    d = this.ff(d, a, b, c, k[13], 12, -40341101);
    c = this.ff(c, d, a, b, k[14], 17, -1502002290);
    b = this.ff(b, c, d, a, k[15], 22, 1236535329);
    a = this.gg(a, b, c, d, k[1], 5, -165796510);
    d = this.gg(d, a, b, c, k[6], 9, -1069501632);
    c = this.gg(c, d, a, b, k[11], 14, 643717713);
    b = this.gg(b, c, d, a, k[0], 20, -373897302);
    a = this.gg(a, b, c, d, k[5], 5, -701558691);
    d = this.gg(d, a, b, c, k[10], 9, 38016083);
    c = this.gg(c, d, a, b, k[15], 14, -660478335);
    b = this.gg(b, c, d, a, k[4], 20, -405537848);
    a = this.gg(a, b, c, d, k[9], 5, 568446438);
    d = this.gg(d, a, b, c, k[14], 9, -1019803690);
    c = this.gg(c, d, a, b, k[3], 14, -187363961);
    b = this.gg(b, c, d, a, k[8], 20, 1163531501);
    a = this.gg(a, b, c, d, k[13], 5, -1444681467);
    d = this.gg(d, a, b, c, k[2], 9, -51403784);
    c = this.gg(c, d, a, b, k[7], 14, 1735328473);
    b = this.gg(b, c, d, a, k[12], 20, -1926607734);
    a = this.hh(a, b, c, d, k[5], 4, -378558);
    d = this.hh(d, a, b, c, k[8], 11, -2022574463);
    c = this.hh(c, d, a, b, k[11], 16, 1839030562);
    b = this.hh(b, c, d, a, k[14], 23, -35309556);
    a = this.hh(a, b, c, d, k[1], 4, -1530992060);
    d = this.hh(d, a, b, c, k[4], 11, 1272893353);
    c = this.hh(c, d, a, b, k[7], 16, -155497632);
    b = this.hh(b, c, d, a, k[10], 23, -1094730640);
    a = this.hh(a, b, c, d, k[13], 4, 681279174);
    d = this.hh(d, a, b, c, k[0], 11, -358537222);
    c = this.hh(c, d, a, b, k[3], 16, -722521979);
    b = this.hh(b, c, d, a, k[6], 23, 76029189);
    a = this.hh(a, b, c, d, k[9], 4, -640364487);
    d = this.hh(d, a, b, c, k[12], 11, -421815835);
    c = this.hh(c, d, a, b, k[15], 16, 530742520);
    b = this.hh(b, c, d, a, k[2], 23, -995338651);
    a = this.ii(a, b, c, d, k[0], 6, -198630844);
    d = this.ii(d, a, b, c, k[7], 10, 1126891415);
    c = this.ii(c, d, a, b, k[14], 15, -1416354905);
    b = this.ii(b, c, d, a, k[5], 21, -57434055);
    a = this.ii(a, b, c, d, k[12], 6, 1700485571);
    d = this.ii(d, a, b, c, k[3], 10, -1894986606);
    c = this.ii(c, d, a, b, k[10], 15, -1051523);
    b = this.ii(b, c, d, a, k[1], 21, -2054922799);
    a = this.ii(a, b, c, d, k[8], 6, 1873313359);
    d = this.ii(d, a, b, c, k[15], 10, -30611744);
    c = this.ii(c, d, a, b, k[6], 15, -1560198380);
    b = this.ii(b, c, d, a, k[13], 21, 1309151649);
    a = this.ii(a, b, c, d, k[4], 6, -145523070);
    d = this.ii(d, a, b, c, k[11], 10, -1120210379);
    c = this.ii(c, d, a, b, k[2], 15, 718787259);
    b = this.ii(b, c, d, a, k[9], 21, -343485551);
    x[0] = this.add32(a, x[0]);
    x[1] = this.add32(b, x[1]);
    x[2] = this.add32(c, x[2]);
    x[3] = this.add32(d, x[3]);
  }
  cmn(q, a, b, x, s, t) {
    a = this.add32(this.add32(a, q), this.add32(x, t));
    return this.add32(a << s | a >>> 32 - s, b);
  }
  ff(a, b, c, d, x, s, t) {
    return this.cmn(b & c | ~b & d, a, b, x, s, t);
  }
  gg(a, b, c, d, x, s, t) {
    return this.cmn(b & d | c & ~d, a, b, x, s, t);
  }
  hh(a, b, c, d, x, s, t) {
    return this.cmn(b ^ c ^ d, a, b, x, s, t);
  }
  ii(a, b, c, d, x, s, t) {
    return this.cmn(c ^ (b | ~d), a, b, x, s, t);
  }
  md51(s) {
    const n = s.length;
    const state = [1732584193, -271733879, -1732584194, 271733878];
    let i;
    for (i = 64; i <= s.length; i += 64) {
      this.md5cycle(state, this.md5blk(s.substring(i - 64, i)));
    }
    s = s.substring(i - 64);
    const tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
    for (i = 0; i < s.length; i++) {
      tail[i >> 2] |= s.charCodeAt(i) << (i % 4 << 3);
    }
    tail[i >> 2] |= 128 << (i % 4 << 3);
    if (i > 55) {
      this.md5cycle(state, tail);
      for (i = 0; i < 16; i++) {
        tail[i] = 0;
      }
    }
    tail[14] = n * 8;
    this.md5cycle(state, tail);
    return state;
  }
  /* there needs to be support for Unicode here, * unless we pretend that we can redefine the MD-5
   * algorithm for multi-byte characters (perhaps by adding every four 16-bit characters and
   * shortening the sum to 32 bits). Otherwise I suggest performing MD-5 as if every character
   * was two bytes--e.g., 0040 0025 = @%--but then how will an ordinary MD-5 sum be matched?
   * There is no way to standardize text to something like UTF-8 before transformation; speed cost is
   * utterly prohibitive. The JavaScript standard itself needs to look at this: it should start
   * providing access to strings as preformed UTF-8 8-bit unsigned value arrays.
   */
  md5blk(s) {
    const md5blks = [];
    for (let i = 0; i < 64; i += 4) {
      md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24);
    }
    return md5blks;
  }
  rhex(n) {
    const hex_chr = "0123456789abcdef".split("");
    let s = "", j = 0;
    for (; j < 4; j++) {
      s += hex_chr[n >> j * 8 + 4 & 15] + hex_chr[n >> j * 8 & 15];
    }
    return s;
  }
  hex(x) {
    for (let i = 0; i < x.length; i++) {
      x[i] = this.rhex(x[i]);
    }
    return x.join("");
  }
  md5(s) {
    return this.hex(this.md51(s));
  }
  add32(a, b) {
    return this.ieCompatibility ? this.add32Compat(a, b) : this.add32Std(a, b);
  }
  /* this function is much faster, so if possible we use it. Some IEs are the only ones I know of that
   need the idiotic second function, generated by an if clause.  */
  add32Std(a, b) {
    return a + b & 4294967295;
  }
  add32Compat(x, y) {
    const lsw = (x & 65535) + (y & 65535), msw = (x >> 16) + (y >> 16) + (lsw >> 16);
    return msw << 16 | lsw & 65535;
  }
};

// packages/ag-charts-enterprise/src/license/licenseManager.ts
function missingOrEmpty(value) {
  return value == null || value.length === 0;
}
var WATERMARK_SVG_DATA_URL = `data:image/svg+xml;base64,[encoded data, 8028 characters]`;
var LICENSE_TYPES = {
  "01": "GRID",
  "02": "CHARTS",
  "0102": "BOTH"
};
var LICENSING_HELP_URL = "https://www.ag-grid.com/charts/licensing/";
var _LicenseManager = class _LicenseManager {
  constructor(document2) {
    this.watermarkMessage = void 0;
    this.totalMessageLength = 124;
    this.document = document2;
    this.md5 = new MD5();
    this.md5.init();
  }
  validateLicense() {
    const licenseDetails = this.getLicenseDetails(_LicenseManager.licenseKey, _LicenseManager.gridContext);
    const currentLicenseName = `AG ${licenseDetails.currentLicenseType === "BOTH" ? "Grid and " : ""}Charts Enterprise`;
    let suppliedLicenseName = "";
    if (licenseDetails.suppliedLicenseType === "BOTH") {
      suppliedLicenseName = "AG Grid and AG Charts Enterprise";
    } else if (licenseDetails.suppliedLicenseType === "GRID") {
      suppliedLicenseName = "AG Grid Enterprise";
    } else if (licenseDetails.suppliedLicenseType !== void 0) {
      suppliedLicenseName = "AG Charts Enterprise";
    }
    if (licenseDetails.missing) {
      if (!this.isWebsiteUrl() || this.isForceWatermark()) {
        this.outputMissingLicenseKey(currentLicenseName);
      }
    } else if (licenseDetails.expired) {
      const gridReleaseDate = _LicenseManager.getChartsReleaseDate();
      const formattedReleaseDate = _LicenseManager.formatDate(gridReleaseDate);
      this.outputExpiredKey(licenseDetails.expiry, formattedReleaseDate, suppliedLicenseName);
    } else if (!licenseDetails.valid) {
      this.outputInvalidLicenseKey(
        !!licenseDetails.incorrectLicenseType,
        currentLicenseName,
        suppliedLicenseName
      );
    } else if (licenseDetails.isTrial && licenseDetails.trialExpired) {
      this.outputExpiredTrialKey(licenseDetails.expiry, currentLicenseName, suppliedLicenseName);
    }
  }
  static extractExpiry(license) {
    const restrictionHashed = license.substring(license.lastIndexOf("_") + 1, license.length);
    return new Date(Number.parseInt(_LicenseManager.decode(restrictionHashed), 10));
  }
  static extractLicenseComponents(licenseKey) {
    let cleanedLicenseKey = licenseKey.replaceAll(/[\u200B-\u200D\uFEFF]/g, "");
    cleanedLicenseKey = cleanedLicenseKey.replaceAll(/\r?\n|\r/g, "");
    if (licenseKey.length <= 32) {
      return { md5: null, license: licenseKey, version: null, isTrial: null };
    }
    const hashStart = cleanedLicenseKey.length - 32;
    const md5 = cleanedLicenseKey.substring(hashStart);
    const license = cleanedLicenseKey.substring(0, hashStart);
    const [version, isTrial, type] = _LicenseManager.extractBracketedInformation(cleanedLicenseKey);
    return { md5, license, version, isTrial, type };
  }
  getLicenseDetails(licenseKey, gridContext = false) {
    const currentLicenseType = "CHARTS";
    if (missingOrEmpty(licenseKey)) {
      return {
        licenseKey,
        valid: false,
        missing: true,
        currentLicenseType
      };
    }
    const chartsReleaseDate = _LicenseManager.getChartsReleaseDate();
    const { md5, license, version, isTrial, type } = _LicenseManager.extractLicenseComponents(licenseKey);
    let valid = md5 === this.md5.md5(license) && !licenseKey.includes("For_Trialing_ag-Grid_Only");
    let trialExpired = void 0;
    let expired = void 0;
    let expiry = null;
    let incorrectLicenseType = false;
    let suppliedLicenseType = void 0;
    function handleTrial() {
      const now = /* @__PURE__ */ new Date();
      trialExpired = expiry < now;
      expired = void 0;
    }
    if (valid) {
      expiry = _LicenseManager.extractExpiry(license);
      valid = !Number.isNaN(expiry.getTime());
      if (valid) {
        expired = chartsReleaseDate > expiry;
        switch (version) {
          case "legacy":
          case "2": {
            valid = false;
            break;
          }
          case "3": {
            if (missingOrEmpty(type)) {
              valid = false;
            } else {
              suppliedLicenseType = type;
              if (type !== LICENSE_TYPES["02"] && type !== LICENSE_TYPES["0102"]) {
                valid = false;
                incorrectLicenseType = true;
              } else if (isTrial) {
                handleTrial();
              }
            }
          }
        }
      }
    }
    if (!valid) {
      return {
        licenseKey,
        valid,
        incorrectLicenseType,
        currentLicenseType,
        suppliedLicenseType
      };
    }
    return {
      licenseKey,
      valid,
      expiry: _LicenseManager.formatDate(expiry),
      expired,
      version,
      isTrial,
      trialExpired,
      invalidLicenseTypeForCombo: gridContext ? suppliedLicenseType !== "BOTH" : void 0,
      incorrectLicenseType,
      currentLicenseType,
      suppliedLicenseType
    };
  }
  isDisplayWatermark() {
    return this.isForceWatermark() || !this.isLocalhost() && !this.isE2ETest() && !this.isWebsiteUrl() && !missingOrEmpty(this.watermarkMessage);
  }
  getWatermarkMessage() {
    return this.watermarkMessage ?? "";
  }
  getWatermarkForegroundConfig() {
    const message = this.getWatermarkMessage();
    if (!message) {
      return void 0;
    }
    return this.buildWatermarkConfig(message);
  }
  getWatermarkForegroundConfigForBrowser() {
    if (!this.isDisplayWatermark()) {
      return void 0;
    }
    const message = this.getWatermarkMessage();
    if (!message) {
      return void 0;
    }
    return this.buildWatermarkConfig(message);
  }
  buildWatermarkConfig(text2) {
    return {
      text: text2,
      image: {
        url: WATERMARK_SVG_DATA_URL,
        width: 170,
        height: 25,
        right: 25,
        bottom: 50,
        opacity: 0.7
      }
    };
  }
  getHostname() {
    if (!this.document) {
      return "localhost";
    }
    const win = this.document.defaultView ?? globalThis;
    if (!win) {
      return "localhost";
    }
    try {
      const hostname = win.location?.hostname ?? "";
      return hostname || "localhost";
    } catch {
      return "localhost";
    }
  }
  isForceWatermark() {
    if (!this.document) {
      return false;
    }
    const win = this.document?.defaultView ?? globalThis.window != void 0 ? globalThis : void 0;
    if (!win) {
      return false;
    }
    const pathname = win.location?.pathname;
    return pathname ? pathname.includes("forceWatermark") : false;
  }
  isWebsiteUrl() {
    const hostname = this.getHostname();
    return /^((?:[\w-]+\.)?ag-grid\.com)$/.exec(hostname) !== null;
  }
  isLocalhost() {
    const hostname = this.getHostname();
    return /^(?:127\.0\.0\.1|localhost)$/.exec(hostname) !== null;
  }
  isE2ETest() {
    const hostname = this.getHostname();
    return /^(?:172\.17\.0\.1|host\.docker\.internal)$/.exec(hostname) !== null;
  }
  static formatDate(date2) {
    const monthNames = [
      "January",
      "February",
      "March",
      "April",
      "May",
      "June",
      "July",
      "August",
      "September",
      "October",
      "November",
      "December"
    ];
    const day = date2.getDate();
    const monthIndex = date2.getMonth();
    const year = date2.getFullYear();
    return day + " " + monthNames[monthIndex] + " " + year;
  }
  static getChartsReleaseDate() {
    return new Date(Number.parseInt(_LicenseManager.decode(_LicenseManager.RELEASE_INFORMATION), 10));
  }
  static decode(input) {
    const keystr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    let t = "";
    let n, r, i;
    let s, o, u, a;
    let f = 0;
    const e = input.replaceAll(/[^A-Za-z0-9+/=]/g, "");
    while (f < e.length) {
      s = keystr.indexOf(e.charAt(f++));
      o = keystr.indexOf(e.charAt(f++));
      u = keystr.indexOf(e.charAt(f++));
      a = keystr.indexOf(e.charAt(f++));
      n = s << 2 | o >> 4;
      r = (o & 15) << 4 | u >> 2;
      i = (u & 3) << 6 | a;
      t = t + String.fromCodePoint(n);
      if (u != 64) {
        t = t + String.fromCodePoint(r);
      }
      if (a != 64) {
        t = t + String.fromCodePoint(i);
      }
    }
    t = _LicenseManager.utf8_decode(t);
    return t;
  }
  static utf8_decode(input) {
    input = input.replaceAll("rn", "n");
    let t = "";
    for (let n = 0; n < input.length; n++) {
      const r = input.codePointAt(n);
      if (r < 128) {
        t += String.fromCodePoint(r);
      } else if (r > 127 && r < 2048) {
        t += String.fromCodePoint(r >> 6 | 192);
        t += String.fromCodePoint(r & 63 | 128);
      } else {
        t += String.fromCodePoint(r >> 12 | 224);
        t += String.fromCodePoint(r >> 6 & 63 | 128);
        t += String.fromCodePoint(r & 63 | 128);
      }
    }
    return t;
  }
  static setGridContext(gridContext = false) {
    _LicenseManager.gridContext = gridContext;
  }
  static setLicenseKey(licenseKey) {
    if (this.licenseKey && this.licenseKey !== licenseKey) {
      console.warn(
        `License Key being set multiple times with different values. This can result in an incorrect license key being used.`
      );
    }
    _LicenseManager.licenseKey = licenseKey;
  }
  static extractBracketedInformation(licenseKey) {
    if (!licenseKey.includes("[")) {
      return ["legacy", false, void 0];
    }
    const matches = licenseKey.match(/\[(.*?)\]/g).map((match) => match.replace("[", "").replace("]", ""));
    if (!matches || matches.length === 0) {
      return ["legacy", false, void 0];
    }
    const isTrial = matches.filter((match) => match === "TRIAL").length === 1;
    const rawVersion = matches.find((match) => match.startsWith("v"));
    const version = rawVersion ? rawVersion.replace("v", "") : "legacy";
    const type = LICENSE_TYPES[matches.find((match) => LICENSE_TYPES[match])];
    return [version, isTrial, type];
  }
  centerPadAndOutput(input) {
    const paddingRequired = this.totalMessageLength - input.length;
    console.error(input.padStart(paddingRequired / 2 + input.length, "*").padEnd(this.totalMessageLength, "*"));
  }
  padAndOutput(input, padding2 = "*", terminateWithPadding = "") {
    console.error(
      input.padEnd(this.totalMessageLength - terminateWithPadding.length, padding2) + terminateWithPadding
    );
  }
  outputInvalidLicenseKey(incorrectLicenseType, currentLicenseName, suppliedLicenseName) {
    if (!_LicenseManager.gridContext) {
      if (incorrectLicenseType) {
        this.centerPadAndOutput("");
        this.centerPadAndOutput(` ${currentLicenseName} License `);
        this.centerPadAndOutput(" Incompatible License Key ");
        this.padAndOutput(
          `* Your license key is for ${suppliedLicenseName} only and does not cover you for ${currentLicenseName}.`,
          " ",
          "*"
        );
        this.padAndOutput(`* To troubleshoot your license key visit ${LICENSING_HELP_URL}.`, " ", "*");
        this.centerPadAndOutput("");
        this.centerPadAndOutput("");
      } else {
        this.centerPadAndOutput("");
        this.centerPadAndOutput(` ${currentLicenseName} License `);
        this.centerPadAndOutput(" Invalid License Key ");
        this.padAndOutput(`* Your license key is not valid.`, " ", "*");
        this.padAndOutput(`* To troubleshoot your license key visit ${LICENSING_HELP_URL}.`, " ", "*");
        this.centerPadAndOutput("");
        this.centerPadAndOutput("");
      }
    }
    this.watermarkMessage = "Invalid License";
  }
  outputExpiredTrialKey(formattedExpiryDate, currentLicenseName, suppliedLicenseName) {
    if (!_LicenseManager.gridContext) {
      this.centerPadAndOutput("");
      this.centerPadAndOutput(` ${currentLicenseName} License `);
      this.centerPadAndOutput(" Trial Period Expired. ");
      this.padAndOutput(
        `* Your trial only license for ${suppliedLicenseName} expired on ${formattedExpiryDate}.`,
        " ",
        "*"
      );
      this.padAndOutput("* Please email info@ag-grid.com to purchase a license.", " ", "*");
      this.centerPadAndOutput("");
      this.centerPadAndOutput("");
    }
    this.watermarkMessage = "Trial Period Expired";
  }
  outputMissingLicenseKey(currentLicenseName) {
    if (!_LicenseManager.gridContext) {
      this.centerPadAndOutput("");
      this.centerPadAndOutput(` ${currentLicenseName} License `);
      this.centerPadAndOutput(" License Key Not Found ");
      this.padAndOutput(`* All ${currentLicenseName} features are unlocked for trial.`, " ", "*");
      this.padAndOutput(
        "* If you want to hide the watermark please email info@ag-grid.com for a trial license key.",
        " ",
        "*"
      );
      this.centerPadAndOutput("");
      this.centerPadAndOutput("");
    }
    this.watermarkMessage = "For Trial Use Only";
  }
  outputExpiredKey(formattedExpiryDate, formattedReleaseDate, currentLicenseName) {
    if (!_LicenseManager.gridContext) {
      this.centerPadAndOutput("");
      this.centerPadAndOutput(` ${currentLicenseName} License `);
      this.centerPadAndOutput(" Incompatible Software Version ");
      this.padAndOutput(
        `* Your license key works with versions of ${currentLicenseName} released before ${formattedExpiryDate}.`,
        " ",
        "*"
      );
      this.padAndOutput(`* The version you are trying to use was released on ${formattedReleaseDate}.`, " ", "*");
      this.padAndOutput("* Please contact info@ag-grid.com to renew your license key.", " ", "*");
      this.centerPadAndOutput("");
      this.centerPadAndOutput("");
    }
    this.watermarkMessage = "License Expired";
  }
};
_LicenseManager.RELEASE_INFORMATION = "MTc3MDgwNzY1NDM4MQ==";
_LicenseManager.gridContext = false;
var LicenseManager = _LicenseManager;

// packages/ag-charts-enterprise/src/license/watermark.ts
function injectWatermark(domManager, text2) {
  const element2 = domManager.addChild("canvas-overlay", "watermark");
  const textElement = createElement("span");
  textElement.innerText = text2;
  element2.addEventListener("animationend", () => {
    domManager.removeChild("canvas-overlay", "watermark");
    domManager.removeStyles("watermark");
  });
  element2.classList.add("ag-watermark");
  element2.appendChild(textElement);
}

// packages/ag-charts-enterprise/src/styles.css
var styles_default2 = `.ag-watermark{position:absolute;bottom:20px;right:25px;font-weight:700;font-family:Impact,sans-serif;font-size:19px;opacity:.7;animation:1s ease-out 3s ag-watermark-fadeout;color:#9b9b9b;pointer-events:none;&:before{content:"";display:block;height:40px;width:170px;background-image:url(data:image/svg+xml;base64,[encoded data, 8028 characters]);background-repeat:no-repeat;background-size:170px 40px}>span{padding-left:.7rem}}@keyframes ag-watermark-fadeout{0%{opacity:.5}to{opacity:0}}.ag-charts-dialog{display:flex;flex-direction:column;font-size:var(--ag-charts-chrome-font-size-large)}.ag-charts-dialog__tabs{display:flex;flex-direction:column}.ag-charts-dialog__header{border-bottom:1px solid var(--ag-charts-border-color);display:flex}.ag-charts-dialog__tab-list{display:flex;gap:calc(var(--ag-charts-spacing) * 2)}.ag-charts-dialog__drag-handle{align-items:center;color:inherit;cursor:grab;display:flex;padding:1px 6px;text-align:center}.ag-charts-dialog__drag-handle--dragging{cursor:grabbing}.ag-charts-dialog__tab-button{background:none;border:0;border-bottom:2px solid transparent;border-radius:0;color:var(--ag-charts-panel-subtle-text-color);margin-bottom:-1px;padding:var(--input-padding) calc(var(--input-padding) / 2)}.ag-charts-dialog__tab-button:hover{background:none}.ag-charts-dialog__tab-button--active{border-color:var(--ag-charts-accent-color);color:inherit}.ag-charts-dialog__drag-handle+.ag-charts-dialog__tab-button{margin-left:calc(var(--ag-charts-spacing) * -2)}.ag-charts-button.ag-charts-dialog__close-button{background:none;border:0;margin-left:auto;padding:1px 6px}.ag-charts-dialog__close-button:focus-visible{outline:var(--ag-charts-focus-border);box-shadow:var(--ag-charts-focus-border-shadow);z-index:calc(var(--ag-charts-layer-ui-overlay) + 1)}.ag-charts-dialog__tab-panel{display:none;flex-direction:column;gap:calc(var(--ag-charts-spacing) * 4);margin:0 calc(var(--ag-charts-spacing) * 4);padding:calc(var(--ag-charts-spacing) * 4) 0}.ag-charts-dialog__tab-panel--active{display:flex}.ag-charts-dialog__input-group-line{display:flex;gap:16px 18px;flex-wrap:wrap}.ag-charts-dialog__input-group{align-items:center;display:flex;font-size:var(--ag-charts-chrome-font-size)}.ag-charts-dialog__input-group-label{color:var(--ag-charts-panel-subtle-text-color);margin-right:5px}.ag-charts-dialog__input-group-label[for]{cursor:pointer}.ag-charts-dialog__button{border-radius:0;margin-right:-1px}.ag-charts-dialog__button.ag-charts-dialog__button--active{background:var(--ag-charts-button-focus-background-color);border-color:var(--ag-charts-input-focus-border-color);color:var(--ag-charts-input-focus-text-color);z-index:var(--input-layer-active)}.ag-charts-dialog__button:first-child,.ag-charts-dialog__input-group-label+.ag-charts-dialog__button{border-bottom-left-radius:var(--ag-charts-input-border-radius);border-top-left-radius:var(--ag-charts-input-border-radius)}.ag-charts-dialog__button:last-child{border-bottom-right-radius:var(--ag-charts-input-border-radius);border-top-right-radius:var(--ag-charts-input-border-radius)}.ag-charts-dialog__color-picker-button{--color: #000;background:var(--color);border:none;color:transparent;height:26px;width:26px}.ag-charts-dialog__color-picker-button:hover{background:var(--color)}.ag-charts-dialog__color-picker-button--multi-color,.ag-charts-dialog__color-picker-button--multi-color:hover{background:linear-gradient(135deg,red 0%,#ff0 calc(100% * 1 / 6),#0f0 calc(100% * 2 / 6),#0ff 50%,#00f calc(100% * 4 / 6),#f0f calc(100% * 5 / 6),red 100%)}.ag-charts-color-picker{width:190px;padding:8px;cursor:default;--h: 0;--s: 0;--v: 0;--a: 0;--color: #000;--color-a: #000;--thumb-size: 18px;--inner-width: 172px;--track-height: 12px;--palette-height: 136px;--checker: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="4" height="4"><rect x="0" y="0" width="4" height="4" fill="%23fff"/><path d="M0 0H2V4H4V2H0Z" fill="%23b2b2b2"/></svg>');--multi-color: linear-gradient( 135deg, #f00 0% , #ff0 calc(100% * 1 / 6), #0f0 calc(100% * 2 / 6), #0ff 50% , #00f calc(100% * 4 / 6), #f0f calc(100% * 5 / 6), #f00 100% )}.ag-charts-color-picker__content{display:flex;flex-direction:column}.ag-charts-color-picker__palette{position:relative;width:100%;height:var(--palette-height);margin-bottom:8px;background:linear-gradient(to bottom,#0000,#000),linear-gradient(to right,#fff,#fff0) hsl(var(--h),100%,50%);border-radius:calc(var(--ag-charts-border-radius) * 1.5);box-shadow:inset 0 0 0 1px #0003}.ag-charts-color-picker__palette:after{content:"";position:absolute;display:block;top:calc(var(--thumb-size) * -.5 + (1 - var(--v)) * 100%);left:calc(var(--thumb-size) * -.5 + var(--s) * 100%);background:var(--color);width:var(--thumb-size);height:var(--thumb-size);border-radius:calc(var(--ag-charts-border-radius) * 99);box-shadow:var(--box-shadow);--box-shadow: inset 0 0 0 3px white, inset 0 0 1px 3px #0006, 0 0 5px #00000038}.ag-charts-color-picker__palette:focus-visible:after{outline:var(--ag-charts-focus-border);box-shadow:var(--box-shadow),0 0 0 2px #fff8,var(--ag-charts-focus-border-shadow)}.ag-charts-color-picker__color-row{display:flex;gap:8px;align-items:center;margin-bottom:4px;--inset: calc((var(--thumb-size) - var(--track-height)) / 2)}.ag-charts-color-picker__hue-input,.ag-charts-color-picker__alpha-input{-webkit-appearance:none;display:block;position:relative;padding:0;margin:0 calc(var(--inset) * -1);border:0;height:var(--thumb-size);width:auto;background:transparent;--inset: calc((var(--thumb-size) - var(--track-height)) / 2)}.ag-charts-color-picker__hue-input::-moz-range-thumb,.ag-charts-color-picker__alpha-input::-moz-range-thumb{appearance:none;width:var(--thumb-size);height:var(--thumb-size);border-radius:calc(var(--ag-charts-border-radius) * 99);box-shadow:var(--box-shadow);--box-shadow: inset 0 0 0 3px white, inset 0 0 1px 3px #0006, 0 0 5px #00000038}.ag-charts-color-picker__hue-input::-webkit-slider-thumb,.ag-charts-color-picker__alpha-input::-webkit-slider-thumb{-webkit-appearance:none;width:var(--thumb-size);height:var(--thumb-size);border-radius:calc(var(--ag-charts-border-radius) * 99);box-shadow:var(--box-shadow);--box-shadow: inset 0 0 0 3px white, inset 0 0 1px 3px #0006, 0 0 5px #00000038;transform:translateZ(0)}.ag-charts-color-picker__hue-input::-moz-range-thumb{background:hsl(var(--h),100%,50%)}.ag-charts-color-picker__hue-input::-webkit-slider-thumb{background:hsl(var(--h),100%,50%)}.ag-charts-color-picker__alpha-input::-moz-range-thumb{background:transparent}.ag-charts-color-picker__alpha-input::-webkit-slider-thumb{background:transparent}.ag-charts-color-picker__alpha-input--opaque::-moz-range-thumb{background:var(--color)}.ag-charts-color-picker__alpha-input--opaque::-webkit-slider-thumb{background:var(--color)}.ag-charts-color-picker__hue-input:focus-visible::-moz-range-thumb,.ag-charts-color-picker__alpha-input:focus-visible::-moz-range-thumb{outline:var(--ag-charts-focus-border);box-shadow:var(--box-shadow),var(--ag-charts-focus-border-shadow)}.ag-charts-color-picker__hue-input:focus-visible::-webkit-slider-thumb,.ag-charts-color-picker__alpha-input:focus-visible::-webkit-slider-thumb{outline:var(--ag-charts-focus-border);box-shadow:var(--box-shadow),var(--ag-charts-focus-border-shadow)}.ag-charts-color-picker__hue-input::-moz-range-track,.ag-charts-color-picker__alpha-input::-moz-range-track{position:absolute;content:"";display:block;top:calc(50% - var(--track-height) / 2);left:var(--inset);right:var(--inset);height:var(--track-height);border-radius:calc(var(--ag-charts-border-radius) * 99);box-shadow:inset 0 0 0 1px #0003}.ag-charts-color-picker__hue-input:before,.ag-charts-color-picker__alpha-input:before{position:absolute;content:"";display:block;top:calc(50% - var(--track-height) / 2);left:var(--inset);right:var(--inset);height:var(--track-height);border-radius:calc(var(--ag-charts-border-radius) * 99);box-shadow:inset 0 0 0 1px #0003}.ag-charts-color-picker__multi-color-button{width:36px;margin-left:var(--inset);height:var(--track-height);border-radius:calc(var(--ag-charts-border-radius) * 99);border:0;background:var(--multi-color);box-shadow:inset 0 0 0 1px #0003}.ag-charts-color-picker__multi-color-button--hidden{display:none}.ag-charts-color-picker__multi-color-button--active{box-shadow:inset 0 0 0 1px #0003;outline-offset:1px;outline:2px solid #2196f3}.ag-charts-color-picker__hue-input{flex:1 0 0}.ag-charts-color-picker__hue-input::-moz-range-track{background:linear-gradient(to right,red,red calc((100% - var(--track-height)) * 0 / 6 + var(--track-height) / 2),#ff0 calc((100% - var(--track-height)) * 1 / 6 + var(--track-height) / 2),#0f0 calc((100% - var(--track-height)) * 2 / 6 + var(--track-height) / 2),#0ff calc((100% - var(--track-height)) * 3 / 6 + var(--track-height) / 2),#00f calc((100% - var(--track-height)) * 4 / 6 + var(--track-height) / 2),#f0f calc((100% - var(--track-height)) * 5 / 6 + var(--track-height) / 2),red calc((100% - var(--track-height)) * 6 / 6 + var(--track-height) / 2))}.ag-charts-color-picker__hue-input:before{background:linear-gradient(to right,red,red calc((100% - var(--track-height)) * 0 / 6 + var(--track-height) / 2),#ff0 calc((100% - var(--track-height)) * 1 / 6 + var(--track-height) / 2),#0f0 calc((100% - var(--track-height)) * 2 / 6 + var(--track-height) / 2),#0ff calc((100% - var(--track-height)) * 3 / 6 + var(--track-height) / 2),#00f calc((100% - var(--track-height)) * 4 / 6 + var(--track-height) / 2),#f0f calc((100% - var(--track-height)) * 5 / 6 + var(--track-height) / 2),red calc((100% - var(--track-height)) * 6 / 6 + var(--track-height) / 2))}.ag-charts-color-picker__alpha-input{margin-bottom:7px}.ag-charts-color-picker__alpha-input::-moz-range-track{background:linear-gradient(to right,transparent,var(--color)),var(--checker) top left / 4px 4px}.ag-charts-color-picker__alpha-input:before{background:linear-gradient(to right,transparent,var(--color)),var(--checker) top left / 4px 4px}.ag-charts-color-picker__color-field{display:flex;border:var(--ag-charts-border);background:var(--ag-charts-background-color);border-radius:var(--ag-charts-border-radius);overflow:hidden}.ag-charts-color-picker__color-field:has(:focus-visible){border-color:var(--ag-charts-accent-color);box-shadow:var(--ag-charts-focus-border-shadow)}.ag-charts-color-picker__color-label{width:16px;height:16px;margin:7px 0 7px 7px;color:transparent;background:linear-gradient(to right,var(--color-a),var(--color-a)),var(--checker) top left / 4px 4px;border-radius:calc(var(--ag-charts-border-radius) / 2);box-shadow:inset 0 0 0 1px #0003}.ag-charts-color-picker__color-label--multi-color{background:var(--multi-color)}.ag-charts-color-picker__color-input{flex:1;min-width:0;padding:7px 7px 7px 8px;border:0;margin:0;color:inherit;background:transparent;font-variant:tabular-nums}.ag-charts-color-picker__color-input:focus-visible{border:none;outline:none}.ag-charts-annotations__line-stroke-width-menu,.ag-charts-annotations__line-style-type-menu,.ag-charts-annotations__text-size-menu{border-top-left-radius:0;border-top-right-radius:0;.ag-charts-menu__row:first-child{border-radius:0}}.ag-charts-annotations__text-size-menu{--item-padding: 4px 8px;min-width:34px;text-align:center}.ag-charts-annotations__line-stroke-width-menu{--item-padding: 6px;column-gap:6px}.ag-charts-annotations__line-style-type-menu{--item-padding: 6px;column-gap:0}.ag-charts-annotations__stroke-width-button:before{background:var(--ag-charts-foreground-color);content:"";margin-right:var(--toolbar-button-padding);height:min(var(--stroke-width),20px);width:12px}.ag-charts-annotations__stroke-width-button[aria-disabled=true]:before{filter:grayscale(1);opacity:.5}.ag-charts-annotations__color-picker-button{--emblem: var(--color)}.ag-charts-annotations__color-picker-button--multi-color{--emblem: linear-gradient( to right, #f00 0% , #ff0 calc(100% * 1 / 6), #0f0 calc(100% * 2 / 6), #0ff 50% , #00f calc(100% * 4 / 6), #f0f calc(100% * 5 / 6), #f00 100% )}.ag-charts-annotations__color-picker-button:after{content:"";display:block;position:absolute;bottom:3px;left:5px;right:5px;height:4px;border-radius:99px;box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ag-charts-foreground-color) 10%,transparent);background:var(--emblem)}.ag-charts-annotations__color-picker-button[aria-disabled=true]:after{filter:grayscale(1);opacity:.5}.ag-charts-annotations__toolbar-menu{min-width:200px}.ag-charts-annotations__axis-button--hidden{display:none}.ag-charts-annotations__axis-button{background-color:var(--ag-charts-crosshair-label-background-color);border-radius:calc(var(--ag-charts-border-radius) / 2);border:none;box-sizing:border-box;color:var(--ag-charts-crosshair-label-text-color);cursor:pointer;font-family:var(--ag-charts-button-font-family);font-size:var(--ag-charts-button-font-size);font-weight:var(--ag-charts-button-font-weight);left:0;line-height:16px;overflow:hidden;padding:0;position:absolute;top:0;user-select:none;white-space:nowrap;z-index:var(--ag-charts-layer-annotations)}.ag-charts-annotations__axis-button:hover{opacity:.8;color:var(--ag-charts-background-color)}.ag-charts-dialog--annotation-settings{min-height:233px;width:289px}.ag-charts-dialog--annotation-settings .ag-charts-textarea{height:calc(10px * 2 + var(--textarea-line-height) * 1em * 3 + 2px);overflow-y:auto;resize:vertical}.ag-charts-context-menu{font-family:var(--ag-charts-chrome-font-family);font-size:var(--ag-charts-chrome-font-size);font-weight:var(--ag-charts-chrome-font-weight);z-index:var(--ag-charts-layer-ui-overlay)}.ag-charts-context-menu__cover{position:fixed;left:0;top:0}.ag-charts-context-menu__menu{background:var(--ag-charts-menu-background-color);border-radius:var(--ag-charts-border-radius);border:var(--ag-charts-menu-border);box-shadow:var(--ag-charts-popup-shadow);color:var(--ag-charts-menu-text-color);display:flex;flex-direction:column;padding:.5em 0;transition:transform .1s ease;white-space:nowrap}.ag-charts-context-menu__menu:focus{outline:none}.ag-charts-context-menu__item{align-items:center;background:none;border:none;box-sizing:border-box;color:inherit;cursor:pointer;display:flex;font:inherit;justify-content:space-between;text-align:left;width:100%;-webkit-appearance:none;-moz-appearance:none}.ag-charts-context-menu__icon>img{width:var(--ag-charts-icon-size);height:var(--ag-charts-icon-size)}.ag-charts-context-menu__icon,.ag-charts-context-menu__cell{display:flex;align-items:center;flex-shrink:0}.ag-charts-context-menu__cell{flex-grow:1}.ag-charts-context-menu__cellpadding{padding:.5em 1em}.ag-charts-context-menu__icon{padding-right:0}.ag-charts-context-menu__item[data-focus-override=true],.ag-charts-context-menu__item:focus,.ag-charts-context-menu__item:active{background:var(--ag-charts-focus-color)}.ag-charts-context-menu__item[data-focus-override=false]{background:inherit}.ag-charts-context-menu__item[data-focus-visible-override=true]:focus,.ag-charts-context-menu__item:focus-visible{outline:var(--ag-charts-focus-border);box-shadow:var(--ag-charts-focus-border-shadow);z-index:calc(var(--ag-charts-layer-ui-overlay) + 1)}.ag-charts-context-menu__item[data-focus-visible-override=false]{outline:inherit;box-shadow:inherit;z-index:inherit}.ag-charts-context-menu__item[aria-disabled=true]{border:none;color:color-mix(in srgb,var(--ag-charts-input-text-color) 50%,transparent)}.ag-charts-context-menu__item[aria-disabled=true]:focus{background:inherit;cursor:inherit}.ag-charts-context-menu__divider{padding:5px 0}.ag-charts-context-menu__divider:after{content:"";display:block;border-top:1px solid var(--ag-charts-border-color)}.ag-charts-crosshair-label{position:absolute;left:0;top:0;user-select:none;pointer-events:none;font-family:var(--ag-charts-font-family);font-size:var(--ag-charts-font-size);font-weight:var(--ag-charts-font-weight);overflow:hidden;white-space:nowrap;z-index:var(--ag-charts-layer-crosshair);box-sizing:border-box}.ag-charts-crosshair-label-content{padding:0 8px;border-radius:calc(var(--ag-charts-border-radius) / 2);line-height:calc(var(--ag-charts-font-size) + 8px);background-color:var(--ag-charts-crosshair-label-background-color);color:var(--ag-charts-crosshair-label-text-color)}.ag-charts-crosshair-label--hidden{visibility:hidden!important}.ag-charts-text-input{position:absolute}.ag-charts-text-input__textarea{--placeholder-text-color: var(--ag-charts-input-placeholder-text-color);display:block;height:100%;width:100%;border:0;background:none;line-height:1.38;outline:none;transform:translateY(.09em)}.ag-charts-text-input__textarea[placeholder]:empty:before{content:attr(placeholder);color:var(--placeholder-text-color);font-weight:400}.ag-charts-text-input__textarea[placeholder]:not(:empty):before{content:""}.ag-charts-chart-toolbar__menu{min-width:200px}.ag-charts-range-buttons .ag-charts-toolbar__button{padding:var(--toolbar-button-padding) calc(var(--toolbar-button-padding) * 1.5)}.ag-charts-zoom-buttons{align-items:center;display:flex;height:44px;justify-content:center;overflow:hidden;padding-bottom:10px;pointer-events:none;width:100%;.ag-charts-toolbar{--toolbar-size: 24px;--toolbar-button-padding: 1px;display:flex;font-size:var(--ag-charts-chrome-font-size);height:var(--toolbar-size);justify-content:center;opacity:1;pointer-events:auto;transition:opacity .2s ease-in-out,transform .4s ease-in-out;.ag-charts-toolbar__button--first{border-bottom-left-radius:var(--ag-charts-border-radius);border-top-left-radius:var(--ag-charts-border-radius)}.ag-charts-toolbar__button--last{border-bottom-right-radius:var(--ag-charts-border-radius);border-top-right-radius:var(--ag-charts-border-radius)}.ag-charts-toolbar__label{padding-left:var(--ag-charts-spacing);padding-right:var(--ag-charts-spacing)}.ag-charts-toolbar__icon+.ag-charts-toolbar__label{padding-left:0}.ag-charts-toolbar__button--gap{margin-left:var(--toolbar-gap)}&.ag-charts-zoom-buttons__toolbar--hidden{opacity:0;transition:opacity .4s ease-in-out,transform .4s ease-in-out}}}.ag-charts-shared-toolbar{gap:var(--toolbar-gap);.ag-charts-toolbar__button{border-radius:var(--ag-charts-border-radius);margin:0}.ag-charts-toolbar__button--active+.ag-charts-toolbar__button{border-left-color:var(--ag-charts-border-color)}}
`;

// packages/ag-charts-enterprise/src/setup.ts
function setupEnterpriseModules() {
  moduleRegistry_exports.registerModules(AllEnterpriseModule);
  enterpriseRegistry.styles = styles_default2;
  enterpriseRegistry.licenseManager = (options) => new LicenseManager(
    options.container?.ownerDocument ?? (typeof document === "undefined" ? void 0 : document)
  );
  enterpriseRegistry.injectWatermark = injectWatermark;
  enterpriseRegistry.createBackground = (ctx) => new Background3(ctx);
  enterpriseRegistry.createForeground = (ctx) => new Foreground(ctx);
}

// packages/ag-charts-enterprise/src/module-bundles/integrated.ts
var LicenseManager2 = {
  setLicenseKey(key) {
    LicenseManager.setLicenseKey(key);
  }
};
var AgChartsEnterpriseModule = {
  VERSION,
  _Scene: integrated_charts_scene_exports,
  _Theme: integrated_charts_theme_exports,
  _Util: integrated_charts_util_exports,
  create: AgCharts.create.bind(AgCharts),
  createSparkline: AgCharts.__createSparkline.bind(AgCharts),
  setup: () => {
    moduleRegistry_exports.setRegistryMode(moduleRegistry_exports.RegistryMode.Integrated);
    setupEnterpriseModules();
  },
  setGridContext: LicenseManager.setGridContext.bind(LicenseManager),
  setLicenseKey: LicenseManager.setLicenseKey.bind(LicenseManager),
  isEnterprise: true
};

// packages/ag-charts-enterprise/src/main.ts
moduleRegistry_exports.setRegistryMode(moduleRegistry_exports.RegistryMode.Enterprise);
enterpriseRegistry.styles = styles_default2;
enterpriseRegistry.licenseManager = (options) => new LicenseManager(options.container?.ownerDocument ?? (typeof document === "undefined" ? void 0 : document));
enterpriseRegistry.injectWatermark = injectWatermark;
enterpriseRegistry.createBackground = (ctx) => new Background3(ctx);
enterpriseRegistry.createForeground = (ctx) => new Foreground(ctx);

// packages/ag-charts-enterprise/src/main-umd.ts
moduleRegistry_exports.setRegistryMode(moduleRegistry_exports.RegistryMode.UMD);
moduleRegistry_exports.registerModules(AllEnterpriseModule);
if (typeof module.exports == "object" && typeof exports == "object") {
  var __cp = (to, from, except, desc) => {
    if ((from && typeof from === "object") || typeof from === "function") {
      for (let key of Object.getOwnPropertyNames(from)) {
        if (!Object.prototype.hasOwnProperty.call(to, key) && key !== except)
        Object.defineProperty(to, key, {
          get: () => from[key],
          enumerable: !(desc = Object.getOwnPropertyDescriptor(from, key)) || desc.enumerable,
        });
      }
    }
    return to;
  };
  module.exports = __cp(module.exports, exports);
}
return module.exports;
}))
