function _assert_this_initialized(self) {
    if (self === void 0) {
        throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
    }
    return self;
}
function _call_super(_this, derived, args) {
    derived = _get_prototype_of(derived);
    return _possible_constructor_return(_this, _is_native_reflect_construct() ? Reflect.construct(derived, args || [], _get_prototype_of(_this).constructor) : derived.apply(_this, args));
}
function _class_call_check(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
        throw new TypeError("Cannot call a class as a function");
    }
}
function _defineProperties(target, props) {
    for(var i = 0; i < props.length; i++){
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
    }
}
function _create_class(Constructor, protoProps, staticProps) {
    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
    if (staticProps) _defineProperties(Constructor, staticProps);
    return Constructor;
}
function _define_property(obj, key, value) {
    if (key in obj) {
        Object.defineProperty(obj, key, {
            value: value,
            enumerable: true,
            configurable: true,
            writable: true
        });
    } else {
        obj[key] = value;
    }
    return obj;
}
function _get_prototype_of(o) {
    _get_prototype_of = Object.setPrototypeOf ? Object.getPrototypeOf : function getPrototypeOf(o) {
        return o.__proto__ || Object.getPrototypeOf(o);
    };
    return _get_prototype_of(o);
}
function _inherits(subClass, superClass) {
    if (typeof superClass !== "function" && superClass !== null) {
        throw new TypeError("Super expression must either be null or a function");
    }
    subClass.prototype = Object.create(superClass && superClass.prototype, {
        constructor: {
            value: subClass,
            writable: true,
            configurable: true
        }
    });
    if (superClass) _set_prototype_of(subClass, superClass);
}
function _instanceof(left, right) {
    "@swc/helpers - instanceof";
    if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
        return !!right[Symbol.hasInstance](left);
    } else {
        return left instanceof right;
    }
}
function _possible_constructor_return(self, call) {
    if (call && (_type_of(call) === "object" || typeof call === "function")) {
        return call;
    }
    return _assert_this_initialized(self);
}
function _set_prototype_of(o, p) {
    _set_prototype_of = Object.setPrototypeOf || function setPrototypeOf(o, p) {
        o.__proto__ = p;
        return o;
    };
    return _set_prototype_of(o, p);
}
function _type_of(obj) {
    "@swc/helpers - typeof";
    return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
}
function _is_native_reflect_construct() {
    try {
        var result = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {}));
    } catch (_) {}
    return (_is_native_reflect_construct = function() {
        return !!result;
    })();
}
import { min } from "d3-array";
import { color } from "d3-color";
import { pointer, select, selectAll } from "d3-selection";
import * as paths from "d3-shape";
import { transition } from "d3-transition";
import textures from "textures";
import { colorContrast } from "@d3plus/color";
import { unique } from "@d3plus/data";
import { assign, attrize, elem, isObject } from "@d3plus/dom";
import { pointDistance } from "@d3plus/math";
import { strip } from "@d3plus/text";
import { TextBox } from "../components/index.js";
import { accessor, BaseClass, configPrep, constant } from "../utils/index.js";
/**
 * @param {*} nodeList
 * @param {*} classNames
 * @private
*/ function findLastIndexWithClass(nodeList, classNames) {
    for(var x = 0; x < classNames.length; x++){
        var className = classNames[x];
        for(var i = nodeList.length - 1; i >= 0; i--){
            // Iterate backwards
            if (nodeList[i].classList.contains(className)) {
                // Check for the class
                return i; // Return the index if found
            }
        }
    }
    return -1; // Return -1 if no element is found with the class
}
import Image from "./Image.js";
var Shape = /*#__PURE__*/ function(BaseClass) {
    "use strict";
    _inherits(Shape, BaseClass);
    function Shape() {
        var tagName = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : "g";
        _class_call_check(this, Shape);
        var _this;
        _this = _call_super(this, Shape), _define_property(_this, "_activeOpacity", void 0), _define_property(_this, "_activeStyle", void 0), _define_property(_this, "_ariaLabel", void 0), _define_property(_this, "_backgroundImage", void 0), _define_property(_this, "_backgroundImageClass", void 0), _define_property(_this, "_data", void 0), _define_property(_this, "_duration", void 0), _define_property(_this, "_fill", void 0), _define_property(_this, "_fillOpacity", void 0), _define_property(_this, "_hoverOpacity", void 0), _define_property(_this, "_hoverStyle", void 0), _define_property(_this, "_id", void 0), _define_property(_this, "_label", void 0), _define_property(_this, "_labelClass", void 0), _define_property(_this, "_labelConfig", void 0), _define_property(_this, "_labelBounds", void 0), _define_property(_this, "_name", void 0), _define_property(_this, "_opacity", void 0), _define_property(_this, "_pointerEvents", void 0), _define_property(_this, "_role", void 0), _define_property(_this, "_rotate", void 0), _define_property(_this, "_rx", void 0), _define_property(_this, "_ry", void 0), _define_property(_this, "_scale", void 0), _define_property(_this, "_shapeRendering", void 0), _define_property(_this, "_stroke", void 0), _define_property(_this, "_strokeDasharray", void 0), _define_property(_this, "_strokeLinecap", void 0), _define_property(_this, "_strokeOpacity", void 0), _define_property(_this, "_strokeWidth", void 0), _define_property(_this, "_tagName", void 0), _define_property(_this, "_textAnchor", void 0), _define_property(_this, "_texture", void 0), _define_property(_this, "_textureDefault", void 0), _define_property(_this, "_textureDefs", void 0), _define_property(_this, "_vectorEffect", void 0), _define_property(_this, "_verticalAlign", void 0), _define_property(_this, "_x", void 0), _define_property(_this, "_y", void 0), _define_property(_this, "_select", void 0), _define_property(_this, "_transition", void 0), _define_property(_this, "_sort", void 0), _define_property(_this, "_group", void 0), _define_property(_this, "_update", void 0), _define_property(_this, "_enter", void 0), _define_property(_this, "_exit", void 0), _define_property(_this, "_hoverGroup", void 0), _define_property(_this, "_activeGroup", void 0), _define_property(_this, "_hitArea", void 0), _define_property(_this, "_active", void 0), _define_property(_this, "_hover", void 0), _define_property(_this, "_discrete", void 0), _define_property(_this, "_path", void 0), _define_property(_this, "_defined", void 0), _define_property(_this, "_curve", void 0);
        _this._activeOpacity = 0.25;
        _this._activeStyle = {
            stroke: function stroke(d, i) {
                var c = _this._fill(d, i);
                if ([
                    "transparent",
                    "none"
                ].includes(c)) c = _this._stroke(d, i);
                return color(c).darker(1);
            },
            "stroke-width": function(d, i) {
                var s = _this._strokeWidth(d, i) || 1;
                return s * 3;
            }
        };
        _this._ariaLabel = constant("");
        _this._backgroundImage = constant(false);
        _this._backgroundImageClass = new Image();
        _this._data = [];
        _this._duration = 600;
        _this._fill = constant("black");
        _this._fillOpacity = constant(1);
        _this._hoverOpacity = 0.5;
        _this._hoverStyle = {
            stroke: function stroke(d, i) {
                var c = _this._fill(d, i);
                if ([
                    "transparent",
                    "none"
                ].includes(c)) c = _this._stroke(d, i);
                return color(c).darker(0.5);
            },
            "stroke-width": function(d, i) {
                var s = _this._strokeWidth(d, i) || 1;
                return s * 2;
            }
        };
        _this._id = function(d, i) {
            return d.id !== void 0 ? d.id : i;
        };
        _this._label = constant(false);
        _this._labelClass = new TextBox();
        _this._labelConfig = {
            fontColor: function fontColor(d, i) {
                return colorContrast(_this._fill(d, i));
            },
            fontSize: 12,
            padding: 5
        };
        _this._name = "Shape";
        _this._opacity = constant(1);
        _this._pointerEvents = constant("visiblePainted");
        _this._role = constant("presentation");
        _this._rotate = constant(0);
        _this._rx = constant(0);
        _this._ry = constant(0);
        _this._scale = constant(1);
        _this._shapeRendering = constant("geometricPrecision");
        _this._stroke = function(d, i) {
            return color(_this._fill(d, i)).darker(1).formatHex();
        };
        _this._strokeDasharray = constant("0");
        _this._strokeLinecap = constant("butt");
        _this._strokeOpacity = constant(1);
        _this._strokeWidth = constant(0);
        _this._tagName = tagName;
        _this._textAnchor = constant("start");
        _this._texture = constant(false);
        _this._textureDefault = {};
        _this._textureDefs = {};
        _this._vectorEffect = constant("non-scaling-stroke");
        _this._verticalAlign = constant("top");
        _this._x = accessor("x", 0);
        _this._y = accessor("y", 0);
        return _this;
    }
    _create_class(Shape, [
        {
            /**
      Given a specific data point and index, returns the aesthetic properties of the shape.
      @param data point*
      @param index @private
*/ key: "_aes",
            value: function _aes(_d, _i) {
                return {};
            }
        },
        {
            /**
      Adds event listeners to each shape group or hit area.
      @private
*/ key: "_applyEvents",
            value: function _applyEvents(handler) {
                var _loop = function(e) {
                    handler.on(events[e], function(event, d) {
                        var i = 0;
                        if (!_this._on[events[e]]) return;
                        if (d.i !== void 0) i = d.i;
                        if (d.nested && d.values) {
                            var calcPoint = function calcPoint(d, i) {
                                if (_this._discrete === "x") return [
                                    _this._x(d, i),
                                    cursor[1]
                                ];
                                else if (_this._discrete === "y") return [
                                    cursor[0],
                                    _this._y(d, i)
                                ];
                                else return [
                                    _this._x(d, i),
                                    _this._y(d, i)
                                ];
                            };
                            var cursor = pointer(event, _this._select.node()), values = d.values.map(function(d) {
                                return pointDistance(cursor, calcPoint(d, i));
                            });
                            i = values.indexOf(min(values));
                            d = d.values[i];
                        }
                        _this._on[events[e]].bind(_this)(d, i, undefined, event);
                    });
                };
                var _this = this;
                var events = Object.keys(this._on);
                for(var e = 0; e < events.length; e++)_loop(e);
            }
        },
        {
            /**
      Provides the updated styling to the given shape elements.

      @private
*/ key: "_updateStyle",
            value: function _updateStyle(elem, style) {
                var that = this;
                if (elem.size() && elem.node().tagName === "g") elem = elem.selectAll("*");
                /**
        Determines whether a shape is a nested collection of data points, and uses the appropriate data and index for the given function context.
        @param d data point
        @param i index
        @private
*/ function styleLogic(d, i) {
                    return typeof this !== "function" ? this : d.nested && d.key && d.values ? this(d.values[0], that._data.indexOf(d.values[0])) : this(d, i);
                }
                var styleObject = {};
                for(var key in style){
                    if (({}).hasOwnProperty.call(style, key)) {
                        styleObject[key] = styleLogic.bind(style[key]);
                    }
                }
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                elem.transition().duration(0).call(attrize, styleObject);
            }
        },
        {
            /**
      Provides the default styling to the shape elements.
      @param elem @private
*/ key: "_applyStyle",
            value: function _applyStyle(elem) {
                var _this = this;
                var that = this;
                if (elem.size() && elem.node().tagName === "g") elem = elem.selectAll("*");
                /**
        Determines whether a shape is a nested collection of data points, and uses the appropriate data and index for the given function context.
        @param d data point
        @param i index
        @private
*/ function styleLogic(d, i) {
                    return typeof this !== "function" ? this : d.nested && d.key && d.values ? this(d.values[0], that._data.indexOf(d.values[0])) : this(d, i);
                }
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                elem.attr("fill", function(d, i) {
                    var texture = _this._getTextureKey.bind(_this)(d, i);
                    return texture ? _this._textureDefs[texture].url() : styleLogic.bind(_this._fill)(d, i);
                }).attr("fill-opacity", styleLogic.bind(this._fillOpacity)).attr("rx", styleLogic.bind(this._rx)).attr("ry", styleLogic.bind(this._ry)).attr("stroke", styleLogic.bind(this._stroke)).attr("stroke-dasharray", styleLogic.bind(this._strokeDasharray)).attr("stroke-linecap", styleLogic.bind(this._strokeLinecap)).attr("stroke-opacity", styleLogic.bind(this._strokeOpacity)).attr("stroke-width", styleLogic.bind(this._strokeWidth)).attr("vector-effect", styleLogic.bind(this._vectorEffect));
            }
        },
        {
            /**
      Calculates the transform for the group elements.
      @param elem @private
*/ key: "_applyTransform",
            value: function _applyTransform(elem) {
                var _this = this;
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                elem.attr("transform", function(d, i) {
                    return "\n        translate(".concat(d.__d3plusShape__ ? d.translate ? d.translate : "".concat(_this._x(d.data, d.i), ",").concat(_this._y(d.data, d.i)) : "".concat(_this._x(d, i), ",").concat(_this._y(d, i)), ")\n        scale(").concat(d.__d3plusShape__ ? d.scale || _this._scale(d.data, d.i) : _this._scale(d, i), ")\n        rotate(").concat(d.__d3plusShape__ ? d.rotate ? d.rotate : _this._rotate(d.data || d, d.i) : _this._rotate(d.data || d, d.i), ")");
                });
            }
        },
        {
            /**
      Returns a full JSON string of the texture config for a given data point.

      @private
*/ key: "_getTextureKey",
            value: function _getTextureKey(d, i) {
                var _this = this;
                var textureVal = this._texture(d, i);
                if (!textureVal) return false;
                /**
        Determines whether a shape is a nested collection of data points, and uses the appropriate data and index for the given function context.
        @private
*/ var styleLogic = function styleLogic(_) {
                    return typeof _ !== "function" ? _ : d.nested && d.key && d.values ? _(d.values[0], _this._data.indexOf(d.values[0])) : _(d, i);
                };
                var fallback = this._textureDefault;
                var texture;
                if (!isObject(textureVal)) texture = {
                    texture: textureVal
                };
                else texture = textureVal;
                if (!texture.background) texture.background = styleLogic(this._fill);
                if (!texture.stroke && !fallback.stroke) texture.stroke = styleLogic(this._stroke);
                var pathNames = [
                    "squares",
                    "nylon",
                    "waves",
                    "woven",
                    "crosses",
                    "caps",
                    "hexagons"
                ];
                if (pathNames.includes(texture.texture) || typeof texture.texture === "function") {
                    texture.d = texture.texture;
                    texture.texture = "paths";
                } else if (texture.texture === "grid") {
                    if (!texture.orientation && !fallback.orientation) texture.orientation = [
                        "vertical",
                        "horizontal"
                    ];
                    texture.texture = "lines";
                }
                if (!texture.fill && texture.texture !== "paths") texture.fill = texture.stroke;
                var retObj = assign({}, fallback, texture);
                if (typeof retObj.d === "function") {
                    retObj.d = retObj.d(retObj.size || 20);
                }
                return JSON.stringify(retObj);
            }
        },
        {
            /**
      Checks for nested data and uses the appropriate variables for accessor functions.
      @param elem @private
*/ key: "_nestWrapper",
            value: function _nestWrapper(method) {
                return function(d, i) {
                    return method(d.__d3plusShape__ ? d.data : d, d.__d3plusShape__ ? d.i : i);
                };
            }
        },
        {
            /**
      Modifies existing shapes to show active status.
      @private
*/ key: "_renderActive",
            value: function _renderActive() {
                var that = this;
                this._group.selectAll(".d3plus-Shape, .d3plus-Image, .d3plus-textBox")// eslint-disable-next-line @typescript-eslint/no-explicit-any
                .each(function(_d, i) {
                    var d = _d || {};
                    if (!d.parentNode) d.parentNode = this.parentNode;
                    var parent = d.parentNode;
                    if (select(this).classed("d3plus-textBox")) d = d.data;
                    if (d.__d3plusShape__ || d.__d3plus__) {
                        while(d && (d.__d3plusShape__ || d.__d3plus__)){
                            i = d.i;
                            d = d.data;
                        }
                    } else i = that._data.indexOf(d);
                    var group = !that._active || typeof that._active !== "function" || !that._active(d, i) ? parent : that._activeGroup.node();
                    if (group !== this.parentNode) {
                        group.appendChild(this);
                        if (this.className.baseVal.includes("d3plus-Shape")) {
                            if (parent === group) // eslint-disable-next-line @typescript-eslint/no-explicit-any
                            select(this).call(that._applyStyle.bind(that));
                            else select(this).call(that._updateStyle.bind(that, select(this), that._activeStyle));
                        }
                    }
                });
                // this._renderImage();
                // this._renderLabels();
                this._group.selectAll("g.d3plus-".concat(this._name, "-shape, g.d3plus-").concat(this._name, "-image, g.d3plus-").concat(this._name, "-text")).attr("opacity", this._hover ? this._hoverOpacity : this._active ? this._activeOpacity : 1);
            }
        },
        {
            /**
      Modifies existing shapes to show hover status.
      @private
*/ key: "_renderHover",
            value: function _renderHover() {
                var that = this;
                this._group.selectAll("g.d3plus-".concat(this._name, "-shape, g.d3plus-").concat(this._name, "-image, g.d3plus-").concat(this._name, "-text, g.d3plus-").concat(this._name, "-hover")).selectAll(".d3plus-Shape, .d3plus-Image, .d3plus-textBox")// eslint-disable-next-line @typescript-eslint/no-explicit-any
                .each(function(_d, i) {
                    var d = _d || {};
                    if (!d.parentNode) d.parentNode = this.parentNode;
                    var parent = d.parentNode;
                    var d3plusType = select(this).classed("d3plus-textBox") ? "textBox" : select(this).classed("d3plus-Image") ? "Image" : "Shape";
                    if (d3plusType === "textBox") d = d.data;
                    if (d.__d3plusShape__ || d.__d3plus__) {
                        while(d && (d.__d3plusShape__ || d.__d3plus__)){
                            i = d.i;
                            d = d.data;
                        }
                    } else i = that._data.indexOf(d);
                    var notHovering = !that._hover || typeof that._hover !== "function" || !that._hover(d, i);
                    var group = notHovering ? parent : that._hoverGroup.node();
                    if (group !== this.parentNode) {
                        var afterIndex = d3plusType === "textBox" ? findLastIndexWithClass(group.childNodes, [
                            "d3plus-Image",
                            "d3plus-Shape"
                        ]) : d3plusType === "Image" ? findLastIndexWithClass(group.childNodes, [
                            "d3plus-Shape"
                        ]) : -1;
                        if (notHovering) group.appendChild(this);
                        else if (afterIndex === -1) group.prepend(this);
                        else group.childNodes[afterIndex].after(this);
                    }
                    if (this.className.baseVal.includes("d3plus-Shape")) {
                        if (parent === group) // eslint-disable-next-line @typescript-eslint/no-explicit-any
                        select(this).call(that._applyStyle.bind(that));
                        else select(this).call(that._updateStyle.bind(that, select(this), that._hoverStyle));
                    }
                });
                // this._renderImage();
                // this._renderLabels();
                this._group.selectAll("g.d3plus-".concat(this._name, "-shape, g.d3plus-").concat(this._name, "-image, g.d3plus-").concat(this._name, "-text")).attr("opacity", this._hover ? this._hoverOpacity : this._active ? this._activeOpacity : 1);
            }
        },
        {
            /**
      Adds background image to each shape group.
      @private
*/ key: "_renderImage",
            value: function _renderImage() {
                var _this = this;
                var imageData = [];
                this._update.merge(this._enter).data().forEach(function(datum, i) {
                    var aes = _this._aes(datum, i);
                    if (aes.r || aes.width && aes.height) {
                        var d = datum;
                        if (datum.nested && datum.key && datum.values) {
                            d = datum.values[0];
                            i = _this._data.indexOf(d);
                        }
                        var height = aes.r ? aes.r * 2 : aes.height, url = _this._backgroundImage(d, i), width = aes.r ? aes.r * 2 : aes.width;
                        if (url) {
                            var x = d.__d3plusShape__ ? d.translate ? d.translate[0] : _this._x(d.data, d.i) : _this._x(d, i), y = d.__d3plusShape__ ? d.translate ? d.translate[1] : _this._y(d.data, d.i) : _this._y(d, i);
                            if (aes.x) x += aes.x;
                            if (aes.y) y += aes.y;
                            if (d.__d3plusShape__) {
                                d = d.data;
                                i = d.i;
                            }
                            imageData.push({
                                __d3plus__: true,
                                data: d,
                                height: height,
                                i: i,
                                id: _this._id(d, i),
                                url: url,
                                width: width,
                                x: x + -width / 2,
                                y: y + -height / 2
                            });
                        }
                    }
                });
                this._backgroundImageClass.data(imageData).duration(this._duration).opacity(this._nestWrapper(this._opacity)).pointerEvents("none").select(elem("g.d3plus-".concat(this._name, "-image"), {
                    parent: this._group,
                    update: {
                        opacity: this._active ? this._activeOpacity : 1
                    }
                }).node()).render();
            }
        },
        {
            /**
      Adds labels to each shape group.
      @private
*/ key: "_renderLabels",
            value: function _renderLabels() {
                var _this = this;
                var labelData = [];
                this._update.merge(this._enter).data().forEach(function(datum, i) {
                    var d = datum;
                    if (datum.nested && datum.key && datum.values) {
                        d = datum.values[0];
                        i = _this._data.indexOf(d);
                    }
                    var labels = _this._label(d, i);
                    if (_this._labelBounds && labels !== false && labels !== undefined && labels !== null) {
                        var bounds = _this._labelBounds.bind(_this)(d, i, _this._aes(datum, i));
                        if (bounds) {
                            if (labels.constructor !== Array) labels = [
                                labels
                            ];
                            var x = d.__d3plusShape__ ? d.translate ? d.translate[0] : _this._x(d.data, d.i) : _this._x(d, i), y = d.__d3plusShape__ ? d.translate ? d.translate[1] : _this._y(d.data, d.i) : _this._y(d, i);
                            if (d.__d3plusShape__) {
                                d = d.data;
                                i = d.i;
                            }
                            for(var l = 0; l < labels.length; l++){
                                var b = bounds.constructor === Array ? bounds[l] : Object.assign({}, bounds);
                                var rotate = _this._rotate(d, i);
                                var labelConfig = d.labelConfig;
                                var r = labelConfig && labelConfig.rotate ? labelConfig.rotate : bounds.angle !== undefined ? bounds.angle : 0;
                                r += rotate;
                                var rotateAnchor = rotate !== 0 ? [
                                    b.x * -1 || 0,
                                    b.y * -1 || 0
                                ] : [
                                    b.width / 2,
                                    b.height / 2
                                ];
                                labelData.push({
                                    __d3plus__: true,
                                    data: d,
                                    height: b.height,
                                    l: l,
                                    id: "".concat(_this._id(d, i), "_").concat(l),
                                    r: r,
                                    rotateAnchor: rotateAnchor,
                                    text: labels[l],
                                    width: b.width,
                                    x: x + b.x,
                                    y: y + b.y
                                });
                            }
                        }
                    }
                });
                this._labelClass.data(labelData).duration(this._duration).fontOpacity(this._nestWrapper(this._opacity)).pointerEvents("none").rotate(function(d) {
                    return d.__d3plus__ ? d.r : d.data.r;
                }).rotateAnchor(function(d) {
                    return d.__d3plus__ ? d.rotateAnchor : d.data.rotateAnchor;
                }).select(elem("g.d3plus-".concat(this._name, "-text"), {
                    parent: this._group,
                    update: {
                        opacity: this._active ? this._activeOpacity : 1
                    }
                }).node())// eslint-disable-next-line @typescript-eslint/no-explicit-any
                .config(configPrep.bind(this)(this._labelConfig)).render();
            }
        },
        {
            /**
      Renders the current Shape to the page. If a *callback* is specified, it will be called once the shapes are done drawing.
    @param callback Optional callback invoked after rendering completes.
*/ key: "render",
            value: function render(callback) {
                var _this = this;
                if (this._select === void 0) {
                    this.select(select("body").append("svg").style("width", "".concat(window.innerWidth, "px")).style("height", "".concat(window.innerHeight, "px")).style("display", "block").node());
                }
                this._transition = transition(this._uuid).duration(this._duration);
                var data = this._data, key = this._id;
                if (this._dataFilter) {
                    data = this._dataFilter(data);
                    if (data.key) key = data.key;
                }
                if (this._sort) {
                    data = data.sort(function(a, b) {
                        while(a.__d3plusShape__ || a.__d3plus__)a = a.data;
                        while(b.__d3plusShape__ || b.__d3plus__)b = b.data;
                        return _this._sort(a, b);
                    });
                }
                var textureSet = unique(data.map(this._getTextureKey.bind(this))).filter(Boolean);
                var existingTextureDefs = Object.keys(this._textureDefs);
                existingTextureDefs.forEach(function(key) {
                    if (!textureSet.includes(key)) {
                        select(// eslint-disable-next-line @typescript-eslint/no-explicit-any
                        _this._select.select("pattern#".concat(_this._textureDefs[key].id())).node().parentNode).remove();
                        delete _this._textureDefs[key];
                    }
                });
                textureSet.forEach(function(key) {
                    if (!existingTextureDefs.includes(key)) {
                        var _loop = function(k) {
                            if (({}).hasOwnProperty.call(t, k) && k in t) {
                                if (k === "d" && typeof k === "function") t[k](function() {
                                    return config[k];
                                });
                                else _instanceof(config[k], Array) ? t[k].apply(null, config[k]) : t[k](config[k]);
                            }
                        };
                        var config = JSON.parse(key);
                        var textureClass = config.texture;
                        delete config.texture;
                        // eslint-disable-next-line @typescript-eslint/no-explicit-any
                        var t = textures[textureClass]();
                        for(var k in config)_loop(k);
                        _this._select.call(t);
                        _this._textureDefs[key] = t;
                    }
                });
                selectAll("g.d3plus-".concat(this._name, "-hover > *, g.d3plus-").concat(this._name, "-active > *")).each(function(d) {
                    var dp = d;
                    if (dp && dp.parentNode) dp.parentNode.appendChild(this);
                    else this.parentNode.removeChild(this);
                });
                // Makes the update state of the group selection accessible.
                this._group = elem("g.d3plus-".concat(this._name, "-group"), {
                    parent: this._select
                });
                var update = this._update = elem("g.d3plus-".concat(this._name, "-shape"), {
                    parent: this._group,
                    update: {
                        opacity: this._active ? this._activeOpacity : 1
                    }
                }).selectAll(".d3plus-".concat(this._name)).data(data, key);
                // Orders and transforms the updating Shapes.
                update.order();
                if (this._duration) {
                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
                    update.transition(this._transition).call(this._applyTransform.bind(this));
                } else {
                    update.call(this._applyTransform.bind(this));
                }
                // Makes the enter state of the group selection accessible.
                var enter = this._enter = update.enter().append(this._tagName).attr("class", function(d, i) {
                    return "d3plus-Shape d3plus-".concat(_this._name, " d3plus-id-").concat(strip(_this._nestWrapper(_this._id)(d, i)));
                }).call(this._applyTransform.bind(this)).attr("aria-label", this._ariaLabel).attr("role", this._role).attr("opacity", this._nestWrapper(this._opacity));
                var enterUpdate = enter.merge(update);
                var enterUpdateRender = enterUpdate.attr("shape-rendering", this._nestWrapper(this._shapeRendering));
                if (this._duration) {
                    enterUpdateRender = enterUpdateRender.attr("pointer-events", "none").transition(this._transition).transition().delay(100).attr("pointer-events", this._pointerEvents);
                }
                enterUpdateRender.attr("opacity", this._nestWrapper(this._opacity));
                // Makes the exit state of the group selection accessible.
                var exit = this._exit = update.exit();
                if (this._duration) exit.transition().delay(this._duration).remove();
                else exit.remove();
                this._renderImage();
                this._renderLabels();
                this._hoverGroup = elem("g.d3plus-".concat(this._name, "-hover"), {
                    parent: this._group
                });
                this._activeGroup = elem("g.d3plus-".concat(this._name, "-active"), {
                    parent: this._group
                });
                var hitAreas = this._group.selectAll(".d3plus-HitArea").data(this._hitArea && Object.keys(this._on).length ? data : [], key);
                hitAreas.order().call(this._applyTransform.bind(this));
                var isLine = this._name === "Line";
                if (isLine) {
                    var curve = this._curve.bind(this)(this.config());
                    isLine && // eslint-disable-next-line @typescript-eslint/no-explicit-any
                    this._path.curve(// eslint-disable-next-line @typescript-eslint/no-explicit-any
                    paths["curve".concat(curve.charAt(0).toUpperCase()).concat(curve.slice(1))]).defined(this._defined).x(this._x).y(this._y);
                }
                var hitEnter = hitAreas.enter().append(isLine ? "path" : "rect").attr("class", function(d, i) {
                    return "d3plus-HitArea d3plus-id-".concat(strip(_this._nestWrapper(_this._id)(d, i)));
                }).attr("fill", "black").attr("stroke", "black").attr("pointer-events", "painted").attr("opacity", 0).call(this._applyTransform.bind(this));
                var that = this;
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                var hitUpdates = hitAreas.merge(hitEnter).each(function(d) {
                    var i = that._data.indexOf(d);
                    var h = that._hitArea(d, i, that._aes(d, i));
                    return h && !(that._name === "Line" && parseFloat(that._strokeWidth(d, i)) > 10) ? select(this).call(attrize, h) : select(this).remove();
                });
                hitAreas.exit().remove();
                this._applyEvents(this._hitArea ? hitUpdates : enterUpdate);
                setTimeout(function() {
                    if (_this._active) _this._renderActive();
                    else if (_this._hover) _this._renderHover();
                    if (callback) callback();
                }, this._duration + 100);
                return this;
            }
        },
        {
            key: "active",
            value: function active(_) {
                if (!arguments.length || _ === undefined) return this._active;
                this._active = _;
                if (this._group) {
                    // this._renderImage();
                    // this._renderLabels();
                    this._renderActive();
                }
                return this;
            }
        },
        {
            key: "activeOpacity",
            value: function activeOpacity(_) {
                return arguments.length ? (this._activeOpacity = _, this) : this._activeOpacity;
            }
        },
        {
            key: "activeStyle",
            value: function activeStyle(_) {
                return arguments.length ? (this._activeStyle = assign({}, this._activeStyle, _), this) : this._activeStyle;
            }
        },
        {
            key: "ariaLabel",
            value: function ariaLabel(_) {
                return _ !== undefined ? (this._ariaLabel = typeof _ === "function" ? _ : constant(_), this) : this._ariaLabel;
            }
        },
        {
            key: "backgroundImage",
            value: function backgroundImage(_) {
                return arguments.length ? (this._backgroundImage = typeof _ === "function" ? _ : constant(_), this) : this._backgroundImage;
            }
        },
        {
            key: "data",
            value: function data(_) {
                return arguments.length ? (this._data = _, this) : this._data;
            }
        },
        {
            key: "discrete",
            value: function discrete(_) {
                return arguments.length ? (this._discrete = _, this) : this._discrete;
            }
        },
        {
            key: "duration",
            value: function duration(_) {
                return arguments.length ? (this._duration = _, this) : this._duration;
            }
        },
        {
            key: "fill",
            value: function fill(_) {
                return arguments.length ? (this._fill = typeof _ === "function" ? _ : constant(_), this) : this._fill;
            }
        },
        {
            key: "fillOpacity",
            value: function fillOpacity(_) {
                return arguments.length ? (this._fillOpacity = typeof _ === "function" ? _ : constant(_), this) : this._fillOpacity;
            }
        },
        {
            key: "hover",
            value: function hover(_) {
                if (!arguments.length || _ === void 0) return this._hover;
                this._hover = _;
                if (this._group) {
                    // this._renderImage();
                    // this._renderLabels();
                    this._renderHover();
                }
                return this;
            }
        },
        {
            key: "hoverStyle",
            value: function hoverStyle(_) {
                return arguments.length ? (this._hoverStyle = assign({}, this._hoverStyle, _), this) : this._hoverStyle;
            }
        },
        {
            key: "hoverOpacity",
            value: function hoverOpacity(_) {
                return arguments.length ? (this._hoverOpacity = _, this) : this._hoverOpacity;
            }
        },
        {
            key: "hitArea",
            value: function hitArea(_) {
                return arguments.length ? (this._hitArea = typeof _ === "function" ? _ : constant(_), this) : this._hitArea;
            }
        },
        {
            key: "id",
            value: function id(_) {
                return arguments.length ? (this._id = _, this) : this._id;
            }
        },
        {
            key: "label",
            value: function label(_) {
                return arguments.length ? (this._label = typeof _ === "function" ? _ : constant(_), this) : this._label;
            }
        },
        {
            key: "labelBounds",
            value: function labelBounds(_) {
                return arguments.length ? (this._labelBounds = typeof _ === "function" ? _ : constant(_), this) : this._labelBounds;
            }
        },
        {
            key: "labelConfig",
            value: function labelConfig(_) {
                return arguments.length ? (this._labelConfig = assign(this._labelConfig, _), this) : this._labelConfig;
            }
        },
        {
            key: "opacity",
            value: function opacity(_) {
                return arguments.length ? (this._opacity = typeof _ === "function" ? _ : constant(_), this) : this._opacity;
            }
        },
        {
            key: "pointerEvents",
            value: function pointerEvents(_) {
                return arguments.length ? (this._pointerEvents = typeof _ === "function" ? _ : constant(_), this) : this._pointerEvents;
            }
        },
        {
            key: "role",
            value: function role(_) {
                return _ !== undefined ? (this._role = typeof _ === "function" ? _ : constant(_), this) : this._role;
            }
        },
        {
            key: "rotate",
            value: function rotate(_) {
                return arguments.length ? (this._rotate = typeof _ === "function" ? _ : constant(_), this) : this._rotate;
            }
        },
        {
            key: "rx",
            value: function rx(_) {
                return arguments.length ? (this._rx = typeof _ === "function" ? _ : constant(_), this) : this._rx;
            }
        },
        {
            key: "ry",
            value: function ry(_) {
                return arguments.length ? (this._ry = typeof _ === "function" ? _ : constant(_), this) : this._ry;
            }
        },
        {
            key: "scale",
            value: function scale(_) {
                return arguments.length ? (this._scale = typeof _ === "function" ? _ : constant(_), this) : this._scale;
            }
        },
        {
            key: "select",
            value: function select1(_) {
                return arguments.length ? (this._select = select(_), this) : this._select;
            }
        },
        {
            key: "shapeRendering",
            value: function shapeRendering(_) {
                return arguments.length ? (this._shapeRendering = typeof _ === "function" ? _ : constant(_), this) : this._shapeRendering;
            }
        },
        {
            key: "sort",
            value: function sort(_) {
                return arguments.length ? (this._sort = _ !== null && _ !== void 0 ? _ : null, this) : this._sort;
            }
        },
        {
            key: "stroke",
            value: function stroke(_) {
                return arguments.length ? (this._stroke = typeof _ === "function" ? _ : constant(_), this) : this._stroke;
            }
        },
        {
            key: "strokeDasharray",
            value: function strokeDasharray(_) {
                return arguments.length ? (this._strokeDasharray = typeof _ === "function" ? _ : constant(_), this) : this._strokeDasharray;
            }
        },
        {
            key: "strokeLinecap",
            value: function strokeLinecap(_) {
                return arguments.length ? (this._strokeLinecap = typeof _ === "function" ? _ : constant(_), this) : this._strokeLinecap;
            }
        },
        {
            key: "strokeOpacity",
            value: function strokeOpacity(_) {
                return arguments.length ? (this._strokeOpacity = typeof _ === "function" ? _ : constant(_), this) : this._strokeOpacity;
            }
        },
        {
            key: "strokeWidth",
            value: function strokeWidth(_) {
                return arguments.length ? (this._strokeWidth = typeof _ === "function" ? _ : constant(_), this) : this._strokeWidth;
            }
        },
        {
            key: "textAnchor",
            value: function textAnchor(_) {
                return arguments.length ? (this._textAnchor = typeof _ === "function" ? _ : constant(_), this) : this._textAnchor;
            }
        },
        {
            key: "texture",
            value: function texture(_) {
                return arguments.length ? (this._texture = typeof _ === "function" ? _ : constant(_), this) : this._texture;
            }
        },
        {
            key: "textureDefault",
            value: function textureDefault(_) {
                return arguments.length ? (this._textureDefault = assign(this._textureDefault, _), this) : this._textureDefault;
            }
        },
        {
            key: "vectorEffect",
            value: function vectorEffect(_) {
                return arguments.length ? (this._vectorEffect = typeof _ === "function" ? _ : constant(_), this) : this._vectorEffect;
            }
        },
        {
            key: "verticalAlign",
            value: function verticalAlign(_) {
                return arguments.length ? (this._verticalAlign = typeof _ === "function" ? _ : constant(_), this) : this._verticalAlign;
            }
        },
        {
            key: "x",
            value: function x(_) {
                return arguments.length ? (this._x = typeof _ === "function" ? _ : constant(_), this) : this._x;
            }
        },
        {
            key: "y",
            value: function y(_) {
                return arguments.length ? (this._y = typeof _ === "function" ? _ : constant(_), this) : this._y;
            }
        }
    ]);
    return Shape;
}(BaseClass);
/**
    An abstracted class for generating shapes.
*/ export { Shape as default };
