/**
 * @license Highcharts JS v11.4.0 (2024-03-04)
 *
 * Arc diagram module
 *
 * (c) 2021 Piotr Madej
 *
 * License: www.highcharts.com/license
 */
(function (factory) {
    if (typeof module === 'object' && module.exports) {
        factory['default'] = factory;
        module.exports = factory;
    } else if (typeof define === 'function' && define.amd) {
        define('highcharts/modules/arc-diagram', ['highcharts', 'highcharts/modules/sankey'], function (Highcharts) {
            factory(Highcharts);
            factory.Highcharts = Highcharts;
            return factory;
        });
    } else {
        factory(typeof Highcharts !== 'undefined' ? Highcharts : undefined);
    }
}(function (Highcharts) {
    'use strict';
    var _modules = Highcharts ? Highcharts._modules : {};
    function _registerModule(obj, path, args, fn) {
        if (!obj.hasOwnProperty(path)) {
            obj[path] = fn.apply(null, args);

            if (typeof CustomEvent === 'function') {
                window.dispatchEvent(new CustomEvent(
                    'HighchartsModuleLoaded',
                    { detail: { path: path, module: obj[path] } }
                ));
            }
        }
    }
    _registerModule(_modules, 'Series/ArcDiagram/ArcDiagramPoint.js', [_modules['Series/NodesComposition.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Utilities.js']], function (NodesComposition, SeriesRegistry, U) {
        /* *
         *
         *  Arc diagram module
         *
         *  (c) 2018-2024 Torstein Honsi
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         * */
        const { seriesTypes: { sankey: { prototype: { pointClass: SankeyPoint } } } } = SeriesRegistry;
        const { extend } = U;
        /* *
         *
         *  Class
         *
         * */
        class ArcDiagramPoint extends SankeyPoint {
            /* *
             *
             *  Functions
             *
             * */
            /* eslint-disable valid-jsdoc */
            isValid() {
                // No null points here
                return true;
            }
        }
        extend(ArcDiagramPoint.prototype, {
            setState: NodesComposition.setNodeState
        });
        /* *
         *
         *  Default Export
         *
         * */

        return ArcDiagramPoint;
    });
    _registerModule(_modules, 'Series/ArcDiagram/ArcDiagramSeries.js', [_modules['Series/ArcDiagram/ArcDiagramPoint.js'], _modules['Series/Sankey/SankeyColumnComposition.js'], _modules['Core/Series/Series.js'], _modules['Core/Series/SeriesRegistry.js'], _modules['Core/Renderer/SVG/SVGRenderer.js'], _modules['Core/Utilities.js']], function (ArcDiagramPoint, SankeyColumnComposition, Series, SeriesRegistry, SVGRenderer, U) {
        /* *
         *
         *  Arc diagram module
         *
         *  (c) 2021 Piotr Madej, Grzegorz Blachliński
         *
         *  License: www.highcharts.com/license
         *
         *  !!!!!!! SOURCE GETS TRANSPILED BY TYPESCRIPT. EDIT TS FILE ONLY. !!!!!!!
         *
         * */
        const { prototype: { symbols } } = SVGRenderer;
        const { seriesTypes: { column: ColumnSeries, sankey: SankeySeries } } = SeriesRegistry;
        const { extend, merge, pick, relativeLength } = U;
        /* *
         *
         *  Class
         *
         * */
        /**
         * @private
         * @class
         * @name Highcharts.seriesTypes.arcdiagram
         *
         * @augments Highcharts.seriesTypes.sankey
         */
        class ArcDiagramSeries extends SankeySeries {
            /* *
             *
             *  Functions
             *
             * */
            /**
             * Create node columns by analyzing the nodes and the relations between
             * incoming and outgoing links.
             * @private
             */
            createNodeColumns() {
                const series = this, chart = series.chart, 
                // column needs casting, to much methods required at the same time
                column = SankeyColumnComposition.compose([], series);
                column.sankeyColumn.maxLength = chart.inverted ?
                    chart.plotHeight : chart.plotWidth;
                // Get the translation factor needed for each column to fill up the plot
                // height
                column.sankeyColumn.getTranslationFactor = (series) => {
                    const nodes = column.slice(), minLinkWidth = this.options.minLinkWidth || 0;
                    let skipPoint, factor = 0, i, radius, maxRadius = 0, scale = 1, additionalSpace = 0, remainingWidth = (chart.plotSizeX || 0) -
                        (series.options.marker &&
                            series.options.marker.lineWidth || 0) -
                        (column.length - 1) *
                            series.nodePadding;
                    // Because the minLinkWidth option doesn't obey the direct
                    // translation, we need to run translation iteratively, check node
                    // heights, remove those nodes affected by minLinkWidth, check
                    // again, etc.
                    while (column.length) {
                        factor = remainingWidth / column.sankeyColumn.sum();
                        skipPoint = false;
                        i = column.length;
                        while (i--) {
                            radius = (column[i].getSum()) * factor * scale;
                            let plotArea = Math.min(chart.plotHeight, chart.plotWidth);
                            if (radius > plotArea) {
                                scale = Math.min(plotArea / radius, scale);
                            }
                            else if (radius < minLinkWidth) {
                                column.splice(i, 1);
                                remainingWidth -= minLinkWidth;
                                radius = minLinkWidth;
                                skipPoint = true;
                            }
                            additionalSpace += radius * (1 - scale) / 2;
                            maxRadius = Math.max(maxRadius, radius);
                        }
                        if (!skipPoint) {
                            break;
                        }
                    }
                    // Re-insert original nodes
                    column.length = 0;
                    nodes.forEach((node) => {
                        node.scale = scale;
                        column.push(node);
                    });
                    column.sankeyColumn.maxRadius = maxRadius;
                    column.sankeyColumn.scale = scale;
                    column.sankeyColumn.additionalSpace = additionalSpace;
                    return factor;
                };
                column.sankeyColumn.offset = function (node, factor) {
                    const equalNodes = node.series.options.equalNodes;
                    let offset = column.sankeyColumn.additionalSpace || 0, totalNodeOffset, nodePadding = series.nodePadding, maxRadius = Math.min(chart.plotWidth, chart.plotHeight, (column.sankeyColumn.maxLength || 0) /
                        series.nodes.length - nodePadding);
                    for (let i = 0; i < column.length; i++) {
                        const sum = column[i].getSum() *
                            (column.sankeyColumn.scale || 0);
                        const width = equalNodes ?
                            maxRadius :
                            Math.max(sum * factor, series.options.minLinkWidth || 0);
                        if (sum) {
                            totalNodeOffset = width + nodePadding;
                        }
                        else {
                            // If node sum equals 0 nodePadding is missed #12453
                            totalNodeOffset = 0;
                        }
                        if (column[i] === node) {
                            return {
                                relativeLeft: offset + relativeLength(node.options.offset || 0, totalNodeOffset)
                            };
                        }
                        offset += totalNodeOffset;
                    }
                };
                // Add nodes directly to the column right after it's creation
                series.nodes.forEach(function (node) {
                    node.column = 0;
                    column.push(node);
                });
                return [column];
            }
            /**
             * Run translation operations for one link.
             * @private
             */
            translateLink(point) {
                const series = this, fromNode = point.fromNode, toNode = point.toNode, chart = this.chart, translationFactor = series.translationFactor, pointOptions = point.options, seriesOptions = series.options, linkWeight = pick(pointOptions.linkWeight, seriesOptions.linkWeight, Math.max((point.weight || 0) *
                    translationFactor *
                    fromNode.scale, (series.options.minLinkWidth || 0))), centeredLinks = point.series.options.centeredLinks, nodeTop = fromNode.nodeY;
                const getX = (node, fromOrTo) => {
                    const linkLeft = ((node.offset(point, fromOrTo) || 0) *
                        translationFactor);
                    const x = Math.min(node.nodeX + linkLeft, 
                    // Prevent links from spilling below the node (#12014)
                    node.nodeX + (node.shapeArgs && node.shapeArgs.height || 0) - linkWeight);
                    return x;
                };
                let fromX = centeredLinks ?
                    fromNode.nodeX +
                        ((fromNode.shapeArgs.height || 0) - linkWeight) / 2 :
                    getX(fromNode, 'linksFrom'), toX = centeredLinks ? toNode.nodeX +
                    ((toNode.shapeArgs.height || 0) - linkWeight) / 2 :
                    getX(toNode, 'linksTo'), bottom = nodeTop;
                if (fromX > toX) {
                    [fromX, toX] = [toX, fromX];
                }
                if (seriesOptions.reversed) {
                    [fromX, toX] = [toX, fromX];
                    bottom = (chart.plotSizeY || 0) - bottom;
                }
                point.shapeType = 'path';
                point.linkBase = [
                    fromX,
                    fromX + linkWeight,
                    toX,
                    toX + linkWeight
                ];
                const linkRadius = ((toX + linkWeight - fromX) / Math.abs(toX + linkWeight - fromX)) * pick(seriesOptions.linkRadius, Math.min(Math.abs(toX + linkWeight - fromX) / 2, fromNode.nodeY - Math.abs(linkWeight)));
                point.shapeArgs = {
                    d: [
                        ['M', fromX, bottom],
                        [
                            'A',
                            (toX + linkWeight - fromX) / 2,
                            linkRadius,
                            0,
                            0,
                            1,
                            toX + linkWeight,
                            bottom
                        ],
                        ['L', toX, bottom],
                        [
                            'A',
                            (toX - fromX - linkWeight) / 2,
                            linkRadius - linkWeight,
                            0,
                            0,
                            0,
                            fromX + linkWeight,
                            bottom
                        ],
                        ['Z']
                    ]
                };
                point.dlBox = {
                    x: fromX + (toX - fromX) / 2,
                    y: bottom - linkRadius,
                    height: linkWeight,
                    width: 0
                };
                // And set the tooltip anchor in the middle
                point.tooltipPos = chart.inverted ? [
                    (chart.plotSizeY || 0) - point.dlBox.y - linkWeight / 2,
                    (chart.plotSizeX || 0) - point.dlBox.x
                ] : [
                    point.dlBox.x,
                    point.dlBox.y + linkWeight / 2
                ];
                // Pass test in drawPoints
                point.y = point.plotY = 1;
                point.x = point.plotX = 1;
                if (!point.color) {
                    point.color = fromNode.color;
                }
            }
            /**
             * Run translation operations for one node.
             * @private
             */
            translateNode(node, column) {
                const series = this, translationFactor = series.translationFactor, chart = series.chart, maxNodesLength = chart.inverted ?
                    chart.plotWidth : chart.plotHeight, options = series.options, maxRadius = Math.min(chart.plotWidth, chart.plotHeight, maxNodesLength / node.series.nodes.length - this.nodePadding), sum = node.getSum() * (column.sankeyColumn.scale || 0), equalNodes = options.equalNodes, nodeHeight = equalNodes ?
                    maxRadius :
                    Math.max(sum * translationFactor, this.options.minLinkWidth || 0), crisp = Math.round(options.marker &&
                    options.marker.lineWidth || 0) % 2 / 2, nodeOffset = column.sankeyColumn.offset(node, translationFactor), fromNodeLeft = Math.floor(pick(nodeOffset && nodeOffset.absoluteLeft, ((column.sankeyColumn.left(translationFactor) || 0) +
                    (nodeOffset && nodeOffset.relativeLeft || 0)))) + crisp, markerOptions = merge(options.marker, node.options.marker), symbol = markerOptions.symbol, markerRadius = markerOptions.radius, top = parseInt(options.offset, 10) *
                    ((chart.inverted ?
                        chart.plotWidth : chart.plotHeight) - (Math.floor(this.colDistance * (node.column || 0) +
                        (markerOptions.lineWidth || 0) / 2) + crisp +
                        (column.sankeyColumn.scale || 0) *
                            (column.sankeyColumn.maxRadius || 0) / 2)) / 100;
                node.sum = sum;
                // If node sum is 0, don’t render the rect #12453
                if (sum) {
                    // Draw the node
                    node.nodeX = fromNodeLeft;
                    node.nodeY = top;
                    const x = fromNodeLeft, width = node.options.width || options.width || nodeHeight, height = node.options.height || options.height || nodeHeight;
                    let y = top;
                    if (options.reversed) {
                        y = (chart.plotSizeY || 0) - top;
                        if (chart.inverted) {
                            y = (chart.plotSizeY || 0) - top;
                        }
                    }
                    if (this.mapOptionsToLevel) {
                        // Calculate data label options for the point
                        node.dlOptions = SankeySeries.getDLOptions({
                            level: this.mapOptionsToLevel[node.level],
                            optionsPoint: node.options
                        });
                    }
                    // Pass test in drawPoints
                    node.plotX = 1;
                    node.plotY = 1;
                    // Set the anchor position for tooltips
                    node.tooltipPos = chart.inverted ? [
                        (chart.plotSizeY || 0) - y - height / 2,
                        (chart.plotSizeX || 0) - x - width / 2
                    ] : [
                        x + width / 2,
                        y + height / 2
                    ];
                    node.shapeType = 'path';
                    node.shapeArgs = {
                        d: symbols[symbol || 'circle'](x, y - (markerRadius || height) / 2, markerRadius || width, markerRadius || height),
                        width: markerRadius || width,
                        height: markerRadius || height
                    };
                    node.dlBox = {
                        x: x + width / 2,
                        y: y,
                        height: 0,
                        width: 0
                    };
                }
                else {
                    node.dlOptions = {
                        enabled: false
                    };
                }
            }
            // Networkgraph has two separate collecions of nodes and lines, render
            // dataLabels for both sets:
            drawDataLabels() {
                if (this.options.dataLabels) {
                    const textPath = this.options.dataLabels.textPath;
                    // Render node labels:
                    ColumnSeries.prototype.drawDataLabels.call(this, this.nodes);
                    // Render link labels:
                    this.options.dataLabels.textPath =
                        this.options.dataLabels.linkTextPath;
                    ColumnSeries.prototype.drawDataLabels.call(this, this.data);
                    // Restore nodes
                    this.options.dataLabels.textPath = textPath;
                }
            }
            pointAttribs(point, 
            // eslint-disable-next-line @typescript-eslint/no-unused-vars
            state) {
                if (point && point.isNode) {
                    const { ...attrs } = Series.prototype.pointAttribs
                        .apply(this, arguments);
                    return attrs;
                }
                return super.pointAttribs.apply(this, arguments);
            }
            markerAttribs(point) {
                if (point.isNode) {
                    return super.markerAttribs.apply(this, arguments);
                }
                return {};
            }
        }
        /**
         *  Arc diagram series is a chart drawing style in which
         *  the vertices of the chart are positioned along a line
         *  on the Euclidean plane and the edges are drawn as a semicircle
         *  in one of the two half-planes delimited by the line,
         *  or as smooth curves formed by sequences of semicircles.
         *
         * @sample highcharts/demo/arc-diagram/
         *         Arc Diagram
         *
         * @extends      plotOptions.sankey
         * @since 10.0.0
         * @product      highcharts
         * @requires     modules/arc-diagram
         * @exclude      curveFactor, connectEnds, connectNulls, colorAxis, colorKey,
         *               dataSorting, dragDrop, getExtremesFromAll, nodeAlignment,
         *               nodePadding, centerInCategory, pointInterval,
         *               pointIntervalUnit, pointPlacement, pointStart,
         *               relativeXValue, softThreshold, stack, stacking, step,
         *               xAxis, yAxis
         * @optionparent plotOptions.arcdiagram
         */
        ArcDiagramSeries.defaultOptions = merge(SankeySeries.defaultOptions, {
            /**
             * The option to center links rather than position them one after
             * another
             *
             * @type    {boolean}
             * @since 10.0.0
             * @default false
             * @product highcharts
             */
            centeredLinks: false,
            /**
             * The radius of the link arc. If not set, series renders a semi-circle
             * between the nodes, except when overflowing the edge of the plot area,
             * in which case an arc touching the edge is rendered. If `linkRadius`
             * is set, an arc extending to the given value is rendered.
             *
             * @type    {number}
             * @since 10.0.0
             * @default undefined
             * @product highcharts
             * @apioption series.arcdiagram.linkRadius
             */
            /**
             * The offset of an arc diagram nodes column in relation to the
             * `plotArea`. The offset equal to 50% places nodes in the center of a
             * chart. By default the series is placed so that the biggest node is
             * touching the bottom border of the `plotArea`.
             *
             * @type    {string}
             * @since 10.0.0
             * @default '100%'
             * @product highcharts
             * @apioption series.arcdiagram.offset
             */
            offset: '100%',
            /**
             * The global link weight, in pixels. If not set, width is calculated
             * per link, depending on the weight value.
             *
             * @sample highcharts/series-arcdiagram/link-weight
             *         Link weight
             *
             * @type    {number}
             * @since 10.0.0
             * @default undefined
             * @product highcharts
             * @apioption series.arcdiagram.linkWeight
             */
            /**
             * Whether nodes with different values should have the same size. If set
             * to true, all nodes are calculated based on the `nodePadding` and
             * current `plotArea`. It is possible to override it using the
             * `marker.radius` option.
             *
             * @type    {boolean}
             * @since 10.0.0
             * @default false
             * @product highcharts
             */
            equalNodes: false,
            /**
             * Whether the series should be placed on the other side of the
             * `plotArea`.
             *
             * @type    {boolean}
             * @since 10.0.0
             * @default false
             * @product highcharts
             */
            reversed: false,
            /**
             * Options for the data labels appearing on top of the nodes and links.
             * For arc diagram charts, data labels are visible for the nodes by
             * default, but hidden for links. This is controlled by modifying the
             * `nodeFormat`, and the `format` that applies to links and is an empty
             * string by default.
             *
             * @declare Highcharts.SeriesArcDiagramDataLabelsOptionsObject
             *
             * @private
             */
            dataLabels: {
                /**
                 * Options for a _link_ label text which should follow link
                 * connection. Border and background are disabled for a label that
                 * follows a path.
                 *
                 * **Note:** Only SVG-based renderer supports this option. Setting
                 * `useHTML` to true will disable this option.
                 *
                 * @extends plotOptions.networkgraph.dataLabels.linkTextPath
                 * @since 10.0.0
                 */
                linkTextPath: {
                    /**
                     * @type    {Highcharts.SVGAttributes}
                     * @default {"startOffset":"25%"}
                     */
                    attributes: {
                        /**
                         * @ignore-option
                         */
                        startOffset: '25%'
                    }
                }
            },
            /**
             * @extends   plotOptions.series.marker
             * @excluding enabled, enabledThreshold, height, width
             */
            marker: {
                symbol: 'circle',
                fillOpacity: 1,
                lineWidth: 0,
                states: {}
            }
        });
        extend(ArcDiagramSeries.prototype, {
            orderNodes: false
        });
        ArcDiagramSeries.prototype.pointClass = ArcDiagramPoint;
        SeriesRegistry.registerSeriesType('arcdiagram', ArcDiagramSeries);
        /* *
         *
         *  Default Export
         *
         * */
        /* *
         *
         *  API Options
         *
         * */
        /**
         * An `arcdiagram` series. If the [type](#series.arcdiagram.type)
         * option is not specified, it is inherited from [chart.type](#chart.type).
         *
         * @extends   series,plotOptions.arcdiagram
         * @exclude   dataSorting, boostThreshold, boostBlending, curveFactor,
         *            connectEnds, connectNulls, colorAxis, colorKey, dataSorting,
         *            dragDrop, getExtremesFromAll, nodePadding, centerInCategory,
         *            pointInterval, pointIntervalUnit, pointPlacement,
         *            pointStart, relativeXValue, softThreshold, stack,
         *            stacking, step, xAxis, yAxis
         * @product   highcharts
         * @requires  modules/sankey
         * @requires  modules/arc-diagram
         * @apioption series.arcdiagram
         */
        /**
         * @extends   plotOptions.series.marker
         * @excluding enabled, enabledThreshold, height, radius, width
         * @apioption series.arcdiagram.marker
         */
        /**
         * @type      {Highcharts.SeriesArcDiagramDataLabelsOptionsObject|Array<Highcharts.SeriesArcDiagramDataLabelsOptionsObject>}
         * @product   highcharts
         * @apioption series.arcdiagram.data.dataLabels
         */
        /**
         * A collection of options for the individual nodes. The nodes in an arc diagram
         * are auto-generated instances of `Highcharts.Point`, but options can be
         * applied here and linked by the `id`.
         *
         * @extends   series.sankey.nodes
         * @type      {Array<*>}
         * @product   highcharts
         * @excluding column, level
         * @apioption series.arcdiagram.nodes
         */
        /**
         * Individual data label for each node. The options are the same as the ones for
         * [series.arcdiagram.dataLabels](#series.arcdiagram.dataLabels).
         *
         * @type
         * {Highcharts.SeriesArcDiagramDataLabelsOptionsObject|Array<Highcharts.SeriesArcDiagramDataLabelsOptionsObject>}
         *
         * @apioption series.arcdiagram.nodes.dataLabels
         */
        /**
         * Individual data label for each node. The options are the same as the ones for
         * [series.arcdiagram.dataLabels](#series.arcdiagram.dataLabels).
         *
         * @type
         * {Highcharts.SeriesArcDiagramDataLabelsOptionsObject|Array<Highcharts.SeriesArcDiagramDataLabelsOptionsObject>}
         *
         */
        /**
         * An array of data points for the series. For the `arcdiagram` series type,
         * points can be given in the following way:
         *
         * An array of objects with named values. The following snippet shows only a few
         * settings, see the complete options set below. If the total number of data
         * points exceeds the series' [turboThreshold](#series.area.turboThreshold),
         * this option is not available.
         *
         *  ```js
         *     data: [{
         *         from: 'Category1',
         *         to: 'Category2',
         *         weight: 2
         *     }, {
         *         from: 'Category1',
         *         to: 'Category3',
         *         weight: 5
         *     }]
         *  ```
         *
         * @type      {Array<*>}
         * @extends   series.sankey.data
         * @product   highcharts
         * @excluding outgoing, dataLabels
         * @apioption series.arcdiagram.data
         */
        ''; // adds doclets above to the transpiled file

        return ArcDiagramSeries;
    });
    _registerModule(_modules, 'masters/modules/arc-diagram.src.js', [_modules['Core/Globals.js']], function (Highcharts) {


        return Highcharts;
    });
}));