bbl-gantt
Version:
一个框架无关的JS甘特图库,支持resize、拖拽新建、支持自定义样式、以及支持duration模式等功能。A framework-independent JS Gantt chart library, supporting resize, drag-and-drop to create new tasks, custom styling, and duration mode functionalities.
1,735 lines • 330 kB
JavaScript
const methods$1 = {};
const names = [];
function registerMethods(name, m) {
if (Array.isArray(name)) {
for (const _name of name) {
registerMethods(_name, m);
}
return;
}
if (typeof name === "object") {
for (const _name in name) {
registerMethods(_name, name[_name]);
}
return;
}
addMethodNames(Object.getOwnPropertyNames(m));
methods$1[name] = Object.assign(methods$1[name] || {}, m);
}
function getMethodsFor(name) {
return methods$1[name] || {};
}
function getMethodNames() {
return [...new Set(names)];
}
function addMethodNames(_names) {
names.push(..._names);
}
function map(array2, block) {
let i;
const il = array2.length;
const result = [];
for (i = 0; i < il; i++) {
result.push(block(array2[i]));
}
return result;
}
function filter(array2, block) {
let i;
const il = array2.length;
const result = [];
for (i = 0; i < il; i++) {
if (block(array2[i])) {
result.push(array2[i]);
}
}
return result;
}
function radians(d) {
return d % 360 * Math.PI / 180;
}
function unCamelCase(s) {
return s.replace(/([A-Z])/g, function(m, g) {
return "-" + g.toLowerCase();
});
}
function capitalize(s) {
return s.charAt(0).toUpperCase() + s.slice(1);
}
function proportionalSize(element, width2, height2, box) {
if (width2 == null || height2 == null) {
box = box || element.bbox();
if (width2 == null) {
width2 = box.width / box.height * height2;
} else if (height2 == null) {
height2 = box.height / box.width * width2;
}
}
return {
width: width2,
height: height2
};
}
function getOrigin(o, element) {
const origin = o.origin;
let ox = o.ox != null ? o.ox : o.originX != null ? o.originX : "center";
let oy = o.oy != null ? o.oy : o.originY != null ? o.originY : "center";
if (origin != null) {
[ox, oy] = Array.isArray(origin) ? origin : typeof origin === "object" ? [origin.x, origin.y] : [origin, origin];
}
const condX = typeof ox === "string";
const condY = typeof oy === "string";
if (condX || condY) {
const { height: height2, width: width2, x: x2, y: y2 } = element.bbox();
if (condX) {
ox = ox.includes("left") ? x2 : ox.includes("right") ? x2 + width2 : x2 + width2 / 2;
}
if (condY) {
oy = oy.includes("top") ? y2 : oy.includes("bottom") ? y2 + height2 : y2 + height2 / 2;
}
}
return [ox, oy];
}
const descriptiveElements = /* @__PURE__ */ new Set(["desc", "metadata", "title"]);
const isDescriptive = (element) => descriptiveElements.has(element.nodeName);
const writeDataToDom = (element, data2, defaults = {}) => {
const cloned = { ...data2 };
for (const key in cloned) {
if (cloned[key].valueOf() === defaults[key]) {
delete cloned[key];
}
}
if (Object.keys(cloned).length) {
element.node.setAttribute("data-svgjs", JSON.stringify(cloned));
} else {
element.node.removeAttribute("data-svgjs");
element.node.removeAttribute("svgjs:data");
}
};
const svg = "http://www.w3.org/2000/svg";
const html = "http://www.w3.org/1999/xhtml";
const xmlns = "http://www.w3.org/2000/xmlns/";
const xlink = "http://www.w3.org/1999/xlink";
const globals = {
window: typeof window === "undefined" ? null : window,
document: typeof document === "undefined" ? null : document
};
function getWindow() {
return globals.window;
}
class Base {
// constructor (node/*, {extensions = []} */) {
// // this.tags = []
// //
// // for (let extension of extensions) {
// // extension.setup.call(this, node)
// // this.tags.push(extension.name)
// // }
// }
}
const elements = {};
const root$1 = "___SYMBOL___ROOT___";
function create(name, ns = svg) {
return globals.document.createElementNS(ns, name);
}
function makeInstance(element, isHTML = false) {
if (element instanceof Base) return element;
if (typeof element === "object") {
return adopter(element);
}
if (element == null) {
return new elements[root$1]();
}
if (typeof element === "string" && element.charAt(0) !== "<") {
return adopter(globals.document.querySelector(element));
}
const wrapper = isHTML ? globals.document.createElement("div") : create("svg");
wrapper.innerHTML = element;
element = adopter(wrapper.firstChild);
wrapper.removeChild(wrapper.firstChild);
return element;
}
function nodeOrNew(name, node) {
return node && (node instanceof globals.window.Node || node.ownerDocument && node instanceof node.ownerDocument.defaultView.Node) ? node : create(name);
}
function adopt(node) {
if (!node) return null;
if (node.instance instanceof Base) return node.instance;
if (node.nodeName === "#document-fragment") {
return new elements.Fragment(node);
}
let className = capitalize(node.nodeName || "Dom");
if (className === "LinearGradient" || className === "RadialGradient") {
className = "Gradient";
} else if (!elements[className]) {
className = "Dom";
}
return new elements[className](node);
}
let adopter = adopt;
function register(element, name = element.name, asRoot = false) {
elements[name] = element;
if (asRoot) elements[root$1] = element;
addMethodNames(Object.getOwnPropertyNames(element.prototype));
return element;
}
function getClass(name) {
return elements[name];
}
let did = 1e3;
function eid(name) {
return "Svgjs" + capitalize(name) + did++;
}
function assignNewId(node) {
for (let i = node.children.length - 1; i >= 0; i--) {
assignNewId(node.children[i]);
}
if (node.id) {
node.id = eid(node.nodeName);
return node;
}
return node;
}
function extend(modules, methods2) {
let key, i;
modules = Array.isArray(modules) ? modules : [modules];
for (i = modules.length - 1; i >= 0; i--) {
for (key in methods2) {
modules[i].prototype[key] = methods2[key];
}
}
}
function wrapWithAttrCheck(fn) {
return function(...args) {
const o = args[args.length - 1];
if (o && o.constructor === Object && !(o instanceof Array)) {
return fn.apply(this, args.slice(0, -1)).attr(o);
} else {
return fn.apply(this, args);
}
};
}
function siblings() {
return this.parent().children();
}
function position() {
return this.parent().index(this);
}
function next() {
return this.siblings()[this.position() + 1];
}
function prev() {
return this.siblings()[this.position() - 1];
}
function forward() {
const i = this.position();
const p = this.parent();
p.add(this.remove(), i + 1);
return this;
}
function backward() {
const i = this.position();
const p = this.parent();
p.add(this.remove(), i ? i - 1 : 0);
return this;
}
function front() {
const p = this.parent();
p.add(this.remove());
return this;
}
function back() {
const p = this.parent();
p.add(this.remove(), 0);
return this;
}
function before(element) {
element = makeInstance(element);
element.remove();
const i = this.position();
this.parent().add(element, i);
return this;
}
function after(element) {
element = makeInstance(element);
element.remove();
const i = this.position();
this.parent().add(element, i + 1);
return this;
}
function insertBefore(element) {
element = makeInstance(element);
element.before(this);
return this;
}
function insertAfter(element) {
element = makeInstance(element);
element.after(this);
return this;
}
registerMethods("Dom", {
siblings,
position,
next,
prev,
forward,
backward,
front,
back,
before,
after,
insertBefore,
insertAfter
});
const numberAndUnit = /^([+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?)([a-z%]*)$/i;
const hex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;
const rgb = /rgb\((\d+),(\d+),(\d+)\)/;
const reference = /(#[a-z_][a-z0-9\-_]*)/i;
const transforms = /\)\s*,?\s*/;
const whitespace = /\s/g;
const isHex = /^#[a-f0-9]{3}$|^#[a-f0-9]{6}$/i;
const isRgb = /^rgb\(/;
const isBlank = /^(\s+)?$/;
const isNumber = /^[+-]?(\d+(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i;
const isImage = /\.(jpg|jpeg|png|gif|svg)(\?[^=]+.*)?/i;
const delimiter = /[\s,]+/;
const isPathLetter = /[MLHVCSQTAZ]/i;
function classes() {
const attr2 = this.attr("class");
return attr2 == null ? [] : attr2.trim().split(delimiter);
}
function hasClass(name) {
return this.classes().indexOf(name) !== -1;
}
function addClass(name) {
if (!this.hasClass(name)) {
const array2 = this.classes();
array2.push(name);
this.attr("class", array2.join(" "));
}
return this;
}
function removeClass(name) {
if (this.hasClass(name)) {
this.attr(
"class",
this.classes().filter(function(c) {
return c !== name;
}).join(" ")
);
}
return this;
}
function toggleClass(name) {
return this.hasClass(name) ? this.removeClass(name) : this.addClass(name);
}
registerMethods("Dom", {
classes,
hasClass,
addClass,
removeClass,
toggleClass
});
function css(style, val) {
const ret = {};
if (arguments.length === 0) {
this.node.style.cssText.split(/\s*;\s*/).filter(function(el) {
return !!el.length;
}).forEach(function(el) {
const t = el.split(/\s*:\s*/);
ret[t[0]] = t[1];
});
return ret;
}
if (arguments.length < 2) {
if (Array.isArray(style)) {
for (const name of style) {
const cased = name;
ret[name] = this.node.style.getPropertyValue(cased);
}
return ret;
}
if (typeof style === "string") {
return this.node.style.getPropertyValue(style);
}
if (typeof style === "object") {
for (const name in style) {
this.node.style.setProperty(
name,
style[name] == null || isBlank.test(style[name]) ? "" : style[name]
);
}
}
}
if (arguments.length === 2) {
this.node.style.setProperty(
style,
val == null || isBlank.test(val) ? "" : val
);
}
return this;
}
function show() {
return this.css("display", "");
}
function hide() {
return this.css("display", "none");
}
function visible() {
return this.css("display") !== "none";
}
registerMethods("Dom", {
css,
show,
hide,
visible
});
function data(a, v, r) {
if (a == null) {
return this.data(
map(
filter(
this.node.attributes,
(el) => el.nodeName.indexOf("data-") === 0
),
(el) => el.nodeName.slice(5)
)
);
} else if (a instanceof Array) {
const data2 = {};
for (const key of a) {
data2[key] = this.data(key);
}
return data2;
} else if (typeof a === "object") {
for (v in a) {
this.data(v, a[v]);
}
} else if (arguments.length < 2) {
try {
return JSON.parse(this.attr("data-" + a));
} catch (e) {
return this.attr("data-" + a);
}
} else {
this.attr(
"data-" + a,
v === null ? null : r === true || typeof v === "string" || typeof v === "number" ? v : JSON.stringify(v)
);
}
return this;
}
registerMethods("Dom", { data });
function remember(k, v) {
if (typeof arguments[0] === "object") {
for (const key in k) {
this.remember(key, k[key]);
}
} else if (arguments.length === 1) {
return this.memory()[k];
} else {
this.memory()[k] = v;
}
return this;
}
function forget() {
if (arguments.length === 0) {
this._memory = {};
} else {
for (let i = arguments.length - 1; i >= 0; i--) {
delete this.memory()[arguments[i]];
}
}
return this;
}
function memory() {
return this._memory = this._memory || {};
}
registerMethods("Dom", { remember, forget, memory });
function sixDigitHex(hex2) {
return hex2.length === 4 ? [
"#",
hex2.substring(1, 2),
hex2.substring(1, 2),
hex2.substring(2, 3),
hex2.substring(2, 3),
hex2.substring(3, 4),
hex2.substring(3, 4)
].join("") : hex2;
}
function componentHex(component) {
const integer = Math.round(component);
const bounded = Math.max(0, Math.min(255, integer));
const hex2 = bounded.toString(16);
return hex2.length === 1 ? "0" + hex2 : hex2;
}
function is(object, space) {
for (let i = space.length; i--; ) {
if (object[space[i]] == null) {
return false;
}
}
return true;
}
function getParameters(a, b) {
const params = is(a, "rgb") ? { _a: a.r, _b: a.g, _c: a.b, _d: 0, space: "rgb" } : is(a, "xyz") ? { _a: a.x, _b: a.y, _c: a.z, _d: 0, space: "xyz" } : is(a, "hsl") ? { _a: a.h, _b: a.s, _c: a.l, _d: 0, space: "hsl" } : is(a, "lab") ? { _a: a.l, _b: a.a, _c: a.b, _d: 0, space: "lab" } : is(a, "lch") ? { _a: a.l, _b: a.c, _c: a.h, _d: 0, space: "lch" } : is(a, "cmyk") ? { _a: a.c, _b: a.m, _c: a.y, _d: a.k, space: "cmyk" } : { _a: 0, _b: 0, _c: 0, space: "rgb" };
params.space = b || params.space;
return params;
}
function cieSpace(space) {
if (space === "lab" || space === "xyz" || space === "lch") {
return true;
} else {
return false;
}
}
function hueToRgb(p, q, 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;
}
class Color {
constructor(...inputs) {
this.init(...inputs);
}
// Test if given value is a color
static isColor(color) {
return color && (color instanceof Color || this.isRgb(color) || this.test(color));
}
// Test if given value is an rgb object
static isRgb(color) {
return color && typeof color.r === "number" && typeof color.g === "number" && typeof color.b === "number";
}
/*
Generating random colors
*/
static random(mode = "vibrant", t) {
const { random, round, sin, PI: pi } = Math;
if (mode === "vibrant") {
const l = (81 - 57) * random() + 57;
const c = (83 - 45) * random() + 45;
const h = 360 * random();
const color = new Color(l, c, h, "lch");
return color;
} else if (mode === "sine") {
t = t == null ? random() : t;
const r = round(80 * sin(2 * pi * t / 0.5 + 0.01) + 150);
const g = round(50 * sin(2 * pi * t / 0.5 + 4.6) + 200);
const b = round(100 * sin(2 * pi * t / 0.5 + 2.3) + 150);
const color = new Color(r, g, b);
return color;
} else if (mode === "pastel") {
const l = (94 - 86) * random() + 86;
const c = (26 - 9) * random() + 9;
const h = 360 * random();
const color = new Color(l, c, h, "lch");
return color;
} else if (mode === "dark") {
const l = 10 + 10 * random();
const c = (125 - 75) * random() + 86;
const h = 360 * random();
const color = new Color(l, c, h, "lch");
return color;
} else if (mode === "rgb") {
const r = 255 * random();
const g = 255 * random();
const b = 255 * random();
const color = new Color(r, g, b);
return color;
} else if (mode === "lab") {
const l = 100 * random();
const a = 256 * random() - 128;
const b = 256 * random() - 128;
const color = new Color(l, a, b, "lab");
return color;
} else if (mode === "grey") {
const grey = 255 * random();
const color = new Color(grey, grey, grey);
return color;
} else {
throw new Error("Unsupported random color mode");
}
}
// Test if given value is a color string
static test(color) {
return typeof color === "string" && (isHex.test(color) || isRgb.test(color));
}
cmyk() {
const { _a, _b, _c } = this.rgb();
const [r, g, b] = [_a, _b, _c].map((v) => v / 255);
const k = Math.min(1 - r, 1 - g, 1 - b);
if (k === 1) {
return new Color(0, 0, 0, 1, "cmyk");
}
const c = (1 - r - k) / (1 - k);
const m = (1 - g - k) / (1 - k);
const y2 = (1 - b - k) / (1 - k);
const color = new Color(c, m, y2, k, "cmyk");
return color;
}
hsl() {
const { _a, _b, _c } = this.rgb();
const [r, g, b] = [_a, _b, _c].map((v) => v / 255);
const max = Math.max(r, g, b);
const min = Math.min(r, g, b);
const l = (max + min) / 2;
const isGrey = max === min;
const delta = max - min;
const s = isGrey ? 0 : l > 0.5 ? delta / (2 - max - min) : delta / (max + min);
const h = isGrey ? 0 : max === r ? ((g - b) / delta + (g < b ? 6 : 0)) / 6 : max === g ? ((b - r) / delta + 2) / 6 : max === b ? ((r - g) / delta + 4) / 6 : 0;
const color = new Color(360 * h, 100 * s, 100 * l, "hsl");
return color;
}
init(a = 0, b = 0, c = 0, d = 0, space = "rgb") {
a = !a ? 0 : a;
if (this.space) {
for (const component in this.space) {
delete this[this.space[component]];
}
}
if (typeof a === "number") {
space = typeof d === "string" ? d : space;
d = typeof d === "string" ? 0 : d;
Object.assign(this, { _a: a, _b: b, _c: c, _d: d, space });
} else if (a instanceof Array) {
this.space = b || (typeof a[3] === "string" ? a[3] : a[4]) || "rgb";
Object.assign(this, { _a: a[0], _b: a[1], _c: a[2], _d: a[3] || 0 });
} else if (a instanceof Object) {
const values = getParameters(a, b);
Object.assign(this, values);
} else if (typeof a === "string") {
if (isRgb.test(a)) {
const noWhitespace = a.replace(whitespace, "");
const [_a2, _b2, _c2] = rgb.exec(noWhitespace).slice(1, 4).map((v) => parseInt(v));
Object.assign(this, { _a: _a2, _b: _b2, _c: _c2, _d: 0, space: "rgb" });
} else if (isHex.test(a)) {
const hexParse = (v) => parseInt(v, 16);
const [, _a2, _b2, _c2] = hex.exec(sixDigitHex(a)).map(hexParse);
Object.assign(this, { _a: _a2, _b: _b2, _c: _c2, _d: 0, space: "rgb" });
} else throw Error("Unsupported string format, can't construct Color");
}
const { _a, _b, _c, _d } = this;
const components = this.space === "rgb" ? { r: _a, g: _b, b: _c } : this.space === "xyz" ? { x: _a, y: _b, z: _c } : this.space === "hsl" ? { h: _a, s: _b, l: _c } : this.space === "lab" ? { l: _a, a: _b, b: _c } : this.space === "lch" ? { l: _a, c: _b, h: _c } : this.space === "cmyk" ? { c: _a, m: _b, y: _c, k: _d } : {};
Object.assign(this, components);
}
lab() {
const { x: x2, y: y2, z } = this.xyz();
const l = 116 * y2 - 16;
const a = 500 * (x2 - y2);
const b = 200 * (y2 - z);
const color = new Color(l, a, b, "lab");
return color;
}
lch() {
const { l, a, b } = this.lab();
const c = Math.sqrt(a ** 2 + b ** 2);
let h = 180 * Math.atan2(b, a) / Math.PI;
if (h < 0) {
h *= -1;
h = 360 - h;
}
const color = new Color(l, c, h, "lch");
return color;
}
/*
Conversion Methods
*/
rgb() {
if (this.space === "rgb") {
return this;
} else if (cieSpace(this.space)) {
let { x: x2, y: y2, z } = this;
if (this.space === "lab" || this.space === "lch") {
let { l, a, b: b2 } = this;
if (this.space === "lch") {
const { c, h } = this;
const dToR = Math.PI / 180;
a = c * Math.cos(dToR * h);
b2 = c * Math.sin(dToR * h);
}
const yL = (l + 16) / 116;
const xL = a / 500 + yL;
const zL = yL - b2 / 200;
const ct = 16 / 116;
const mx = 8856e-6;
const nm = 7.787;
x2 = 0.95047 * (xL ** 3 > mx ? xL ** 3 : (xL - ct) / nm);
y2 = 1 * (yL ** 3 > mx ? yL ** 3 : (yL - ct) / nm);
z = 1.08883 * (zL ** 3 > mx ? zL ** 3 : (zL - ct) / nm);
}
const rU = x2 * 3.2406 + y2 * -1.5372 + z * -0.4986;
const gU = x2 * -0.9689 + y2 * 1.8758 + z * 0.0415;
const bU = x2 * 0.0557 + y2 * -0.204 + z * 1.057;
const pow = Math.pow;
const bd = 31308e-7;
const r = rU > bd ? 1.055 * pow(rU, 1 / 2.4) - 0.055 : 12.92 * rU;
const g = gU > bd ? 1.055 * pow(gU, 1 / 2.4) - 0.055 : 12.92 * gU;
const b = bU > bd ? 1.055 * pow(bU, 1 / 2.4) - 0.055 : 12.92 * bU;
const color = new Color(255 * r, 255 * g, 255 * b);
return color;
} else if (this.space === "hsl") {
let { h, s, l } = this;
h /= 360;
s /= 100;
l /= 100;
if (s === 0) {
l *= 255;
const color2 = new Color(l, l, l);
return color2;
}
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
const p = 2 * l - q;
const r = 255 * hueToRgb(p, q, h + 1 / 3);
const g = 255 * hueToRgb(p, q, h);
const b = 255 * hueToRgb(p, q, h - 1 / 3);
const color = new Color(r, g, b);
return color;
} else if (this.space === "cmyk") {
const { c, m, y: y2, k } = this;
const r = 255 * (1 - Math.min(1, c * (1 - k) + k));
const g = 255 * (1 - Math.min(1, m * (1 - k) + k));
const b = 255 * (1 - Math.min(1, y2 * (1 - k) + k));
const color = new Color(r, g, b);
return color;
} else {
return this;
}
}
toArray() {
const { _a, _b, _c, _d, space } = this;
return [_a, _b, _c, _d, space];
}
toHex() {
const [r, g, b] = this._clamped().map(componentHex);
return `#${r}${g}${b}`;
}
toRgb() {
const [rV, gV, bV] = this._clamped();
const string = `rgb(${rV},${gV},${bV})`;
return string;
}
toString() {
return this.toHex();
}
xyz() {
const { _a: r255, _b: g255, _c: b255 } = this.rgb();
const [r, g, b] = [r255, g255, b255].map((v) => v / 255);
const rL = r > 0.04045 ? Math.pow((r + 0.055) / 1.055, 2.4) : r / 12.92;
const gL = g > 0.04045 ? Math.pow((g + 0.055) / 1.055, 2.4) : g / 12.92;
const bL = b > 0.04045 ? Math.pow((b + 0.055) / 1.055, 2.4) : b / 12.92;
const xU = (rL * 0.4124 + gL * 0.3576 + bL * 0.1805) / 0.95047;
const yU = (rL * 0.2126 + gL * 0.7152 + bL * 0.0722) / 1;
const zU = (rL * 0.0193 + gL * 0.1192 + bL * 0.9505) / 1.08883;
const x2 = xU > 8856e-6 ? Math.pow(xU, 1 / 3) : 7.787 * xU + 16 / 116;
const y2 = yU > 8856e-6 ? Math.pow(yU, 1 / 3) : 7.787 * yU + 16 / 116;
const z = zU > 8856e-6 ? Math.pow(zU, 1 / 3) : 7.787 * zU + 16 / 116;
const color = new Color(x2, y2, z, "xyz");
return color;
}
/*
Input and Output methods
*/
_clamped() {
const { _a, _b, _c } = this.rgb();
const { max, min, round } = Math;
const format = (v) => max(0, min(round(v), 255));
return [_a, _b, _c].map(format);
}
/*
Constructing colors
*/
}
class Point {
// Initialize
constructor(...args) {
this.init(...args);
}
// Clone point
clone() {
return new Point(this);
}
init(x2, y2) {
const base = { x: 0, y: 0 };
const source = Array.isArray(x2) ? { x: x2[0], y: x2[1] } : typeof x2 === "object" ? { x: x2.x, y: x2.y } : { x: x2, y: y2 };
this.x = source.x == null ? base.x : source.x;
this.y = source.y == null ? base.y : source.y;
return this;
}
toArray() {
return [this.x, this.y];
}
transform(m) {
return this.clone().transformO(m);
}
// Transform point with matrix
transformO(m) {
if (!Matrix.isMatrixLike(m)) {
m = new Matrix(m);
}
const { x: x2, y: y2 } = this;
this.x = m.a * x2 + m.c * y2 + m.e;
this.y = m.b * x2 + m.d * y2 + m.f;
return this;
}
}
function point(x2, y2) {
return new Point(x2, y2).transformO(this.screenCTM().inverseO());
}
function unpoint(x2, y2) {
return new Point(x2, y2).transformO(this.screenCTM());
}
function closeEnough(a, b, threshold) {
return Math.abs(b - a) < 1e-6;
}
class Matrix {
constructor(...args) {
this.init(...args);
}
static formatTransforms(o) {
const flipBoth = o.flip === "both" || o.flip === true;
const flipX = o.flip && (flipBoth || o.flip === "x") ? -1 : 1;
const flipY = o.flip && (flipBoth || o.flip === "y") ? -1 : 1;
const skewX = o.skew && o.skew.length ? o.skew[0] : isFinite(o.skew) ? o.skew : isFinite(o.skewX) ? o.skewX : 0;
const skewY = o.skew && o.skew.length ? o.skew[1] : isFinite(o.skew) ? o.skew : isFinite(o.skewY) ? o.skewY : 0;
const scaleX = o.scale && o.scale.length ? o.scale[0] * flipX : isFinite(o.scale) ? o.scale * flipX : isFinite(o.scaleX) ? o.scaleX * flipX : flipX;
const scaleY = o.scale && o.scale.length ? o.scale[1] * flipY : isFinite(o.scale) ? o.scale * flipY : isFinite(o.scaleY) ? o.scaleY * flipY : flipY;
const shear = o.shear || 0;
const theta = o.rotate || o.theta || 0;
const origin = new Point(
o.origin || o.around || o.ox || o.originX,
o.oy || o.originY
);
const ox = origin.x;
const oy = origin.y;
const position2 = new Point(
o.position || o.px || o.positionX || NaN,
o.py || o.positionY || NaN
);
const px = position2.x;
const py = position2.y;
const translate = new Point(
o.translate || o.tx || o.translateX,
o.ty || o.translateY
);
const tx = translate.x;
const ty = translate.y;
const relative = new Point(
o.relative || o.rx || o.relativeX,
o.ry || o.relativeY
);
const rx2 = relative.x;
const ry2 = relative.y;
return {
scaleX,
scaleY,
skewX,
skewY,
shear,
theta,
rx: rx2,
ry: ry2,
tx,
ty,
ox,
oy,
px,
py
};
}
static fromArray(a) {
return { a: a[0], b: a[1], c: a[2], d: a[3], e: a[4], f: a[5] };
}
static isMatrixLike(o) {
return o.a != null || o.b != null || o.c != null || o.d != null || o.e != null || o.f != null;
}
// left matrix, right matrix, target matrix which is overwritten
static matrixMultiply(l, r, o) {
const a = l.a * r.a + l.c * r.b;
const b = l.b * r.a + l.d * r.b;
const c = l.a * r.c + l.c * r.d;
const d = l.b * r.c + l.d * r.d;
const e = l.e + l.a * r.e + l.c * r.f;
const f = l.f + l.b * r.e + l.d * r.f;
o.a = a;
o.b = b;
o.c = c;
o.d = d;
o.e = e;
o.f = f;
return o;
}
around(cx2, cy2, matrix) {
return this.clone().aroundO(cx2, cy2, matrix);
}
// Transform around a center point
aroundO(cx2, cy2, matrix) {
const dx2 = cx2 || 0;
const dy2 = cy2 || 0;
return this.translateO(-dx2, -dy2).lmultiplyO(matrix).translateO(dx2, dy2);
}
// Clones this matrix
clone() {
return new Matrix(this);
}
// Decomposes this matrix into its affine parameters
decompose(cx2 = 0, cy2 = 0) {
const a = this.a;
const b = this.b;
const c = this.c;
const d = this.d;
const e = this.e;
const f = this.f;
const determinant = a * d - b * c;
const ccw = determinant > 0 ? 1 : -1;
const sx = ccw * Math.sqrt(a * a + b * b);
const thetaRad = Math.atan2(ccw * b, ccw * a);
const theta = 180 / Math.PI * thetaRad;
const ct = Math.cos(thetaRad);
const st = Math.sin(thetaRad);
const lam = (a * c + b * d) / determinant;
const sy = c * sx / (lam * a - b) || d * sx / (lam * b + a);
const tx = e - cx2 + cx2 * ct * sx + cy2 * (lam * ct * sx - st * sy);
const ty = f - cy2 + cx2 * st * sx + cy2 * (lam * st * sx + ct * sy);
return {
// Return the affine parameters
scaleX: sx,
scaleY: sy,
shear: lam,
rotate: theta,
translateX: tx,
translateY: ty,
originX: cx2,
originY: cy2,
// Return the matrix parameters
a: this.a,
b: this.b,
c: this.c,
d: this.d,
e: this.e,
f: this.f
};
}
// Check if two matrices are equal
equals(other) {
if (other === this) return true;
const comp = new Matrix(other);
return closeEnough(this.a, comp.a) && closeEnough(this.b, comp.b) && closeEnough(this.c, comp.c) && closeEnough(this.d, comp.d) && closeEnough(this.e, comp.e) && closeEnough(this.f, comp.f);
}
// Flip matrix on x or y, at a given offset
flip(axis, around) {
return this.clone().flipO(axis, around);
}
flipO(axis, around) {
return axis === "x" ? this.scaleO(-1, 1, around, 0) : axis === "y" ? this.scaleO(1, -1, 0, around) : this.scaleO(-1, -1, axis, around || axis);
}
// Initialize
init(source) {
const base = Matrix.fromArray([1, 0, 0, 1, 0, 0]);
source = source instanceof Element ? source.matrixify() : typeof source === "string" ? Matrix.fromArray(source.split(delimiter).map(parseFloat)) : Array.isArray(source) ? Matrix.fromArray(source) : typeof source === "object" && Matrix.isMatrixLike(source) ? source : typeof source === "object" ? new Matrix().transform(source) : arguments.length === 6 ? Matrix.fromArray([].slice.call(arguments)) : base;
this.a = source.a != null ? source.a : base.a;
this.b = source.b != null ? source.b : base.b;
this.c = source.c != null ? source.c : base.c;
this.d = source.d != null ? source.d : base.d;
this.e = source.e != null ? source.e : base.e;
this.f = source.f != null ? source.f : base.f;
return this;
}
inverse() {
return this.clone().inverseO();
}
// Inverses matrix
inverseO() {
const a = this.a;
const b = this.b;
const c = this.c;
const d = this.d;
const e = this.e;
const f = this.f;
const det = a * d - b * c;
if (!det) throw new Error("Cannot invert " + this);
const na = d / det;
const nb = -b / det;
const nc = -c / det;
const nd = a / det;
const ne = -(na * e + nc * f);
const nf = -(nb * e + nd * f);
this.a = na;
this.b = nb;
this.c = nc;
this.d = nd;
this.e = ne;
this.f = nf;
return this;
}
lmultiply(matrix) {
return this.clone().lmultiplyO(matrix);
}
lmultiplyO(matrix) {
const r = this;
const l = matrix instanceof Matrix ? matrix : new Matrix(matrix);
return Matrix.matrixMultiply(l, r, this);
}
// Left multiplies by the given matrix
multiply(matrix) {
return this.clone().multiplyO(matrix);
}
multiplyO(matrix) {
const l = this;
const r = matrix instanceof Matrix ? matrix : new Matrix(matrix);
return Matrix.matrixMultiply(l, r, this);
}
// Rotate matrix
rotate(r, cx2, cy2) {
return this.clone().rotateO(r, cx2, cy2);
}
rotateO(r, cx2 = 0, cy2 = 0) {
r = radians(r);
const cos = Math.cos(r);
const sin = Math.sin(r);
const { a, b, c, d, e, f } = this;
this.a = a * cos - b * sin;
this.b = b * cos + a * sin;
this.c = c * cos - d * sin;
this.d = d * cos + c * sin;
this.e = e * cos - f * sin + cy2 * sin - cx2 * cos + cx2;
this.f = f * cos + e * sin - cx2 * sin - cy2 * cos + cy2;
return this;
}
// Scale matrix
scale() {
return this.clone().scaleO(...arguments);
}
scaleO(x2, y2 = x2, cx2 = 0, cy2 = 0) {
if (arguments.length === 3) {
cy2 = cx2;
cx2 = y2;
y2 = x2;
}
const { a, b, c, d, e, f } = this;
this.a = a * x2;
this.b = b * y2;
this.c = c * x2;
this.d = d * y2;
this.e = e * x2 - cx2 * x2 + cx2;
this.f = f * y2 - cy2 * y2 + cy2;
return this;
}
// Shear matrix
shear(a, cx2, cy2) {
return this.clone().shearO(a, cx2, cy2);
}
// eslint-disable-next-line no-unused-vars
shearO(lx, cx2 = 0, cy2 = 0) {
const { a, b, c, d, e, f } = this;
this.a = a + b * lx;
this.c = c + d * lx;
this.e = e + f * lx - cy2 * lx;
return this;
}
// Skew Matrix
skew() {
return this.clone().skewO(...arguments);
}
skewO(x2, y2 = x2, cx2 = 0, cy2 = 0) {
if (arguments.length === 3) {
cy2 = cx2;
cx2 = y2;
y2 = x2;
}
x2 = radians(x2);
y2 = radians(y2);
const lx = Math.tan(x2);
const ly = Math.tan(y2);
const { a, b, c, d, e, f } = this;
this.a = a + b * lx;
this.b = b + a * ly;
this.c = c + d * lx;
this.d = d + c * ly;
this.e = e + f * lx - cy2 * lx;
this.f = f + e * ly - cx2 * ly;
return this;
}
// SkewX
skewX(x2, cx2, cy2) {
return this.skew(x2, 0, cx2, cy2);
}
// SkewY
skewY(y2, cx2, cy2) {
return this.skew(0, y2, cx2, cy2);
}
toArray() {
return [this.a, this.b, this.c, this.d, this.e, this.f];
}
// Convert matrix to string
toString() {
return "matrix(" + this.a + "," + this.b + "," + this.c + "," + this.d + "," + this.e + "," + this.f + ")";
}
// Transform a matrix into another matrix by manipulating the space
transform(o) {
if (Matrix.isMatrixLike(o)) {
const matrix = new Matrix(o);
return matrix.multiplyO(this);
}
const t = Matrix.formatTransforms(o);
const current = this;
const { x: ox, y: oy } = new Point(t.ox, t.oy).transform(current);
const transformer = new Matrix().translateO(t.rx, t.ry).lmultiplyO(current).translateO(-ox, -oy).scaleO(t.scaleX, t.scaleY).skewO(t.skewX, t.skewY).shearO(t.shear).rotateO(t.theta).translateO(ox, oy);
if (isFinite(t.px) || isFinite(t.py)) {
const origin = new Point(ox, oy).transform(transformer);
const dx2 = isFinite(t.px) ? t.px - origin.x : 0;
const dy2 = isFinite(t.py) ? t.py - origin.y : 0;
transformer.translateO(dx2, dy2);
}
transformer.translateO(t.tx, t.ty);
return transformer;
}
// Translate matrix
translate(x2, y2) {
return this.clone().translateO(x2, y2);
}
translateO(x2, y2) {
this.e += x2 || 0;
this.f += y2 || 0;
return this;
}
valueOf() {
return {
a: this.a,
b: this.b,
c: this.c,
d: this.d,
e: this.e,
f: this.f
};
}
}
function ctm() {
return new Matrix(this.node.getCTM());
}
function screenCTM() {
try {
if (typeof this.isRoot === "function" && !this.isRoot()) {
const rect = this.rect(1, 1);
const m = rect.node.getScreenCTM();
rect.remove();
return new Matrix(m);
}
return new Matrix(this.node.getScreenCTM());
} catch (e) {
return new Matrix();
}
}
register(Matrix, "Matrix");
function parser() {
if (!parser.nodes) {
const svg2 = makeInstance().size(2, 0);
svg2.node.style.cssText = [
"opacity: 0",
"position: absolute",
"left: -100%",
"top: -100%",
"overflow: hidden"
].join(";");
svg2.attr("focusable", "false");
svg2.attr("aria-hidden", "true");
const path = svg2.path().node;
parser.nodes = { svg: svg2, path };
}
if (!parser.nodes.svg.node.parentNode) {
const b = globals.document.body || globals.document.documentElement;
parser.nodes.svg.addTo(b);
}
return parser.nodes;
}
function isNulledBox(box) {
return !box.width && !box.height && !box.x && !box.y;
}
function domContains(node) {
return node === globals.document || (globals.document.documentElement.contains || function(node2) {
while (node2.parentNode) {
node2 = node2.parentNode;
}
return node2 === globals.document;
}).call(globals.document.documentElement, node);
}
class Box {
constructor(...args) {
this.init(...args);
}
addOffset() {
this.x += globals.window.pageXOffset;
this.y += globals.window.pageYOffset;
return new Box(this);
}
init(source) {
const base = [0, 0, 0, 0];
source = typeof source === "string" ? source.split(delimiter).map(parseFloat) : Array.isArray(source) ? source : typeof source === "object" ? [
source.left != null ? source.left : source.x,
source.top != null ? source.top : source.y,
source.width,
source.height
] : arguments.length === 4 ? [].slice.call(arguments) : base;
this.x = source[0] || 0;
this.y = source[1] || 0;
this.width = this.w = source[2] || 0;
this.height = this.h = source[3] || 0;
this.x2 = this.x + this.w;
this.y2 = this.y + this.h;
this.cx = this.x + this.w / 2;
this.cy = this.y + this.h / 2;
return this;
}
isNulled() {
return isNulledBox(this);
}
// Merge rect box with another, return a new instance
merge(box) {
const x2 = Math.min(this.x, box.x);
const y2 = Math.min(this.y, box.y);
const width2 = Math.max(this.x + this.width, box.x + box.width) - x2;
const height2 = Math.max(this.y + this.height, box.y + box.height) - y2;
return new Box(x2, y2, width2, height2);
}
toArray() {
return [this.x, this.y, this.width, this.height];
}
toString() {
return this.x + " " + this.y + " " + this.width + " " + this.height;
}
transform(m) {
if (!(m instanceof Matrix)) {
m = new Matrix(m);
}
let xMin = Infinity;
let xMax = -Infinity;
let yMin = Infinity;
let yMax = -Infinity;
const pts = [
new Point(this.x, this.y),
new Point(this.x2, this.y),
new Point(this.x, this.y2),
new Point(this.x2, this.y2)
];
pts.forEach(function(p) {
p = p.transform(m);
xMin = Math.min(xMin, p.x);
xMax = Math.max(xMax, p.x);
yMin = Math.min(yMin, p.y);
yMax = Math.max(yMax, p.y);
});
return new Box(xMin, yMin, xMax - xMin, yMax - yMin);
}
}
function getBox(el, getBBoxFn, retry) {
let box;
try {
box = getBBoxFn(el.node);
if (isNulledBox(box) && !domContains(el.node)) {
throw new Error("Element not in the dom");
}
} catch (e) {
box = retry(el);
}
return box;
}
function bbox() {
const getBBox = (node) => node.getBBox();
const retry = (el) => {
try {
const clone = el.clone().addTo(parser().svg).show();
const box2 = clone.node.getBBox();
clone.remove();
return box2;
} catch (e) {
throw new Error(
`Getting bbox of element "${el.node.nodeName}" is not possible: ${e.toString()}`
);
}
};
const box = getBox(this, getBBox, retry);
const bbox2 = new Box(box);
return bbox2;
}
function rbox(el) {
const getRBox = (node) => node.getBoundingClientRect();
const retry = (el2) => {
throw new Error(
`Getting rbox of element "${el2.node.nodeName}" is not possible`
);
};
const box = getBox(this, getRBox, retry);
const rbox2 = new Box(box);
if (el) {
return rbox2.transform(el.screenCTM().inverseO());
}
return rbox2.addOffset();
}
function inside(x2, y2) {
const box = this.bbox();
return x2 > box.x && y2 > box.y && x2 < box.x + box.width && y2 < box.y + box.height;
}
registerMethods({
viewbox: {
viewbox(x2, y2, width2, height2) {
if (x2 == null) return new Box(this.attr("viewBox"));
return this.attr("viewBox", new Box(x2, y2, width2, height2));
},
zoom(level, point2) {
let { width: width2, height: height2 } = this.attr(["width", "height"]);
if (!width2 && !height2 || typeof width2 === "string" || typeof height2 === "string") {
width2 = this.node.clientWidth;
height2 = this.node.clientHeight;
}
if (!width2 || !height2) {
throw new Error(
"Impossible to get absolute width and height. Please provide an absolute width and height attribute on the zooming element"
);
}
const v = this.viewbox();
const zoomX = width2 / v.width;
const zoomY = height2 / v.height;
const zoom = Math.min(zoomX, zoomY);
if (level == null) {
return zoom;
}
let zoomAmount = zoom / level;
if (zoomAmount === Infinity) zoomAmount = Number.MAX_SAFE_INTEGER / 100;
point2 = point2 || new Point(width2 / 2 / zoomX + v.x, height2 / 2 / zoomY + v.y);
const box = new Box(v).transform(
new Matrix({ scale: zoomAmount, origin: point2 })
);
return this.viewbox(box);
}
}
});
register(Box, "Box");
class List extends Array {
constructor(arr = [], ...args) {
super(arr, ...args);
if (typeof arr === "number") return this;
this.length = 0;
this.push(...arr);
}
}
extend([List], {
each(fnOrMethodName, ...args) {
if (typeof fnOrMethodName === "function") {
return this.map((el, i, arr) => {
return fnOrMethodName.call(el, el, i, arr);
});
} else {
return this.map((el) => {
return el[fnOrMethodName](...args);
});
}
},
toArray() {
return Array.prototype.concat.apply([], this);
}
});
const reserved = ["toArray", "constructor", "each"];
List.extend = function(methods2) {
methods2 = methods2.reduce((obj, name) => {
if (reserved.includes(name)) return obj;
if (name[0] === "_") return obj;
if (name in Array.prototype) {
obj["$" + name] = Array.prototype[name];
}
obj[name] = function(...attrs2) {
return this.each(name, ...attrs2);
};
return obj;
}, {});
extend([List], methods2);
};
function baseFind(query, parent) {
return new List(
map((parent || globals.document).querySelectorAll(query), function(node) {
return adopt(node);
})
);
}
function find$1(query) {
return baseFind(query, this.node);
}
function findOne(query) {
return adopt(this.node.querySelector(query));
}
let listenerId = 0;
const windowEvents = {};
function getEvents(instance) {
let n = instance.getEventHolder();
if (n === globals.window) n = windowEvents;
if (!n.events) n.events = {};
return n.events;
}
function getEventTarget(instance) {
return instance.getEventTarget();
}
function clearEvents(instance) {
let n = instance.getEventHolder();
if (n === globals.window) n = windowEvents;
if (n.events) n.events = {};
}
function on(node, events, listener, binding, options) {
const l = listener.bind(binding || node);
const instance = makeInstance(node);
const bag = getEvents(instance);
const n = getEventTarget(instance);
events = Array.isArray(events) ? events : events.split(delimiter);
if (!listener._svgjsListenerId) {
listener._svgjsListenerId = ++listenerId;
}
events.forEach(function(event) {
const ev = event.split(".")[0];
const ns = event.split(".")[1] || "*";
bag[ev] = bag[ev] || {};
bag[ev][ns] = bag[ev][ns] || {};
bag[ev][ns][listener._svgjsListenerId] = l;
n.addEventListener(ev, l, options || false);
});
}
function off(node, events, listener, options) {
const instance = makeInstance(node);
const bag = getEvents(instance);
const n = getEventTarget(instance);
if (typeof listener === "function") {
listener = listener._svgjsListenerId;
if (!listener) return;
}
events = Array.isArray(events) ? events : (events || "").split(delimiter);
events.forEach(function(event) {
const ev = event && event.split(".")[0];
const ns = event && event.split(".")[1];
let namespace, l;
if (listener) {
if (bag[ev] && bag[ev][ns || "*"]) {
n.removeEventListener(
ev,
bag[ev][ns || "*"][listener],
options || false
);
delete bag[ev][ns || "*"][listener];
}
} else if (ev && ns) {
if (bag[ev] && bag[ev][ns]) {
for (l in bag[ev][ns]) {
off(n, [ev, ns].join("."), l);
}
delete bag[ev][ns];
}
} else if (ns) {
for (event in bag) {
for (namespace in bag[event]) {
if (ns === namespace) {
off(n, [event, ns].join("."));
}
}
}
} else if (ev) {
if (bag[ev]) {
for (namespace in bag[ev]) {
off(n, [ev, namespace].join("."));
}
delete bag[ev];
}
} else {
for (event in bag) {
off(n, event);
}
clearEvents(instance);
}
});
}
function dispatch(node, event, data2, options) {
const n = getEventTarget(node);
if (event instanceof globals.window.Event) {
n.dispatchEvent(event);
} else {
event = new globals.window.CustomEvent(event, {
detail: data2,
cancelable: true,
...options
});
n.dispatchEvent(event);
}
return event;
}
class EventTarget extends Base {
addEventListener() {
}
dispatch(event, data2, options) {
return dispatch(this, event, data2, options);
}
dispatchEvent(event) {
const bag = this.getEventHolder().events;
if (!bag) return true;
const events = bag[event.type];
for (const i in events) {
for (const j in events[i]) {
events[i][j](event);
}
}
return !event.defaultPrevented;
}
// Fire given event
fire(event, data2, options) {
this.dispatch(event, data2, options);
return this;
}
getEventHolder() {
return this;
}
getEventTarget() {
return this;
}
// Unbind event from listener
off(event, listener, options) {
off(this, event, listener, options);
return this;
}
// Bind given event to listener
on(event, listener, binding, options) {
on(this, event, listener, binding, options);
return this;
}
removeEventListener() {
}
}
register(EventTarget, "EventTarget");
function noop() {
}
const timeline = {
duration: 400,
ease: ">",
delay: 0
};
const attrs = {
// fill and stroke
"fill-opacity": 1,
"stroke-opacity": 1,
"stroke-width": 0,
"stroke-linejoin": "miter",
"stroke-linecap": "butt",
fill: "#000000",
stroke: "#000000",
opacity: 1,
// position
x: 0,
y: 0,
cx: 0,
cy: 0,
// size
width: 0,
height: 0,
// radius
r: 0,
rx: 0,
ry: 0,
// gradient
offset: 0,
"stop-opacity": 1,
"stop-color": "#000000",
// text
"text-anchor": "start"
};
class SVGArray extends Array {
constructor(...args) {
super(...args);
this.init(...args);
}
clone() {
return new this.constructor(this);
}
init(arr) {
if (typeof arr === "number") return this;
this.length = 0;
this.push(...this.parse(arr));
return this;
}
// Parse whitespace separated string
parse(array2 = []) {
if (array2 instanceof Array) return array2;
return array2.trim().split(delimiter).map(parseFloat);
}
toArray() {
return Array.prototype.concat.apply([], this);
}
toSet() {
return new Set(this);
}
toString() {
return this.join(" ");
}
// Flattens the array if needed
valueOf() {
const ret = [];
ret.push(...this);
return ret;
}
}
class SVGNumber {
// Initialize
constructor(...args) {
this.init(...args);
}
convert(unit) {
return new SVGNumber(this.value, unit);
}
// Divide number
divide(number) {
number = new SVGNumber(number);
return new SVGNumber(this / number, this.unit || number.unit);
}
init(value, unit) {
unit = Array.isArray(value) ? value[1] : unit;
value = Array.isArray(value) ? value[0] : value;
this.value = 0;
this.unit = unit || "";
if (typeof value === "number") {
this.value = isNaN(value) ? 0 : !isFinite(value) ? value < 0 ? -34e37 : 34e37 : value;
} else if (typeof value === "string") {
unit = value.match(numberAndUnit);
if (unit) {
this.value = parseFloat(unit[1]);
if (unit[5] === "%") {
this.value /= 100;
} else if (unit[5] === "s") {
this.value *= 1e3;
}
this.unit = unit[5];
}
} else {
if (value instanceof SVGNumber) {
this.value = value.valueOf();
this.unit = value.unit;
}
}
return this;
}
// Subtract number
minus(number) {
number = new SVGNumber(number);
return new SVGNumber(this - number, this.unit || number.unit);
}
// Add number
plus(number) {
number = new SVGNumber(number);
return new SVGNumber(this + number, this.unit || number.unit);
}
// Multiply number
times(number) {
number = new SVGNumber(number);
return new SVGNumber(this * number, this.unit || number.unit);
}
toArray() {
return [this.value, this.unit];
}
toJSON() {
return this.toString();
}
toString() {
return (this.unit === "%" ? ~~(this.value * 1e8) / 1e6 : this.unit === "s" ? this.value / 1e3 : this.value) + this.unit;
}
valueOf() {
return this.value;
}
}
const colorAttributes = /* @__PURE__ */ new Set([
"fill",
"stroke",
"color",
"bgcolor",
"stop-color",
"flood-color",
"lighting-color"
]);
const hooks = [];
function registerAttrHook(fn) {
hooks.push(fn);
}
function attr(attr2, val, ns) {
if (attr2 == null) {
attr2 = {};
val = this.node.attributes;
for (const node of val) {
attr2[node.nodeName] = isNumber.test(node.nodeValue) ? parseFloat(node.nodeValue) : node.nodeValue;
}
return attr2;
} else if (attr2 instanceof Array) {
return attr2.reduce((last, curr) => {
last[curr] = this.attr(curr);
return last;
}, {});
} else if (typeof attr2 === "object" && attr2.constructor === Object) {
for (val in attr2) this.attr(val, attr2[val]);
} else if (val === null) {
this.node.removeAttribute(attr2);
} else if (val == null) {
val = this.node.getAttribute(attr2);
return val == null ? attrs[attr2] : isNumber.test(val) ? parseFloat(val) : val;
} else {
val = hooks.reduce((_val, hook) => {
return hook(attr2, _val, this);
}, val);
if (typeof val === "number") {
val = new SVGNumber(val);
} else if (colorAttributes.has(attr2) && Color.isColor(val)) {
val = new Color(val);
} else if (val.constructor === Array) {
val = new SVGArray(val);
}
if (attr2 === "leading") {
if (this.leading) {
this.leading(val);
}
} else {
typeof ns === "string" ? this.node.setAttributeNS(ns, attr2, val.toString()) : this.node.setAttribute(attr2, val.toString());
}
if (this.rebuild && (attr2 === "font-size" || attr2 === "x")) {
this.rebuild();
}
}
return this;
}
class Dom extends EventTarget {
constructor(node, attrs2) {
super();
this.node = node;
this.type = node.nodeName;
if (attrs2 && node !== attrs2) {
this.attr(attrs2);
}
}
// Add given element at a position
add(element, i) {
element = makeInstance(element);
if (element.removeNamespace && this.node instanceof globals.window.SVGElement) {
element.removeNamespace();
}
if (i == null) {
this.node.appendChild(element.node);
} else if (element.node !== this.node.childNodes[i]) {
this.node.insertBefore(element.node, this.node.childNodes[i]);
}
return this;
}
// Add element to given container and return self
addTo(parent, i) {
return makeInstance(parent).put(this, i);
}
// Returns all child elements
children() {
return new List(
map(this.node.children, function(node) {
return adopt(node);
})
);
}
// Remove all elements in this container
clear() {
while (this.node.hasChildNodes()) {
t