h.x&&(h=n),n.depth>l.depth&&(l=n)}));var p=c===h?1:n(c,h)/2,d=p-c.x,s=r/(h.x+p+d),v=t/(l.depth||1);i.eachBefore((function(n){n.x=(n.x+d)*s,n.y=n.depth*v}))}return i}function u(r){var t=r.children,e=r.parent.children,i=r.i?e[r.i-1]:null;if(t){!function(n){for(var r,t=0,e=0,i=n.children,u=i.length;--u>=0;)(r=i[u]).z+=t,r.m+=t,t+=r.s+(e+=r.c)}(r);var u=(t[0].z+t[t.length-1].z)/2;i?(r.z=i.z+n(r._,i._),r.m=r.z-u):r.z=u}else i&&(r.z=i.z+n(r._,i._));r.parent.A=function(r,t,e){if(t){for(var i,u=r,o=r,f=t,a=u.parent.children[0],c=u.m,h=o.m,l=f.m,p=a.m;f=H(f),u=G(u),f&&u;)a=G(a),(o=H(o)).a=r,(i=f.z+l-u.z-c+n(f._,u._))>0&&(J(K(f,r,e),r,i),c+=i,h+=i),l+=f.m,c+=u.m,p+=a.m,h+=o.m;f&&!H(o)&&(o.t=f,o.m+=l-h),u&&!G(a)&&(a.t=u,a.m+=c-p,e=r)}return e}(r,i,r.parent.A||e[0])}function o(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function f(n){n.x*=r,n.y=n.depth*t}return i.separation=function(r){return arguments.length?(n=r,i):n},i.size=function(n){return arguments.length?(e=!1,r=+n[0],t=+n[1],i):e?null:[r,t]},i.nodeSize=function(n){return arguments.length?(e=!0,r=+n[0],t=+n[1],i):e?[r,t]:null},i},n.treemap=function(){var n=X,r=!1,t=1,e=1,i=[0],u=d,o=d,f=d,a=d,c=d;function h(n){return n.x0=n.y0=0,n.x1=t,n.y1=e,n.eachBefore(l),i=[0],r&&n.eachBefore(j),n}function l(r){var t=i[r.depth],e=r.x0+t,h=r.y0+t,l=r.x1-t,p=r.y1-t;l=t-1){var h=f[r];return h.x0=i,h.y0=u,h.x1=o,void(h.y1=a)}var l=c[r],p=e/2+l,d=r+1,s=t-1;for(;d>>1;c[v]a-u){var g=e?(i*y+o*x)/e:o;n(r,d,x,i,u,g,a),n(d,t,y,g,u,o,a)}else{var m=e?(u*y+a*x)/e:a;n(r,d,x,i,u,o,m),n(d,t,y,i,m,o,a)}}(0,a,n.value,r,t,e,i)},n.treemapDice=O,n.treemapResquarify=Y,n.treemapSlice=U,n.treemapSliceDice=function(n,r,t,e,i){(1&n.depth?U:O)(n,r,t,e,i)},n.treemapSquarify=X,Object.defineProperty(n,"__esModule",{value:!0})}));
diff --git a/node_modules/d3-hierarchy/package.json b/node_modules/d3-hierarchy/package.json
new file mode 100644
index 00000000..d3739915
--- /dev/null
+++ b/node_modules/d3-hierarchy/package.json
@@ -0,0 +1,84 @@
+{
+ "_from": "d3-hierarchy@3",
+ "_id": "d3-hierarchy@3.1.2",
+ "_inBundle": false,
+ "_integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==",
+ "_location": "/d3-hierarchy",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "range",
+ "registry": true,
+ "raw": "d3-hierarchy@3",
+ "name": "d3-hierarchy",
+ "escapedName": "d3-hierarchy",
+ "rawSpec": "3",
+ "saveSpec": null,
+ "fetchSpec": "3"
+ },
+ "_requiredBy": [
+ "/d3"
+ ],
+ "_resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz",
+ "_shasum": "b01cd42c1eed3d46db77a5966cf726f8c09160c6",
+ "_spec": "d3-hierarchy@3",
+ "_where": "C:\\Users\\colbs\\CS4241\\d3a4\\node_modules\\d3",
+ "author": {
+ "name": "Mike Bostock",
+ "url": "http://bost.ocks.org/mike"
+ },
+ "bugs": {
+ "url": "https://github.com/d3/d3-hierarchy/issues"
+ },
+ "bundleDependencies": false,
+ "deprecated": false,
+ "description": "Layout algorithms for visualizing hierarchical data.",
+ "devDependencies": {
+ "benchmark": "2",
+ "d3-array": "1.2.0 - 3",
+ "d3-dsv": "1 - 3",
+ "d3-random": "1.1.0 - 3",
+ "eslint": "8",
+ "mocha": "9",
+ "rollup": "2",
+ "rollup-plugin-terser": "7"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "exports": {
+ "umd": "./dist/d3-hierarchy.min.js",
+ "default": "./src/index.js"
+ },
+ "files": [
+ "dist/**/*.js",
+ "src/**/*.js"
+ ],
+ "homepage": "https://d3js.org/d3-hierarchy/",
+ "jsdelivr": "dist/d3-hierarchy.min.js",
+ "keywords": [
+ "d3",
+ "d3-module",
+ "layout",
+ "tree",
+ "treemap",
+ "hierarchy",
+ "infovis"
+ ],
+ "license": "ISC",
+ "main": "src/index.js",
+ "module": "src/index.js",
+ "name": "d3-hierarchy",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/d3/d3-hierarchy.git"
+ },
+ "scripts": {
+ "postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -",
+ "prepublishOnly": "rm -rf dist && yarn test && rollup -c",
+ "test": "mocha 'test/**/*-test.js' && eslint src test"
+ },
+ "sideEffects": false,
+ "type": "module",
+ "unpkg": "dist/d3-hierarchy.min.js",
+ "version": "3.1.2"
+}
diff --git a/node_modules/d3-hierarchy/src/accessors.js b/node_modules/d3-hierarchy/src/accessors.js
new file mode 100644
index 00000000..369c4145
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/accessors.js
@@ -0,0 +1,8 @@
+export function optional(f) {
+ return f == null ? null : required(f);
+}
+
+export function required(f) {
+ if (typeof f !== "function") throw new Error;
+ return f;
+}
diff --git a/node_modules/d3-hierarchy/src/array.js b/node_modules/d3-hierarchy/src/array.js
new file mode 100644
index 00000000..b46d1b9c
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/array.js
@@ -0,0 +1,20 @@
+export default function(x) {
+ return typeof x === "object" && "length" in x
+ ? x // Array, TypedArray, NodeList, array-like
+ : Array.from(x); // Map, Set, iterable, string, or anything else
+}
+
+export function shuffle(array, random) {
+ let m = array.length,
+ t,
+ i;
+
+ while (m) {
+ i = random() * m-- | 0;
+ t = array[m];
+ array[m] = array[i];
+ array[i] = t;
+ }
+
+ return array;
+}
diff --git a/node_modules/d3-hierarchy/src/cluster.js b/node_modules/d3-hierarchy/src/cluster.js
new file mode 100644
index 00000000..f5a280e2
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/cluster.js
@@ -0,0 +1,84 @@
+function defaultSeparation(a, b) {
+ return a.parent === b.parent ? 1 : 2;
+}
+
+function meanX(children) {
+ return children.reduce(meanXReduce, 0) / children.length;
+}
+
+function meanXReduce(x, c) {
+ return x + c.x;
+}
+
+function maxY(children) {
+ return 1 + children.reduce(maxYReduce, 0);
+}
+
+function maxYReduce(y, c) {
+ return Math.max(y, c.y);
+}
+
+function leafLeft(node) {
+ var children;
+ while (children = node.children) node = children[0];
+ return node;
+}
+
+function leafRight(node) {
+ var children;
+ while (children = node.children) node = children[children.length - 1];
+ return node;
+}
+
+export default function() {
+ var separation = defaultSeparation,
+ dx = 1,
+ dy = 1,
+ nodeSize = false;
+
+ function cluster(root) {
+ var previousNode,
+ x = 0;
+
+ // First walk, computing the initial x & y values.
+ root.eachAfter(function(node) {
+ var children = node.children;
+ if (children) {
+ node.x = meanX(children);
+ node.y = maxY(children);
+ } else {
+ node.x = previousNode ? x += separation(node, previousNode) : 0;
+ node.y = 0;
+ previousNode = node;
+ }
+ });
+
+ var left = leafLeft(root),
+ right = leafRight(root),
+ x0 = left.x - separation(left, right) / 2,
+ x1 = right.x + separation(right, left) / 2;
+
+ // Second walk, normalizing x & y to the desired size.
+ return root.eachAfter(nodeSize ? function(node) {
+ node.x = (node.x - root.x) * dx;
+ node.y = (root.y - node.y) * dy;
+ } : function(node) {
+ node.x = (node.x - x0) / (x1 - x0) * dx;
+ node.y = (1 - (root.y ? node.y / root.y : 1)) * dy;
+ });
+ }
+
+ cluster.separation = function(x) {
+ return arguments.length ? (separation = x, cluster) : separation;
+ };
+
+ cluster.size = function(x) {
+ return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? null : [dx, dy]);
+ };
+
+ cluster.nodeSize = function(x) {
+ return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], cluster) : (nodeSize ? [dx, dy] : null);
+ };
+
+ return cluster;
+}
diff --git a/node_modules/d3-hierarchy/src/constant.js b/node_modules/d3-hierarchy/src/constant.js
new file mode 100644
index 00000000..1d947c4f
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/constant.js
@@ -0,0 +1,9 @@
+export function constantZero() {
+ return 0;
+}
+
+export default function(x) {
+ return function() {
+ return x;
+ };
+}
diff --git a/node_modules/d3-hierarchy/src/hierarchy/ancestors.js b/node_modules/d3-hierarchy/src/hierarchy/ancestors.js
new file mode 100644
index 00000000..f70c7264
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/hierarchy/ancestors.js
@@ -0,0 +1,7 @@
+export default function() {
+ var node = this, nodes = [node];
+ while (node = node.parent) {
+ nodes.push(node);
+ }
+ return nodes;
+}
diff --git a/node_modules/d3-hierarchy/src/hierarchy/count.js b/node_modules/d3-hierarchy/src/hierarchy/count.js
new file mode 100644
index 00000000..0b90f1bd
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/hierarchy/count.js
@@ -0,0 +1,12 @@
+function count(node) {
+ var sum = 0,
+ children = node.children,
+ i = children && children.length;
+ if (!i) sum = 1;
+ else while (--i >= 0) sum += children[i].value;
+ node.value = sum;
+}
+
+export default function() {
+ return this.eachAfter(count);
+}
diff --git a/node_modules/d3-hierarchy/src/hierarchy/descendants.js b/node_modules/d3-hierarchy/src/hierarchy/descendants.js
new file mode 100644
index 00000000..7f38090d
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/hierarchy/descendants.js
@@ -0,0 +1,3 @@
+export default function() {
+ return Array.from(this);
+}
diff --git a/node_modules/d3-hierarchy/src/hierarchy/each.js b/node_modules/d3-hierarchy/src/hierarchy/each.js
new file mode 100644
index 00000000..af911cc7
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/hierarchy/each.js
@@ -0,0 +1,7 @@
+export default function(callback, that) {
+ let index = -1;
+ for (const node of this) {
+ callback.call(that, node, ++index, this);
+ }
+ return this;
+}
diff --git a/node_modules/d3-hierarchy/src/hierarchy/eachAfter.js b/node_modules/d3-hierarchy/src/hierarchy/eachAfter.js
new file mode 100644
index 00000000..a3f0a2c0
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/hierarchy/eachAfter.js
@@ -0,0 +1,15 @@
+export default function(callback, that) {
+ var node = this, nodes = [node], next = [], children, i, n, index = -1;
+ while (node = nodes.pop()) {
+ next.push(node);
+ if (children = node.children) {
+ for (i = 0, n = children.length; i < n; ++i) {
+ nodes.push(children[i]);
+ }
+ }
+ }
+ while (node = next.pop()) {
+ callback.call(that, node, ++index, this);
+ }
+ return this;
+}
diff --git a/node_modules/d3-hierarchy/src/hierarchy/eachBefore.js b/node_modules/d3-hierarchy/src/hierarchy/eachBefore.js
new file mode 100644
index 00000000..f3cd524b
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/hierarchy/eachBefore.js
@@ -0,0 +1,12 @@
+export default function(callback, that) {
+ var node = this, nodes = [node], children, i, index = -1;
+ while (node = nodes.pop()) {
+ callback.call(that, node, ++index, this);
+ if (children = node.children) {
+ for (i = children.length - 1; i >= 0; --i) {
+ nodes.push(children[i]);
+ }
+ }
+ }
+ return this;
+}
diff --git a/node_modules/d3-hierarchy/src/hierarchy/find.js b/node_modules/d3-hierarchy/src/hierarchy/find.js
new file mode 100644
index 00000000..f4ed8c68
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/hierarchy/find.js
@@ -0,0 +1,8 @@
+export default function(callback, that) {
+ let index = -1;
+ for (const node of this) {
+ if (callback.call(that, node, ++index, this)) {
+ return node;
+ }
+ }
+}
diff --git a/node_modules/d3-hierarchy/src/hierarchy/index.js b/node_modules/d3-hierarchy/src/hierarchy/index.js
new file mode 100644
index 00000000..b9c1026f
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/hierarchy/index.js
@@ -0,0 +1,91 @@
+import node_count from "./count.js";
+import node_each from "./each.js";
+import node_eachBefore from "./eachBefore.js";
+import node_eachAfter from "./eachAfter.js";
+import node_find from "./find.js";
+import node_sum from "./sum.js";
+import node_sort from "./sort.js";
+import node_path from "./path.js";
+import node_ancestors from "./ancestors.js";
+import node_descendants from "./descendants.js";
+import node_leaves from "./leaves.js";
+import node_links from "./links.js";
+import node_iterator from "./iterator.js";
+
+export default function hierarchy(data, children) {
+ if (data instanceof Map) {
+ data = [undefined, data];
+ if (children === undefined) children = mapChildren;
+ } else if (children === undefined) {
+ children = objectChildren;
+ }
+
+ var root = new Node(data),
+ node,
+ nodes = [root],
+ child,
+ childs,
+ i,
+ n;
+
+ while (node = nodes.pop()) {
+ if ((childs = children(node.data)) && (n = (childs = Array.from(childs)).length)) {
+ node.children = childs;
+ for (i = n - 1; i >= 0; --i) {
+ nodes.push(child = childs[i] = new Node(childs[i]));
+ child.parent = node;
+ child.depth = node.depth + 1;
+ }
+ }
+ }
+
+ return root.eachBefore(computeHeight);
+}
+
+function node_copy() {
+ return hierarchy(this).eachBefore(copyData);
+}
+
+function objectChildren(d) {
+ return d.children;
+}
+
+function mapChildren(d) {
+ return Array.isArray(d) ? d[1] : null;
+}
+
+function copyData(node) {
+ if (node.data.value !== undefined) node.value = node.data.value;
+ node.data = node.data.data;
+}
+
+export function computeHeight(node) {
+ var height = 0;
+ do node.height = height;
+ while ((node = node.parent) && (node.height < ++height));
+}
+
+export function Node(data) {
+ this.data = data;
+ this.depth =
+ this.height = 0;
+ this.parent = null;
+}
+
+Node.prototype = hierarchy.prototype = {
+ constructor: Node,
+ count: node_count,
+ each: node_each,
+ eachAfter: node_eachAfter,
+ eachBefore: node_eachBefore,
+ find: node_find,
+ sum: node_sum,
+ sort: node_sort,
+ path: node_path,
+ ancestors: node_ancestors,
+ descendants: node_descendants,
+ leaves: node_leaves,
+ links: node_links,
+ copy: node_copy,
+ [Symbol.iterator]: node_iterator
+};
diff --git a/node_modules/d3-hierarchy/src/hierarchy/iterator.js b/node_modules/d3-hierarchy/src/hierarchy/iterator.js
new file mode 100644
index 00000000..7e06b620
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/hierarchy/iterator.js
@@ -0,0 +1,14 @@
+export default function*() {
+ var node = this, current, next = [node], children, i, n;
+ do {
+ current = next.reverse(), next = [];
+ while (node = current.pop()) {
+ yield node;
+ if (children = node.children) {
+ for (i = 0, n = children.length; i < n; ++i) {
+ next.push(children[i]);
+ }
+ }
+ }
+ } while (next.length);
+}
diff --git a/node_modules/d3-hierarchy/src/hierarchy/leaves.js b/node_modules/d3-hierarchy/src/hierarchy/leaves.js
new file mode 100644
index 00000000..401c5b53
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/hierarchy/leaves.js
@@ -0,0 +1,9 @@
+export default function() {
+ var leaves = [];
+ this.eachBefore(function(node) {
+ if (!node.children) {
+ leaves.push(node);
+ }
+ });
+ return leaves;
+}
diff --git a/node_modules/d3-hierarchy/src/hierarchy/links.js b/node_modules/d3-hierarchy/src/hierarchy/links.js
new file mode 100644
index 00000000..6fcb82fa
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/hierarchy/links.js
@@ -0,0 +1,9 @@
+export default function() {
+ var root = this, links = [];
+ root.each(function(node) {
+ if (node !== root) { // Don’t include the root’s parent, if any.
+ links.push({source: node.parent, target: node});
+ }
+ });
+ return links;
+}
diff --git a/node_modules/d3-hierarchy/src/hierarchy/path.js b/node_modules/d3-hierarchy/src/hierarchy/path.js
new file mode 100644
index 00000000..99589138
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/hierarchy/path.js
@@ -0,0 +1,30 @@
+export default function(end) {
+ var start = this,
+ ancestor = leastCommonAncestor(start, end),
+ nodes = [start];
+ while (start !== ancestor) {
+ start = start.parent;
+ nodes.push(start);
+ }
+ var k = nodes.length;
+ while (end !== ancestor) {
+ nodes.splice(k, 0, end);
+ end = end.parent;
+ }
+ return nodes;
+}
+
+function leastCommonAncestor(a, b) {
+ if (a === b) return a;
+ var aNodes = a.ancestors(),
+ bNodes = b.ancestors(),
+ c = null;
+ a = aNodes.pop();
+ b = bNodes.pop();
+ while (a === b) {
+ c = a;
+ a = aNodes.pop();
+ b = bNodes.pop();
+ }
+ return c;
+}
diff --git a/node_modules/d3-hierarchy/src/hierarchy/sort.js b/node_modules/d3-hierarchy/src/hierarchy/sort.js
new file mode 100644
index 00000000..5d0426d5
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/hierarchy/sort.js
@@ -0,0 +1,7 @@
+export default function(compare) {
+ return this.eachBefore(function(node) {
+ if (node.children) {
+ node.children.sort(compare);
+ }
+ });
+}
diff --git a/node_modules/d3-hierarchy/src/hierarchy/sum.js b/node_modules/d3-hierarchy/src/hierarchy/sum.js
new file mode 100644
index 00000000..350a965e
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/hierarchy/sum.js
@@ -0,0 +1,9 @@
+export default function(value) {
+ return this.eachAfter(function(node) {
+ var sum = +value(node.data) || 0,
+ children = node.children,
+ i = children && children.length;
+ while (--i >= 0) sum += children[i].value;
+ node.value = sum;
+ });
+}
diff --git a/node_modules/d3-hierarchy/src/index.js b/node_modules/d3-hierarchy/src/index.js
new file mode 100644
index 00000000..e5952b18
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/index.js
@@ -0,0 +1,15 @@
+export {default as cluster} from "./cluster.js";
+export {default as hierarchy, Node} from "./hierarchy/index.js";
+export {default as pack} from "./pack/index.js";
+export {default as packSiblings} from "./pack/siblings.js";
+export {default as packEnclose} from "./pack/enclose.js";
+export {default as partition} from "./partition.js";
+export {default as stratify} from "./stratify.js";
+export {default as tree} from "./tree.js";
+export {default as treemap} from "./treemap/index.js";
+export {default as treemapBinary} from "./treemap/binary.js";
+export {default as treemapDice} from "./treemap/dice.js";
+export {default as treemapSlice} from "./treemap/slice.js";
+export {default as treemapSliceDice} from "./treemap/sliceDice.js";
+export {default as treemapSquarify} from "./treemap/squarify.js";
+export {default as treemapResquarify} from "./treemap/resquarify.js";
diff --git a/node_modules/d3-hierarchy/src/lcg.js b/node_modules/d3-hierarchy/src/lcg.js
new file mode 100644
index 00000000..a13cf79e
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/lcg.js
@@ -0,0 +1,9 @@
+// https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use
+const a = 1664525;
+const c = 1013904223;
+const m = 4294967296; // 2^32
+
+export default function() {
+ let s = 1;
+ return () => (s = (a * s + c) % m) / m;
+}
diff --git a/node_modules/d3-hierarchy/src/pack/enclose.js b/node_modules/d3-hierarchy/src/pack/enclose.js
new file mode 100644
index 00000000..f6eb67f1
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/pack/enclose.js
@@ -0,0 +1,123 @@
+import {shuffle} from "../array.js";
+import lcg from "../lcg.js";
+
+export default function(circles) {
+ return packEncloseRandom(circles, lcg());
+}
+
+export function packEncloseRandom(circles, random) {
+ var i = 0, n = (circles = shuffle(Array.from(circles), random)).length, B = [], p, e;
+
+ while (i < n) {
+ p = circles[i];
+ if (e && enclosesWeak(e, p)) ++i;
+ else e = encloseBasis(B = extendBasis(B, p)), i = 0;
+ }
+
+ return e;
+}
+
+function extendBasis(B, p) {
+ var i, j;
+
+ if (enclosesWeakAll(p, B)) return [p];
+
+ // If we get here then B must have at least one element.
+ for (i = 0; i < B.length; ++i) {
+ if (enclosesNot(p, B[i])
+ && enclosesWeakAll(encloseBasis2(B[i], p), B)) {
+ return [B[i], p];
+ }
+ }
+
+ // If we get here then B must have at least two elements.
+ for (i = 0; i < B.length - 1; ++i) {
+ for (j = i + 1; j < B.length; ++j) {
+ if (enclosesNot(encloseBasis2(B[i], B[j]), p)
+ && enclosesNot(encloseBasis2(B[i], p), B[j])
+ && enclosesNot(encloseBasis2(B[j], p), B[i])
+ && enclosesWeakAll(encloseBasis3(B[i], B[j], p), B)) {
+ return [B[i], B[j], p];
+ }
+ }
+ }
+
+ // If we get here then something is very wrong.
+ throw new Error;
+}
+
+function enclosesNot(a, b) {
+ var dr = a.r - b.r, dx = b.x - a.x, dy = b.y - a.y;
+ return dr < 0 || dr * dr < dx * dx + dy * dy;
+}
+
+function enclosesWeak(a, b) {
+ var dr = a.r - b.r + Math.max(a.r, b.r, 1) * 1e-9, dx = b.x - a.x, dy = b.y - a.y;
+ return dr > 0 && dr * dr > dx * dx + dy * dy;
+}
+
+function enclosesWeakAll(a, B) {
+ for (var i = 0; i < B.length; ++i) {
+ if (!enclosesWeak(a, B[i])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+function encloseBasis(B) {
+ switch (B.length) {
+ case 1: return encloseBasis1(B[0]);
+ case 2: return encloseBasis2(B[0], B[1]);
+ case 3: return encloseBasis3(B[0], B[1], B[2]);
+ }
+}
+
+function encloseBasis1(a) {
+ return {
+ x: a.x,
+ y: a.y,
+ r: a.r
+ };
+}
+
+function encloseBasis2(a, b) {
+ var x1 = a.x, y1 = a.y, r1 = a.r,
+ x2 = b.x, y2 = b.y, r2 = b.r,
+ x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1,
+ l = Math.sqrt(x21 * x21 + y21 * y21);
+ return {
+ x: (x1 + x2 + x21 / l * r21) / 2,
+ y: (y1 + y2 + y21 / l * r21) / 2,
+ r: (l + r1 + r2) / 2
+ };
+}
+
+function encloseBasis3(a, b, c) {
+ var x1 = a.x, y1 = a.y, r1 = a.r,
+ x2 = b.x, y2 = b.y, r2 = b.r,
+ x3 = c.x, y3 = c.y, r3 = c.r,
+ a2 = x1 - x2,
+ a3 = x1 - x3,
+ b2 = y1 - y2,
+ b3 = y1 - y3,
+ c2 = r2 - r1,
+ c3 = r3 - r1,
+ d1 = x1 * x1 + y1 * y1 - r1 * r1,
+ d2 = d1 - x2 * x2 - y2 * y2 + r2 * r2,
+ d3 = d1 - x3 * x3 - y3 * y3 + r3 * r3,
+ ab = a3 * b2 - a2 * b3,
+ xa = (b2 * d3 - b3 * d2) / (ab * 2) - x1,
+ xb = (b3 * c2 - b2 * c3) / ab,
+ ya = (a3 * d2 - a2 * d3) / (ab * 2) - y1,
+ yb = (a2 * c3 - a3 * c2) / ab,
+ A = xb * xb + yb * yb - 1,
+ B = 2 * (r1 + xa * xb + ya * yb),
+ C = xa * xa + ya * ya - r1 * r1,
+ r = -(Math.abs(A) > 1e-6 ? (B + Math.sqrt(B * B - 4 * A * C)) / (2 * A) : C / B);
+ return {
+ x: x1 + xa + xb * r,
+ y: y1 + ya + yb * r,
+ r: r
+ };
+}
diff --git a/node_modules/d3-hierarchy/src/pack/index.js b/node_modules/d3-hierarchy/src/pack/index.js
new file mode 100644
index 00000000..8b710b3f
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/pack/index.js
@@ -0,0 +1,81 @@
+import {optional} from "../accessors.js";
+import constant, {constantZero} from "../constant.js";
+import lcg from "../lcg.js";
+import {packSiblingsRandom} from "./siblings.js";
+
+function defaultRadius(d) {
+ return Math.sqrt(d.value);
+}
+
+export default function() {
+ var radius = null,
+ dx = 1,
+ dy = 1,
+ padding = constantZero;
+
+ function pack(root) {
+ const random = lcg();
+ root.x = dx / 2, root.y = dy / 2;
+ if (radius) {
+ root.eachBefore(radiusLeaf(radius))
+ .eachAfter(packChildrenRandom(padding, 0.5, random))
+ .eachBefore(translateChild(1));
+ } else {
+ root.eachBefore(radiusLeaf(defaultRadius))
+ .eachAfter(packChildrenRandom(constantZero, 1, random))
+ .eachAfter(packChildrenRandom(padding, root.r / Math.min(dx, dy), random))
+ .eachBefore(translateChild(Math.min(dx, dy) / (2 * root.r)));
+ }
+ return root;
+ }
+
+ pack.radius = function(x) {
+ return arguments.length ? (radius = optional(x), pack) : radius;
+ };
+
+ pack.size = function(x) {
+ return arguments.length ? (dx = +x[0], dy = +x[1], pack) : [dx, dy];
+ };
+
+ pack.padding = function(x) {
+ return arguments.length ? (padding = typeof x === "function" ? x : constant(+x), pack) : padding;
+ };
+
+ return pack;
+}
+
+function radiusLeaf(radius) {
+ return function(node) {
+ if (!node.children) {
+ node.r = Math.max(0, +radius(node) || 0);
+ }
+ };
+}
+
+function packChildrenRandom(padding, k, random) {
+ return function(node) {
+ if (children = node.children) {
+ var children,
+ i,
+ n = children.length,
+ r = padding(node) * k || 0,
+ e;
+
+ if (r) for (i = 0; i < n; ++i) children[i].r += r;
+ e = packSiblingsRandom(children, random);
+ if (r) for (i = 0; i < n; ++i) children[i].r -= r;
+ node.r = e + r;
+ }
+ };
+}
+
+function translateChild(k) {
+ return function(node) {
+ var parent = node.parent;
+ node.r *= k;
+ if (parent) {
+ node.x = parent.x + k * node.x;
+ node.y = parent.y + k * node.y;
+ }
+ };
+}
diff --git a/node_modules/d3-hierarchy/src/pack/siblings.js b/node_modules/d3-hierarchy/src/pack/siblings.js
new file mode 100644
index 00000000..e7f5df46
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/pack/siblings.js
@@ -0,0 +1,120 @@
+import array from "../array.js";
+import lcg from "../lcg.js";
+import {packEncloseRandom} from "./enclose.js";
+
+function place(b, a, c) {
+ var dx = b.x - a.x, x, a2,
+ dy = b.y - a.y, y, b2,
+ d2 = dx * dx + dy * dy;
+ if (d2) {
+ a2 = a.r + c.r, a2 *= a2;
+ b2 = b.r + c.r, b2 *= b2;
+ if (a2 > b2) {
+ x = (d2 + b2 - a2) / (2 * d2);
+ y = Math.sqrt(Math.max(0, b2 / d2 - x * x));
+ c.x = b.x - x * dx - y * dy;
+ c.y = b.y - x * dy + y * dx;
+ } else {
+ x = (d2 + a2 - b2) / (2 * d2);
+ y = Math.sqrt(Math.max(0, a2 / d2 - x * x));
+ c.x = a.x + x * dx - y * dy;
+ c.y = a.y + x * dy + y * dx;
+ }
+ } else {
+ c.x = a.x + c.r;
+ c.y = a.y;
+ }
+}
+
+function intersects(a, b) {
+ var dr = a.r + b.r - 1e-6, dx = b.x - a.x, dy = b.y - a.y;
+ return dr > 0 && dr * dr > dx * dx + dy * dy;
+}
+
+function score(node) {
+ var a = node._,
+ b = node.next._,
+ ab = a.r + b.r,
+ dx = (a.x * b.r + b.x * a.r) / ab,
+ dy = (a.y * b.r + b.y * a.r) / ab;
+ return dx * dx + dy * dy;
+}
+
+function Node(circle) {
+ this._ = circle;
+ this.next = null;
+ this.previous = null;
+}
+
+export function packSiblingsRandom(circles, random) {
+ if (!(n = (circles = array(circles)).length)) return 0;
+
+ var a, b, c, n, aa, ca, i, j, k, sj, sk;
+
+ // Place the first circle.
+ a = circles[0], a.x = 0, a.y = 0;
+ if (!(n > 1)) return a.r;
+
+ // Place the second circle.
+ b = circles[1], a.x = -b.r, b.x = a.r, b.y = 0;
+ if (!(n > 2)) return a.r + b.r;
+
+ // Place the third circle.
+ place(b, a, c = circles[2]);
+
+ // Initialize the front-chain using the first three circles a, b and c.
+ a = new Node(a), b = new Node(b), c = new Node(c);
+ a.next = c.previous = b;
+ b.next = a.previous = c;
+ c.next = b.previous = a;
+
+ // Attempt to place each remaining circle…
+ pack: for (i = 3; i < n; ++i) {
+ place(a._, b._, c = circles[i]), c = new Node(c);
+
+ // Find the closest intersecting circle on the front-chain, if any.
+ // “Closeness” is determined by linear distance along the front-chain.
+ // “Ahead” or “behind” is likewise determined by linear distance.
+ j = b.next, k = a.previous, sj = b._.r, sk = a._.r;
+ do {
+ if (sj <= sk) {
+ if (intersects(j._, c._)) {
+ b = j, a.next = b, b.previous = a, --i;
+ continue pack;
+ }
+ sj += j._.r, j = j.next;
+ } else {
+ if (intersects(k._, c._)) {
+ a = k, a.next = b, b.previous = a, --i;
+ continue pack;
+ }
+ sk += k._.r, k = k.previous;
+ }
+ } while (j !== k.next);
+
+ // Success! Insert the new circle c between a and b.
+ c.previous = a, c.next = b, a.next = b.previous = b = c;
+
+ // Compute the new closest circle pair to the centroid.
+ aa = score(a);
+ while ((c = c.next) !== b) {
+ if ((ca = score(c)) < aa) {
+ a = c, aa = ca;
+ }
+ }
+ b = a.next;
+ }
+
+ // Compute the enclosing circle of the front chain.
+ a = [b._], c = b; while ((c = c.next) !== b) a.push(c._); c = packEncloseRandom(a, random);
+
+ // Translate the circles to put the enclosing circle around the origin.
+ for (i = 0; i < n; ++i) a = circles[i], a.x -= c.x, a.y -= c.y;
+
+ return c.r;
+}
+
+export default function(circles) {
+ packSiblingsRandom(circles, lcg());
+ return circles;
+}
diff --git a/node_modules/d3-hierarchy/src/partition.js b/node_modules/d3-hierarchy/src/partition.js
new file mode 100644
index 00000000..0165ef73
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/partition.js
@@ -0,0 +1,52 @@
+import roundNode from "./treemap/round.js";
+import treemapDice from "./treemap/dice.js";
+
+export default function() {
+ var dx = 1,
+ dy = 1,
+ padding = 0,
+ round = false;
+
+ function partition(root) {
+ var n = root.height + 1;
+ root.x0 =
+ root.y0 = padding;
+ root.x1 = dx;
+ root.y1 = dy / n;
+ root.eachBefore(positionNode(dy, n));
+ if (round) root.eachBefore(roundNode);
+ return root;
+ }
+
+ function positionNode(dy, n) {
+ return function(node) {
+ if (node.children) {
+ treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n);
+ }
+ var x0 = node.x0,
+ y0 = node.y0,
+ x1 = node.x1 - padding,
+ y1 = node.y1 - padding;
+ if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
+ if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
+ node.x0 = x0;
+ node.y0 = y0;
+ node.x1 = x1;
+ node.y1 = y1;
+ };
+ }
+
+ partition.round = function(x) {
+ return arguments.length ? (round = !!x, partition) : round;
+ };
+
+ partition.size = function(x) {
+ return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy];
+ };
+
+ partition.padding = function(x) {
+ return arguments.length ? (padding = +x, partition) : padding;
+ };
+
+ return partition;
+}
diff --git a/node_modules/d3-hierarchy/src/stratify.js b/node_modules/d3-hierarchy/src/stratify.js
new file mode 100644
index 00000000..d113100d
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/stratify.js
@@ -0,0 +1,145 @@
+import {optional} from "./accessors.js";
+import {Node, computeHeight} from "./hierarchy/index.js";
+
+var preroot = {depth: -1},
+ ambiguous = {},
+ imputed = {};
+
+function defaultId(d) {
+ return d.id;
+}
+
+function defaultParentId(d) {
+ return d.parentId;
+}
+
+export default function() {
+ var id = defaultId,
+ parentId = defaultParentId,
+ path;
+
+ function stratify(data) {
+ var nodes = Array.from(data),
+ currentId = id,
+ currentParentId = parentId,
+ n,
+ d,
+ i,
+ root,
+ parent,
+ node,
+ nodeId,
+ nodeKey,
+ nodeByKey = new Map;
+
+ if (path != null) {
+ const I = nodes.map((d, i) => normalize(path(d, i, data)));
+ const P = I.map(parentof);
+ const S = new Set(I).add("");
+ for (const i of P) {
+ if (!S.has(i)) {
+ S.add(i);
+ I.push(i);
+ P.push(parentof(i));
+ nodes.push(imputed);
+ }
+ }
+ currentId = (_, i) => I[i];
+ currentParentId = (_, i) => P[i];
+ }
+
+ for (i = 0, n = nodes.length; i < n; ++i) {
+ d = nodes[i], node = nodes[i] = new Node(d);
+ if ((nodeId = currentId(d, i, data)) != null && (nodeId += "")) {
+ nodeKey = node.id = nodeId;
+ nodeByKey.set(nodeKey, nodeByKey.has(nodeKey) ? ambiguous : node);
+ }
+ if ((nodeId = currentParentId(d, i, data)) != null && (nodeId += "")) {
+ node.parent = nodeId;
+ }
+ }
+
+ for (i = 0; i < n; ++i) {
+ node = nodes[i];
+ if (nodeId = node.parent) {
+ parent = nodeByKey.get(nodeId);
+ if (!parent) throw new Error("missing: " + nodeId);
+ if (parent === ambiguous) throw new Error("ambiguous: " + nodeId);
+ if (parent.children) parent.children.push(node);
+ else parent.children = [node];
+ node.parent = parent;
+ } else {
+ if (root) throw new Error("multiple roots");
+ root = node;
+ }
+ }
+
+ if (!root) throw new Error("no root");
+
+ // When imputing internal nodes, only introduce roots if needed.
+ // Then replace the imputed marker data with null.
+ if (path != null) {
+ while (root.data === imputed && root.children.length === 1) {
+ root = root.children[0], --n;
+ }
+ for (let i = nodes.length - 1; i >= 0; --i) {
+ node = nodes[i];
+ if (node.data !== imputed) break;
+ node.data = null;
+ }
+ }
+
+ root.parent = preroot;
+ root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight);
+ root.parent = null;
+ if (n > 0) throw new Error("cycle");
+
+ return root;
+ }
+
+ stratify.id = function(x) {
+ return arguments.length ? (id = optional(x), stratify) : id;
+ };
+
+ stratify.parentId = function(x) {
+ return arguments.length ? (parentId = optional(x), stratify) : parentId;
+ };
+
+ stratify.path = function(x) {
+ return arguments.length ? (path = optional(x), stratify) : path;
+ };
+
+ return stratify;
+}
+
+// To normalize a path, we coerce to a string, strip the trailing slash if any
+// (as long as the trailing slash is not immediately preceded by another slash),
+// and add leading slash if missing.
+function normalize(path) {
+ path = `${path}`;
+ let i = path.length;
+ if (slash(path, i - 1) && !slash(path, i - 2)) path = path.slice(0, -1);
+ return path[0] === "/" ? path : `/${path}`;
+}
+
+// Walk backwards to find the first slash that is not the leading slash, e.g.:
+// "/foo/bar" ⇥ "/foo", "/foo" ⇥ "/", "/" ↦ "". (The root is special-cased
+// because the id of the root must be a truthy value.)
+function parentof(path) {
+ let i = path.length;
+ if (i < 2) return "";
+ while (--i > 1) if (slash(path, i)) break;
+ return path.slice(0, i);
+}
+
+// Slashes can be escaped; to determine whether a slash is a path delimiter, we
+// count the number of preceding backslashes escaping the forward slash: an odd
+// number indicates an escaped forward slash.
+function slash(path, i) {
+ if (path[i] === "/") {
+ let k = 0;
+ while (i > 0 && path[--i] === "\\") ++k;
+ if ((k & 1) === 0) return true;
+ }
+ return false;
+}
diff --git a/node_modules/d3-hierarchy/src/tree.js b/node_modules/d3-hierarchy/src/tree.js
new file mode 100644
index 00000000..dc4275e4
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/tree.js
@@ -0,0 +1,237 @@
+import {Node} from "./hierarchy/index.js";
+
+function defaultSeparation(a, b) {
+ return a.parent === b.parent ? 1 : 2;
+}
+
+// function radialSeparation(a, b) {
+// return (a.parent === b.parent ? 1 : 2) / a.depth;
+// }
+
+// This function is used to traverse the left contour of a subtree (or
+// subforest). It returns the successor of v on this contour. This successor is
+// either given by the leftmost child of v or by the thread of v. The function
+// returns null if and only if v is on the highest level of its subtree.
+function nextLeft(v) {
+ var children = v.children;
+ return children ? children[0] : v.t;
+}
+
+// This function works analogously to nextLeft.
+function nextRight(v) {
+ var children = v.children;
+ return children ? children[children.length - 1] : v.t;
+}
+
+// Shifts the current subtree rooted at w+. This is done by increasing
+// prelim(w+) and mod(w+) by shift.
+function moveSubtree(wm, wp, shift) {
+ var change = shift / (wp.i - wm.i);
+ wp.c -= change;
+ wp.s += shift;
+ wm.c += change;
+ wp.z += shift;
+ wp.m += shift;
+}
+
+// All other shifts, applied to the smaller subtrees between w- and w+, are
+// performed by this function. To prepare the shifts, we have to adjust
+// change(w+), shift(w+), and change(w-).
+function executeShifts(v) {
+ var shift = 0,
+ change = 0,
+ children = v.children,
+ i = children.length,
+ w;
+ while (--i >= 0) {
+ w = children[i];
+ w.z += shift;
+ w.m += shift;
+ shift += w.s + (change += w.c);
+ }
+}
+
+// If vi-’s ancestor is a sibling of v, returns vi-’s ancestor. Otherwise,
+// returns the specified (default) ancestor.
+function nextAncestor(vim, v, ancestor) {
+ return vim.a.parent === v.parent ? vim.a : ancestor;
+}
+
+function TreeNode(node, i) {
+ this._ = node;
+ this.parent = null;
+ this.children = null;
+ this.A = null; // default ancestor
+ this.a = this; // ancestor
+ this.z = 0; // prelim
+ this.m = 0; // mod
+ this.c = 0; // change
+ this.s = 0; // shift
+ this.t = null; // thread
+ this.i = i; // number
+}
+
+TreeNode.prototype = Object.create(Node.prototype);
+
+function treeRoot(root) {
+ var tree = new TreeNode(root, 0),
+ node,
+ nodes = [tree],
+ child,
+ children,
+ i,
+ n;
+
+ while (node = nodes.pop()) {
+ if (children = node._.children) {
+ node.children = new Array(n = children.length);
+ for (i = n - 1; i >= 0; --i) {
+ nodes.push(child = node.children[i] = new TreeNode(children[i], i));
+ child.parent = node;
+ }
+ }
+ }
+
+ (tree.parent = new TreeNode(null, 0)).children = [tree];
+ return tree;
+}
+
+// Node-link tree diagram using the Reingold-Tilford "tidy" algorithm
+export default function() {
+ var separation = defaultSeparation,
+ dx = 1,
+ dy = 1,
+ nodeSize = null;
+
+ function tree(root) {
+ var t = treeRoot(root);
+
+ // Compute the layout using Buchheim et al.’s algorithm.
+ t.eachAfter(firstWalk), t.parent.m = -t.z;
+ t.eachBefore(secondWalk);
+
+ // If a fixed node size is specified, scale x and y.
+ if (nodeSize) root.eachBefore(sizeNode);
+
+ // If a fixed tree size is specified, scale x and y based on the extent.
+ // Compute the left-most, right-most, and depth-most nodes for extents.
+ else {
+ var left = root,
+ right = root,
+ bottom = root;
+ root.eachBefore(function(node) {
+ if (node.x < left.x) left = node;
+ if (node.x > right.x) right = node;
+ if (node.depth > bottom.depth) bottom = node;
+ });
+ var s = left === right ? 1 : separation(left, right) / 2,
+ tx = s - left.x,
+ kx = dx / (right.x + s + tx),
+ ky = dy / (bottom.depth || 1);
+ root.eachBefore(function(node) {
+ node.x = (node.x + tx) * kx;
+ node.y = node.depth * ky;
+ });
+ }
+
+ return root;
+ }
+
+ // Computes a preliminary x-coordinate for v. Before that, FIRST WALK is
+ // applied recursively to the children of v, as well as the function
+ // APPORTION. After spacing out the children by calling EXECUTE SHIFTS, the
+ // node v is placed to the midpoint of its outermost children.
+ function firstWalk(v) {
+ var children = v.children,
+ siblings = v.parent.children,
+ w = v.i ? siblings[v.i - 1] : null;
+ if (children) {
+ executeShifts(v);
+ var midpoint = (children[0].z + children[children.length - 1].z) / 2;
+ if (w) {
+ v.z = w.z + separation(v._, w._);
+ v.m = v.z - midpoint;
+ } else {
+ v.z = midpoint;
+ }
+ } else if (w) {
+ v.z = w.z + separation(v._, w._);
+ }
+ v.parent.A = apportion(v, w, v.parent.A || siblings[0]);
+ }
+
+ // Computes all real x-coordinates by summing up the modifiers recursively.
+ function secondWalk(v) {
+ v._.x = v.z + v.parent.m;
+ v.m += v.parent.m;
+ }
+
+ // The core of the algorithm. Here, a new subtree is combined with the
+ // previous subtrees. Threads are used to traverse the inside and outside
+ // contours of the left and right subtree up to the highest common level. The
+ // vertices used for the traversals are vi+, vi-, vo-, and vo+, where the
+ // superscript o means outside and i means inside, the subscript - means left
+ // subtree and + means right subtree. For summing up the modifiers along the
+ // contour, we use respective variables si+, si-, so-, and so+. Whenever two
+ // nodes of the inside contours conflict, we compute the left one of the
+ // greatest uncommon ancestors using the function ANCESTOR and call MOVE
+ // SUBTREE to shift the subtree and prepare the shifts of smaller subtrees.
+ // Finally, we add a new thread (if necessary).
+ function apportion(v, w, ancestor) {
+ if (w) {
+ var vip = v,
+ vop = v,
+ vim = w,
+ vom = vip.parent.children[0],
+ sip = vip.m,
+ sop = vop.m,
+ sim = vim.m,
+ som = vom.m,
+ shift;
+ while (vim = nextRight(vim), vip = nextLeft(vip), vim && vip) {
+ vom = nextLeft(vom);
+ vop = nextRight(vop);
+ vop.a = v;
+ shift = vim.z + sim - vip.z - sip + separation(vim._, vip._);
+ if (shift > 0) {
+ moveSubtree(nextAncestor(vim, v, ancestor), v, shift);
+ sip += shift;
+ sop += shift;
+ }
+ sim += vim.m;
+ sip += vip.m;
+ som += vom.m;
+ sop += vop.m;
+ }
+ if (vim && !nextRight(vop)) {
+ vop.t = vim;
+ vop.m += sim - sop;
+ }
+ if (vip && !nextLeft(vom)) {
+ vom.t = vip;
+ vom.m += sip - som;
+ ancestor = v;
+ }
+ }
+ return ancestor;
+ }
+
+ function sizeNode(node) {
+ node.x *= dx;
+ node.y = node.depth * dy;
+ }
+
+ tree.separation = function(x) {
+ return arguments.length ? (separation = x, tree) : separation;
+ };
+
+ tree.size = function(x) {
+ return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], tree) : (nodeSize ? null : [dx, dy]);
+ };
+
+ tree.nodeSize = function(x) {
+ return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], tree) : (nodeSize ? [dx, dy] : null);
+ };
+
+ return tree;
+}
diff --git a/node_modules/d3-hierarchy/src/treemap/binary.js b/node_modules/d3-hierarchy/src/treemap/binary.js
new file mode 100644
index 00000000..a9395dc2
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/treemap/binary.js
@@ -0,0 +1,46 @@
+export default function(parent, x0, y0, x1, y1) {
+ var nodes = parent.children,
+ i, n = nodes.length,
+ sum, sums = new Array(n + 1);
+
+ for (sums[0] = sum = i = 0; i < n; ++i) {
+ sums[i + 1] = sum += nodes[i].value;
+ }
+
+ partition(0, n, parent.value, x0, y0, x1, y1);
+
+ function partition(i, j, value, x0, y0, x1, y1) {
+ if (i >= j - 1) {
+ var node = nodes[i];
+ node.x0 = x0, node.y0 = y0;
+ node.x1 = x1, node.y1 = y1;
+ return;
+ }
+
+ var valueOffset = sums[i],
+ valueTarget = (value / 2) + valueOffset,
+ k = i + 1,
+ hi = j - 1;
+
+ while (k < hi) {
+ var mid = k + hi >>> 1;
+ if (sums[mid] < valueTarget) k = mid + 1;
+ else hi = mid;
+ }
+
+ if ((valueTarget - sums[k - 1]) < (sums[k] - valueTarget) && i + 1 < k) --k;
+
+ var valueLeft = sums[k] - valueOffset,
+ valueRight = value - valueLeft;
+
+ if ((x1 - x0) > (y1 - y0)) {
+ var xk = value ? (x0 * valueRight + x1 * valueLeft) / value : x1;
+ partition(i, k, valueLeft, x0, y0, xk, y1);
+ partition(k, j, valueRight, xk, y0, x1, y1);
+ } else {
+ var yk = value ? (y0 * valueRight + y1 * valueLeft) / value : y1;
+ partition(i, k, valueLeft, x0, y0, x1, yk);
+ partition(k, j, valueRight, x0, yk, x1, y1);
+ }
+ }
+}
diff --git a/node_modules/d3-hierarchy/src/treemap/dice.js b/node_modules/d3-hierarchy/src/treemap/dice.js
new file mode 100644
index 00000000..605c1f66
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/treemap/dice.js
@@ -0,0 +1,12 @@
+export default function(parent, x0, y0, x1, y1) {
+ var nodes = parent.children,
+ node,
+ i = -1,
+ n = nodes.length,
+ k = parent.value && (x1 - x0) / parent.value;
+
+ while (++i < n) {
+ node = nodes[i], node.y0 = y0, node.y1 = y1;
+ node.x0 = x0, node.x1 = x0 += node.value * k;
+ }
+}
diff --git a/node_modules/d3-hierarchy/src/treemap/index.js b/node_modules/d3-hierarchy/src/treemap/index.js
new file mode 100644
index 00000000..ccc42c9d
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/treemap/index.js
@@ -0,0 +1,94 @@
+import roundNode from "./round.js";
+import squarify from "./squarify.js";
+import {required} from "../accessors.js";
+import constant, {constantZero} from "../constant.js";
+
+export default function() {
+ var tile = squarify,
+ round = false,
+ dx = 1,
+ dy = 1,
+ paddingStack = [0],
+ paddingInner = constantZero,
+ paddingTop = constantZero,
+ paddingRight = constantZero,
+ paddingBottom = constantZero,
+ paddingLeft = constantZero;
+
+ function treemap(root) {
+ root.x0 =
+ root.y0 = 0;
+ root.x1 = dx;
+ root.y1 = dy;
+ root.eachBefore(positionNode);
+ paddingStack = [0];
+ if (round) root.eachBefore(roundNode);
+ return root;
+ }
+
+ function positionNode(node) {
+ var p = paddingStack[node.depth],
+ x0 = node.x0 + p,
+ y0 = node.y0 + p,
+ x1 = node.x1 - p,
+ y1 = node.y1 - p;
+ if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
+ if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
+ node.x0 = x0;
+ node.y0 = y0;
+ node.x1 = x1;
+ node.y1 = y1;
+ if (node.children) {
+ p = paddingStack[node.depth + 1] = paddingInner(node) / 2;
+ x0 += paddingLeft(node) - p;
+ y0 += paddingTop(node) - p;
+ x1 -= paddingRight(node) - p;
+ y1 -= paddingBottom(node) - p;
+ if (x1 < x0) x0 = x1 = (x0 + x1) / 2;
+ if (y1 < y0) y0 = y1 = (y0 + y1) / 2;
+ tile(node, x0, y0, x1, y1);
+ }
+ }
+
+ treemap.round = function(x) {
+ return arguments.length ? (round = !!x, treemap) : round;
+ };
+
+ treemap.size = function(x) {
+ return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy];
+ };
+
+ treemap.tile = function(x) {
+ return arguments.length ? (tile = required(x), treemap) : tile;
+ };
+
+ treemap.padding = function(x) {
+ return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner();
+ };
+
+ treemap.paddingInner = function(x) {
+ return arguments.length ? (paddingInner = typeof x === "function" ? x : constant(+x), treemap) : paddingInner;
+ };
+
+ treemap.paddingOuter = function(x) {
+ return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop();
+ };
+
+ treemap.paddingTop = function(x) {
+ return arguments.length ? (paddingTop = typeof x === "function" ? x : constant(+x), treemap) : paddingTop;
+ };
+
+ treemap.paddingRight = function(x) {
+ return arguments.length ? (paddingRight = typeof x === "function" ? x : constant(+x), treemap) : paddingRight;
+ };
+
+ treemap.paddingBottom = function(x) {
+ return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant(+x), treemap) : paddingBottom;
+ };
+
+ treemap.paddingLeft = function(x) {
+ return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant(+x), treemap) : paddingLeft;
+ };
+
+ return treemap;
+}
diff --git a/node_modules/d3-hierarchy/src/treemap/resquarify.js b/node_modules/d3-hierarchy/src/treemap/resquarify.js
new file mode 100644
index 00000000..de720473
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/treemap/resquarify.js
@@ -0,0 +1,36 @@
+import treemapDice from "./dice.js";
+import treemapSlice from "./slice.js";
+import {phi, squarifyRatio} from "./squarify.js";
+
+export default (function custom(ratio) {
+
+ function resquarify(parent, x0, y0, x1, y1) {
+ if ((rows = parent._squarify) && (rows.ratio === ratio)) {
+ var rows,
+ row,
+ nodes,
+ i,
+ j = -1,
+ n,
+ m = rows.length,
+ value = parent.value;
+
+ while (++j < m) {
+ row = rows[j], nodes = row.children;
+ for (i = row.value = 0, n = nodes.length; i < n; ++i) row.value += nodes[i].value;
+ if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += (y1 - y0) * row.value / value : y1);
+ else treemapSlice(row, x0, y0, value ? x0 += (x1 - x0) * row.value / value : x1, y1);
+ value -= row.value;
+ }
+ } else {
+ parent._squarify = rows = squarifyRatio(ratio, parent, x0, y0, x1, y1);
+ rows.ratio = ratio;
+ }
+ }
+
+ resquarify.ratio = function(x) {
+ return custom((x = +x) > 1 ? x : 1);
+ };
+
+ return resquarify;
+})(phi);
diff --git a/node_modules/d3-hierarchy/src/treemap/round.js b/node_modules/d3-hierarchy/src/treemap/round.js
new file mode 100644
index 00000000..7ac45ec2
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/treemap/round.js
@@ -0,0 +1,6 @@
+export default function(node) {
+ node.x0 = Math.round(node.x0);
+ node.y0 = Math.round(node.y0);
+ node.x1 = Math.round(node.x1);
+ node.y1 = Math.round(node.y1);
+}
diff --git a/node_modules/d3-hierarchy/src/treemap/slice.js b/node_modules/d3-hierarchy/src/treemap/slice.js
new file mode 100644
index 00000000..1022bfad
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/treemap/slice.js
@@ -0,0 +1,12 @@
+export default function(parent, x0, y0, x1, y1) {
+ var nodes = parent.children,
+ node,
+ i = -1,
+ n = nodes.length,
+ k = parent.value && (y1 - y0) / parent.value;
+
+ while (++i < n) {
+ node = nodes[i], node.x0 = x0, node.x1 = x1;
+ node.y0 = y0, node.y1 = y0 += node.value * k;
+ }
+}
diff --git a/node_modules/d3-hierarchy/src/treemap/sliceDice.js b/node_modules/d3-hierarchy/src/treemap/sliceDice.js
new file mode 100644
index 00000000..545ad42b
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/treemap/sliceDice.js
@@ -0,0 +1,6 @@
+import dice from "./dice.js";
+import slice from "./slice.js";
+
+export default function(parent, x0, y0, x1, y1) {
+ (parent.depth & 1 ? slice : dice)(parent, x0, y0, x1, y1);
+}
diff --git a/node_modules/d3-hierarchy/src/treemap/squarify.js b/node_modules/d3-hierarchy/src/treemap/squarify.js
new file mode 100644
index 00000000..f8010703
--- /dev/null
+++ b/node_modules/d3-hierarchy/src/treemap/squarify.js
@@ -0,0 +1,66 @@
+import treemapDice from "./dice.js";
+import treemapSlice from "./slice.js";
+
+export var phi = (1 + Math.sqrt(5)) / 2;
+
+export function squarifyRatio(ratio, parent, x0, y0, x1, y1) {
+ var rows = [],
+ nodes = parent.children,
+ row,
+ nodeValue,
+ i0 = 0,
+ i1 = 0,
+ n = nodes.length,
+ dx, dy,
+ value = parent.value,
+ sumValue,
+ minValue,
+ maxValue,
+ newRatio,
+ minRatio,
+ alpha,
+ beta;
+
+ while (i0 < n) {
+ dx = x1 - x0, dy = y1 - y0;
+
+ // Find the next non-empty node.
+ do sumValue = nodes[i1++].value; while (!sumValue && i1 < n);
+ minValue = maxValue = sumValue;
+ alpha = Math.max(dy / dx, dx / dy) / (value * ratio);
+ beta = sumValue * sumValue * alpha;
+ minRatio = Math.max(maxValue / beta, beta / minValue);
+
+ // Keep adding nodes while the aspect ratio maintains or improves.
+ for (; i1 < n; ++i1) {
+ sumValue += nodeValue = nodes[i1].value;
+ if (nodeValue < minValue) minValue = nodeValue;
+ if (nodeValue > maxValue) maxValue = nodeValue;
+ beta = sumValue * sumValue * alpha;
+ newRatio = Math.max(maxValue / beta, beta / minValue);
+ if (newRatio > minRatio) { sumValue -= nodeValue; break; }
+ minRatio = newRatio;
+ }
+
+ // Position and record the row orientation.
+ rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)});
+ if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1);
+ else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1);
+ value -= sumValue, i0 = i1;
+ }
+
+ return rows;
+}
+
+export default (function custom(ratio) {
+
+ function squarify(parent, x0, y0, x1, y1) {
+ squarifyRatio(ratio, parent, x0, y0, x1, y1);
+ }
+
+ squarify.ratio = function(x) {
+ return custom((x = +x) > 1 ? x : 1);
+ };
+
+ return squarify;
+})(phi);
diff --git a/node_modules/d3-interpolate/LICENSE b/node_modules/d3-interpolate/LICENSE
new file mode 100644
index 00000000..b0145150
--- /dev/null
+++ b/node_modules/d3-interpolate/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2010-2021 Mike Bostock
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/node_modules/d3-interpolate/README.md b/node_modules/d3-interpolate/README.md
new file mode 100644
index 00000000..f5d82e78
--- /dev/null
+++ b/node_modules/d3-interpolate/README.md
@@ -0,0 +1,268 @@
+# d3-interpolate
+
+This module provides a variety of interpolation methods for blending between two values. Values may be numbers, colors, strings, arrays, or even deeply-nested objects. For example:
+
+```js
+const i = d3.interpolateNumber(10, 20);
+i(0.0); // 10
+i(0.2); // 12
+i(0.5); // 15
+i(1.0); // 20
+```
+
+The returned function `i` is called an *interpolator*. Given a starting value *a* and an ending value *b*, it takes a parameter *t* in the domain [0, 1] and returns the corresponding interpolated value between *a* and *b*. An interpolator typically returns a value equivalent to *a* at *t* = 0 and a value equivalent to *b* at *t* = 1.
+
+You can interpolate more than just numbers. To find the perceptual midpoint between steelblue and brown:
+
+```js
+d3.interpolateLab("steelblue", "brown")(0.5); // "rgb(142, 92, 109)"
+```
+
+Here’s a more elaborate example demonstrating type inference used by [interpolate](#interpolate):
+
+```js
+const i = d3.interpolate({colors: ["red", "blue"]}, {colors: ["white", "black"]});
+i(0.0); // {colors: ["rgb(255, 0, 0)", "rgb(0, 0, 255)"]}
+i(0.5); // {colors: ["rgb(255, 128, 128)", "rgb(0, 0, 128)"]}
+i(1.0); // {colors: ["rgb(255, 255, 255)", "rgb(0, 0, 0)"]}
+```
+
+Note that the generic value interpolator detects not only nested objects and arrays, but also color strings and numbers embedded in strings!
+
+## Installing
+
+If you use npm, `npm install d3-interpolate`. You can also download the [latest release on GitHub](https://github.com/d3/d3-interpolate/releases/latest). For vanilla HTML in modern browsers, import d3-interpolate from Skypack:
+
+```html
+
+```
+
+For legacy environments, you can load d3-interpolate’s UMD bundle from an npm-based CDN such as jsDelivr; a `d3` global is exported. (If using [color interpolation](#color-spaces), also load [d3-color](https://github.com/d3/d3-color).)
+
+```html
+
+
+
+```
+
+## API Reference
+
+# d3.interpolate(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/value.js), [Examples](https://observablehq.com/@d3/d3-interpolate)
+
+Returns an interpolator between the two arbitrary values *a* and *b*. The interpolator implementation is based on the type of the end value *b*, using the following algorithm:
+
+1. If *b* is null, undefined or a boolean, use the constant *b*.
+2. If *b* is a number, use [interpolateNumber](#interpolateNumber).
+3. If *b* is a [color](https://github.com/d3/d3-color/blob/master/README.md#color) or a string coercible to a color, use [interpolateRgb](#interpolateRgb).
+4. If *b* is a [date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date), use [interpolateDate](#interpolateDate).
+5. If *b* is a string, use [interpolateString](#interpolateString).
+6. If *b* is a [typed array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray) of numbers, use [interpolateNumberArray](#interpolateNumberArray).
+7. If *b* is a generic [array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray), use [interpolateArray](#interpolateArray).
+8. If *b* is coercible to a number, use [interpolateNumber](#interpolateNumber).
+9. Use [interpolateObject](#interpolateObject).
+
+Based on the chosen interpolator, *a* is coerced to the suitable corresponding type.
+
+# d3.interpolateNumber(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/number.js), [Examples](https://observablehq.com/@d3/d3-interpolatenumber)
+
+Returns an interpolator between the two numbers *a* and *b*. The returned interpolator is equivalent to:
+
+```js
+function interpolator(t) {
+ return a * (1 - t) + b * t;
+}
+```
+
+Caution: avoid interpolating to or from the number zero when the interpolator is used to generate a string. When very small values are stringified, they may be converted to scientific notation, which is an invalid attribute or style property value in older browsers. For example, the number `0.0000001` is converted to the string `"1e-7"`. This is particularly noticeable with interpolating opacity. To avoid scientific notation, start or end the transition at 1e-6: the smallest value that is not stringified in scientific notation.
+
+# d3.interpolateRound(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/round.js), [Examples](https://observablehq.com/@d3/d3-interpolatenumber)
+
+Returns an interpolator between the two numbers *a* and *b*; the interpolator is similar to [interpolateNumber](#interpolateNumber), except it will round the resulting value to the nearest integer.
+
+# d3.interpolateString(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/string.js), [Examples](https://observablehq.com/@d3/d3-interpolatestring)
+
+Returns an interpolator between the two strings *a* and *b*. The string interpolator finds numbers embedded in *a* and *b*, where each number is of the form understood by JavaScript. A few examples of numbers that will be detected within a string: `-1`, `42`, `3.14159`, and `6.0221413e+23`.
+
+For each number embedded in *b*, the interpolator will attempt to find a corresponding number in *a*. If a corresponding number is found, a numeric interpolator is created using [interpolateNumber](#interpolateNumber). The remaining parts of the string *b* are used as a template: the static parts of the string *b* remain constant for the interpolation, with the interpolated numeric values embedded in the template.
+
+For example, if *a* is `"300 12px sans-serif"`, and *b* is `"500 36px Comic-Sans"`, two embedded numbers are found. The remaining static parts (of string *b*) are a space between the two numbers (`" "`), and the suffix (`"px Comic-Sans"`). The result of the interpolator at *t* = 0.5 is `"400 24px Comic-Sans"`.
+
+# d3.interpolateDate(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/date.js), [Examples](https://observablehq.com/@d3/d3-interpolatedate)
+
+Returns an interpolator between the two [dates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) *a* and *b*.
+
+Note: **no defensive copy** of the returned date is created; the same Date instance is returned for every evaluation of the interpolator. No copy is made for performance reasons; interpolators are often part of the inner loop of [animated transitions](https://github.com/d3/d3-transition).
+
+# d3.interpolateArray(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/array.js), [Examples](https://observablehq.com/@d3/d3-interpolateobject)
+
+Returns an interpolator between the two arrays *a* and *b*. If *b* is a typed array (e.g., Float64Array), [interpolateNumberArray](#interpolateNumberArray) is called instead.
+
+Internally, an array template is created that is the same length as *b*. For each element in *b*, if there exists a corresponding element in *a*, a generic interpolator is created for the two elements using [interpolate](#interpolate). If there is no such element, the static value from *b* is used in the template. Then, for the given parameter *t*, the template’s embedded interpolators are evaluated. The updated array template is then returned.
+
+For example, if *a* is the array `[0, 1]` and *b* is the array `[1, 10, 100]`, then the result of the interpolator for *t* = 0.5 is the array `[0.5, 5.5, 100]`.
+
+Note: **no defensive copy** of the template array is created; modifications of the returned array may adversely affect subsequent evaluation of the interpolator. No copy is made for performance reasons; interpolators are often part of the inner loop of [animated transitions](https://github.com/d3/d3-transition).
+
+# d3.interpolateNumberArray(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/numberArray.js), [Examples](https://observablehq.com/@d3/d3-interpolatenumberarray)
+
+Returns an interpolator between the two arrays of numbers *a* and *b*. Internally, an array template is created that is the same type and length as *b*. For each element in *b*, if there exists a corresponding element in *a*, the values are directly interpolated in the array template. If there is no such element, the static value from *b* is copied. The updated array template is then returned.
+
+Note: For performance reasons, **no defensive copy** is made of the template array and the arguments *a* and *b*; modifications of these arrays may affect subsequent evaluation of the interpolator.
+
+# d3.interpolateObject(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/object.js), [Examples](https://observablehq.com/@d3/d3-interpolateobject)
+
+Returns an interpolator between the two objects *a* and *b*. Internally, an object template is created that has the same properties as *b*. For each property in *b*, if there exists a corresponding property in *a*, a generic interpolator is created for the two elements using [interpolate](#interpolate). If there is no such property, the static value from *b* is used in the template. Then, for the given parameter *t*, the template's embedded interpolators are evaluated and the updated object template is then returned.
+
+For example, if *a* is the object `{x: 0, y: 1}` and *b* is the object `{x: 1, y: 10, z: 100}`, the result of the interpolator for *t* = 0.5 is the object `{x: 0.5, y: 5.5, z: 100}`.
+
+Object interpolation is particularly useful for *dataspace interpolation*, where data is interpolated rather than attribute values. For example, you can interpolate an object which describes an arc in a pie chart, and then use [d3.arc](https://github.com/d3/d3-shape/blob/master/README.md#arc) to compute the new SVG path data.
+
+Note: **no defensive copy** of the template object is created; modifications of the returned object may adversely affect subsequent evaluation of the interpolator. No copy is made for performance reasons; interpolators are often part of the inner loop of [animated transitions](https://github.com/d3/d3-transition).
+
+# d3.interpolateTransformCss(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/transform/index.js#L62), [Examples](https://observablehq.com/@d3/d3-interpolatetransformcss)
+
+Returns an interpolator between the two 2D CSS transforms represented by *a* and *b*. Each transform is decomposed to a standard representation of translate, rotate, *x*-skew and scale; these component transformations are then interpolated. This behavior is standardized by CSS: see [matrix decomposition for animation](http://www.w3.org/TR/css3-2d-transforms/#matrix-decomposition).
+
+# d3.interpolateTransformSvg(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/transform/index.js#L63), [Examples](https://observablehq.com/@d3/d3-interpolatetransformcss)
+
+Returns an interpolator between the two 2D SVG transforms represented by *a* and *b*. Each transform is decomposed to a standard representation of translate, rotate, *x*-skew and scale; these component transformations are then interpolated. This behavior is standardized by CSS: see [matrix decomposition for animation](http://www.w3.org/TR/css3-2d-transforms/#matrix-decomposition).
+
+# d3.interpolateZoom(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/zoom.js), [Examples](https://observablehq.com/@d3/d3-interpolatezoom)
+
+Returns an interpolator between the two views *a* and *b* of a two-dimensional plane, based on [“Smooth and efficient zooming and panning”](http://www.win.tue.nl/~vanwijk/zoompan.pdf) by Jarke J. van Wijk and Wim A.A. Nuij. Each view is defined as an array of three numbers: *cx*, *cy* and *width*. The first two coordinates *cx*, *cy* represent the center of the viewport; the last coordinate *width* represents the size of the viewport.
+
+The returned interpolator exposes a *duration* property which encodes the recommended transition duration in milliseconds. This duration is based on the path length of the curved trajectory through *x,y* space. If you want a slower or faster transition, multiply this by an arbitrary scale factor (V as described in the original paper).
+
+# *interpolateZoom*.rho(rho) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/zoom.js)
+
+Given a [zoom interpolator](#interpolateZoom), returns a new zoom interpolator using the specified curvature *rho*. When *rho* is close to 0, the interpolator is almost linear. The default curvature is sqrt(2).
+
+# d3.interpolateDiscrete(values) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/discrete.js), [Examples](https://observablehq.com/@d3/d3-interpolatediscrete)
+
+Returns a discrete interpolator for the given array of *values*. The returned interpolator maps *t* in [0, 1 / *n*) to *values*[0], *t* in [1 / *n*, 2 / *n*) to *values*[1], and so on, where *n* = *values*.length. In effect, this is a lightweight [quantize scale](https://github.com/d3/d3-scale/blob/master/README.md#quantize-scales) with a fixed domain of [0, 1].
+
+### Sampling
+
+# d3.quantize(interpolator, n) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/quantize.js), [Examples](https://observablehq.com/@d3/d3-quantize)
+
+Returns *n* uniformly-spaced samples from the specified *interpolator*, where *n* is an integer greater than one. The first sample is always at *t* = 0, and the last sample is always at *t* = 1. This can be useful in generating a fixed number of samples from a given interpolator, such as to derive the range of a [quantize scale](https://github.com/d3/d3-scale/blob/master/README.md#quantize-scales) from a [continuous interpolator](https://github.com/d3/d3-scale-chromatic/blob/master/README.md#interpolateWarm).
+
+Caution: this method will not work with interpolators that do not return defensive copies of their output, such as [d3.interpolateArray](#interpolateArray), [d3.interpolateDate](#interpolateDate) and [d3.interpolateObject](#interpolateObject). For those interpolators, you must wrap the interpolator and create a copy for each returned value.
+
+### Color Spaces
+
+# d3.interpolateRgb(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/rgb.js), [Examples](https://observablehq.com/@d3/working-with-color)
+
+
+
+Or, with a corrected [gamma](#interpolate_gamma) of 2.2:
+
+
+
+Returns an RGB color space interpolator between the two colors *a* and *b* with a configurable [gamma](#interpolate_gamma). If the gamma is not specified, it defaults to 1.0. The colors *a* and *b* need not be in RGB; they will be converted to RGB using [d3.rgb](https://github.com/d3/d3-color/blob/master/README.md#rgb). The return value of the interpolator is an RGB string.
+
+# d3.interpolateRgbBasis(colors) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/rgb.js#L54), [Examples](https://observablehq.com/@d3/working-with-color)
+
+Returns a uniform nonrational B-spline interpolator through the specified array of *colors*, which are converted to [RGB color space](https://github.com/d3/d3-color/blob/master/README.md#rgb). Implicit control points are generated such that the interpolator returns *colors*[0] at *t* = 0 and *colors*[*colors*.length - 1] at *t* = 1. Opacity interpolation is not currently supported. See also [d3.interpolateBasis](#interpolateBasis), and see [d3-scale-chromatic](https://github.com/d3/d3-scale-chromatic) for examples.
+
+# d3.interpolateRgbBasisClosed(colors) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/rgb.js#L55), [Examples](https://observablehq.com/@d3/working-with-color)
+
+Returns a uniform nonrational B-spline interpolator through the specified array of *colors*, which are converted to [RGB color space](https://github.com/d3/d3-color/blob/master/README.md#rgb). The control points are implicitly repeated such that the resulting spline has cyclical C² continuity when repeated around *t* in [0,1]; this is useful, for example, to create cyclical color scales. Opacity interpolation is not currently supported. See also [d3.interpolateBasisClosed](#interpolateBasisClosed), and see [d3-scale-chromatic](https://github.com/d3/d3-scale-chromatic) for examples.
+
+# d3.interpolateHsl(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/hsl.js), [Examples](https://observablehq.com/@d3/working-with-color)
+
+
+
+Returns an HSL color space interpolator between the two colors *a* and *b*. The colors *a* and *b* need not be in HSL; they will be converted to HSL using [d3.hsl](https://github.com/d3/d3-color/blob/master/README.md#hsl). If either color’s hue or saturation is NaN, the opposing color’s channel value is used. The shortest path between hues is used. The return value of the interpolator is an RGB string.
+
+# d3.interpolateHslLong(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/hsl.js#L21), [Examples](https://observablehq.com/@d3/working-with-color)
+
+
+
+Like [interpolateHsl](#interpolateHsl), but does not use the shortest path between hues.
+
+# d3.interpolateLab(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/lab.js), [Examples](https://observablehq.com/@d3/working-with-color)
+
+
+
+Returns a [CIELAB color space](https://en.wikipedia.org/wiki/Lab_color_space#CIELAB) interpolator between the two colors *a* and *b*. The colors *a* and *b* need not be in CIELAB; they will be converted to CIELAB using [d3.lab](https://github.com/d3/d3-color/blob/master/README.md#lab). The return value of the interpolator is an RGB string.
+
+# d3.interpolateHcl(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/hcl.js), [Examples](https://observablehq.com/@d3/working-with-color)
+
+
+
+Returns a [CIELChab color space](https://en.wikipedia.org/wiki/CIELAB_color_space#Cylindrical_representation:_CIELCh_or_CIEHLC) interpolator between the two colors *a* and *b*. The colors *a* and *b* need not be in CIELChab; they will be converted to CIELChab using [d3.hcl](https://github.com/d3/d3-color/blob/master/README.md#hcl). If either color’s hue or chroma is NaN, the opposing color’s channel value is used. The shortest path between hues is used. The return value of the interpolator is an RGB string.
+
+# d3.interpolateHclLong(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/hcl.js#L21), [Examples](https://observablehq.com/@d3/working-with-color)
+
+
+
+Like [interpolateHcl](#interpolateHcl), but does not use the shortest path between hues.
+
+# d3.interpolateCubehelix(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/cubehelix.js), [Examples](https://observablehq.com/@d3/working-with-color)
+
+
+
+Or, with a [gamma](#interpolate_gamma) of 3.0 to emphasize high-intensity values:
+
+
+
+Returns a Cubehelix color space interpolator between the two colors *a* and *b* using a configurable [gamma](#interpolate_gamma). If the gamma is not specified, it defaults to 1.0. The colors *a* and *b* need not be in Cubehelix; they will be converted to Cubehelix using [d3.cubehelix](https://github.com/d3/d3-color/blob/master/README.md#cubehelix). If either color’s hue or saturation is NaN, the opposing color’s channel value is used. The shortest path between hues is used. The return value of the interpolator is an RGB string.
+
+# d3.interpolateCubehelixLong(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/cubehelix.js#L29), [Examples](https://observablehq.com/@d3/working-with-color)
+
+
+
+Or, with a [gamma](#interpolate_gamma) of 3.0 to emphasize high-intensity values:
+
+
+
+Like [interpolateCubehelix](#interpolateCubehelix), but does not use the shortest path between hues.
+
+# interpolate.gamma(gamma)
+
+Given that *interpolate* is one of [interpolateRgb](#interpolateRgb), [interpolateCubehelix](#interpolateCubehelix) or [interpolateCubehelixLong](#interpolateCubehelixLong), returns a new interpolator factory of the same type using the specified *gamma*. For example, to interpolate from purple to orange with a gamma of 2.2 in RGB space:
+
+```js
+const interpolator = d3.interpolateRgb.gamma(2.2)("purple", "orange");
+```
+
+See Eric Brasseur’s article, [Gamma error in picture scaling](http://www.ericbrasseur.org/gamma.html), for more on gamma correction.
+
+# d3.interpolateHue(a, b) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/hue.js), [Examples](https://observablehq.com/@d3/working-with-color)
+
+Returns an interpolator between the two hue angles *a* and *b*. If either hue is NaN, the opposing value is used. The shortest path between hues is used. The return value of the interpolator is a number in [0, 360).
+
+### Splines
+
+Whereas standard interpolators blend from a starting value *a* at *t* = 0 to an ending value *b* at *t* = 1, spline interpolators smoothly blend multiple input values for *t* in [0,1] using piecewise polynomial functions. Only cubic uniform nonrational [B-splines](https://en.wikipedia.org/wiki/B-spline) are currently supported, also known as basis splines.
+
+# d3.interpolateBasis(values) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/basis.js), [Examples](https://observablehq.com/@d3/d3-interpolatebasis)
+
+Returns a uniform nonrational B-spline interpolator through the specified array of *values*, which must be numbers. Implicit control points are generated such that the interpolator returns *values*[0] at *t* = 0 and *values*[*values*.length - 1] at *t* = 1. See also [d3.curveBasis](https://github.com/d3/d3-shape/blob/master/README.md#curveBasis).
+
+# d3.interpolateBasisClosed(values) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/basisClosed.js), [Examples](https://observablehq.com/@d3/d3-interpolatebasis)
+
+Returns a uniform nonrational B-spline interpolator through the specified array of *values*, which must be numbers. The control points are implicitly repeated such that the resulting one-dimensional spline has cyclical C² continuity when repeated around *t* in [0,1]. See also [d3.curveBasisClosed](https://github.com/d3/d3-shape/blob/master/README.md#curveBasisClosed).
+
+### Piecewise
+
+# d3.piecewise([interpolate, ]values) · [Source](https://github.com/d3/d3-interpolate/blob/master/src/piecewise.js), [Examples](https://observablehq.com/@d3/d3-piecewise)
+
+Returns a piecewise interpolator, composing interpolators for each adjacent pair of *values*. The returned interpolator maps *t* in [0, 1 / (*n* - 1)] to *interpolate*(*values*[0], *values*[1]), *t* in [1 / (*n* - 1), 2 / (*n* - 1)] to *interpolate*(*values*[1], *values*[2]), and so on, where *n* = *values*.length. In effect, this is a lightweight [linear scale](https://github.com/d3/d3-scale/blob/master/README.md#linear-scales). For example, to blend through red, green and blue:
+
+```js
+const interpolate = d3.piecewise(d3.interpolateRgb.gamma(2.2), ["red", "green", "blue"]);
+```
+
+If *interpolate* is not specified, defaults to [d3.interpolate](#interpolate).
diff --git a/node_modules/d3-interpolate/dist/d3-interpolate.js b/node_modules/d3-interpolate/dist/d3-interpolate.js
new file mode 100644
index 00000000..a374eedf
--- /dev/null
+++ b/node_modules/d3-interpolate/dist/d3-interpolate.js
@@ -0,0 +1,590 @@
+// https://d3js.org/d3-interpolate/ v3.0.1 Copyright 2010-2021 Mike Bostock
+(function (global, factory) {
+typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-color')) :
+typeof define === 'function' && define.amd ? define(['exports', 'd3-color'], factory) :
+(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}, global.d3));
+}(this, (function (exports, d3Color) { 'use strict';
+
+function basis(t1, v0, v1, v2, v3) {
+ var t2 = t1 * t1, t3 = t2 * t1;
+ return ((1 - 3 * t1 + 3 * t2 - t3) * v0
+ + (4 - 6 * t2 + 3 * t3) * v1
+ + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2
+ + t3 * v3) / 6;
+}
+
+function basis$1(values) {
+ var n = values.length - 1;
+ return function(t) {
+ var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),
+ v1 = values[i],
+ v2 = values[i + 1],
+ v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,
+ v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;
+ return basis((t - i / n) * n, v0, v1, v2, v3);
+ };
+}
+
+function basisClosed(values) {
+ var n = values.length;
+ return function(t) {
+ var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),
+ v0 = values[(i + n - 1) % n],
+ v1 = values[i % n],
+ v2 = values[(i + 1) % n],
+ v3 = values[(i + 2) % n];
+ return basis((t - i / n) * n, v0, v1, v2, v3);
+ };
+}
+
+var constant = x => () => x;
+
+function linear(a, d) {
+ return function(t) {
+ return a + t * d;
+ };
+}
+
+function exponential(a, b, y) {
+ return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {
+ return Math.pow(a + t * b, y);
+ };
+}
+
+function hue$1(a, b) {
+ var d = b - a;
+ return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant(isNaN(a) ? b : a);
+}
+
+function gamma(y) {
+ return (y = +y) === 1 ? nogamma : function(a, b) {
+ return b - a ? exponential(a, b, y) : constant(isNaN(a) ? b : a);
+ };
+}
+
+function nogamma(a, b) {
+ var d = b - a;
+ return d ? linear(a, d) : constant(isNaN(a) ? b : a);
+}
+
+var rgb = (function rgbGamma(y) {
+ var color = gamma(y);
+
+ function rgb(start, end) {
+ var r = color((start = d3Color.rgb(start)).r, (end = d3Color.rgb(end)).r),
+ g = color(start.g, end.g),
+ b = color(start.b, end.b),
+ opacity = nogamma(start.opacity, end.opacity);
+ return function(t) {
+ start.r = r(t);
+ start.g = g(t);
+ start.b = b(t);
+ start.opacity = opacity(t);
+ return start + "";
+ };
+ }
+
+ rgb.gamma = rgbGamma;
+
+ return rgb;
+})(1);
+
+function rgbSpline(spline) {
+ return function(colors) {
+ var n = colors.length,
+ r = new Array(n),
+ g = new Array(n),
+ b = new Array(n),
+ i, color;
+ for (i = 0; i < n; ++i) {
+ color = d3Color.rgb(colors[i]);
+ r[i] = color.r || 0;
+ g[i] = color.g || 0;
+ b[i] = color.b || 0;
+ }
+ r = spline(r);
+ g = spline(g);
+ b = spline(b);
+ color.opacity = 1;
+ return function(t) {
+ color.r = r(t);
+ color.g = g(t);
+ color.b = b(t);
+ return color + "";
+ };
+ };
+}
+
+var rgbBasis = rgbSpline(basis$1);
+var rgbBasisClosed = rgbSpline(basisClosed);
+
+function numberArray(a, b) {
+ if (!b) b = [];
+ var n = a ? Math.min(b.length, a.length) : 0,
+ c = b.slice(),
+ i;
+ return function(t) {
+ for (i = 0; i < n; ++i) c[i] = a[i] * (1 - t) + b[i] * t;
+ return c;
+ };
+}
+
+function isNumberArray(x) {
+ return ArrayBuffer.isView(x) && !(x instanceof DataView);
+}
+
+function array(a, b) {
+ return (isNumberArray(b) ? numberArray : genericArray)(a, b);
+}
+
+function genericArray(a, b) {
+ var nb = b ? b.length : 0,
+ na = a ? Math.min(nb, a.length) : 0,
+ x = new Array(na),
+ c = new Array(nb),
+ i;
+
+ for (i = 0; i < na; ++i) x[i] = value(a[i], b[i]);
+ for (; i < nb; ++i) c[i] = b[i];
+
+ return function(t) {
+ for (i = 0; i < na; ++i) c[i] = x[i](t);
+ return c;
+ };
+}
+
+function date(a, b) {
+ var d = new Date;
+ return a = +a, b = +b, function(t) {
+ return d.setTime(a * (1 - t) + b * t), d;
+ };
+}
+
+function number(a, b) {
+ return a = +a, b = +b, function(t) {
+ return a * (1 - t) + b * t;
+ };
+}
+
+function object(a, b) {
+ var i = {},
+ c = {},
+ k;
+
+ if (a === null || typeof a !== "object") a = {};
+ if (b === null || typeof b !== "object") b = {};
+
+ for (k in b) {
+ if (k in a) {
+ i[k] = value(a[k], b[k]);
+ } else {
+ c[k] = b[k];
+ }
+ }
+
+ return function(t) {
+ for (k in i) c[k] = i[k](t);
+ return c;
+ };
+}
+
+var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,
+ reB = new RegExp(reA.source, "g");
+
+function zero(b) {
+ return function() {
+ return b;
+ };
+}
+
+function one(b) {
+ return function(t) {
+ return b(t) + "";
+ };
+}
+
+function string(a, b) {
+ var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b
+ am, // current match in a
+ bm, // current match in b
+ bs, // string preceding current number in b, if any
+ i = -1, // index in s
+ s = [], // string constants and placeholders
+ q = []; // number interpolators
+
+ // Coerce inputs to strings.
+ a = a + "", b = b + "";
+
+ // Interpolate pairs of numbers in a & b.
+ while ((am = reA.exec(a))
+ && (bm = reB.exec(b))) {
+ if ((bs = bm.index) > bi) { // a string precedes the next number in b
+ bs = b.slice(bi, bs);
+ if (s[i]) s[i] += bs; // coalesce with previous string
+ else s[++i] = bs;
+ }
+ if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match
+ if (s[i]) s[i] += bm; // coalesce with previous string
+ else s[++i] = bm;
+ } else { // interpolate non-matching numbers
+ s[++i] = null;
+ q.push({i: i, x: number(am, bm)});
+ }
+ bi = reB.lastIndex;
+ }
+
+ // Add remains of b.
+ if (bi < b.length) {
+ bs = b.slice(bi);
+ if (s[i]) s[i] += bs; // coalesce with previous string
+ else s[++i] = bs;
+ }
+
+ // Special optimization for only a single match.
+ // Otherwise, interpolate each of the numbers and rejoin the string.
+ return s.length < 2 ? (q[0]
+ ? one(q[0].x)
+ : zero(b))
+ : (b = q.length, function(t) {
+ for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);
+ return s.join("");
+ });
+}
+
+function value(a, b) {
+ var t = typeof b, c;
+ return b == null || t === "boolean" ? constant(b)
+ : (t === "number" ? number
+ : t === "string" ? ((c = d3Color.color(b)) ? (b = c, rgb) : string)
+ : b instanceof d3Color.color ? rgb
+ : b instanceof Date ? date
+ : isNumberArray(b) ? numberArray
+ : Array.isArray(b) ? genericArray
+ : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object
+ : number)(a, b);
+}
+
+function discrete(range) {
+ var n = range.length;
+ return function(t) {
+ return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];
+ };
+}
+
+function hue(a, b) {
+ var i = hue$1(+a, +b);
+ return function(t) {
+ var x = i(t);
+ return x - 360 * Math.floor(x / 360);
+ };
+}
+
+function round(a, b) {
+ return a = +a, b = +b, function(t) {
+ return Math.round(a * (1 - t) + b * t);
+ };
+}
+
+var degrees = 180 / Math.PI;
+
+var identity = {
+ translateX: 0,
+ translateY: 0,
+ rotate: 0,
+ skewX: 0,
+ scaleX: 1,
+ scaleY: 1
+};
+
+function decompose(a, b, c, d, e, f) {
+ var scaleX, scaleY, skewX;
+ if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;
+ if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;
+ if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;
+ if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;
+ return {
+ translateX: e,
+ translateY: f,
+ rotate: Math.atan2(b, a) * degrees,
+ skewX: Math.atan(skewX) * degrees,
+ scaleX: scaleX,
+ scaleY: scaleY
+ };
+}
+
+var svgNode;
+
+/* eslint-disable no-undef */
+function parseCss(value) {
+ const m = new (typeof DOMMatrix === "function" ? DOMMatrix : WebKitCSSMatrix)(value + "");
+ return m.isIdentity ? identity : decompose(m.a, m.b, m.c, m.d, m.e, m.f);
+}
+
+function parseSvg(value) {
+ if (value == null) return identity;
+ if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
+ svgNode.setAttribute("transform", value);
+ if (!(value = svgNode.transform.baseVal.consolidate())) return identity;
+ value = value.matrix;
+ return decompose(value.a, value.b, value.c, value.d, value.e, value.f);
+}
+
+function interpolateTransform(parse, pxComma, pxParen, degParen) {
+
+ function pop(s) {
+ return s.length ? s.pop() + " " : "";
+ }
+
+ function translate(xa, ya, xb, yb, s, q) {
+ if (xa !== xb || ya !== yb) {
+ var i = s.push("translate(", null, pxComma, null, pxParen);
+ q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)});
+ } else if (xb || yb) {
+ s.push("translate(" + xb + pxComma + yb + pxParen);
+ }
+ }
+
+ function rotate(a, b, s, q) {
+ if (a !== b) {
+ if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path
+ q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: number(a, b)});
+ } else if (b) {
+ s.push(pop(s) + "rotate(" + b + degParen);
+ }
+ }
+
+ function skewX(a, b, s, q) {
+ if (a !== b) {
+ q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: number(a, b)});
+ } else if (b) {
+ s.push(pop(s) + "skewX(" + b + degParen);
+ }
+ }
+
+ function scale(xa, ya, xb, yb, s, q) {
+ if (xa !== xb || ya !== yb) {
+ var i = s.push(pop(s) + "scale(", null, ",", null, ")");
+ q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)});
+ } else if (xb !== 1 || yb !== 1) {
+ s.push(pop(s) + "scale(" + xb + "," + yb + ")");
+ }
+ }
+
+ return function(a, b) {
+ var s = [], // string constants and placeholders
+ q = []; // number interpolators
+ a = parse(a), b = parse(b);
+ translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);
+ rotate(a.rotate, b.rotate, s, q);
+ skewX(a.skewX, b.skewX, s, q);
+ scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);
+ a = b = null; // gc
+ return function(t) {
+ var i = -1, n = q.length, o;
+ while (++i < n) s[(o = q[i]).i] = o.x(t);
+ return s.join("");
+ };
+ };
+}
+
+var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)");
+var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")");
+
+var epsilon2 = 1e-12;
+
+function cosh(x) {
+ return ((x = Math.exp(x)) + 1 / x) / 2;
+}
+
+function sinh(x) {
+ return ((x = Math.exp(x)) - 1 / x) / 2;
+}
+
+function tanh(x) {
+ return ((x = Math.exp(2 * x)) - 1) / (x + 1);
+}
+
+var zoom = (function zoomRho(rho, rho2, rho4) {
+
+ // p0 = [ux0, uy0, w0]
+ // p1 = [ux1, uy1, w1]
+ function zoom(p0, p1) {
+ var ux0 = p0[0], uy0 = p0[1], w0 = p0[2],
+ ux1 = p1[0], uy1 = p1[1], w1 = p1[2],
+ dx = ux1 - ux0,
+ dy = uy1 - uy0,
+ d2 = dx * dx + dy * dy,
+ i,
+ S;
+
+ // Special case for u0 ≅ u1.
+ if (d2 < epsilon2) {
+ S = Math.log(w1 / w0) / rho;
+ i = function(t) {
+ return [
+ ux0 + t * dx,
+ uy0 + t * dy,
+ w0 * Math.exp(rho * t * S)
+ ];
+ };
+ }
+
+ // General case.
+ else {
+ var d1 = Math.sqrt(d2),
+ b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1),
+ b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1),
+ r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0),
+ r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);
+ S = (r1 - r0) / rho;
+ i = function(t) {
+ var s = t * S,
+ coshr0 = cosh(r0),
+ u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));
+ return [
+ ux0 + u * dx,
+ uy0 + u * dy,
+ w0 * coshr0 / cosh(rho * s + r0)
+ ];
+ };
+ }
+
+ i.duration = S * 1000 * rho / Math.SQRT2;
+
+ return i;
+ }
+
+ zoom.rho = function(_) {
+ var _1 = Math.max(1e-3, +_), _2 = _1 * _1, _4 = _2 * _2;
+ return zoomRho(_1, _2, _4);
+ };
+
+ return zoom;
+})(Math.SQRT2, 2, 4);
+
+function hsl(hue) {
+ return function(start, end) {
+ var h = hue((start = d3Color.hsl(start)).h, (end = d3Color.hsl(end)).h),
+ s = nogamma(start.s, end.s),
+ l = nogamma(start.l, end.l),
+ opacity = nogamma(start.opacity, end.opacity);
+ return function(t) {
+ start.h = h(t);
+ start.s = s(t);
+ start.l = l(t);
+ start.opacity = opacity(t);
+ return start + "";
+ };
+ }
+}
+
+var hsl$1 = hsl(hue$1);
+var hslLong = hsl(nogamma);
+
+function lab(start, end) {
+ var l = nogamma((start = d3Color.lab(start)).l, (end = d3Color.lab(end)).l),
+ a = nogamma(start.a, end.a),
+ b = nogamma(start.b, end.b),
+ opacity = nogamma(start.opacity, end.opacity);
+ return function(t) {
+ start.l = l(t);
+ start.a = a(t);
+ start.b = b(t);
+ start.opacity = opacity(t);
+ return start + "";
+ };
+}
+
+function hcl(hue) {
+ return function(start, end) {
+ var h = hue((start = d3Color.hcl(start)).h, (end = d3Color.hcl(end)).h),
+ c = nogamma(start.c, end.c),
+ l = nogamma(start.l, end.l),
+ opacity = nogamma(start.opacity, end.opacity);
+ return function(t) {
+ start.h = h(t);
+ start.c = c(t);
+ start.l = l(t);
+ start.opacity = opacity(t);
+ return start + "";
+ };
+ }
+}
+
+var hcl$1 = hcl(hue$1);
+var hclLong = hcl(nogamma);
+
+function cubehelix(hue) {
+ return (function cubehelixGamma(y) {
+ y = +y;
+
+ function cubehelix(start, end) {
+ var h = hue((start = d3Color.cubehelix(start)).h, (end = d3Color.cubehelix(end)).h),
+ s = nogamma(start.s, end.s),
+ l = nogamma(start.l, end.l),
+ opacity = nogamma(start.opacity, end.opacity);
+ return function(t) {
+ start.h = h(t);
+ start.s = s(t);
+ start.l = l(Math.pow(t, y));
+ start.opacity = opacity(t);
+ return start + "";
+ };
+ }
+
+ cubehelix.gamma = cubehelixGamma;
+
+ return cubehelix;
+ })(1);
+}
+
+var cubehelix$1 = cubehelix(hue$1);
+var cubehelixLong = cubehelix(nogamma);
+
+function piecewise(interpolate, values) {
+ if (values === undefined) values = interpolate, interpolate = value;
+ var i = 0, n = values.length - 1, v = values[0], I = new Array(n < 0 ? 0 : n);
+ while (i < n) I[i] = interpolate(v, v = values[++i]);
+ return function(t) {
+ var i = Math.max(0, Math.min(n - 1, Math.floor(t *= n)));
+ return I[i](t - i);
+ };
+}
+
+function quantize(interpolator, n) {
+ var samples = new Array(n);
+ for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1));
+ return samples;
+}
+
+exports.interpolate = value;
+exports.interpolateArray = array;
+exports.interpolateBasis = basis$1;
+exports.interpolateBasisClosed = basisClosed;
+exports.interpolateCubehelix = cubehelix$1;
+exports.interpolateCubehelixLong = cubehelixLong;
+exports.interpolateDate = date;
+exports.interpolateDiscrete = discrete;
+exports.interpolateHcl = hcl$1;
+exports.interpolateHclLong = hclLong;
+exports.interpolateHsl = hsl$1;
+exports.interpolateHslLong = hslLong;
+exports.interpolateHue = hue;
+exports.interpolateLab = lab;
+exports.interpolateNumber = number;
+exports.interpolateNumberArray = numberArray;
+exports.interpolateObject = object;
+exports.interpolateRgb = rgb;
+exports.interpolateRgbBasis = rgbBasis;
+exports.interpolateRgbBasisClosed = rgbBasisClosed;
+exports.interpolateRound = round;
+exports.interpolateString = string;
+exports.interpolateTransformCss = interpolateTransformCss;
+exports.interpolateTransformSvg = interpolateTransformSvg;
+exports.interpolateZoom = zoom;
+exports.piecewise = piecewise;
+exports.quantize = quantize;
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+})));
diff --git a/node_modules/d3-interpolate/dist/d3-interpolate.min.js b/node_modules/d3-interpolate/dist/d3-interpolate.min.js
new file mode 100644
index 00000000..d1b62636
--- /dev/null
+++ b/node_modules/d3-interpolate/dist/d3-interpolate.min.js
@@ -0,0 +1,2 @@
+// https://d3js.org/d3-interpolate/ v3.0.1 Copyright 2010-2021 Mike Bostock
+!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("d3-color")):"function"==typeof define&&define.amd?define(["exports","d3-color"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self).d3=t.d3||{},t.d3)}(this,(function(t,n){"use strict";function r(t,n,r,e,a){var o=t*t,u=o*t;return((1-3*t+3*o-u)*n+(4-6*o+3*u)*r+(1+3*t+3*o-3*u)*e+u*a)/6}function e(t){var n=t.length-1;return function(e){var a=e<=0?e=0:e>=1?(e=1,n-1):Math.floor(e*n),o=t[a],u=t[a+1],i=a>0?t[a-1]:2*o-u,c=a()=>t;function u(t,n){return function(r){return t+r*n}}function i(t,n){var r=n-t;return r?u(t,r>180||r<-180?r-360*Math.round(r/360):r):o(isNaN(t)?n:t)}function c(t){return 1==(t=+t)?l:function(n,r){return r-n?function(t,n,r){return t=Math.pow(t,r),n=Math.pow(n,r)-t,r=1/r,function(e){return Math.pow(t+e*n,r)}}(n,r,t):o(isNaN(n)?r:n)}}function l(t,n){var r=n-t;return r?u(t,r):o(isNaN(t)?n:t)}var f=function t(r){var e=c(r);function a(t,r){var a=e((t=n.rgb(t)).r,(r=n.rgb(r)).r),o=e(t.g,r.g),u=e(t.b,r.b),i=l(t.opacity,r.opacity);return function(n){return t.r=a(n),t.g=o(n),t.b=u(n),t.opacity=i(n),t+""}}return a.gamma=t,a}(1);function s(t){return function(r){var e,a,o=r.length,u=new Array(o),i=new Array(o),c=new Array(o);for(e=0;eo&&(a=n.slice(o,a),i[u]?i[u]+=a:i[++u]=a),(r=r[0])===(e=e[0])?i[u]?i[u]+=e:i[++u]=e:(i[++u]=null,c.push({i:u,x:b(r,e)})),o=w.lastIndex;return o180?n+=360:n-t>180&&(t+=360),o.push({i:r.push(a(r)+"rotate(",null,e)-2,x:b(t,n)})):n&&r.push(a(r)+"rotate("+n+e)}(o.rotate,u.rotate,i,c),function(t,n,r,o){t!==n?o.push({i:r.push(a(r)+"skewX(",null,e)-2,x:b(t,n)}):n&&r.push(a(r)+"skewX("+n+e)}(o.skewX,u.skewX,i,c),function(t,n,r,e,o,u){if(t!==r||n!==e){var i=o.push(a(o)+"scale(",null,",",null,")");u.push({i:i-4,x:b(t,r)},{i:i-2,x:b(n,e)})}else 1===r&&1===e||o.push(a(o)+"scale("+r+","+e+")")}(o.scaleX,o.scaleY,u.scaleX,u.scaleY,i,c),o=u=null,function(t){for(var n,r=-1,e=c.length;++r=12"
+ },
+ "exports": {
+ "umd": "./dist/d3-interpolate.min.js",
+ "default": "./src/index.js"
+ },
+ "files": [
+ "dist/**/*.js",
+ "src/**/*.js"
+ ],
+ "homepage": "https://d3js.org/d3-interpolate/",
+ "jsdelivr": "dist/d3-interpolate.min.js",
+ "keywords": [
+ "d3",
+ "d3-module",
+ "interpolate",
+ "interpolation",
+ "color"
+ ],
+ "license": "ISC",
+ "main": "src/index.js",
+ "module": "src/index.js",
+ "name": "d3-interpolate",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/d3/d3-interpolate.git"
+ },
+ "scripts": {
+ "postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -",
+ "prepublishOnly": "rm -rf dist && yarn test && rollup -c",
+ "test": "mocha 'test/**/*-test.js' && eslint src test"
+ },
+ "sideEffects": false,
+ "type": "module",
+ "unpkg": "dist/d3-interpolate.min.js",
+ "version": "3.0.1"
+}
diff --git a/node_modules/d3-interpolate/src/array.js b/node_modules/d3-interpolate/src/array.js
new file mode 100644
index 00000000..89f77225
--- /dev/null
+++ b/node_modules/d3-interpolate/src/array.js
@@ -0,0 +1,22 @@
+import value from "./value.js";
+import numberArray, {isNumberArray} from "./numberArray.js";
+
+export default function(a, b) {
+ return (isNumberArray(b) ? numberArray : genericArray)(a, b);
+}
+
+export function genericArray(a, b) {
+ var nb = b ? b.length : 0,
+ na = a ? Math.min(nb, a.length) : 0,
+ x = new Array(na),
+ c = new Array(nb),
+ i;
+
+ for (i = 0; i < na; ++i) x[i] = value(a[i], b[i]);
+ for (; i < nb; ++i) c[i] = b[i];
+
+ return function(t) {
+ for (i = 0; i < na; ++i) c[i] = x[i](t);
+ return c;
+ };
+}
diff --git a/node_modules/d3-interpolate/src/basis.js b/node_modules/d3-interpolate/src/basis.js
new file mode 100644
index 00000000..0d853f05
--- /dev/null
+++ b/node_modules/d3-interpolate/src/basis.js
@@ -0,0 +1,19 @@
+export function basis(t1, v0, v1, v2, v3) {
+ var t2 = t1 * t1, t3 = t2 * t1;
+ return ((1 - 3 * t1 + 3 * t2 - t3) * v0
+ + (4 - 6 * t2 + 3 * t3) * v1
+ + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2
+ + t3 * v3) / 6;
+}
+
+export default function(values) {
+ var n = values.length - 1;
+ return function(t) {
+ var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n),
+ v1 = values[i],
+ v2 = values[i + 1],
+ v0 = i > 0 ? values[i - 1] : 2 * v1 - v2,
+ v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1;
+ return basis((t - i / n) * n, v0, v1, v2, v3);
+ };
+}
diff --git a/node_modules/d3-interpolate/src/basisClosed.js b/node_modules/d3-interpolate/src/basisClosed.js
new file mode 100644
index 00000000..2639d928
--- /dev/null
+++ b/node_modules/d3-interpolate/src/basisClosed.js
@@ -0,0 +1,13 @@
+import {basis} from "./basis.js";
+
+export default function(values) {
+ var n = values.length;
+ return function(t) {
+ var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n),
+ v0 = values[(i + n - 1) % n],
+ v1 = values[i % n],
+ v2 = values[(i + 1) % n],
+ v3 = values[(i + 2) % n];
+ return basis((t - i / n) * n, v0, v1, v2, v3);
+ };
+}
diff --git a/node_modules/d3-interpolate/src/color.js b/node_modules/d3-interpolate/src/color.js
new file mode 100644
index 00000000..4630fb2f
--- /dev/null
+++ b/node_modules/d3-interpolate/src/color.js
@@ -0,0 +1,29 @@
+import constant from "./constant.js";
+
+function linear(a, d) {
+ return function(t) {
+ return a + t * d;
+ };
+}
+
+function exponential(a, b, y) {
+ return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) {
+ return Math.pow(a + t * b, y);
+ };
+}
+
+export function hue(a, b) {
+ var d = b - a;
+ return d ? linear(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant(isNaN(a) ? b : a);
+}
+
+export function gamma(y) {
+ return (y = +y) === 1 ? nogamma : function(a, b) {
+ return b - a ? exponential(a, b, y) : constant(isNaN(a) ? b : a);
+ };
+}
+
+export default function nogamma(a, b) {
+ var d = b - a;
+ return d ? linear(a, d) : constant(isNaN(a) ? b : a);
+}
diff --git a/node_modules/d3-interpolate/src/constant.js b/node_modules/d3-interpolate/src/constant.js
new file mode 100644
index 00000000..3487c0dd
--- /dev/null
+++ b/node_modules/d3-interpolate/src/constant.js
@@ -0,0 +1 @@
+export default x => () => x;
diff --git a/node_modules/d3-interpolate/src/cubehelix.js b/node_modules/d3-interpolate/src/cubehelix.js
new file mode 100644
index 00000000..2c4f64bd
--- /dev/null
+++ b/node_modules/d3-interpolate/src/cubehelix.js
@@ -0,0 +1,29 @@
+import {cubehelix as colorCubehelix} from "d3-color";
+import color, {hue} from "./color.js";
+
+function cubehelix(hue) {
+ return (function cubehelixGamma(y) {
+ y = +y;
+
+ function cubehelix(start, end) {
+ var h = hue((start = colorCubehelix(start)).h, (end = colorCubehelix(end)).h),
+ s = color(start.s, end.s),
+ l = color(start.l, end.l),
+ opacity = color(start.opacity, end.opacity);
+ return function(t) {
+ start.h = h(t);
+ start.s = s(t);
+ start.l = l(Math.pow(t, y));
+ start.opacity = opacity(t);
+ return start + "";
+ };
+ }
+
+ cubehelix.gamma = cubehelixGamma;
+
+ return cubehelix;
+ })(1);
+}
+
+export default cubehelix(hue);
+export var cubehelixLong = cubehelix(color);
diff --git a/node_modules/d3-interpolate/src/date.js b/node_modules/d3-interpolate/src/date.js
new file mode 100644
index 00000000..cdfbea79
--- /dev/null
+++ b/node_modules/d3-interpolate/src/date.js
@@ -0,0 +1,6 @@
+export default function(a, b) {
+ var d = new Date;
+ return a = +a, b = +b, function(t) {
+ return d.setTime(a * (1 - t) + b * t), d;
+ };
+}
diff --git a/node_modules/d3-interpolate/src/discrete.js b/node_modules/d3-interpolate/src/discrete.js
new file mode 100644
index 00000000..b3d1e3b6
--- /dev/null
+++ b/node_modules/d3-interpolate/src/discrete.js
@@ -0,0 +1,6 @@
+export default function(range) {
+ var n = range.length;
+ return function(t) {
+ return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];
+ };
+}
diff --git a/node_modules/d3-interpolate/src/hcl.js b/node_modules/d3-interpolate/src/hcl.js
new file mode 100644
index 00000000..03125802
--- /dev/null
+++ b/node_modules/d3-interpolate/src/hcl.js
@@ -0,0 +1,21 @@
+import {hcl as colorHcl} from "d3-color";
+import color, {hue} from "./color.js";
+
+function hcl(hue) {
+ return function(start, end) {
+ var h = hue((start = colorHcl(start)).h, (end = colorHcl(end)).h),
+ c = color(start.c, end.c),
+ l = color(start.l, end.l),
+ opacity = color(start.opacity, end.opacity);
+ return function(t) {
+ start.h = h(t);
+ start.c = c(t);
+ start.l = l(t);
+ start.opacity = opacity(t);
+ return start + "";
+ };
+ }
+}
+
+export default hcl(hue);
+export var hclLong = hcl(color);
diff --git a/node_modules/d3-interpolate/src/hsl.js b/node_modules/d3-interpolate/src/hsl.js
new file mode 100644
index 00000000..2f78a901
--- /dev/null
+++ b/node_modules/d3-interpolate/src/hsl.js
@@ -0,0 +1,21 @@
+import {hsl as colorHsl} from "d3-color";
+import color, {hue} from "./color.js";
+
+function hsl(hue) {
+ return function(start, end) {
+ var h = hue((start = colorHsl(start)).h, (end = colorHsl(end)).h),
+ s = color(start.s, end.s),
+ l = color(start.l, end.l),
+ opacity = color(start.opacity, end.opacity);
+ return function(t) {
+ start.h = h(t);
+ start.s = s(t);
+ start.l = l(t);
+ start.opacity = opacity(t);
+ return start + "";
+ };
+ }
+}
+
+export default hsl(hue);
+export var hslLong = hsl(color);
diff --git a/node_modules/d3-interpolate/src/hue.js b/node_modules/d3-interpolate/src/hue.js
new file mode 100644
index 00000000..5d8d4b9c
--- /dev/null
+++ b/node_modules/d3-interpolate/src/hue.js
@@ -0,0 +1,9 @@
+import {hue} from "./color.js";
+
+export default function(a, b) {
+ var i = hue(+a, +b);
+ return function(t) {
+ var x = i(t);
+ return x - 360 * Math.floor(x / 360);
+ };
+}
diff --git a/node_modules/d3-interpolate/src/index.js b/node_modules/d3-interpolate/src/index.js
new file mode 100644
index 00000000..b4dce7d5
--- /dev/null
+++ b/node_modules/d3-interpolate/src/index.js
@@ -0,0 +1,21 @@
+export {default as interpolate} from "./value.js";
+export {default as interpolateArray} from "./array.js";
+export {default as interpolateBasis} from "./basis.js";
+export {default as interpolateBasisClosed} from "./basisClosed.js";
+export {default as interpolateDate} from "./date.js";
+export {default as interpolateDiscrete} from "./discrete.js";
+export {default as interpolateHue} from "./hue.js";
+export {default as interpolateNumber} from "./number.js";
+export {default as interpolateNumberArray} from "./numberArray.js";
+export {default as interpolateObject} from "./object.js";
+export {default as interpolateRound} from "./round.js";
+export {default as interpolateString} from "./string.js";
+export {interpolateTransformCss, interpolateTransformSvg} from "./transform/index.js";
+export {default as interpolateZoom} from "./zoom.js";
+export {default as interpolateRgb, rgbBasis as interpolateRgbBasis, rgbBasisClosed as interpolateRgbBasisClosed} from "./rgb.js";
+export {default as interpolateHsl, hslLong as interpolateHslLong} from "./hsl.js";
+export {default as interpolateLab} from "./lab.js";
+export {default as interpolateHcl, hclLong as interpolateHclLong} from "./hcl.js";
+export {default as interpolateCubehelix, cubehelixLong as interpolateCubehelixLong} from "./cubehelix.js";
+export {default as piecewise} from "./piecewise.js";
+export {default as quantize} from "./quantize.js";
diff --git a/node_modules/d3-interpolate/src/lab.js b/node_modules/d3-interpolate/src/lab.js
new file mode 100644
index 00000000..8fbf7f35
--- /dev/null
+++ b/node_modules/d3-interpolate/src/lab.js
@@ -0,0 +1,16 @@
+import {lab as colorLab} from "d3-color";
+import color from "./color.js";
+
+export default function lab(start, end) {
+ var l = color((start = colorLab(start)).l, (end = colorLab(end)).l),
+ a = color(start.a, end.a),
+ b = color(start.b, end.b),
+ opacity = color(start.opacity, end.opacity);
+ return function(t) {
+ start.l = l(t);
+ start.a = a(t);
+ start.b = b(t);
+ start.opacity = opacity(t);
+ return start + "";
+ };
+}
diff --git a/node_modules/d3-interpolate/src/number.js b/node_modules/d3-interpolate/src/number.js
new file mode 100644
index 00000000..837b13db
--- /dev/null
+++ b/node_modules/d3-interpolate/src/number.js
@@ -0,0 +1,5 @@
+export default function(a, b) {
+ return a = +a, b = +b, function(t) {
+ return a * (1 - t) + b * t;
+ };
+}
diff --git a/node_modules/d3-interpolate/src/numberArray.js b/node_modules/d3-interpolate/src/numberArray.js
new file mode 100644
index 00000000..4081086c
--- /dev/null
+++ b/node_modules/d3-interpolate/src/numberArray.js
@@ -0,0 +1,14 @@
+export default function(a, b) {
+ if (!b) b = [];
+ var n = a ? Math.min(b.length, a.length) : 0,
+ c = b.slice(),
+ i;
+ return function(t) {
+ for (i = 0; i < n; ++i) c[i] = a[i] * (1 - t) + b[i] * t;
+ return c;
+ };
+}
+
+export function isNumberArray(x) {
+ return ArrayBuffer.isView(x) && !(x instanceof DataView);
+}
diff --git a/node_modules/d3-interpolate/src/object.js b/node_modules/d3-interpolate/src/object.js
new file mode 100644
index 00000000..b521c337
--- /dev/null
+++ b/node_modules/d3-interpolate/src/object.js
@@ -0,0 +1,23 @@
+import value from "./value.js";
+
+export default function(a, b) {
+ var i = {},
+ c = {},
+ k;
+
+ if (a === null || typeof a !== "object") a = {};
+ if (b === null || typeof b !== "object") b = {};
+
+ for (k in b) {
+ if (k in a) {
+ i[k] = value(a[k], b[k]);
+ } else {
+ c[k] = b[k];
+ }
+ }
+
+ return function(t) {
+ for (k in i) c[k] = i[k](t);
+ return c;
+ };
+}
diff --git a/node_modules/d3-interpolate/src/piecewise.js b/node_modules/d3-interpolate/src/piecewise.js
new file mode 100644
index 00000000..8b568c5f
--- /dev/null
+++ b/node_modules/d3-interpolate/src/piecewise.js
@@ -0,0 +1,11 @@
+import {default as value} from "./value.js";
+
+export default function piecewise(interpolate, values) {
+ if (values === undefined) values = interpolate, interpolate = value;
+ var i = 0, n = values.length - 1, v = values[0], I = new Array(n < 0 ? 0 : n);
+ while (i < n) I[i] = interpolate(v, v = values[++i]);
+ return function(t) {
+ var i = Math.max(0, Math.min(n - 1, Math.floor(t *= n)));
+ return I[i](t - i);
+ };
+}
diff --git a/node_modules/d3-interpolate/src/quantize.js b/node_modules/d3-interpolate/src/quantize.js
new file mode 100644
index 00000000..d7c23e69
--- /dev/null
+++ b/node_modules/d3-interpolate/src/quantize.js
@@ -0,0 +1,5 @@
+export default function(interpolator, n) {
+ var samples = new Array(n);
+ for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1));
+ return samples;
+}
diff --git a/node_modules/d3-interpolate/src/rgb.js b/node_modules/d3-interpolate/src/rgb.js
new file mode 100644
index 00000000..495c1f8c
--- /dev/null
+++ b/node_modules/d3-interpolate/src/rgb.js
@@ -0,0 +1,55 @@
+import {rgb as colorRgb} from "d3-color";
+import basis from "./basis.js";
+import basisClosed from "./basisClosed.js";
+import nogamma, {gamma} from "./color.js";
+
+export default (function rgbGamma(y) {
+ var color = gamma(y);
+
+ function rgb(start, end) {
+ var r = color((start = colorRgb(start)).r, (end = colorRgb(end)).r),
+ g = color(start.g, end.g),
+ b = color(start.b, end.b),
+ opacity = nogamma(start.opacity, end.opacity);
+ return function(t) {
+ start.r = r(t);
+ start.g = g(t);
+ start.b = b(t);
+ start.opacity = opacity(t);
+ return start + "";
+ };
+ }
+
+ rgb.gamma = rgbGamma;
+
+ return rgb;
+})(1);
+
+function rgbSpline(spline) {
+ return function(colors) {
+ var n = colors.length,
+ r = new Array(n),
+ g = new Array(n),
+ b = new Array(n),
+ i, color;
+ for (i = 0; i < n; ++i) {
+ color = colorRgb(colors[i]);
+ r[i] = color.r || 0;
+ g[i] = color.g || 0;
+ b[i] = color.b || 0;
+ }
+ r = spline(r);
+ g = spline(g);
+ b = spline(b);
+ color.opacity = 1;
+ return function(t) {
+ color.r = r(t);
+ color.g = g(t);
+ color.b = b(t);
+ return color + "";
+ };
+ };
+}
+
+export var rgbBasis = rgbSpline(basis);
+export var rgbBasisClosed = rgbSpline(basisClosed);
diff --git a/node_modules/d3-interpolate/src/round.js b/node_modules/d3-interpolate/src/round.js
new file mode 100644
index 00000000..2635d28c
--- /dev/null
+++ b/node_modules/d3-interpolate/src/round.js
@@ -0,0 +1,5 @@
+export default function(a, b) {
+ return a = +a, b = +b, function(t) {
+ return Math.round(a * (1 - t) + b * t);
+ };
+}
diff --git a/node_modules/d3-interpolate/src/string.js b/node_modules/d3-interpolate/src/string.js
new file mode 100644
index 00000000..7f04d2d0
--- /dev/null
+++ b/node_modules/d3-interpolate/src/string.js
@@ -0,0 +1,64 @@
+import number from "./number.js";
+
+var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g,
+ reB = new RegExp(reA.source, "g");
+
+function zero(b) {
+ return function() {
+ return b;
+ };
+}
+
+function one(b) {
+ return function(t) {
+ return b(t) + "";
+ };
+}
+
+export default function(a, b) {
+ var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b
+ am, // current match in a
+ bm, // current match in b
+ bs, // string preceding current number in b, if any
+ i = -1, // index in s
+ s = [], // string constants and placeholders
+ q = []; // number interpolators
+
+ // Coerce inputs to strings.
+ a = a + "", b = b + "";
+
+ // Interpolate pairs of numbers in a & b.
+ while ((am = reA.exec(a))
+ && (bm = reB.exec(b))) {
+ if ((bs = bm.index) > bi) { // a string precedes the next number in b
+ bs = b.slice(bi, bs);
+ if (s[i]) s[i] += bs; // coalesce with previous string
+ else s[++i] = bs;
+ }
+ if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match
+ if (s[i]) s[i] += bm; // coalesce with previous string
+ else s[++i] = bm;
+ } else { // interpolate non-matching numbers
+ s[++i] = null;
+ q.push({i: i, x: number(am, bm)});
+ }
+ bi = reB.lastIndex;
+ }
+
+ // Add remains of b.
+ if (bi < b.length) {
+ bs = b.slice(bi);
+ if (s[i]) s[i] += bs; // coalesce with previous string
+ else s[++i] = bs;
+ }
+
+ // Special optimization for only a single match.
+ // Otherwise, interpolate each of the numbers and rejoin the string.
+ return s.length < 2 ? (q[0]
+ ? one(q[0].x)
+ : zero(b))
+ : (b = q.length, function(t) {
+ for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t);
+ return s.join("");
+ });
+}
diff --git a/node_modules/d3-interpolate/src/transform/decompose.js b/node_modules/d3-interpolate/src/transform/decompose.js
new file mode 100644
index 00000000..3535f231
--- /dev/null
+++ b/node_modules/d3-interpolate/src/transform/decompose.js
@@ -0,0 +1,26 @@
+var degrees = 180 / Math.PI;
+
+export var identity = {
+ translateX: 0,
+ translateY: 0,
+ rotate: 0,
+ skewX: 0,
+ scaleX: 1,
+ scaleY: 1
+};
+
+export default function(a, b, c, d, e, f) {
+ var scaleX, scaleY, skewX;
+ if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX;
+ if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX;
+ if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY;
+ if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX;
+ return {
+ translateX: e,
+ translateY: f,
+ rotate: Math.atan2(b, a) * degrees,
+ skewX: Math.atan(skewX) * degrees,
+ scaleX: scaleX,
+ scaleY: scaleY
+ };
+}
diff --git a/node_modules/d3-interpolate/src/transform/index.js b/node_modules/d3-interpolate/src/transform/index.js
new file mode 100644
index 00000000..5383d5f8
--- /dev/null
+++ b/node_modules/d3-interpolate/src/transform/index.js
@@ -0,0 +1,63 @@
+import number from "../number.js";
+import {parseCss, parseSvg} from "./parse.js";
+
+function interpolateTransform(parse, pxComma, pxParen, degParen) {
+
+ function pop(s) {
+ return s.length ? s.pop() + " " : "";
+ }
+
+ function translate(xa, ya, xb, yb, s, q) {
+ if (xa !== xb || ya !== yb) {
+ var i = s.push("translate(", null, pxComma, null, pxParen);
+ q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)});
+ } else if (xb || yb) {
+ s.push("translate(" + xb + pxComma + yb + pxParen);
+ }
+ }
+
+ function rotate(a, b, s, q) {
+ if (a !== b) {
+ if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path
+ q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: number(a, b)});
+ } else if (b) {
+ s.push(pop(s) + "rotate(" + b + degParen);
+ }
+ }
+
+ function skewX(a, b, s, q) {
+ if (a !== b) {
+ q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: number(a, b)});
+ } else if (b) {
+ s.push(pop(s) + "skewX(" + b + degParen);
+ }
+ }
+
+ function scale(xa, ya, xb, yb, s, q) {
+ if (xa !== xb || ya !== yb) {
+ var i = s.push(pop(s) + "scale(", null, ",", null, ")");
+ q.push({i: i - 4, x: number(xa, xb)}, {i: i - 2, x: number(ya, yb)});
+ } else if (xb !== 1 || yb !== 1) {
+ s.push(pop(s) + "scale(" + xb + "," + yb + ")");
+ }
+ }
+
+ return function(a, b) {
+ var s = [], // string constants and placeholders
+ q = []; // number interpolators
+ a = parse(a), b = parse(b);
+ translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q);
+ rotate(a.rotate, b.rotate, s, q);
+ skewX(a.skewX, b.skewX, s, q);
+ scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q);
+ a = b = null; // gc
+ return function(t) {
+ var i = -1, n = q.length, o;
+ while (++i < n) s[(o = q[i]).i] = o.x(t);
+ return s.join("");
+ };
+ };
+}
+
+export var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)");
+export var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")");
diff --git a/node_modules/d3-interpolate/src/transform/parse.js b/node_modules/d3-interpolate/src/transform/parse.js
new file mode 100644
index 00000000..c62088e0
--- /dev/null
+++ b/node_modules/d3-interpolate/src/transform/parse.js
@@ -0,0 +1,18 @@
+import decompose, {identity} from "./decompose.js";
+
+var svgNode;
+
+/* eslint-disable no-undef */
+export function parseCss(value) {
+ const m = new (typeof DOMMatrix === "function" ? DOMMatrix : WebKitCSSMatrix)(value + "");
+ return m.isIdentity ? identity : decompose(m.a, m.b, m.c, m.d, m.e, m.f);
+}
+
+export function parseSvg(value) {
+ if (value == null) return identity;
+ if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g");
+ svgNode.setAttribute("transform", value);
+ if (!(value = svgNode.transform.baseVal.consolidate())) return identity;
+ value = value.matrix;
+ return decompose(value.a, value.b, value.c, value.d, value.e, value.f);
+}
diff --git a/node_modules/d3-interpolate/src/value.js b/node_modules/d3-interpolate/src/value.js
new file mode 100644
index 00000000..6a67ac4a
--- /dev/null
+++ b/node_modules/d3-interpolate/src/value.js
@@ -0,0 +1,22 @@
+import {color} from "d3-color";
+import rgb from "./rgb.js";
+import {genericArray} from "./array.js";
+import date from "./date.js";
+import number from "./number.js";
+import object from "./object.js";
+import string from "./string.js";
+import constant from "./constant.js";
+import numberArray, {isNumberArray} from "./numberArray.js";
+
+export default function(a, b) {
+ var t = typeof b, c;
+ return b == null || t === "boolean" ? constant(b)
+ : (t === "number" ? number
+ : t === "string" ? ((c = color(b)) ? (b = c, rgb) : string)
+ : b instanceof color ? rgb
+ : b instanceof Date ? date
+ : isNumberArray(b) ? numberArray
+ : Array.isArray(b) ? genericArray
+ : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object
+ : number)(a, b);
+}
diff --git a/node_modules/d3-interpolate/src/zoom.js b/node_modules/d3-interpolate/src/zoom.js
new file mode 100644
index 00000000..f2756026
--- /dev/null
+++ b/node_modules/d3-interpolate/src/zoom.js
@@ -0,0 +1,71 @@
+var epsilon2 = 1e-12;
+
+function cosh(x) {
+ return ((x = Math.exp(x)) + 1 / x) / 2;
+}
+
+function sinh(x) {
+ return ((x = Math.exp(x)) - 1 / x) / 2;
+}
+
+function tanh(x) {
+ return ((x = Math.exp(2 * x)) - 1) / (x + 1);
+}
+
+export default (function zoomRho(rho, rho2, rho4) {
+
+ // p0 = [ux0, uy0, w0]
+ // p1 = [ux1, uy1, w1]
+ function zoom(p0, p1) {
+ var ux0 = p0[0], uy0 = p0[1], w0 = p0[2],
+ ux1 = p1[0], uy1 = p1[1], w1 = p1[2],
+ dx = ux1 - ux0,
+ dy = uy1 - uy0,
+ d2 = dx * dx + dy * dy,
+ i,
+ S;
+
+ // Special case for u0 ≅ u1.
+ if (d2 < epsilon2) {
+ S = Math.log(w1 / w0) / rho;
+ i = function(t) {
+ return [
+ ux0 + t * dx,
+ uy0 + t * dy,
+ w0 * Math.exp(rho * t * S)
+ ];
+ }
+ }
+
+ // General case.
+ else {
+ var d1 = Math.sqrt(d2),
+ b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1),
+ b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1),
+ r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0),
+ r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1);
+ S = (r1 - r0) / rho;
+ i = function(t) {
+ var s = t * S,
+ coshr0 = cosh(r0),
+ u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0));
+ return [
+ ux0 + u * dx,
+ uy0 + u * dy,
+ w0 * coshr0 / cosh(rho * s + r0)
+ ];
+ }
+ }
+
+ i.duration = S * 1000 * rho / Math.SQRT2;
+
+ return i;
+ }
+
+ zoom.rho = function(_) {
+ var _1 = Math.max(1e-3, +_), _2 = _1 * _1, _4 = _2 * _2;
+ return zoomRho(_1, _2, _4);
+ };
+
+ return zoom;
+})(Math.SQRT2, 2, 4);
diff --git a/node_modules/d3-path/LICENSE b/node_modules/d3-path/LICENSE
new file mode 100644
index 00000000..76cb4be4
--- /dev/null
+++ b/node_modules/d3-path/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2015-2021 Mike Bostock
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/node_modules/d3-path/README.md b/node_modules/d3-path/README.md
new file mode 100644
index 00000000..768ea95f
--- /dev/null
+++ b/node_modules/d3-path/README.md
@@ -0,0 +1,90 @@
+# d3-path
+
+Say you have some code that draws to a 2D canvas:
+
+```js
+function drawCircle(context, radius) {
+ context.moveTo(radius, 0);
+ context.arc(0, 0, radius, 0, 2 * Math.PI);
+}
+```
+
+The d3-path module lets you take this exact code and additionally render to [SVG](http://www.w3.org/TR/SVG/paths.html). It works by [serializing](#path_toString) [CanvasPathMethods](http://www.w3.org/TR/2dcontext/#canvaspathmethods) calls to [SVG path data](http://www.w3.org/TR/SVG/paths.html#PathData). For example:
+
+```js
+const context = d3.path();
+drawCircle(context, 40);
+pathElement.setAttribute("d", context.toString());
+```
+
+Now code you write once can be used with both Canvas (for performance) and SVG (for convenience). For a practical example, see [d3-shape](https://github.com/d3/d3-shape).
+
+## Installing
+
+If you use npm, `npm install d3-path`. You can also download the [latest release on GitHub](https://github.com/d3/d3-path/releases/latest). In modern browsers, you can import d3-path from Skypack:
+
+```html
+
+```
+
+For legacy environments, you can load d3-path’s UMD bundle from an npm-based CDN such as jsDelivr; a `d3` global is exported:
+
+```html
+
+
+```
+
+## API Reference
+
+# d3.path() · [Source](https://github.com/d3/d3-path/blob/master/src/path.js), [Examples](https://observablehq.com/@d3/d3-path)
+
+Constructs a new path serializer that implements [CanvasPathMethods](http://www.w3.org/TR/2dcontext/#canvaspathmethods).
+
+# path.moveTo(x, y)
+
+Move to the specified point ⟨*x*, *y*⟩. Equivalent to [*context*.moveTo](http://www.w3.org/TR/2dcontext/#dom-context-2d-moveto) and SVG’s [“moveto” command](http://www.w3.org/TR/SVG/paths.html#PathDataMovetoCommands).
+
+# path.closePath()
+
+Ends the current subpath and causes an automatic straight line to be drawn from the current point to the initial point of the current subpath. Equivalent to [*context*.closePath](http://www.w3.org/TR/2dcontext/#dom-context-2d-closepath) and SVG’s [“closepath” command](http://www.w3.org/TR/SVG/paths.html#PathDataClosePathCommand).
+
+# path.lineTo(x, y)
+
+Draws a straight line from the current point to the specified point ⟨*x*, *y*⟩. Equivalent to [*context*.lineTo](http://www.w3.org/TR/2dcontext/#dom-context-2d-lineto) and SVG’s [“lineto” command](http://www.w3.org/TR/SVG/paths.html#PathDataLinetoCommands).
+
+# path.quadraticCurveTo(cpx, cpy, x, y)
+
+Draws a quadratic Bézier segment from the current point to the specified point ⟨*x*, *y*⟩, with the specified control point ⟨*cpx*, *cpy*⟩. Equivalent to [*context*.quadraticCurveTo](http://www.w3.org/TR/2dcontext/#dom-context-2d-quadraticcurveto) and SVG’s [quadratic Bézier curve commands](http://www.w3.org/TR/SVG/paths.html#PathDataQuadraticBezierCommands).
+
+# path.bezierCurveTo(cpx1, cpy1, cpx2, cpy2, x, y)
+
+Draws a cubic Bézier segment from the current point to the specified point ⟨*x*, *y*⟩, with the specified control points ⟨*cpx1*, *cpy1*⟩ and ⟨*cpx2*, *cpy2*⟩. Equivalent to [*context*.bezierCurveTo](http://www.w3.org/TR/2dcontext/#dom-context-2d-beziercurveto) and SVG’s [cubic Bézier curve commands](http://www.w3.org/TR/SVG/paths.html#PathDataCubicBezierCommands).
+
+# path.arcTo(x1, y1, x2, y2, radius)
+
+Draws a circular arc segment with the specified *radius* that starts tangent to the line between the current point and the specified point ⟨*x1*, *y1*⟩ and ends tangent to the line between the specified points ⟨*x1*, *y1*⟩ and ⟨*x2*, *y2*⟩. If the first tangent point is not equal to the current point, a straight line is drawn between the current point and the first tangent point. Equivalent to [*context*.arcTo](http://www.w3.org/TR/2dcontext/#dom-context-2d-arcto) and uses SVG’s [elliptical arc curve commands](http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands).
+
+# path.arc(x, y, radius, startAngle, endAngle[, anticlockwise])
+
+Draws a circular arc segment with the specified center ⟨*x*, *y*⟩, *radius*, *startAngle* and *endAngle*. If *anticlockwise* is true, the arc is drawn in the anticlockwise direction; otherwise, it is drawn in the clockwise direction. If the current point is not equal to the starting point of the arc, a straight line is drawn from the current point to the start of the arc. Equivalent to [*context*.arc](http://www.w3.org/TR/2dcontext/#dom-context-2d-arc) and uses SVG’s [elliptical arc curve commands](http://www.w3.org/TR/SVG/paths.html#PathDataEllipticalArcCommands).
+
+# path.rect(x, y, w, h)
+
+Creates a new subpath containing just the four points ⟨*x*, *y*⟩, ⟨*x* + *w*, *y*⟩, ⟨*x* + *w*, *y* + *h*⟩, ⟨*x*, *y* + *h*⟩, with those four points connected by straight lines, and then marks the subpath as closed. Equivalent to [*context*.rect](http://www.w3.org/TR/2dcontext/#dom-context-2d-rect) and uses SVG’s [“lineto” commands](http://www.w3.org/TR/SVG/paths.html#PathDataLinetoCommands).
+
+# path.toString()
+
+Returns the string representation of this *path* according to SVG’s [path data specification](http://www.w3.org/TR/SVG/paths.html#PathData).
diff --git a/node_modules/d3-path/dist/d3-path.js b/node_modules/d3-path/dist/d3-path.js
new file mode 100644
index 00000000..6227ffd2
--- /dev/null
+++ b/node_modules/d3-path/dist/d3-path.js
@@ -0,0 +1,141 @@
+// https://d3js.org/d3-path/ v3.0.1 Copyright 2015-2021 Mike Bostock
+(function (global, factory) {
+typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+typeof define === 'function' && define.amd ? define(['exports'], factory) :
+(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}));
+}(this, (function (exports) { 'use strict';
+
+const pi = Math.PI,
+ tau = 2 * pi,
+ epsilon = 1e-6,
+ tauEpsilon = tau - epsilon;
+
+function Path() {
+ this._x0 = this._y0 = // start of current subpath
+ this._x1 = this._y1 = null; // end of current subpath
+ this._ = "";
+}
+
+function path() {
+ return new Path;
+}
+
+Path.prototype = path.prototype = {
+ constructor: Path,
+ moveTo: function(x, y) {
+ this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y);
+ },
+ closePath: function() {
+ if (this._x1 !== null) {
+ this._x1 = this._x0, this._y1 = this._y0;
+ this._ += "Z";
+ }
+ },
+ lineTo: function(x, y) {
+ this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y);
+ },
+ quadraticCurveTo: function(x1, y1, x, y) {
+ this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
+ },
+ bezierCurveTo: function(x1, y1, x2, y2, x, y) {
+ this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
+ },
+ arcTo: function(x1, y1, x2, y2, r) {
+ x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;
+ var x0 = this._x1,
+ y0 = this._y1,
+ x21 = x2 - x1,
+ y21 = y2 - y1,
+ x01 = x0 - x1,
+ y01 = y0 - y1,
+ l01_2 = x01 * x01 + y01 * y01;
+
+ // Is the radius negative? Error.
+ if (r < 0) throw new Error("negative radius: " + r);
+
+ // Is this path empty? Move to (x1,y1).
+ if (this._x1 === null) {
+ this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1);
+ }
+
+ // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.
+ else if (!(l01_2 > epsilon));
+
+ // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?
+ // Equivalently, is (x1,y1) coincident with (x2,y2)?
+ // Or, is the radius zero? Line to (x1,y1).
+ else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {
+ this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1);
+ }
+
+ // Otherwise, draw an arc!
+ else {
+ var x20 = x2 - x0,
+ y20 = y2 - y0,
+ l21_2 = x21 * x21 + y21 * y21,
+ l20_2 = x20 * x20 + y20 * y20,
+ l21 = Math.sqrt(l21_2),
+ l01 = Math.sqrt(l01_2),
+ l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),
+ t01 = l / l01,
+ t21 = l / l21;
+
+ // If the start tangent is not coincident with (x0,y0), line to.
+ if (Math.abs(t01 - 1) > epsilon) {
+ this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01);
+ }
+
+ this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21);
+ }
+ },
+ arc: function(x, y, r, a0, a1, ccw) {
+ x = +x, y = +y, r = +r, ccw = !!ccw;
+ var dx = r * Math.cos(a0),
+ dy = r * Math.sin(a0),
+ x0 = x + dx,
+ y0 = y + dy,
+ cw = 1 ^ ccw,
+ da = ccw ? a0 - a1 : a1 - a0;
+
+ // Is the radius negative? Error.
+ if (r < 0) throw new Error("negative radius: " + r);
+
+ // Is this path empty? Move to (x0,y0).
+ if (this._x1 === null) {
+ this._ += "M" + x0 + "," + y0;
+ }
+
+ // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).
+ else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {
+ this._ += "L" + x0 + "," + y0;
+ }
+
+ // Is this arc empty? We’re done.
+ if (!r) return;
+
+ // Does the angle go the wrong way? Flip the direction.
+ if (da < 0) da = da % tau + tau;
+
+ // Is this a complete circle? Draw two arcs to complete the circle.
+ if (da > tauEpsilon) {
+ this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0);
+ }
+
+ // Is this arc non-empty? Draw an arc!
+ else if (da > epsilon) {
+ this._ += "A" + r + "," + r + ",0," + (+(da >= pi)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1));
+ }
+ },
+ rect: function(x, y, w, h) {
+ this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z";
+ },
+ toString: function() {
+ return this._;
+ }
+};
+
+exports.path = path;
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+})));
diff --git a/node_modules/d3-path/dist/d3-path.min.js b/node_modules/d3-path/dist/d3-path.min.js
new file mode 100644
index 00000000..db7d1f4c
--- /dev/null
+++ b/node_modules/d3-path/dist/d3-path.min.js
@@ -0,0 +1,2 @@
+// https://d3js.org/d3-path/ v3.0.1 Copyright 2015-2021 Mike Bostock
+!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports):"function"==typeof define&&define.amd?define(["exports"],i):i((t="undefined"!=typeof globalThis?globalThis:t||self).d3=t.d3||{})}(this,(function(t){"use strict";const i=Math.PI,s=2*i,h=1e-6,_=s-h;function e(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function n(){return new e}e.prototype=n.prototype={constructor:e,moveTo:function(t,i){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+i)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(t,i){this._+="L"+(this._x1=+t)+","+(this._y1=+i)},quadraticCurveTo:function(t,i,s,h){this._+="Q"+ +t+","+ +i+","+(this._x1=+s)+","+(this._y1=+h)},bezierCurveTo:function(t,i,s,h,_,e){this._+="C"+ +t+","+ +i+","+ +s+","+ +h+","+(this._x1=+_)+","+(this._y1=+e)},arcTo:function(t,s,_,e,n){t=+t,s=+s,_=+_,e=+e,n=+n;var o=this._x1,r=this._y1,a=_-t,u=e-s,f=o-t,c=r-s,y=f*f+c*c;if(n<0)throw new Error("negative radius: "+n);if(null===this._x1)this._+="M"+(this._x1=t)+","+(this._y1=s);else if(y>h)if(Math.abs(c*a-u*f)>h&&n){var x=_-o,l=e-r,M=a*a+u*u,d=x*x+l*l,p=Math.sqrt(M),v=Math.sqrt(y),b=n*Math.tan((i-Math.acos((M+y-d)/(2*p*v)))/2),T=b/v,g=b/p;Math.abs(T-1)>h&&(this._+="L"+(t+T*f)+","+(s+T*c)),this._+="A"+n+","+n+",0,0,"+ +(c*x>f*l)+","+(this._x1=t+g*a)+","+(this._y1=s+g*u)}else this._+="L"+(this._x1=t)+","+(this._y1=s);else;},arc:function(t,e,n,o,r,a){t=+t,e=+e,a=!!a;var u=(n=+n)*Math.cos(o),f=n*Math.sin(o),c=t+u,y=e+f,x=1^a,l=a?o-r:r-o;if(n<0)throw new Error("negative radius: "+n);null===this._x1?this._+="M"+c+","+y:(Math.abs(this._x1-c)>h||Math.abs(this._y1-y)>h)&&(this._+="L"+c+","+y),n&&(l<0&&(l=l%s+s),l>_?this._+="A"+n+","+n+",0,1,"+x+","+(t-u)+","+(e-f)+"A"+n+","+n+",0,1,"+x+","+(this._x1=c)+","+(this._y1=y):l>h&&(this._+="A"+n+","+n+",0,"+ +(l>=i)+","+x+","+(this._x1=t+n*Math.cos(r))+","+(this._y1=e+n*Math.sin(r))))},rect:function(t,i,s,h){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+i)+"h"+ +s+"v"+ +h+"h"+-s+"Z"},toString:function(){return this._}},t.path=n,Object.defineProperty(t,"__esModule",{value:!0})}));
diff --git a/node_modules/d3-path/package.json b/node_modules/d3-path/package.json
new file mode 100644
index 00000000..a060f8de
--- /dev/null
+++ b/node_modules/d3-path/package.json
@@ -0,0 +1,84 @@
+{
+ "_from": "d3-path@3",
+ "_id": "d3-path@3.0.1",
+ "_inBundle": false,
+ "_integrity": "sha512-gq6gZom9AFZby0YLduxT1qmrp4xpBA1YZr19OI717WIdKE2OM5ETq5qrHLb301IgxhLwcuxvGZVLeeWc/k1I6w==",
+ "_location": "/d3-path",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "range",
+ "registry": true,
+ "raw": "d3-path@3",
+ "name": "d3-path",
+ "escapedName": "d3-path",
+ "rawSpec": "3",
+ "saveSpec": null,
+ "fetchSpec": "3"
+ },
+ "_requiredBy": [
+ "/d3",
+ "/d3-chord",
+ "/d3-shape"
+ ],
+ "_resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.0.1.tgz",
+ "_shasum": "f09dec0aaffd770b7995f1a399152bf93052321e",
+ "_spec": "d3-path@3",
+ "_where": "C:\\Users\\colbs\\CS4241\\d3a4\\node_modules\\d3",
+ "author": {
+ "name": "Mike Bostock",
+ "url": "http://bost.ocks.org/mike"
+ },
+ "bugs": {
+ "url": "https://github.com/d3/d3-path/issues"
+ },
+ "bundleDependencies": false,
+ "deprecated": false,
+ "description": "Serialize Canvas path commands to SVG.",
+ "devDependencies": {
+ "eslint": "7",
+ "mocha": "8",
+ "rollup": "2",
+ "rollup-plugin-terser": "7"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "exports": {
+ "umd": "./dist/d3-path.min.js",
+ "default": "./src/index.js"
+ },
+ "files": [
+ "dist/**/*.js",
+ "src/**/*.js"
+ ],
+ "homepage": "https://d3js.org/d3-path/",
+ "jsdelivr": "dist/d3-path.min.js",
+ "keywords": [
+ "d3",
+ "d3-module",
+ "canvas",
+ "path",
+ "svg",
+ "graphics",
+ "CanvasRenderingContext2D",
+ "CanvasPathMethods",
+ "Path2D"
+ ],
+ "license": "ISC",
+ "main": "src/index.js",
+ "module": "src/index.js",
+ "name": "d3-path",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/d3/d3-path.git"
+ },
+ "scripts": {
+ "postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -",
+ "prepublishOnly": "rm -rf dist && yarn test && rollup -c",
+ "test": "mocha 'test/**/*-test.js' && eslint src test"
+ },
+ "sideEffects": false,
+ "type": "module",
+ "unpkg": "dist/d3-path.min.js",
+ "version": "3.0.1"
+}
diff --git a/node_modules/d3-path/src/index.js b/node_modules/d3-path/src/index.js
new file mode 100644
index 00000000..968e6e58
--- /dev/null
+++ b/node_modules/d3-path/src/index.js
@@ -0,0 +1 @@
+export {default as path} from "./path.js";
diff --git a/node_modules/d3-path/src/path.js b/node_modules/d3-path/src/path.js
new file mode 100644
index 00000000..28f1f666
--- /dev/null
+++ b/node_modules/d3-path/src/path.js
@@ -0,0 +1,130 @@
+const pi = Math.PI,
+ tau = 2 * pi,
+ epsilon = 1e-6,
+ tauEpsilon = tau - epsilon;
+
+function Path() {
+ this._x0 = this._y0 = // start of current subpath
+ this._x1 = this._y1 = null; // end of current subpath
+ this._ = "";
+}
+
+function path() {
+ return new Path;
+}
+
+Path.prototype = path.prototype = {
+ constructor: Path,
+ moveTo: function(x, y) {
+ this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y);
+ },
+ closePath: function() {
+ if (this._x1 !== null) {
+ this._x1 = this._x0, this._y1 = this._y0;
+ this._ += "Z";
+ }
+ },
+ lineTo: function(x, y) {
+ this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y);
+ },
+ quadraticCurveTo: function(x1, y1, x, y) {
+ this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
+ },
+ bezierCurveTo: function(x1, y1, x2, y2, x, y) {
+ this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y);
+ },
+ arcTo: function(x1, y1, x2, y2, r) {
+ x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;
+ var x0 = this._x1,
+ y0 = this._y1,
+ x21 = x2 - x1,
+ y21 = y2 - y1,
+ x01 = x0 - x1,
+ y01 = y0 - y1,
+ l01_2 = x01 * x01 + y01 * y01;
+
+ // Is the radius negative? Error.
+ if (r < 0) throw new Error("negative radius: " + r);
+
+ // Is this path empty? Move to (x1,y1).
+ if (this._x1 === null) {
+ this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1);
+ }
+
+ // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.
+ else if (!(l01_2 > epsilon));
+
+ // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?
+ // Equivalently, is (x1,y1) coincident with (x2,y2)?
+ // Or, is the radius zero? Line to (x1,y1).
+ else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {
+ this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1);
+ }
+
+ // Otherwise, draw an arc!
+ else {
+ var x20 = x2 - x0,
+ y20 = y2 - y0,
+ l21_2 = x21 * x21 + y21 * y21,
+ l20_2 = x20 * x20 + y20 * y20,
+ l21 = Math.sqrt(l21_2),
+ l01 = Math.sqrt(l01_2),
+ l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),
+ t01 = l / l01,
+ t21 = l / l21;
+
+ // If the start tangent is not coincident with (x0,y0), line to.
+ if (Math.abs(t01 - 1) > epsilon) {
+ this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01);
+ }
+
+ this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21);
+ }
+ },
+ arc: function(x, y, r, a0, a1, ccw) {
+ x = +x, y = +y, r = +r, ccw = !!ccw;
+ var dx = r * Math.cos(a0),
+ dy = r * Math.sin(a0),
+ x0 = x + dx,
+ y0 = y + dy,
+ cw = 1 ^ ccw,
+ da = ccw ? a0 - a1 : a1 - a0;
+
+ // Is the radius negative? Error.
+ if (r < 0) throw new Error("negative radius: " + r);
+
+ // Is this path empty? Move to (x0,y0).
+ if (this._x1 === null) {
+ this._ += "M" + x0 + "," + y0;
+ }
+
+ // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).
+ else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {
+ this._ += "L" + x0 + "," + y0;
+ }
+
+ // Is this arc empty? We’re done.
+ if (!r) return;
+
+ // Does the angle go the wrong way? Flip the direction.
+ if (da < 0) da = da % tau + tau;
+
+ // Is this a complete circle? Draw two arcs to complete the circle.
+ if (da > tauEpsilon) {
+ this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0);
+ }
+
+ // Is this arc non-empty? Draw an arc!
+ else if (da > epsilon) {
+ this._ += "A" + r + "," + r + ",0," + (+(da >= pi)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1));
+ }
+ },
+ rect: function(x, y, w, h) {
+ this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z";
+ },
+ toString: function() {
+ return this._;
+ }
+};
+
+export default path;
diff --git a/node_modules/d3-polygon/LICENSE b/node_modules/d3-polygon/LICENSE
new file mode 100644
index 00000000..b0145150
--- /dev/null
+++ b/node_modules/d3-polygon/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2010-2021 Mike Bostock
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/node_modules/d3-polygon/README.md b/node_modules/d3-polygon/README.md
new file mode 100644
index 00000000..ecdc791d
--- /dev/null
+++ b/node_modules/d3-polygon/README.md
@@ -0,0 +1,52 @@
+# d3-polygon
+
+This module provides a few basic geometric operations for two-dimensional polygons. Each polygon is represented as an array of two-element arrays [[x1, y1], [x2, y2], …], and may either be closed (wherein the first and last point are the same) or open (wherein they are not). Typically polygons are in counterclockwise order, assuming a coordinate system where the origin ⟨0,0⟩ is in the top-left corner.
+
+## Installing
+
+If you use npm, `npm install d3-polygon`. You can also download the [latest release on GitHub](https://github.com/d3/d3-polygon/releases/latest). For vanilla HTML in modern browsers, import d3-polygon from Skypack:
+
+```html
+
+```
+
+For legacy environments, you can load d3-polygon’s UMD bundle from an npm-based CDN such as jsDelivr; a `d3` global is exported:
+
+```html
+
+
+```
+
+## API Reference
+
+# d3.polygonArea(polygon) [<>](https://github.com/d3/d3-polygon/blob/master/src/area.js "Source Code")
+
+Returns the signed area of the specified *polygon*. If the vertices of the polygon are in counterclockwise order (assuming a coordinate system where the origin ⟨0,0⟩ is in the top-left corner), the returned area is positive; otherwise it is negative, or zero.
+
+# d3.polygonCentroid(polygon) [<>](https://github.com/d3/d3-polygon/blob/master/src/centroid.js "Source Code")
+
+Returns the [centroid](https://en.wikipedia.org/wiki/Centroid) of the specified *polygon*.
+
+# d3.polygonHull(points) [<>](https://github.com/d3/d3-polygon/blob/master/src/hull.js#L23 "Source Code")
+
+
+
+Returns the [convex hull](https://en.wikipedia.org/wiki/Convex_hull) of the specified *points* using [Andrew’s monotone chain algorithm](http://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain). The returned hull is represented as an array containing a subset of the input *points* arranged in counterclockwise order. Returns null if *points* has fewer than three elements.
+
+# d3.polygonContains(polygon, point) [<>](https://github.com/d3/d3-polygon/blob/master/src/contains.js "Source Code")
+
+Returns true if and only if the specified *point* is inside the specified *polygon*.
+
+# d3.polygonLength(polygon) [<>](https://github.com/d3/d3-polygon/blob/master/src/length.js "Source Code")
+
+Returns the length of the perimeter of the specified *polygon*.
diff --git a/node_modules/d3-polygon/dist/d3-polygon.js b/node_modules/d3-polygon/dist/d3-polygon.js
new file mode 100644
index 00000000..33ba08b5
--- /dev/null
+++ b/node_modules/d3-polygon/dist/d3-polygon.js
@@ -0,0 +1,150 @@
+// https://d3js.org/d3-polygon/ v3.0.1 Copyright 2010-2021 Mike Bostock
+(function (global, factory) {
+typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+typeof define === 'function' && define.amd ? define(['exports'], factory) :
+(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}));
+}(this, (function (exports) { 'use strict';
+
+function area(polygon) {
+ var i = -1,
+ n = polygon.length,
+ a,
+ b = polygon[n - 1],
+ area = 0;
+
+ while (++i < n) {
+ a = b;
+ b = polygon[i];
+ area += a[1] * b[0] - a[0] * b[1];
+ }
+
+ return area / 2;
+}
+
+function centroid(polygon) {
+ var i = -1,
+ n = polygon.length,
+ x = 0,
+ y = 0,
+ a,
+ b = polygon[n - 1],
+ c,
+ k = 0;
+
+ while (++i < n) {
+ a = b;
+ b = polygon[i];
+ k += c = a[0] * b[1] - b[0] * a[1];
+ x += (a[0] + b[0]) * c;
+ y += (a[1] + b[1]) * c;
+ }
+
+ return k *= 3, [x / k, y / k];
+}
+
+// Returns the 2D cross product of AB and AC vectors, i.e., the z-component of
+// the 3D cross product in a quadrant I Cartesian coordinate system (+x is
+// right, +y is up). Returns a positive value if ABC is counter-clockwise,
+// negative if clockwise, and zero if the points are collinear.
+function cross(a, b, c) {
+ return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
+}
+
+function lexicographicOrder(a, b) {
+ return a[0] - b[0] || a[1] - b[1];
+}
+
+// Computes the upper convex hull per the monotone chain algorithm.
+// Assumes points.length >= 3, is sorted by x, unique in y.
+// Returns an array of indices into points in left-to-right order.
+function computeUpperHullIndexes(points) {
+ const n = points.length,
+ indexes = [0, 1];
+ let size = 2, i;
+
+ for (i = 2; i < n; ++i) {
+ while (size > 1 && cross(points[indexes[size - 2]], points[indexes[size - 1]], points[i]) <= 0) --size;
+ indexes[size++] = i;
+ }
+
+ return indexes.slice(0, size); // remove popped points
+}
+
+function hull(points) {
+ if ((n = points.length) < 3) return null;
+
+ var i,
+ n,
+ sortedPoints = new Array(n),
+ flippedPoints = new Array(n);
+
+ for (i = 0; i < n; ++i) sortedPoints[i] = [+points[i][0], +points[i][1], i];
+ sortedPoints.sort(lexicographicOrder);
+ for (i = 0; i < n; ++i) flippedPoints[i] = [sortedPoints[i][0], -sortedPoints[i][1]];
+
+ var upperIndexes = computeUpperHullIndexes(sortedPoints),
+ lowerIndexes = computeUpperHullIndexes(flippedPoints);
+
+ // Construct the hull polygon, removing possible duplicate endpoints.
+ var skipLeft = lowerIndexes[0] === upperIndexes[0],
+ skipRight = lowerIndexes[lowerIndexes.length - 1] === upperIndexes[upperIndexes.length - 1],
+ hull = [];
+
+ // Add upper hull in right-to-l order.
+ // Then add lower hull in left-to-right order.
+ for (i = upperIndexes.length - 1; i >= 0; --i) hull.push(points[sortedPoints[upperIndexes[i]][2]]);
+ for (i = +skipLeft; i < lowerIndexes.length - skipRight; ++i) hull.push(points[sortedPoints[lowerIndexes[i]][2]]);
+
+ return hull;
+}
+
+function contains(polygon, point) {
+ var n = polygon.length,
+ p = polygon[n - 1],
+ x = point[0], y = point[1],
+ x0 = p[0], y0 = p[1],
+ x1, y1,
+ inside = false;
+
+ for (var i = 0; i < n; ++i) {
+ p = polygon[i], x1 = p[0], y1 = p[1];
+ if (((y1 > y) !== (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1) + x1)) inside = !inside;
+ x0 = x1, y0 = y1;
+ }
+
+ return inside;
+}
+
+function length(polygon) {
+ var i = -1,
+ n = polygon.length,
+ b = polygon[n - 1],
+ xa,
+ ya,
+ xb = b[0],
+ yb = b[1],
+ perimeter = 0;
+
+ while (++i < n) {
+ xa = xb;
+ ya = yb;
+ b = polygon[i];
+ xb = b[0];
+ yb = b[1];
+ xa -= xb;
+ ya -= yb;
+ perimeter += Math.hypot(xa, ya);
+ }
+
+ return perimeter;
+}
+
+exports.polygonArea = area;
+exports.polygonCentroid = centroid;
+exports.polygonContains = contains;
+exports.polygonHull = hull;
+exports.polygonLength = length;
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+})));
diff --git a/node_modules/d3-polygon/dist/d3-polygon.min.js b/node_modules/d3-polygon/dist/d3-polygon.min.js
new file mode 100644
index 00000000..38fcfc32
--- /dev/null
+++ b/node_modules/d3-polygon/dist/d3-polygon.min.js
@@ -0,0 +1,2 @@
+// https://d3js.org/d3-polygon/ v3.0.1 Copyright 2010-2021 Mike Bostock
+!function(n,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((n="undefined"!=typeof globalThis?globalThis:n||self).d3=n.d3||{})}(this,(function(n){"use strict";function e(n,e){return n[0]-e[0]||n[1]-e[1]}function t(n){const e=n.length,t=[0,1];let o,r=2;for(o=2;o1&&(f=n[t[r-2]],l=n[t[r-1]],u=n[o],(l[0]-f[0])*(u[1]-f[1])-(l[1]-f[1])*(u[0]-f[0])<=0);)--r;t[r++]=o}var f,l,u;return t.slice(0,r)}n.polygonArea=function(n){for(var e,t=-1,o=n.length,r=n[o-1],f=0;++tu!=g>u&&l<(i-t)*(u-o)/(g-o)+t&&(h=!h),i=t,g=o;return h},n.polygonHull=function(n){if((r=n.length)<3)return null;var o,r,f=new Array(r),l=new Array(r);for(o=0;o=0;--o)a.push(n[f[u[o]][2]]);for(o=+g;o=12"
+ },
+ "exports": {
+ "umd": "./dist/d3-polygon.min.js",
+ "default": "./src/index.js"
+ },
+ "files": [
+ "dist/**/*.js",
+ "src/**/*.js"
+ ],
+ "homepage": "https://d3js.org/d3-polygon/",
+ "jsdelivr": "dist/d3-polygon.min.js",
+ "keywords": [
+ "d3",
+ "d3-module",
+ "polygon",
+ "hull",
+ "geometry",
+ "graphics"
+ ],
+ "license": "ISC",
+ "main": "src/index.js",
+ "module": "src/index.js",
+ "name": "d3-polygon",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/d3/d3-polygon.git"
+ },
+ "scripts": {
+ "postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -",
+ "prepublishOnly": "rm -rf dist && yarn test && rollup -c",
+ "test": "mocha 'test/**/*-test.js' && eslint src test"
+ },
+ "sideEffects": false,
+ "type": "module",
+ "unpkg": "dist/d3-polygon.min.js",
+ "version": "3.0.1"
+}
diff --git a/node_modules/d3-polygon/src/area.js b/node_modules/d3-polygon/src/area.js
new file mode 100644
index 00000000..109efb48
--- /dev/null
+++ b/node_modules/d3-polygon/src/area.js
@@ -0,0 +1,15 @@
+export default function(polygon) {
+ var i = -1,
+ n = polygon.length,
+ a,
+ b = polygon[n - 1],
+ area = 0;
+
+ while (++i < n) {
+ a = b;
+ b = polygon[i];
+ area += a[1] * b[0] - a[0] * b[1];
+ }
+
+ return area / 2;
+}
diff --git a/node_modules/d3-polygon/src/centroid.js b/node_modules/d3-polygon/src/centroid.js
new file mode 100644
index 00000000..6c8ece1f
--- /dev/null
+++ b/node_modules/d3-polygon/src/centroid.js
@@ -0,0 +1,20 @@
+export default function(polygon) {
+ var i = -1,
+ n = polygon.length,
+ x = 0,
+ y = 0,
+ a,
+ b = polygon[n - 1],
+ c,
+ k = 0;
+
+ while (++i < n) {
+ a = b;
+ b = polygon[i];
+ k += c = a[0] * b[1] - b[0] * a[1];
+ x += (a[0] + b[0]) * c;
+ y += (a[1] + b[1]) * c;
+ }
+
+ return k *= 3, [x / k, y / k];
+}
diff --git a/node_modules/d3-polygon/src/contains.js b/node_modules/d3-polygon/src/contains.js
new file mode 100644
index 00000000..a0beabca
--- /dev/null
+++ b/node_modules/d3-polygon/src/contains.js
@@ -0,0 +1,16 @@
+export default function(polygon, point) {
+ var n = polygon.length,
+ p = polygon[n - 1],
+ x = point[0], y = point[1],
+ x0 = p[0], y0 = p[1],
+ x1, y1,
+ inside = false;
+
+ for (var i = 0; i < n; ++i) {
+ p = polygon[i], x1 = p[0], y1 = p[1];
+ if (((y1 > y) !== (y0 > y)) && (x < (x0 - x1) * (y - y1) / (y0 - y1) + x1)) inside = !inside;
+ x0 = x1, y0 = y1;
+ }
+
+ return inside;
+}
diff --git a/node_modules/d3-polygon/src/cross.js b/node_modules/d3-polygon/src/cross.js
new file mode 100644
index 00000000..11a6df07
--- /dev/null
+++ b/node_modules/d3-polygon/src/cross.js
@@ -0,0 +1,7 @@
+// Returns the 2D cross product of AB and AC vectors, i.e., the z-component of
+// the 3D cross product in a quadrant I Cartesian coordinate system (+x is
+// right, +y is up). Returns a positive value if ABC is counter-clockwise,
+// negative if clockwise, and zero if the points are collinear.
+export default function(a, b, c) {
+ return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]);
+}
diff --git a/node_modules/d3-polygon/src/hull.js b/node_modules/d3-polygon/src/hull.js
new file mode 100644
index 00000000..daaf9a51
--- /dev/null
+++ b/node_modules/d3-polygon/src/hull.js
@@ -0,0 +1,49 @@
+import cross from "./cross.js";
+
+function lexicographicOrder(a, b) {
+ return a[0] - b[0] || a[1] - b[1];
+}
+
+// Computes the upper convex hull per the monotone chain algorithm.
+// Assumes points.length >= 3, is sorted by x, unique in y.
+// Returns an array of indices into points in left-to-right order.
+function computeUpperHullIndexes(points) {
+ const n = points.length,
+ indexes = [0, 1];
+ let size = 2, i;
+
+ for (i = 2; i < n; ++i) {
+ while (size > 1 && cross(points[indexes[size - 2]], points[indexes[size - 1]], points[i]) <= 0) --size;
+ indexes[size++] = i;
+ }
+
+ return indexes.slice(0, size); // remove popped points
+}
+
+export default function(points) {
+ if ((n = points.length) < 3) return null;
+
+ var i,
+ n,
+ sortedPoints = new Array(n),
+ flippedPoints = new Array(n);
+
+ for (i = 0; i < n; ++i) sortedPoints[i] = [+points[i][0], +points[i][1], i];
+ sortedPoints.sort(lexicographicOrder);
+ for (i = 0; i < n; ++i) flippedPoints[i] = [sortedPoints[i][0], -sortedPoints[i][1]];
+
+ var upperIndexes = computeUpperHullIndexes(sortedPoints),
+ lowerIndexes = computeUpperHullIndexes(flippedPoints);
+
+ // Construct the hull polygon, removing possible duplicate endpoints.
+ var skipLeft = lowerIndexes[0] === upperIndexes[0],
+ skipRight = lowerIndexes[lowerIndexes.length - 1] === upperIndexes[upperIndexes.length - 1],
+ hull = [];
+
+ // Add upper hull in right-to-l order.
+ // Then add lower hull in left-to-right order.
+ for (i = upperIndexes.length - 1; i >= 0; --i) hull.push(points[sortedPoints[upperIndexes[i]][2]]);
+ for (i = +skipLeft; i < lowerIndexes.length - skipRight; ++i) hull.push(points[sortedPoints[lowerIndexes[i]][2]]);
+
+ return hull;
+}
diff --git a/node_modules/d3-polygon/src/index.js b/node_modules/d3-polygon/src/index.js
new file mode 100644
index 00000000..e774be97
--- /dev/null
+++ b/node_modules/d3-polygon/src/index.js
@@ -0,0 +1,5 @@
+export {default as polygonArea} from "./area.js";
+export {default as polygonCentroid} from "./centroid.js";
+export {default as polygonHull} from "./hull.js";
+export {default as polygonContains} from "./contains.js";
+export {default as polygonLength} from "./length.js";
diff --git a/node_modules/d3-polygon/src/length.js b/node_modules/d3-polygon/src/length.js
new file mode 100644
index 00000000..8e4da5ed
--- /dev/null
+++ b/node_modules/d3-polygon/src/length.js
@@ -0,0 +1,23 @@
+export default function(polygon) {
+ var i = -1,
+ n = polygon.length,
+ b = polygon[n - 1],
+ xa,
+ ya,
+ xb = b[0],
+ yb = b[1],
+ perimeter = 0;
+
+ while (++i < n) {
+ xa = xb;
+ ya = yb;
+ b = polygon[i];
+ xb = b[0];
+ yb = b[1];
+ xa -= xb;
+ ya -= yb;
+ perimeter += Math.hypot(xa, ya);
+ }
+
+ return perimeter;
+}
diff --git a/node_modules/d3-quadtree/LICENSE b/node_modules/d3-quadtree/LICENSE
new file mode 100644
index 00000000..b0145150
--- /dev/null
+++ b/node_modules/d3-quadtree/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2010-2021 Mike Bostock
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/node_modules/d3-quadtree/README.md b/node_modules/d3-quadtree/README.md
new file mode 100644
index 00000000..0a930a2a
--- /dev/null
+++ b/node_modules/d3-quadtree/README.md
@@ -0,0 +1,181 @@
+# d3-quadtree
+
+A [quadtree](https://en.wikipedia.org/wiki/Quadtree) recursively partitions two-dimensional space into squares, dividing each square into four equally-sized squares. Each distinct point exists in a unique leaf [node](#nodes); coincident points are represented by a linked list. Quadtrees can accelerate various spatial operations, such as the [Barnes–Hut approximation](https://en.wikipedia.org/wiki/Barnes–Hut_simulation) for computing many-body forces, collision detection, and searching for nearby points.
+
+
+
+
+## Installing
+
+If you use npm, `npm install d3-quadtree`. You can also download the [latest release on GitHub](https://github.com/d3/d3-quadtree/releases/latest). For vanilla HTML in modern browsers, import d3-quadtree from Skypack:
+
+```html
+
+```
+
+For legacy environments, you can load d3-quadtree’s UMD bundle from an npm-based CDN such as jsDelivr; a `d3` global is exported:
+
+```html
+
+
+```
+
+## API Reference
+
+# d3.quadtree([data[, x, y]]) [<>](https://github.com/d3/d3-quadtree/blob/master/src/quadtree.js "Source")
+
+Creates a new, empty quadtree with an empty [extent](#quadtree_extent) and the default [*x*-](#quadtree_x) and [*y*-](#quadtree_y)accessors. If *data* is specified, [adds](#quadtree_addAll) the specified array of data to the quadtree. This is equivalent to:
+
+```js
+const tree = d3.quadtree()
+ .addAll(data);
+```
+
+If *x* and *y* are also specified, sets the [*x*-](#quadtree_x) and [*y*-](#quadtree_y) accessors to the specified functions before adding the specified array of data to the quadtree, equivalent to:
+
+```js
+const tree = d3.quadtree()
+ .x(x)
+ .y(y)
+ .addAll(data);
+```
+
+# quadtree.x([x]) [<>](https://github.com/d3/d3-quadtree/blob/master/src/x.js "Source")
+
+If *x* is specified, sets the current *x*-coordinate accessor and returns the quadtree. If *x* is not specified, returns the current *x*-accessor, which defaults to:
+
+```js
+function x(d) {
+ return d[0];
+}
+```
+
+The *x*-acccessor is used to derive the *x*-coordinate of data when [adding](#quadtree_add) to and [removing](#quadtree_remove) from the tree. It is also used when [finding](#quadtree_find) to re-access the coordinates of data previously added to the tree; therefore, the *x*- and *y*-accessors must be consistent, returning the same value given the same input.
+
+# quadtree.y([y]) [<>](https://github.com/d3/d3-quadtree/blob/master/src/y.js "Source")
+
+If *y* is specified, sets the current *y*-coordinate accessor and returns the quadtree. If *y* is not specified, returns the current *y*-accessor, which defaults to:
+
+```js
+function y(d) {
+ return d[1];
+}
+```
+
+The *y*-acccessor is used to derive the *y*-coordinate of data when [adding](#quadtree_add) to and [removing](#quadtree_remove) from the tree. It is also used when [finding](#quadtree_find) to re-access the coordinates of data previously added to the tree; therefore, the *x*- and *y*-accessors must be consistent, returning the same value given the same input.
+
+# quadtree.extent([*extent*]) [<>](https://github.com/d3/d3-quadtree/blob/master/src/extent.js "Source")
+
+If *extent* is specified, expands the quadtree to [cover](#quadtree_cover) the specified points [[*x0*, *y0*], [*x1*, *y1*]] and returns the quadtree. If *extent* is not specified, returns the quadtree’s current extent [[*x0*, *y0*], [*x1*, *y1*]], where *x0* and *y0* are the inclusive lower bounds and *x1* and *y1* are the inclusive upper bounds, or undefined if the quadtree has no extent. The extent may also be expanded by calling [*quadtree*.cover](#quadtree_cover) or [*quadtree*.add](#quadtree_add).
+
+# quadtree.cover(x, y) [<>](https://github.com/d3/d3-quadtree/blob/master/src/cover.js "Source")
+
+Expands the quadtree to cover the specified point ⟨*x*,*y*⟩, and returns the quadtree. If the quadtree’s extent already covers the specified point, this method does nothing. If the quadtree has an extent, the extent is repeatedly doubled to cover the specified point, wrapping the [root](#quadtree_root) [node](#nodes) as necessary; if the quadtree is empty, the extent is initialized to the extent [[⌊*x*⌋, ⌊*y*⌋], [⌈*x*⌉, ⌈*y*⌉]]. (Rounding is necessary such that if the extent is later doubled, the boundaries of existing quadrants do not change due to floating point error.)
+
+# quadtree.add(datum) [<>](https://github.com/d3/d3-quadtree/blob/master/src/add.js "Source")
+
+Adds the specified *datum* to the quadtree, deriving its coordinates ⟨*x*,*y*⟩ using the current [*x*-](#quadtree_x) and [*y*-](#quadtree_y)accessors, and returns the quadtree. If the new point is outside the current [extent](#quadtree_extent) of the quadtree, the quadtree is automatically expanded to [cover](#quadtree_cover) the new point.
+
+# quadtree.addAll(data) [<>](https://github.com/d3/d3-quadtree/blob/master/src/add.js "Source")
+
+Adds the specified array of *data* to the quadtree, deriving each element’s coordinates ⟨*x*,*y*⟩ using the current [*x*-](#quadtree_x) and [*y*-](#quadtree_y)accessors, and return this quadtree. This is approximately equivalent to calling [*quadtree*.add](#quadtree_add) repeatedly:
+
+```js
+for (let i = 0, n = data.length; i < n; ++i) {
+ quadtree.add(data[i]);
+}
+```
+
+However, this method results in a more compact quadtree because the extent of the *data* is computed first before adding the data.
+
+# quadtree.remove(datum) [<>](https://github.com/d3/d3-quadtree/blob/master/src/remove.js "Source")
+
+Removes the specified *datum* from the quadtree, deriving its coordinates ⟨*x*,*y*⟩ using the current [*x*-](#quadtree_x) and [*y*-](#quadtree_y)accessors, and returns the quadtree. If the specified *datum* does not exist in this quadtree, this method does nothing.
+
+# quadtree.removeAll(data) [<>](https://github.com/d3/d3-quadtree/blob/master/src/remove.js "Source")
+
+Removes the specified *data* from the quadtree, deriving their coordinates ⟨*x*,*y*⟩ using the current [*x*-](#quadtree_x) and [*y*-](#quadtree_y)accessors, and returns the quadtree. If a specified datum does not exist in this quadtree, it is ignored.
+
+# quadtree.copy()
+
+Returns a copy of the quadtree. All [nodes](#nodes) in the returned quadtree are identical copies of the corresponding node in the quadtree; however, any data in the quadtree is shared by reference and not copied.
+
+# quadtree.root() [<>](https://github.com/d3/d3-quadtree/blob/master/src/root.js "Source")
+
+Returns the root [node](#nodes) of the quadtree.
+
+# quadtree.data() [<>](https://github.com/d3/d3-quadtree/blob/master/src/data.js "Source")
+
+Returns an array of all data in the quadtree.
+
+# quadtree.size() [<>](https://github.com/d3/d3-quadtree/blob/master/src/size.js "Source")
+
+Returns the total number of data in the quadtree.
+
+# quadtree.find(x, y[, radius]) [<>](https://github.com/d3/d3-quadtree/blob/master/src/find.js "Source")
+
+Returns the datum closest to the position ⟨*x*,*y*⟩ with the given search *radius*. If *radius* is not specified, it defaults to infinity. If there is no datum within the search area, returns undefined.
+
+# quadtree.visit(callback) [<>](https://github.com/d3/d3-quadtree/blob/master/src/visit.js "Source")
+
+Visits each [node](#nodes) in the quadtree in pre-order traversal, invoking the specified *callback* with arguments *node*, *x0*, *y0*, *x1*, *y1* for each node, where *node* is the node being visited, ⟨*x0*, *y0*⟩ are the lower bounds of the node, and ⟨*x1*, *y1*⟩ are the upper bounds, and returns the quadtree. (Assuming that positive *x* is right and positive *y* is down, as is typically the case in Canvas and SVG, ⟨*x0*, *y0*⟩ is the top-left corner and ⟨*x1*, *y1*⟩ is the lower-right corner; however, the coordinate system is arbitrary, so more formally *x0* <= *x1* and *y0* <= *y1*.)
+
+If the *callback* returns true for a given node, then the children of that node are not visited; otherwise, all child nodes are visited. This can be used to quickly visit only parts of the tree, for example when using the [Barnes–Hut approximation](https://en.wikipedia.org/wiki/Barnes–Hut_simulation). Note, however, that child quadrants are always visited in sibling order: top-left, top-right, bottom-left, bottom-right. In cases such as [search](#quadtree_find), visiting siblings in a specific order may be faster.
+
+As an example, the following visits the quadtree and returns all the nodes within a rectangular extent [xmin, ymin, xmax, ymax], ignoring quads that cannot possibly contain any such node:
+
+```js
+function search(quadtree, xmin, ymin, xmax, ymax) {
+ const results = [];
+ quadtree.visit((node, x1, y1, x2, y2) => {
+ if (!node.length) {
+ do {
+ let d = node.data;
+ if (d[0] >= xmin && d[0] < xmax && d[1] >= ymin && d[1] < ymax) {
+ results.push(d);
+ }
+ } while (node = node.next);
+ }
+ return x1 >= xmax || y1 >= ymax || x2 < xmin || y2 < ymin;
+ });
+ return results;
+}
+```
+
+# quadtree.visitAfter(callback) [<>](https://github.com/d3/d3-quadtree/blob/master/src/visitAfter.js "Source")
+
+Visits each [node](#nodes) in the quadtree in post-order traversal, invoking the specified *callback* with arguments *node*, *x0*, *y0*, *x1*, *y1* for each node, where *node* is the node being visited, ⟨*x0*, *y0*⟩ are the lower bounds of the node, and ⟨*x1*, *y1*⟩ are the upper bounds, and returns the quadtree. (Assuming that positive *x* is right and positive *y* is down, as is typically the case in Canvas and SVG, ⟨*x0*, *y0*⟩ is the top-left corner and ⟨*x1*, *y1*⟩ is the lower-right corner; however, the coordinate system is arbitrary, so more formally *x0* <= *x1* and *y0* <= *y1*.) Returns *root*.
+
+### Nodes
+
+Internal nodes of the quadtree are represented as four-element arrays in left-to-right, top-to-bottom order:
+
+* `0` - the top-left quadrant, if any.
+* `1` - the top-right quadrant, if any.
+* `2` - the bottom-left quadrant, if any.
+* `3` - the bottom-right quadrant, if any.
+
+A child quadrant may be undefined if it is empty.
+
+Leaf nodes are represented as objects with the following properties:
+
+* `data` - the data associated with this point, as passed to [*quadtree*.add](#quadtree_add).
+* `next` - the next datum in this leaf, if any.
+
+The `length` property may be used to distinguish leaf nodes from internal nodes: it is undefined for leaf nodes, and 4 for internal nodes. For example, to iterate over all data in a leaf node:
+
+```js
+if (!node.length) do console.log(node.data); while (node = node.next);
+```
+
+The point’s *x*- and *y*-coordinates **must not be modified** while the point is in the quadtree. To update a point’s position, [remove](#quadtree_remove) the point and then re-[add](#quadtree_add) it to the quadtree at the new position. Alternatively, you may discard the existing quadtree entirely and create a new one from scratch; this may be more efficient if many of the points have moved.
diff --git a/node_modules/d3-quadtree/dist/d3-quadtree.js b/node_modules/d3-quadtree/dist/d3-quadtree.js
new file mode 100644
index 00000000..e2afa700
--- /dev/null
+++ b/node_modules/d3-quadtree/dist/d3-quadtree.js
@@ -0,0 +1,419 @@
+// https://d3js.org/d3-quadtree/ v3.0.1 Copyright 2010-2021 Mike Bostock
+(function (global, factory) {
+typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+typeof define === 'function' && define.amd ? define(['exports'], factory) :
+(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}));
+}(this, (function (exports) { 'use strict';
+
+function tree_add(d) {
+ const x = +this._x.call(null, d),
+ y = +this._y.call(null, d);
+ return add(this.cover(x, y), x, y, d);
+}
+
+function add(tree, x, y, d) {
+ if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points
+
+ var parent,
+ node = tree._root,
+ leaf = {data: d},
+ x0 = tree._x0,
+ y0 = tree._y0,
+ x1 = tree._x1,
+ y1 = tree._y1,
+ xm,
+ ym,
+ xp,
+ yp,
+ right,
+ bottom,
+ i,
+ j;
+
+ // If the tree is empty, initialize the root as a leaf.
+ if (!node) return tree._root = leaf, tree;
+
+ // Find the existing leaf for the new point, or add it.
+ while (node.length) {
+ if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
+ if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
+ if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree;
+ }
+
+ // Is the new point is exactly coincident with the existing point?
+ xp = +tree._x.call(null, node.data);
+ yp = +tree._y.call(null, node.data);
+ if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree;
+
+ // Otherwise, split the leaf node until the old and new point are separated.
+ do {
+ parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4);
+ if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
+ if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
+ } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm)));
+ return parent[j] = node, parent[i] = leaf, tree;
+}
+
+function addAll(data) {
+ var d, i, n = data.length,
+ x,
+ y,
+ xz = new Array(n),
+ yz = new Array(n),
+ x0 = Infinity,
+ y0 = Infinity,
+ x1 = -Infinity,
+ y1 = -Infinity;
+
+ // Compute the points and their extent.
+ for (i = 0; i < n; ++i) {
+ if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue;
+ xz[i] = x;
+ yz[i] = y;
+ if (x < x0) x0 = x;
+ if (x > x1) x1 = x;
+ if (y < y0) y0 = y;
+ if (y > y1) y1 = y;
+ }
+
+ // If there were no (valid) points, abort.
+ if (x0 > x1 || y0 > y1) return this;
+
+ // Expand the tree to cover the new points.
+ this.cover(x0, y0).cover(x1, y1);
+
+ // Add the new points.
+ for (i = 0; i < n; ++i) {
+ add(this, xz[i], yz[i], data[i]);
+ }
+
+ return this;
+}
+
+function tree_cover(x, y) {
+ if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points
+
+ var x0 = this._x0,
+ y0 = this._y0,
+ x1 = this._x1,
+ y1 = this._y1;
+
+ // If the quadtree has no extent, initialize them.
+ // Integer extent are necessary so that if we later double the extent,
+ // the existing quadrant boundaries don’t change due to floating point error!
+ if (isNaN(x0)) {
+ x1 = (x0 = Math.floor(x)) + 1;
+ y1 = (y0 = Math.floor(y)) + 1;
+ }
+
+ // Otherwise, double repeatedly to cover.
+ else {
+ var z = x1 - x0 || 1,
+ node = this._root,
+ parent,
+ i;
+
+ while (x0 > x || x >= x1 || y0 > y || y >= y1) {
+ i = (y < y0) << 1 | (x < x0);
+ parent = new Array(4), parent[i] = node, node = parent, z *= 2;
+ switch (i) {
+ case 0: x1 = x0 + z, y1 = y0 + z; break;
+ case 1: x0 = x1 - z, y1 = y0 + z; break;
+ case 2: x1 = x0 + z, y0 = y1 - z; break;
+ case 3: x0 = x1 - z, y0 = y1 - z; break;
+ }
+ }
+
+ if (this._root && this._root.length) this._root = node;
+ }
+
+ this._x0 = x0;
+ this._y0 = y0;
+ this._x1 = x1;
+ this._y1 = y1;
+ return this;
+}
+
+function tree_data() {
+ var data = [];
+ this.visit(function(node) {
+ if (!node.length) do data.push(node.data); while (node = node.next)
+ });
+ return data;
+}
+
+function tree_extent(_) {
+ return arguments.length
+ ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1])
+ : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]];
+}
+
+function Quad(node, x0, y0, x1, y1) {
+ this.node = node;
+ this.x0 = x0;
+ this.y0 = y0;
+ this.x1 = x1;
+ this.y1 = y1;
+}
+
+function tree_find(x, y, radius) {
+ var data,
+ x0 = this._x0,
+ y0 = this._y0,
+ x1,
+ y1,
+ x2,
+ y2,
+ x3 = this._x1,
+ y3 = this._y1,
+ quads = [],
+ node = this._root,
+ q,
+ i;
+
+ if (node) quads.push(new Quad(node, x0, y0, x3, y3));
+ if (radius == null) radius = Infinity;
+ else {
+ x0 = x - radius, y0 = y - radius;
+ x3 = x + radius, y3 = y + radius;
+ radius *= radius;
+ }
+
+ while (q = quads.pop()) {
+
+ // Stop searching if this quadrant can’t contain a closer node.
+ if (!(node = q.node)
+ || (x1 = q.x0) > x3
+ || (y1 = q.y0) > y3
+ || (x2 = q.x1) < x0
+ || (y2 = q.y1) < y0) continue;
+
+ // Bisect the current quadrant.
+ if (node.length) {
+ var xm = (x1 + x2) / 2,
+ ym = (y1 + y2) / 2;
+
+ quads.push(
+ new Quad(node[3], xm, ym, x2, y2),
+ new Quad(node[2], x1, ym, xm, y2),
+ new Quad(node[1], xm, y1, x2, ym),
+ new Quad(node[0], x1, y1, xm, ym)
+ );
+
+ // Visit the closest quadrant first.
+ if (i = (y >= ym) << 1 | (x >= xm)) {
+ q = quads[quads.length - 1];
+ quads[quads.length - 1] = quads[quads.length - 1 - i];
+ quads[quads.length - 1 - i] = q;
+ }
+ }
+
+ // Visit this point. (Visiting coincident points isn’t necessary!)
+ else {
+ var dx = x - +this._x.call(null, node.data),
+ dy = y - +this._y.call(null, node.data),
+ d2 = dx * dx + dy * dy;
+ if (d2 < radius) {
+ var d = Math.sqrt(radius = d2);
+ x0 = x - d, y0 = y - d;
+ x3 = x + d, y3 = y + d;
+ data = node.data;
+ }
+ }
+ }
+
+ return data;
+}
+
+function tree_remove(d) {
+ if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points
+
+ var parent,
+ node = this._root,
+ retainer,
+ previous,
+ next,
+ x0 = this._x0,
+ y0 = this._y0,
+ x1 = this._x1,
+ y1 = this._y1,
+ x,
+ y,
+ xm,
+ ym,
+ right,
+ bottom,
+ i,
+ j;
+
+ // If the tree is empty, initialize the root as a leaf.
+ if (!node) return this;
+
+ // Find the leaf node for the point.
+ // While descending, also retain the deepest parent with a non-removed sibling.
+ if (node.length) while (true) {
+ if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
+ if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
+ if (!(parent = node, node = node[i = bottom << 1 | right])) return this;
+ if (!node.length) break;
+ if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i;
+ }
+
+ // Find the point to remove.
+ while (node.data !== d) if (!(previous = node, node = node.next)) return this;
+ if (next = node.next) delete node.next;
+
+ // If there are multiple coincident points, remove just the point.
+ if (previous) return (next ? previous.next = next : delete previous.next), this;
+
+ // If this is the root point, remove it.
+ if (!parent) return this._root = next, this;
+
+ // Remove this leaf.
+ next ? parent[i] = next : delete parent[i];
+
+ // If the parent now contains exactly one leaf, collapse superfluous parents.
+ if ((node = parent[0] || parent[1] || parent[2] || parent[3])
+ && node === (parent[3] || parent[2] || parent[1] || parent[0])
+ && !node.length) {
+ if (retainer) retainer[j] = node;
+ else this._root = node;
+ }
+
+ return this;
+}
+
+function removeAll(data) {
+ for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]);
+ return this;
+}
+
+function tree_root() {
+ return this._root;
+}
+
+function tree_size() {
+ var size = 0;
+ this.visit(function(node) {
+ if (!node.length) do ++size; while (node = node.next)
+ });
+ return size;
+}
+
+function tree_visit(callback) {
+ var quads = [], q, node = this._root, child, x0, y0, x1, y1;
+ if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1));
+ while (q = quads.pop()) {
+ if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) {
+ var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
+ if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
+ if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
+ if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
+ if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
+ }
+ }
+ return this;
+}
+
+function tree_visitAfter(callback) {
+ var quads = [], next = [], q;
+ if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1));
+ while (q = quads.pop()) {
+ var node = q.node;
+ if (node.length) {
+ var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
+ if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
+ if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
+ if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
+ if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
+ }
+ next.push(q);
+ }
+ while (q = next.pop()) {
+ callback(q.node, q.x0, q.y0, q.x1, q.y1);
+ }
+ return this;
+}
+
+function defaultX(d) {
+ return d[0];
+}
+
+function tree_x(_) {
+ return arguments.length ? (this._x = _, this) : this._x;
+}
+
+function defaultY(d) {
+ return d[1];
+}
+
+function tree_y(_) {
+ return arguments.length ? (this._y = _, this) : this._y;
+}
+
+function quadtree(nodes, x, y) {
+ var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN);
+ return nodes == null ? tree : tree.addAll(nodes);
+}
+
+function Quadtree(x, y, x0, y0, x1, y1) {
+ this._x = x;
+ this._y = y;
+ this._x0 = x0;
+ this._y0 = y0;
+ this._x1 = x1;
+ this._y1 = y1;
+ this._root = undefined;
+}
+
+function leaf_copy(leaf) {
+ var copy = {data: leaf.data}, next = copy;
+ while (leaf = leaf.next) next = next.next = {data: leaf.data};
+ return copy;
+}
+
+var treeProto = quadtree.prototype = Quadtree.prototype;
+
+treeProto.copy = function() {
+ var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1),
+ node = this._root,
+ nodes,
+ child;
+
+ if (!node) return copy;
+
+ if (!node.length) return copy._root = leaf_copy(node), copy;
+
+ nodes = [{source: node, target: copy._root = new Array(4)}];
+ while (node = nodes.pop()) {
+ for (var i = 0; i < 4; ++i) {
+ if (child = node.source[i]) {
+ if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)});
+ else node.target[i] = leaf_copy(child);
+ }
+ }
+ }
+
+ return copy;
+};
+
+treeProto.add = tree_add;
+treeProto.addAll = addAll;
+treeProto.cover = tree_cover;
+treeProto.data = tree_data;
+treeProto.extent = tree_extent;
+treeProto.find = tree_find;
+treeProto.remove = tree_remove;
+treeProto.removeAll = removeAll;
+treeProto.root = tree_root;
+treeProto.size = tree_size;
+treeProto.visit = tree_visit;
+treeProto.visitAfter = tree_visitAfter;
+treeProto.x = tree_x;
+treeProto.y = tree_y;
+
+exports.quadtree = quadtree;
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+})));
diff --git a/node_modules/d3-quadtree/dist/d3-quadtree.min.js b/node_modules/d3-quadtree/dist/d3-quadtree.min.js
new file mode 100644
index 00000000..670fa61c
--- /dev/null
+++ b/node_modules/d3-quadtree/dist/d3-quadtree.min.js
@@ -0,0 +1,2 @@
+// https://d3js.org/d3-quadtree/ v3.0.1 Copyright 2010-2021 Mike Bostock
+!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports):"function"==typeof define&&define.amd?define(["exports"],i):i((t="undefined"!=typeof globalThis?globalThis:t||self).d3=t.d3||{})}(this,(function(t){"use strict";function i(t,i,e,n){if(isNaN(i)||isNaN(e))return t;var r,s,h,o,a,u,l,_,f,c=t._root,x={data:n},y=t._x0,d=t._y0,p=t._x1,v=t._y1;if(!c)return t._root=x,t;for(;c.length;)if((u=i>=(s=(y+p)/2))?y=s:p=s,(l=e>=(h=(d+v)/2))?d=h:v=h,r=c,!(c=c[_=l<<1|u]))return r[_]=x,t;if(o=+t._x.call(null,c.data),a=+t._y.call(null,c.data),i===o&&e===a)return x.next=c,r?r[_]=x:t._root=x,t;do{r=r?r[_]=new Array(4):t._root=new Array(4),(u=i>=(s=(y+p)/2))?y=s:p=s,(l=e>=(h=(d+v)/2))?d=h:v=h}while((_=l<<1|u)==(f=(a>=h)<<1|o>=s));return r[f]=c,r[_]=x,t}function e(t,i,e,n,r){this.node=t,this.x0=i,this.y0=e,this.x1=n,this.y1=r}function n(t){return t[0]}function r(t){return t[1]}function s(t,i,e){var s=new h(null==i?n:i,null==e?r:e,NaN,NaN,NaN,NaN);return null==t?s:s.addAll(t)}function h(t,i,e,n,r,s){this._x=t,this._y=i,this._x0=e,this._y0=n,this._x1=r,this._y1=s,this._root=void 0}function o(t){for(var i={data:t.data},e=i;t=t.next;)e=e.next={data:t.data};return i}var a=s.prototype=h.prototype;a.copy=function(){var t,i,e=new h(this._x,this._y,this._x0,this._y0,this._x1,this._y1),n=this._root;if(!n)return e;if(!n.length)return e._root=o(n),e;for(t=[{source:n,target:e._root=new Array(4)}];n=t.pop();)for(var r=0;r<4;++r)(i=n.source[r])&&(i.length?t.push({source:i,target:n.target[r]=new Array(4)}):n.target[r]=o(i));return e},a.add=function(t){const e=+this._x.call(null,t),n=+this._y.call(null,t);return i(this.cover(e,n),e,n,t)},a.addAll=function(t){var e,n,r,s,h=t.length,o=new Array(h),a=new Array(h),u=1/0,l=1/0,_=-1/0,f=-1/0;for(n=0;n_&&(_=r),sf&&(f=s));if(u>_||l>f)return this;for(this.cover(u,l).cover(_,f),n=0;nt||t>=r||n>i||i>=s;)switch(o=(ic||(h=u.y0)>x||(o=u.x1)<_||(a=u.y1)=v)<<1|t>=p)&&(u=y[y.length-1],y[y.length-1]=y[y.length-1-l],y[y.length-1-l]=u)}else{var w=t-+this._x.call(null,d.data),N=i-+this._y.call(null,d.data),g=w*w+N*N;if(g=(o=(x+d)/2))?x=o:d=o,(l=h>=(a=(y+p)/2))?y=a:p=a,i=c,!(c=c[_=l<<1|u]))return this;if(!c.length)break;(i[_+1&3]||i[_+2&3]||i[_+3&3])&&(e=i,f=_)}for(;c.data!==t;)if(n=c,!(c=c.next))return this;return(r=c.next)&&delete c.next,n?(r?n.next=r:delete n.next,this):i?(r?i[_]=r:delete i[_],(c=i[0]||i[1]||i[2]||i[3])&&c===(i[3]||i[2]||i[1]||i[0])&&!c.length&&(e?e[f]=c:this._root=c),this):(this._root=r,this)},a.removeAll=function(t){for(var i=0,e=t.length;i=12"
+ },
+ "exports": {
+ "umd": "./dist/d3-quadtree.min.js",
+ "default": "./src/index.js"
+ },
+ "files": [
+ "dist/**/*.js",
+ "src/**/*.js"
+ ],
+ "homepage": "https://d3js.org/d3-quadtree/",
+ "jsdelivr": "dist/d3-quadtree.min.js",
+ "keywords": [
+ "d3",
+ "d3-module",
+ "quadtree"
+ ],
+ "license": "ISC",
+ "main": "src/index.js",
+ "module": "src/index.js",
+ "name": "d3-quadtree",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/d3/d3-quadtree.git"
+ },
+ "scripts": {
+ "postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -",
+ "prepublishOnly": "rm -rf dist && yarn test && rollup -c",
+ "test": "mocha 'test/**/*-test.js' && eslint src test"
+ },
+ "sideEffects": false,
+ "type": "module",
+ "unpkg": "dist/d3-quadtree.min.js",
+ "version": "3.0.1"
+}
diff --git a/node_modules/d3-quadtree/src/add.js b/node_modules/d3-quadtree/src/add.js
new file mode 100644
index 00000000..985adfcf
--- /dev/null
+++ b/node_modules/d3-quadtree/src/add.js
@@ -0,0 +1,84 @@
+export default function(d) {
+ const x = +this._x.call(null, d),
+ y = +this._y.call(null, d);
+ return add(this.cover(x, y), x, y, d);
+}
+
+function add(tree, x, y, d) {
+ if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points
+
+ var parent,
+ node = tree._root,
+ leaf = {data: d},
+ x0 = tree._x0,
+ y0 = tree._y0,
+ x1 = tree._x1,
+ y1 = tree._y1,
+ xm,
+ ym,
+ xp,
+ yp,
+ right,
+ bottom,
+ i,
+ j;
+
+ // If the tree is empty, initialize the root as a leaf.
+ if (!node) return tree._root = leaf, tree;
+
+ // Find the existing leaf for the new point, or add it.
+ while (node.length) {
+ if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
+ if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
+ if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree;
+ }
+
+ // Is the new point is exactly coincident with the existing point?
+ xp = +tree._x.call(null, node.data);
+ yp = +tree._y.call(null, node.data);
+ if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree;
+
+ // Otherwise, split the leaf node until the old and new point are separated.
+ do {
+ parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4);
+ if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
+ if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
+ } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm)));
+ return parent[j] = node, parent[i] = leaf, tree;
+}
+
+export function addAll(data) {
+ var d, i, n = data.length,
+ x,
+ y,
+ xz = new Array(n),
+ yz = new Array(n),
+ x0 = Infinity,
+ y0 = Infinity,
+ x1 = -Infinity,
+ y1 = -Infinity;
+
+ // Compute the points and their extent.
+ for (i = 0; i < n; ++i) {
+ if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue;
+ xz[i] = x;
+ yz[i] = y;
+ if (x < x0) x0 = x;
+ if (x > x1) x1 = x;
+ if (y < y0) y0 = y;
+ if (y > y1) y1 = y;
+ }
+
+ // If there were no (valid) points, abort.
+ if (x0 > x1 || y0 > y1) return this;
+
+ // Expand the tree to cover the new points.
+ this.cover(x0, y0).cover(x1, y1);
+
+ // Add the new points.
+ for (i = 0; i < n; ++i) {
+ add(this, xz[i], yz[i], data[i]);
+ }
+
+ return this;
+}
diff --git a/node_modules/d3-quadtree/src/cover.js b/node_modules/d3-quadtree/src/cover.js
new file mode 100644
index 00000000..e1d47cd6
--- /dev/null
+++ b/node_modules/d3-quadtree/src/cover.js
@@ -0,0 +1,43 @@
+export default function(x, y) {
+ if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points
+
+ var x0 = this._x0,
+ y0 = this._y0,
+ x1 = this._x1,
+ y1 = this._y1;
+
+ // If the quadtree has no extent, initialize them.
+ // Integer extent are necessary so that if we later double the extent,
+ // the existing quadrant boundaries don’t change due to floating point error!
+ if (isNaN(x0)) {
+ x1 = (x0 = Math.floor(x)) + 1;
+ y1 = (y0 = Math.floor(y)) + 1;
+ }
+
+ // Otherwise, double repeatedly to cover.
+ else {
+ var z = x1 - x0 || 1,
+ node = this._root,
+ parent,
+ i;
+
+ while (x0 > x || x >= x1 || y0 > y || y >= y1) {
+ i = (y < y0) << 1 | (x < x0);
+ parent = new Array(4), parent[i] = node, node = parent, z *= 2;
+ switch (i) {
+ case 0: x1 = x0 + z, y1 = y0 + z; break;
+ case 1: x0 = x1 - z, y1 = y0 + z; break;
+ case 2: x1 = x0 + z, y0 = y1 - z; break;
+ case 3: x0 = x1 - z, y0 = y1 - z; break;
+ }
+ }
+
+ if (this._root && this._root.length) this._root = node;
+ }
+
+ this._x0 = x0;
+ this._y0 = y0;
+ this._x1 = x1;
+ this._y1 = y1;
+ return this;
+}
diff --git a/node_modules/d3-quadtree/src/data.js b/node_modules/d3-quadtree/src/data.js
new file mode 100644
index 00000000..e934fa9d
--- /dev/null
+++ b/node_modules/d3-quadtree/src/data.js
@@ -0,0 +1,7 @@
+export default function() {
+ var data = [];
+ this.visit(function(node) {
+ if (!node.length) do data.push(node.data); while (node = node.next)
+ });
+ return data;
+}
diff --git a/node_modules/d3-quadtree/src/extent.js b/node_modules/d3-quadtree/src/extent.js
new file mode 100644
index 00000000..9e65a90a
--- /dev/null
+++ b/node_modules/d3-quadtree/src/extent.js
@@ -0,0 +1,5 @@
+export default function(_) {
+ return arguments.length
+ ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1])
+ : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]];
+}
diff --git a/node_modules/d3-quadtree/src/find.js b/node_modules/d3-quadtree/src/find.js
new file mode 100644
index 00000000..e9db6c41
--- /dev/null
+++ b/node_modules/d3-quadtree/src/find.js
@@ -0,0 +1,70 @@
+import Quad from "./quad.js";
+
+export default function(x, y, radius) {
+ var data,
+ x0 = this._x0,
+ y0 = this._y0,
+ x1,
+ y1,
+ x2,
+ y2,
+ x3 = this._x1,
+ y3 = this._y1,
+ quads = [],
+ node = this._root,
+ q,
+ i;
+
+ if (node) quads.push(new Quad(node, x0, y0, x3, y3));
+ if (radius == null) radius = Infinity;
+ else {
+ x0 = x - radius, y0 = y - radius;
+ x3 = x + radius, y3 = y + radius;
+ radius *= radius;
+ }
+
+ while (q = quads.pop()) {
+
+ // Stop searching if this quadrant can’t contain a closer node.
+ if (!(node = q.node)
+ || (x1 = q.x0) > x3
+ || (y1 = q.y0) > y3
+ || (x2 = q.x1) < x0
+ || (y2 = q.y1) < y0) continue;
+
+ // Bisect the current quadrant.
+ if (node.length) {
+ var xm = (x1 + x2) / 2,
+ ym = (y1 + y2) / 2;
+
+ quads.push(
+ new Quad(node[3], xm, ym, x2, y2),
+ new Quad(node[2], x1, ym, xm, y2),
+ new Quad(node[1], xm, y1, x2, ym),
+ new Quad(node[0], x1, y1, xm, ym)
+ );
+
+ // Visit the closest quadrant first.
+ if (i = (y >= ym) << 1 | (x >= xm)) {
+ q = quads[quads.length - 1];
+ quads[quads.length - 1] = quads[quads.length - 1 - i];
+ quads[quads.length - 1 - i] = q;
+ }
+ }
+
+ // Visit this point. (Visiting coincident points isn’t necessary!)
+ else {
+ var dx = x - +this._x.call(null, node.data),
+ dy = y - +this._y.call(null, node.data),
+ d2 = dx * dx + dy * dy;
+ if (d2 < radius) {
+ var d = Math.sqrt(radius = d2);
+ x0 = x - d, y0 = y - d;
+ x3 = x + d, y3 = y + d;
+ data = node.data;
+ }
+ }
+ }
+
+ return data;
+}
diff --git a/node_modules/d3-quadtree/src/index.js b/node_modules/d3-quadtree/src/index.js
new file mode 100644
index 00000000..e2b2c313
--- /dev/null
+++ b/node_modules/d3-quadtree/src/index.js
@@ -0,0 +1 @@
+export {default as quadtree} from "./quadtree.js";
diff --git a/node_modules/d3-quadtree/src/quad.js b/node_modules/d3-quadtree/src/quad.js
new file mode 100644
index 00000000..6f714dbb
--- /dev/null
+++ b/node_modules/d3-quadtree/src/quad.js
@@ -0,0 +1,7 @@
+export default function(node, x0, y0, x1, y1) {
+ this.node = node;
+ this.x0 = x0;
+ this.y0 = y0;
+ this.x1 = x1;
+ this.y1 = y1;
+}
diff --git a/node_modules/d3-quadtree/src/quadtree.js b/node_modules/d3-quadtree/src/quadtree.js
new file mode 100644
index 00000000..5d585938
--- /dev/null
+++ b/node_modules/d3-quadtree/src/quadtree.js
@@ -0,0 +1,73 @@
+import tree_add, {addAll as tree_addAll} from "./add.js";
+import tree_cover from "./cover.js";
+import tree_data from "./data.js";
+import tree_extent from "./extent.js";
+import tree_find from "./find.js";
+import tree_remove, {removeAll as tree_removeAll} from "./remove.js";
+import tree_root from "./root.js";
+import tree_size from "./size.js";
+import tree_visit from "./visit.js";
+import tree_visitAfter from "./visitAfter.js";
+import tree_x, {defaultX} from "./x.js";
+import tree_y, {defaultY} from "./y.js";
+
+export default function quadtree(nodes, x, y) {
+ var tree = new Quadtree(x == null ? defaultX : x, y == null ? defaultY : y, NaN, NaN, NaN, NaN);
+ return nodes == null ? tree : tree.addAll(nodes);
+}
+
+function Quadtree(x, y, x0, y0, x1, y1) {
+ this._x = x;
+ this._y = y;
+ this._x0 = x0;
+ this._y0 = y0;
+ this._x1 = x1;
+ this._y1 = y1;
+ this._root = undefined;
+}
+
+function leaf_copy(leaf) {
+ var copy = {data: leaf.data}, next = copy;
+ while (leaf = leaf.next) next = next.next = {data: leaf.data};
+ return copy;
+}
+
+var treeProto = quadtree.prototype = Quadtree.prototype;
+
+treeProto.copy = function() {
+ var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1),
+ node = this._root,
+ nodes,
+ child;
+
+ if (!node) return copy;
+
+ if (!node.length) return copy._root = leaf_copy(node), copy;
+
+ nodes = [{source: node, target: copy._root = new Array(4)}];
+ while (node = nodes.pop()) {
+ for (var i = 0; i < 4; ++i) {
+ if (child = node.source[i]) {
+ if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)});
+ else node.target[i] = leaf_copy(child);
+ }
+ }
+ }
+
+ return copy;
+};
+
+treeProto.add = tree_add;
+treeProto.addAll = tree_addAll;
+treeProto.cover = tree_cover;
+treeProto.data = tree_data;
+treeProto.extent = tree_extent;
+treeProto.find = tree_find;
+treeProto.remove = tree_remove;
+treeProto.removeAll = tree_removeAll;
+treeProto.root = tree_root;
+treeProto.size = tree_size;
+treeProto.visit = tree_visit;
+treeProto.visitAfter = tree_visitAfter;
+treeProto.x = tree_x;
+treeProto.y = tree_y;
diff --git a/node_modules/d3-quadtree/src/remove.js b/node_modules/d3-quadtree/src/remove.js
new file mode 100644
index 00000000..0ba27abe
--- /dev/null
+++ b/node_modules/d3-quadtree/src/remove.js
@@ -0,0 +1,62 @@
+export default function(d) {
+ if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points
+
+ var parent,
+ node = this._root,
+ retainer,
+ previous,
+ next,
+ x0 = this._x0,
+ y0 = this._y0,
+ x1 = this._x1,
+ y1 = this._y1,
+ x,
+ y,
+ xm,
+ ym,
+ right,
+ bottom,
+ i,
+ j;
+
+ // If the tree is empty, initialize the root as a leaf.
+ if (!node) return this;
+
+ // Find the leaf node for the point.
+ // While descending, also retain the deepest parent with a non-removed sibling.
+ if (node.length) while (true) {
+ if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm;
+ if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym;
+ if (!(parent = node, node = node[i = bottom << 1 | right])) return this;
+ if (!node.length) break;
+ if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i;
+ }
+
+ // Find the point to remove.
+ while (node.data !== d) if (!(previous = node, node = node.next)) return this;
+ if (next = node.next) delete node.next;
+
+ // If there are multiple coincident points, remove just the point.
+ if (previous) return (next ? previous.next = next : delete previous.next), this;
+
+ // If this is the root point, remove it.
+ if (!parent) return this._root = next, this;
+
+ // Remove this leaf.
+ next ? parent[i] = next : delete parent[i];
+
+ // If the parent now contains exactly one leaf, collapse superfluous parents.
+ if ((node = parent[0] || parent[1] || parent[2] || parent[3])
+ && node === (parent[3] || parent[2] || parent[1] || parent[0])
+ && !node.length) {
+ if (retainer) retainer[j] = node;
+ else this._root = node;
+ }
+
+ return this;
+}
+
+export function removeAll(data) {
+ for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]);
+ return this;
+}
diff --git a/node_modules/d3-quadtree/src/root.js b/node_modules/d3-quadtree/src/root.js
new file mode 100644
index 00000000..c32889f7
--- /dev/null
+++ b/node_modules/d3-quadtree/src/root.js
@@ -0,0 +1,3 @@
+export default function() {
+ return this._root;
+}
diff --git a/node_modules/d3-quadtree/src/size.js b/node_modules/d3-quadtree/src/size.js
new file mode 100644
index 00000000..d2d5ab61
--- /dev/null
+++ b/node_modules/d3-quadtree/src/size.js
@@ -0,0 +1,7 @@
+export default function() {
+ var size = 0;
+ this.visit(function(node) {
+ if (!node.length) do ++size; while (node = node.next)
+ });
+ return size;
+}
diff --git a/node_modules/d3-quadtree/src/visit.js b/node_modules/d3-quadtree/src/visit.js
new file mode 100644
index 00000000..941ab884
--- /dev/null
+++ b/node_modules/d3-quadtree/src/visit.js
@@ -0,0 +1,16 @@
+import Quad from "./quad.js";
+
+export default function(callback) {
+ var quads = [], q, node = this._root, child, x0, y0, x1, y1;
+ if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1));
+ while (q = quads.pop()) {
+ if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) {
+ var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
+ if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
+ if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
+ if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
+ if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
+ }
+ }
+ return this;
+}
diff --git a/node_modules/d3-quadtree/src/visitAfter.js b/node_modules/d3-quadtree/src/visitAfter.js
new file mode 100644
index 00000000..20966553
--- /dev/null
+++ b/node_modules/d3-quadtree/src/visitAfter.js
@@ -0,0 +1,21 @@
+import Quad from "./quad.js";
+
+export default function(callback) {
+ var quads = [], next = [], q;
+ if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1));
+ while (q = quads.pop()) {
+ var node = q.node;
+ if (node.length) {
+ var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2;
+ if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym));
+ if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym));
+ if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1));
+ if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1));
+ }
+ next.push(q);
+ }
+ while (q = next.pop()) {
+ callback(q.node, q.x0, q.y0, q.x1, q.y1);
+ }
+ return this;
+}
diff --git a/node_modules/d3-quadtree/src/x.js b/node_modules/d3-quadtree/src/x.js
new file mode 100644
index 00000000..ffea5075
--- /dev/null
+++ b/node_modules/d3-quadtree/src/x.js
@@ -0,0 +1,7 @@
+export function defaultX(d) {
+ return d[0];
+}
+
+export default function(_) {
+ return arguments.length ? (this._x = _, this) : this._x;
+}
diff --git a/node_modules/d3-quadtree/src/y.js b/node_modules/d3-quadtree/src/y.js
new file mode 100644
index 00000000..d2d29cb7
--- /dev/null
+++ b/node_modules/d3-quadtree/src/y.js
@@ -0,0 +1,7 @@
+export function defaultY(d) {
+ return d[1];
+}
+
+export default function(_) {
+ return arguments.length ? (this._y = _, this) : this._y;
+}
diff --git a/node_modules/d3-random/LICENSE b/node_modules/d3-random/LICENSE
new file mode 100644
index 00000000..b0145150
--- /dev/null
+++ b/node_modules/d3-random/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2010-2021 Mike Bostock
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/node_modules/d3-random/README.md b/node_modules/d3-random/README.md
new file mode 100644
index 00000000..1e67488a
--- /dev/null
+++ b/node_modules/d3-random/README.md
@@ -0,0 +1,133 @@
+# d3-random
+
+Generate random numbers from various distributions.
+
+See the [d3-random collection on Observable](https://observablehq.com/collection/@d3/d3-random) for examples.
+
+## Installing
+
+If you use npm, `npm install d3-random`. You can also download the [latest release on GitHub](https://github.com/d3/d3-random/releases/latest). For vanilla HTML in modern browsers, import d3-random from Skypack:
+
+```html
+
+```
+
+For legacy environments, you can load d3-random’s UMD bundle from an npm-based CDN such as jsDelivr; a `d3` global is exported:
+
+```html
+
+
+```
+
+## API Reference
+
+# d3.randomUniform([min, ][max]) · [Source](https://github.com/d3/d3-random/blob/master/src/uniform.js), [Examples](https://observablehq.com/@d3/d3-random#uniform)
+
+Returns a function for generating random numbers with a [uniform distribution](https://en.wikipedia.org/wiki/Uniform_distribution_\(continuous\)). The minimum allowed value of a returned number is *min* (inclusive), and the maximum is *max* (exclusive). If *min* is not specified, it defaults to 0; if *max* is not specified, it defaults to 1. For example:
+
+```js
+d3.randomUniform(6)(); // Returns a number greater than or equal to 0 and less than 6.
+d3.randomUniform(1, 5)(); // Returns a number greater than or equal to 1 and less than 5.
+```
+
+# d3.randomInt([min, ][max]) · [Source](https://github.com/d3/d3-random/blob/master/src/int.js), [Examples](https://observablehq.com/@d3/d3-random#int)
+
+Returns a function for generating random integers with a [uniform distribution](https://en.wikipedia.org/wiki/Uniform_distribution_\(continuous\)). The minimum allowed value of a returned number is ⌊*min*⌋ (inclusive), and the maximum is ⌊*max* - 1⌋ (inclusive). If *min* is not specified, it defaults to 0. For example:
+
+```js
+d3.randomInt(6)(); // Returns an integer greater than or equal to 0 and less than 6.
+d3.randomInt(1, 5)(); // Returns an integer greater than or equal to 1 and less than 5.
+```
+
+# d3.randomNormal([mu][, sigma]) · [Source](https://github.com/d3/d3-random/blob/master/src/normal.js), [Examples](https://observablehq.com/@d3/d3-random#normal)
+
+Returns a function for generating random numbers with a [normal (Gaussian) distribution](https://en.wikipedia.org/wiki/Normal_distribution). The expected value of the generated numbers is *mu*, with the given standard deviation *sigma*. If *mu* is not specified, it defaults to 0; if *sigma* is not specified, it defaults to 1.
+
+# d3.randomLogNormal([mu][, sigma]) · [Source](https://github.com/d3/d3-random/blob/master/src/logNormal.js), [Examples](https://observablehq.com/@d3/d3-random#logNormal)
+
+Returns a function for generating random numbers with a [log-normal distribution](https://en.wikipedia.org/wiki/Log-normal_distribution). The expected value of the random variable’s natural logarithm is *mu*, with the given standard deviation *sigma*. If *mu* is not specified, it defaults to 0; if *sigma* is not specified, it defaults to 1.
+
+# d3.randomBates(n) · [Source](https://github.com/d3/d3-random/blob/master/src/bates.js), [Examples](https://observablehq.com/@d3/d3-random#bates)
+
+Returns a function for generating random numbers with a [Bates distribution](https://en.wikipedia.org/wiki/Bates_distribution) with *n* independent variables. The case of fractional *n* is handled as with d3.randomIrwinHall, and d3.randomBates(0) is equivalent to d3.randomUniform().
+
+# d3.randomIrwinHall(n) · [Source](https://github.com/d3/d3-random/blob/master/src/irwinHall.js), [Examples](https://observablehq.com/@d3/d3-random#irwinHall)
+
+Returns a function for generating random numbers with an [Irwin–Hall distribution](https://en.wikipedia.org/wiki/Irwin–Hall_distribution) with *n* independent variables. If the fractional part of *n* is non-zero, this is treated as adding d3.randomUniform() times that fractional part to the integral part.
+
+# d3.randomExponential(lambda) · [Source](https://github.com/d3/d3-random/blob/master/src/exponential.js), [Examples](https://observablehq.com/@d3/d3-random#exponential)
+
+Returns a function for generating random numbers with an [exponential distribution](https://en.wikipedia.org/wiki/Exponential_distribution) with the rate *lambda*; equivalent to time between events in a [Poisson process](https://en.wikipedia.org/wiki/Poisson_point_process) with a mean of 1 / *lambda*. For example, exponential(1/40) generates random times between events where, on average, one event occurs every 40 units of time.
+
+# d3.randomPareto(alpha) · [Source](https://github.com/d3/d3-random/blob/master/src/pareto.js), [Examples](https://observablehq.com/@d3/d3-random#pareto)
+
+Returns a function for generating random numbers with a [Pareto distribution](https://en.wikipedia.org/wiki/Pareto_distribution) with the shape *alpha*. The value *alpha* must be a positive value.
+
+# d3.randomBernoulli(p) · [Source](https://github.com/d3/d3-random/blob/master/src/bernoulli.js), [Examples](https://observablehq.com/@d3/d3-random#bernoulli)
+
+Returns a function for generating either 1 or 0 according to a [Bernoulli distribution](https://en.wikipedia.org/wiki/Binomial_distribution) with 1 being returned with success probability *p* and 0 with failure probability *q* = 1 - *p*. The value *p* is in the range [0, 1].
+
+# d3.randomGeometric(p) · [Source](https://github.com/d3/d3-random/blob/master/src/geometric.js), [Examples](https://observablehq.com/@d3/d3-random#geometric)
+
+Returns a function for generating numbers with a [geometric distribution](https://en.wikipedia.org/wiki/Geometric_distribution) with success probability *p*. The value *p* is in the range [0, 1].
+
+# d3.randomBinomial(n, p) · [Source](https://github.com/d3/d3-random/blob/master/src/binomial.js), [Examples](https://observablehq.com/@d3/d3-random#binomial)
+
+Returns a function for generating random numbers with a [binomial distribution](https://en.wikipedia.org/wiki/Binomial_distribution) with *n* the number of trials and *p* the probability of success in each trial. The value *n* is greater or equal to 0, and the value *p* is in the range [0, 1].
+
+# d3.randomGamma(k, [theta]) · [Source](https://github.com/d3/d3-random/blob/master/src/gamma.js), [Examples](https://observablehq.com/@parcly-taxel/the-gamma-and-beta-distributions)
+
+Returns a function for generating random numbers with a [gamma distribution](https://en.wikipedia.org/wiki/Gamma_distribution) with *k* the shape parameter and *theta* the scale parameter. The value *k* must be a positive value; if *theta* is not specified, it defaults to 1.
+
+# d3.randomBeta(alpha, beta) · [Source](https://github.com/d3/d3-random/blob/master/src/beta.js), [Examples](https://observablehq.com/@parcly-taxel/the-gamma-and-beta-distributions)
+
+Returns a function for generating random numbers with a [beta distribution](https://en.wikipedia.org/wiki/Beta_distribution) with *alpha* and *beta* shape parameters, which must both be positive.
+
+# d3.randomWeibull(k, [a], [b]) · [Source](https://github.com/d3/d3-random/blob/master/src/weibull.js), [Examples](https://observablehq.com/@parcly-taxel/frechet-gumbel-weibull)
+
+Returns a function for generating random numbers with one of the [generalized extreme value distributions](https://en.wikipedia.org/wiki/Generalized_extreme_value_distribution), depending on *k*:
+
+* If *k* is positive, the [Weibull distribution](https://en.wikipedia.org/wiki/Weibull_distribution) with shape parameter *k*
+* If *k* is zero, the [Gumbel distribution](https://en.wikipedia.org/wiki/Gumbel_distribution)
+* If *k* is negative, the [Fréchet distribution](https://en.wikipedia.org/wiki/Fréchet_distribution) with shape parameter −*k*
+
+In all three cases, *a* is the location parameter and *b* is the scale parameter. If *a* is not specified, it defaults to 0; if *b* is not specified, it defaults to 1.
+
+# d3.randomCauchy([a], [b]) · [Source](https://github.com/d3/d3-random/blob/master/src/cauchy.js), [Examples](https://observablehq.com/@parcly-taxel/cauchy-and-logistic-distributions)
+
+Returns a function for generating random numbers with a [Cauchy distribution](https://en.wikipedia.org/wiki/Cauchy_distribution). *a* and *b* have the same meanings and default values as in d3.randomWeibull.
+
+# d3.randomLogistic([a], [b]) · [Source](https://github.com/d3/d3-random/blob/master/src/logistic.js), [Examples](https://observablehq.com/@parcly-taxel/cauchy-and-logistic-distributions)
+
+Returns a function for generating random numbers with a [logistic distribution](https://en.wikipedia.org/wiki/Logistic_distribution). *a* and *b* have the same meanings and default values as in d3.randomWeibull.
+
+# d3.randomPoisson(lambda) · [Source](https://github.com/d3/d3-random/blob/master/src/poisson.js), [Examples](https://observablehq.com/@parcly-taxel/the-poisson-distribution)
+
+Returns a function for generating random numbers with a [Poisson distribution](https://en.wikipedia.org/wiki/Poisson_distribution) with mean *lambda*.
+
+# random.source(source) · [Examples](https://observablehq.com/@d3/random-source)
+
+Returns the same type of function for generating random numbers but where the given random number generator *source* is used as the source of randomness instead of Math.random. The given random number generator must implement the same interface as Math.random and only return values in the range [0, 1). This is useful when a seeded random number generator is preferable to Math.random. For example:
+
+```js
+import {randomLcg, randomNumber} from "d3-random";
+
+const seed = 0.44871573888282423; // any number in [0, 1)
+const random = randomNormal.source(randomLcg(seed))(0, 1);
+
+random(); // -0.6253955998897069
+```
+
+# d3.randomLcg([seed]) · [Source](https://github.com/d3/d3-random/blob/master/src/lcg.js), [Examples](https://observablehq.com/@d3/d3-randomlcg)
+
+Returns a [linear congruential generator](https://en.wikipedia.org/wiki/Linear_congruential_generator); this function can be called repeatedly to obtain pseudorandom values well-distributed on the interval [0,1) and with a long period (up to 1 billion numbers), similar to Math.random. A *seed* can be specified as a real number in the interval [0,1) or as any integer. In the latter case, only the lower 32 bits are considered. Two generators instanced with the same seed generate the same sequence, allowing to create reproducible pseudo-random experiments. If the *seed* is not specified, one is chosen using Math.random.
diff --git a/node_modules/d3-random/dist/d3-random.js b/node_modules/d3-random/dist/d3-random.js
new file mode 100644
index 00000000..e4b6eaae
--- /dev/null
+++ b/node_modules/d3-random/dist/d3-random.js
@@ -0,0 +1,358 @@
+// https://d3js.org/d3-random/ v3.0.1 Copyright 2010-2021 Mike Bostock
+(function (global, factory) {
+typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+typeof define === 'function' && define.amd ? define(['exports'], factory) :
+(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}));
+}(this, (function (exports) { 'use strict';
+
+var defaultSource = Math.random;
+
+var uniform = (function sourceRandomUniform(source) {
+ function randomUniform(min, max) {
+ min = min == null ? 0 : +min;
+ max = max == null ? 1 : +max;
+ if (arguments.length === 1) max = min, min = 0;
+ else max -= min;
+ return function() {
+ return source() * max + min;
+ };
+ }
+
+ randomUniform.source = sourceRandomUniform;
+
+ return randomUniform;
+})(defaultSource);
+
+var int = (function sourceRandomInt(source) {
+ function randomInt(min, max) {
+ if (arguments.length < 2) max = min, min = 0;
+ min = Math.floor(min);
+ max = Math.floor(max) - min;
+ return function() {
+ return Math.floor(source() * max + min);
+ };
+ }
+
+ randomInt.source = sourceRandomInt;
+
+ return randomInt;
+})(defaultSource);
+
+var normal = (function sourceRandomNormal(source) {
+ function randomNormal(mu, sigma) {
+ var x, r;
+ mu = mu == null ? 0 : +mu;
+ sigma = sigma == null ? 1 : +sigma;
+ return function() {
+ var y;
+
+ // If available, use the second previously-generated uniform random.
+ if (x != null) y = x, x = null;
+
+ // Otherwise, generate a new x and y.
+ else do {
+ x = source() * 2 - 1;
+ y = source() * 2 - 1;
+ r = x * x + y * y;
+ } while (!r || r > 1);
+
+ return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r);
+ };
+ }
+
+ randomNormal.source = sourceRandomNormal;
+
+ return randomNormal;
+})(defaultSource);
+
+var logNormal = (function sourceRandomLogNormal(source) {
+ var N = normal.source(source);
+
+ function randomLogNormal() {
+ var randomNormal = N.apply(this, arguments);
+ return function() {
+ return Math.exp(randomNormal());
+ };
+ }
+
+ randomLogNormal.source = sourceRandomLogNormal;
+
+ return randomLogNormal;
+})(defaultSource);
+
+var irwinHall = (function sourceRandomIrwinHall(source) {
+ function randomIrwinHall(n) {
+ if ((n = +n) <= 0) return () => 0;
+ return function() {
+ for (var sum = 0, i = n; i > 1; --i) sum += source();
+ return sum + i * source();
+ };
+ }
+
+ randomIrwinHall.source = sourceRandomIrwinHall;
+
+ return randomIrwinHall;
+})(defaultSource);
+
+var bates = (function sourceRandomBates(source) {
+ var I = irwinHall.source(source);
+
+ function randomBates(n) {
+ // use limiting distribution at n === 0
+ if ((n = +n) === 0) return source;
+ var randomIrwinHall = I(n);
+ return function() {
+ return randomIrwinHall() / n;
+ };
+ }
+
+ randomBates.source = sourceRandomBates;
+
+ return randomBates;
+})(defaultSource);
+
+var exponential = (function sourceRandomExponential(source) {
+ function randomExponential(lambda) {
+ return function() {
+ return -Math.log1p(-source()) / lambda;
+ };
+ }
+
+ randomExponential.source = sourceRandomExponential;
+
+ return randomExponential;
+})(defaultSource);
+
+var pareto = (function sourceRandomPareto(source) {
+ function randomPareto(alpha) {
+ if ((alpha = +alpha) < 0) throw new RangeError("invalid alpha");
+ alpha = 1 / -alpha;
+ return function() {
+ return Math.pow(1 - source(), alpha);
+ };
+ }
+
+ randomPareto.source = sourceRandomPareto;
+
+ return randomPareto;
+})(defaultSource);
+
+var bernoulli = (function sourceRandomBernoulli(source) {
+ function randomBernoulli(p) {
+ if ((p = +p) < 0 || p > 1) throw new RangeError("invalid p");
+ return function() {
+ return Math.floor(source() + p);
+ };
+ }
+
+ randomBernoulli.source = sourceRandomBernoulli;
+
+ return randomBernoulli;
+})(defaultSource);
+
+var geometric = (function sourceRandomGeometric(source) {
+ function randomGeometric(p) {
+ if ((p = +p) < 0 || p > 1) throw new RangeError("invalid p");
+ if (p === 0) return () => Infinity;
+ if (p === 1) return () => 1;
+ p = Math.log1p(-p);
+ return function() {
+ return 1 + Math.floor(Math.log1p(-source()) / p);
+ };
+ }
+
+ randomGeometric.source = sourceRandomGeometric;
+
+ return randomGeometric;
+})(defaultSource);
+
+var gamma = (function sourceRandomGamma(source) {
+ var randomNormal = normal.source(source)();
+
+ function randomGamma(k, theta) {
+ if ((k = +k) < 0) throw new RangeError("invalid k");
+ // degenerate distribution if k === 0
+ if (k === 0) return () => 0;
+ theta = theta == null ? 1 : +theta;
+ // exponential distribution if k === 1
+ if (k === 1) return () => -Math.log1p(-source()) * theta;
+
+ var d = (k < 1 ? k + 1 : k) - 1 / 3,
+ c = 1 / (3 * Math.sqrt(d)),
+ multiplier = k < 1 ? () => Math.pow(source(), 1 / k) : () => 1;
+ return function() {
+ do {
+ do {
+ var x = randomNormal(),
+ v = 1 + c * x;
+ } while (v <= 0);
+ v *= v * v;
+ var u = 1 - source();
+ } while (u >= 1 - 0.0331 * x * x * x * x && Math.log(u) >= 0.5 * x * x + d * (1 - v + Math.log(v)));
+ return d * v * multiplier() * theta;
+ };
+ }
+
+ randomGamma.source = sourceRandomGamma;
+
+ return randomGamma;
+})(defaultSource);
+
+var beta = (function sourceRandomBeta(source) {
+ var G = gamma.source(source);
+
+ function randomBeta(alpha, beta) {
+ var X = G(alpha),
+ Y = G(beta);
+ return function() {
+ var x = X();
+ return x === 0 ? 0 : x / (x + Y());
+ };
+ }
+
+ randomBeta.source = sourceRandomBeta;
+
+ return randomBeta;
+})(defaultSource);
+
+var binomial = (function sourceRandomBinomial(source) {
+ var G = geometric.source(source),
+ B = beta.source(source);
+
+ function randomBinomial(n, p) {
+ n = +n;
+ if ((p = +p) >= 1) return () => n;
+ if (p <= 0) return () => 0;
+ return function() {
+ var acc = 0, nn = n, pp = p;
+ while (nn * pp > 16 && nn * (1 - pp) > 16) {
+ var i = Math.floor((nn + 1) * pp),
+ y = B(i, nn - i + 1)();
+ if (y <= pp) {
+ acc += i;
+ nn -= i;
+ pp = (pp - y) / (1 - y);
+ } else {
+ nn = i - 1;
+ pp /= y;
+ }
+ }
+ var sign = pp < 0.5,
+ pFinal = sign ? pp : 1 - pp,
+ g = G(pFinal);
+ for (var s = g(), k = 0; s <= nn; ++k) s += g();
+ return acc + (sign ? k : nn - k);
+ };
+ }
+
+ randomBinomial.source = sourceRandomBinomial;
+
+ return randomBinomial;
+})(defaultSource);
+
+var weibull = (function sourceRandomWeibull(source) {
+ function randomWeibull(k, a, b) {
+ var outerFunc;
+ if ((k = +k) === 0) {
+ outerFunc = x => -Math.log(x);
+ } else {
+ k = 1 / k;
+ outerFunc = x => Math.pow(x, k);
+ }
+ a = a == null ? 0 : +a;
+ b = b == null ? 1 : +b;
+ return function() {
+ return a + b * outerFunc(-Math.log1p(-source()));
+ };
+ }
+
+ randomWeibull.source = sourceRandomWeibull;
+
+ return randomWeibull;
+})(defaultSource);
+
+var cauchy = (function sourceRandomCauchy(source) {
+ function randomCauchy(a, b) {
+ a = a == null ? 0 : +a;
+ b = b == null ? 1 : +b;
+ return function() {
+ return a + b * Math.tan(Math.PI * source());
+ };
+ }
+
+ randomCauchy.source = sourceRandomCauchy;
+
+ return randomCauchy;
+})(defaultSource);
+
+var logistic = (function sourceRandomLogistic(source) {
+ function randomLogistic(a, b) {
+ a = a == null ? 0 : +a;
+ b = b == null ? 1 : +b;
+ return function() {
+ var u = source();
+ return a + b * Math.log(u / (1 - u));
+ };
+ }
+
+ randomLogistic.source = sourceRandomLogistic;
+
+ return randomLogistic;
+})(defaultSource);
+
+var poisson = (function sourceRandomPoisson(source) {
+ var G = gamma.source(source),
+ B = binomial.source(source);
+
+ function randomPoisson(lambda) {
+ return function() {
+ var acc = 0, l = lambda;
+ while (l > 16) {
+ var n = Math.floor(0.875 * l),
+ t = G(n)();
+ if (t > l) return acc + B(n - 1, l / t)();
+ acc += n;
+ l -= t;
+ }
+ for (var s = -Math.log1p(-source()), k = 0; s <= l; ++k) s -= Math.log1p(-source());
+ return acc + k;
+ };
+ }
+
+ randomPoisson.source = sourceRandomPoisson;
+
+ return randomPoisson;
+})(defaultSource);
+
+// https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use
+const mul = 0x19660D;
+const inc = 0x3C6EF35F;
+const eps = 1 / 0x100000000;
+
+function lcg(seed = Math.random()) {
+ let state = (0 <= seed && seed < 1 ? seed / eps : Math.abs(seed)) | 0;
+ return () => (state = mul * state + inc | 0, eps * (state >>> 0));
+}
+
+exports.randomBates = bates;
+exports.randomBernoulli = bernoulli;
+exports.randomBeta = beta;
+exports.randomBinomial = binomial;
+exports.randomCauchy = cauchy;
+exports.randomExponential = exponential;
+exports.randomGamma = gamma;
+exports.randomGeometric = geometric;
+exports.randomInt = int;
+exports.randomIrwinHall = irwinHall;
+exports.randomLcg = lcg;
+exports.randomLogNormal = logNormal;
+exports.randomLogistic = logistic;
+exports.randomNormal = normal;
+exports.randomPareto = pareto;
+exports.randomPoisson = poisson;
+exports.randomUniform = uniform;
+exports.randomWeibull = weibull;
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+})));
diff --git a/node_modules/d3-random/dist/d3-random.min.js b/node_modules/d3-random/dist/d3-random.min.js
new file mode 100644
index 00000000..d83f671a
--- /dev/null
+++ b/node_modules/d3-random/dist/d3-random.min.js
@@ -0,0 +1,2 @@
+// https://d3js.org/d3-random/ v3.0.1 Copyright 2010-2021 Mike Bostock
+!function(n,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r((n="undefined"!=typeof globalThis?globalThis:n||self).d3=n.d3||{})}(this,(function(n){"use strict";var r=Math.random,t=function n(r){function t(n,t){return n=null==n?0:+n,t=null==t?1:+t,1===arguments.length?(t=n,n=0):t-=n,function(){return r()*t+n}}return t.source=n,t}(r),o=function n(r){function t(n,t){return arguments.length<2&&(t=n,n=0),n=Math.floor(n),t=Math.floor(t)-n,function(){return Math.floor(r()*t+n)}}return t.source=n,t}(r),u=function n(r){function t(n,t){var o,u;return n=null==n?0:+n,t=null==t?1:+t,function(){var e;if(null!=o)e=o,o=null;else do{o=2*r()-1,e=2*r()-1,u=o*o+e*e}while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}}return t.source=n,t}(r),e=function n(r){var t=u.source(r);function o(){var n=t.apply(this,arguments);return function(){return Math.exp(n())}}return o.source=n,o}(r),a=function n(r){function t(n){return(n=+n)<=0?()=>0:function(){for(var t=0,o=n;o>1;--o)t+=r();return t+o*r()}}return t.source=n,t}(r),i=function n(r){var t=a.source(r);function o(n){if(0==(n=+n))return r;var o=t(n);return function(){return o()/n}}return o.source=n,o}(r),c=function n(r){function t(n){return function(){return-Math.log1p(-r())/n}}return t.source=n,t}(r),f=function n(r){function t(n){if((n=+n)<0)throw new RangeError("invalid alpha");return n=1/-n,function(){return Math.pow(1-r(),n)}}return t.source=n,t}(r),l=function n(r){function t(n){if((n=+n)<0||n>1)throw new RangeError("invalid p");return function(){return Math.floor(r()+n)}}return t.source=n,t}(r),h=function n(r){function t(n){if((n=+n)<0||n>1)throw new RangeError("invalid p");return 0===n?()=>1/0:1===n?()=>1:(n=Math.log1p(-n),function(){return 1+Math.floor(Math.log1p(-r())/n)})}return t.source=n,t}(r),s=function n(r){var t=u.source(r)();function o(n,o){if((n=+n)<0)throw new RangeError("invalid k");if(0===n)return()=>0;if(o=null==o?1:+o,1===n)return()=>-Math.log1p(-r())*o;var u=(n<1?n+1:n)-1/3,e=1/(3*Math.sqrt(u)),a=n<1?()=>Math.pow(r(),1/n):()=>1;return function(){do{do{var n=t(),i=1+e*n}while(i<=0);i*=i*i;var c=1-r()}while(c>=1-.0331*n*n*n*n&&Math.log(c)>=.5*n*n+u*(1-i+Math.log(i)));return u*i*a()*o}}return o.source=n,o}(r),d=function n(r){var t=s.source(r);function o(n,r){var o=t(n),u=t(r);return function(){var n=o();return 0===n?0:n/(n+u())}}return o.source=n,o}(r),M=function n(r){var t=h.source(r),o=d.source(r);function u(n,r){return n=+n,(r=+r)>=1?()=>n:r<=0?()=>0:function(){for(var u=0,e=n,a=r;e*a>16&&e*(1-a)>16;){var i=Math.floor((e+1)*a),c=o(i,e-i+1)();c<=a?(u+=i,e-=i,a=(a-c)/(1-c)):(e=i-1,a/=c)}for(var f=a<.5,l=t(f?a:1-a),h=l(),s=0;h<=e;++s)h+=l();return u+(f?s:e-s)}}return u.source=n,u}(r),v=function n(r){function t(n,t,o){var u;return 0==(n=+n)?u=n=>-Math.log(n):(n=1/n,u=r=>Math.pow(r,n)),t=null==t?0:+t,o=null==o?1:+o,function(){return t+o*u(-Math.log1p(-r()))}}return t.source=n,t}(r),m=function n(r){function t(n,t){return n=null==n?0:+n,t=null==t?1:+t,function(){return n+t*Math.tan(Math.PI*r())}}return t.source=n,t}(r),p=function n(r){function t(n,t){return n=null==n?0:+n,t=null==t?1:+t,function(){var o=r();return n+t*Math.log(o/(1-o))}}return t.source=n,t}(r),g=function n(r){var t=s.source(r),o=M.source(r);function u(n){return function(){for(var u=0,e=n;e>16;){var a=Math.floor(.875*e),i=t(a)();if(i>e)return u+o(a-1,e/i)();u+=a,e-=i}for(var c=-Math.log1p(-r()),f=0;c<=e;++f)c-=Math.log1p(-r());return u+f}}return u.source=n,u}(r);const w=1/4294967296;n.randomBates=i,n.randomBernoulli=l,n.randomBeta=d,n.randomBinomial=M,n.randomCauchy=m,n.randomExponential=c,n.randomGamma=s,n.randomGeometric=h,n.randomInt=o,n.randomIrwinHall=a,n.randomLcg=function(n=Math.random()){let r=0|(0<=n&&n<1?n/w:Math.abs(n));return()=>(r=1664525*r+1013904223|0,w*(r>>>0))},n.randomLogNormal=e,n.randomLogistic=p,n.randomNormal=u,n.randomPareto=f,n.randomPoisson=g,n.randomUniform=t,n.randomWeibull=v,Object.defineProperty(n,"__esModule",{value:!0})}));
diff --git a/node_modules/d3-random/package.json b/node_modules/d3-random/package.json
new file mode 100644
index 00000000..ebbcd2dd
--- /dev/null
+++ b/node_modules/d3-random/package.json
@@ -0,0 +1,79 @@
+{
+ "_from": "d3-random@3",
+ "_id": "d3-random@3.0.1",
+ "_inBundle": false,
+ "_integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==",
+ "_location": "/d3-random",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "range",
+ "registry": true,
+ "raw": "d3-random@3",
+ "name": "d3-random",
+ "escapedName": "d3-random",
+ "rawSpec": "3",
+ "saveSpec": null,
+ "fetchSpec": "3"
+ },
+ "_requiredBy": [
+ "/d3"
+ ],
+ "_resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz",
+ "_shasum": "d4926378d333d9c0bfd1e6fa0194d30aebaa20f4",
+ "_spec": "d3-random@3",
+ "_where": "C:\\Users\\colbs\\CS4241\\d3a4\\node_modules\\d3",
+ "author": {
+ "name": "Mike Bostock",
+ "url": "http://bost.ocks.org/mike"
+ },
+ "bugs": {
+ "url": "https://github.com/d3/d3-random/issues"
+ },
+ "bundleDependencies": false,
+ "deprecated": false,
+ "description": "Generate random numbers from various distributions.",
+ "devDependencies": {
+ "d3-array": "1 - 2",
+ "eslint": "7",
+ "jsdom": "16",
+ "mocha": "8",
+ "rollup": "2",
+ "rollup-plugin-terser": "7"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "exports": {
+ "umd": "./dist/d3-random.min.js",
+ "default": "./src/index.js"
+ },
+ "files": [
+ "dist/**/*.js",
+ "src/**/*.js"
+ ],
+ "homepage": "https://d3js.org/d3-random/",
+ "jsdelivr": "dist/d3-random.min.js",
+ "keywords": [
+ "d3",
+ "d3-module",
+ "random",
+ "rng"
+ ],
+ "license": "ISC",
+ "main": "src/index.js",
+ "module": "src/index.js",
+ "name": "d3-random",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/d3/d3-random.git"
+ },
+ "scripts": {
+ "postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -",
+ "prepublishOnly": "rm -rf dist && yarn test && rollup -c",
+ "test": "mocha 'test/**/*-test.js' && eslint src test"
+ },
+ "sideEffects": false,
+ "type": "module",
+ "unpkg": "dist/d3-random.min.js",
+ "version": "3.0.1"
+}
diff --git a/node_modules/d3-random/src/bates.js b/node_modules/d3-random/src/bates.js
new file mode 100644
index 00000000..6bafddd0
--- /dev/null
+++ b/node_modules/d3-random/src/bates.js
@@ -0,0 +1,19 @@
+import defaultSource from "./defaultSource.js";
+import irwinHall from "./irwinHall.js";
+
+export default (function sourceRandomBates(source) {
+ var I = irwinHall.source(source);
+
+ function randomBates(n) {
+ // use limiting distribution at n === 0
+ if ((n = +n) === 0) return source;
+ var randomIrwinHall = I(n);
+ return function() {
+ return randomIrwinHall() / n;
+ };
+ }
+
+ randomBates.source = sourceRandomBates;
+
+ return randomBates;
+})(defaultSource);
diff --git a/node_modules/d3-random/src/bernoulli.js b/node_modules/d3-random/src/bernoulli.js
new file mode 100644
index 00000000..8751b433
--- /dev/null
+++ b/node_modules/d3-random/src/bernoulli.js
@@ -0,0 +1,14 @@
+import defaultSource from "./defaultSource.js";
+
+export default (function sourceRandomBernoulli(source) {
+ function randomBernoulli(p) {
+ if ((p = +p) < 0 || p > 1) throw new RangeError("invalid p");
+ return function() {
+ return Math.floor(source() + p);
+ };
+ }
+
+ randomBernoulli.source = sourceRandomBernoulli;
+
+ return randomBernoulli;
+})(defaultSource);
diff --git a/node_modules/d3-random/src/beta.js b/node_modules/d3-random/src/beta.js
new file mode 100644
index 00000000..15bb2b35
--- /dev/null
+++ b/node_modules/d3-random/src/beta.js
@@ -0,0 +1,19 @@
+import defaultSource from "./defaultSource.js";
+import gamma from "./gamma.js";
+
+export default (function sourceRandomBeta(source) {
+ var G = gamma.source(source);
+
+ function randomBeta(alpha, beta) {
+ var X = G(alpha),
+ Y = G(beta);
+ return function() {
+ var x = X();
+ return x === 0 ? 0 : x / (x + Y());
+ };
+ }
+
+ randomBeta.source = sourceRandomBeta;
+
+ return randomBeta;
+})(defaultSource);
diff --git a/node_modules/d3-random/src/binomial.js b/node_modules/d3-random/src/binomial.js
new file mode 100644
index 00000000..3213b4a7
--- /dev/null
+++ b/node_modules/d3-random/src/binomial.js
@@ -0,0 +1,38 @@
+import defaultSource from "./defaultSource.js";
+import beta from "./beta.js";
+import geometric from "./geometric.js";
+
+export default (function sourceRandomBinomial(source) {
+ var G = geometric.source(source),
+ B = beta.source(source);
+
+ function randomBinomial(n, p) {
+ n = +n;
+ if ((p = +p) >= 1) return () => n;
+ if (p <= 0) return () => 0;
+ return function() {
+ var acc = 0, nn = n, pp = p;
+ while (nn * pp > 16 && nn * (1 - pp) > 16) {
+ var i = Math.floor((nn + 1) * pp),
+ y = B(i, nn - i + 1)();
+ if (y <= pp) {
+ acc += i;
+ nn -= i;
+ pp = (pp - y) / (1 - y);
+ } else {
+ nn = i - 1;
+ pp /= y;
+ }
+ }
+ var sign = pp < 0.5,
+ pFinal = sign ? pp : 1 - pp,
+ g = G(pFinal);
+ for (var s = g(), k = 0; s <= nn; ++k) s += g();
+ return acc + (sign ? k : nn - k);
+ };
+ }
+
+ randomBinomial.source = sourceRandomBinomial;
+
+ return randomBinomial;
+})(defaultSource);
diff --git a/node_modules/d3-random/src/cauchy.js b/node_modules/d3-random/src/cauchy.js
new file mode 100644
index 00000000..95c15ca1
--- /dev/null
+++ b/node_modules/d3-random/src/cauchy.js
@@ -0,0 +1,15 @@
+import defaultSource from "./defaultSource.js";
+
+export default (function sourceRandomCauchy(source) {
+ function randomCauchy(a, b) {
+ a = a == null ? 0 : +a;
+ b = b == null ? 1 : +b;
+ return function() {
+ return a + b * Math.tan(Math.PI * source());
+ };
+ }
+
+ randomCauchy.source = sourceRandomCauchy;
+
+ return randomCauchy;
+})(defaultSource);
diff --git a/node_modules/d3-random/src/defaultSource.js b/node_modules/d3-random/src/defaultSource.js
new file mode 100644
index 00000000..ef54f3df
--- /dev/null
+++ b/node_modules/d3-random/src/defaultSource.js
@@ -0,0 +1 @@
+export default Math.random;
diff --git a/node_modules/d3-random/src/exponential.js b/node_modules/d3-random/src/exponential.js
new file mode 100644
index 00000000..0d4304cc
--- /dev/null
+++ b/node_modules/d3-random/src/exponential.js
@@ -0,0 +1,13 @@
+import defaultSource from "./defaultSource.js";
+
+export default (function sourceRandomExponential(source) {
+ function randomExponential(lambda) {
+ return function() {
+ return -Math.log1p(-source()) / lambda;
+ };
+ }
+
+ randomExponential.source = sourceRandomExponential;
+
+ return randomExponential;
+})(defaultSource);
diff --git a/node_modules/d3-random/src/gamma.js b/node_modules/d3-random/src/gamma.js
new file mode 100644
index 00000000..48bf7062
--- /dev/null
+++ b/node_modules/d3-random/src/gamma.js
@@ -0,0 +1,34 @@
+import defaultSource from "./defaultSource.js";
+import normal from "./normal.js";
+
+export default (function sourceRandomGamma(source) {
+ var randomNormal = normal.source(source)();
+
+ function randomGamma(k, theta) {
+ if ((k = +k) < 0) throw new RangeError("invalid k");
+ // degenerate distribution if k === 0
+ if (k === 0) return () => 0;
+ theta = theta == null ? 1 : +theta;
+ // exponential distribution if k === 1
+ if (k === 1) return () => -Math.log1p(-source()) * theta;
+
+ var d = (k < 1 ? k + 1 : k) - 1 / 3,
+ c = 1 / (3 * Math.sqrt(d)),
+ multiplier = k < 1 ? () => Math.pow(source(), 1 / k) : () => 1;
+ return function() {
+ do {
+ do {
+ var x = randomNormal(),
+ v = 1 + c * x;
+ } while (v <= 0);
+ v *= v * v;
+ var u = 1 - source();
+ } while (u >= 1 - 0.0331 * x * x * x * x && Math.log(u) >= 0.5 * x * x + d * (1 - v + Math.log(v)));
+ return d * v * multiplier() * theta;
+ };
+ }
+
+ randomGamma.source = sourceRandomGamma;
+
+ return randomGamma;
+})(defaultSource);
diff --git a/node_modules/d3-random/src/geometric.js b/node_modules/d3-random/src/geometric.js
new file mode 100644
index 00000000..2cae2cc8
--- /dev/null
+++ b/node_modules/d3-random/src/geometric.js
@@ -0,0 +1,17 @@
+import defaultSource from "./defaultSource.js";
+
+export default (function sourceRandomGeometric(source) {
+ function randomGeometric(p) {
+ if ((p = +p) < 0 || p > 1) throw new RangeError("invalid p");
+ if (p === 0) return () => Infinity;
+ if (p === 1) return () => 1;
+ p = Math.log1p(-p);
+ return function() {
+ return 1 + Math.floor(Math.log1p(-source()) / p);
+ };
+ }
+
+ randomGeometric.source = sourceRandomGeometric;
+
+ return randomGeometric;
+})(defaultSource);
diff --git a/node_modules/d3-random/src/index.js b/node_modules/d3-random/src/index.js
new file mode 100644
index 00000000..033891e9
--- /dev/null
+++ b/node_modules/d3-random/src/index.js
@@ -0,0 +1,18 @@
+export {default as randomUniform} from "./uniform.js";
+export {default as randomInt} from "./int.js";
+export {default as randomNormal} from "./normal.js";
+export {default as randomLogNormal} from "./logNormal.js";
+export {default as randomBates} from "./bates.js";
+export {default as randomIrwinHall} from "./irwinHall.js";
+export {default as randomExponential} from "./exponential.js";
+export {default as randomPareto} from "./pareto.js";
+export {default as randomBernoulli} from "./bernoulli.js";
+export {default as randomGeometric} from "./geometric.js";
+export {default as randomBinomial} from "./binomial.js";
+export {default as randomGamma} from "./gamma.js";
+export {default as randomBeta} from "./beta.js";
+export {default as randomWeibull} from "./weibull.js";
+export {default as randomCauchy} from "./cauchy.js";
+export {default as randomLogistic} from "./logistic.js";
+export {default as randomPoisson} from "./poisson.js";
+export {default as randomLcg} from "./lcg.js";
diff --git a/node_modules/d3-random/src/int.js b/node_modules/d3-random/src/int.js
new file mode 100644
index 00000000..a47249b7
--- /dev/null
+++ b/node_modules/d3-random/src/int.js
@@ -0,0 +1,16 @@
+import defaultSource from "./defaultSource.js";
+
+export default (function sourceRandomInt(source) {
+ function randomInt(min, max) {
+ if (arguments.length < 2) max = min, min = 0;
+ min = Math.floor(min);
+ max = Math.floor(max) - min;
+ return function() {
+ return Math.floor(source() * max + min);
+ };
+ }
+
+ randomInt.source = sourceRandomInt;
+
+ return randomInt;
+})(defaultSource);
diff --git a/node_modules/d3-random/src/irwinHall.js b/node_modules/d3-random/src/irwinHall.js
new file mode 100644
index 00000000..4db5dccb
--- /dev/null
+++ b/node_modules/d3-random/src/irwinHall.js
@@ -0,0 +1,15 @@
+import defaultSource from "./defaultSource.js";
+
+export default (function sourceRandomIrwinHall(source) {
+ function randomIrwinHall(n) {
+ if ((n = +n) <= 0) return () => 0;
+ return function() {
+ for (var sum = 0, i = n; i > 1; --i) sum += source();
+ return sum + i * source();
+ };
+ }
+
+ randomIrwinHall.source = sourceRandomIrwinHall;
+
+ return randomIrwinHall;
+})(defaultSource);
diff --git a/node_modules/d3-random/src/lcg.js b/node_modules/d3-random/src/lcg.js
new file mode 100644
index 00000000..fb058788
--- /dev/null
+++ b/node_modules/d3-random/src/lcg.js
@@ -0,0 +1,9 @@
+// https://en.wikipedia.org/wiki/Linear_congruential_generator#Parameters_in_common_use
+const mul = 0x19660D;
+const inc = 0x3C6EF35F;
+const eps = 1 / 0x100000000;
+
+export default function lcg(seed = Math.random()) {
+ let state = (0 <= seed && seed < 1 ? seed / eps : Math.abs(seed)) | 0;
+ return () => (state = mul * state + inc | 0, eps * (state >>> 0));
+}
diff --git a/node_modules/d3-random/src/logNormal.js b/node_modules/d3-random/src/logNormal.js
new file mode 100644
index 00000000..3465fba3
--- /dev/null
+++ b/node_modules/d3-random/src/logNormal.js
@@ -0,0 +1,17 @@
+import defaultSource from "./defaultSource.js";
+import normal from "./normal.js";
+
+export default (function sourceRandomLogNormal(source) {
+ var N = normal.source(source);
+
+ function randomLogNormal() {
+ var randomNormal = N.apply(this, arguments);
+ return function() {
+ return Math.exp(randomNormal());
+ };
+ }
+
+ randomLogNormal.source = sourceRandomLogNormal;
+
+ return randomLogNormal;
+})(defaultSource);
diff --git a/node_modules/d3-random/src/logistic.js b/node_modules/d3-random/src/logistic.js
new file mode 100644
index 00000000..b2cda2a3
--- /dev/null
+++ b/node_modules/d3-random/src/logistic.js
@@ -0,0 +1,16 @@
+import defaultSource from "./defaultSource.js";
+
+export default (function sourceRandomLogistic(source) {
+ function randomLogistic(a, b) {
+ a = a == null ? 0 : +a;
+ b = b == null ? 1 : +b;
+ return function() {
+ var u = source();
+ return a + b * Math.log(u / (1 - u));
+ };
+ }
+
+ randomLogistic.source = sourceRandomLogistic;
+
+ return randomLogistic;
+})(defaultSource);
diff --git a/node_modules/d3-random/src/normal.js b/node_modules/d3-random/src/normal.js
new file mode 100644
index 00000000..b6838d67
--- /dev/null
+++ b/node_modules/d3-random/src/normal.js
@@ -0,0 +1,28 @@
+import defaultSource from "./defaultSource.js";
+
+export default (function sourceRandomNormal(source) {
+ function randomNormal(mu, sigma) {
+ var x, r;
+ mu = mu == null ? 0 : +mu;
+ sigma = sigma == null ? 1 : +sigma;
+ return function() {
+ var y;
+
+ // If available, use the second previously-generated uniform random.
+ if (x != null) y = x, x = null;
+
+ // Otherwise, generate a new x and y.
+ else do {
+ x = source() * 2 - 1;
+ y = source() * 2 - 1;
+ r = x * x + y * y;
+ } while (!r || r > 1);
+
+ return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r);
+ };
+ }
+
+ randomNormal.source = sourceRandomNormal;
+
+ return randomNormal;
+})(defaultSource);
diff --git a/node_modules/d3-random/src/pareto.js b/node_modules/d3-random/src/pareto.js
new file mode 100644
index 00000000..e5496f0c
--- /dev/null
+++ b/node_modules/d3-random/src/pareto.js
@@ -0,0 +1,15 @@
+import defaultSource from "./defaultSource.js";
+
+export default (function sourceRandomPareto(source) {
+ function randomPareto(alpha) {
+ if ((alpha = +alpha) < 0) throw new RangeError("invalid alpha");
+ alpha = 1 / -alpha;
+ return function() {
+ return Math.pow(1 - source(), alpha);
+ };
+ }
+
+ randomPareto.source = sourceRandomPareto;
+
+ return randomPareto;
+})(defaultSource);
diff --git a/node_modules/d3-random/src/poisson.js b/node_modules/d3-random/src/poisson.js
new file mode 100644
index 00000000..da939955
--- /dev/null
+++ b/node_modules/d3-random/src/poisson.js
@@ -0,0 +1,27 @@
+import defaultSource from "./defaultSource.js";
+import binomial from "./binomial.js";
+import gamma from "./gamma.js";
+
+export default (function sourceRandomPoisson(source) {
+ var G = gamma.source(source),
+ B = binomial.source(source);
+
+ function randomPoisson(lambda) {
+ return function() {
+ var acc = 0, l = lambda;
+ while (l > 16) {
+ var n = Math.floor(0.875 * l),
+ t = G(n)();
+ if (t > l) return acc + B(n - 1, l / t)();
+ acc += n;
+ l -= t;
+ }
+ for (var s = -Math.log1p(-source()), k = 0; s <= l; ++k) s -= Math.log1p(-source());
+ return acc + k;
+ };
+ }
+
+ randomPoisson.source = sourceRandomPoisson;
+
+ return randomPoisson;
+})(defaultSource);
diff --git a/node_modules/d3-random/src/uniform.js b/node_modules/d3-random/src/uniform.js
new file mode 100644
index 00000000..a2bc468a
--- /dev/null
+++ b/node_modules/d3-random/src/uniform.js
@@ -0,0 +1,17 @@
+import defaultSource from "./defaultSource.js";
+
+export default (function sourceRandomUniform(source) {
+ function randomUniform(min, max) {
+ min = min == null ? 0 : +min;
+ max = max == null ? 1 : +max;
+ if (arguments.length === 1) max = min, min = 0;
+ else max -= min;
+ return function() {
+ return source() * max + min;
+ };
+ }
+
+ randomUniform.source = sourceRandomUniform;
+
+ return randomUniform;
+})(defaultSource);
diff --git a/node_modules/d3-random/src/weibull.js b/node_modules/d3-random/src/weibull.js
new file mode 100644
index 00000000..b7d796cc
--- /dev/null
+++ b/node_modules/d3-random/src/weibull.js
@@ -0,0 +1,22 @@
+import defaultSource from "./defaultSource.js";
+
+export default (function sourceRandomWeibull(source) {
+ function randomWeibull(k, a, b) {
+ var outerFunc;
+ if ((k = +k) === 0) {
+ outerFunc = x => -Math.log(x);
+ } else {
+ k = 1 / k;
+ outerFunc = x => Math.pow(x, k);
+ }
+ a = a == null ? 0 : +a;
+ b = b == null ? 1 : +b;
+ return function() {
+ return a + b * outerFunc(-Math.log1p(-source()));
+ };
+ }
+
+ randomWeibull.source = sourceRandomWeibull;
+
+ return randomWeibull;
+})(defaultSource);
diff --git a/node_modules/d3-scale-chromatic/LICENSE b/node_modules/d3-scale-chromatic/LICENSE
new file mode 100644
index 00000000..65f32f10
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/LICENSE
@@ -0,0 +1,28 @@
+Copyright 2010-2021 Mike Bostock
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+Apache-Style Software License for ColorBrewer software and ColorBrewer Color Schemes
+
+Copyright 2002 Cynthia Brewer, Mark Harrower, and The Pennsylvania State University
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+this file except in compliance with the License. You may obtain a copy of the
+License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed
+under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+CONDITIONS OF ANY KIND, either express or implied. See the License for the
+specific language governing permissions and limitations under the License.
diff --git a/node_modules/d3-scale-chromatic/README.md b/node_modules/d3-scale-chromatic/README.md
new file mode 100644
index 00000000..96b574b7
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/README.md
@@ -0,0 +1,387 @@
+# d3-scale-chromatic
+
+This module provides sequential, diverging and categorical color schemes designed to work with [d3-scale](https://github.com/d3/d3-scale)’s [d3.scaleOrdinal](https://github.com/d3/d3-scale#ordinal-scales) and [d3.scaleSequential](https://github.com/d3/d3-scale#sequential-scales). Most of these schemes are derived from Cynthia A. Brewer’s [ColorBrewer](http://colorbrewer2.org). Since ColorBrewer publishes only discrete color schemes, the sequential and diverging scales are interpolated using [uniform B-splines](https://bl.ocks.org/mbostock/048d21cf747371b11884f75ad896e5a5).
+
+For example, to create a categorical color scale using the [Accent](#schemeAccent) color scheme:
+
+```js
+var accent = d3.scaleOrdinal(d3.schemeAccent);
+```
+
+To create a sequential discrete nine-color scale using the [Blues](#schemeBlues) color scheme:
+
+```js
+var blues = d3.scaleOrdinal(d3.schemeBlues[9]);
+```
+
+To create a diverging, continuous color scale using the [PiYG](#interpolatePiYG) color scheme:
+
+```js
+var piyg = d3.scaleSequential(d3.interpolatePiYG);
+```
+
+## Installing
+
+If you use npm, `npm install d3-scale-chromatic`. You can also download the [latest release on GitHub](https://github.com/d3/d3-scale-chromatic/releases/latest). For vanilla HTML in modern browsers, import d3-scale-chromatic from Skypack:
+
+```html
+
+```
+
+For legacy environments, you can load d3-scale-chromatic’s UMD bundle from an npm-based CDN such as jsDelivr; a `d3` global is exported:
+
+```html
+
+
+
+
+```
+
+[Try d3-scale-chromatic in your browser.](https://observablehq.com/collection/@d3/d3-scale-chromatic)
+
+## API Reference
+
+### Categorical
+
+# d3.schemeCategory10 [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/categorical/category10.js "Source")
+
+
+
+An array of ten categorical colors represented as RGB hexadecimal strings.
+
+# d3.schemeAccent [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/categorical/Accent.js "Source")
+
+
+
+An array of eight categorical colors represented as RGB hexadecimal strings.
+
+# d3.schemeDark2 [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/categorical/Dark2.js "Source")
+
+
+
+An array of eight categorical colors represented as RGB hexadecimal strings.
+
+# d3.schemePaired [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/categorical/Paired.js "Source")
+
+
+
+An array of twelve categorical colors represented as RGB hexadecimal strings.
+
+# d3.schemePastel1 [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/categorical/Pastel1.js "Source")
+
+
+
+An array of nine categorical colors represented as RGB hexadecimal strings.
+
+# d3.schemePastel2 [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/categorical/Pastel2.js "Source")
+
+
+
+An array of eight categorical colors represented as RGB hexadecimal strings.
+
+# d3.schemeSet1 [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/categorical/Set1.js "Source")
+
+
+
+An array of nine categorical colors represented as RGB hexadecimal strings.
+
+# d3.schemeSet2 [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/categorical/Set2.js "Source")
+
+
+
+An array of eight categorical colors represented as RGB hexadecimal strings.
+
+# d3.schemeSet3 [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/categorical/Set3.js "Source")
+
+
+
+An array of twelve categorical colors represented as RGB hexadecimal strings.
+
+# d3.schemeTableau10 [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/categorical/Tableau10.js "Source")
+
+
+
+An array of ten categorical colors authored by Tableau as part of [Tableau 10](https://www.tableau.com/about/blog/2016/7/colors-upgrade-tableau-10-56782) represented as RGB hexadecimal strings.
+
+### Diverging
+
+Diverging color schemes are available as continuous interpolators (often used with [d3.scaleSequential](https://github.com/d3/d3-scale/blob/master/README.md#sequential-scales)) and as discrete schemes (often used with [d3.scaleOrdinal](https://github.com/d3/d3-scale/blob/master/README.md#ordinal-scales)). Each discrete scheme, such as [d3.schemeBrBG](#schemeBrBG), is represented as an array of arrays of hexadecimal color strings. The *k*th element of this array contains the color scheme of size *k*; for example, `d3.schemeBrBG[9]` contains an array of nine strings representing the nine colors of the brown-blue-green diverging color scheme. Diverging color schemes support a size *k* ranging from 3 to 11.
+
+# d3.interpolateBrBG(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/diverging/BrBG.js "Source")
+
# d3.schemeBrBG[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “BrBG” diverging color scheme represented as an RGB string.
+
+# d3.interpolatePRGn(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/diverging/PRGn.js "Source")
+
# d3.schemePRGn[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “PRGn” diverging color scheme represented as an RGB string.
+
+# d3.interpolatePiYG(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/diverging/PiYG.js "Source")
+
# d3.schemePiYG[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “PiYG” diverging color scheme represented as an RGB string.
+
+# d3.interpolatePuOr(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/diverging/PuOr.js "Source")
+
# d3.schemePuOr[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “PuOr” diverging color scheme represented as an RGB string.
+
+# d3.interpolateRdBu(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/diverging/RdBu.js "Source")
+
# d3.schemeRdBu[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “RdBu” diverging color scheme represented as an RGB string.
+
+# d3.interpolateRdGy(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/diverging/RdGy.js "Source")
+
# d3.schemeRdGy[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “RdGy” diverging color scheme represented as an RGB string.
+
+# d3.interpolateRdYlBu(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/diverging/RdYlBu.js "Source")
+
# d3.schemeRdYlBu[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “RdYlBu” diverging color scheme represented as an RGB string.
+
+# d3.interpolateRdYlGn(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/diverging/RdYlGn.js "Source")
+
# d3.schemeRdYlGn[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “RdYlGn” diverging color scheme represented as an RGB string.
+
+# d3.interpolateSpectral(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/diverging/Spectral.js "Source")
+
# d3.schemeSpectral[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “Spectral” diverging color scheme represented as an RGB string.
+
+### Sequential (Single Hue)
+
+Sequential, single-hue color schemes are available as continuous interpolators (often used with [d3.scaleSequential](https://github.com/d3/d3-scale/blob/master/README.md#sequential-scales)) and as discrete schemes (often used with [d3.scaleOrdinal](https://github.com/d3/d3-scale/blob/master/README.md#ordinal-scales)). Each discrete scheme, such as [d3.schemeBlues](#schemeBlues), is represented as an array of arrays of hexadecimal color strings. The *k*th element of this array contains the color scheme of size *k*; for example, `d3.schemeBlues[9]` contains an array of nine strings representing the nine colors of the blue sequential color scheme. Sequential, single-hue color schemes support a size *k* ranging from 3 to 9.
+
+# d3.interpolateBlues(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-single/Blues.js "Source")
+
# d3.schemeBlues[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “Blues” sequential color scheme represented as an RGB string.
+
+# d3.interpolateGreens(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-single/Greens.js "Source")
+
# d3.schemeGreens[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “Greens” sequential color scheme represented as an RGB string.
+
+# d3.interpolateGreys(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-single/Greys.js "Source")
+
# d3.schemeGreys[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “Greys” sequential color scheme represented as an RGB string.
+
+# d3.interpolateOranges(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-single/Oranges.js "Source")
+
# d3.schemeOranges[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “Oranges” sequential color scheme represented as an RGB string.
+
+# d3.interpolatePurples(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-single/Purples.js "Source")
+
# d3.schemePurples[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “Purples” sequential color scheme represented as an RGB string.
+
+# d3.interpolateReds(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-single/Reds.js "Source")
+
# d3.schemeReds[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “Reds” sequential color scheme represented as an RGB string.
+
+### Sequential (Multi-Hue)
+
+Sequential, multi-hue color schemes are available as continuous interpolators (often used with [d3.scaleSequential](https://github.com/d3/d3-scale/blob/master/README.md#sequential-scales)) and as discrete schemes (often used with [d3.scaleOrdinal](https://github.com/d3/d3-scale/blob/master/README.md#ordinal-scales)). Each discrete scheme, such as [d3.schemeBuGn](#schemeBuGn), is represented as an array of arrays of hexadecimal color strings. The *k*th element of this array contains the color scheme of size *k*; for example, `d3.schemeBuGn[9]` contains an array of nine strings representing the nine colors of the blue-green sequential color scheme. Sequential, multi-hue color schemes support a size *k* ranging from 3 to 9.
+
+# d3.interpolateTurbo(t) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/turbo.js "Source")
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “turbo” color scheme by [Anton Mikhailov](https://ai.googleblog.com/2019/08/turbo-improved-rainbow-colormap-for.html).
+
+# d3.interpolateViridis(t) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/viridis.js "Source")
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “viridis” perceptually-uniform color scheme designed by [van der Walt, Smith and Firing](https://bids.github.io/colormap/) for matplotlib, represented as an RGB string.
+
+# d3.interpolateInferno(t) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/viridis.js "Source")
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “inferno” perceptually-uniform color scheme designed by [van der Walt and Smith](https://bids.github.io/colormap/) for matplotlib, represented as an RGB string.
+
+# d3.interpolateMagma(t) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/viridis.js "Source")
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “magma” perceptually-uniform color scheme designed by [van der Walt and Smith](https://bids.github.io/colormap/) for matplotlib, represented as an RGB string.
+
+# d3.interpolatePlasma(t) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/viridis.js "Source")
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “plasma” perceptually-uniform color scheme designed by [van der Walt and Smith](https://bids.github.io/colormap/) for matplotlib, represented as an RGB string.
+
+# d3.interpolateCividis(t) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/cividis.js "Source")
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “cividis” color vision deficiency-optimized color scheme designed by [Nuñez, Anderton, and Renslow](https://journals.plos.org/plosone/article?id=10.1371/journal.pone.0199239), represented as an RGB string.
+
+# d3.interpolateWarm(t) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/rainbow.js "Source")
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from a 180° rotation of [Niccoli’s perceptual rainbow](https://mycarta.wordpress.com/2013/02/21/perceptual-rainbow-palette-the-method/), represented as an RGB string.
+
+# d3.interpolateCool(t) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/rainbow.js "Source")
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from [Niccoli’s perceptual rainbow](https://mycarta.wordpress.com/2013/02/21/perceptual-rainbow-palette-the-method/), represented as an RGB string.
+
+# d3.interpolateCubehelixDefault(t) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/cubehelix.js "Source")
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from [Green’s default Cubehelix](http://www.mrao.cam.ac.uk/~dag/CUBEHELIX/) represented as an RGB string.
+
+# d3.interpolateBuGn(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/BuGn.js "Source")
+
# d3.schemeBuGn[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “BuGn” sequential color scheme represented as an RGB string.
+
+# d3.interpolateBuPu(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/BuPu.js "Source")
+
# d3.schemeBuPu[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “BuPu” sequential color scheme represented as an RGB string.
+
+# d3.interpolateGnBu(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/GnBu.js "Source")
+
# d3.schemeGnBu[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “GnBu” sequential color scheme represented as an RGB string.
+
+# d3.interpolateOrRd(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/OrRd.js "Source")
+
# d3.schemeOrRd[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “OrRd” sequential color scheme represented as an RGB string.
+
+# d3.interpolatePuBuGn(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/PuBuGn.js "Source")
+
# d3.schemePuBuGn[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “PuBuGn” sequential color scheme represented as an RGB string.
+
+# d3.interpolatePuBu(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/PuBu.js "Source")
+
# d3.schemePuBu[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “PuBu” sequential color scheme represented as an RGB string.
+
+# d3.interpolatePuRd(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/PuRd.js "Source")
+
# d3.schemePuRd[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “PuRd” sequential color scheme represented as an RGB string.
+
+# d3.interpolateRdPu(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/RdPu.js "Source")
+
# d3.schemeRdPu[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “RdPu” sequential color scheme represented as an RGB string.
+
+# d3.interpolateYlGnBu(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/YlGnBu.js "Source")
+
# d3.schemeYlGnBu[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “YlGnBu” sequential color scheme represented as an RGB string.
+
+# d3.interpolateYlGn(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/YlGn.js "Source")
+
# d3.schemeYlGn[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “YlGn” sequential color scheme represented as an RGB string.
+
+# d3.interpolateYlOrBr(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/YlOrBr.js "Source")
+
# d3.schemeYlOrBr[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “YlOrBr” sequential color scheme represented as an RGB string.
+
+# d3.interpolateYlOrRd(*t*) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/YlOrRd.js "Source")
+
# d3.schemeYlOrRd[*k*]
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “YlOrRd” sequential color scheme represented as an RGB string.
+
+### Cyclical
+
+# d3.interpolateRainbow(t) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/rainbow.js "Source")
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from [d3.interpolateWarm](#interpolateWarm) scale from [0.0, 0.5] followed by the [d3.interpolateCool](#interpolateCool) scale from [0.5, 1.0], thus implementing the cyclical [less-angry rainbow](http://bl.ocks.org/mbostock/310c99e53880faec2434) color scheme.
+
+# d3.interpolateSinebow(t) [<>](https://github.com/d3/d3-scale-chromatic/blob/master/src/sequential-multi/sinebow.js "Source")
+
+
+
+Given a number *t* in the range [0,1], returns the corresponding color from the “sinebow” color scheme by [Jim Bumgardner](https://krazydad.com/tutorials/makecolors.php) and [Charlie Loyd](http://basecase.org/env/on-rainbows).
diff --git a/node_modules/d3-scale-chromatic/dist/d3-scale-chromatic.js b/node_modules/d3-scale-chromatic/dist/d3-scale-chromatic.js
new file mode 100644
index 00000000..f5942bd8
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/dist/d3-scale-chromatic.js
@@ -0,0 +1,519 @@
+// https://d3js.org/d3-scale-chromatic/ v3.0.0 Copyright 2010-2021 Mike Bostock; 2002 Cynthia Brewer, Mark Harrower, and The Pennsylvania State University
+(function (global, factory) {
+typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-interpolate'), require('d3-color')) :
+typeof define === 'function' && define.amd ? define(['exports', 'd3-interpolate', 'd3-color'], factory) :
+(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}, global.d3, global.d3));
+}(this, (function (exports, d3Interpolate, d3Color) { 'use strict';
+
+function colors(specifier) {
+ var n = specifier.length / 6 | 0, colors = new Array(n), i = 0;
+ while (i < n) colors[i] = "#" + specifier.slice(i * 6, ++i * 6);
+ return colors;
+}
+
+var category10 = colors("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf");
+
+var Accent = colors("7fc97fbeaed4fdc086ffff99386cb0f0027fbf5b17666666");
+
+var Dark2 = colors("1b9e77d95f027570b3e7298a66a61ee6ab02a6761d666666");
+
+var Paired = colors("a6cee31f78b4b2df8a33a02cfb9a99e31a1cfdbf6fff7f00cab2d66a3d9affff99b15928");
+
+var Pastel1 = colors("fbb4aeb3cde3ccebc5decbe4fed9a6ffffcce5d8bdfddaecf2f2f2");
+
+var Pastel2 = colors("b3e2cdfdcdaccbd5e8f4cae4e6f5c9fff2aef1e2cccccccc");
+
+var Set1 = colors("e41a1c377eb84daf4a984ea3ff7f00ffff33a65628f781bf999999");
+
+var Set2 = colors("66c2a5fc8d628da0cbe78ac3a6d854ffd92fe5c494b3b3b3");
+
+var Set3 = colors("8dd3c7ffffb3bebadafb807280b1d3fdb462b3de69fccde5d9d9d9bc80bdccebc5ffed6f");
+
+var Tableau10 = colors("4e79a7f28e2ce1575976b7b259a14fedc949af7aa1ff9da79c755fbab0ab");
+
+var ramp$1 = scheme => d3Interpolate.interpolateRgbBasis(scheme[scheme.length - 1]);
+
+var scheme$q = new Array(3).concat(
+ "d8b365f5f5f55ab4ac",
+ "a6611adfc27d80cdc1018571",
+ "a6611adfc27df5f5f580cdc1018571",
+ "8c510ad8b365f6e8c3c7eae55ab4ac01665e",
+ "8c510ad8b365f6e8c3f5f5f5c7eae55ab4ac01665e",
+ "8c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e",
+ "8c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e",
+ "5430058c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e003c30",
+ "5430058c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e003c30"
+).map(colors);
+
+var BrBG = ramp$1(scheme$q);
+
+var scheme$p = new Array(3).concat(
+ "af8dc3f7f7f77fbf7b",
+ "7b3294c2a5cfa6dba0008837",
+ "7b3294c2a5cff7f7f7a6dba0008837",
+ "762a83af8dc3e7d4e8d9f0d37fbf7b1b7837",
+ "762a83af8dc3e7d4e8f7f7f7d9f0d37fbf7b1b7837",
+ "762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b7837",
+ "762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b7837",
+ "40004b762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b783700441b",
+ "40004b762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b783700441b"
+).map(colors);
+
+var PRGn = ramp$1(scheme$p);
+
+var scheme$o = new Array(3).concat(
+ "e9a3c9f7f7f7a1d76a",
+ "d01c8bf1b6dab8e1864dac26",
+ "d01c8bf1b6daf7f7f7b8e1864dac26",
+ "c51b7de9a3c9fde0efe6f5d0a1d76a4d9221",
+ "c51b7de9a3c9fde0eff7f7f7e6f5d0a1d76a4d9221",
+ "c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221",
+ "c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221",
+ "8e0152c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221276419",
+ "8e0152c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221276419"
+).map(colors);
+
+var PiYG = ramp$1(scheme$o);
+
+var scheme$n = new Array(3).concat(
+ "998ec3f7f7f7f1a340",
+ "5e3c99b2abd2fdb863e66101",
+ "5e3c99b2abd2f7f7f7fdb863e66101",
+ "542788998ec3d8daebfee0b6f1a340b35806",
+ "542788998ec3d8daebf7f7f7fee0b6f1a340b35806",
+ "5427888073acb2abd2d8daebfee0b6fdb863e08214b35806",
+ "5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b35806",
+ "2d004b5427888073acb2abd2d8daebfee0b6fdb863e08214b358067f3b08",
+ "2d004b5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b358067f3b08"
+).map(colors);
+
+var PuOr = ramp$1(scheme$n);
+
+var scheme$m = new Array(3).concat(
+ "ef8a62f7f7f767a9cf",
+ "ca0020f4a58292c5de0571b0",
+ "ca0020f4a582f7f7f792c5de0571b0",
+ "b2182bef8a62fddbc7d1e5f067a9cf2166ac",
+ "b2182bef8a62fddbc7f7f7f7d1e5f067a9cf2166ac",
+ "b2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac",
+ "b2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac",
+ "67001fb2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac053061",
+ "67001fb2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac053061"
+).map(colors);
+
+var RdBu = ramp$1(scheme$m);
+
+var scheme$l = new Array(3).concat(
+ "ef8a62ffffff999999",
+ "ca0020f4a582bababa404040",
+ "ca0020f4a582ffffffbababa404040",
+ "b2182bef8a62fddbc7e0e0e09999994d4d4d",
+ "b2182bef8a62fddbc7ffffffe0e0e09999994d4d4d",
+ "b2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d",
+ "b2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d",
+ "67001fb2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d1a1a1a",
+ "67001fb2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d1a1a1a"
+).map(colors);
+
+var RdGy = ramp$1(scheme$l);
+
+var scheme$k = new Array(3).concat(
+ "fc8d59ffffbf91bfdb",
+ "d7191cfdae61abd9e92c7bb6",
+ "d7191cfdae61ffffbfabd9e92c7bb6",
+ "d73027fc8d59fee090e0f3f891bfdb4575b4",
+ "d73027fc8d59fee090ffffbfe0f3f891bfdb4575b4",
+ "d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4",
+ "d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4",
+ "a50026d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4313695",
+ "a50026d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4313695"
+).map(colors);
+
+var RdYlBu = ramp$1(scheme$k);
+
+var scheme$j = new Array(3).concat(
+ "fc8d59ffffbf91cf60",
+ "d7191cfdae61a6d96a1a9641",
+ "d7191cfdae61ffffbfa6d96a1a9641",
+ "d73027fc8d59fee08bd9ef8b91cf601a9850",
+ "d73027fc8d59fee08bffffbfd9ef8b91cf601a9850",
+ "d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850",
+ "d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850",
+ "a50026d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850006837",
+ "a50026d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850006837"
+).map(colors);
+
+var RdYlGn = ramp$1(scheme$j);
+
+var scheme$i = new Array(3).concat(
+ "fc8d59ffffbf99d594",
+ "d7191cfdae61abdda42b83ba",
+ "d7191cfdae61ffffbfabdda42b83ba",
+ "d53e4ffc8d59fee08be6f59899d5943288bd",
+ "d53e4ffc8d59fee08bffffbfe6f59899d5943288bd",
+ "d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd",
+ "d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd",
+ "9e0142d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd5e4fa2",
+ "9e0142d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd5e4fa2"
+).map(colors);
+
+var Spectral = ramp$1(scheme$i);
+
+var scheme$h = new Array(3).concat(
+ "e5f5f999d8c92ca25f",
+ "edf8fbb2e2e266c2a4238b45",
+ "edf8fbb2e2e266c2a42ca25f006d2c",
+ "edf8fbccece699d8c966c2a42ca25f006d2c",
+ "edf8fbccece699d8c966c2a441ae76238b45005824",
+ "f7fcfde5f5f9ccece699d8c966c2a441ae76238b45005824",
+ "f7fcfde5f5f9ccece699d8c966c2a441ae76238b45006d2c00441b"
+).map(colors);
+
+var BuGn = ramp$1(scheme$h);
+
+var scheme$g = new Array(3).concat(
+ "e0ecf49ebcda8856a7",
+ "edf8fbb3cde38c96c688419d",
+ "edf8fbb3cde38c96c68856a7810f7c",
+ "edf8fbbfd3e69ebcda8c96c68856a7810f7c",
+ "edf8fbbfd3e69ebcda8c96c68c6bb188419d6e016b",
+ "f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d6e016b",
+ "f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d810f7c4d004b"
+).map(colors);
+
+var BuPu = ramp$1(scheme$g);
+
+var scheme$f = new Array(3).concat(
+ "e0f3dba8ddb543a2ca",
+ "f0f9e8bae4bc7bccc42b8cbe",
+ "f0f9e8bae4bc7bccc443a2ca0868ac",
+ "f0f9e8ccebc5a8ddb57bccc443a2ca0868ac",
+ "f0f9e8ccebc5a8ddb57bccc44eb3d32b8cbe08589e",
+ "f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe08589e",
+ "f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe0868ac084081"
+).map(colors);
+
+var GnBu = ramp$1(scheme$f);
+
+var scheme$e = new Array(3).concat(
+ "fee8c8fdbb84e34a33",
+ "fef0d9fdcc8afc8d59d7301f",
+ "fef0d9fdcc8afc8d59e34a33b30000",
+ "fef0d9fdd49efdbb84fc8d59e34a33b30000",
+ "fef0d9fdd49efdbb84fc8d59ef6548d7301f990000",
+ "fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301f990000",
+ "fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301fb300007f0000"
+).map(colors);
+
+var OrRd = ramp$1(scheme$e);
+
+var scheme$d = new Array(3).concat(
+ "ece2f0a6bddb1c9099",
+ "f6eff7bdc9e167a9cf02818a",
+ "f6eff7bdc9e167a9cf1c9099016c59",
+ "f6eff7d0d1e6a6bddb67a9cf1c9099016c59",
+ "f6eff7d0d1e6a6bddb67a9cf3690c002818a016450",
+ "fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016450",
+ "fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016c59014636"
+).map(colors);
+
+var PuBuGn = ramp$1(scheme$d);
+
+var scheme$c = new Array(3).concat(
+ "ece7f2a6bddb2b8cbe",
+ "f1eef6bdc9e174a9cf0570b0",
+ "f1eef6bdc9e174a9cf2b8cbe045a8d",
+ "f1eef6d0d1e6a6bddb74a9cf2b8cbe045a8d",
+ "f1eef6d0d1e6a6bddb74a9cf3690c00570b0034e7b",
+ "fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0034e7b",
+ "fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0045a8d023858"
+).map(colors);
+
+var PuBu = ramp$1(scheme$c);
+
+var scheme$b = new Array(3).concat(
+ "e7e1efc994c7dd1c77",
+ "f1eef6d7b5d8df65b0ce1256",
+ "f1eef6d7b5d8df65b0dd1c77980043",
+ "f1eef6d4b9dac994c7df65b0dd1c77980043",
+ "f1eef6d4b9dac994c7df65b0e7298ace125691003f",
+ "f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125691003f",
+ "f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125698004367001f"
+).map(colors);
+
+var PuRd = ramp$1(scheme$b);
+
+var scheme$a = new Array(3).concat(
+ "fde0ddfa9fb5c51b8a",
+ "feebe2fbb4b9f768a1ae017e",
+ "feebe2fbb4b9f768a1c51b8a7a0177",
+ "feebe2fcc5c0fa9fb5f768a1c51b8a7a0177",
+ "feebe2fcc5c0fa9fb5f768a1dd3497ae017e7a0177",
+ "fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a0177",
+ "fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a017749006a"
+).map(colors);
+
+var RdPu = ramp$1(scheme$a);
+
+var scheme$9 = new Array(3).concat(
+ "edf8b17fcdbb2c7fb8",
+ "ffffcca1dab441b6c4225ea8",
+ "ffffcca1dab441b6c42c7fb8253494",
+ "ffffccc7e9b47fcdbb41b6c42c7fb8253494",
+ "ffffccc7e9b47fcdbb41b6c41d91c0225ea80c2c84",
+ "ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea80c2c84",
+ "ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea8253494081d58"
+).map(colors);
+
+var YlGnBu = ramp$1(scheme$9);
+
+var scheme$8 = new Array(3).concat(
+ "f7fcb9addd8e31a354",
+ "ffffccc2e69978c679238443",
+ "ffffccc2e69978c67931a354006837",
+ "ffffccd9f0a3addd8e78c67931a354006837",
+ "ffffccd9f0a3addd8e78c67941ab5d238443005a32",
+ "ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443005a32",
+ "ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443006837004529"
+).map(colors);
+
+var YlGn = ramp$1(scheme$8);
+
+var scheme$7 = new Array(3).concat(
+ "fff7bcfec44fd95f0e",
+ "ffffd4fed98efe9929cc4c02",
+ "ffffd4fed98efe9929d95f0e993404",
+ "ffffd4fee391fec44ffe9929d95f0e993404",
+ "ffffd4fee391fec44ffe9929ec7014cc4c028c2d04",
+ "ffffe5fff7bcfee391fec44ffe9929ec7014cc4c028c2d04",
+ "ffffe5fff7bcfee391fec44ffe9929ec7014cc4c02993404662506"
+).map(colors);
+
+var YlOrBr = ramp$1(scheme$7);
+
+var scheme$6 = new Array(3).concat(
+ "ffeda0feb24cf03b20",
+ "ffffb2fecc5cfd8d3ce31a1c",
+ "ffffb2fecc5cfd8d3cf03b20bd0026",
+ "ffffb2fed976feb24cfd8d3cf03b20bd0026",
+ "ffffb2fed976feb24cfd8d3cfc4e2ae31a1cb10026",
+ "ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cb10026",
+ "ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cbd0026800026"
+).map(colors);
+
+var YlOrRd = ramp$1(scheme$6);
+
+var scheme$5 = new Array(3).concat(
+ "deebf79ecae13182bd",
+ "eff3ffbdd7e76baed62171b5",
+ "eff3ffbdd7e76baed63182bd08519c",
+ "eff3ffc6dbef9ecae16baed63182bd08519c",
+ "eff3ffc6dbef9ecae16baed64292c62171b5084594",
+ "f7fbffdeebf7c6dbef9ecae16baed64292c62171b5084594",
+ "f7fbffdeebf7c6dbef9ecae16baed64292c62171b508519c08306b"
+).map(colors);
+
+var Blues = ramp$1(scheme$5);
+
+var scheme$4 = new Array(3).concat(
+ "e5f5e0a1d99b31a354",
+ "edf8e9bae4b374c476238b45",
+ "edf8e9bae4b374c47631a354006d2c",
+ "edf8e9c7e9c0a1d99b74c47631a354006d2c",
+ "edf8e9c7e9c0a1d99b74c47641ab5d238b45005a32",
+ "f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45005a32",
+ "f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45006d2c00441b"
+).map(colors);
+
+var Greens = ramp$1(scheme$4);
+
+var scheme$3 = new Array(3).concat(
+ "f0f0f0bdbdbd636363",
+ "f7f7f7cccccc969696525252",
+ "f7f7f7cccccc969696636363252525",
+ "f7f7f7d9d9d9bdbdbd969696636363252525",
+ "f7f7f7d9d9d9bdbdbd969696737373525252252525",
+ "fffffff0f0f0d9d9d9bdbdbd969696737373525252252525",
+ "fffffff0f0f0d9d9d9bdbdbd969696737373525252252525000000"
+).map(colors);
+
+var Greys = ramp$1(scheme$3);
+
+var scheme$2 = new Array(3).concat(
+ "efedf5bcbddc756bb1",
+ "f2f0f7cbc9e29e9ac86a51a3",
+ "f2f0f7cbc9e29e9ac8756bb154278f",
+ "f2f0f7dadaebbcbddc9e9ac8756bb154278f",
+ "f2f0f7dadaebbcbddc9e9ac8807dba6a51a34a1486",
+ "fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a34a1486",
+ "fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a354278f3f007d"
+).map(colors);
+
+var Purples = ramp$1(scheme$2);
+
+var scheme$1 = new Array(3).concat(
+ "fee0d2fc9272de2d26",
+ "fee5d9fcae91fb6a4acb181d",
+ "fee5d9fcae91fb6a4ade2d26a50f15",
+ "fee5d9fcbba1fc9272fb6a4ade2d26a50f15",
+ "fee5d9fcbba1fc9272fb6a4aef3b2ccb181d99000d",
+ "fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181d99000d",
+ "fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181da50f1567000d"
+).map(colors);
+
+var Reds = ramp$1(scheme$1);
+
+var scheme = new Array(3).concat(
+ "fee6cefdae6be6550d",
+ "feeddefdbe85fd8d3cd94701",
+ "feeddefdbe85fd8d3ce6550da63603",
+ "feeddefdd0a2fdae6bfd8d3ce6550da63603",
+ "feeddefdd0a2fdae6bfd8d3cf16913d948018c2d04",
+ "fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d948018c2d04",
+ "fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d94801a636037f2704"
+).map(colors);
+
+var Oranges = ramp$1(scheme);
+
+function cividis(t) {
+ t = Math.max(0, Math.min(1, t));
+ return "rgb("
+ + Math.max(0, Math.min(255, Math.round(-4.54 - t * (35.34 - t * (2381.73 - t * (6402.7 - t * (7024.72 - t * 2710.57))))))) + ", "
+ + Math.max(0, Math.min(255, Math.round(32.49 + t * (170.73 + t * (52.82 - t * (131.46 - t * (176.58 - t * 67.37))))))) + ", "
+ + Math.max(0, Math.min(255, Math.round(81.24 + t * (442.36 - t * (2482.43 - t * (6167.24 - t * (6614.94 - t * 2475.67)))))))
+ + ")";
+}
+
+var cubehelix = d3Interpolate.interpolateCubehelixLong(d3Color.cubehelix(300, 0.5, 0.0), d3Color.cubehelix(-240, 0.5, 1.0));
+
+var warm = d3Interpolate.interpolateCubehelixLong(d3Color.cubehelix(-100, 0.75, 0.35), d3Color.cubehelix(80, 1.50, 0.8));
+
+var cool = d3Interpolate.interpolateCubehelixLong(d3Color.cubehelix(260, 0.75, 0.35), d3Color.cubehelix(80, 1.50, 0.8));
+
+var c$1 = d3Color.cubehelix();
+
+function rainbow(t) {
+ if (t < 0 || t > 1) t -= Math.floor(t);
+ var ts = Math.abs(t - 0.5);
+ c$1.h = 360 * t - 100;
+ c$1.s = 1.5 - 1.5 * ts;
+ c$1.l = 0.8 - 0.9 * ts;
+ return c$1 + "";
+}
+
+var c = d3Color.rgb(),
+ pi_1_3 = Math.PI / 3,
+ pi_2_3 = Math.PI * 2 / 3;
+
+function sinebow(t) {
+ var x;
+ t = (0.5 - t) * Math.PI;
+ c.r = 255 * (x = Math.sin(t)) * x;
+ c.g = 255 * (x = Math.sin(t + pi_1_3)) * x;
+ c.b = 255 * (x = Math.sin(t + pi_2_3)) * x;
+ return c + "";
+}
+
+function turbo(t) {
+ t = Math.max(0, Math.min(1, t));
+ return "rgb("
+ + Math.max(0, Math.min(255, Math.round(34.61 + t * (1172.33 - t * (10793.56 - t * (33300.12 - t * (38394.49 - t * 14825.05))))))) + ", "
+ + Math.max(0, Math.min(255, Math.round(23.31 + t * (557.33 + t * (1225.33 - t * (3574.96 - t * (1073.77 + t * 707.56))))))) + ", "
+ + Math.max(0, Math.min(255, Math.round(27.2 + t * (3211.1 - t * (15327.97 - t * (27814 - t * (22569.18 - t * 6838.66)))))))
+ + ")";
+}
+
+function ramp(range) {
+ var n = range.length;
+ return function(t) {
+ return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];
+ };
+}
+
+var viridis = ramp(colors("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));
+
+var magma = ramp(colors("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf"));
+
+var inferno = ramp(colors("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4"));
+
+var plasma = ramp(colors("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921"));
+
+exports.interpolateBlues = Blues;
+exports.interpolateBrBG = BrBG;
+exports.interpolateBuGn = BuGn;
+exports.interpolateBuPu = BuPu;
+exports.interpolateCividis = cividis;
+exports.interpolateCool = cool;
+exports.interpolateCubehelixDefault = cubehelix;
+exports.interpolateGnBu = GnBu;
+exports.interpolateGreens = Greens;
+exports.interpolateGreys = Greys;
+exports.interpolateInferno = inferno;
+exports.interpolateMagma = magma;
+exports.interpolateOrRd = OrRd;
+exports.interpolateOranges = Oranges;
+exports.interpolatePRGn = PRGn;
+exports.interpolatePiYG = PiYG;
+exports.interpolatePlasma = plasma;
+exports.interpolatePuBu = PuBu;
+exports.interpolatePuBuGn = PuBuGn;
+exports.interpolatePuOr = PuOr;
+exports.interpolatePuRd = PuRd;
+exports.interpolatePurples = Purples;
+exports.interpolateRainbow = rainbow;
+exports.interpolateRdBu = RdBu;
+exports.interpolateRdGy = RdGy;
+exports.interpolateRdPu = RdPu;
+exports.interpolateRdYlBu = RdYlBu;
+exports.interpolateRdYlGn = RdYlGn;
+exports.interpolateReds = Reds;
+exports.interpolateSinebow = sinebow;
+exports.interpolateSpectral = Spectral;
+exports.interpolateTurbo = turbo;
+exports.interpolateViridis = viridis;
+exports.interpolateWarm = warm;
+exports.interpolateYlGn = YlGn;
+exports.interpolateYlGnBu = YlGnBu;
+exports.interpolateYlOrBr = YlOrBr;
+exports.interpolateYlOrRd = YlOrRd;
+exports.schemeAccent = Accent;
+exports.schemeBlues = scheme$5;
+exports.schemeBrBG = scheme$q;
+exports.schemeBuGn = scheme$h;
+exports.schemeBuPu = scheme$g;
+exports.schemeCategory10 = category10;
+exports.schemeDark2 = Dark2;
+exports.schemeGnBu = scheme$f;
+exports.schemeGreens = scheme$4;
+exports.schemeGreys = scheme$3;
+exports.schemeOrRd = scheme$e;
+exports.schemeOranges = scheme;
+exports.schemePRGn = scheme$p;
+exports.schemePaired = Paired;
+exports.schemePastel1 = Pastel1;
+exports.schemePastel2 = Pastel2;
+exports.schemePiYG = scheme$o;
+exports.schemePuBu = scheme$c;
+exports.schemePuBuGn = scheme$d;
+exports.schemePuOr = scheme$n;
+exports.schemePuRd = scheme$b;
+exports.schemePurples = scheme$2;
+exports.schemeRdBu = scheme$m;
+exports.schemeRdGy = scheme$l;
+exports.schemeRdPu = scheme$a;
+exports.schemeRdYlBu = scheme$k;
+exports.schemeRdYlGn = scheme$j;
+exports.schemeReds = scheme$1;
+exports.schemeSet1 = Set1;
+exports.schemeSet2 = Set2;
+exports.schemeSet3 = Set3;
+exports.schemeSpectral = scheme$i;
+exports.schemeTableau10 = Tableau10;
+exports.schemeYlGn = scheme$8;
+exports.schemeYlGnBu = scheme$9;
+exports.schemeYlOrBr = scheme$7;
+exports.schemeYlOrRd = scheme$6;
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+})));
diff --git a/node_modules/d3-scale-chromatic/dist/d3-scale-chromatic.min.js b/node_modules/d3-scale-chromatic/dist/d3-scale-chromatic.min.js
new file mode 100644
index 00000000..4ad16891
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/dist/d3-scale-chromatic.min.js
@@ -0,0 +1,2 @@
+// https://d3js.org/d3-scale-chromatic/ v3.0.0 Copyright 2010-2021 Mike Bostock; 2002 Cynthia Brewer, Mark Harrower, and The Pennsylvania State University
+!function(f,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("d3-interpolate"),require("d3-color")):"function"==typeof define&&define.amd?define(["exports","d3-interpolate","d3-color"],e):e((f="undefined"!=typeof globalThis?globalThis:f||self).d3=f.d3||{},f.d3,f.d3)}(this,(function(f,e,d){"use strict";function a(f){for(var e=f.length/6|0,d=new Array(e),a=0;ae.interpolateRgbBasis(f[f.length-1]),u=new Array(3).concat("d8b365f5f5f55ab4ac","a6611adfc27d80cdc1018571","a6611adfc27df5f5f580cdc1018571","8c510ad8b365f6e8c3c7eae55ab4ac01665e","8c510ad8b365f6e8c3f5f5f5c7eae55ab4ac01665e","8c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e","8c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e","5430058c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e003c30","5430058c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e003c30").map(a),s=p(u),y=new Array(3).concat("af8dc3f7f7f77fbf7b","7b3294c2a5cfa6dba0008837","7b3294c2a5cff7f7f7a6dba0008837","762a83af8dc3e7d4e8d9f0d37fbf7b1b7837","762a83af8dc3e7d4e8f7f7f7d9f0d37fbf7b1b7837","762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b7837","762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b7837","40004b762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b783700441b","40004b762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b783700441b").map(a),M=p(y),w=new Array(3).concat("e9a3c9f7f7f7a1d76a","d01c8bf1b6dab8e1864dac26","d01c8bf1b6daf7f7f7b8e1864dac26","c51b7de9a3c9fde0efe6f5d0a1d76a4d9221","c51b7de9a3c9fde0eff7f7f7e6f5d0a1d76a4d9221","c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221","c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221","8e0152c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221276419","8e0152c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221276419").map(a),A=p(w),P=new Array(3).concat("998ec3f7f7f7f1a340","5e3c99b2abd2fdb863e66101","5e3c99b2abd2f7f7f7fdb863e66101","542788998ec3d8daebfee0b6f1a340b35806","542788998ec3d8daebf7f7f7fee0b6f1a340b35806","5427888073acb2abd2d8daebfee0b6fdb863e08214b35806","5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b35806","2d004b5427888073acb2abd2d8daebfee0b6fdb863e08214b358067f3b08","2d004b5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b358067f3b08").map(a),B=p(P),G=new Array(3).concat("ef8a62f7f7f767a9cf","ca0020f4a58292c5de0571b0","ca0020f4a582f7f7f792c5de0571b0","b2182bef8a62fddbc7d1e5f067a9cf2166ac","b2182bef8a62fddbc7f7f7f7d1e5f067a9cf2166ac","b2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac","b2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac","67001fb2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac053061","67001fb2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac053061").map(a),x=p(G),R=new Array(3).concat("ef8a62ffffff999999","ca0020f4a582bababa404040","ca0020f4a582ffffffbababa404040","b2182bef8a62fddbc7e0e0e09999994d4d4d","b2182bef8a62fddbc7ffffffe0e0e09999994d4d4d","b2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d","b2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d","67001fb2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d1a1a1a","67001fb2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d1a1a1a").map(a),g=p(R),Y=new Array(3).concat("fc8d59ffffbf91bfdb","d7191cfdae61abd9e92c7bb6","d7191cfdae61ffffbfabd9e92c7bb6","d73027fc8d59fee090e0f3f891bfdb4575b4","d73027fc8d59fee090ffffbfe0f3f891bfdb4575b4","d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4","d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4","a50026d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4313695","a50026d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4313695").map(a),O=p(Y),v=new Array(3).concat("fc8d59ffffbf91cf60","d7191cfdae61a6d96a1a9641","d7191cfdae61ffffbfa6d96a1a9641","d73027fc8d59fee08bd9ef8b91cf601a9850","d73027fc8d59fee08bffffbfd9ef8b91cf601a9850","d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850","d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850","a50026d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850006837","a50026d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850006837").map(a),C=p(v),S=new Array(3).concat("fc8d59ffffbf99d594","d7191cfdae61abdda42b83ba","d7191cfdae61ffffbfabdda42b83ba","d53e4ffc8d59fee08be6f59899d5943288bd","d53e4ffc8d59fee08bffffbfe6f59899d5943288bd","d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd","d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd","9e0142d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd5e4fa2","9e0142d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd5e4fa2").map(a),I=p(S),T=new Array(3).concat("e5f5f999d8c92ca25f","edf8fbb2e2e266c2a4238b45","edf8fbb2e2e266c2a42ca25f006d2c","edf8fbccece699d8c966c2a42ca25f006d2c","edf8fbccece699d8c966c2a441ae76238b45005824","f7fcfde5f5f9ccece699d8c966c2a441ae76238b45005824","f7fcfde5f5f9ccece699d8c966c2a441ae76238b45006d2c00441b").map(a),L=p(T),j=new Array(3).concat("e0ecf49ebcda8856a7","edf8fbb3cde38c96c688419d","edf8fbb3cde38c96c68856a7810f7c","edf8fbbfd3e69ebcda8c96c68856a7810f7c","edf8fbbfd3e69ebcda8c96c68c6bb188419d6e016b","f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d6e016b","f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d810f7c4d004b").map(a),q=p(j),D=new Array(3).concat("e0f3dba8ddb543a2ca","f0f9e8bae4bc7bccc42b8cbe","f0f9e8bae4bc7bccc443a2ca0868ac","f0f9e8ccebc5a8ddb57bccc443a2ca0868ac","f0f9e8ccebc5a8ddb57bccc44eb3d32b8cbe08589e","f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe08589e","f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe0868ac084081").map(a),_=p(D),k=new Array(3).concat("fee8c8fdbb84e34a33","fef0d9fdcc8afc8d59d7301f","fef0d9fdcc8afc8d59e34a33b30000","fef0d9fdd49efdbb84fc8d59e34a33b30000","fef0d9fdd49efdbb84fc8d59ef6548d7301f990000","fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301f990000","fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301fb300007f0000").map(a),V=p(k),W=new Array(3).concat("ece2f0a6bddb1c9099","f6eff7bdc9e167a9cf02818a","f6eff7bdc9e167a9cf1c9099016c59","f6eff7d0d1e6a6bddb67a9cf1c9099016c59","f6eff7d0d1e6a6bddb67a9cf3690c002818a016450","fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016450","fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016c59014636").map(a),z=p(W),E=new Array(3).concat("ece7f2a6bddb2b8cbe","f1eef6bdc9e174a9cf0570b0","f1eef6bdc9e174a9cf2b8cbe045a8d","f1eef6d0d1e6a6bddb74a9cf2b8cbe045a8d","f1eef6d0d1e6a6bddb74a9cf3690c00570b0034e7b","fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0034e7b","fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0045a8d023858").map(a),F=p(E),H=new Array(3).concat("e7e1efc994c7dd1c77","f1eef6d7b5d8df65b0ce1256","f1eef6d7b5d8df65b0dd1c77980043","f1eef6d4b9dac994c7df65b0dd1c77980043","f1eef6d4b9dac994c7df65b0e7298ace125691003f","f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125691003f","f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125698004367001f").map(a),J=p(H),K=new Array(3).concat("fde0ddfa9fb5c51b8a","feebe2fbb4b9f768a1ae017e","feebe2fbb4b9f768a1c51b8a7a0177","feebe2fcc5c0fa9fb5f768a1c51b8a7a0177","feebe2fcc5c0fa9fb5f768a1dd3497ae017e7a0177","fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a0177","fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a017749006a").map(a),N=p(K),Q=new Array(3).concat("edf8b17fcdbb2c7fb8","ffffcca1dab441b6c4225ea8","ffffcca1dab441b6c42c7fb8253494","ffffccc7e9b47fcdbb41b6c42c7fb8253494","ffffccc7e9b47fcdbb41b6c41d91c0225ea80c2c84","ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea80c2c84","ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea8253494081d58").map(a),U=p(Q),X=new Array(3).concat("f7fcb9addd8e31a354","ffffccc2e69978c679238443","ffffccc2e69978c67931a354006837","ffffccd9f0a3addd8e78c67931a354006837","ffffccd9f0a3addd8e78c67941ab5d238443005a32","ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443005a32","ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443006837004529").map(a),Z=p(X),$=new Array(3).concat("fff7bcfec44fd95f0e","ffffd4fed98efe9929cc4c02","ffffd4fed98efe9929d95f0e993404","ffffd4fee391fec44ffe9929d95f0e993404","ffffd4fee391fec44ffe9929ec7014cc4c028c2d04","ffffe5fff7bcfee391fec44ffe9929ec7014cc4c028c2d04","ffffe5fff7bcfee391fec44ffe9929ec7014cc4c02993404662506").map(a),ff=p($),ef=new Array(3).concat("ffeda0feb24cf03b20","ffffb2fecc5cfd8d3ce31a1c","ffffb2fecc5cfd8d3cf03b20bd0026","ffffb2fed976feb24cfd8d3cf03b20bd0026","ffffb2fed976feb24cfd8d3cfc4e2ae31a1cb10026","ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cb10026","ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cbd0026800026").map(a),df=p(ef),af=new Array(3).concat("deebf79ecae13182bd","eff3ffbdd7e76baed62171b5","eff3ffbdd7e76baed63182bd08519c","eff3ffc6dbef9ecae16baed63182bd08519c","eff3ffc6dbef9ecae16baed64292c62171b5084594","f7fbffdeebf7c6dbef9ecae16baed64292c62171b5084594","f7fbffdeebf7c6dbef9ecae16baed64292c62171b508519c08306b").map(a),cf=p(af),bf=new Array(3).concat("e5f5e0a1d99b31a354","edf8e9bae4b374c476238b45","edf8e9bae4b374c47631a354006d2c","edf8e9c7e9c0a1d99b74c47631a354006d2c","edf8e9c7e9c0a1d99b74c47641ab5d238b45005a32","f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45005a32","f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45006d2c00441b").map(a),tf=p(bf),nf=new Array(3).concat("f0f0f0bdbdbd636363","f7f7f7cccccc969696525252","f7f7f7cccccc969696636363252525","f7f7f7d9d9d9bdbdbd969696636363252525","f7f7f7d9d9d9bdbdbd969696737373525252252525","fffffff0f0f0d9d9d9bdbdbd969696737373525252252525","fffffff0f0f0d9d9d9bdbdbd969696737373525252252525000000").map(a),rf=p(nf),of=new Array(3).concat("efedf5bcbddc756bb1","f2f0f7cbc9e29e9ac86a51a3","f2f0f7cbc9e29e9ac8756bb154278f","f2f0f7dadaebbcbddc9e9ac8756bb154278f","f2f0f7dadaebbcbddc9e9ac8807dba6a51a34a1486","fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a34a1486","fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a354278f3f007d").map(a),lf=p(of),hf=new Array(3).concat("fee0d2fc9272de2d26","fee5d9fcae91fb6a4acb181d","fee5d9fcae91fb6a4ade2d26a50f15","fee5d9fcbba1fc9272fb6a4ade2d26a50f15","fee5d9fcbba1fc9272fb6a4aef3b2ccb181d99000d","fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181d99000d","fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181da50f1567000d").map(a),mf=p(hf),pf=new Array(3).concat("fee6cefdae6be6550d","feeddefdbe85fd8d3cd94701","feeddefdbe85fd8d3ce6550da63603","feeddefdd0a2fdae6bfd8d3ce6550da63603","feeddefdd0a2fdae6bfd8d3cf16913d948018c2d04","fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d948018c2d04","fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d94801a636037f2704").map(a),uf=p(pf);var sf=e.interpolateCubehelixLong(d.cubehelix(300,.5,0),d.cubehelix(-240,.5,1)),yf=e.interpolateCubehelixLong(d.cubehelix(-100,.75,.35),d.cubehelix(80,1.5,.8)),Mf=e.interpolateCubehelixLong(d.cubehelix(260,.75,.35),d.cubehelix(80,1.5,.8)),wf=d.cubehelix();var Af=d.rgb(),Pf=Math.PI/3,Bf=2*Math.PI/3;function Gf(f){var e=f.length;return function(d){return f[Math.max(0,Math.min(e-1,Math.floor(d*e)))]}}var xf=Gf(a("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725")),Rf=Gf(a("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")),gf=Gf(a("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")),Yf=Gf(a("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921"));f.interpolateBlues=cf,f.interpolateBrBG=s,f.interpolateBuGn=L,f.interpolateBuPu=q,f.interpolateCividis=function(f){return f=Math.max(0,Math.min(1,f)),"rgb("+Math.max(0,Math.min(255,Math.round(-4.54-f*(35.34-f*(2381.73-f*(6402.7-f*(7024.72-2710.57*f)))))))+", "+Math.max(0,Math.min(255,Math.round(32.49+f*(170.73+f*(52.82-f*(131.46-f*(176.58-67.37*f)))))))+", "+Math.max(0,Math.min(255,Math.round(81.24+f*(442.36-f*(2482.43-f*(6167.24-f*(6614.94-2475.67*f)))))))+")"},f.interpolateCool=Mf,f.interpolateCubehelixDefault=sf,f.interpolateGnBu=_,f.interpolateGreens=tf,f.interpolateGreys=rf,f.interpolateInferno=gf,f.interpolateMagma=Rf,f.interpolateOrRd=V,f.interpolateOranges=uf,f.interpolatePRGn=M,f.interpolatePiYG=A,f.interpolatePlasma=Yf,f.interpolatePuBu=F,f.interpolatePuBuGn=z,f.interpolatePuOr=B,f.interpolatePuRd=J,f.interpolatePurples=lf,f.interpolateRainbow=function(f){(f<0||f>1)&&(f-=Math.floor(f));var e=Math.abs(f-.5);return wf.h=360*f-100,wf.s=1.5-1.5*e,wf.l=.8-.9*e,wf+""},f.interpolateRdBu=x,f.interpolateRdGy=g,f.interpolateRdPu=N,f.interpolateRdYlBu=O,f.interpolateRdYlGn=C,f.interpolateReds=mf,f.interpolateSinebow=function(f){var e;return f=(.5-f)*Math.PI,Af.r=255*(e=Math.sin(f))*e,Af.g=255*(e=Math.sin(f+Pf))*e,Af.b=255*(e=Math.sin(f+Bf))*e,Af+""},f.interpolateSpectral=I,f.interpolateTurbo=function(f){return f=Math.max(0,Math.min(1,f)),"rgb("+Math.max(0,Math.min(255,Math.round(34.61+f*(1172.33-f*(10793.56-f*(33300.12-f*(38394.49-14825.05*f)))))))+", "+Math.max(0,Math.min(255,Math.round(23.31+f*(557.33+f*(1225.33-f*(3574.96-f*(1073.77+707.56*f)))))))+", "+Math.max(0,Math.min(255,Math.round(27.2+f*(3211.1-f*(15327.97-f*(27814-f*(22569.18-6838.66*f)))))))+")"},f.interpolateViridis=xf,f.interpolateWarm=yf,f.interpolateYlGn=Z,f.interpolateYlGnBu=U,f.interpolateYlOrBr=ff,f.interpolateYlOrRd=df,f.schemeAccent=b,f.schemeBlues=af,f.schemeBrBG=u,f.schemeBuGn=T,f.schemeBuPu=j,f.schemeCategory10=c,f.schemeDark2=t,f.schemeGnBu=D,f.schemeGreens=bf,f.schemeGreys=nf,f.schemeOrRd=k,f.schemeOranges=pf,f.schemePRGn=y,f.schemePaired=n,f.schemePastel1=r,f.schemePastel2=o,f.schemePiYG=w,f.schemePuBu=E,f.schemePuBuGn=W,f.schemePuOr=P,f.schemePuRd=H,f.schemePurples=of,f.schemeRdBu=G,f.schemeRdGy=R,f.schemeRdPu=K,f.schemeRdYlBu=Y,f.schemeRdYlGn=v,f.schemeReds=hf,f.schemeSet1=i,f.schemeSet2=l,f.schemeSet3=h,f.schemeSpectral=S,f.schemeTableau10=m,f.schemeYlGn=X,f.schemeYlGnBu=Q,f.schemeYlOrBr=$,f.schemeYlOrRd=ef,Object.defineProperty(f,"__esModule",{value:!0})}));
diff --git a/node_modules/d3-scale-chromatic/package.json b/node_modules/d3-scale-chromatic/package.json
new file mode 100644
index 00000000..efb23a44
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/package.json
@@ -0,0 +1,83 @@
+{
+ "_from": "d3-scale-chromatic@3",
+ "_id": "d3-scale-chromatic@3.0.0",
+ "_inBundle": false,
+ "_integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==",
+ "_location": "/d3-scale-chromatic",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "range",
+ "registry": true,
+ "raw": "d3-scale-chromatic@3",
+ "name": "d3-scale-chromatic",
+ "escapedName": "d3-scale-chromatic",
+ "rawSpec": "3",
+ "saveSpec": null,
+ "fetchSpec": "3"
+ },
+ "_requiredBy": [
+ "/d3"
+ ],
+ "_resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz",
+ "_shasum": "15b4ceb8ca2bb0dcb6d1a641ee03d59c3b62376a",
+ "_spec": "d3-scale-chromatic@3",
+ "_where": "C:\\Users\\colbs\\CS4241\\d3a4\\node_modules\\d3",
+ "author": {
+ "name": "Mike Bostock",
+ "url": "https://bost.ocks.org/mike"
+ },
+ "bugs": {
+ "url": "https://github.com/d3/d3-scale-chromatic/issues"
+ },
+ "bundleDependencies": false,
+ "dependencies": {
+ "d3-color": "1 - 3",
+ "d3-interpolate": "1 - 3"
+ },
+ "deprecated": false,
+ "description": "Sequential, diverging and categorical color schemes.",
+ "devDependencies": {
+ "eslint": "7",
+ "mocha": "8",
+ "rollup": "2",
+ "rollup-plugin-terser": "7"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "exports": {
+ "umd": "./dist/d3-scale-chromatic.min.js",
+ "default": "./src/index.js"
+ },
+ "files": [
+ "dist/**/*.js",
+ "src/**/*.js"
+ ],
+ "homepage": "https://d3js.org/d3-scale-chromatic/",
+ "jsdelivr": "dist/d3-scale-chromatic.min.js",
+ "keywords": [
+ "d3",
+ "d3-module",
+ "color",
+ "scale",
+ "sequential",
+ "colorbrewer"
+ ],
+ "license": "ISC",
+ "main": "src/index.js",
+ "module": "src/index.js",
+ "name": "d3-scale-chromatic",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/d3/d3-scale-chromatic.git"
+ },
+ "scripts": {
+ "postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -",
+ "prepublishOnly": "rm -rf dist && yarn test && rollup -c",
+ "test": "mocha 'test/**/*-test.js' && eslint src test"
+ },
+ "sideEffects": false,
+ "type": "module",
+ "unpkg": "dist/d3-scale-chromatic.min.js",
+ "version": "3.0.0"
+}
diff --git a/node_modules/d3-scale-chromatic/src/categorical/Accent.js b/node_modules/d3-scale-chromatic/src/categorical/Accent.js
new file mode 100644
index 00000000..3a1a9fd4
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/categorical/Accent.js
@@ -0,0 +1,3 @@
+import colors from "../colors.js";
+
+export default colors("7fc97fbeaed4fdc086ffff99386cb0f0027fbf5b17666666");
diff --git a/node_modules/d3-scale-chromatic/src/categorical/Dark2.js b/node_modules/d3-scale-chromatic/src/categorical/Dark2.js
new file mode 100644
index 00000000..1fe995da
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/categorical/Dark2.js
@@ -0,0 +1,3 @@
+import colors from "../colors.js";
+
+export default colors("1b9e77d95f027570b3e7298a66a61ee6ab02a6761d666666");
diff --git a/node_modules/d3-scale-chromatic/src/categorical/Paired.js b/node_modules/d3-scale-chromatic/src/categorical/Paired.js
new file mode 100644
index 00000000..831fba32
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/categorical/Paired.js
@@ -0,0 +1,3 @@
+import colors from "../colors.js";
+
+export default colors("a6cee31f78b4b2df8a33a02cfb9a99e31a1cfdbf6fff7f00cab2d66a3d9affff99b15928");
diff --git a/node_modules/d3-scale-chromatic/src/categorical/Pastel1.js b/node_modules/d3-scale-chromatic/src/categorical/Pastel1.js
new file mode 100644
index 00000000..d39c8034
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/categorical/Pastel1.js
@@ -0,0 +1,3 @@
+import colors from "../colors.js";
+
+export default colors("fbb4aeb3cde3ccebc5decbe4fed9a6ffffcce5d8bdfddaecf2f2f2");
diff --git a/node_modules/d3-scale-chromatic/src/categorical/Pastel2.js b/node_modules/d3-scale-chromatic/src/categorical/Pastel2.js
new file mode 100644
index 00000000..342e3ce3
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/categorical/Pastel2.js
@@ -0,0 +1,3 @@
+import colors from "../colors.js";
+
+export default colors("b3e2cdfdcdaccbd5e8f4cae4e6f5c9fff2aef1e2cccccccc");
diff --git a/node_modules/d3-scale-chromatic/src/categorical/Set1.js b/node_modules/d3-scale-chromatic/src/categorical/Set1.js
new file mode 100644
index 00000000..408887ba
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/categorical/Set1.js
@@ -0,0 +1,3 @@
+import colors from "../colors.js";
+
+export default colors("e41a1c377eb84daf4a984ea3ff7f00ffff33a65628f781bf999999");
diff --git a/node_modules/d3-scale-chromatic/src/categorical/Set2.js b/node_modules/d3-scale-chromatic/src/categorical/Set2.js
new file mode 100644
index 00000000..9aa80301
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/categorical/Set2.js
@@ -0,0 +1,3 @@
+import colors from "../colors.js";
+
+export default colors("66c2a5fc8d628da0cbe78ac3a6d854ffd92fe5c494b3b3b3");
diff --git a/node_modules/d3-scale-chromatic/src/categorical/Set3.js b/node_modules/d3-scale-chromatic/src/categorical/Set3.js
new file mode 100644
index 00000000..d3b9b27d
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/categorical/Set3.js
@@ -0,0 +1,3 @@
+import colors from "../colors.js";
+
+export default colors("8dd3c7ffffb3bebadafb807280b1d3fdb462b3de69fccde5d9d9d9bc80bdccebc5ffed6f");
diff --git a/node_modules/d3-scale-chromatic/src/categorical/Tableau10.js b/node_modules/d3-scale-chromatic/src/categorical/Tableau10.js
new file mode 100644
index 00000000..370c9502
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/categorical/Tableau10.js
@@ -0,0 +1,3 @@
+import colors from "../colors.js";
+
+export default colors("4e79a7f28e2ce1575976b7b259a14fedc949af7aa1ff9da79c755fbab0ab");
diff --git a/node_modules/d3-scale-chromatic/src/categorical/category10.js b/node_modules/d3-scale-chromatic/src/categorical/category10.js
new file mode 100644
index 00000000..9adcd019
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/categorical/category10.js
@@ -0,0 +1,3 @@
+import colors from "../colors.js";
+
+export default colors("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf");
diff --git a/node_modules/d3-scale-chromatic/src/colors.js b/node_modules/d3-scale-chromatic/src/colors.js
new file mode 100644
index 00000000..aeedad53
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/colors.js
@@ -0,0 +1,5 @@
+export default function(specifier) {
+ var n = specifier.length / 6 | 0, colors = new Array(n), i = 0;
+ while (i < n) colors[i] = "#" + specifier.slice(i * 6, ++i * 6);
+ return colors;
+}
diff --git a/node_modules/d3-scale-chromatic/src/diverging/BrBG.js b/node_modules/d3-scale-chromatic/src/diverging/BrBG.js
new file mode 100644
index 00000000..6a467f7c
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/diverging/BrBG.js
@@ -0,0 +1,16 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "d8b365f5f5f55ab4ac",
+ "a6611adfc27d80cdc1018571",
+ "a6611adfc27df5f5f580cdc1018571",
+ "8c510ad8b365f6e8c3c7eae55ab4ac01665e",
+ "8c510ad8b365f6e8c3f5f5f5c7eae55ab4ac01665e",
+ "8c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e",
+ "8c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e",
+ "5430058c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e003c30",
+ "5430058c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e003c30"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/diverging/PRGn.js b/node_modules/d3-scale-chromatic/src/diverging/PRGn.js
new file mode 100644
index 00000000..dd278aa3
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/diverging/PRGn.js
@@ -0,0 +1,16 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "af8dc3f7f7f77fbf7b",
+ "7b3294c2a5cfa6dba0008837",
+ "7b3294c2a5cff7f7f7a6dba0008837",
+ "762a83af8dc3e7d4e8d9f0d37fbf7b1b7837",
+ "762a83af8dc3e7d4e8f7f7f7d9f0d37fbf7b1b7837",
+ "762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b7837",
+ "762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b7837",
+ "40004b762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b783700441b",
+ "40004b762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b783700441b"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/diverging/PiYG.js b/node_modules/d3-scale-chromatic/src/diverging/PiYG.js
new file mode 100644
index 00000000..43ef32d7
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/diverging/PiYG.js
@@ -0,0 +1,16 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "e9a3c9f7f7f7a1d76a",
+ "d01c8bf1b6dab8e1864dac26",
+ "d01c8bf1b6daf7f7f7b8e1864dac26",
+ "c51b7de9a3c9fde0efe6f5d0a1d76a4d9221",
+ "c51b7de9a3c9fde0eff7f7f7e6f5d0a1d76a4d9221",
+ "c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221",
+ "c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221",
+ "8e0152c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221276419",
+ "8e0152c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221276419"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/diverging/PuOr.js b/node_modules/d3-scale-chromatic/src/diverging/PuOr.js
new file mode 100644
index 00000000..770ef90f
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/diverging/PuOr.js
@@ -0,0 +1,16 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "998ec3f7f7f7f1a340",
+ "5e3c99b2abd2fdb863e66101",
+ "5e3c99b2abd2f7f7f7fdb863e66101",
+ "542788998ec3d8daebfee0b6f1a340b35806",
+ "542788998ec3d8daebf7f7f7fee0b6f1a340b35806",
+ "5427888073acb2abd2d8daebfee0b6fdb863e08214b35806",
+ "5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b35806",
+ "2d004b5427888073acb2abd2d8daebfee0b6fdb863e08214b358067f3b08",
+ "2d004b5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b358067f3b08"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/diverging/RdBu.js b/node_modules/d3-scale-chromatic/src/diverging/RdBu.js
new file mode 100644
index 00000000..703d61c5
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/diverging/RdBu.js
@@ -0,0 +1,16 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "ef8a62f7f7f767a9cf",
+ "ca0020f4a58292c5de0571b0",
+ "ca0020f4a582f7f7f792c5de0571b0",
+ "b2182bef8a62fddbc7d1e5f067a9cf2166ac",
+ "b2182bef8a62fddbc7f7f7f7d1e5f067a9cf2166ac",
+ "b2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac",
+ "b2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac",
+ "67001fb2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac053061",
+ "67001fb2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac053061"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/diverging/RdGy.js b/node_modules/d3-scale-chromatic/src/diverging/RdGy.js
new file mode 100644
index 00000000..b4deb6a0
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/diverging/RdGy.js
@@ -0,0 +1,16 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "ef8a62ffffff999999",
+ "ca0020f4a582bababa404040",
+ "ca0020f4a582ffffffbababa404040",
+ "b2182bef8a62fddbc7e0e0e09999994d4d4d",
+ "b2182bef8a62fddbc7ffffffe0e0e09999994d4d4d",
+ "b2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d",
+ "b2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d",
+ "67001fb2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d1a1a1a",
+ "67001fb2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d1a1a1a"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/diverging/RdYlBu.js b/node_modules/d3-scale-chromatic/src/diverging/RdYlBu.js
new file mode 100644
index 00000000..ad1a4128
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/diverging/RdYlBu.js
@@ -0,0 +1,16 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "fc8d59ffffbf91bfdb",
+ "d7191cfdae61abd9e92c7bb6",
+ "d7191cfdae61ffffbfabd9e92c7bb6",
+ "d73027fc8d59fee090e0f3f891bfdb4575b4",
+ "d73027fc8d59fee090ffffbfe0f3f891bfdb4575b4",
+ "d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4",
+ "d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4",
+ "a50026d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4313695",
+ "a50026d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4313695"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/diverging/RdYlGn.js b/node_modules/d3-scale-chromatic/src/diverging/RdYlGn.js
new file mode 100644
index 00000000..3cd897e1
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/diverging/RdYlGn.js
@@ -0,0 +1,16 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "fc8d59ffffbf91cf60",
+ "d7191cfdae61a6d96a1a9641",
+ "d7191cfdae61ffffbfa6d96a1a9641",
+ "d73027fc8d59fee08bd9ef8b91cf601a9850",
+ "d73027fc8d59fee08bffffbfd9ef8b91cf601a9850",
+ "d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850",
+ "d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850",
+ "a50026d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850006837",
+ "a50026d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850006837"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/diverging/Spectral.js b/node_modules/d3-scale-chromatic/src/diverging/Spectral.js
new file mode 100644
index 00000000..cd1e1085
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/diverging/Spectral.js
@@ -0,0 +1,16 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "fc8d59ffffbf99d594",
+ "d7191cfdae61abdda42b83ba",
+ "d7191cfdae61ffffbfabdda42b83ba",
+ "d53e4ffc8d59fee08be6f59899d5943288bd",
+ "d53e4ffc8d59fee08bffffbfe6f59899d5943288bd",
+ "d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd",
+ "d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd",
+ "9e0142d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd5e4fa2",
+ "9e0142d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd5e4fa2"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/index.js b/node_modules/d3-scale-chromatic/src/index.js
new file mode 100644
index 00000000..3170296b
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/index.js
@@ -0,0 +1,43 @@
+export {default as schemeCategory10} from "./categorical/category10.js";
+export {default as schemeAccent} from "./categorical/Accent.js";
+export {default as schemeDark2} from "./categorical/Dark2.js";
+export {default as schemePaired} from "./categorical/Paired.js";
+export {default as schemePastel1} from "./categorical/Pastel1.js";
+export {default as schemePastel2} from "./categorical/Pastel2.js";
+export {default as schemeSet1} from "./categorical/Set1.js";
+export {default as schemeSet2} from "./categorical/Set2.js";
+export {default as schemeSet3} from "./categorical/Set3.js";
+export {default as schemeTableau10} from "./categorical/Tableau10.js";
+export {default as interpolateBrBG, scheme as schemeBrBG} from "./diverging/BrBG.js";
+export {default as interpolatePRGn, scheme as schemePRGn} from "./diverging/PRGn.js";
+export {default as interpolatePiYG, scheme as schemePiYG} from "./diverging/PiYG.js";
+export {default as interpolatePuOr, scheme as schemePuOr} from "./diverging/PuOr.js";
+export {default as interpolateRdBu, scheme as schemeRdBu} from "./diverging/RdBu.js";
+export {default as interpolateRdGy, scheme as schemeRdGy} from "./diverging/RdGy.js";
+export {default as interpolateRdYlBu, scheme as schemeRdYlBu} from "./diverging/RdYlBu.js";
+export {default as interpolateRdYlGn, scheme as schemeRdYlGn} from "./diverging/RdYlGn.js";
+export {default as interpolateSpectral, scheme as schemeSpectral} from "./diverging/Spectral.js";
+export {default as interpolateBuGn, scheme as schemeBuGn} from "./sequential-multi/BuGn.js";
+export {default as interpolateBuPu, scheme as schemeBuPu} from "./sequential-multi/BuPu.js";
+export {default as interpolateGnBu, scheme as schemeGnBu} from "./sequential-multi/GnBu.js";
+export {default as interpolateOrRd, scheme as schemeOrRd} from "./sequential-multi/OrRd.js";
+export {default as interpolatePuBuGn, scheme as schemePuBuGn} from "./sequential-multi/PuBuGn.js";
+export {default as interpolatePuBu, scheme as schemePuBu} from "./sequential-multi/PuBu.js";
+export {default as interpolatePuRd, scheme as schemePuRd} from "./sequential-multi/PuRd.js";
+export {default as interpolateRdPu, scheme as schemeRdPu} from "./sequential-multi/RdPu.js";
+export {default as interpolateYlGnBu, scheme as schemeYlGnBu} from "./sequential-multi/YlGnBu.js";
+export {default as interpolateYlGn, scheme as schemeYlGn} from "./sequential-multi/YlGn.js";
+export {default as interpolateYlOrBr, scheme as schemeYlOrBr} from "./sequential-multi/YlOrBr.js";
+export {default as interpolateYlOrRd, scheme as schemeYlOrRd} from "./sequential-multi/YlOrRd.js";
+export {default as interpolateBlues, scheme as schemeBlues} from "./sequential-single/Blues.js";
+export {default as interpolateGreens, scheme as schemeGreens} from "./sequential-single/Greens.js";
+export {default as interpolateGreys, scheme as schemeGreys} from "./sequential-single/Greys.js";
+export {default as interpolatePurples, scheme as schemePurples} from "./sequential-single/Purples.js";
+export {default as interpolateReds, scheme as schemeReds} from "./sequential-single/Reds.js";
+export {default as interpolateOranges, scheme as schemeOranges} from "./sequential-single/Oranges.js";
+export {default as interpolateCividis} from "./sequential-multi/cividis.js";
+export {default as interpolateCubehelixDefault} from "./sequential-multi/cubehelix.js";
+export {default as interpolateRainbow, warm as interpolateWarm, cool as interpolateCool} from "./sequential-multi/rainbow.js";
+export {default as interpolateSinebow} from "./sequential-multi/sinebow.js";
+export {default as interpolateTurbo} from "./sequential-multi/turbo.js";
+export {default as interpolateViridis, magma as interpolateMagma, inferno as interpolateInferno, plasma as interpolatePlasma} from "./sequential-multi/viridis.js";
diff --git a/node_modules/d3-scale-chromatic/src/ramp.js b/node_modules/d3-scale-chromatic/src/ramp.js
new file mode 100644
index 00000000..14f40508
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/ramp.js
@@ -0,0 +1,3 @@
+import {interpolateRgbBasis} from "d3-interpolate";
+
+export default scheme => interpolateRgbBasis(scheme[scheme.length - 1]);
diff --git a/node_modules/d3-scale-chromatic/src/rampClosed.js b/node_modules/d3-scale-chromatic/src/rampClosed.js
new file mode 100644
index 00000000..217d5024
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/rampClosed.js
@@ -0,0 +1,9 @@
+import {scaleSequential} from "d3-scale";
+import {interpolateRgbBasisClosed} from "d3-interpolate";
+import colors from "./colors.js";
+
+export default function(range) {
+ var s = scaleSequential(interpolateRgbBasisClosed(colors(range))).clamp(true);
+ delete s.clamp;
+ return s;
+}
diff --git a/node_modules/d3-scale-chromatic/src/sequential-multi/BuGn.js b/node_modules/d3-scale-chromatic/src/sequential-multi/BuGn.js
new file mode 100644
index 00000000..bfd4ff4a
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-multi/BuGn.js
@@ -0,0 +1,14 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "e5f5f999d8c92ca25f",
+ "edf8fbb2e2e266c2a4238b45",
+ "edf8fbb2e2e266c2a42ca25f006d2c",
+ "edf8fbccece699d8c966c2a42ca25f006d2c",
+ "edf8fbccece699d8c966c2a441ae76238b45005824",
+ "f7fcfde5f5f9ccece699d8c966c2a441ae76238b45005824",
+ "f7fcfde5f5f9ccece699d8c966c2a441ae76238b45006d2c00441b"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/sequential-multi/BuPu.js b/node_modules/d3-scale-chromatic/src/sequential-multi/BuPu.js
new file mode 100644
index 00000000..7b6b7cc8
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-multi/BuPu.js
@@ -0,0 +1,14 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "e0ecf49ebcda8856a7",
+ "edf8fbb3cde38c96c688419d",
+ "edf8fbb3cde38c96c68856a7810f7c",
+ "edf8fbbfd3e69ebcda8c96c68856a7810f7c",
+ "edf8fbbfd3e69ebcda8c96c68c6bb188419d6e016b",
+ "f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d6e016b",
+ "f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d810f7c4d004b"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/sequential-multi/GnBu.js b/node_modules/d3-scale-chromatic/src/sequential-multi/GnBu.js
new file mode 100644
index 00000000..0e1a31c6
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-multi/GnBu.js
@@ -0,0 +1,14 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "e0f3dba8ddb543a2ca",
+ "f0f9e8bae4bc7bccc42b8cbe",
+ "f0f9e8bae4bc7bccc443a2ca0868ac",
+ "f0f9e8ccebc5a8ddb57bccc443a2ca0868ac",
+ "f0f9e8ccebc5a8ddb57bccc44eb3d32b8cbe08589e",
+ "f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe08589e",
+ "f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe0868ac084081"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/sequential-multi/OrRd.js b/node_modules/d3-scale-chromatic/src/sequential-multi/OrRd.js
new file mode 100644
index 00000000..6726f75b
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-multi/OrRd.js
@@ -0,0 +1,14 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "fee8c8fdbb84e34a33",
+ "fef0d9fdcc8afc8d59d7301f",
+ "fef0d9fdcc8afc8d59e34a33b30000",
+ "fef0d9fdd49efdbb84fc8d59e34a33b30000",
+ "fef0d9fdd49efdbb84fc8d59ef6548d7301f990000",
+ "fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301f990000",
+ "fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301fb300007f0000"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/sequential-multi/PuBu.js b/node_modules/d3-scale-chromatic/src/sequential-multi/PuBu.js
new file mode 100644
index 00000000..4a632812
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-multi/PuBu.js
@@ -0,0 +1,14 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "ece7f2a6bddb2b8cbe",
+ "f1eef6bdc9e174a9cf0570b0",
+ "f1eef6bdc9e174a9cf2b8cbe045a8d",
+ "f1eef6d0d1e6a6bddb74a9cf2b8cbe045a8d",
+ "f1eef6d0d1e6a6bddb74a9cf3690c00570b0034e7b",
+ "fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0034e7b",
+ "fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0045a8d023858"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/sequential-multi/PuBuGn.js b/node_modules/d3-scale-chromatic/src/sequential-multi/PuBuGn.js
new file mode 100644
index 00000000..11a60d4c
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-multi/PuBuGn.js
@@ -0,0 +1,14 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "ece2f0a6bddb1c9099",
+ "f6eff7bdc9e167a9cf02818a",
+ "f6eff7bdc9e167a9cf1c9099016c59",
+ "f6eff7d0d1e6a6bddb67a9cf1c9099016c59",
+ "f6eff7d0d1e6a6bddb67a9cf3690c002818a016450",
+ "fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016450",
+ "fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016c59014636"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/sequential-multi/PuRd.js b/node_modules/d3-scale-chromatic/src/sequential-multi/PuRd.js
new file mode 100644
index 00000000..2d9e1435
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-multi/PuRd.js
@@ -0,0 +1,14 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "e7e1efc994c7dd1c77",
+ "f1eef6d7b5d8df65b0ce1256",
+ "f1eef6d7b5d8df65b0dd1c77980043",
+ "f1eef6d4b9dac994c7df65b0dd1c77980043",
+ "f1eef6d4b9dac994c7df65b0e7298ace125691003f",
+ "f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125691003f",
+ "f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125698004367001f"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/sequential-multi/RdPu.js b/node_modules/d3-scale-chromatic/src/sequential-multi/RdPu.js
new file mode 100644
index 00000000..680a5b13
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-multi/RdPu.js
@@ -0,0 +1,14 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "fde0ddfa9fb5c51b8a",
+ "feebe2fbb4b9f768a1ae017e",
+ "feebe2fbb4b9f768a1c51b8a7a0177",
+ "feebe2fcc5c0fa9fb5f768a1c51b8a7a0177",
+ "feebe2fcc5c0fa9fb5f768a1dd3497ae017e7a0177",
+ "fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a0177",
+ "fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a017749006a"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/sequential-multi/YlGn.js b/node_modules/d3-scale-chromatic/src/sequential-multi/YlGn.js
new file mode 100644
index 00000000..883ce593
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-multi/YlGn.js
@@ -0,0 +1,14 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "f7fcb9addd8e31a354",
+ "ffffccc2e69978c679238443",
+ "ffffccc2e69978c67931a354006837",
+ "ffffccd9f0a3addd8e78c67931a354006837",
+ "ffffccd9f0a3addd8e78c67941ab5d238443005a32",
+ "ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443005a32",
+ "ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443006837004529"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/sequential-multi/YlGnBu.js b/node_modules/d3-scale-chromatic/src/sequential-multi/YlGnBu.js
new file mode 100644
index 00000000..d002b3d5
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-multi/YlGnBu.js
@@ -0,0 +1,14 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "edf8b17fcdbb2c7fb8",
+ "ffffcca1dab441b6c4225ea8",
+ "ffffcca1dab441b6c42c7fb8253494",
+ "ffffccc7e9b47fcdbb41b6c42c7fb8253494",
+ "ffffccc7e9b47fcdbb41b6c41d91c0225ea80c2c84",
+ "ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea80c2c84",
+ "ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea8253494081d58"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/sequential-multi/YlOrBr.js b/node_modules/d3-scale-chromatic/src/sequential-multi/YlOrBr.js
new file mode 100644
index 00000000..cb32c44a
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-multi/YlOrBr.js
@@ -0,0 +1,14 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "fff7bcfec44fd95f0e",
+ "ffffd4fed98efe9929cc4c02",
+ "ffffd4fed98efe9929d95f0e993404",
+ "ffffd4fee391fec44ffe9929d95f0e993404",
+ "ffffd4fee391fec44ffe9929ec7014cc4c028c2d04",
+ "ffffe5fff7bcfee391fec44ffe9929ec7014cc4c028c2d04",
+ "ffffe5fff7bcfee391fec44ffe9929ec7014cc4c02993404662506"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/sequential-multi/YlOrRd.js b/node_modules/d3-scale-chromatic/src/sequential-multi/YlOrRd.js
new file mode 100644
index 00000000..6c314bad
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-multi/YlOrRd.js
@@ -0,0 +1,14 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "ffeda0feb24cf03b20",
+ "ffffb2fecc5cfd8d3ce31a1c",
+ "ffffb2fecc5cfd8d3cf03b20bd0026",
+ "ffffb2fed976feb24cfd8d3cf03b20bd0026",
+ "ffffb2fed976feb24cfd8d3cfc4e2ae31a1cb10026",
+ "ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cb10026",
+ "ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cbd0026800026"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/sequential-multi/cividis.js b/node_modules/d3-scale-chromatic/src/sequential-multi/cividis.js
new file mode 100644
index 00000000..46da9aba
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-multi/cividis.js
@@ -0,0 +1,8 @@
+export default function(t) {
+ t = Math.max(0, Math.min(1, t));
+ return "rgb("
+ + Math.max(0, Math.min(255, Math.round(-4.54 - t * (35.34 - t * (2381.73 - t * (6402.7 - t * (7024.72 - t * 2710.57))))))) + ", "
+ + Math.max(0, Math.min(255, Math.round(32.49 + t * (170.73 + t * (52.82 - t * (131.46 - t * (176.58 - t * 67.37))))))) + ", "
+ + Math.max(0, Math.min(255, Math.round(81.24 + t * (442.36 - t * (2482.43 - t * (6167.24 - t * (6614.94 - t * 2475.67)))))))
+ + ")";
+}
diff --git a/node_modules/d3-scale-chromatic/src/sequential-multi/cubehelix.js b/node_modules/d3-scale-chromatic/src/sequential-multi/cubehelix.js
new file mode 100644
index 00000000..7e9be127
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-multi/cubehelix.js
@@ -0,0 +1,4 @@
+import {cubehelix} from "d3-color";
+import {interpolateCubehelixLong} from "d3-interpolate";
+
+export default interpolateCubehelixLong(cubehelix(300, 0.5, 0.0), cubehelix(-240, 0.5, 1.0));
diff --git a/node_modules/d3-scale-chromatic/src/sequential-multi/rainbow.js b/node_modules/d3-scale-chromatic/src/sequential-multi/rainbow.js
new file mode 100644
index 00000000..b33cd35a
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-multi/rainbow.js
@@ -0,0 +1,17 @@
+import {cubehelix} from "d3-color";
+import {interpolateCubehelixLong} from "d3-interpolate";
+
+export var warm = interpolateCubehelixLong(cubehelix(-100, 0.75, 0.35), cubehelix(80, 1.50, 0.8));
+
+export var cool = interpolateCubehelixLong(cubehelix(260, 0.75, 0.35), cubehelix(80, 1.50, 0.8));
+
+var c = cubehelix();
+
+export default function(t) {
+ if (t < 0 || t > 1) t -= Math.floor(t);
+ var ts = Math.abs(t - 0.5);
+ c.h = 360 * t - 100;
+ c.s = 1.5 - 1.5 * ts;
+ c.l = 0.8 - 0.9 * ts;
+ return c + "";
+}
diff --git a/node_modules/d3-scale-chromatic/src/sequential-multi/sinebow.js b/node_modules/d3-scale-chromatic/src/sequential-multi/sinebow.js
new file mode 100644
index 00000000..09eb2de9
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-multi/sinebow.js
@@ -0,0 +1,14 @@
+import {rgb} from "d3-color";
+
+var c = rgb(),
+ pi_1_3 = Math.PI / 3,
+ pi_2_3 = Math.PI * 2 / 3;
+
+export default function(t) {
+ var x;
+ t = (0.5 - t) * Math.PI;
+ c.r = 255 * (x = Math.sin(t)) * x;
+ c.g = 255 * (x = Math.sin(t + pi_1_3)) * x;
+ c.b = 255 * (x = Math.sin(t + pi_2_3)) * x;
+ return c + "";
+}
diff --git a/node_modules/d3-scale-chromatic/src/sequential-multi/turbo.js b/node_modules/d3-scale-chromatic/src/sequential-multi/turbo.js
new file mode 100644
index 00000000..31ae8a44
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-multi/turbo.js
@@ -0,0 +1,8 @@
+export default function(t) {
+ t = Math.max(0, Math.min(1, t));
+ return "rgb("
+ + Math.max(0, Math.min(255, Math.round(34.61 + t * (1172.33 - t * (10793.56 - t * (33300.12 - t * (38394.49 - t * 14825.05))))))) + ", "
+ + Math.max(0, Math.min(255, Math.round(23.31 + t * (557.33 + t * (1225.33 - t * (3574.96 - t * (1073.77 + t * 707.56))))))) + ", "
+ + Math.max(0, Math.min(255, Math.round(27.2 + t * (3211.1 - t * (15327.97 - t * (27814 - t * (22569.18 - t * 6838.66)))))))
+ + ")";
+}
diff --git a/node_modules/d3-scale-chromatic/src/sequential-multi/viridis.js b/node_modules/d3-scale-chromatic/src/sequential-multi/viridis.js
new file mode 100644
index 00000000..2eeb758f
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-multi/viridis.js
@@ -0,0 +1,16 @@
+import colors from "../colors.js";
+
+function ramp(range) {
+ var n = range.length;
+ return function(t) {
+ return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))];
+ };
+}
+
+export default ramp(colors("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725"));
+
+export var magma = ramp(colors("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf"));
+
+export var inferno = ramp(colors("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4"));
+
+export var plasma = ramp(colors("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921"));
diff --git a/node_modules/d3-scale-chromatic/src/sequential-single/Blues.js b/node_modules/d3-scale-chromatic/src/sequential-single/Blues.js
new file mode 100644
index 00000000..7acfdd31
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-single/Blues.js
@@ -0,0 +1,14 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "deebf79ecae13182bd",
+ "eff3ffbdd7e76baed62171b5",
+ "eff3ffbdd7e76baed63182bd08519c",
+ "eff3ffc6dbef9ecae16baed63182bd08519c",
+ "eff3ffc6dbef9ecae16baed64292c62171b5084594",
+ "f7fbffdeebf7c6dbef9ecae16baed64292c62171b5084594",
+ "f7fbffdeebf7c6dbef9ecae16baed64292c62171b508519c08306b"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/sequential-single/Greens.js b/node_modules/d3-scale-chromatic/src/sequential-single/Greens.js
new file mode 100644
index 00000000..48eb102e
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-single/Greens.js
@@ -0,0 +1,14 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "e5f5e0a1d99b31a354",
+ "edf8e9bae4b374c476238b45",
+ "edf8e9bae4b374c47631a354006d2c",
+ "edf8e9c7e9c0a1d99b74c47631a354006d2c",
+ "edf8e9c7e9c0a1d99b74c47641ab5d238b45005a32",
+ "f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45005a32",
+ "f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45006d2c00441b"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/sequential-single/Greys.js b/node_modules/d3-scale-chromatic/src/sequential-single/Greys.js
new file mode 100644
index 00000000..315ca0a1
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-single/Greys.js
@@ -0,0 +1,14 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "f0f0f0bdbdbd636363",
+ "f7f7f7cccccc969696525252",
+ "f7f7f7cccccc969696636363252525",
+ "f7f7f7d9d9d9bdbdbd969696636363252525",
+ "f7f7f7d9d9d9bdbdbd969696737373525252252525",
+ "fffffff0f0f0d9d9d9bdbdbd969696737373525252252525",
+ "fffffff0f0f0d9d9d9bdbdbd969696737373525252252525000000"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/sequential-single/Oranges.js b/node_modules/d3-scale-chromatic/src/sequential-single/Oranges.js
new file mode 100644
index 00000000..392bf233
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-single/Oranges.js
@@ -0,0 +1,14 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "fee6cefdae6be6550d",
+ "feeddefdbe85fd8d3cd94701",
+ "feeddefdbe85fd8d3ce6550da63603",
+ "feeddefdd0a2fdae6bfd8d3ce6550da63603",
+ "feeddefdd0a2fdae6bfd8d3cf16913d948018c2d04",
+ "fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d948018c2d04",
+ "fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d94801a636037f2704"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/sequential-single/Purples.js b/node_modules/d3-scale-chromatic/src/sequential-single/Purples.js
new file mode 100644
index 00000000..f4b22a5a
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-single/Purples.js
@@ -0,0 +1,14 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "efedf5bcbddc756bb1",
+ "f2f0f7cbc9e29e9ac86a51a3",
+ "f2f0f7cbc9e29e9ac8756bb154278f",
+ "f2f0f7dadaebbcbddc9e9ac8756bb154278f",
+ "f2f0f7dadaebbcbddc9e9ac8807dba6a51a34a1486",
+ "fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a34a1486",
+ "fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a354278f3f007d"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale-chromatic/src/sequential-single/Reds.js b/node_modules/d3-scale-chromatic/src/sequential-single/Reds.js
new file mode 100644
index 00000000..35a048fa
--- /dev/null
+++ b/node_modules/d3-scale-chromatic/src/sequential-single/Reds.js
@@ -0,0 +1,14 @@
+import colors from "../colors.js";
+import ramp from "../ramp.js";
+
+export var scheme = new Array(3).concat(
+ "fee0d2fc9272de2d26",
+ "fee5d9fcae91fb6a4acb181d",
+ "fee5d9fcae91fb6a4ade2d26a50f15",
+ "fee5d9fcbba1fc9272fb6a4ade2d26a50f15",
+ "fee5d9fcbba1fc9272fb6a4aef3b2ccb181d99000d",
+ "fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181d99000d",
+ "fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181da50f1567000d"
+).map(colors);
+
+export default ramp(scheme);
diff --git a/node_modules/d3-scale/LICENSE b/node_modules/d3-scale/LICENSE
new file mode 100644
index 00000000..b0145150
--- /dev/null
+++ b/node_modules/d3-scale/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2010-2021 Mike Bostock
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/node_modules/d3-scale/README.md b/node_modules/d3-scale/README.md
new file mode 100644
index 00000000..9024eaf9
--- /dev/null
+++ b/node_modules/d3-scale/README.md
@@ -0,0 +1,1003 @@
+# d3-scale
+
+Scales are a convenient abstraction for a fundamental task in visualization: mapping a dimension of abstract data to a visual representation. Although most often used for position-encoding quantitative data, such as mapping a measurement in meters to a position in pixels for dots in a scatterplot, scales can represent virtually any visual encoding, such as diverging colors, stroke widths, or symbol size. Scales can also be used with virtually any type of data, such as named categorical data or discrete data that requires sensible breaks.
+
+For [continuous](#continuous-scales) quantitative data, you typically want a [linear scale](#linear-scales). (For time series data, a [time scale](#time-scales).) If the distribution calls for it, consider transforming data using a [power](#power-scales) or [log](#log-scales) scale. A [quantize scale](#quantize-scales) may aid differentiation by rounding continuous data to a fixed set of discrete values; similarly, a [quantile scale](#quantile-scales) computes quantiles from a sample population, and a [threshold scale](#threshold-scales) allows you to specify arbitrary breaks in continuous data.
+
+For discrete ordinal (ordered) or categorical (unordered) data, an [ordinal scale](#ordinal-scales) specifies an explicit mapping from a set of data values to a corresponding set of visual attributes (such as colors). The related [band](#band-scales) and [point](#point-scales) scales are useful for position-encoding ordinal data, such as bars in a bar chart or dots in an categorical scatterplot.
+
+This repository does not provide color schemes; see [d3-scale-chromatic](https://github.com/d3/d3-scale-chromatic) for color schemes designed to work with d3-scale.
+
+Scales have no intrinsic visual representation. However, most scales can [generate](#continuous_ticks) and [format](#continuous_tickFormat) ticks for reference marks to aid in the construction of axes.
+
+For a longer introduction, see these recommended tutorials:
+
+* [Introducing d3-scale](https://medium.com/@mbostock/introducing-d3-scale-61980c51545f) by Mike Bostock
+
+* Chapter 7. Scales of [*Interactive Data Visualization for the Web*](http://alignedleft.com/work/d3-book) by Scott Murray
+
+* [d3: scales, and color.](https://jckr.github.io/blog/2011/08/11/d3-scales-and-color/) by Jérôme Cukier
+
+## Installing
+
+If you use npm, `npm install d3-scale`. You can also download the [latest release on GitHub](https://github.com/d3/d3-scale/releases/latest). For vanilla HTML in modern browsers, import d3-scale from Skypack:
+
+```html
+
+```
+
+For legacy environments, you can load d3-scale’s UMD bundle from an npm-based CDN such as jsDelivr; a `d3` global is exported:
+
+```html
+
+
+
+
+
+
+
+
+```
+
+(You can omit d3-time and d3-time-format if you’re not using [d3.scaleTime](#scaleTime) or [d3.scaleUtc](#scaleUtc).)
+
+## API Reference
+
+* [Continuous](#continuous-scales) ([Linear](#linear-scales), [Power](#power-scales), [Log](#log-scales), [Identity](#identity-scales), [Time](#time-scales), [Radial](#radial-scales))
+* [Sequential](#sequential-scales)
+* [Diverging](#diverging-scales)
+* [Quantize](#quantize-scales)
+* [Quantile](#quantile-scales)
+* [Threshold](#threshold-scales)
+* [Ordinal](#ordinal-scales) ([Band](#band-scales), [Point](#point-scales))
+
+### Continuous Scales
+
+Continuous scales map a continuous, quantitative input [domain](#continuous_domain) to a continuous output [range](#continuous_range). If the range is also numeric, the mapping may be [inverted](#continuous_invert). A continuous scale is not constructed directly; instead, try a [linear](#linear-scales), [power](#power-scales), [log](#log-scales), [identity](#identity-scales), [radial](#radial-scales), [time](#time-scales) or [sequential color](#sequential-scales) scale.
+
+# continuous(value) · [Source](https://github.com/d3/d3-scale/blob/master/src/continuous.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+Given a *value* from the [domain](#continuous_domain), returns the corresponding value from the [range](#continuous_range). If the given *value* is outside the domain, and [clamping](#continuous_clamp) is not enabled, the mapping may be extrapolated such that the returned value is outside the range. For example, to apply a position encoding:
+
+```js
+var x = d3.scaleLinear()
+ .domain([10, 130])
+ .range([0, 960]);
+
+x(20); // 80
+x(50); // 320
+```
+
+Or to apply a color encoding:
+
+```js
+var color = d3.scaleLinear()
+ .domain([10, 100])
+ .range(["brown", "steelblue"]);
+
+color(20); // "#9a3439"
+color(50); // "#7b5167"
+```
+
+Or, in shorthand:
+
+```js
+var x = d3.scaleLinear([10, 130], [0, 960]);
+var color = d3.scaleLinear([10, 100], ["brown", "steelblue"]);
+```
+
+# continuous.invert(value) · [Source](https://github.com/d3/d3-scale/blob/master/src/continuous.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+Given a *value* from the [range](#continuous_range), returns the corresponding value from the [domain](#continuous_domain). Inversion is useful for interaction, say to determine the data value corresponding to the position of the mouse. For example, to invert a position encoding:
+
+```js
+var x = d3.scaleLinear()
+ .domain([10, 130])
+ .range([0, 960]);
+
+x.invert(80); // 20
+x.invert(320); // 50
+```
+
+If the given *value* is outside the range, and [clamping](#continuous_clamp) is not enabled, the mapping may be extrapolated such that the returned value is outside the domain. This method is only supported if the range is numeric. If the range is not numeric, returns NaN.
+
+For a valid value *y* in the range, continuous(continuous.invert(y)) approximately equals *y*; similarly, for a valid value *x* in the domain, continuous.invert(continuous(x)) approximately equals *x*. The scale and its inverse may not be exact due to the limitations of floating point precision.
+
+# continuous.domain([domain]) · [Source](https://github.com/d3/d3-scale/blob/master/src/continuous.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+If *domain* is specified, sets the scale’s domain to the specified array of numbers. The array must contain two or more elements. If the elements in the given array are not numbers, they will be coerced to numbers. If *domain* is not specified, returns a copy of the scale’s current domain.
+
+Although continuous scales typically have two values each in their domain and range, specifying more than two values produces a piecewise scale. For example, to create a [diverging color scale](#diverging-scales) that interpolates between white and red for negative values, and white and green for positive values, say:
+
+```js
+var color = d3.scaleLinear()
+ .domain([-1, 0, 1])
+ .range(["red", "white", "green"]);
+
+color(-0.5); // "rgb(255, 128, 128)"
+color(+0.5); // "rgb(128, 192, 128)"
+```
+
+Internally, a piecewise scale performs a [binary search](https://github.com/d3/d3-array/blob/master/README.md#bisect) for the range interpolator corresponding to the given domain value. Thus, the domain must be in ascending or descending order. If the domain and range have different lengths *N* and *M*, only the first *min(N,M)* elements in each are observed.
+
+# continuous.range([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/continuous.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+If *range* is specified, sets the scale’s range to the specified array of values. The array must contain two or more elements. Unlike the [domain](#continuous_domain), elements in the given array need not be numbers; any value that is supported by the underlying [interpolator](#continuous_interpolate) will work, though note that numeric ranges are required for [invert](#continuous_invert). If *range* is not specified, returns a copy of the scale’s current range. See [*continuous*.interpolate](#continuous_interpolate) for more examples.
+
+# continuous.rangeRound([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/continuous.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+Sets the scale’s [*range*](#continuous_range) to the specified array of values while also setting the scale’s [interpolator](#continuous_interpolate) to [interpolateRound](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateRound). This is a convenience method equivalent to:
+
+```js
+continuous
+ .range(range)
+ .interpolate(d3.interpolateRound);
+```
+
+The rounding interpolator is sometimes useful for avoiding antialiasing artifacts, though also consider the [shape-rendering](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/shape-rendering) “crispEdges” styles. Note that this interpolator can only be used with numeric ranges.
+
+# continuous.clamp(clamp) · [Source](https://github.com/d3/d3-scale/blob/master/src/continuous.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+If *clamp* is specified, enables or disables clamping accordingly. If clamping is disabled and the scale is passed a value outside the [domain](#continuous_domain), the scale may return a value outside the [range](#continuous_range) through extrapolation. If clamping is enabled, the return value of the scale is always within the scale’s range. Clamping similarly applies to [*continuous*.invert](#continuous_invert). For example:
+
+```js
+var x = d3.scaleLinear()
+ .domain([10, 130])
+ .range([0, 960]);
+
+x(-10); // -160, outside range
+x.invert(-160); // -10, outside domain
+
+x.clamp(true);
+x(-10); // 0, clamped to range
+x.invert(-160); // 10, clamped to domain
+```
+
+If *clamp* is not specified, returns whether or not the scale currently clamps values to within the range.
+
+# continuous.unknown([value]) · [Source](https://github.com/d3/d3-scale/blob/master/src/continuous.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+If *value* is specified, sets the output value of the scale for undefined (or NaN) input values and returns this scale. If *value* is not specified, returns the current unknown value, which defaults to undefined.
+
+# continuous.interpolate(interpolate) · [Source](https://github.com/d3/d3-scale/blob/master/src/continuous.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+If *interpolate* is specified, sets the scale’s [range](#continuous_range) interpolator factory. This interpolator factory is used to create interpolators for each adjacent pair of values from the range; these interpolators then map a normalized domain parameter *t* in [0, 1] to the corresponding value in the range. If *factory* is not specified, returns the scale’s current interpolator factory, which defaults to [d3.interpolate](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate). See [d3-interpolate](https://github.com/d3/d3-interpolate) for more interpolators.
+
+For example, consider a diverging color scale with three colors in the range:
+
+```js
+var color = d3.scaleLinear()
+ .domain([-100, 0, +100])
+ .range(["red", "white", "green"]);
+```
+
+Two interpolators are created internally by the scale, equivalent to:
+
+```js
+var i0 = d3.interpolate("red", "white"),
+ i1 = d3.interpolate("white", "green");
+```
+
+A common reason to specify a custom interpolator is to change the color space of interpolation. For example, to use [HCL](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateHcl):
+
+```js
+var color = d3.scaleLinear()
+ .domain([10, 100])
+ .range(["brown", "steelblue"])
+ .interpolate(d3.interpolateHcl);
+```
+
+Or for [Cubehelix](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateCubehelix) with a custom gamma:
+
+```js
+var color = d3.scaleLinear()
+ .domain([10, 100])
+ .range(["brown", "steelblue"])
+ .interpolate(d3.interpolateCubehelix.gamma(3));
+```
+
+Note: the [default interpolator](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate) **may reuse return values**. For example, if the range values are objects, then the value interpolator always returns the same object, modifying it in-place. If the scale is used to set an attribute or style, this is typically acceptable (and desirable for performance); however, if you need to store the scale’s return value, you must specify your own interpolator or make a copy as appropriate.
+
+# continuous.ticks([count])
+
+Returns approximately *count* representative values from the scale’s [domain](#continuous_domain). If *count* is not specified, it defaults to 10. The returned tick values are uniformly spaced, have human-readable values (such as multiples of powers of 10), and are guaranteed to be within the extent of the domain. Ticks are often used to display reference lines, or tick marks, in conjunction with the visualized data. The specified *count* is only a hint; the scale may return more or fewer values depending on the domain. See also d3-array’s [ticks](https://github.com/d3/d3-array/blob/master/README.md#ticks).
+
+# continuous.tickFormat([count[, specifier]]) · [Source](https://github.com/d3/d3-scale/blob/master/src/tickFormat.js), [Examples](https://observablehq.com/@d3/scale-ticks)
+
+Returns a [number format](https://github.com/d3/d3-format) function suitable for displaying a tick value, automatically computing the appropriate precision based on the fixed interval between tick values. The specified *count* should have the same value as the count that is used to generate the [tick values](#continuous_ticks).
+
+An optional *specifier* allows a [custom format](https://github.com/d3/d3-format/blob/master/README.md#locale_format) where the precision of the format is automatically set by the scale as appropriate for the tick interval. For example, to format percentage change, you might say:
+
+```js
+var x = d3.scaleLinear()
+ .domain([-1, 1])
+ .range([0, 960]);
+
+var ticks = x.ticks(5),
+ tickFormat = x.tickFormat(5, "+%");
+
+ticks.map(tickFormat); // ["-100%", "-50%", "+0%", "+50%", "+100%"]
+```
+
+If *specifier* uses the format type `s`, the scale will return a [SI-prefix format](https://github.com/d3/d3-format/blob/master/README.md#locale_formatPrefix) based on the largest value in the domain. If the *specifier* already specifies a precision, this method is equivalent to [*locale*.format](https://github.com/d3/d3-format/blob/master/README.md#locale_format).
+
+See also [d3.tickFormat](#tickFormat).
+
+# continuous.nice([count]) · [Source](https://github.com/d3/d3-scale/blob/master/src/nice.js), [Examples](https://observablehq.com/@d3/d3-scalelinear)
+
+Extends the [domain](#continuous_domain) so that it starts and ends on nice round values. This method typically modifies the scale’s domain, and may only extend the bounds to the nearest round value. An optional tick *count* argument allows greater control over the step size used to extend the bounds, guaranteeing that the returned [ticks](#continuous_ticks) will exactly cover the domain. Nicing is useful if the domain is computed from data, say using [extent](https://github.com/d3/d3-array/blob/master/README.md#extent), and may be irregular. For example, for a domain of [0.201479…, 0.996679…], a nice domain might be [0.2, 1.0]. If the domain has more than two values, nicing the domain only affects the first and last value. See also d3-array’s [tickStep](https://github.com/d3/d3-array/blob/master/README.md#tickStep).
+
+Nicing a scale only modifies the current domain; it does not automatically nice domains that are subsequently set using [*continuous*.domain](#continuous_domain). You must re-nice the scale after setting the new domain, if desired.
+
+# continuous.copy() · [Source](https://github.com/d3/d3-scale/blob/master/src/continuous.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+Returns an exact copy of this scale. Changes to this scale will not affect the returned scale, and vice versa.
+
+# d3.tickFormat(start, stop, count[, specifier]) · [Source](https://github.com/d3/d3-scale/blob/master/src/tickFormat.js), [Examples](https://observablehq.com/@d3/scale-ticks)
+
+Returns a [number format](https://github.com/d3/d3-format) function suitable for displaying a tick value, automatically computing the appropriate precision based on the fixed interval between tick values, as determined by [d3.tickStep](https://github.com/d3/d3-array/blob/master/README.md#tickStep).
+
+An optional *specifier* allows a [custom format](https://github.com/d3/d3-format/blob/master/README.md#locale_format) where the precision of the format is automatically set by the scale as appropriate for the tick interval. For example, to format percentage change, you might say:
+
+```js
+var tickFormat = d3.tickFormat(-1, 1, 5, "+%");
+
+tickFormat(-0.5); // "-50%"
+```
+
+If *specifier* uses the format type `s`, the scale will return a [SI-prefix format](https://github.com/d3/d3-format/blob/master/README.md#locale_formatPrefix) based on the larger absolute value of *start* and *stop*. If the *specifier* already specifies a precision, this method is equivalent to [*locale*.format](https://github.com/d3/d3-format/blob/master/README.md#locale_format).
+
+#### Linear Scales
+
+# d3.scaleLinear([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/linear.js), [Examples](https://observablehq.com/@d3/d3-scalelinear)
+
+Constructs a new [continuous scale](#continuous-scales) with the specified [domain](#continuous_domain) and [range](#continuous_range), the [default](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate) [interpolator](#continuous_interpolate) and [clamping](#continuous_clamp) disabled. If either *domain* or *range* are not specified, each defaults to [0, 1]. Linear scales are a good default choice for continuous quantitative data because they preserve proportional differences. Each range value *y* can be expressed as a function of the domain value *x*: *y* = *mx* + *b*.
+
+#### Power Scales
+
+Power scales are similar to [linear scales](#linear-scales), except an exponential transform is applied to the input domain value before the output range value is computed. Each range value *y* can be expressed as a function of the domain value *x*: *y* = *mx^k* + *b*, where *k* is the [exponent](#pow_exponent) value. Power scales also support negative domain values, in which case the input value and the resulting output value are multiplied by -1.
+
+# d3.scalePow([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/pow.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+Constructs a new [continuous scale](#continuous-scales) with the specified [domain](#continuous_domain) and [range](#continuous_range), the [exponent](#pow_exponent) 1, the [default](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate) [interpolator](#continuous_interpolate) and [clamping](#continuous_clamp) disabled. If either *domain* or *range* are not specified, each defaults to [0, 1]. (Note that this is effectively a [linear](#linear-scales) scale until you set a different exponent.)
+
+# pow(value) · [Source](https://github.com/d3/d3-scale/blob/master/src/pow.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+See [*continuous*](#_continuous).
+
+# pow.invert(value) · [Source](https://github.com/d3/d3-scale/blob/master/src/pow.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+See [*continuous*.invert](#continuous_invert).
+
+# pow.exponent([exponent]) · [Source](https://github.com/d3/d3-scale/blob/master/src/pow.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+If *exponent* is specified, sets the current exponent to the given numeric value. If *exponent* is not specified, returns the current exponent, which defaults to 1. (Note that this is effectively a [linear](#linear-scales) scale until you set a different exponent.)
+
+# pow.domain([domain]) · [Source](https://github.com/d3/d3-scale/blob/master/src/pow.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+See [*continuous*.domain](#continuous_domain).
+
+# pow.range([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/pow.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+See [*continuous*.range](#continuous_range).
+
+# pow.rangeRound([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/pow.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+See [*continuous*.rangeRound](#continuous_rangeRound).
+
+# pow.clamp(clamp) · [Source](https://github.com/d3/d3-scale/blob/master/src/pow.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+See [*continuous*.clamp](#continuous_clamp).
+
+# pow.interpolate(interpolate) · [Source](https://github.com/d3/d3-scale/blob/master/src/pow.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+See [*continuous*.interpolate](#continuous_interpolate).
+
+# pow.ticks([count]) · [Source](https://github.com/d3/d3-scale/blob/master/src/pow.js), [Examples](https://observablehq.com/@d3/scale-ticks)
+
+See [*continuous*.ticks](#continuous_ticks).
+
+# pow.tickFormat([count[, specifier]]) · [Source](https://github.com/d3/d3-scale/blob/master/src/pow.js), [Examples](https://observablehq.com/@d3/scale-ticks)
+
+See [*continuous*.tickFormat](#continuous_tickFormat).
+
+# pow.nice([count]) · [Source](https://github.com/d3/d3-scale/blob/master/src/pow.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+See [*continuous*.nice](#continuous_nice).
+
+# pow.copy() · [Source](https://github.com/d3/d3-scale/blob/master/src/pow.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+See [*continuous*.copy](#continuous_copy).
+
+# d3.scaleSqrt([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/pow.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+Constructs a new [continuous](#continuous-scales) [power scale](#power-scales) with the specified [domain](#continuous_domain) and [range](#continuous_range), the [exponent](#pow_exponent) 0.5, the [default](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate) [interpolator](#continuous_interpolate) and [clamping](#continuous_clamp) disabled. If either *domain* or *range* are not specified, each defaults to [0, 1]. This is a convenience method equivalent to `d3.scalePow(…).exponent(0.5)`.
+
+#### Log Scales
+
+Log scales are similar to [linear scales](#linear-scales), except a logarithmic transform is applied to the input domain value before the output range value is computed. The mapping to the range value *y* can be expressed as a function of the domain value *x*: *y* = *m* log(x) + *b*.
+
+As log(0) = -∞, a log scale domain must be **strictly-positive or strictly-negative**; the domain must not include or cross zero. A log scale with a positive domain has a well-defined behavior for positive values, and a log scale with a negative domain has a well-defined behavior for negative values. (For a negative domain, input and output values are implicitly multiplied by -1.) The behavior of the scale is undefined if you pass a negative value to a log scale with a positive domain or vice versa.
+
+# d3.scaleLog([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/log.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+Constructs a new [continuous scale](#continuous-scales) with the specified [domain](#log_domain) and [range](#log_range), the [base](#log_base) 10, the [default](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate) [interpolator](#log_interpolate) and [clamping](#log_clamp) disabled. If *domain* is not specified, it defaults to [1, 10]. If *range* is not specified, it defaults to [0, 1].
+
+# log(value) · [Source](https://github.com/d3/d3-scale/blob/master/src/log.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+See [*continuous*](#_continuous).
+
+# log.invert(value) · [Source](https://github.com/d3/d3-scale/blob/master/src/log.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+See [*continuous*.invert](#continuous_invert).
+
+# log.base([base]) · [Source](https://github.com/d3/d3-scale/blob/master/src/log.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+If *base* is specified, sets the base for this logarithmic scale to the specified value. If *base* is not specified, returns the current base, which defaults to 10.
+
+# log.domain([domain]) · [Source](https://github.com/d3/d3-scale/blob/master/src/log.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+See [*continuous*.domain](#continuous_domain).
+
+# log.range([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/continuous.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+See [*continuous*.range](#continuous_range).
+
+# log.rangeRound([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/log.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+See [*continuous*.rangeRound](#continuous_rangeRound).
+
+# log.clamp(clamp) · [Source](https://github.com/d3/d3-scale/blob/master/src/log.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+See [*continuous*.clamp](#continuous_clamp).
+
+# log.interpolate(interpolate) · [Source](https://github.com/d3/d3-scale/blob/master/src/log.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+See [*continuous*.interpolate](#continuous_interpolate).
+
+# log.ticks([count]) · [Source](https://github.com/d3/d3-scale/blob/master/src/log.js), [Examples](https://observablehq.com/@d3/scale-ticks)
+
+Like [*continuous*.ticks](#continuous_ticks), but customized for a log scale. If the [base](#log_base) is an integer, the returned ticks are uniformly spaced within each integer power of base; otherwise, one tick per power of base is returned. The returned ticks are guaranteed to be within the extent of the domain. If the orders of magnitude in the [domain](#log_domain) is greater than *count*, then at most one tick per power is returned. Otherwise, the tick values are unfiltered, but note that you can use [*log*.tickFormat](#log_tickFormat) to filter the display of tick labels. If *count* is not specified, it defaults to 10.
+
+# log.tickFormat([count[, specifier]]) · [Source](https://github.com/d3/d3-scale/blob/master/src/log.js), [Examples](https://observablehq.com/@d3/scale-ticks)
+
+Like [*continuous*.tickFormat](#continuous_tickFormat), but customized for a log scale. The specified *count* typically has the same value as the count that is used to generate the [tick values](#continuous_ticks). If there are too many ticks, the formatter may return the empty string for some of the tick labels; however, note that the ticks are still shown. To disable filtering, specify a *count* of Infinity. When specifying a count, you may also provide a format *specifier* or format function. For example, to get a tick formatter that will display 20 ticks of a currency, say `log.tickFormat(20, "$,f")`. If the specifier does not have a defined precision, the precision will be set automatically by the scale, returning the appropriate format. This provides a convenient way of specifying a format whose precision will be automatically set by the scale.
+
+# log.nice() · [Source](https://github.com/d3/d3-scale/blob/master/src/log.js), [Examples](https://observablehq.com/@d3/d3-scalelinear)
+
+Like [*continuous*.nice](#continuous_nice), except extends the domain to integer powers of [base](#log_base). For example, for a domain of [0.201479…, 0.996679…], and base 10, the nice domain is [0.1, 1]. If the domain has more than two values, nicing the domain only affects the first and last value.
+
+# log.copy() · [Source](https://github.com/d3/d3-scale/blob/master/src/log.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+See [*continuous*.copy](#continuous_copy).
+
+#### Symlog Scales
+
+See [A bi-symmetric log transformation for wide-range data](https://www.researchgate.net/profile/John_Webber4/publication/233967063_A_bi-symmetric_log_transformation_for_wide-range_data/links/0fcfd50d791c85082e000000.pdf) by Webber for more.
+
+# d3.scaleSymlog([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/symlog.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+Constructs a new [continuous scale](#continuous-scales) with the specified [domain](#continuous_domain) and [range](#continuous_range), the [constant](#symlog_constant) 1, the [default](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate) [interpolator](#continuous_interpolate) and [clamping](#continuous_clamp) disabled. If *domain* is not specified, it defaults to [0, 1]. If *range* is not specified, it defaults to [0, 1].
+
+# symlog.constant([constant]) · [Source](https://github.com/d3/d3-scale/blob/master/src/symlog.js), [Examples](https://observablehq.com/@d3/continuous-scales)
+
+If *constant* is specified, sets the symlog constant to the specified number and returns this scale; otherwise returns the current value of the symlog constant, which defaults to 1. See “A bi-symmetric log transformation for wide-range data” by Webber for more.
+
+#### Identity Scales
+
+Identity scales are a special case of [linear scales](#linear-scales) where the domain and range are identical; the scale and its invert method are thus the identity function. These scales are occasionally useful when working with pixel coordinates, say in conjunction with an axis. Identity scales do not support [rangeRound](#continuous_rangeRound), [clamp](#continuous_clamp) or [interpolate](#continuous_interpolate).
+
+# d3.scaleIdentity([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/identity.js), [Examples](https://observablehq.com/@d3/d3-scalelinear)
+
+Constructs a new identity scale with the specified [domain](#continuous_domain) and [range](#continuous_range). If *range* is not specified, it defaults to [0, 1].
+
+#### Radial Scales
+
+Radial scales are a variant of [linear scales](#linear-scales) where the range is internally squared so that an input value corresponds linearly to the squared output value. These scales are useful when you want the input value to correspond to the area of a graphical mark and the mark is specified by radius, as in a radial bar chart. Radial scales do not support [interpolate](#continuous_interpolate).
+
+# d3.scaleRadial([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/radial.js), [Examples](https://observablehq.com/@d3/radial-stacked-bar-chart)
+
+Constructs a new radial scale with the specified [domain](#continuous_domain) and [range](#continuous_range). If *domain* or *range* is not specified, each defaults to [0, 1].
+
+#### Time Scales
+
+Time scales are a variant of [linear scales](#linear-scales) that have a temporal domain: domain values are coerced to [dates](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date) rather than numbers, and [invert](#continuous_invert) likewise returns a date. Time scales implement [ticks](#time_ticks) based on [calendar intervals](https://github.com/d3/d3-time), taking the pain out of generating axes for temporal domains.
+
+For example, to create a position encoding:
+
+```js
+var x = d3.scaleTime()
+ .domain([new Date(2000, 0, 1), new Date(2000, 0, 2)])
+ .range([0, 960]);
+
+x(new Date(2000, 0, 1, 5)); // 200
+x(new Date(2000, 0, 1, 16)); // 640
+x.invert(200); // Sat Jan 01 2000 05:00:00 GMT-0800 (PST)
+x.invert(640); // Sat Jan 01 2000 16:00:00 GMT-0800 (PST)
+```
+
+For a valid value *y* in the range, time(time.invert(y)) equals *y*; similarly, for a valid value *x* in the domain, time.invert(time(x)) equals *x*. The invert method is useful for interaction, say to determine the value in the domain that corresponds to the pixel location under the mouse.
+
+# d3.scaleTime([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/time.js), [Examples](https://observablehq.com/@d3/d3-scaletime)
+
+Constructs a new time scale with the specified [domain](#time_domain) and [range](#time_range), the [default](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate) [interpolator](#time_interpolate) and [clamping](#time_clamp) disabled. If *domain* is not specified, it defaults to [2000-01-01, 2000-01-02]. If *range* is not specified, it defaults to [0, 1].
+
+# time(value) · [Source](https://github.com/d3/d3-scale/blob/master/src/time.js), [Examples](https://observablehq.com/@d3/d3-scaletime)
+
+See [*continuous*](#_continuous).
+
+# time.invert(value) · [Source](https://github.com/d3/d3-scale/blob/master/src/time.js), [Examples](https://observablehq.com/@d3/d3-scaletime)
+
+See [*continuous*.invert](#continuous_invert).
+
+# time.domain([domain]) · [Source](https://github.com/d3/d3-scale/blob/master/src/time.js), [Examples](https://observablehq.com/@d3/d3-scaletime)
+
+See [*continuous*.domain](#continuous_domain).
+
+# time.range([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/time.js), [Examples](https://observablehq.com/@d3/d3-scaletime)
+
+See [*continuous*.range](#continuous_range).
+
+# time.rangeRound([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/time.js), [Examples](https://observablehq.com/@d3/d3-scaletime)
+
+See [*continuous*.rangeRound](#continuous_rangeRound).
+
+# time.clamp(clamp) · [Source](https://github.com/d3/d3-scale/blob/master/src/time.js), [Examples](https://observablehq.com/@d3/d3-scaletime)
+
+See [*continuous*.clamp](#continuous_clamp).
+
+# time.interpolate(interpolate) · [Source](https://github.com/d3/d3-scale/blob/master/src/time.js), [Examples](https://observablehq.com/@d3/d3-scaletime)
+
+See [*continuous*.interpolate](#continuous_interpolate).
+
+# time.ticks([count]) · [Source](https://github.com/d3/d3-scale/blob/master/src/time.js), [Examples](https://observablehq.com/@d3/d3-scaletime)
+
# time.ticks([interval])
+
+Returns representative dates from the scale’s [domain](#time_domain). The returned tick values are uniformly-spaced (mostly), have sensible values (such as every day at midnight), and are guaranteed to be within the extent of the domain. Ticks are often used to display reference lines, or tick marks, in conjunction with the visualized data.
+
+An optional *count* may be specified to affect how many ticks are generated. If *count* is not specified, it defaults to 10. The specified *count* is only a hint; the scale may return more or fewer values depending on the domain. For example, to create ten default ticks, say:
+
+```js
+var x = d3.scaleTime();
+
+x.ticks(10);
+// [Sat Jan 01 2000 00:00:00 GMT-0800 (PST),
+// Sat Jan 01 2000 03:00:00 GMT-0800 (PST),
+// Sat Jan 01 2000 06:00:00 GMT-0800 (PST),
+// Sat Jan 01 2000 09:00:00 GMT-0800 (PST),
+// Sat Jan 01 2000 12:00:00 GMT-0800 (PST),
+// Sat Jan 01 2000 15:00:00 GMT-0800 (PST),
+// Sat Jan 01 2000 18:00:00 GMT-0800 (PST),
+// Sat Jan 01 2000 21:00:00 GMT-0800 (PST),
+// Sun Jan 02 2000 00:00:00 GMT-0800 (PST)]
+```
+
+The following time intervals are considered for automatic ticks:
+
+* 1-, 5-, 15- and 30-second.
+* 1-, 5-, 15- and 30-minute.
+* 1-, 3-, 6- and 12-hour.
+* 1- and 2-day.
+* 1-week.
+* 1- and 3-month.
+* 1-year.
+
+In lieu of a *count*, a [time *interval*](https://github.com/d3/d3-time/blob/master/README.md#intervals) may be explicitly specified. To prune the generated ticks for a given time *interval*, use [*interval*.every](https://github.com/d3/d3-time/blob/master/README.md#interval_every). For example, to generate ticks at 15-[minute](https://github.com/d3/d3-time/blob/master/README.md#minute) intervals:
+
+```js
+var x = d3.scaleTime()
+ .domain([new Date(2000, 0, 1, 0), new Date(2000, 0, 1, 2)]);
+
+x.ticks(d3.timeMinute.every(15));
+// [Sat Jan 01 2000 00:00:00 GMT-0800 (PST),
+// Sat Jan 01 2000 00:15:00 GMT-0800 (PST),
+// Sat Jan 01 2000 00:30:00 GMT-0800 (PST),
+// Sat Jan 01 2000 00:45:00 GMT-0800 (PST),
+// Sat Jan 01 2000 01:00:00 GMT-0800 (PST),
+// Sat Jan 01 2000 01:15:00 GMT-0800 (PST),
+// Sat Jan 01 2000 01:30:00 GMT-0800 (PST),
+// Sat Jan 01 2000 01:45:00 GMT-0800 (PST),
+// Sat Jan 01 2000 02:00:00 GMT-0800 (PST)]
+```
+
+Alternatively, pass a test function to [*interval*.filter](https://github.com/d3/d3-time/blob/master/README.md#interval_filter):
+
+```js
+x.ticks(d3.timeMinute.filter(function(d) {
+ return d.getMinutes() % 15 === 0;
+}));
+```
+
+Note: in some cases, such as with day ticks, specifying a *step* can result in irregular spacing of ticks because time intervals have varying length.
+
+# time.tickFormat([count[, specifier]]) · [Source](https://github.com/d3/d3-scale/blob/master/src/time.js), [Examples](https://observablehq.com/@d3/scale-ticks)
+
# time.tickFormat([interval[, specifier]])
+
+Returns a time format function suitable for displaying [tick](#time_ticks) values. The specified *count* or *interval* is currently ignored, but is accepted for consistency with other scales such as [*continuous*.tickFormat](#continuous_tickFormat). If a format *specifier* is specified, this method is equivalent to [format](https://github.com/d3/d3-time-format/blob/master/README.md#format). If *specifier* is not specified, the default time format is returned. The default multi-scale time format chooses a human-readable representation based on the specified date as follows:
+
+* `%Y` - for year boundaries, such as `2011`.
+* `%B` - for month boundaries, such as `February`.
+* `%b %d` - for week boundaries, such as `Feb 06`.
+* `%a %d` - for day boundaries, such as `Mon 07`.
+* `%I %p` - for hour boundaries, such as `01 AM`.
+* `%I:%M` - for minute boundaries, such as `01:23`.
+* `:%S` - for second boundaries, such as `:45`.
+* `.%L` - milliseconds for all other times, such as `.012`.
+
+Although somewhat unusual, this default behavior has the benefit of providing both local and global context: for example, formatting a sequence of ticks as [11 PM, Mon 07, 01 AM] reveals information about hours, dates, and day simultaneously, rather than just the hours [11 PM, 12 AM, 01 AM]. See [d3-time-format](https://github.com/d3/d3-time-format) if you’d like to roll your own conditional time format.
+
+# time.nice([count]) · [Source](https://github.com/d3/d3-scale/blob/master/src/time.js), [Examples](https://observablehq.com/@d3/d3-scaletime)
+
# time.nice([interval])
+
+Extends the [domain](#time_domain) so that it starts and ends on nice round values. This method typically modifies the scale’s domain, and may only extend the bounds to the nearest round value. See [*continuous*.nice](#continuous_nice) for more.
+
+An optional tick *count* argument allows greater control over the step size used to extend the bounds, guaranteeing that the returned [ticks](#time_ticks) will exactly cover the domain. Alternatively, a [time *interval*](https://github.com/d3/d3-time/blob/master/README.md#intervals) may be specified to explicitly set the ticks. If an *interval* is specified, an optional *step* may also be specified to skip some ticks. For example, `time.nice(d3.timeSecond.every(10))` will extend the domain to an even ten seconds (0, 10, 20, etc.). See [*time*.ticks](#time_ticks) and [*interval*.every](https://github.com/d3/d3-time/blob/master/README.md#interval_every) for further detail.
+
+Nicing is useful if the domain is computed from data, say using [extent](https://github.com/d3/d3-array/blob/master/README.md#extent), and may be irregular. For example, for a domain of [2009-07-13T00:02, 2009-07-13T23:48], the nice domain is [2009-07-13, 2009-07-14]. If the domain has more than two values, nicing the domain only affects the first and last value.
+
+# time.copy() · [Source](https://github.com/d3/d3-scale/blob/master/src/time.js), [Examples](https://observablehq.com/@d3/d3-scaletime)
+
+See [*continuous*.copy](#continuous_copy).
+
+# d3.scaleUtc([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/utcTime.js), [Examples](https://observablehq.com/@d3/d3-scaletime)
+
+Equivalent to [scaleTime](#scaleTime), but the returned time scale operates in [Coordinated Universal Time](https://en.wikipedia.org/wiki/Coordinated_Universal_Time) rather than local time.
+
+### Sequential Scales
+
+Sequential scales, like [diverging scales](#diverging-scales), are similar to [continuous scales](#continuous-scales) in that they map a continuous, numeric input domain to a continuous output range. However, unlike continuous scales, the input domain and output range of a sequential scale always has exactly two elements, and the output range is typically specified as an interpolator rather than an array of values. These scales do not expose [invert](#continuous_invert) and [interpolate](#continuous_interpolate) methods.
+
+# d3.scaleSequential([[domain, ]interpolator]) · [Source](https://github.com/d3/d3-scale/blob/master/src/sequential.js), [Examples](https://observablehq.com/@d3/sequential-scales)
+
+Constructs a new sequential scale with the specified [*domain*](#sequential_domain) and [*interpolator*](#sequential_interpolator) function or array. If *domain* is not specified, it defaults to [0, 1]. If *interpolator* is not specified, it defaults to the identity function. When the scale is [applied](#_sequential), the interpolator will be invoked with a value typically in the range [0, 1], where 0 represents the minimum value and 1 represents the maximum value. For example, to implement the ill-advised [HSL](https://github.com/d3/d3-color/blob/master/README.md#hsl) rainbow scale:
+
+```js
+var rainbow = d3.scaleSequential(function(t) {
+ return d3.hsl(t * 360, 1, 0.5) + "";
+});
+```
+
+A more aesthetically-pleasing and perceptually-effective cyclical hue encoding is to use [d3.interpolateRainbow](https://github.com/d3/d3-scale-chromatic/blob/master/README.md#interpolateRainbow):
+
+```js
+var rainbow = d3.scaleSequential(d3.interpolateRainbow);
+```
+
+If *interpolator* is an array, it represents the scale’s two-element output range and is converted to an interpolator function using [d3.interpolate](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate).
+
+# sequential(value) · [Source](https://github.com/d3/d3-scale/blob/master/src/sequential.js), [Examples](https://observablehq.com/@d3/sequential-scales)
+
+See [*continuous*](#_continuous).
+
+# sequential.domain([domain]) · [Source](https://github.com/d3/d3-scale/blob/master/src/sequential.js), [Examples](https://observablehq.com/@d3/sequential-scales)
+
+See [*continuous*.domain](#continuous_domain). Note that a sequential scale’s domain must be numeric and must contain exactly two values.
+
+# sequential.clamp([clamp]) · [Source](https://github.com/d3/d3-scale/blob/master/src/sequential.js), [Examples](https://observablehq.com/@d3/sequential-scales)
+
+See [*continuous*.clamp](#continuous_clamp).
+
+# sequential.interpolator([interpolator]) · [Source](https://github.com/d3/d3-scale/blob/master/src/sequential.js), [Examples](https://observablehq.com/@d3/sequential-scales)
+
+If *interpolator* is specified, sets the scale’s interpolator to the specified function. If *interpolator* is not specified, returns the scale’s current interpolator.
+
+# sequential.range([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/sequential.js), [Examples](https://observablehq.com/@d3/sequential-scales)
+
+See [*continuous*.range](#continuous_range). If *range* is specified, the given two-element array is converted to an interpolator function using [d3.interpolate](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate).
+
+# sequential.rangeRound([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/sequential.js), [Examples](https://observablehq.com/@d3/sequential-scales)
+
+See [*continuous*.rangeRound](#continuous_rangeRound). If *range* is specified, implicitly uses [d3.interpolateRound](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateRound) as the interpolator.
+
+# sequential.copy() · [Source](https://github.com/d3/d3-scale/blob/master/src/sequential.js), [Examples](https://observablehq.com/@d3/sequential-scales)
+
+See [*continuous*.copy](#continuous_copy).
+
+# d3.scaleSequentialLog([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/sequential.js), [Examples](https://observablehq.com/@d3/sequential-scales)
+
+A [sequential scale](#sequential-scales) with a logarithmic transform, analogous to a [log scale](#log-scales).
+
+# d3.scaleSequentialPow([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/sequential.js), [Examples](https://observablehq.com/@d3/sequential-scales)
+
+A [sequential scale](#sequential-scales) with an exponential transform, analogous to a [power scale](#pow-scales).
+
+# d3.scaleSequentialSqrt([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/sequential.js), [Examples](https://observablehq.com/@d3/sequential-scales)
+
+A [sequential scale](#sequential-scales) with a square-root transform, analogous to a [d3.scaleSqrt](#scaleSqrt).
+
+# d3.scaleSequentialSymlog([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/sequential.js), [Examples](https://observablehq.com/@d3/sequential-scales)
+
+A [sequential scale](#sequential-scales) with a symmetric logarithmic transform, analogous to a [symlog scale](#symlog-scales).
+
+# d3.scaleSequentialQuantile([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/sequentialQuantile.js), [Examples](https://observablehq.com/@d3/sequential-scales)
+
+A [sequential scale](#sequential-scales) using a *p*-quantile transform, analogous to a [quantile scale](#quantile-scales).
+
+# sequentialQuantile.quantiles(n) · [Source](https://github.com/d3/d3-scale/blob/master/src/sequentialQuantile.js), [Examples](https://observablehq.com/@d3/sequential-scales)
+
+Returns an array of *n* + 1 quantiles. For example, if *n* = 4, returns an array of five numbers: the minimum value, the first quartile, the median, the third quartile, and the maximum.
+
+### Diverging Scales
+
+Diverging scales, like [sequential scales](#sequential-scales), are similar to [continuous scales](#continuous-scales) in that they map a continuous, numeric input domain to a continuous output range. However, unlike continuous scales, the input domain and output range of a diverging scale always has exactly three elements, and the output range is typically specified as an interpolator rather than an array of values. These scales do not expose [invert](#continuous_invert) and [interpolate](#continuous_interpolate) methods.
+
+# d3.scaleDiverging([[domain, ]interpolator]) · [Source](https://github.com/d3/d3-scale/blob/master/src/diverging.js), [Examples](https://observablehq.com/@d3/diverging-scales)
+
+Constructs a new diverging scale with the specified [*domain*](#diverging_domain) and [*interpolator*](#diverging_interpolator) function or array. If *domain* is not specified, it defaults to [0, 0.5, 1]. If *interpolator* is not specified, it defaults to the identity function. When the scale is [applied](#_diverging), the interpolator will be invoked with a value typically in the range [0, 1], where 0 represents the extreme negative value, 0.5 represents the neutral value, and 1 represents the extreme positive value. For example, using [d3.interpolateSpectral](https://github.com/d3/d3-scale-chromatic/blob/master/README.md#interpolateSpectral):
+
+```js
+var spectral = d3.scaleDiverging(d3.interpolateSpectral);
+```
+
+If *interpolator* is an array, it represents the scale’s three-element output range and is converted to an interpolator function using [d3.interpolate](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate) and [d3.piecewise](https://github.com/d3/d3-interpolate/blob/master/README.md#piecewise).
+
+# diverging(value) · [Source](https://github.com/d3/d3-scale/blob/master/src/diverging.js), [Examples](https://observablehq.com/@d3/diverging-scales)
+
+See [*continuous*](#_continuous).
+
+# diverging.domain([domain]) · [Source](https://github.com/d3/d3-scale/blob/master/src/diverging.js), [Examples](https://observablehq.com/@d3/diverging-scales)
+
+See [*continuous*.domain](#continuous_domain). Note that a diverging scale’s domain must be numeric and must contain exactly three values. The default domain is [0, 0.5, 1].
+
+# diverging.clamp([clamp]) · [Source](https://github.com/d3/d3-scale/blob/master/src/diverging.js), [Examples](https://observablehq.com/@d3/diverging-scales)
+
+See [*continuous*.clamp](#continuous_clamp).
+
+# diverging.interpolator([interpolator]) · [Source](https://github.com/d3/d3-scale/blob/master/src/diverging.js), [Examples](https://observablehq.com/@d3/diverging-scales)
+
+If *interpolator* is specified, sets the scale’s interpolator to the specified function. If *interpolator* is not specified, returns the scale’s current interpolator.
+
+# diverging.range([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/diverging.js), [Examples](https://observablehq.com/@d3/diverging-scales)
+
+See [*continuous*.range](#continuous_range). If *range* is specified, the given three-element array is converted to an interpolator function using [d3.interpolate](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolate) and [d3.piecewise](https://github.com/d3/d3-interpolate/blob/master/README.md#piecewise).
+
+# diverging.rangeRound([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/diverging.js), [Examples](https://observablehq.com/@d3/diverging-scales)
+
+See [*continuous*.range](#continuous_rangeRound). If *range* is specified, implicitly uses [d3.interpolateRound](https://github.com/d3/d3-interpolate/blob/master/README.md#interpolateRound) as the interpolator.
+
+# diverging.copy() · [Source](https://github.com/d3/d3-scale/blob/master/src/diverging.js), [Examples](https://observablehq.com/@d3/diverging-scales)
+
+See [*continuous*.copy](#continuous_copy).
+
+# diverging.unknown() · [Source](https://github.com/d3/d3-scale/blob/master/src/diverging.js), [Examples](https://observablehq.com/@d3/diverging-scales)
+
+See [*continuous*.unknown](#continuous_unknown).
+
+# d3.scaleDivergingLog([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/diverging.js), [Examples](https://observablehq.com/@d3/diverging-scales)
+
+A [diverging scale](#diverging-scales) with a logarithmic transform, analogous to a [log scale](#log-scales).
+
+# d3.scaleDivergingPow([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/diverging.js), [Examples](https://observablehq.com/@d3/diverging-scales)
+
+A [diverging scale](#diverging-scales) with an exponential transform, analogous to a [power scale](#pow-scales).
+
+# d3.scaleDivergingSqrt([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/diverging.js), [Examples](https://observablehq.com/@d3/diverging-scales)
+
+A [diverging scale](#diverging-scales) with a square-root transform, analogous to a [d3.scaleSqrt](#scaleSqrt).
+
+# d3.scaleDivergingSymlog([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/diverging.js), [Examples](https://observablehq.com/@d3/diverging-scales)
+
+A [diverging scale](#diverging-scales) with a symmetric logarithmic transform, analogous to a [symlog scale](#symlog-scales).
+
+### Quantize Scales
+
+Quantize scales are similar to [linear scales](#linear-scales), except they use a discrete rather than continuous range. The continuous input domain is divided into uniform segments based on the number of values in (*i.e.*, the cardinality of) the output range. Each range value *y* can be expressed as a quantized linear function of the domain value *x*: *y* = *m round(x)* + *b*. See [this choropleth](https://observablehq.com/@d3/choropleth) for an example.
+
+# d3.scaleQuantize([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/quantize.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+Constructs a new quantize scale with the specified [*domain*](#quantize_domain) and [*range*](#quantize_range). If either *domain* or *range* is not specified, each defaults to [0, 1]. Thus, the default quantize scale is equivalent to the [Math.round](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Math/round) function.
+
+# quantize(value) · [Source](https://github.com/d3/d3-scale/blob/master/src/quantize.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+Given a *value* in the input [domain](#quantize_domain), returns the corresponding value in the output [range](#quantize_range). For example, to apply a color encoding:
+
+```js
+var color = d3.scaleQuantize()
+ .domain([0, 1])
+ .range(["brown", "steelblue"]);
+
+color(0.49); // "brown"
+color(0.51); // "steelblue"
+```
+
+Or dividing the domain into three equally-sized parts with different range values to compute an appropriate stroke width:
+
+```js
+var width = d3.scaleQuantize()
+ .domain([10, 100])
+ .range([1, 2, 4]);
+
+width(20); // 1
+width(50); // 2
+width(80); // 4
+```
+
+# quantize.invertExtent(value) · [Source](https://github.com/d3/d3-scale/blob/master/src/quantize.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+Returns the extent of values in the [domain](#quantize_domain) [x0, x1] for the corresponding *value* in the [range](#quantize_range): the inverse of [*quantize*](#_quantize). This method is useful for interaction, say to determine the value in the domain that corresponds to the pixel location under the mouse.
+
+```js
+var width = d3.scaleQuantize()
+ .domain([10, 100])
+ .range([1, 2, 4]);
+
+width.invertExtent(2); // [40, 70]
+```
+
+# quantize.domain([domain]) · [Source](https://github.com/d3/d3-scale/blob/master/src/quantize.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+If *domain* is specified, sets the scale’s domain to the specified two-element array of numbers. If the elements in the given array are not numbers, they will be coerced to numbers. The numbers must be in ascending order or the behavior of the scale is undefined. If *domain* is not specified, returns the scale’s current domain.
+
+# quantize.range([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/quantize.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+If *range* is specified, sets the scale’s range to the specified array of values. The array may contain any number of discrete values. The elements in the given array need not be numbers; any value or type will work. If *range* is not specified, returns the scale’s current range.
+
+# quantize.ticks([count]) · [Source](https://github.com/d3/d3-scale/blob/master/src/quantize.js), [Examples](https://observablehq.com/@d3/scale-ticks)
+
+Equivalent to [*continuous*.ticks](#continuous_ticks).
+
+# quantize.tickFormat([count[, specifier]]) · [Source](https://github.com/d3/d3-scale/blob/master/src/linear.js), [Examples](https://observablehq.com/@d3/scale-ticks)
+
+Equivalent to [*continuous*.tickFormat](#continuous_tickFormat).
+
+# quantize.nice() · [Source](https://github.com/d3/d3-scale/blob/master/src/quantize.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+Equivalent to [*continuous*.nice](#continuous_nice).
+
+# quantize.thresholds() · [Source](https://github.com/d3/d3-scale/blob/master/src/quantize.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+Returns the array of computed thresholds within the [domain](#quantize_domain).
+
+# quantize.copy() · [Source](https://github.com/d3/d3-scale/blob/master/src/quantize.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+Returns an exact copy of this scale. Changes to this scale will not affect the returned scale, and vice versa.
+
+### Quantile Scales
+
+Quantile scales map a sampled input domain to a discrete range. The domain is considered continuous and thus the scale will accept any reasonable input value; however, the domain is specified as a discrete set of sample values. The number of values in (the cardinality of) the output range determines the number of quantiles that will be computed from the domain. To compute the quantiles, the domain is sorted, and treated as a [population of discrete values](https://en.wikipedia.org/wiki/Quantile#Quantiles_of_a_population); see d3-array’s [quantile](https://github.com/d3/d3-array/blob/master/README.md#quantile). See [this quantile choropleth](https://observablehq.com/@d3/quantile-choropleth) for an example.
+
+# d3.scaleQuantile([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/quantile.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+Constructs a new quantile scale with the specified [*domain*](#quantile_domain) and [*range*](#quantile_range). If either *domain* or *range* is not specified, each defaults to the empty array. The quantile scale is invalid until both a domain and range are specified.
+
+# quantile(value) · [Source](https://github.com/d3/d3-scale/blob/master/src/quantile.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+Given a *value* in the input [domain](#quantile_domain), returns the corresponding value in the output [range](#quantile_range).
+
+# quantile.invertExtent(value) · [Source](https://github.com/d3/d3-scale/blob/master/src/quantile.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+Returns the extent of values in the [domain](#quantile_domain) [x0, x1] for the corresponding *value* in the [range](#quantile_range): the inverse of [*quantile*](#_quantile). This method is useful for interaction, say to determine the value in the domain that corresponds to the pixel location under the mouse.
+
+# quantile.domain([domain]) · [Source](https://github.com/d3/d3-scale/blob/master/src/quantile.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+If *domain* is specified, sets the domain of the quantile scale to the specified set of discrete numeric values. The array must not be empty, and must contain at least one numeric value; NaN, null and undefined values are ignored and not considered part of the sample population. If the elements in the given array are not numbers, they will be coerced to numbers. A copy of the input array is sorted and stored internally. If *domain* is not specified, returns the scale’s current domain.
+
+# quantile.range([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/quantile.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+If *range* is specified, sets the discrete values in the range. The array must not be empty, and may contain any type of value. The number of values in (the cardinality, or length, of) the *range* array determines the number of quantiles that are computed. For example, to compute quartiles, *range* must be an array of four elements such as [0, 1, 2, 3]. If *range* is not specified, returns the current range.
+
+# quantile.quantiles() · [Source](https://github.com/d3/d3-scale/blob/master/src/quantile.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+Returns the quantile thresholds. If the [range](#quantile_range) contains *n* discrete values, the returned array will contain *n* - 1 thresholds. Values less than the first threshold are considered in the first quantile; values greater than or equal to the first threshold but less than the second threshold are in the second quantile, and so on. Internally, the thresholds array is used with [bisect](https://github.com/d3/d3-array/blob/master/README.md#bisect) to find the output quantile associated with the given input value.
+
+# quantile.copy() · [Source](https://github.com/d3/d3-scale/blob/master/src/quantile.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+Returns an exact copy of this scale. Changes to this scale will not affect the returned scale, and vice versa.
+
+### Threshold Scales
+
+Threshold scales are similar to [quantize scales](#quantize-scales), except they allow you to map arbitrary subsets of the domain to discrete values in the range. The input domain is still continuous, and divided into slices based on a set of threshold values. See [this choropleth](https://observablehq.com/@d3/threshold-choropleth) for an example.
+
+# d3.scaleThreshold([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/threshold.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+Constructs a new threshold scale with the specified [*domain*](#threshold_domain) and [*range*](#threshold_range). If *domain* is not specified, it defaults to [0.5]. If *range* is not specified, it defaults to [0, 1]. Thus, the default threshold scale is equivalent to the [Math.round](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Math/round) function for numbers; for example threshold(0.49) returns 0, and threshold(0.51) returns 1.
+
+# threshold(value) · [Source](https://github.com/d3/d3-scale/blob/master/src/threshold.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+Given a *value* in the input [domain](#threshold_domain), returns the corresponding value in the output [range](#threshold_range). For example:
+
+```js
+var color = d3.scaleThreshold()
+ .domain([0, 1])
+ .range(["red", "white", "green"]);
+
+color(-1); // "red"
+color(0); // "white"
+color(0.5); // "white"
+color(1); // "green"
+color(1000); // "green"
+```
+
+# threshold.invertExtent(value) · [Source](https://github.com/d3/d3-scale/blob/master/src/threshold.js), [Examples](https://observablehq.com/@d3/choropleth)
+
+Returns the extent of values in the [domain](#threshold_domain) [x0, x1] for the corresponding *value* in the [range](#threshold_range), representing the inverse mapping from range to domain. This method is useful for interaction, say to determine the value in the domain that corresponds to the pixel location under the mouse. For example:
+
+```js
+var color = d3.scaleThreshold()
+ .domain([0, 1])
+ .range(["red", "white", "green"]);
+
+color.invertExtent("red"); // [undefined, 0]
+color.invertExtent("white"); // [0, 1]
+color.invertExtent("green"); // [1, undefined]
+```
+
+# threshold.domain([domain]) · [Source](https://github.com/d3/d3-scale/blob/master/src/threshold.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+If *domain* is specified, sets the scale’s domain to the specified array of values. The values must be in ascending order or the behavior of the scale is undefined. The values are typically numbers, but any naturally ordered values (such as strings) will work; a threshold scale can be used to encode any type that is ordered. If the number of values in the scale’s range is N+1, the number of values in the scale’s domain must be N. If there are fewer than N elements in the domain, the additional values in the range are ignored. If there are more than N elements in the domain, the scale may return undefined for some inputs. If *domain* is not specified, returns the scale’s current domain.
+
+# threshold.range([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/threshold.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+If *range* is specified, sets the scale’s range to the specified array of values. If the number of values in the scale’s domain is N, the number of values in the scale’s range must be N+1. If there are fewer than N+1 elements in the range, the scale may return undefined for some inputs. If there are more than N+1 elements in the range, the additional values are ignored. The elements in the given array need not be numbers; any value or type will work. If *range* is not specified, returns the scale’s current range.
+
+# threshold.copy() · [Source](https://github.com/d3/d3-scale/blob/master/src/threshold.js), [Examples](https://observablehq.com/@d3/quantile-quantize-and-threshold-scales)
+
+Returns an exact copy of this scale. Changes to this scale will not affect the returned scale, and vice versa.
+
+### Ordinal Scales
+
+Unlike [continuous scales](#continuous-scales), ordinal scales have a discrete domain and range. For example, an ordinal scale might map a set of named categories to a set of colors, or determine the horizontal positions of columns in a column chart.
+
+# d3.scaleOrdinal([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/ordinal.js), [Examples](https://observablehq.com/@d3/d3-scaleordinal)
+
+Constructs a new ordinal scale with the specified [*domain*](#ordinal_domain) and [*range*](#ordinal_range). If *domain* is not specified, it defaults to the empty array. If *range* is not specified, it defaults to the empty array; an ordinal scale always returns undefined until a non-empty range is defined.
+
+# ordinal(value) · [Source](https://github.com/d3/d3-scale/blob/master/src/ordinal.js), [Examples](https://observablehq.com/@d3/d3-scaleordinal)
+
+Given a *value* in the input [domain](#ordinal_domain), returns the corresponding value in the output [range](#ordinal_range). If the given *value* is not in the scale’s [domain](#ordinal_domain), returns the [unknown](#ordinal_unknown); or, if the unknown value is [implicit](#scaleImplicit) (the default), then the *value* is implicitly added to the domain and the next-available value in the range is assigned to *value*, such that this and subsequent invocations of the scale given the same input *value* return the same output value.
+
+# ordinal.domain([domain]) · [Source](https://github.com/d3/d3-scale/blob/master/src/ordinal.js), [Examples](https://observablehq.com/@d3/d3-scaleordinal)
+
+If *domain* is specified, sets the domain to the specified array of values. The first element in *domain* will be mapped to the first element in the range, the second domain value to the second range value, and so on. Domain values are stored internally in an [InternMap](https://github.com/mbostock/internmap) from primitive value to index; the resulting index is then used to retrieve a value from the range. Thus, an ordinal scale’s values must be coercible to a primitive value, and the primitive domain value uniquely identifies the corresponding range value. If *domain* is not specified, this method returns the current domain.
+
+Setting the domain on an ordinal scale is optional if the [unknown value](#ordinal_unknown) is [implicit](#scaleImplicit) (the default). In this case, the domain will be inferred implicitly from usage by assigning each unique value passed to the scale a new value from the range. Note that an explicit domain is recommended to ensure deterministic behavior, as inferring the domain from usage will be dependent on ordering.
+
+# ordinal.range([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/ordinal.js), [Examples](https://observablehq.com/@d3/d3-scaleordinal)
+
+If *range* is specified, sets the range of the ordinal scale to the specified array of values. The first element in the domain will be mapped to the first element in *range*, the second domain value to the second range value, and so on. If there are fewer elements in the range than in the domain, the scale will reuse values from the start of the range. If *range* is not specified, this method returns the current range.
+
+# ordinal.unknown([value]) · [Source](https://github.com/d3/d3-scale/blob/master/src/ordinal.js), [Examples](https://observablehq.com/@d3/d3-scaleordinal)
+
+If *value* is specified, sets the output value of the scale for unknown input values and returns this scale. If *value* is not specified, returns the current unknown value, which defaults to [implicit](#scaleImplicit). The implicit value enables implicit domain construction; see [*ordinal*.domain](#ordinal_domain).
+
+# ordinal.copy() · [Source](https://github.com/d3/d3-scale/blob/master/src/ordinal.js), [Examples](https://observablehq.com/@d3/d3-scaleordinal)
+
+Returns an exact copy of this ordinal scale. Changes to this scale will not affect the returned scale, and vice versa.
+
+# d3.scaleImplicit · [Source](https://github.com/d3/d3-scale/blob/master/src/ordinal.js), [Examples](https://observablehq.com/@d3/d3-scaleordinal)
+
+A special value for [*ordinal*.unknown](#ordinal_unknown) that enables implicit domain construction: unknown values are implicitly added to the domain.
+
+#### Band Scales
+
+Band scales are like [ordinal scales](#ordinal-scales) except the output range is continuous and numeric. Discrete output values are automatically computed by the scale by dividing the continuous range into uniform bands. Band scales are typically used for bar charts with an ordinal or categorical dimension. The [unknown value](#ordinal_unknown) of a band scale is effectively undefined: they do not allow implicit domain construction.
+
+
+
+# d3.scaleBand([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scaleband)
+
+Constructs a new band scale with the specified [*domain*](#band_domain) and [*range*](#band_range), no [padding](#band_padding), no [rounding](#band_round) and center [alignment](#band_align). If *domain* is not specified, it defaults to the empty domain. If *range* is not specified, it defaults to the unit range [0, 1].
+
+# band(*value*) · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scaleband)
+
+Given a *value* in the input [domain](#band_domain), returns the start of the corresponding band derived from the output [range](#band_range). If the given *value* is not in the scale’s domain, returns undefined.
+
+# band.domain([domain]) · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scaleband)
+
+If *domain* is specified, sets the domain to the specified array of values. The first element in *domain* will be mapped to the first band, the second domain value to the second band, and so on. Domain values are stored internally in an [InternMap](https://github.com/mbostock/internmap) from primitive value to index; the resulting index is then used to determine the band. Thus, a band scale’s values must be coercible to a primitive value, and the primitive domain value uniquely identifies the corresponding band. If *domain* is not specified, this method returns the current domain.
+
+# band.range([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scaleband)
+
+If *range* is specified, sets the scale’s range to the specified two-element array of numbers. If the elements in the given array are not numbers, they will be coerced to numbers. If *range* is not specified, returns the scale’s current range, which defaults to [0, 1].
+
+# band.rangeRound([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scaleband)
+
+Sets the scale’s [*range*](#band_range) to the specified two-element array of numbers while also enabling [rounding](#band_round). This is a convenience method equivalent to:
+
+```js
+band
+ .range(range)
+ .round(true);
+```
+
+Rounding is sometimes useful for avoiding antialiasing artifacts, though also consider the [shape-rendering](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/shape-rendering) “crispEdges” styles.
+
+# band.round([round]) · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scaleband)
+
+If *round* is specified, enables or disables rounding accordingly. If rounding is enabled, the start and stop of each band will be integers. Rounding is sometimes useful for avoiding antialiasing artifacts, though also consider the [shape-rendering](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/shape-rendering) “crispEdges” styles. Note that if the width of the domain is not a multiple of the cardinality of the range, there may be leftover unused space, even without padding! Use [*band*.align](#band_align) to specify how the leftover space is distributed.
+
+# band.paddingInner([padding]) · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scaleband)
+
+If *padding* is specified, sets the inner padding to the specified number which must be less than or equal to 1. If *padding* is not specified, returns the current inner padding which defaults to 0. The inner padding specifies the proportion of the range that is reserved for blank space between bands; a value of 0 means no blank space between bands, and a value of 1 means a [bandwidth](#band_bandwidth) of zero.
+
+# band.paddingOuter([padding]) · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scaleband)
+
+If *padding* is specified, sets the outer padding to the specified number which is typically in the range [0, 1]. If *padding* is not specified, returns the current outer padding which defaults to 0. The outer padding specifies the amount of blank space, in terms of multiples of the [step](#band_step), to reserve before the first band and after the last band.
+
+# band.padding([padding]) · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scaleband)
+
+A convenience method for setting the [inner](#band_paddingInner) and [outer](#band_paddingOuter) padding to the same *padding* value. If *padding* is not specified, returns the inner padding.
+
+# band.align([align]) · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scaleband)
+
+If *align* is specified, sets the alignment to the specified value which must be in the range [0, 1]. If *align* is not specified, returns the current alignment which defaults to 0.5. The alignment specifies how outer padding is distributed in the range. A value of 0.5 indicates that the outer padding should be equally distributed before the first band and after the last band; *i.e.*, the bands should be centered within the range. A value of 0 or 1 may be used to shift the bands to one side, say to position them adjacent to an axis. For more, [see this explainer](https://observablehq.com/@d3/band-align).
+
+# band.bandwidth() · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scaleband)
+
+Returns the width of each band.
+
+# band.step() · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scaleband)
+
+Returns the distance between the starts of adjacent bands.
+
+# band.copy() · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scaleband)
+
+Returns an exact copy of this scale. Changes to this scale will not affect the returned scale, and vice versa.
+
+#### Point Scales
+
+Point scales are a variant of [band scales](#band-scales) with the bandwidth fixed to zero. Point scales are typically used for scatterplots with an ordinal or categorical dimension. The [unknown value](#ordinal_unknown) of a point scale is always undefined: they do not allow implicit domain construction.
+
+
+
+# d3.scalePoint([[domain, ]range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scalepoint)
+
+Constructs a new point scale with the specified [*domain*](#point_domain) and [*range*](#point_range), no [padding](#point_padding), no [rounding](#point_round) and center [alignment](#point_align). If *domain* is not specified, it defaults to the empty domain. If *range* is not specified, it defaults to the unit range [0, 1].
+
+# point(*value*) · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scalepoint)
+
+Given a *value* in the input [domain](#point_domain), returns the corresponding point derived from the output [range](#point_range). If the given *value* is not in the scale’s domain, returns undefined.
+
+# point.domain([domain]) · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scalepoint)
+
+If *domain* is specified, sets the domain to the specified array of values. The first element in *domain* will be mapped to the first point, the second domain value to the second point, and so on. Domain values are stored internally in an [InternMap](https://github.com/mbostock/internmap) from primitive value to index; the resulting index is then used to determine the point. Thus, a point scale’s values must be coercible to a primitive value, and the primitive domain value uniquely identifies the corresponding point. If *domain* is not specified, this method returns the current domain.
+
+# point.range([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scalepoint)
+
+If *range* is specified, sets the scale’s range to the specified two-element array of numbers. If the elements in the given array are not numbers, they will be coerced to numbers. If *range* is not specified, returns the scale’s current range, which defaults to [0, 1].
+
+# point.rangeRound([range]) · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scalepoint)
+
+Sets the scale’s [*range*](#point_range) to the specified two-element array of numbers while also enabling [rounding](#point_round). This is a convenience method equivalent to:
+
+```js
+point
+ .range(range)
+ .round(true);
+```
+
+Rounding is sometimes useful for avoiding antialiasing artifacts, though also consider the [shape-rendering](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/shape-rendering) “crispEdges” styles.
+
+# point.round([round]) · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scalepoint)
+
+If *round* is specified, enables or disables rounding accordingly. If rounding is enabled, the position of each point will be integers. Rounding is sometimes useful for avoiding antialiasing artifacts, though also consider the [shape-rendering](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/shape-rendering) “crispEdges” styles. Note that if the width of the domain is not a multiple of the cardinality of the range, there may be leftover unused space, even without padding! Use [*point*.align](#point_align) to specify how the leftover space is distributed.
+
+# point.padding([padding]) · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scalepoint)
+
+If *padding* is specified, sets the outer padding to the specified number which is typically in the range [0, 1]. If *padding* is not specified, returns the current outer padding which defaults to 0. The outer padding specifies the amount of blank space, in terms of multiples of the [step](#band_step), to reserve before the first point and after the last point. Equivalent to [*band*.paddingOuter](#band_paddingOuter).
+
+# point.align([align]) · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scalepoint)
+
+If *align* is specified, sets the alignment to the specified value which must be in the range [0, 1]. If *align* is not specified, returns the current alignment which defaults to 0.5. The alignment specifies how any leftover unused space in the range is distributed. A value of 0.5 indicates that the leftover space should be equally distributed before the first point and after the last point; *i.e.*, the points should be centered within the range. A value of 0 or 1 may be used to shift the points to one side, say to position them adjacent to an axis.
+
+# point.bandwidth() · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scalepoint)
+
+Returns zero.
+
+# point.step() · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scalepoint)
+
+Returns the distance between the starts of adjacent points.
+
+# point.copy() · [Source](https://github.com/d3/d3-scale/blob/master/src/band.js), [Examples](https://observablehq.com/@d3/d3-scalepoint)
+
+Returns an exact copy of this scale. Changes to this scale will not affect the returned scale, and vice versa.
diff --git a/node_modules/d3-scale/dist/d3-scale.js b/node_modules/d3-scale/dist/d3-scale.js
new file mode 100644
index 00000000..408d9271
--- /dev/null
+++ b/node_modules/d3-scale/dist/d3-scale.js
@@ -0,0 +1,1196 @@
+// https://d3js.org/d3-scale/ v4.0.2 Copyright 2010-2021 Mike Bostock
+(function (global, factory) {
+typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-array'), require('d3-interpolate'), require('d3-format'), require('d3-time'), require('d3-time-format')) :
+typeof define === 'function' && define.amd ? define(['exports', 'd3-array', 'd3-interpolate', 'd3-format', 'd3-time', 'd3-time-format'], factory) :
+(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}, global.d3, global.d3, global.d3, global.d3, global.d3));
+})(this, (function (exports, d3Array, d3Interpolate, d3Format, d3Time, d3TimeFormat) { 'use strict';
+
+function initRange(domain, range) {
+ switch (arguments.length) {
+ case 0: break;
+ case 1: this.range(domain); break;
+ default: this.range(range).domain(domain); break;
+ }
+ return this;
+}
+
+function initInterpolator(domain, interpolator) {
+ switch (arguments.length) {
+ case 0: break;
+ case 1: {
+ if (typeof domain === "function") this.interpolator(domain);
+ else this.range(domain);
+ break;
+ }
+ default: {
+ this.domain(domain);
+ if (typeof interpolator === "function") this.interpolator(interpolator);
+ else this.range(interpolator);
+ break;
+ }
+ }
+ return this;
+}
+
+const implicit = Symbol("implicit");
+
+function ordinal() {
+ var index = new d3Array.InternMap(),
+ domain = [],
+ range = [],
+ unknown = implicit;
+
+ function scale(d) {
+ let i = index.get(d);
+ if (i === undefined) {
+ if (unknown !== implicit) return unknown;
+ index.set(d, i = domain.push(d) - 1);
+ }
+ return range[i % range.length];
+ }
+
+ scale.domain = function(_) {
+ if (!arguments.length) return domain.slice();
+ domain = [], index = new d3Array.InternMap();
+ for (const value of _) {
+ if (index.has(value)) continue;
+ index.set(value, domain.push(value) - 1);
+ }
+ return scale;
+ };
+
+ scale.range = function(_) {
+ return arguments.length ? (range = Array.from(_), scale) : range.slice();
+ };
+
+ scale.unknown = function(_) {
+ return arguments.length ? (unknown = _, scale) : unknown;
+ };
+
+ scale.copy = function() {
+ return ordinal(domain, range).unknown(unknown);
+ };
+
+ initRange.apply(scale, arguments);
+
+ return scale;
+}
+
+function band() {
+ var scale = ordinal().unknown(undefined),
+ domain = scale.domain,
+ ordinalRange = scale.range,
+ r0 = 0,
+ r1 = 1,
+ step,
+ bandwidth,
+ round = false,
+ paddingInner = 0,
+ paddingOuter = 0,
+ align = 0.5;
+
+ delete scale.unknown;
+
+ function rescale() {
+ var n = domain().length,
+ reverse = r1 < r0,
+ start = reverse ? r1 : r0,
+ stop = reverse ? r0 : r1;
+ step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);
+ if (round) step = Math.floor(step);
+ start += (stop - start - step * (n - paddingInner)) * align;
+ bandwidth = step * (1 - paddingInner);
+ if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);
+ var values = d3Array.range(n).map(function(i) { return start + step * i; });
+ return ordinalRange(reverse ? values.reverse() : values);
+ }
+
+ scale.domain = function(_) {
+ return arguments.length ? (domain(_), rescale()) : domain();
+ };
+
+ scale.range = function(_) {
+ return arguments.length ? ([r0, r1] = _, r0 = +r0, r1 = +r1, rescale()) : [r0, r1];
+ };
+
+ scale.rangeRound = function(_) {
+ return [r0, r1] = _, r0 = +r0, r1 = +r1, round = true, rescale();
+ };
+
+ scale.bandwidth = function() {
+ return bandwidth;
+ };
+
+ scale.step = function() {
+ return step;
+ };
+
+ scale.round = function(_) {
+ return arguments.length ? (round = !!_, rescale()) : round;
+ };
+
+ scale.padding = function(_) {
+ return arguments.length ? (paddingInner = Math.min(1, paddingOuter = +_), rescale()) : paddingInner;
+ };
+
+ scale.paddingInner = function(_) {
+ return arguments.length ? (paddingInner = Math.min(1, _), rescale()) : paddingInner;
+ };
+
+ scale.paddingOuter = function(_) {
+ return arguments.length ? (paddingOuter = +_, rescale()) : paddingOuter;
+ };
+
+ scale.align = function(_) {
+ return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;
+ };
+
+ scale.copy = function() {
+ return band(domain(), [r0, r1])
+ .round(round)
+ .paddingInner(paddingInner)
+ .paddingOuter(paddingOuter)
+ .align(align);
+ };
+
+ return initRange.apply(rescale(), arguments);
+}
+
+function pointish(scale) {
+ var copy = scale.copy;
+
+ scale.padding = scale.paddingOuter;
+ delete scale.paddingInner;
+ delete scale.paddingOuter;
+
+ scale.copy = function() {
+ return pointish(copy());
+ };
+
+ return scale;
+}
+
+function point() {
+ return pointish(band.apply(null, arguments).paddingInner(1));
+}
+
+function constants(x) {
+ return function() {
+ return x;
+ };
+}
+
+function number$1(x) {
+ return +x;
+}
+
+var unit = [0, 1];
+
+function identity$1(x) {
+ return x;
+}
+
+function normalize(a, b) {
+ return (b -= (a = +a))
+ ? function(x) { return (x - a) / b; }
+ : constants(isNaN(b) ? NaN : 0.5);
+}
+
+function clamper(a, b) {
+ var t;
+ if (a > b) t = a, a = b, b = t;
+ return function(x) { return Math.max(a, Math.min(b, x)); };
+}
+
+// normalize(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].
+// interpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding range value x in [a,b].
+function bimap(domain, range, interpolate) {
+ var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1];
+ if (d1 < d0) d0 = normalize(d1, d0), r0 = interpolate(r1, r0);
+ else d0 = normalize(d0, d1), r0 = interpolate(r0, r1);
+ return function(x) { return r0(d0(x)); };
+}
+
+function polymap(domain, range, interpolate) {
+ var j = Math.min(domain.length, range.length) - 1,
+ d = new Array(j),
+ r = new Array(j),
+ i = -1;
+
+ // Reverse descending domains.
+ if (domain[j] < domain[0]) {
+ domain = domain.slice().reverse();
+ range = range.slice().reverse();
+ }
+
+ while (++i < j) {
+ d[i] = normalize(domain[i], domain[i + 1]);
+ r[i] = interpolate(range[i], range[i + 1]);
+ }
+
+ return function(x) {
+ var i = d3Array.bisect(domain, x, 1, j) - 1;
+ return r[i](d[i](x));
+ };
+}
+
+function copy$1(source, target) {
+ return target
+ .domain(source.domain())
+ .range(source.range())
+ .interpolate(source.interpolate())
+ .clamp(source.clamp())
+ .unknown(source.unknown());
+}
+
+function transformer$2() {
+ var domain = unit,
+ range = unit,
+ interpolate = d3Interpolate.interpolate,
+ transform,
+ untransform,
+ unknown,
+ clamp = identity$1,
+ piecewise,
+ output,
+ input;
+
+ function rescale() {
+ var n = Math.min(domain.length, range.length);
+ if (clamp !== identity$1) clamp = clamper(domain[0], domain[n - 1]);
+ piecewise = n > 2 ? polymap : bimap;
+ output = input = null;
+ return scale;
+ }
+
+ function scale(x) {
+ return x == null || isNaN(x = +x) ? unknown : (output || (output = piecewise(domain.map(transform), range, interpolate)))(transform(clamp(x)));
+ }
+
+ scale.invert = function(y) {
+ return clamp(untransform((input || (input = piecewise(range, domain.map(transform), d3Interpolate.interpolateNumber)))(y)));
+ };
+
+ scale.domain = function(_) {
+ return arguments.length ? (domain = Array.from(_, number$1), rescale()) : domain.slice();
+ };
+
+ scale.range = function(_) {
+ return arguments.length ? (range = Array.from(_), rescale()) : range.slice();
+ };
+
+ scale.rangeRound = function(_) {
+ return range = Array.from(_), interpolate = d3Interpolate.interpolateRound, rescale();
+ };
+
+ scale.clamp = function(_) {
+ return arguments.length ? (clamp = _ ? true : identity$1, rescale()) : clamp !== identity$1;
+ };
+
+ scale.interpolate = function(_) {
+ return arguments.length ? (interpolate = _, rescale()) : interpolate;
+ };
+
+ scale.unknown = function(_) {
+ return arguments.length ? (unknown = _, scale) : unknown;
+ };
+
+ return function(t, u) {
+ transform = t, untransform = u;
+ return rescale();
+ };
+}
+
+function continuous() {
+ return transformer$2()(identity$1, identity$1);
+}
+
+function tickFormat(start, stop, count, specifier) {
+ var step = d3Array.tickStep(start, stop, count),
+ precision;
+ specifier = d3Format.formatSpecifier(specifier == null ? ",f" : specifier);
+ switch (specifier.type) {
+ case "s": {
+ var value = Math.max(Math.abs(start), Math.abs(stop));
+ if (specifier.precision == null && !isNaN(precision = d3Format.precisionPrefix(step, value))) specifier.precision = precision;
+ return d3Format.formatPrefix(specifier, value);
+ }
+ case "":
+ case "e":
+ case "g":
+ case "p":
+ case "r": {
+ if (specifier.precision == null && !isNaN(precision = d3Format.precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e");
+ break;
+ }
+ case "f":
+ case "%": {
+ if (specifier.precision == null && !isNaN(precision = d3Format.precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2;
+ break;
+ }
+ }
+ return d3Format.format(specifier);
+}
+
+function linearish(scale) {
+ var domain = scale.domain;
+
+ scale.ticks = function(count) {
+ var d = domain();
+ return d3Array.ticks(d[0], d[d.length - 1], count == null ? 10 : count);
+ };
+
+ scale.tickFormat = function(count, specifier) {
+ var d = domain();
+ return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier);
+ };
+
+ scale.nice = function(count) {
+ if (count == null) count = 10;
+
+ var d = domain();
+ var i0 = 0;
+ var i1 = d.length - 1;
+ var start = d[i0];
+ var stop = d[i1];
+ var prestep;
+ var step;
+ var maxIter = 10;
+
+ if (stop < start) {
+ step = start, start = stop, stop = step;
+ step = i0, i0 = i1, i1 = step;
+ }
+
+ while (maxIter-- > 0) {
+ step = d3Array.tickIncrement(start, stop, count);
+ if (step === prestep) {
+ d[i0] = start;
+ d[i1] = stop;
+ return domain(d);
+ } else if (step > 0) {
+ start = Math.floor(start / step) * step;
+ stop = Math.ceil(stop / step) * step;
+ } else if (step < 0) {
+ start = Math.ceil(start * step) / step;
+ stop = Math.floor(stop * step) / step;
+ } else {
+ break;
+ }
+ prestep = step;
+ }
+
+ return scale;
+ };
+
+ return scale;
+}
+
+function linear() {
+ var scale = continuous();
+
+ scale.copy = function() {
+ return copy$1(scale, linear());
+ };
+
+ initRange.apply(scale, arguments);
+
+ return linearish(scale);
+}
+
+function identity(domain) {
+ var unknown;
+
+ function scale(x) {
+ return x == null || isNaN(x = +x) ? unknown : x;
+ }
+
+ scale.invert = scale;
+
+ scale.domain = scale.range = function(_) {
+ return arguments.length ? (domain = Array.from(_, number$1), scale) : domain.slice();
+ };
+
+ scale.unknown = function(_) {
+ return arguments.length ? (unknown = _, scale) : unknown;
+ };
+
+ scale.copy = function() {
+ return identity(domain).unknown(unknown);
+ };
+
+ domain = arguments.length ? Array.from(domain, number$1) : [0, 1];
+
+ return linearish(scale);
+}
+
+function nice(domain, interval) {
+ domain = domain.slice();
+
+ var i0 = 0,
+ i1 = domain.length - 1,
+ x0 = domain[i0],
+ x1 = domain[i1],
+ t;
+
+ if (x1 < x0) {
+ t = i0, i0 = i1, i1 = t;
+ t = x0, x0 = x1, x1 = t;
+ }
+
+ domain[i0] = interval.floor(x0);
+ domain[i1] = interval.ceil(x1);
+ return domain;
+}
+
+function transformLog(x) {
+ return Math.log(x);
+}
+
+function transformExp(x) {
+ return Math.exp(x);
+}
+
+function transformLogn(x) {
+ return -Math.log(-x);
+}
+
+function transformExpn(x) {
+ return -Math.exp(-x);
+}
+
+function pow10(x) {
+ return isFinite(x) ? +("1e" + x) : x < 0 ? 0 : x;
+}
+
+function powp(base) {
+ return base === 10 ? pow10
+ : base === Math.E ? Math.exp
+ : x => Math.pow(base, x);
+}
+
+function logp(base) {
+ return base === Math.E ? Math.log
+ : base === 10 && Math.log10
+ || base === 2 && Math.log2
+ || (base = Math.log(base), x => Math.log(x) / base);
+}
+
+function reflect(f) {
+ return (x, k) => -f(-x, k);
+}
+
+function loggish(transform) {
+ const scale = transform(transformLog, transformExp);
+ const domain = scale.domain;
+ let base = 10;
+ let logs;
+ let pows;
+
+ function rescale() {
+ logs = logp(base), pows = powp(base);
+ if (domain()[0] < 0) {
+ logs = reflect(logs), pows = reflect(pows);
+ transform(transformLogn, transformExpn);
+ } else {
+ transform(transformLog, transformExp);
+ }
+ return scale;
+ }
+
+ scale.base = function(_) {
+ return arguments.length ? (base = +_, rescale()) : base;
+ };
+
+ scale.domain = function(_) {
+ return arguments.length ? (domain(_), rescale()) : domain();
+ };
+
+ scale.ticks = count => {
+ const d = domain();
+ let u = d[0];
+ let v = d[d.length - 1];
+ const r = v < u;
+
+ if (r) ([u, v] = [v, u]);
+
+ let i = logs(u);
+ let j = logs(v);
+ let k;
+ let t;
+ const n = count == null ? 10 : +count;
+ let z = [];
+
+ if (!(base % 1) && j - i < n) {
+ i = Math.floor(i), j = Math.ceil(j);
+ if (u > 0) for (; i <= j; ++i) {
+ for (k = 1; k < base; ++k) {
+ t = i < 0 ? k / pows(-i) : k * pows(i);
+ if (t < u) continue;
+ if (t > v) break;
+ z.push(t);
+ }
+ } else for (; i <= j; ++i) {
+ for (k = base - 1; k >= 1; --k) {
+ t = i > 0 ? k / pows(-i) : k * pows(i);
+ if (t < u) continue;
+ if (t > v) break;
+ z.push(t);
+ }
+ }
+ if (z.length * 2 < n) z = d3Array.ticks(u, v, n);
+ } else {
+ z = d3Array.ticks(i, j, Math.min(j - i, n)).map(pows);
+ }
+ return r ? z.reverse() : z;
+ };
+
+ scale.tickFormat = (count, specifier) => {
+ if (count == null) count = 10;
+ if (specifier == null) specifier = base === 10 ? "s" : ",";
+ if (typeof specifier !== "function") {
+ if (!(base % 1) && (specifier = d3Format.formatSpecifier(specifier)).precision == null) specifier.trim = true;
+ specifier = d3Format.format(specifier);
+ }
+ if (count === Infinity) return specifier;
+ const k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?
+ return d => {
+ let i = d / pows(Math.round(logs(d)));
+ if (i * base < base - 0.5) i *= base;
+ return i <= k ? specifier(d) : "";
+ };
+ };
+
+ scale.nice = () => {
+ return domain(nice(domain(), {
+ floor: x => pows(Math.floor(logs(x))),
+ ceil: x => pows(Math.ceil(logs(x)))
+ }));
+ };
+
+ return scale;
+}
+
+function log() {
+ const scale = loggish(transformer$2()).domain([1, 10]);
+ scale.copy = () => copy$1(scale, log()).base(scale.base());
+ initRange.apply(scale, arguments);
+ return scale;
+}
+
+function transformSymlog(c) {
+ return function(x) {
+ return Math.sign(x) * Math.log1p(Math.abs(x / c));
+ };
+}
+
+function transformSymexp(c) {
+ return function(x) {
+ return Math.sign(x) * Math.expm1(Math.abs(x)) * c;
+ };
+}
+
+function symlogish(transform) {
+ var c = 1, scale = transform(transformSymlog(c), transformSymexp(c));
+
+ scale.constant = function(_) {
+ return arguments.length ? transform(transformSymlog(c = +_), transformSymexp(c)) : c;
+ };
+
+ return linearish(scale);
+}
+
+function symlog() {
+ var scale = symlogish(transformer$2());
+
+ scale.copy = function() {
+ return copy$1(scale, symlog()).constant(scale.constant());
+ };
+
+ return initRange.apply(scale, arguments);
+}
+
+function transformPow(exponent) {
+ return function(x) {
+ return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);
+ };
+}
+
+function transformSqrt(x) {
+ return x < 0 ? -Math.sqrt(-x) : Math.sqrt(x);
+}
+
+function transformSquare(x) {
+ return x < 0 ? -x * x : x * x;
+}
+
+function powish(transform) {
+ var scale = transform(identity$1, identity$1),
+ exponent = 1;
+
+ function rescale() {
+ return exponent === 1 ? transform(identity$1, identity$1)
+ : exponent === 0.5 ? transform(transformSqrt, transformSquare)
+ : transform(transformPow(exponent), transformPow(1 / exponent));
+ }
+
+ scale.exponent = function(_) {
+ return arguments.length ? (exponent = +_, rescale()) : exponent;
+ };
+
+ return linearish(scale);
+}
+
+function pow() {
+ var scale = powish(transformer$2());
+
+ scale.copy = function() {
+ return copy$1(scale, pow()).exponent(scale.exponent());
+ };
+
+ initRange.apply(scale, arguments);
+
+ return scale;
+}
+
+function sqrt() {
+ return pow.apply(null, arguments).exponent(0.5);
+}
+
+function square(x) {
+ return Math.sign(x) * x * x;
+}
+
+function unsquare(x) {
+ return Math.sign(x) * Math.sqrt(Math.abs(x));
+}
+
+function radial() {
+ var squared = continuous(),
+ range = [0, 1],
+ round = false,
+ unknown;
+
+ function scale(x) {
+ var y = unsquare(squared(x));
+ return isNaN(y) ? unknown : round ? Math.round(y) : y;
+ }
+
+ scale.invert = function(y) {
+ return squared.invert(square(y));
+ };
+
+ scale.domain = function(_) {
+ return arguments.length ? (squared.domain(_), scale) : squared.domain();
+ };
+
+ scale.range = function(_) {
+ return arguments.length ? (squared.range((range = Array.from(_, number$1)).map(square)), scale) : range.slice();
+ };
+
+ scale.rangeRound = function(_) {
+ return scale.range(_).round(true);
+ };
+
+ scale.round = function(_) {
+ return arguments.length ? (round = !!_, scale) : round;
+ };
+
+ scale.clamp = function(_) {
+ return arguments.length ? (squared.clamp(_), scale) : squared.clamp();
+ };
+
+ scale.unknown = function(_) {
+ return arguments.length ? (unknown = _, scale) : unknown;
+ };
+
+ scale.copy = function() {
+ return radial(squared.domain(), range)
+ .round(round)
+ .clamp(squared.clamp())
+ .unknown(unknown);
+ };
+
+ initRange.apply(scale, arguments);
+
+ return linearish(scale);
+}
+
+function quantile() {
+ var domain = [],
+ range = [],
+ thresholds = [],
+ unknown;
+
+ function rescale() {
+ var i = 0, n = Math.max(1, range.length);
+ thresholds = new Array(n - 1);
+ while (++i < n) thresholds[i - 1] = d3Array.quantileSorted(domain, i / n);
+ return scale;
+ }
+
+ function scale(x) {
+ return x == null || isNaN(x = +x) ? unknown : range[d3Array.bisect(thresholds, x)];
+ }
+
+ scale.invertExtent = function(y) {
+ var i = range.indexOf(y);
+ return i < 0 ? [NaN, NaN] : [
+ i > 0 ? thresholds[i - 1] : domain[0],
+ i < thresholds.length ? thresholds[i] : domain[domain.length - 1]
+ ];
+ };
+
+ scale.domain = function(_) {
+ if (!arguments.length) return domain.slice();
+ domain = [];
+ for (let d of _) if (d != null && !isNaN(d = +d)) domain.push(d);
+ domain.sort(d3Array.ascending);
+ return rescale();
+ };
+
+ scale.range = function(_) {
+ return arguments.length ? (range = Array.from(_), rescale()) : range.slice();
+ };
+
+ scale.unknown = function(_) {
+ return arguments.length ? (unknown = _, scale) : unknown;
+ };
+
+ scale.quantiles = function() {
+ return thresholds.slice();
+ };
+
+ scale.copy = function() {
+ return quantile()
+ .domain(domain)
+ .range(range)
+ .unknown(unknown);
+ };
+
+ return initRange.apply(scale, arguments);
+}
+
+function quantize() {
+ var x0 = 0,
+ x1 = 1,
+ n = 1,
+ domain = [0.5],
+ range = [0, 1],
+ unknown;
+
+ function scale(x) {
+ return x != null && x <= x ? range[d3Array.bisect(domain, x, 0, n)] : unknown;
+ }
+
+ function rescale() {
+ var i = -1;
+ domain = new Array(n);
+ while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1);
+ return scale;
+ }
+
+ scale.domain = function(_) {
+ return arguments.length ? ([x0, x1] = _, x0 = +x0, x1 = +x1, rescale()) : [x0, x1];
+ };
+
+ scale.range = function(_) {
+ return arguments.length ? (n = (range = Array.from(_)).length - 1, rescale()) : range.slice();
+ };
+
+ scale.invertExtent = function(y) {
+ var i = range.indexOf(y);
+ return i < 0 ? [NaN, NaN]
+ : i < 1 ? [x0, domain[0]]
+ : i >= n ? [domain[n - 1], x1]
+ : [domain[i - 1], domain[i]];
+ };
+
+ scale.unknown = function(_) {
+ return arguments.length ? (unknown = _, scale) : scale;
+ };
+
+ scale.thresholds = function() {
+ return domain.slice();
+ };
+
+ scale.copy = function() {
+ return quantize()
+ .domain([x0, x1])
+ .range(range)
+ .unknown(unknown);
+ };
+
+ return initRange.apply(linearish(scale), arguments);
+}
+
+function threshold() {
+ var domain = [0.5],
+ range = [0, 1],
+ unknown,
+ n = 1;
+
+ function scale(x) {
+ return x != null && x <= x ? range[d3Array.bisect(domain, x, 0, n)] : unknown;
+ }
+
+ scale.domain = function(_) {
+ return arguments.length ? (domain = Array.from(_), n = Math.min(domain.length, range.length - 1), scale) : domain.slice();
+ };
+
+ scale.range = function(_) {
+ return arguments.length ? (range = Array.from(_), n = Math.min(domain.length, range.length - 1), scale) : range.slice();
+ };
+
+ scale.invertExtent = function(y) {
+ var i = range.indexOf(y);
+ return [domain[i - 1], domain[i]];
+ };
+
+ scale.unknown = function(_) {
+ return arguments.length ? (unknown = _, scale) : unknown;
+ };
+
+ scale.copy = function() {
+ return threshold()
+ .domain(domain)
+ .range(range)
+ .unknown(unknown);
+ };
+
+ return initRange.apply(scale, arguments);
+}
+
+function date(t) {
+ return new Date(t);
+}
+
+function number(t) {
+ return t instanceof Date ? +t : +new Date(+t);
+}
+
+function calendar(ticks, tickInterval, year, month, week, day, hour, minute, second, format) {
+ var scale = continuous(),
+ invert = scale.invert,
+ domain = scale.domain;
+
+ var formatMillisecond = format(".%L"),
+ formatSecond = format(":%S"),
+ formatMinute = format("%I:%M"),
+ formatHour = format("%I %p"),
+ formatDay = format("%a %d"),
+ formatWeek = format("%b %d"),
+ formatMonth = format("%B"),
+ formatYear = format("%Y");
+
+ function tickFormat(date) {
+ return (second(date) < date ? formatMillisecond
+ : minute(date) < date ? formatSecond
+ : hour(date) < date ? formatMinute
+ : day(date) < date ? formatHour
+ : month(date) < date ? (week(date) < date ? formatDay : formatWeek)
+ : year(date) < date ? formatMonth
+ : formatYear)(date);
+ }
+
+ scale.invert = function(y) {
+ return new Date(invert(y));
+ };
+
+ scale.domain = function(_) {
+ return arguments.length ? domain(Array.from(_, number)) : domain().map(date);
+ };
+
+ scale.ticks = function(interval) {
+ var d = domain();
+ return ticks(d[0], d[d.length - 1], interval == null ? 10 : interval);
+ };
+
+ scale.tickFormat = function(count, specifier) {
+ return specifier == null ? tickFormat : format(specifier);
+ };
+
+ scale.nice = function(interval) {
+ var d = domain();
+ if (!interval || typeof interval.range !== "function") interval = tickInterval(d[0], d[d.length - 1], interval == null ? 10 : interval);
+ return interval ? domain(nice(d, interval)) : scale;
+ };
+
+ scale.copy = function() {
+ return copy$1(scale, calendar(ticks, tickInterval, year, month, week, day, hour, minute, second, format));
+ };
+
+ return scale;
+}
+
+function time() {
+ return initRange.apply(calendar(d3Time.timeTicks, d3Time.timeTickInterval, d3Time.timeYear, d3Time.timeMonth, d3Time.timeWeek, d3Time.timeDay, d3Time.timeHour, d3Time.timeMinute, d3Time.timeSecond, d3TimeFormat.timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]), arguments);
+}
+
+function utcTime() {
+ return initRange.apply(calendar(d3Time.utcTicks, d3Time.utcTickInterval, d3Time.utcYear, d3Time.utcMonth, d3Time.utcWeek, d3Time.utcDay, d3Time.utcHour, d3Time.utcMinute, d3Time.utcSecond, d3TimeFormat.utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]), arguments);
+}
+
+function transformer$1() {
+ var x0 = 0,
+ x1 = 1,
+ t0,
+ t1,
+ k10,
+ transform,
+ interpolator = identity$1,
+ clamp = false,
+ unknown;
+
+ function scale(x) {
+ return x == null || isNaN(x = +x) ? unknown : interpolator(k10 === 0 ? 0.5 : (x = (transform(x) - t0) * k10, clamp ? Math.max(0, Math.min(1, x)) : x));
+ }
+
+ scale.domain = function(_) {
+ return arguments.length ? ([x0, x1] = _, t0 = transform(x0 = +x0), t1 = transform(x1 = +x1), k10 = t0 === t1 ? 0 : 1 / (t1 - t0), scale) : [x0, x1];
+ };
+
+ scale.clamp = function(_) {
+ return arguments.length ? (clamp = !!_, scale) : clamp;
+ };
+
+ scale.interpolator = function(_) {
+ return arguments.length ? (interpolator = _, scale) : interpolator;
+ };
+
+ function range(interpolate) {
+ return function(_) {
+ var r0, r1;
+ return arguments.length ? ([r0, r1] = _, interpolator = interpolate(r0, r1), scale) : [interpolator(0), interpolator(1)];
+ };
+ }
+
+ scale.range = range(d3Interpolate.interpolate);
+
+ scale.rangeRound = range(d3Interpolate.interpolateRound);
+
+ scale.unknown = function(_) {
+ return arguments.length ? (unknown = _, scale) : unknown;
+ };
+
+ return function(t) {
+ transform = t, t0 = t(x0), t1 = t(x1), k10 = t0 === t1 ? 0 : 1 / (t1 - t0);
+ return scale;
+ };
+}
+
+function copy(source, target) {
+ return target
+ .domain(source.domain())
+ .interpolator(source.interpolator())
+ .clamp(source.clamp())
+ .unknown(source.unknown());
+}
+
+function sequential() {
+ var scale = linearish(transformer$1()(identity$1));
+
+ scale.copy = function() {
+ return copy(scale, sequential());
+ };
+
+ return initInterpolator.apply(scale, arguments);
+}
+
+function sequentialLog() {
+ var scale = loggish(transformer$1()).domain([1, 10]);
+
+ scale.copy = function() {
+ return copy(scale, sequentialLog()).base(scale.base());
+ };
+
+ return initInterpolator.apply(scale, arguments);
+}
+
+function sequentialSymlog() {
+ var scale = symlogish(transformer$1());
+
+ scale.copy = function() {
+ return copy(scale, sequentialSymlog()).constant(scale.constant());
+ };
+
+ return initInterpolator.apply(scale, arguments);
+}
+
+function sequentialPow() {
+ var scale = powish(transformer$1());
+
+ scale.copy = function() {
+ return copy(scale, sequentialPow()).exponent(scale.exponent());
+ };
+
+ return initInterpolator.apply(scale, arguments);
+}
+
+function sequentialSqrt() {
+ return sequentialPow.apply(null, arguments).exponent(0.5);
+}
+
+function sequentialQuantile() {
+ var domain = [],
+ interpolator = identity$1;
+
+ function scale(x) {
+ if (x != null && !isNaN(x = +x)) return interpolator((d3Array.bisect(domain, x, 1) - 1) / (domain.length - 1));
+ }
+
+ scale.domain = function(_) {
+ if (!arguments.length) return domain.slice();
+ domain = [];
+ for (let d of _) if (d != null && !isNaN(d = +d)) domain.push(d);
+ domain.sort(d3Array.ascending);
+ return scale;
+ };
+
+ scale.interpolator = function(_) {
+ return arguments.length ? (interpolator = _, scale) : interpolator;
+ };
+
+ scale.range = function() {
+ return domain.map((d, i) => interpolator(i / (domain.length - 1)));
+ };
+
+ scale.quantiles = function(n) {
+ return Array.from({length: n + 1}, (_, i) => d3Array.quantile(domain, i / n));
+ };
+
+ scale.copy = function() {
+ return sequentialQuantile(interpolator).domain(domain);
+ };
+
+ return initInterpolator.apply(scale, arguments);
+}
+
+function transformer() {
+ var x0 = 0,
+ x1 = 0.5,
+ x2 = 1,
+ s = 1,
+ t0,
+ t1,
+ t2,
+ k10,
+ k21,
+ interpolator = identity$1,
+ transform,
+ clamp = false,
+ unknown;
+
+ function scale(x) {
+ return isNaN(x = +x) ? unknown : (x = 0.5 + ((x = +transform(x)) - t1) * (s * x < s * t1 ? k10 : k21), interpolator(clamp ? Math.max(0, Math.min(1, x)) : x));
+ }
+
+ scale.domain = function(_) {
+ return arguments.length ? ([x0, x1, x2] = _, t0 = transform(x0 = +x0), t1 = transform(x1 = +x1), t2 = transform(x2 = +x2), k10 = t0 === t1 ? 0 : 0.5 / (t1 - t0), k21 = t1 === t2 ? 0 : 0.5 / (t2 - t1), s = t1 < t0 ? -1 : 1, scale) : [x0, x1, x2];
+ };
+
+ scale.clamp = function(_) {
+ return arguments.length ? (clamp = !!_, scale) : clamp;
+ };
+
+ scale.interpolator = function(_) {
+ return arguments.length ? (interpolator = _, scale) : interpolator;
+ };
+
+ function range(interpolate) {
+ return function(_) {
+ var r0, r1, r2;
+ return arguments.length ? ([r0, r1, r2] = _, interpolator = d3Interpolate.piecewise(interpolate, [r0, r1, r2]), scale) : [interpolator(0), interpolator(0.5), interpolator(1)];
+ };
+ }
+
+ scale.range = range(d3Interpolate.interpolate);
+
+ scale.rangeRound = range(d3Interpolate.interpolateRound);
+
+ scale.unknown = function(_) {
+ return arguments.length ? (unknown = _, scale) : unknown;
+ };
+
+ return function(t) {
+ transform = t, t0 = t(x0), t1 = t(x1), t2 = t(x2), k10 = t0 === t1 ? 0 : 0.5 / (t1 - t0), k21 = t1 === t2 ? 0 : 0.5 / (t2 - t1), s = t1 < t0 ? -1 : 1;
+ return scale;
+ };
+}
+
+function diverging() {
+ var scale = linearish(transformer()(identity$1));
+
+ scale.copy = function() {
+ return copy(scale, diverging());
+ };
+
+ return initInterpolator.apply(scale, arguments);
+}
+
+function divergingLog() {
+ var scale = loggish(transformer()).domain([0.1, 1, 10]);
+
+ scale.copy = function() {
+ return copy(scale, divergingLog()).base(scale.base());
+ };
+
+ return initInterpolator.apply(scale, arguments);
+}
+
+function divergingSymlog() {
+ var scale = symlogish(transformer());
+
+ scale.copy = function() {
+ return copy(scale, divergingSymlog()).constant(scale.constant());
+ };
+
+ return initInterpolator.apply(scale, arguments);
+}
+
+function divergingPow() {
+ var scale = powish(transformer());
+
+ scale.copy = function() {
+ return copy(scale, divergingPow()).exponent(scale.exponent());
+ };
+
+ return initInterpolator.apply(scale, arguments);
+}
+
+function divergingSqrt() {
+ return divergingPow.apply(null, arguments).exponent(0.5);
+}
+
+exports.scaleBand = band;
+exports.scaleDiverging = diverging;
+exports.scaleDivergingLog = divergingLog;
+exports.scaleDivergingPow = divergingPow;
+exports.scaleDivergingSqrt = divergingSqrt;
+exports.scaleDivergingSymlog = divergingSymlog;
+exports.scaleIdentity = identity;
+exports.scaleImplicit = implicit;
+exports.scaleLinear = linear;
+exports.scaleLog = log;
+exports.scaleOrdinal = ordinal;
+exports.scalePoint = point;
+exports.scalePow = pow;
+exports.scaleQuantile = quantile;
+exports.scaleQuantize = quantize;
+exports.scaleRadial = radial;
+exports.scaleSequential = sequential;
+exports.scaleSequentialLog = sequentialLog;
+exports.scaleSequentialPow = sequentialPow;
+exports.scaleSequentialQuantile = sequentialQuantile;
+exports.scaleSequentialSqrt = sequentialSqrt;
+exports.scaleSequentialSymlog = sequentialSymlog;
+exports.scaleSqrt = sqrt;
+exports.scaleSymlog = symlog;
+exports.scaleThreshold = threshold;
+exports.scaleTime = time;
+exports.scaleUtc = utcTime;
+exports.tickFormat = tickFormat;
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+}));
diff --git a/node_modules/d3-scale/dist/d3-scale.min.js b/node_modules/d3-scale/dist/d3-scale.min.js
new file mode 100644
index 00000000..1612ea9f
--- /dev/null
+++ b/node_modules/d3-scale/dist/d3-scale.min.js
@@ -0,0 +1,2 @@
+// https://d3js.org/d3-scale/ v4.0.2 Copyright 2010-2021 Mike Bostock
+!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("d3-array"),require("d3-interpolate"),require("d3-format"),require("d3-time"),require("d3-time-format")):"function"==typeof define&&define.amd?define(["exports","d3-array","d3-interpolate","d3-format","d3-time","d3-time-format"],t):t((n="undefined"!=typeof globalThis?globalThis:n||self).d3=n.d3||{},n.d3,n.d3,n.d3,n.d3,n.d3)}(this,(function(n,t,r,e,u,i){"use strict";function o(n,t){switch(arguments.length){case 0:break;case 1:this.range(n);break;default:this.range(t).domain(n)}return this}function a(n,t){switch(arguments.length){case 0:break;case 1:"function"==typeof n?this.interpolator(n):this.range(n);break;default:this.domain(n),"function"==typeof t?this.interpolator(t):this.range(t)}return this}const c=Symbol("implicit");function l(){var n=new t.InternMap,r=[],e=[],u=c;function i(t){let i=n.get(t);if(void 0===i){if(u!==c)return u;n.set(t,i=r.push(t)-1)}return e[i%e.length]}return i.domain=function(e){if(!arguments.length)return r.slice();r=[],n=new t.InternMap;for(const t of e)n.has(t)||n.set(t,r.push(t)-1);return i},i.range=function(n){return arguments.length?(e=Array.from(n),i):e.slice()},i.unknown=function(n){return arguments.length?(u=n,i):u},i.copy=function(){return l(r,e).unknown(u)},o.apply(i,arguments),i}function f(){var n,r,e=l().unknown(void 0),u=e.domain,i=e.range,a=0,c=1,s=!1,p=0,h=0,g=.5;function m(){var e=u().length,o=ct&&(r=n,n=t,t=r),f=function(r){return Math.max(n,Math.min(t,r))}),u=e>2?y:d,i=o=null,m}function m(t){return null==t||isNaN(t=+t)?e:(i||(i=u(a.map(n),c,l)))(n(f(t)))}return m.invert=function(e){return f(t((o||(o=u(c,a.map(n),r.interpolateNumber)))(e)))},m.domain=function(n){return arguments.length?(a=Array.from(n,p),s()):a.slice()},m.range=function(n){return arguments.length?(c=Array.from(n),s()):c.slice()},m.rangeRound=function(n){return c=Array.from(n),l=r.interpolateRound,s()},m.clamp=function(n){return arguments.length?(f=!!n||g,s()):f!==g},m.interpolate=function(n){return arguments.length?(l=n,s()):l},m.unknown=function(n){return arguments.length?(e=n,m):e},function(r,e){return n=r,t=e,s()}}function k(){return M()(g,g)}function w(n,r,u,i){var o,a=t.tickStep(n,r,u);switch((i=e.formatSpecifier(null==i?",f":i)).type){case"s":var c=Math.max(Math.abs(n),Math.abs(r));return null!=i.precision||isNaN(o=e.precisionPrefix(a,c))||(i.precision=o),e.formatPrefix(i,c);case"":case"e":case"g":case"p":case"r":null!=i.precision||isNaN(o=e.precisionRound(a,Math.max(Math.abs(n),Math.abs(r))))||(i.precision=o-("e"===i.type));break;case"f":case"%":null!=i.precision||isNaN(o=e.precisionFixed(a))||(i.precision=o-2*("%"===i.type))}return e.format(i)}function N(n){var r=n.domain;return n.ticks=function(n){var e=r();return t.ticks(e[0],e[e.length-1],null==n?10:n)},n.tickFormat=function(n,t){var e=r();return w(e[0],e[e.length-1],null==n?10:n,t)},n.nice=function(e){null==e&&(e=10);var u,i,o=r(),a=0,c=o.length-1,l=o[a],f=o[c],s=10;for(f0;){if((i=t.tickIncrement(l,f,e))===u)return o[a]=l,o[c]=f,r(o);if(i>0)l=Math.floor(l/i)*i,f=Math.ceil(f/i)*i;else{if(!(i<0))break;l=Math.ceil(l*i)/i,f=Math.floor(f*i)/i}u=i}return n},n}function b(n,t){var r,e=0,u=(n=n.slice()).length-1,i=n[e],o=n[u];return o-n(-t,r)}function R(n){const r=n(x,q),u=r.domain;let i,o,a=10;function c(){return i=function(n){return n===Math.E?Math.log:10===n&&Math.log10||2===n&&Math.log2||(n=Math.log(n),t=>Math.log(t)/n)}(a),o=function(n){return 10===n?D:n===Math.E?Math.exp:t=>Math.pow(n,t)}(a),u()[0]<0?(i=I(i),o=I(o),n(S,A)):n(x,q),r}return r.base=function(n){return arguments.length?(a=+n,c()):a},r.domain=function(n){return arguments.length?(u(n),c()):u()},r.ticks=n=>{const r=u();let e=r[0],c=r[r.length-1];const l=c0){for(;p<=h;++p)for(f=1;fc)break;m.push(s)}}else for(;p<=h;++p)for(f=a-1;f>=1;--f)if(s=p>0?f/o(-p):f*o(p),!(sc)break;m.push(s)}2*m.length{if(null==n&&(n=10),null==t&&(t=10===a?"s":","),"function"!=typeof t&&(a%1||null!=(t=e.formatSpecifier(t)).precision||(t.trim=!0),t=e.format(t)),n===1/0)return t;const u=Math.max(1,a*n/r.ticks().length);return n=>{let r=n/o(Math.round(i(n)));return r*au(b(u(),{floor:n=>o(Math.floor(i(n))),ceil:n=>o(Math.ceil(i(n)))})),r}function T(n){return function(t){return Math.sign(t)*Math.log1p(Math.abs(t/n))}}function O(n){return function(t){return Math.sign(t)*Math.expm1(Math.abs(t))*n}}function F(n){var t=1,r=n(T(t),O(t));return r.constant=function(r){return arguments.length?n(T(t=+r),O(t)):t},N(r)}function P(n){return function(t){return t<0?-Math.pow(-t,n):Math.pow(t,n)}}function E(n){return n<0?-Math.sqrt(-n):Math.sqrt(n)}function L(n){return n<0?-n*n:n*n}function Q(n){var t=n(g,g),r=1;function e(){return 1===r?n(g,g):.5===r?n(E,L):n(P(r),P(1/r))}return t.exponent=function(n){return arguments.length?(r=+n,e()):r},N(t)}function U(){var n=Q(M());return n.copy=function(){return v(n,U()).exponent(n.exponent())},o.apply(n,arguments),n}function Y(n){return Math.sign(n)*n*n}function j(n){return Math.sign(n)*Math.sqrt(Math.abs(n))}function B(n){return new Date(n)}function C(n){return n instanceof Date?+n:+new Date(+n)}function H(n,t,r,e,u,i,o,a,c,l){var f=k(),s=f.invert,p=f.domain,h=l(".%L"),g=l(":%S"),m=l("%I:%M"),d=l("%I %p"),y=l("%a %d"),M=l("%b %d"),w=l("%B"),N=l("%Y");function x(n){return(c(n)v(t,n()).base(t.base()),o.apply(t,arguments),t},n.scaleOrdinal=l,n.scalePoint=function(){return s(f.apply(null,arguments).paddingInner(1))},n.scalePow=U,n.scaleQuantile=function n(){var r,e=[],u=[],i=[];function a(){var n=0,r=Math.max(1,u.length);for(i=new Array(r-1);++n0?i[t-1]:e[0],t=i?[a[i-1],u]:[a[t-1],a[t]]},l.unknown=function(n){return arguments.length?(r=n,l):l},l.thresholds=function(){return a.slice()},l.copy=function(){return n().domain([e,u]).range(c).unknown(r)},o.apply(N(l),arguments)},n.scaleRadial=function n(){var t,r=k(),e=[0,1],u=!1;function i(n){var e=j(r(n));return isNaN(e)?t:u?Math.round(e):e}return i.invert=function(n){return r.invert(Y(n))},i.domain=function(n){return arguments.length?(r.domain(n),i):r.domain()},i.range=function(n){return arguments.length?(r.range((e=Array.from(n,p)).map(Y)),i):e.slice()},i.rangeRound=function(n){return i.range(n).round(!0)},i.round=function(n){return arguments.length?(u=!!n,i):u},i.clamp=function(n){return arguments.length?(r.clamp(n),i):r.clamp()},i.unknown=function(n){return arguments.length?(t=n,i):t},i.copy=function(){return n(r.domain(),e).round(u).clamp(r.clamp()).unknown(t)},o.apply(i,arguments),N(i)},n.scaleSequential=function n(){var t=N(W()(g));return t.copy=function(){return _(t,n())},a.apply(t,arguments)},n.scaleSequentialLog=function n(){var t=R(W()).domain([1,10]);return t.copy=function(){return _(t,n()).base(t.base())},a.apply(t,arguments)},n.scaleSequentialPow=z,n.scaleSequentialQuantile=function n(){var r=[],e=g;function u(n){if(null!=n&&!isNaN(n=+n))return e((t.bisect(r,n,1)-1)/(r.length-1))}return u.domain=function(n){if(!arguments.length)return r.slice();r=[];for(let t of n)null==t||isNaN(t=+t)||r.push(t);return r.sort(t.ascending),u},u.interpolator=function(n){return arguments.length?(e=n,u):e},u.range=function(){return r.map(((n,t)=>e(t/(r.length-1))))},u.quantiles=function(n){return Array.from({length:n+1},((e,u)=>t.quantile(r,u/n)))},u.copy=function(){return n(e).domain(r)},a.apply(u,arguments)},n.scaleSequentialSqrt=function(){return z.apply(null,arguments).exponent(.5)},n.scaleSequentialSymlog=function n(){var t=F(W());return t.copy=function(){return _(t,n()).constant(t.constant())},a.apply(t,arguments)},n.scaleSqrt=function(){return U.apply(null,arguments).exponent(.5)},n.scaleSymlog=function n(){var t=F(M());return t.copy=function(){return v(t,n()).constant(t.constant())},o.apply(t,arguments)},n.scaleThreshold=function n(){var r,e=[.5],u=[0,1],i=1;function a(n){return null!=n&&n<=n?u[t.bisect(e,n,0,i)]:r}return a.domain=function(n){return arguments.length?(e=Array.from(n),i=Math.min(e.length,u.length-1),a):e.slice()},a.range=function(n){return arguments.length?(u=Array.from(n),i=Math.min(e.length,u.length-1),a):u.slice()},a.invertExtent=function(n){var t=u.indexOf(n);return[e[t-1],e[t]]},a.unknown=function(n){return arguments.length?(r=n,a):r},a.copy=function(){return n().domain(e).range(u).unknown(r)},o.apply(a,arguments)},n.scaleTime=function(){return o.apply(H(u.timeTicks,u.timeTickInterval,u.timeYear,u.timeMonth,u.timeWeek,u.timeDay,u.timeHour,u.timeMinute,u.timeSecond,i.timeFormat).domain([new Date(2e3,0,1),new Date(2e3,0,2)]),arguments)},n.scaleUtc=function(){return o.apply(H(u.utcTicks,u.utcTickInterval,u.utcYear,u.utcMonth,u.utcWeek,u.utcDay,u.utcHour,u.utcMinute,u.utcSecond,i.utcFormat).domain([Date.UTC(2e3,0,1),Date.UTC(2e3,0,2)]),arguments)},n.tickFormat=w,Object.defineProperty(n,"__esModule",{value:!0})}));
diff --git a/node_modules/d3-scale/package.json b/node_modules/d3-scale/package.json
new file mode 100644
index 00000000..4e7a63a7
--- /dev/null
+++ b/node_modules/d3-scale/package.json
@@ -0,0 +1,85 @@
+{
+ "_from": "d3-scale@4",
+ "_id": "d3-scale@4.0.2",
+ "_inBundle": false,
+ "_integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
+ "_location": "/d3-scale",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "range",
+ "registry": true,
+ "raw": "d3-scale@4",
+ "name": "d3-scale",
+ "escapedName": "d3-scale",
+ "rawSpec": "4",
+ "saveSpec": null,
+ "fetchSpec": "4"
+ },
+ "_requiredBy": [
+ "/d3"
+ ],
+ "_resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
+ "_shasum": "82b38e8e8ff7080764f8dcec77bd4be393689396",
+ "_spec": "d3-scale@4",
+ "_where": "C:\\Users\\colbs\\CS4241\\d3a4\\node_modules\\d3",
+ "author": {
+ "name": "Mike Bostock",
+ "url": "https://bost.ocks.org/mike"
+ },
+ "bugs": {
+ "url": "https://github.com/d3/d3-scale/issues"
+ },
+ "bundleDependencies": false,
+ "dependencies": {
+ "d3-array": "2.10.0 - 3",
+ "d3-format": "1 - 3",
+ "d3-interpolate": "1.2.0 - 3",
+ "d3-time": "2.1.1 - 3",
+ "d3-time-format": "2 - 4"
+ },
+ "deprecated": false,
+ "description": "Encodings that map abstract data to visual representation.",
+ "devDependencies": {
+ "d3-color": "1 - 3",
+ "eslint": "7",
+ "mocha": "9",
+ "rollup": "2",
+ "rollup-plugin-terser": "7"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "exports": {
+ "umd": "./dist/d3-scale.min.js",
+ "default": "./src/index.js"
+ },
+ "files": [
+ "dist/**/*.js",
+ "src/**/*.js"
+ ],
+ "homepage": "https://d3js.org/d3-scale/",
+ "jsdelivr": "dist/d3-scale.min.js",
+ "keywords": [
+ "d3",
+ "d3-module",
+ "scale",
+ "visualization"
+ ],
+ "license": "ISC",
+ "main": "src/index.js",
+ "module": "src/index.js",
+ "name": "d3-scale",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/d3/d3-scale.git"
+ },
+ "scripts": {
+ "postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -",
+ "prepublishOnly": "rm -rf dist && yarn test && rollup -c",
+ "test": "TZ=America/Los_Angeles mocha 'test/**/*-test.js' && eslint src test"
+ },
+ "sideEffects": false,
+ "type": "module",
+ "unpkg": "dist/d3-scale.min.js",
+ "version": "4.0.2"
+}
diff --git a/node_modules/d3-scale/src/band.js b/node_modules/d3-scale/src/band.js
new file mode 100644
index 00000000..88e1fbdf
--- /dev/null
+++ b/node_modules/d3-scale/src/band.js
@@ -0,0 +1,101 @@
+import {range as sequence} from "d3-array";
+import {initRange} from "./init.js";
+import ordinal from "./ordinal.js";
+
+export default function band() {
+ var scale = ordinal().unknown(undefined),
+ domain = scale.domain,
+ ordinalRange = scale.range,
+ r0 = 0,
+ r1 = 1,
+ step,
+ bandwidth,
+ round = false,
+ paddingInner = 0,
+ paddingOuter = 0,
+ align = 0.5;
+
+ delete scale.unknown;
+
+ function rescale() {
+ var n = domain().length,
+ reverse = r1 < r0,
+ start = reverse ? r1 : r0,
+ stop = reverse ? r0 : r1;
+ step = (stop - start) / Math.max(1, n - paddingInner + paddingOuter * 2);
+ if (round) step = Math.floor(step);
+ start += (stop - start - step * (n - paddingInner)) * align;
+ bandwidth = step * (1 - paddingInner);
+ if (round) start = Math.round(start), bandwidth = Math.round(bandwidth);
+ var values = sequence(n).map(function(i) { return start + step * i; });
+ return ordinalRange(reverse ? values.reverse() : values);
+ }
+
+ scale.domain = function(_) {
+ return arguments.length ? (domain(_), rescale()) : domain();
+ };
+
+ scale.range = function(_) {
+ return arguments.length ? ([r0, r1] = _, r0 = +r0, r1 = +r1, rescale()) : [r0, r1];
+ };
+
+ scale.rangeRound = function(_) {
+ return [r0, r1] = _, r0 = +r0, r1 = +r1, round = true, rescale();
+ };
+
+ scale.bandwidth = function() {
+ return bandwidth;
+ };
+
+ scale.step = function() {
+ return step;
+ };
+
+ scale.round = function(_) {
+ return arguments.length ? (round = !!_, rescale()) : round;
+ };
+
+ scale.padding = function(_) {
+ return arguments.length ? (paddingInner = Math.min(1, paddingOuter = +_), rescale()) : paddingInner;
+ };
+
+ scale.paddingInner = function(_) {
+ return arguments.length ? (paddingInner = Math.min(1, _), rescale()) : paddingInner;
+ };
+
+ scale.paddingOuter = function(_) {
+ return arguments.length ? (paddingOuter = +_, rescale()) : paddingOuter;
+ };
+
+ scale.align = function(_) {
+ return arguments.length ? (align = Math.max(0, Math.min(1, _)), rescale()) : align;
+ };
+
+ scale.copy = function() {
+ return band(domain(), [r0, r1])
+ .round(round)
+ .paddingInner(paddingInner)
+ .paddingOuter(paddingOuter)
+ .align(align);
+ };
+
+ return initRange.apply(rescale(), arguments);
+}
+
+function pointish(scale) {
+ var copy = scale.copy;
+
+ scale.padding = scale.paddingOuter;
+ delete scale.paddingInner;
+ delete scale.paddingOuter;
+
+ scale.copy = function() {
+ return pointish(copy());
+ };
+
+ return scale;
+}
+
+export function point() {
+ return pointish(band.apply(null, arguments).paddingInner(1));
+}
diff --git a/node_modules/d3-scale/src/colors.js b/node_modules/d3-scale/src/colors.js
new file mode 100644
index 00000000..b344ddb7
--- /dev/null
+++ b/node_modules/d3-scale/src/colors.js
@@ -0,0 +1,5 @@
+export default function colors(s) {
+ return s.match(/.{6}/g).map(function(x) {
+ return "#" + x;
+ });
+}
diff --git a/node_modules/d3-scale/src/constant.js b/node_modules/d3-scale/src/constant.js
new file mode 100644
index 00000000..be84feec
--- /dev/null
+++ b/node_modules/d3-scale/src/constant.js
@@ -0,0 +1,5 @@
+export default function constants(x) {
+ return function() {
+ return x;
+ };
+}
diff --git a/node_modules/d3-scale/src/continuous.js b/node_modules/d3-scale/src/continuous.js
new file mode 100644
index 00000000..d932095f
--- /dev/null
+++ b/node_modules/d3-scale/src/continuous.js
@@ -0,0 +1,125 @@
+import {bisect} from "d3-array";
+import {interpolate as interpolateValue, interpolateNumber, interpolateRound} from "d3-interpolate";
+import constant from "./constant.js";
+import number from "./number.js";
+
+var unit = [0, 1];
+
+export function identity(x) {
+ return x;
+}
+
+function normalize(a, b) {
+ return (b -= (a = +a))
+ ? function(x) { return (x - a) / b; }
+ : constant(isNaN(b) ? NaN : 0.5);
+}
+
+function clamper(a, b) {
+ var t;
+ if (a > b) t = a, a = b, b = t;
+ return function(x) { return Math.max(a, Math.min(b, x)); };
+}
+
+// normalize(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1].
+// interpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding range value x in [a,b].
+function bimap(domain, range, interpolate) {
+ var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1];
+ if (d1 < d0) d0 = normalize(d1, d0), r0 = interpolate(r1, r0);
+ else d0 = normalize(d0, d1), r0 = interpolate(r0, r1);
+ return function(x) { return r0(d0(x)); };
+}
+
+function polymap(domain, range, interpolate) {
+ var j = Math.min(domain.length, range.length) - 1,
+ d = new Array(j),
+ r = new Array(j),
+ i = -1;
+
+ // Reverse descending domains.
+ if (domain[j] < domain[0]) {
+ domain = domain.slice().reverse();
+ range = range.slice().reverse();
+ }
+
+ while (++i < j) {
+ d[i] = normalize(domain[i], domain[i + 1]);
+ r[i] = interpolate(range[i], range[i + 1]);
+ }
+
+ return function(x) {
+ var i = bisect(domain, x, 1, j) - 1;
+ return r[i](d[i](x));
+ };
+}
+
+export function copy(source, target) {
+ return target
+ .domain(source.domain())
+ .range(source.range())
+ .interpolate(source.interpolate())
+ .clamp(source.clamp())
+ .unknown(source.unknown());
+}
+
+export function transformer() {
+ var domain = unit,
+ range = unit,
+ interpolate = interpolateValue,
+ transform,
+ untransform,
+ unknown,
+ clamp = identity,
+ piecewise,
+ output,
+ input;
+
+ function rescale() {
+ var n = Math.min(domain.length, range.length);
+ if (clamp !== identity) clamp = clamper(domain[0], domain[n - 1]);
+ piecewise = n > 2 ? polymap : bimap;
+ output = input = null;
+ return scale;
+ }
+
+ function scale(x) {
+ return x == null || isNaN(x = +x) ? unknown : (output || (output = piecewise(domain.map(transform), range, interpolate)))(transform(clamp(x)));
+ }
+
+ scale.invert = function(y) {
+ return clamp(untransform((input || (input = piecewise(range, domain.map(transform), interpolateNumber)))(y)));
+ };
+
+ scale.domain = function(_) {
+ return arguments.length ? (domain = Array.from(_, number), rescale()) : domain.slice();
+ };
+
+ scale.range = function(_) {
+ return arguments.length ? (range = Array.from(_), rescale()) : range.slice();
+ };
+
+ scale.rangeRound = function(_) {
+ return range = Array.from(_), interpolate = interpolateRound, rescale();
+ };
+
+ scale.clamp = function(_) {
+ return arguments.length ? (clamp = _ ? true : identity, rescale()) : clamp !== identity;
+ };
+
+ scale.interpolate = function(_) {
+ return arguments.length ? (interpolate = _, rescale()) : interpolate;
+ };
+
+ scale.unknown = function(_) {
+ return arguments.length ? (unknown = _, scale) : unknown;
+ };
+
+ return function(t, u) {
+ transform = t, untransform = u;
+ return rescale();
+ };
+}
+
+export default function continuous() {
+ return transformer()(identity, identity);
+}
diff --git a/node_modules/d3-scale/src/diverging.js b/node_modules/d3-scale/src/diverging.js
new file mode 100644
index 00000000..f5907488
--- /dev/null
+++ b/node_modules/d3-scale/src/diverging.js
@@ -0,0 +1,104 @@
+import {interpolate, interpolateRound, piecewise} from "d3-interpolate";
+import {identity} from "./continuous.js";
+import {initInterpolator} from "./init.js";
+import {linearish} from "./linear.js";
+import {loggish} from "./log.js";
+import {copy} from "./sequential.js";
+import {symlogish} from "./symlog.js";
+import {powish} from "./pow.js";
+
+function transformer() {
+ var x0 = 0,
+ x1 = 0.5,
+ x2 = 1,
+ s = 1,
+ t0,
+ t1,
+ t2,
+ k10,
+ k21,
+ interpolator = identity,
+ transform,
+ clamp = false,
+ unknown;
+
+ function scale(x) {
+ return isNaN(x = +x) ? unknown : (x = 0.5 + ((x = +transform(x)) - t1) * (s * x < s * t1 ? k10 : k21), interpolator(clamp ? Math.max(0, Math.min(1, x)) : x));
+ }
+
+ scale.domain = function(_) {
+ return arguments.length ? ([x0, x1, x2] = _, t0 = transform(x0 = +x0), t1 = transform(x1 = +x1), t2 = transform(x2 = +x2), k10 = t0 === t1 ? 0 : 0.5 / (t1 - t0), k21 = t1 === t2 ? 0 : 0.5 / (t2 - t1), s = t1 < t0 ? -1 : 1, scale) : [x0, x1, x2];
+ };
+
+ scale.clamp = function(_) {
+ return arguments.length ? (clamp = !!_, scale) : clamp;
+ };
+
+ scale.interpolator = function(_) {
+ return arguments.length ? (interpolator = _, scale) : interpolator;
+ };
+
+ function range(interpolate) {
+ return function(_) {
+ var r0, r1, r2;
+ return arguments.length ? ([r0, r1, r2] = _, interpolator = piecewise(interpolate, [r0, r1, r2]), scale) : [interpolator(0), interpolator(0.5), interpolator(1)];
+ };
+ }
+
+ scale.range = range(interpolate);
+
+ scale.rangeRound = range(interpolateRound);
+
+ scale.unknown = function(_) {
+ return arguments.length ? (unknown = _, scale) : unknown;
+ };
+
+ return function(t) {
+ transform = t, t0 = t(x0), t1 = t(x1), t2 = t(x2), k10 = t0 === t1 ? 0 : 0.5 / (t1 - t0), k21 = t1 === t2 ? 0 : 0.5 / (t2 - t1), s = t1 < t0 ? -1 : 1;
+ return scale;
+ };
+}
+
+export default function diverging() {
+ var scale = linearish(transformer()(identity));
+
+ scale.copy = function() {
+ return copy(scale, diverging());
+ };
+
+ return initInterpolator.apply(scale, arguments);
+}
+
+export function divergingLog() {
+ var scale = loggish(transformer()).domain([0.1, 1, 10]);
+
+ scale.copy = function() {
+ return copy(scale, divergingLog()).base(scale.base());
+ };
+
+ return initInterpolator.apply(scale, arguments);
+}
+
+export function divergingSymlog() {
+ var scale = symlogish(transformer());
+
+ scale.copy = function() {
+ return copy(scale, divergingSymlog()).constant(scale.constant());
+ };
+
+ return initInterpolator.apply(scale, arguments);
+}
+
+export function divergingPow() {
+ var scale = powish(transformer());
+
+ scale.copy = function() {
+ return copy(scale, divergingPow()).exponent(scale.exponent());
+ };
+
+ return initInterpolator.apply(scale, arguments);
+}
+
+export function divergingSqrt() {
+ return divergingPow.apply(null, arguments).exponent(0.5);
+}
diff --git a/node_modules/d3-scale/src/identity.js b/node_modules/d3-scale/src/identity.js
new file mode 100644
index 00000000..e1d1da77
--- /dev/null
+++ b/node_modules/d3-scale/src/identity.js
@@ -0,0 +1,28 @@
+import {linearish} from "./linear.js";
+import number from "./number.js";
+
+export default function identity(domain) {
+ var unknown;
+
+ function scale(x) {
+ return x == null || isNaN(x = +x) ? unknown : x;
+ }
+
+ scale.invert = scale;
+
+ scale.domain = scale.range = function(_) {
+ return arguments.length ? (domain = Array.from(_, number), scale) : domain.slice();
+ };
+
+ scale.unknown = function(_) {
+ return arguments.length ? (unknown = _, scale) : unknown;
+ };
+
+ scale.copy = function() {
+ return identity(domain).unknown(unknown);
+ };
+
+ domain = arguments.length ? Array.from(domain, number) : [0, 1];
+
+ return linearish(scale);
+}
diff --git a/node_modules/d3-scale/src/index.js b/node_modules/d3-scale/src/index.js
new file mode 100644
index 00000000..510103cc
--- /dev/null
+++ b/node_modules/d3-scale/src/index.js
@@ -0,0 +1,78 @@
+export {
+ default as scaleBand,
+ point as scalePoint
+} from "./band.js";
+
+export {
+ default as scaleIdentity
+} from "./identity.js";
+
+export {
+ default as scaleLinear
+} from "./linear.js";
+
+export {
+ default as scaleLog
+} from "./log.js";
+
+export {
+ default as scaleSymlog
+} from "./symlog.js";
+
+export {
+ default as scaleOrdinal,
+ implicit as scaleImplicit
+} from "./ordinal.js";
+
+export {
+ default as scalePow,
+ sqrt as scaleSqrt
+} from "./pow.js";
+
+export {
+ default as scaleRadial
+} from "./radial.js";
+
+export {
+ default as scaleQuantile
+} from "./quantile.js";
+
+export {
+ default as scaleQuantize
+} from "./quantize.js";
+
+export {
+ default as scaleThreshold
+} from "./threshold.js";
+
+export {
+ default as scaleTime
+} from "./time.js";
+
+export {
+ default as scaleUtc
+} from "./utcTime.js";
+
+export {
+ default as scaleSequential,
+ sequentialLog as scaleSequentialLog,
+ sequentialPow as scaleSequentialPow,
+ sequentialSqrt as scaleSequentialSqrt,
+ sequentialSymlog as scaleSequentialSymlog
+} from "./sequential.js";
+
+export {
+ default as scaleSequentialQuantile
+} from "./sequentialQuantile.js";
+
+export {
+ default as scaleDiverging,
+ divergingLog as scaleDivergingLog,
+ divergingPow as scaleDivergingPow,
+ divergingSqrt as scaleDivergingSqrt,
+ divergingSymlog as scaleDivergingSymlog
+} from "./diverging.js";
+
+export {
+ default as tickFormat
+} from "./tickFormat.js";
diff --git a/node_modules/d3-scale/src/init.js b/node_modules/d3-scale/src/init.js
new file mode 100644
index 00000000..61f51a07
--- /dev/null
+++ b/node_modules/d3-scale/src/init.js
@@ -0,0 +1,26 @@
+export function initRange(domain, range) {
+ switch (arguments.length) {
+ case 0: break;
+ case 1: this.range(domain); break;
+ default: this.range(range).domain(domain); break;
+ }
+ return this;
+}
+
+export function initInterpolator(domain, interpolator) {
+ switch (arguments.length) {
+ case 0: break;
+ case 1: {
+ if (typeof domain === "function") this.interpolator(domain);
+ else this.range(domain);
+ break;
+ }
+ default: {
+ this.domain(domain);
+ if (typeof interpolator === "function") this.interpolator(interpolator);
+ else this.range(interpolator);
+ break;
+ }
+ }
+ return this;
+}
diff --git a/node_modules/d3-scale/src/linear.js b/node_modules/d3-scale/src/linear.js
new file mode 100644
index 00000000..3617d32a
--- /dev/null
+++ b/node_modules/d3-scale/src/linear.js
@@ -0,0 +1,70 @@
+import {ticks, tickIncrement} from "d3-array";
+import continuous, {copy} from "./continuous.js";
+import {initRange} from "./init.js";
+import tickFormat from "./tickFormat.js";
+
+export function linearish(scale) {
+ var domain = scale.domain;
+
+ scale.ticks = function(count) {
+ var d = domain();
+ return ticks(d[0], d[d.length - 1], count == null ? 10 : count);
+ };
+
+ scale.tickFormat = function(count, specifier) {
+ var d = domain();
+ return tickFormat(d[0], d[d.length - 1], count == null ? 10 : count, specifier);
+ };
+
+ scale.nice = function(count) {
+ if (count == null) count = 10;
+
+ var d = domain();
+ var i0 = 0;
+ var i1 = d.length - 1;
+ var start = d[i0];
+ var stop = d[i1];
+ var prestep;
+ var step;
+ var maxIter = 10;
+
+ if (stop < start) {
+ step = start, start = stop, stop = step;
+ step = i0, i0 = i1, i1 = step;
+ }
+
+ while (maxIter-- > 0) {
+ step = tickIncrement(start, stop, count);
+ if (step === prestep) {
+ d[i0] = start
+ d[i1] = stop
+ return domain(d);
+ } else if (step > 0) {
+ start = Math.floor(start / step) * step;
+ stop = Math.ceil(stop / step) * step;
+ } else if (step < 0) {
+ start = Math.ceil(start * step) / step;
+ stop = Math.floor(stop * step) / step;
+ } else {
+ break;
+ }
+ prestep = step;
+ }
+
+ return scale;
+ };
+
+ return scale;
+}
+
+export default function linear() {
+ var scale = continuous();
+
+ scale.copy = function() {
+ return copy(scale, linear());
+ };
+
+ initRange.apply(scale, arguments);
+
+ return linearish(scale);
+}
diff --git a/node_modules/d3-scale/src/log.js b/node_modules/d3-scale/src/log.js
new file mode 100644
index 00000000..170cd697
--- /dev/null
+++ b/node_modules/d3-scale/src/log.js
@@ -0,0 +1,140 @@
+import {ticks} from "d3-array";
+import {format, formatSpecifier} from "d3-format";
+import nice from "./nice.js";
+import {copy, transformer} from "./continuous.js";
+import {initRange} from "./init.js";
+
+function transformLog(x) {
+ return Math.log(x);
+}
+
+function transformExp(x) {
+ return Math.exp(x);
+}
+
+function transformLogn(x) {
+ return -Math.log(-x);
+}
+
+function transformExpn(x) {
+ return -Math.exp(-x);
+}
+
+function pow10(x) {
+ return isFinite(x) ? +("1e" + x) : x < 0 ? 0 : x;
+}
+
+function powp(base) {
+ return base === 10 ? pow10
+ : base === Math.E ? Math.exp
+ : x => Math.pow(base, x);
+}
+
+function logp(base) {
+ return base === Math.E ? Math.log
+ : base === 10 && Math.log10
+ || base === 2 && Math.log2
+ || (base = Math.log(base), x => Math.log(x) / base);
+}
+
+function reflect(f) {
+ return (x, k) => -f(-x, k);
+}
+
+export function loggish(transform) {
+ const scale = transform(transformLog, transformExp);
+ const domain = scale.domain;
+ let base = 10;
+ let logs;
+ let pows;
+
+ function rescale() {
+ logs = logp(base), pows = powp(base);
+ if (domain()[0] < 0) {
+ logs = reflect(logs), pows = reflect(pows);
+ transform(transformLogn, transformExpn);
+ } else {
+ transform(transformLog, transformExp);
+ }
+ return scale;
+ }
+
+ scale.base = function(_) {
+ return arguments.length ? (base = +_, rescale()) : base;
+ };
+
+ scale.domain = function(_) {
+ return arguments.length ? (domain(_), rescale()) : domain();
+ };
+
+ scale.ticks = count => {
+ const d = domain();
+ let u = d[0];
+ let v = d[d.length - 1];
+ const r = v < u;
+
+ if (r) ([u, v] = [v, u]);
+
+ let i = logs(u);
+ let j = logs(v);
+ let k;
+ let t;
+ const n = count == null ? 10 : +count;
+ let z = [];
+
+ if (!(base % 1) && j - i < n) {
+ i = Math.floor(i), j = Math.ceil(j);
+ if (u > 0) for (; i <= j; ++i) {
+ for (k = 1; k < base; ++k) {
+ t = i < 0 ? k / pows(-i) : k * pows(i);
+ if (t < u) continue;
+ if (t > v) break;
+ z.push(t);
+ }
+ } else for (; i <= j; ++i) {
+ for (k = base - 1; k >= 1; --k) {
+ t = i > 0 ? k / pows(-i) : k * pows(i);
+ if (t < u) continue;
+ if (t > v) break;
+ z.push(t);
+ }
+ }
+ if (z.length * 2 < n) z = ticks(u, v, n);
+ } else {
+ z = ticks(i, j, Math.min(j - i, n)).map(pows);
+ }
+ return r ? z.reverse() : z;
+ };
+
+ scale.tickFormat = (count, specifier) => {
+ if (count == null) count = 10;
+ if (specifier == null) specifier = base === 10 ? "s" : ",";
+ if (typeof specifier !== "function") {
+ if (!(base % 1) && (specifier = formatSpecifier(specifier)).precision == null) specifier.trim = true;
+ specifier = format(specifier);
+ }
+ if (count === Infinity) return specifier;
+ const k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate?
+ return d => {
+ let i = d / pows(Math.round(logs(d)));
+ if (i * base < base - 0.5) i *= base;
+ return i <= k ? specifier(d) : "";
+ };
+ };
+
+ scale.nice = () => {
+ return domain(nice(domain(), {
+ floor: x => pows(Math.floor(logs(x))),
+ ceil: x => pows(Math.ceil(logs(x)))
+ }));
+ };
+
+ return scale;
+}
+
+export default function log() {
+ const scale = loggish(transformer()).domain([1, 10]);
+ scale.copy = () => copy(scale, log()).base(scale.base());
+ initRange.apply(scale, arguments);
+ return scale;
+}
diff --git a/node_modules/d3-scale/src/nice.js b/node_modules/d3-scale/src/nice.js
new file mode 100644
index 00000000..a44e6015
--- /dev/null
+++ b/node_modules/d3-scale/src/nice.js
@@ -0,0 +1,18 @@
+export default function nice(domain, interval) {
+ domain = domain.slice();
+
+ var i0 = 0,
+ i1 = domain.length - 1,
+ x0 = domain[i0],
+ x1 = domain[i1],
+ t;
+
+ if (x1 < x0) {
+ t = i0, i0 = i1, i1 = t;
+ t = x0, x0 = x1, x1 = t;
+ }
+
+ domain[i0] = interval.floor(x0);
+ domain[i1] = interval.ceil(x1);
+ return domain;
+}
diff --git a/node_modules/d3-scale/src/number.js b/node_modules/d3-scale/src/number.js
new file mode 100644
index 00000000..d185907f
--- /dev/null
+++ b/node_modules/d3-scale/src/number.js
@@ -0,0 +1,3 @@
+export default function number(x) {
+ return +x;
+}
diff --git a/node_modules/d3-scale/src/ordinal.js b/node_modules/d3-scale/src/ordinal.js
new file mode 100644
index 00000000..74152805
--- /dev/null
+++ b/node_modules/d3-scale/src/ordinal.js
@@ -0,0 +1,46 @@
+import {InternMap} from "d3-array";
+import {initRange} from "./init.js";
+
+export const implicit = Symbol("implicit");
+
+export default function ordinal() {
+ var index = new InternMap(),
+ domain = [],
+ range = [],
+ unknown = implicit;
+
+ function scale(d) {
+ let i = index.get(d);
+ if (i === undefined) {
+ if (unknown !== implicit) return unknown;
+ index.set(d, i = domain.push(d) - 1);
+ }
+ return range[i % range.length];
+ }
+
+ scale.domain = function(_) {
+ if (!arguments.length) return domain.slice();
+ domain = [], index = new InternMap();
+ for (const value of _) {
+ if (index.has(value)) continue;
+ index.set(value, domain.push(value) - 1);
+ }
+ return scale;
+ };
+
+ scale.range = function(_) {
+ return arguments.length ? (range = Array.from(_), scale) : range.slice();
+ };
+
+ scale.unknown = function(_) {
+ return arguments.length ? (unknown = _, scale) : unknown;
+ };
+
+ scale.copy = function() {
+ return ordinal(domain, range).unknown(unknown);
+ };
+
+ initRange.apply(scale, arguments);
+
+ return scale;
+}
diff --git a/node_modules/d3-scale/src/pow.js b/node_modules/d3-scale/src/pow.js
new file mode 100644
index 00000000..8146f1c0
--- /dev/null
+++ b/node_modules/d3-scale/src/pow.js
@@ -0,0 +1,50 @@
+import {linearish} from "./linear.js";
+import {copy, identity, transformer} from "./continuous.js";
+import {initRange} from "./init.js";
+
+function transformPow(exponent) {
+ return function(x) {
+ return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent);
+ };
+}
+
+function transformSqrt(x) {
+ return x < 0 ? -Math.sqrt(-x) : Math.sqrt(x);
+}
+
+function transformSquare(x) {
+ return x < 0 ? -x * x : x * x;
+}
+
+export function powish(transform) {
+ var scale = transform(identity, identity),
+ exponent = 1;
+
+ function rescale() {
+ return exponent === 1 ? transform(identity, identity)
+ : exponent === 0.5 ? transform(transformSqrt, transformSquare)
+ : transform(transformPow(exponent), transformPow(1 / exponent));
+ }
+
+ scale.exponent = function(_) {
+ return arguments.length ? (exponent = +_, rescale()) : exponent;
+ };
+
+ return linearish(scale);
+}
+
+export default function pow() {
+ var scale = powish(transformer());
+
+ scale.copy = function() {
+ return copy(scale, pow()).exponent(scale.exponent());
+ };
+
+ initRange.apply(scale, arguments);
+
+ return scale;
+}
+
+export function sqrt() {
+ return pow.apply(null, arguments).exponent(0.5);
+}
diff --git a/node_modules/d3-scale/src/quantile.js b/node_modules/d3-scale/src/quantile.js
new file mode 100644
index 00000000..303f935a
--- /dev/null
+++ b/node_modules/d3-scale/src/quantile.js
@@ -0,0 +1,57 @@
+import {ascending, bisect, quantileSorted as threshold} from "d3-array";
+import {initRange} from "./init.js";
+
+export default function quantile() {
+ var domain = [],
+ range = [],
+ thresholds = [],
+ unknown;
+
+ function rescale() {
+ var i = 0, n = Math.max(1, range.length);
+ thresholds = new Array(n - 1);
+ while (++i < n) thresholds[i - 1] = threshold(domain, i / n);
+ return scale;
+ }
+
+ function scale(x) {
+ return x == null || isNaN(x = +x) ? unknown : range[bisect(thresholds, x)];
+ }
+
+ scale.invertExtent = function(y) {
+ var i = range.indexOf(y);
+ return i < 0 ? [NaN, NaN] : [
+ i > 0 ? thresholds[i - 1] : domain[0],
+ i < thresholds.length ? thresholds[i] : domain[domain.length - 1]
+ ];
+ };
+
+ scale.domain = function(_) {
+ if (!arguments.length) return domain.slice();
+ domain = [];
+ for (let d of _) if (d != null && !isNaN(d = +d)) domain.push(d);
+ domain.sort(ascending);
+ return rescale();
+ };
+
+ scale.range = function(_) {
+ return arguments.length ? (range = Array.from(_), rescale()) : range.slice();
+ };
+
+ scale.unknown = function(_) {
+ return arguments.length ? (unknown = _, scale) : unknown;
+ };
+
+ scale.quantiles = function() {
+ return thresholds.slice();
+ };
+
+ scale.copy = function() {
+ return quantile()
+ .domain(domain)
+ .range(range)
+ .unknown(unknown);
+ };
+
+ return initRange.apply(scale, arguments);
+}
diff --git a/node_modules/d3-scale/src/quantize.js b/node_modules/d3-scale/src/quantize.js
new file mode 100644
index 00000000..0f540035
--- /dev/null
+++ b/node_modules/d3-scale/src/quantize.js
@@ -0,0 +1,56 @@
+import {bisect} from "d3-array";
+import {linearish} from "./linear.js";
+import {initRange} from "./init.js";
+
+export default function quantize() {
+ var x0 = 0,
+ x1 = 1,
+ n = 1,
+ domain = [0.5],
+ range = [0, 1],
+ unknown;
+
+ function scale(x) {
+ return x != null && x <= x ? range[bisect(domain, x, 0, n)] : unknown;
+ }
+
+ function rescale() {
+ var i = -1;
+ domain = new Array(n);
+ while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1);
+ return scale;
+ }
+
+ scale.domain = function(_) {
+ return arguments.length ? ([x0, x1] = _, x0 = +x0, x1 = +x1, rescale()) : [x0, x1];
+ };
+
+ scale.range = function(_) {
+ return arguments.length ? (n = (range = Array.from(_)).length - 1, rescale()) : range.slice();
+ };
+
+ scale.invertExtent = function(y) {
+ var i = range.indexOf(y);
+ return i < 0 ? [NaN, NaN]
+ : i < 1 ? [x0, domain[0]]
+ : i >= n ? [domain[n - 1], x1]
+ : [domain[i - 1], domain[i]];
+ };
+
+ scale.unknown = function(_) {
+ return arguments.length ? (unknown = _, scale) : scale;
+ };
+
+ scale.thresholds = function() {
+ return domain.slice();
+ };
+
+ scale.copy = function() {
+ return quantize()
+ .domain([x0, x1])
+ .range(range)
+ .unknown(unknown);
+ };
+
+ return initRange.apply(linearish(scale), arguments);
+}
diff --git a/node_modules/d3-scale/src/radial.js b/node_modules/d3-scale/src/radial.js
new file mode 100644
index 00000000..5c00cc6d
--- /dev/null
+++ b/node_modules/d3-scale/src/radial.js
@@ -0,0 +1,63 @@
+import continuous from "./continuous.js";
+import {initRange} from "./init.js";
+import {linearish} from "./linear.js";
+import number from "./number.js";
+
+function square(x) {
+ return Math.sign(x) * x * x;
+}
+
+function unsquare(x) {
+ return Math.sign(x) * Math.sqrt(Math.abs(x));
+}
+
+export default function radial() {
+ var squared = continuous(),
+ range = [0, 1],
+ round = false,
+ unknown;
+
+ function scale(x) {
+ var y = unsquare(squared(x));
+ return isNaN(y) ? unknown : round ? Math.round(y) : y;
+ }
+
+ scale.invert = function(y) {
+ return squared.invert(square(y));
+ };
+
+ scale.domain = function(_) {
+ return arguments.length ? (squared.domain(_), scale) : squared.domain();
+ };
+
+ scale.range = function(_) {
+ return arguments.length ? (squared.range((range = Array.from(_, number)).map(square)), scale) : range.slice();
+ };
+
+ scale.rangeRound = function(_) {
+ return scale.range(_).round(true);
+ };
+
+ scale.round = function(_) {
+ return arguments.length ? (round = !!_, scale) : round;
+ };
+
+ scale.clamp = function(_) {
+ return arguments.length ? (squared.clamp(_), scale) : squared.clamp();
+ };
+
+ scale.unknown = function(_) {
+ return arguments.length ? (unknown = _, scale) : unknown;
+ };
+
+ scale.copy = function() {
+ return radial(squared.domain(), range)
+ .round(round)
+ .clamp(squared.clamp())
+ .unknown(unknown);
+ };
+
+ initRange.apply(scale, arguments);
+
+ return linearish(scale);
+}
diff --git a/node_modules/d3-scale/src/sequential.js b/node_modules/d3-scale/src/sequential.js
new file mode 100644
index 00000000..547dc404
--- /dev/null
+++ b/node_modules/d3-scale/src/sequential.js
@@ -0,0 +1,107 @@
+import {interpolate, interpolateRound} from "d3-interpolate";
+import {identity} from "./continuous.js";
+import {initInterpolator} from "./init.js";
+import {linearish} from "./linear.js";
+import {loggish} from "./log.js";
+import {symlogish} from "./symlog.js";
+import {powish} from "./pow.js";
+
+function transformer() {
+ var x0 = 0,
+ x1 = 1,
+ t0,
+ t1,
+ k10,
+ transform,
+ interpolator = identity,
+ clamp = false,
+ unknown;
+
+ function scale(x) {
+ return x == null || isNaN(x = +x) ? unknown : interpolator(k10 === 0 ? 0.5 : (x = (transform(x) - t0) * k10, clamp ? Math.max(0, Math.min(1, x)) : x));
+ }
+
+ scale.domain = function(_) {
+ return arguments.length ? ([x0, x1] = _, t0 = transform(x0 = +x0), t1 = transform(x1 = +x1), k10 = t0 === t1 ? 0 : 1 / (t1 - t0), scale) : [x0, x1];
+ };
+
+ scale.clamp = function(_) {
+ return arguments.length ? (clamp = !!_, scale) : clamp;
+ };
+
+ scale.interpolator = function(_) {
+ return arguments.length ? (interpolator = _, scale) : interpolator;
+ };
+
+ function range(interpolate) {
+ return function(_) {
+ var r0, r1;
+ return arguments.length ? ([r0, r1] = _, interpolator = interpolate(r0, r1), scale) : [interpolator(0), interpolator(1)];
+ };
+ }
+
+ scale.range = range(interpolate);
+
+ scale.rangeRound = range(interpolateRound);
+
+ scale.unknown = function(_) {
+ return arguments.length ? (unknown = _, scale) : unknown;
+ };
+
+ return function(t) {
+ transform = t, t0 = t(x0), t1 = t(x1), k10 = t0 === t1 ? 0 : 1 / (t1 - t0);
+ return scale;
+ };
+}
+
+export function copy(source, target) {
+ return target
+ .domain(source.domain())
+ .interpolator(source.interpolator())
+ .clamp(source.clamp())
+ .unknown(source.unknown());
+}
+
+export default function sequential() {
+ var scale = linearish(transformer()(identity));
+
+ scale.copy = function() {
+ return copy(scale, sequential());
+ };
+
+ return initInterpolator.apply(scale, arguments);
+}
+
+export function sequentialLog() {
+ var scale = loggish(transformer()).domain([1, 10]);
+
+ scale.copy = function() {
+ return copy(scale, sequentialLog()).base(scale.base());
+ };
+
+ return initInterpolator.apply(scale, arguments);
+}
+
+export function sequentialSymlog() {
+ var scale = symlogish(transformer());
+
+ scale.copy = function() {
+ return copy(scale, sequentialSymlog()).constant(scale.constant());
+ };
+
+ return initInterpolator.apply(scale, arguments);
+}
+
+export function sequentialPow() {
+ var scale = powish(transformer());
+
+ scale.copy = function() {
+ return copy(scale, sequentialPow()).exponent(scale.exponent());
+ };
+
+ return initInterpolator.apply(scale, arguments);
+}
+
+export function sequentialSqrt() {
+ return sequentialPow.apply(null, arguments).exponent(0.5);
+}
diff --git a/node_modules/d3-scale/src/sequentialQuantile.js b/node_modules/d3-scale/src/sequentialQuantile.js
new file mode 100644
index 00000000..7437e558
--- /dev/null
+++ b/node_modules/d3-scale/src/sequentialQuantile.js
@@ -0,0 +1,38 @@
+import {ascending, bisect, quantile} from "d3-array";
+import {identity} from "./continuous.js";
+import {initInterpolator} from "./init.js";
+
+export default function sequentialQuantile() {
+ var domain = [],
+ interpolator = identity;
+
+ function scale(x) {
+ if (x != null && !isNaN(x = +x)) return interpolator((bisect(domain, x, 1) - 1) / (domain.length - 1));
+ }
+
+ scale.domain = function(_) {
+ if (!arguments.length) return domain.slice();
+ domain = [];
+ for (let d of _) if (d != null && !isNaN(d = +d)) domain.push(d);
+ domain.sort(ascending);
+ return scale;
+ };
+
+ scale.interpolator = function(_) {
+ return arguments.length ? (interpolator = _, scale) : interpolator;
+ };
+
+ scale.range = function() {
+ return domain.map((d, i) => interpolator(i / (domain.length - 1)));
+ };
+
+ scale.quantiles = function(n) {
+ return Array.from({length: n + 1}, (_, i) => quantile(domain, i / n));
+ };
+
+ scale.copy = function() {
+ return sequentialQuantile(interpolator).domain(domain);
+ };
+
+ return initInterpolator.apply(scale, arguments);
+}
diff --git a/node_modules/d3-scale/src/symlog.js b/node_modules/d3-scale/src/symlog.js
new file mode 100644
index 00000000..125fa7b5
--- /dev/null
+++ b/node_modules/d3-scale/src/symlog.js
@@ -0,0 +1,35 @@
+import {linearish} from "./linear.js";
+import {copy, transformer} from "./continuous.js";
+import {initRange} from "./init.js";
+
+function transformSymlog(c) {
+ return function(x) {
+ return Math.sign(x) * Math.log1p(Math.abs(x / c));
+ };
+}
+
+function transformSymexp(c) {
+ return function(x) {
+ return Math.sign(x) * Math.expm1(Math.abs(x)) * c;
+ };
+}
+
+export function symlogish(transform) {
+ var c = 1, scale = transform(transformSymlog(c), transformSymexp(c));
+
+ scale.constant = function(_) {
+ return arguments.length ? transform(transformSymlog(c = +_), transformSymexp(c)) : c;
+ };
+
+ return linearish(scale);
+}
+
+export default function symlog() {
+ var scale = symlogish(transformer());
+
+ scale.copy = function() {
+ return copy(scale, symlog()).constant(scale.constant());
+ };
+
+ return initRange.apply(scale, arguments);
+}
diff --git a/node_modules/d3-scale/src/threshold.js b/node_modules/d3-scale/src/threshold.js
new file mode 100644
index 00000000..bbdbe392
--- /dev/null
+++ b/node_modules/d3-scale/src/threshold.js
@@ -0,0 +1,39 @@
+import {bisect} from "d3-array";
+import {initRange} from "./init.js";
+
+export default function threshold() {
+ var domain = [0.5],
+ range = [0, 1],
+ unknown,
+ n = 1;
+
+ function scale(x) {
+ return x != null && x <= x ? range[bisect(domain, x, 0, n)] : unknown;
+ }
+
+ scale.domain = function(_) {
+ return arguments.length ? (domain = Array.from(_), n = Math.min(domain.length, range.length - 1), scale) : domain.slice();
+ };
+
+ scale.range = function(_) {
+ return arguments.length ? (range = Array.from(_), n = Math.min(domain.length, range.length - 1), scale) : range.slice();
+ };
+
+ scale.invertExtent = function(y) {
+ var i = range.indexOf(y);
+ return [domain[i - 1], domain[i]];
+ };
+
+ scale.unknown = function(_) {
+ return arguments.length ? (unknown = _, scale) : unknown;
+ };
+
+ scale.copy = function() {
+ return threshold()
+ .domain(domain)
+ .range(range)
+ .unknown(unknown);
+ };
+
+ return initRange.apply(scale, arguments);
+}
diff --git a/node_modules/d3-scale/src/tickFormat.js b/node_modules/d3-scale/src/tickFormat.js
new file mode 100644
index 00000000..15fc54ef
--- /dev/null
+++ b/node_modules/d3-scale/src/tickFormat.js
@@ -0,0 +1,29 @@
+import {tickStep} from "d3-array";
+import {format, formatPrefix, formatSpecifier, precisionFixed, precisionPrefix, precisionRound} from "d3-format";
+
+export default function tickFormat(start, stop, count, specifier) {
+ var step = tickStep(start, stop, count),
+ precision;
+ specifier = formatSpecifier(specifier == null ? ",f" : specifier);
+ switch (specifier.type) {
+ case "s": {
+ var value = Math.max(Math.abs(start), Math.abs(stop));
+ if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision;
+ return formatPrefix(specifier, value);
+ }
+ case "":
+ case "e":
+ case "g":
+ case "p":
+ case "r": {
+ if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e");
+ break;
+ }
+ case "f":
+ case "%": {
+ if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2;
+ break;
+ }
+ }
+ return format(specifier);
+}
diff --git a/node_modules/d3-scale/src/time.js b/node_modules/d3-scale/src/time.js
new file mode 100644
index 00000000..d1ea678f
--- /dev/null
+++ b/node_modules/d3-scale/src/time.js
@@ -0,0 +1,71 @@
+import {timeYear, timeMonth, timeWeek, timeDay, timeHour, timeMinute, timeSecond, timeTicks, timeTickInterval} from "d3-time";
+import {timeFormat} from "d3-time-format";
+import continuous, {copy} from "./continuous.js";
+import {initRange} from "./init.js";
+import nice from "./nice.js";
+
+function date(t) {
+ return new Date(t);
+}
+
+function number(t) {
+ return t instanceof Date ? +t : +new Date(+t);
+}
+
+export function calendar(ticks, tickInterval, year, month, week, day, hour, minute, second, format) {
+ var scale = continuous(),
+ invert = scale.invert,
+ domain = scale.domain;
+
+ var formatMillisecond = format(".%L"),
+ formatSecond = format(":%S"),
+ formatMinute = format("%I:%M"),
+ formatHour = format("%I %p"),
+ formatDay = format("%a %d"),
+ formatWeek = format("%b %d"),
+ formatMonth = format("%B"),
+ formatYear = format("%Y");
+
+ function tickFormat(date) {
+ return (second(date) < date ? formatMillisecond
+ : minute(date) < date ? formatSecond
+ : hour(date) < date ? formatMinute
+ : day(date) < date ? formatHour
+ : month(date) < date ? (week(date) < date ? formatDay : formatWeek)
+ : year(date) < date ? formatMonth
+ : formatYear)(date);
+ }
+
+ scale.invert = function(y) {
+ return new Date(invert(y));
+ };
+
+ scale.domain = function(_) {
+ return arguments.length ? domain(Array.from(_, number)) : domain().map(date);
+ };
+
+ scale.ticks = function(interval) {
+ var d = domain();
+ return ticks(d[0], d[d.length - 1], interval == null ? 10 : interval);
+ };
+
+ scale.tickFormat = function(count, specifier) {
+ return specifier == null ? tickFormat : format(specifier);
+ };
+
+ scale.nice = function(interval) {
+ var d = domain();
+ if (!interval || typeof interval.range !== "function") interval = tickInterval(d[0], d[d.length - 1], interval == null ? 10 : interval);
+ return interval ? domain(nice(d, interval)) : scale;
+ };
+
+ scale.copy = function() {
+ return copy(scale, calendar(ticks, tickInterval, year, month, week, day, hour, minute, second, format));
+ };
+
+ return scale;
+}
+
+export default function time() {
+ return initRange.apply(calendar(timeTicks, timeTickInterval, timeYear, timeMonth, timeWeek, timeDay, timeHour, timeMinute, timeSecond, timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]), arguments);
+}
diff --git a/node_modules/d3-scale/src/utcTime.js b/node_modules/d3-scale/src/utcTime.js
new file mode 100644
index 00000000..9741716b
--- /dev/null
+++ b/node_modules/d3-scale/src/utcTime.js
@@ -0,0 +1,8 @@
+import {utcYear, utcMonth, utcWeek, utcDay, utcHour, utcMinute, utcSecond, utcTicks, utcTickInterval} from "d3-time";
+import {utcFormat} from "d3-time-format";
+import {calendar} from "./time.js";
+import {initRange} from "./init.js";
+
+export default function utcTime() {
+ return initRange.apply(calendar(utcTicks, utcTickInterval, utcYear, utcMonth, utcWeek, utcDay, utcHour, utcMinute, utcSecond, utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]), arguments);
+}
diff --git a/node_modules/d3-selection/LICENSE b/node_modules/d3-selection/LICENSE
new file mode 100644
index 00000000..b0145150
--- /dev/null
+++ b/node_modules/d3-selection/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2010-2021 Mike Bostock
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/node_modules/d3-selection/README.md b/node_modules/d3-selection/README.md
new file mode 100644
index 00000000..b8513c67
--- /dev/null
+++ b/node_modules/d3-selection/README.md
@@ -0,0 +1,863 @@
+# d3-selection
+
+Selections allow powerful data-driven transformation of the document object model (DOM): set [attributes](#selection_attr), [styles](#selection_style), [properties](#selection_property), [HTML](#selection_html) or [text](#selection_text) content, and more. Using the [data join](#joining-data)’s [enter](#selection_enter) and [exit](#selection_enter) selections, you can also [add](#selection_append) or [remove](#selection_remove) elements to correspond to data.
+
+Selection methods typically return the current selection, or a new selection, allowing the concise application of multiple operations on a given selection via method chaining. For example, to set the class and color style of all paragraph elements in the current document:
+
+```js
+d3.selectAll("p")
+ .attr("class", "graf")
+ .style("color", "red");
+```
+
+This is equivalent to:
+
+```js
+const p = d3.selectAll("p");
+p.attr("class", "graf");
+p.style("color", "red");
+```
+
+By convention, selection methods that return the current selection use *four* spaces of indent, while methods that return a new selection use only *two*. This helps reveal changes of context by making them stick out of the chain:
+
+```js
+d3.select("body")
+ .append("svg")
+ .attr("width", 960)
+ .attr("height", 500)
+ .append("g")
+ .attr("transform", "translate(20,20)")
+ .append("rect")
+ .attr("width", 920)
+ .attr("height", 460);
+```
+
+Selections are immutable. All selection methods that affect which elements are selected (or their order) return a new selection rather than modifying the current selection. However, note that elements are necessarily mutable, as selections drive transformations of the document!
+
+For more, see [the d3-selection collection on Observable](https://observablehq.com/collection/@d3/d3-selection).
+
+## Installing
+
+If you use npm, `npm install d3-selection`. You can also download the [latest release on GitHub](https://github.com/d3/d3-selection/releases/latest). For vanilla HTML in modern browsers, import d3-selection from Skypack:
+
+```html
+
+```
+
+For legacy environments, you can load d3-selection’s UMD bundle from an npm-based CDN such as jsDelivr; a `d3` global is exported:
+
+```html
+
+
+```
+
+[Try d3-selection in your browser.](https://observablehq.com/collection/@d3/d3-selection)
+
+## API Reference
+
+* [Selecting Elements](#selecting-elements)
+* [Modifying Elements](#modifying-elements)
+* [Joining Data](#joining-data)
+* [Handling Events](#handling-events)
+* [Control Flow](#control-flow)
+* [Local Variables](#local-variables)
+* [Namespaces](#namespaces)
+
+### Selecting Elements
+
+Selection methods accept [W3C selector strings](http://www.w3.org/TR/selectors-api/) such as `.fancy` to select elements with the class *fancy*, or `div` to select DIV elements. Selection methods come in two forms: select and selectAll: the former selects only the first matching element, while the latter selects all matching elements in document order. The top-level selection methods, [d3.select](#select) and [d3.selectAll](#selectAll), query the entire document; the subselection methods, [*selection*.select](#selection_select) and [*selection*.selectAll](#selection_selectAll), restrict selection to descendants of the selected elements.
+
+# d3.selection() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/index.js)
+
+[Selects](#select) the root element, `document.documentElement`. This function can also be used to test for selections (`instanceof d3.selection`) or to extend the selection prototype. For example, to add a method to check checkboxes:
+
+```js
+d3.selection.prototype.checked = function(value) {
+ return arguments.length < 1
+ ? this.property("checked")
+ : this.property("checked", !!value);
+};
+```
+
+And then to use:
+
+```js
+d3.selectAll("input[type=checkbox]").checked(true);
+```
+
+# d3.select(selector) · [Source](https://github.com/d3/d3-selection/blob/master/src/select.js)
+
+Selects the first element that matches the specified *selector* string. If no elements match the *selector*, returns an empty selection. If multiple elements match the *selector*, only the first matching element (in document order) will be selected. For example, to select the first anchor element:
+
+```js
+const anchor = d3.select("a");
+```
+
+If the *selector* is not a string, instead selects the specified node; this is useful if you already have a reference to a node, such as `this` within an event listener or a global such as `document.body`. For example, to make a clicked paragraph red:
+
+```js
+d3.selectAll("p").on("click", function(event) {
+ d3.select(this).style("color", "red");
+});
+```
+
+# d3.selectAll(selector) · [Source](https://github.com/d3/d3-selection/blob/master/src/selectAll.js)
+
+Selects all elements that match the specified *selector* string. The elements will be selected in document order (top-to-bottom). If no elements in the document match the *selector*, or if the *selector* is null or undefined, returns an empty selection. For example, to select all paragraphs:
+
+```js
+const paragraph = d3.selectAll("p");
+```
+
+If the *selector* is not a string, instead selects the specified array of nodes; this is useful if you already have a reference to nodes, such as `this.childNodes` within an event listener or a global such as `document.links`. The nodes may instead be an iterable, or a pseudo-array such as a NodeList. For example, to color all links red:
+
+```js
+d3.selectAll(document.links).style("color", "red");
+```
+
+# selection.select(selector) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/select.js)
+
+For each selected element, selects the first descendant element that matches the specified *selector* string. If no element matches the specified selector for the current element, the element at the current index will be null in the returned selection. (If the *selector* is null, every element in the returned selection will be null, resulting in an empty selection.) If the current element has associated data, this data is propagated to the corresponding selected element. If multiple elements match the selector, only the first matching element in document order is selected. For example, to select the first bold element in every paragraph:
+
+```js
+const b = d3.selectAll("p").select("b");
+```
+
+If the *selector* is a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element (*nodes*[*i*]). It must return an element, or null if there is no matching element. For example, to select the previous sibling of each paragraph:
+
+```js
+const previous = d3.selectAll("p").select(function() {
+ return this.previousElementSibling;
+});
+```
+
+Unlike [*selection*.selectAll](#selection_selectAll), *selection*.select does not affect grouping: it preserves the existing group structure and indexes, and propagates data (if any) to selected children. Grouping plays an important role in the [data join](#joining-data). See [Nested Selections](http://bost.ocks.org/mike/nest/) and [How Selections Work](http://bost.ocks.org/mike/selection/) for more on this topic.
+
+# selection.selectAll(selector) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/selectAll.js)
+
+For each selected element, selects the descendant elements that match the specified *selector* string. The elements in the returned selection are grouped by their corresponding parent node in this selection. If no element matches the specified selector for the current element, or if the *selector* is null, the group at the current index will be empty. The selected elements do not inherit data from this selection; use [*selection*.data](#selection_data) to propagate data to children. For example, to select the bold elements in every paragraph:
+
+```js
+const b = d3.selectAll("p").selectAll("b");
+```
+
+If the *selector* is a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element (*nodes*[*i*]). It must return an array of elements (or an iterable, or a pseudo-array such as a NodeList), or the empty array if there are no matching elements. For example, to select the previous and next siblings of each paragraph:
+
+```js
+const sibling = d3.selectAll("p").selectAll(function() {
+ return [
+ this.previousElementSibling,
+ this.nextElementSibling
+ ];
+});
+```
+
+Unlike [*selection*.select](#selection_select), *selection*.selectAll does affect grouping: each selected descendant is grouped by the parent element in the originating selection. Grouping plays an important role in the [data join](#joining-data). See [Nested Selections](http://bost.ocks.org/mike/nest/) and [How Selections Work](http://bost.ocks.org/mike/selection/) for more on this topic.
+
+# selection.filter(filter) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/filter.js)
+
+Filters the selection, returning a new selection that contains only the elements for which the specified *filter* is true. The *filter* may be specified either as a selector string or a function. If the *filter* is a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element (*nodes*[*i*]).
+
+For example, to filter a selection of table rows to contain only even rows:
+
+```js
+const even = d3.selectAll("tr").filter(":nth-child(even)");
+```
+
+This is approximately equivalent to using [d3.selectAll](#selectAll) directly, although the indexes may be different:
+
+```js
+const even = d3.selectAll("tr:nth-child(even)");
+```
+
+Similarly, using a function:
+
+```js
+const even = d3.selectAll("tr").filter((d, i) => i & 1);
+```
+
+Or using [*selection*.select](#selection_select) (and avoiding an arrow function, since *this* is needed to refer to the current element):
+
+```js
+const even = d3.selectAll("tr").select(function(d, i) { return i & 1 ? this : null; });
+```
+
+Note that the `:nth-child` pseudo-class is a one-based index rather than a zero-based index. Also, the above filter functions do not have precisely the same meaning as `:nth-child`; they rely on the selection index rather than the number of preceding sibling elements in the DOM.
+
+The returned filtered selection preserves the parents of this selection, but like [*array*.filter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter), it does not preserve indexes as some elements may be removed; use [*selection*.select](#selection_select) to preserve the index, if needed.
+
+# selection.merge(other) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/merge.js)
+
+Returns a new selection merging this selection with the specified *other* selection or transition. The returned selection has the same number of groups and the same parents as this selection. Any missing (null) elements in this selection are filled with the corresponding element, if present (not null), from the specified *selection*. (If the *other* selection has additional groups or parents, they are ignored.)
+
+This method is used internally by [*selection*.join](#selection_join) to merge the [enter](#selection_enter) and [update](#selection_data) selections after [binding data](#joining-data). You can also merge explicitly, although note that since merging is based on element index, you should use operations that preserve index, such as [*selection*.select](#selection_select) instead of [*selection*.filter](#selection_filter). For example:
+
+```js
+const odd = selection.select(function(d, i) { return i & 1 ? this : null; ));
+const even = selection.select(function(d, i) { return i & 1 ? null : this; ));
+const merged = odd.merge(even);
+```
+
+See [*selection*.data](#selection_data) for more.
+
+This method is not intended for concatenating arbitrary selections, however: if both this selection and the specified *other* selection have (non-null) elements at the same index, this selection’s element is returned in the merge and the *other* selection’s element is ignored.
+
+# selection.selectChild([selector]) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/selectChild.js)
+
+Returns a new selection with the (first) child of each element of the current selection matching the *selector*. If no *selector* is specified, selects the first child (if any). If the *selector* is specified as a string, selects the first child that matches (if any). If the *selector* is a function, it is evaluated for each of the children nodes, in order, being passed the child (*child*), the child’s index (*i*), and the list of children (*children*); the method selects the first child for which the selector return truthy, if any.
+
+# selection.selectChildren([selector]) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/selectChildren.js)
+
+Returns a new selection with the children of each element of the current selection matching the *selector*. If no *selector* is specified, selects all the children. If the *selector* is specified as a string, selects the children that match (if any). If the *selector* is a function, it is evaluated for each of the children nodes, in order, being passed the child (*child*), the child’s index (*i*), and the list of children (*children*); the method selects all children for which the selector return truthy.
+
+# selection.selection() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/index.js)
+
+Returns the selection (for symmetry with [transition.selection](https://github.com/d3/d3-transition/blob/master/README.md#transition_selection)).
+
+# d3.matcher(selector) · [Source](https://github.com/d3/d3-selection/blob/master/src/matcher.js)
+
+Given the specified *selector*, returns a function which returns true if `this` element [matches](https://developer.mozilla.org/en-US/docs/Web/API/Element/matches) the specified selector. This method is used internally by [*selection*.filter](#selection_filter). For example, this:
+
+```js
+const div = selection.filter("div");
+```
+
+Is equivalent to:
+
+```js
+const div = selection.filter(d3.matcher("div"));
+```
+
+(Although D3 is not a compatibility layer, this implementation does support vendor-prefixed implementations due to the recent standardization of *element*.matches.)
+
+# d3.selector(selector) · [Source](https://github.com/d3/d3-selection/blob/master/src/selector.js)
+
+Given the specified *selector*, returns a function which returns the first descendant of `this` element that matches the specified selector. This method is used internally by [*selection*.select](#selection_select). For example, this:
+
+```js
+const div = selection.select("div");
+```
+
+Is equivalent to:
+
+```js
+const div = selection.select(d3.selector("div"));
+```
+
+# d3.selectorAll(selector) · [Source](https://github.com/d3/d3-selection/blob/master/src/selectAll.js)
+
+Given the specified *selector*, returns a function which returns all descendants of `this` element that match the specified selector. This method is used internally by [*selection*.selectAll](#selection_selectAll). For example, this:
+
+```js
+const div = selection.selectAll("div");
+```
+
+Is equivalent to:
+
+```js
+const div = selection.selectAll(d3.selectorAll("div"));
+```
+
+# d3.window(node) · [Source](https://github.com/d3/d3-selection/blob/master/src/window.js)
+
+Returns the owner window for the specified *node*. If *node* is a node, returns the owner document’s default view; if *node* is a document, returns its default view; otherwise returns the *node*.
+
+# d3.style(node, name) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/style.js)
+
+Returns the value of the style property with the specified *name* for the specified *node*. If the *node* has an inline style with the specified *name*, its value is returned; otherwise, the [computed property value](https://developer.mozilla.org/en-US/docs/Web/CSS/computed_value) is returned. See also [*selection*.style](#selection_style).
+
+### Modifying Elements
+
+After selecting elements, use the selection’s transformation methods to affect document content. For example, to set the name attribute and color style of an anchor element:
+
+```js
+d3.select("a")
+ .attr("name", "fred")
+ .style("color", "red");
+```
+
+To experiment with selections, visit [d3js.org](https://d3js.org) and open your browser’s developer console! (In Chrome, open the console with ⌥⌘J.) Select elements and then inspect the returned selection to see which elements are selected and how they are grouped. Call selection methods and see how the page content changes.
+
+# selection.attr(name[, value]) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/attr.js)
+
+If a *value* is specified, sets the attribute with the specified *name* to the specified value on the selected elements and returns this selection. If the *value* is a constant, all elements are given the same attribute value; otherwise, if the *value* is a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element (*nodes*[*i*]). The function’s return value is then used to set each element’s attribute. A null value will remove the specified attribute.
+
+If a *value* is not specified, returns the current value of the specified attribute for the first (non-null) element in the selection. This is generally useful only if you know that the selection contains exactly one element.
+
+The specified *name* may have a namespace prefix, such as `xlink:href` to specify the `href` attribute in the XLink namespace. See [namespaces](#namespaces) for the map of supported namespaces; additional namespaces can be registered by adding to the map.
+
+# selection.classed(names[, value]) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/classed.js)
+
+If a *value* is specified, assigns or unassigns the specified CSS class *names* on the selected elements by setting the `class` attribute or modifying the `classList` property and returns this selection. The specified *names* is a string of space-separated class names. For example, to assign the classes `foo` and `bar` to the selected elements:
+
+```js
+selection.classed("foo bar", true);
+```
+
+If the *value* is truthy, then all elements are assigned the specified classes; otherwise, the classes are unassigned. If the *value* is a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element (*nodes*[*i*]). The function’s return value is then used to assign or unassign classes on each element. For example, to randomly associate the class *foo* with on average half the selected elements:
+
+```js
+selection.classed("foo", () => Math.random() > 0.5);
+```
+
+If a *value* is not specified, returns true if and only if the first (non-null) selected element has the specified *classes*. This is generally useful only if you know the selection contains exactly one element.
+
+# selection.style(name[, value[, priority]]) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/style.js)
+
+If a *value* is specified, sets the style property with the specified *name* to the specified value on the selected elements and returns this selection. If the *value* is a constant, then all elements are given the same style property value; otherwise, if the *value* is a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element (*nodes*[*i*]). The function’s return value is then used to set each element’s style property. A null value will remove the style property. An optional *priority* may also be specified, either as null or the string `important` (without the exclamation point).
+
+If a *value* is not specified, returns the current value of the specified style property for the first (non-null) element in the selection. The current value is defined as the element’s inline value, if present, and otherwise its [computed value](https://developer.mozilla.org/en-US/docs/Web/CSS/computed_value). Accessing the current style value is generally useful only if you know the selection contains exactly one element.
+
+Caution: unlike many SVG attributes, CSS styles typically have associated units. For example, `3px` is a valid stroke-width property value, while `3` is not. Some browsers implicitly assign the `px` (pixel) unit to numeric values, but not all browsers do: IE, for example, throws an “invalid arguments” error!
+
+# selection.property(name[, value]) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/property.js)
+
+Some HTML elements have special properties that are not addressable using attributes or styles, such as a form field’s text `value` and a checkbox’s `checked` boolean. Use this method to get or set these properties.
+
+If a *value* is specified, sets the property with the specified *name* to the specified value on selected elements. If the *value* is a constant, then all elements are given the same property value; otherwise, if the *value* is a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element (*nodes*[*i*]). The function’s return value is then used to set each element’s property. A null value will delete the specified property.
+
+If a *value* is not specified, returns the value of the specified property for the first (non-null) element in the selection. This is generally useful only if you know the selection contains exactly one element.
+
+# selection.text([value]) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/text.js)
+
+If a *value* is specified, sets the [text content](http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-textContent) to the specified value on all selected elements, replacing any existing child elements. If the *value* is a constant, then all elements are given the same text content; otherwise, if the *value* is a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element (*nodes*[*i*]). The function’s return value is then used to set each element’s text content. A null value will clear the content.
+
+If a *value* is not specified, returns the text content for the first (non-null) element in the selection. This is generally useful only if you know the selection contains exactly one element.
+
+# selection.html([value]) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/html.js)
+
+If a *value* is specified, sets the [inner HTML](http://dev.w3.org/html5/spec-LC/apis-in-html-documents.html#innerhtml) to the specified value on all selected elements, replacing any existing child elements. If the *value* is a constant, then all elements are given the same inner HTML; otherwise, if the *value* is a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element (*nodes*[*i*]). The function’s return value is then used to set each element’s inner HTML. A null value will clear the content.
+
+If a *value* is not specified, returns the inner HTML for the first (non-null) element in the selection. This is generally useful only if you know the selection contains exactly one element.
+
+Use [*selection*.append](#selection_append) or [*selection*.insert](#selection_insert) instead to create data-driven content; this method is intended for when you want a little bit of HTML, say for rich formatting. Also, *selection*.html is only supported on HTML elements. SVG elements and other non-HTML elements do not support the innerHTML property, and thus are incompatible with *selection*.html. Consider using [XMLSerializer](https://developer.mozilla.org/en-US/docs/XMLSerializer) to convert a DOM subtree to text. See also the [innersvg polyfill](https://code.google.com/p/innersvg/), which provides a shim to support the innerHTML property on SVG elements.
+
+# selection.append(type) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/append.js)
+
+If the specified *type* is a string, appends a new element of this type (tag name) as the last child of each selected element, or before the next following sibling in the update selection if this is an [enter selection](#selection_enter). The latter behavior for enter selections allows you to insert elements into the DOM in an order consistent with the new bound data; however, note that [*selection*.order](#selection_order) may still be required if updating elements change order (*i.e.*, if the order of new data is inconsistent with old data).
+
+If the specified *type* is a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element (*nodes*[*i*]). This function should return an element to be appended. (The function typically creates a new element, but it may instead return an existing element.) For example, to append a paragraph to each DIV element:
+
+```js
+d3.selectAll("div").append("p");
+```
+
+This is equivalent to:
+
+```js
+d3.selectAll("div").append(() => document.createElement("p"));
+```
+
+Which is equivalent to:
+
+```js
+d3.selectAll("div").select(function() {
+ return this.appendChild(document.createElement("p"));
+});
+```
+
+In both cases, this method returns a new selection containing the appended elements. Each new element inherits the data of the current elements, if any, in the same manner as [*selection*.select](#selection_select).
+
+The specified *name* may have a namespace prefix, such as `svg:text` to specify a `text` attribute in the SVG namespace. See [namespaces](#namespaces) for the map of supported namespaces; additional namespaces can be registered by adding to the map. If no namespace is specified, the namespace will be inherited from the parent element; or, if the name is one of the known prefixes, the corresponding namespace will be used (for example, `svg` implies `svg:svg`).
+
+# selection.insert(type[, before]) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/insert.js)
+
+If the specified *type* is a string, inserts a new element of this type (tag name) before the first element matching the specified *before* selector for each selected element. For example, a *before* selector `:first-child` will prepend nodes before the first child. If *before* is not specified, it defaults to null. (To append elements in an order consistent with [bound data](#joining-data), use [*selection*.append](#selection_append).)
+
+Both *type* and *before* may instead be specified as functions which are evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element (*nodes*[*i*]). The *type* function should return an element to be inserted; the *before* function should return the child element before which the element should be inserted. For example, to append a paragraph to each DIV element:
+
+```js
+d3.selectAll("div").insert("p");
+```
+
+This is equivalent to:
+
+```js
+d3.selectAll("div").insert(() => document.createElement("p"));
+```
+
+Which is equivalent to:
+
+```js
+d3.selectAll("div").select(function() {
+ return this.insertBefore(document.createElement("p"), null);
+});
+```
+
+In both cases, this method returns a new selection containing the appended elements. Each new element inherits the data of the current elements, if any, in the same manner as [*selection*.select](#selection_select).
+
+The specified *name* may have a namespace prefix, such as `svg:text` to specify a `text` attribute in the SVG namespace. See [namespaces](#namespaces) for the map of supported namespaces; additional namespaces can be registered by adding to the map. If no namespace is specified, the namespace will be inherited from the parent element; or, if the name is one of the known prefixes, the corresponding namespace will be used (for example, `svg` implies `svg:svg`).
+
+# selection.remove() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/remove.js)
+
+Removes the selected elements from the document. Returns this selection (the removed elements) which are now detached from the DOM. There is not currently a dedicated API to add removed elements back to the document; however, you can pass a function to [*selection*.append](#selection_append) or [*selection*.insert](#selection_insert) to re-add elements.
+
+# selection.clone([deep]) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/clone.js)
+
+Inserts clones of the selected elements immediately following the selected elements and returns a selection of the newly added clones. If *deep* is truthy, the descendant nodes of the selected elements will be cloned as well. Otherwise, only the elements themselves will be cloned. Equivalent to:
+
+```js
+selection.select(function() {
+ return this.parentNode.insertBefore(this.cloneNode(deep), this.nextSibling);
+});
+```
+
+# selection.sort(compare) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/sort.js)
+
+Returns a new selection that contains a copy of each group in this selection sorted according to the *compare* function. After sorting, re-inserts elements to match the resulting order (per [*selection*.order](#selection_order)).
+
+The compare function, which defaults to [ascending](https://github.com/d3/d3-array#ascending), is passed two elements’ data *a* and *b* to compare. It should return either a negative, positive, or zero value. If negative, then *a* should be before *b*; if positive, then *a* should be after *b*; otherwise, *a* and *b* are considered equal and the order is arbitrary.
+
+Note that sorting is not guaranteed to be stable; however, it is guaranteed to have the same behavior as your browser’s built-in [sort](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/sort) method on arrays.
+
+# selection.order() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/order.js)
+
+Re-inserts elements into the document such that the document order of each group matches the selection order. This is equivalent to calling [*selection*.sort](#selection_sort) if the data is already sorted, but much faster.
+
+# selection.raise() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/raise.js)
+
+Re-inserts each selected element, in order, as the last child of its parent. Equivalent to:
+
+```js
+selection.each(function() {
+ this.parentNode.appendChild(this);
+});
+```
+
+# selection.lower() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/lower.js)
+
+Re-inserts each selected element, in order, as the first child of its parent. Equivalent to:
+
+```js
+selection.each(function() {
+ this.parentNode.insertBefore(this, this.parentNode.firstChild);
+});
+```
+
+# d3.create(name) · [Source](https://github.com/d3/d3-selection/blob/master/src/create.js)
+
+Given the specified element *name*, returns a single-element selection containing a detached element of the given name in the current document. This method assumes the HTML namespace, so you must specify a namespace explicitly when creating SVG or other non-HTML elements; see [namespace](#namespace) for details on supported namespace prefixes.
+
+```js
+d3.create("svg") // equivalent to svg:svg
+d3.create("svg:svg") // more explicitly
+d3.create("svg:g") // an SVG G element
+d3.create("g") // an HTML G (unknown) element
+```
+
+# d3.creator(name) · [Source](https://github.com/d3/d3-selection/blob/master/src/creator.js)
+
+Given the specified element *name*, returns a function which creates an element of the given name, assuming that `this` is the parent element. This method is used internally by [*selection*.append](#selection_append) and [*selection*.insert](#selection_insert) to create new elements. For example, this:
+
+```js
+selection.append("div");
+```
+
+Is equivalent to:
+
+```js
+selection.append(d3.creator("div"));
+```
+
+See [namespace](#namespace) for details on supported namespace prefixes, such as for SVG elements.
+
+### Joining Data
+
+For an introduction to D3’s data joins, see the [*selection*.join notebook](https://observablehq.com/@d3/selection-join). Also see [Thinking With Joins](http://bost.ocks.org/mike/join/).
+
+# selection.data([data[, key]]) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/data.js), [Examples](https://observablehq.com/@d3/brushable-scatterplot)
+
+Binds the specified array of *data* with the selected elements, returning a new selection that represents the *update* selection: the elements successfully bound to data. Also defines the [enter](#selection_enter) and [exit](#selection_exit) selections on the returned selection, which can be used to add or remove elements to correspond to the new data. The specified *data* is an array of arbitrary values (*e.g.*, numbers or objects), or a function that returns an array of values for each group. When data is assigned to an element, it is stored in the property `__data__`, thus making the data “sticky” and available on re-selection.
+
+The *data* is specified **for each group** in the selection. If the selection has multiple groups (such as [d3.selectAll](#selectAll) followed by [*selection*.selectAll](#selection_selectAll)), then *data* should typically be specified as a function. This function will be evaluated for each group in order, being passed the group’s parent datum (*d*, which may be undefined), the group index (*i*), and the selection’s parent nodes (*nodes*), with *this* as the group’s parent element.
+
+In conjunction with [*selection*.join](#selection_join) (or more explicitly with [*selection*.enter](#selection_enter), [*selection*.exit](#selection_exit), [*selection*.append](#selection_append) and [*selection*.remove](#selection_remove)), *selection*.data can be used to enter, update and exit elements to match data. For example, to create an HTML table from a matrix of numbers:
+
+```js
+const matrix = [
+ [11975, 5871, 8916, 2868],
+ [ 1951, 10048, 2060, 6171],
+ [ 8010, 16145, 8090, 8045],
+ [ 1013, 990, 940, 6907]
+];
+
+d3.select("body")
+ .append("table")
+ .selectAll("tr")
+ .data(matrix)
+ .join("tr")
+ .selectAll("td")
+ .data(d => d)
+ .join("td")
+ .text(d => d);
+```
+
+In this example the *data* function is the identity function: for each table row, it returns the corresponding row from the data matrix.
+
+If a *key* function is not specified, then the first datum in *data* is assigned to the first selected element, the second datum to the second selected element, and so on. A *key* function may be specified to control which datum is assigned to which element, replacing the default join-by-index, by computing a string identifier for each datum and element. This key function is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element (*nodes*[*i*]); the returned string is the element’s key. The key function is then also evaluated for each new datum in *data*, being passed the current datum (*d*), the current index (*i*), and the group’s new *data*, with *this* as the group’s parent DOM element; the returned string is the datum’s key. The datum for a given key is assigned to the element with the matching key. If multiple elements have the same key, the duplicate elements are put into the exit selection; if multiple data have the same key, the duplicate data are put into the enter selection.
+
+For example, given this document:
+
+```html
+
+
+
+
+
+
+```
+
+You could join data by key as follows:
+
+
+```js
+const data = [
+ {name: "Locke", number: 4},
+ {name: "Reyes", number: 8},
+ {name: "Ford", number: 15},
+ {name: "Jarrah", number: 16},
+ {name: "Shephard", number: 23},
+ {name: "Kwon", number: 42}
+];
+
+d3.selectAll("div")
+ .data(data, function(d) { return d ? d.name : this.id; })
+ .text(d => d.number);
+```
+
+This example key function uses the datum *d* if present, and otherwise falls back to the element’s id property. Since these elements were not previously bound to data, the datum *d* is null when the key function is evaluated on selected elements, and non-null when the key function is evaluated on the new data.
+
+The *update* and *enter* selections are returned in data order, while the *exit* selection preserves the selection order prior to the join. If a key function is specified, the order of elements in the selection may not match their order in the document; use [*selection*.order](#selection_order) or [*selection*.sort](#selection_sort) as needed. For more on how the key function affects the join, see [A Bar Chart, Part 2](http://bost.ocks.org/mike/bar/2/) and [Object Constancy](http://bost.ocks.org/mike/constancy/).
+
+If *data* is not specified, this method returns the array of data for the selected elements.
+
+This method cannot be used to clear bound data; use [*selection*.datum](#selection_datum) instead.
+
+# selection.join(enter[, update][, exit]) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/join.js)
+
+Appends, removes and reorders elements as necessary to match the data that was previously bound by [*selection*.data](#selection_data), returning the [merged](#selection_merge) enter and update selection. This method is a convenient alternative to the explicit [general update pattern](https://bl.ocks.org/mbostock/3808218), replacing [*selection*.enter](#selection_enter), [*selection*.exit](#selection_exit), [*selection*.append](#selection_append), [*selection*.remove](#selection_remove), and [*selection*.order](#selection_order). For example:
+
+```js
+svg.selectAll("circle")
+ .data(data)
+ .join("circle")
+ .attr("fill", "none")
+ .attr("stroke", "black");
+```
+
+The *enter* function may be specified as a string shorthand, as above, which is equivalent to [*selection*.append](#selection_append) with the given element name. Likewise, optional *update* and *exit* functions may be specified, which default to the identity function and calling [*selection*.remove](#selection_remove), respectively. The shorthand above is thus equivalent to:
+
+```js
+svg.selectAll("circle")
+ .data(data)
+ .join(
+ enter => enter.append("circle"),
+ update => update,
+ exit => exit.remove()
+ )
+ .attr("fill", "none")
+ .attr("stroke", "black");
+````
+
+By passing separate functions on enter, update and exit, you have greater control over what happens. And by specifying a key function to [*selection*.data](#selection_data), you can minimize changes to the DOM to optimize performance. For example, to set different fill colors for enter and update:
+
+```js
+svg.selectAll("circle")
+ .data(data)
+ .join(
+ enter => enter.append("circle").attr("fill", "green"),
+ update => update.attr("fill", "blue")
+ )
+ .attr("stroke", "black");
+```
+
+The selections returned by the *enter* and *update* functions are merged and then returned by *selection*.join.
+
+You can animate enter, update and exit by creating transitions inside the *enter*, *update* and *exit* functions. If the *enter* and *update* functions return transitions, their underlying selections are merged and then returned by *selection*.join. The return value of the *exit* function is not used.
+
+For more, see the [*selection*.join notebook](https://observablehq.com/@d3/selection-join).
+
+# selection.enter() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/enter.js)
+
+Returns the enter selection: placeholder nodes for each datum that had no corresponding DOM element in the selection. (The enter selection is empty for selections not returned by [*selection*.data](#selection_data).)
+
+The enter selection is typically used to create “missing” elements corresponding to new data. For example, to create DIV elements from an array of numbers:
+
+```js
+const div = d3.select("body")
+ .selectAll("div")
+ .data([4, 8, 15, 16, 23, 42])
+ .enter().append("div")
+ .text(d => d);
+```
+
+If the body is initially empty, the above code will create six new DIV elements, append them to the body in-order, and assign their text content as the associated (string-coerced) number:
+
+```html
+4
+8
+15
+16
+23
+42
+```
+
+Conceptually, the enter selection’s placeholders are pointers to the parent element (in this example, the document body). The enter selection is typically only used transiently to append elements, and is often [merged](#selection_merge) with the update selection after appending, such that modifications can be applied to both entering and updating elements.
+
+# selection.exit() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/exit.js)
+
+Returns the exit selection: existing DOM elements in the selection for which no new datum was found. (The exit selection is empty for selections not returned by [*selection*.data](#selection_data).)
+
+The exit selection is typically used to remove “superfluous” elements corresponding to old data. For example, to update the DIV elements created previously with a new array of numbers:
+
+```js
+div = div.data([1, 2, 4, 8, 16, 32], d => d);
+```
+
+Since a key function was specified (as the identity function), and the new data contains the numbers [4, 8, 16] which match existing elements in the document, the update selection contains three DIV elements. Leaving those elements as-is, we can append new elements for [1, 2, 32] using the enter selection:
+
+```js
+div.enter().append("div").text(d => d);
+```
+
+Likewise, to remove the exiting elements [15, 23, 42]:
+
+```js
+div.exit().remove();
+```
+
+Now the document body looks like this:
+
+```html
+1
+2
+4
+8
+16
+32
+```
+
+The order of the DOM elements matches the order of the data because the old data’s order and the new data’s order were consistent. If the new data’s order is different, use [*selection*.order](#selection_order) to reorder the elements in the DOM. See the [General Update Pattern](http://bl.ocks.org/mbostock/3808218) example thread for more on data joins.
+
+# selection.datum([value]) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/datum.js)
+
+Gets or sets the bound data for each selected element. Unlike [*selection*.data](#selection_data), this method does not compute a join and does not affect indexes or the enter and exit selections.
+
+If a *value* is specified, sets the element’s bound data to the specified value on all selected elements. If the *value* is a constant, all elements are given the same datum; otherwise, if the *value* is a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element (*nodes*[*i*]). The function is then used to set each element’s new data. A null value will delete the bound data.
+
+If a *value* is not specified, returns the bound datum for the first (non-null) element in the selection. This is generally useful only if you know the selection contains exactly one element.
+
+This method is useful for accessing HTML5 [custom data attributes](http://www.w3.org/TR/html5/dom.html#custom-data-attribute). For example, given the following elements:
+
+```html
+
+ - Shawn Allen
+ - Mike Bostock
+
+```
+
+You can expose the custom data attributes by setting each element’s data as the built-in [dataset](http://www.w3.org/TR/html5/dom.html#dom-dataset) property:
+
+```js
+selection.datum(function() { return this.dataset; })
+```
+
+### Handling Events
+
+For interaction, selections allow listening for and dispatching of events.
+
+# selection.on(typenames[, listener[, options]]) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/on.js)
+
+Adds or removes a *listener* to each selected element for the specified event *typenames*. The *typenames* is a string event type, such as `click`, `mouseover`, or `submit`; any [DOM event type](https://developer.mozilla.org/en-US/docs/Web/Events#Standard_events) supported by your browser may be used. The type may be optionally followed by a period (`.`) and a name; the optional name allows multiple callbacks to be registered to receive events of the same type, such as `click.foo` and `click.bar`. To specify multiple typenames, separate typenames with spaces, such as `input change` or `click.foo click.bar`.
+
+When a specified event is dispatched on a selected element, the specified *listener* will be evaluated for the element, being passed the current event (*event*) and the current datum (*d*), with *this* as the current DOM element (*event*.currentTarget). Listeners always see the latest datum for their element. Note: while you can use [*event*.pageX](https://developer.mozilla.org/en/DOM/event.pageX) and [*event*.pageY](https://developer.mozilla.org/en/DOM/event.pageY) directly, it is often convenient to transform the event position to the local coordinate system of the element that received the event using [d3.pointer](#pointer).
+
+If an event listener was previously registered for the same *typename* on a selected element, the old listener is removed before the new listener is added. To remove a listener, pass null as the *listener*. To remove all listeners for a given name, pass null as the *listener* and `.foo` as the *typename*, where `foo` is the name; to remove all listeners with no name, specify `.` as the *typename*.
+
+An optional *options* object may specify characteristics about the event listener, such as whether it is capturing or passive; see [*element*.addEventListener](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener).
+
+If a *listener* is not specified, returns the currently-assigned listener for the specified event *typename* on the first (non-null) selected element, if any. If multiple typenames are specified, the first matching listener is returned.
+
+# selection.dispatch(type[, parameters]) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/dispatch.js)
+
+Dispatches a [custom event](http://www.w3.org/TR/dom/#interface-customevent) of the specified *type* to each selected element, in order. An optional *parameters* map may be specified to set additional properties of the event. It may contain the following fields:
+
+* [`bubbles`](https://www.w3.org/TR/dom/#dom-event-bubbles) - if true, the event is dispatched to ancestors in reverse tree order.
+* [`cancelable`](https://www.w3.org/TR/dom/#dom-event-cancelable) - if true, *event*.preventDefault is allowed.
+* [`detail`](https://www.w3.org/TR/dom/#dom-customevent-detail) - any custom data associated with the event.
+
+If *parameters* is a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element (*nodes*[*i*]). It must return the parameters map for the current element.
+
+# d3.pointer(event[, target]) · [Source](https://github.com/d3/d3-selection/blob/master/src/pointer.js)
+
+Returns a two-element array of numbers [*x*, *y*] representing the coordinates of the specified *event* relative to the specified *target*. *event* can be a [MouseEvent](https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent), a [PointerEvent](https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent), a [Touch](https://www.w3.org/TR/touch-events/#touch-interface), or a custom event holding a UIEvent as *event*.sourceEvent.
+
+If *target* is not specified, it defaults to the source event’s currentTarget property, if available. If the *target* is an SVG element, the event’s coordinates are transformed using the [inverse](https://www.w3.org/TR/geometry-1/#dom-dommatrixreadonly-inverse) of the [screen coordinate transformation matrix](https://www.w3.org/TR/SVG/types.html#__svg__SVGGraphicsElement__getScreenCTM). If the *target* is an HTML element, the event’s coordinates are translated relative to the top-left corner of the *target*’s [bounding client rectangle](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect). (As such, the coordinate system can only be translated relative to the client coordinates. See also [GeometryUtils](https://www.w3.org/TR/cssom-view-1/#the-geometryutils-interface).) Otherwise, [*event*.pageX, *event*.pageY] is returned.
+
+# d3.pointers(event[, target]) · [Source](https://github.com/d3/d3-selection/blob/master/src/pointers.js)
+
+Returns an array [[*x0*, *y0*], [*x1*, *y1*]…] of coordinates of the specified *event*’s pointer locations relative to the specified *target*. For touch events, the returned array of positions corresponds to the *event*.touches array; for other events, returns a single-element array.
+
+If *target* is not specified, it defaults to the source event’s currentTarget property, if any.
+
+### Control Flow
+
+For advanced usage, selections provide methods for custom control flow.
+
+# selection.each(function) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/each.js)
+
+Invokes the specified *function* for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element (*nodes*[*i*]). This method can be used to invoke arbitrary code for each selected element, and is useful for creating a context to access parent and child data simultaneously, such as:
+
+```js
+parent.each(function(p, j) {
+ d3.select(this)
+ .selectAll(".child")
+ .text(d => `child ${d.name} of ${p.name}`);
+});
+```
+
+See [Sized Donut Multiples](http://bl.ocks.org/mbostock/4c5fad723c87d2fd8273) for an example.
+
+# selection.call(function[, arguments…]) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/call.js)
+
+Invokes the specified *function* exactly once, passing in this selection along with any optional *arguments*. Returns this selection. This is equivalent to invoking the function by hand but facilitates method chaining. For example, to set several styles in a reusable function:
+
+```js
+function name(selection, first, last) {
+ selection
+ .attr("first-name", first)
+ .attr("last-name", last);
+}
+```
+
+Now say:
+
+```js
+d3.selectAll("div").call(name, "John", "Snow");
+```
+
+This is roughly equivalent to:
+
+```js
+name(d3.selectAll("div"), "John", "Snow");
+```
+
+The only difference is that *selection*.call always returns the *selection* and not the return value of the called *function*, `name`.
+
+# selection.empty() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/empty.js)
+
+Returns true if this selection contains no (non-null) elements.
+
+# selection.nodes() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/nodes.js)
+
+Returns an array of all (non-null) elements in this selection. Equivalent to:
+
+```js
+const elements = Array.from(selection);
+````
+
+See also [*selection*[Symbol.iterator]](#selection_iterator).
+
+# selection.node() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/node.js)
+
+Returns the first (non-null) element in this selection. If the selection is empty, returns null.
+
+# selection.size() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/size.js)
+
+Returns the total number of (non-null) elements in this selection.
+
+# selection\[Symbol.iterator\]() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/iterator.js)
+
+Returns an iterator over the selected (non-null) elements. For example, to iterate over the selected elements:
+
+```js
+for (const element of selection) {
+ console.log(element);
+}
+```
+
+To flatten the selection to an array:
+
+```js
+const elements = [...selection];
+````
+
+### Local Variables
+
+D3 locals allow you to define local state independent of data. For instance, when rendering [small multiples](http://bl.ocks.org/mbostock/e1192fe405703d8321a5187350910e08) of time-series data, you might want the same *x*-scale for all charts but distinct *y*-scales to compare the relative performance of each metric. D3 locals are scoped by DOM elements: on set, the value is stored on the given element; on get, the value is retrieved from given element or the nearest ancestor that defines it.
+
+# d3.local() · [Source](https://github.com/d3/d3-selection/blob/master/src/local.js)
+
+Declares a new local variable. For example:
+
+```js
+const foo = d3.local();
+```
+
+Like `var`, each local is a distinct symbolic reference; unlike `var`, the value of each local is also scoped by the DOM.
+
+# local.set(node, value) · [Source](https://github.com/d3/d3-selection/blob/master/src/local.js)
+
+Sets the value of this local on the specified *node* to the *value*, and returns the specified *value*. This is often performed using [*selection*.each](#selection_each):
+
+```js
+selection.each(function(d) { foo.set(this, d.value); });
+```
+
+If you are just setting a single variable, consider using [*selection*.property](#selection_property):
+
+```js
+selection.property(foo, d => d.value);
+```
+
+# local.get(node) · [Source](https://github.com/d3/d3-selection/blob/master/src/local.js)
+
+Returns the value of this local on the specified *node*. If the *node* does not define this local, returns the value from the nearest ancestor that defines it. Returns undefined if no ancestor defines this local.
+
+# local.remove(node) · [Source](https://github.com/d3/d3-selection/blob/master/src/local.js)
+
+Deletes this local’s value from the specified *node*. Returns true if the *node* defined this local prior to removal, and false otherwise. If ancestors also define this local, those definitions are unaffected, and thus [*local*.get](#local_get) will still return the inherited value.
+
+# local.toString() · [Source](https://github.com/d3/d3-selection/blob/master/src/local.js)
+
+Returns the automatically-generated identifier for this local. This is the name of the property that is used to store the local’s value on elements, and thus you can also set or get the local’s value using *element*[*local*] or by using [*selection*.property](#selection_property).
+
+### Namespaces
+
+XML namespaces are fun! Right? Fortunately you can mostly ignore them.
+
+# d3.namespace(name) · [Source](https://github.com/d3/d3-selection/blob/master/src/namespace.js)
+
+Qualifies the specified *name*, which may or may not have a namespace prefix. If the name contains a colon (`:`), the substring before the colon is interpreted as the namespace prefix, which must be registered in [d3.namespaces](#namespaces). Returns an object `space` and `local` attributes describing the full namespace URL and the local name. For example:
+
+```js
+d3.namespace("svg:text"); // {space: "http://www.w3.org/2000/svg", local: "text"}
+```
+
+If the name does not contain a colon, this function merely returns the input name.
+
+# d3.namespaces · [Source](https://github.com/d3/d3-selection/blob/master/src/namespaces.js)
+
+The map of registered namespace prefixes. The initial value is:
+
+```js
+{
+ svg: "http://www.w3.org/2000/svg",
+ xhtml: "http://www.w3.org/1999/xhtml",
+ xlink: "http://www.w3.org/1999/xlink",
+ xml: "http://www.w3.org/XML/1998/namespace",
+ xmlns: "http://www.w3.org/2000/xmlns/"
+}
+```
+
+Additional prefixes may be assigned as needed to create elements or attributes in other namespaces.
diff --git a/node_modules/d3-selection/dist/d3-selection.js b/node_modules/d3-selection/dist/d3-selection.js
new file mode 100644
index 00000000..9ffc1e84
--- /dev/null
+++ b/node_modules/d3-selection/dist/d3-selection.js
@@ -0,0 +1,1022 @@
+// https://d3js.org/d3-selection/ v3.0.0 Copyright 2010-2021 Mike Bostock
+(function (global, factory) {
+typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+typeof define === 'function' && define.amd ? define(['exports'], factory) :
+(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}));
+}(this, (function (exports) { 'use strict';
+
+var xhtml = "http://www.w3.org/1999/xhtml";
+
+var namespaces = {
+ svg: "http://www.w3.org/2000/svg",
+ xhtml: xhtml,
+ xlink: "http://www.w3.org/1999/xlink",
+ xml: "http://www.w3.org/XML/1998/namespace",
+ xmlns: "http://www.w3.org/2000/xmlns/"
+};
+
+function namespace(name) {
+ var prefix = name += "", i = prefix.indexOf(":");
+ if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1);
+ return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name; // eslint-disable-line no-prototype-builtins
+}
+
+function creatorInherit(name) {
+ return function() {
+ var document = this.ownerDocument,
+ uri = this.namespaceURI;
+ return uri === xhtml && document.documentElement.namespaceURI === xhtml
+ ? document.createElement(name)
+ : document.createElementNS(uri, name);
+ };
+}
+
+function creatorFixed(fullname) {
+ return function() {
+ return this.ownerDocument.createElementNS(fullname.space, fullname.local);
+ };
+}
+
+function creator(name) {
+ var fullname = namespace(name);
+ return (fullname.local
+ ? creatorFixed
+ : creatorInherit)(fullname);
+}
+
+function none() {}
+
+function selector(selector) {
+ return selector == null ? none : function() {
+ return this.querySelector(selector);
+ };
+}
+
+function selection_select(select) {
+ if (typeof select !== "function") select = selector(select);
+
+ for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
+ for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
+ if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
+ if ("__data__" in node) subnode.__data__ = node.__data__;
+ subgroup[i] = subnode;
+ }
+ }
+ }
+
+ return new Selection(subgroups, this._parents);
+}
+
+// Given something array like (or null), returns something that is strictly an
+// array. This is used to ensure that array-like objects passed to d3.selectAll
+// or selection.selectAll are converted into proper arrays when creating a
+// selection; we don’t ever want to create a selection backed by a live
+// HTMLCollection or NodeList. However, note that selection.selectAll will use a
+// static NodeList as a group, since it safely derived from querySelectorAll.
+function array(x) {
+ return x == null ? [] : Array.isArray(x) ? x : Array.from(x);
+}
+
+function empty() {
+ return [];
+}
+
+function selectorAll(selector) {
+ return selector == null ? empty : function() {
+ return this.querySelectorAll(selector);
+ };
+}
+
+function arrayAll(select) {
+ return function() {
+ return array(select.apply(this, arguments));
+ };
+}
+
+function selection_selectAll(select) {
+ if (typeof select === "function") select = arrayAll(select);
+ else select = selectorAll(select);
+
+ for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
+ for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
+ if (node = group[i]) {
+ subgroups.push(select.call(node, node.__data__, i, group));
+ parents.push(node);
+ }
+ }
+ }
+
+ return new Selection(subgroups, parents);
+}
+
+function matcher(selector) {
+ return function() {
+ return this.matches(selector);
+ };
+}
+
+function childMatcher(selector) {
+ return function(node) {
+ return node.matches(selector);
+ };
+}
+
+var find = Array.prototype.find;
+
+function childFind(match) {
+ return function() {
+ return find.call(this.children, match);
+ };
+}
+
+function childFirst() {
+ return this.firstElementChild;
+}
+
+function selection_selectChild(match) {
+ return this.select(match == null ? childFirst
+ : childFind(typeof match === "function" ? match : childMatcher(match)));
+}
+
+var filter = Array.prototype.filter;
+
+function children() {
+ return Array.from(this.children);
+}
+
+function childrenFilter(match) {
+ return function() {
+ return filter.call(this.children, match);
+ };
+}
+
+function selection_selectChildren(match) {
+ return this.selectAll(match == null ? children
+ : childrenFilter(typeof match === "function" ? match : childMatcher(match)));
+}
+
+function selection_filter(match) {
+ if (typeof match !== "function") match = matcher(match);
+
+ for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
+ for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
+ if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
+ subgroup.push(node);
+ }
+ }
+ }
+
+ return new Selection(subgroups, this._parents);
+}
+
+function sparse(update) {
+ return new Array(update.length);
+}
+
+function selection_enter() {
+ return new Selection(this._enter || this._groups.map(sparse), this._parents);
+}
+
+function EnterNode(parent, datum) {
+ this.ownerDocument = parent.ownerDocument;
+ this.namespaceURI = parent.namespaceURI;
+ this._next = null;
+ this._parent = parent;
+ this.__data__ = datum;
+}
+
+EnterNode.prototype = {
+ constructor: EnterNode,
+ appendChild: function(child) { return this._parent.insertBefore(child, this._next); },
+ insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },
+ querySelector: function(selector) { return this._parent.querySelector(selector); },
+ querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }
+};
+
+function constant(x) {
+ return function() {
+ return x;
+ };
+}
+
+function bindIndex(parent, group, enter, update, exit, data) {
+ var i = 0,
+ node,
+ groupLength = group.length,
+ dataLength = data.length;
+
+ // Put any non-null nodes that fit into update.
+ // Put any null nodes into enter.
+ // Put any remaining data into enter.
+ for (; i < dataLength; ++i) {
+ if (node = group[i]) {
+ node.__data__ = data[i];
+ update[i] = node;
+ } else {
+ enter[i] = new EnterNode(parent, data[i]);
+ }
+ }
+
+ // Put any non-null nodes that don’t fit into exit.
+ for (; i < groupLength; ++i) {
+ if (node = group[i]) {
+ exit[i] = node;
+ }
+ }
+}
+
+function bindKey(parent, group, enter, update, exit, data, key) {
+ var i,
+ node,
+ nodeByKeyValue = new Map,
+ groupLength = group.length,
+ dataLength = data.length,
+ keyValues = new Array(groupLength),
+ keyValue;
+
+ // Compute the key for each node.
+ // If multiple nodes have the same key, the duplicates are added to exit.
+ for (i = 0; i < groupLength; ++i) {
+ if (node = group[i]) {
+ keyValues[i] = keyValue = key.call(node, node.__data__, i, group) + "";
+ if (nodeByKeyValue.has(keyValue)) {
+ exit[i] = node;
+ } else {
+ nodeByKeyValue.set(keyValue, node);
+ }
+ }
+ }
+
+ // Compute the key for each datum.
+ // If there a node associated with this key, join and add it to update.
+ // If there is not (or the key is a duplicate), add it to enter.
+ for (i = 0; i < dataLength; ++i) {
+ keyValue = key.call(parent, data[i], i, data) + "";
+ if (node = nodeByKeyValue.get(keyValue)) {
+ update[i] = node;
+ node.__data__ = data[i];
+ nodeByKeyValue.delete(keyValue);
+ } else {
+ enter[i] = new EnterNode(parent, data[i]);
+ }
+ }
+
+ // Add any remaining nodes that were not bound to data to exit.
+ for (i = 0; i < groupLength; ++i) {
+ if ((node = group[i]) && (nodeByKeyValue.get(keyValues[i]) === node)) {
+ exit[i] = node;
+ }
+ }
+}
+
+function datum(node) {
+ return node.__data__;
+}
+
+function selection_data(value, key) {
+ if (!arguments.length) return Array.from(this, datum);
+
+ var bind = key ? bindKey : bindIndex,
+ parents = this._parents,
+ groups = this._groups;
+
+ if (typeof value !== "function") value = constant(value);
+
+ for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {
+ var parent = parents[j],
+ group = groups[j],
+ groupLength = group.length,
+ data = arraylike(value.call(parent, parent && parent.__data__, j, parents)),
+ dataLength = data.length,
+ enterGroup = enter[j] = new Array(dataLength),
+ updateGroup = update[j] = new Array(dataLength),
+ exitGroup = exit[j] = new Array(groupLength);
+
+ bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);
+
+ // Now connect the enter nodes to their following update node, such that
+ // appendChild can insert the materialized enter node before this node,
+ // rather than at the end of the parent node.
+ for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {
+ if (previous = enterGroup[i0]) {
+ if (i0 >= i1) i1 = i0 + 1;
+ while (!(next = updateGroup[i1]) && ++i1 < dataLength);
+ previous._next = next || null;
+ }
+ }
+ }
+
+ update = new Selection(update, parents);
+ update._enter = enter;
+ update._exit = exit;
+ return update;
+}
+
+// Given some data, this returns an array-like view of it: an object that
+// exposes a length property and allows numeric indexing. Note that unlike
+// selectAll, this isn’t worried about “live” collections because the resulting
+// array will only be used briefly while data is being bound. (It is possible to
+// cause the data to change while iterating by using a key function, but please
+// don’t; we’d rather avoid a gratuitous copy.)
+function arraylike(data) {
+ return typeof data === "object" && "length" in data
+ ? data // Array, TypedArray, NodeList, array-like
+ : Array.from(data); // Map, Set, iterable, string, or anything else
+}
+
+function selection_exit() {
+ return new Selection(this._exit || this._groups.map(sparse), this._parents);
+}
+
+function selection_join(onenter, onupdate, onexit) {
+ var enter = this.enter(), update = this, exit = this.exit();
+ if (typeof onenter === "function") {
+ enter = onenter(enter);
+ if (enter) enter = enter.selection();
+ } else {
+ enter = enter.append(onenter + "");
+ }
+ if (onupdate != null) {
+ update = onupdate(update);
+ if (update) update = update.selection();
+ }
+ if (onexit == null) exit.remove(); else onexit(exit);
+ return enter && update ? enter.merge(update).order() : update;
+}
+
+function selection_merge(context) {
+ var selection = context.selection ? context.selection() : context;
+
+ for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
+ for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
+ if (node = group0[i] || group1[i]) {
+ merge[i] = node;
+ }
+ }
+ }
+
+ for (; j < m0; ++j) {
+ merges[j] = groups0[j];
+ }
+
+ return new Selection(merges, this._parents);
+}
+
+function selection_order() {
+
+ for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {
+ for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {
+ if (node = group[i]) {
+ if (next && node.compareDocumentPosition(next) ^ 4) next.parentNode.insertBefore(node, next);
+ next = node;
+ }
+ }
+ }
+
+ return this;
+}
+
+function selection_sort(compare) {
+ if (!compare) compare = ascending;
+
+ function compareNode(a, b) {
+ return a && b ? compare(a.__data__, b.__data__) : !a - !b;
+ }
+
+ for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {
+ for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {
+ if (node = group[i]) {
+ sortgroup[i] = node;
+ }
+ }
+ sortgroup.sort(compareNode);
+ }
+
+ return new Selection(sortgroups, this._parents).order();
+}
+
+function ascending(a, b) {
+ return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
+}
+
+function selection_call() {
+ var callback = arguments[0];
+ arguments[0] = this;
+ callback.apply(null, arguments);
+ return this;
+}
+
+function selection_nodes() {
+ return Array.from(this);
+}
+
+function selection_node() {
+
+ for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
+ for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {
+ var node = group[i];
+ if (node) return node;
+ }
+ }
+
+ return null;
+}
+
+function selection_size() {
+ let size = 0;
+ for (const node of this) ++size; // eslint-disable-line no-unused-vars
+ return size;
+}
+
+function selection_empty() {
+ return !this.node();
+}
+
+function selection_each(callback) {
+
+ for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
+ for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {
+ if (node = group[i]) callback.call(node, node.__data__, i, group);
+ }
+ }
+
+ return this;
+}
+
+function attrRemove(name) {
+ return function() {
+ this.removeAttribute(name);
+ };
+}
+
+function attrRemoveNS(fullname) {
+ return function() {
+ this.removeAttributeNS(fullname.space, fullname.local);
+ };
+}
+
+function attrConstant(name, value) {
+ return function() {
+ this.setAttribute(name, value);
+ };
+}
+
+function attrConstantNS(fullname, value) {
+ return function() {
+ this.setAttributeNS(fullname.space, fullname.local, value);
+ };
+}
+
+function attrFunction(name, value) {
+ return function() {
+ var v = value.apply(this, arguments);
+ if (v == null) this.removeAttribute(name);
+ else this.setAttribute(name, v);
+ };
+}
+
+function attrFunctionNS(fullname, value) {
+ return function() {
+ var v = value.apply(this, arguments);
+ if (v == null) this.removeAttributeNS(fullname.space, fullname.local);
+ else this.setAttributeNS(fullname.space, fullname.local, v);
+ };
+}
+
+function selection_attr(name, value) {
+ var fullname = namespace(name);
+
+ if (arguments.length < 2) {
+ var node = this.node();
+ return fullname.local
+ ? node.getAttributeNS(fullname.space, fullname.local)
+ : node.getAttribute(fullname);
+ }
+
+ return this.each((value == null
+ ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function"
+ ? (fullname.local ? attrFunctionNS : attrFunction)
+ : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));
+}
+
+function defaultView(node) {
+ return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node
+ || (node.document && node) // node is a Window
+ || node.defaultView; // node is a Document
+}
+
+function styleRemove(name) {
+ return function() {
+ this.style.removeProperty(name);
+ };
+}
+
+function styleConstant(name, value, priority) {
+ return function() {
+ this.style.setProperty(name, value, priority);
+ };
+}
+
+function styleFunction(name, value, priority) {
+ return function() {
+ var v = value.apply(this, arguments);
+ if (v == null) this.style.removeProperty(name);
+ else this.style.setProperty(name, v, priority);
+ };
+}
+
+function selection_style(name, value, priority) {
+ return arguments.length > 1
+ ? this.each((value == null
+ ? styleRemove : typeof value === "function"
+ ? styleFunction
+ : styleConstant)(name, value, priority == null ? "" : priority))
+ : styleValue(this.node(), name);
+}
+
+function styleValue(node, name) {
+ return node.style.getPropertyValue(name)
+ || defaultView(node).getComputedStyle(node, null).getPropertyValue(name);
+}
+
+function propertyRemove(name) {
+ return function() {
+ delete this[name];
+ };
+}
+
+function propertyConstant(name, value) {
+ return function() {
+ this[name] = value;
+ };
+}
+
+function propertyFunction(name, value) {
+ return function() {
+ var v = value.apply(this, arguments);
+ if (v == null) delete this[name];
+ else this[name] = v;
+ };
+}
+
+function selection_property(name, value) {
+ return arguments.length > 1
+ ? this.each((value == null
+ ? propertyRemove : typeof value === "function"
+ ? propertyFunction
+ : propertyConstant)(name, value))
+ : this.node()[name];
+}
+
+function classArray(string) {
+ return string.trim().split(/^|\s+/);
+}
+
+function classList(node) {
+ return node.classList || new ClassList(node);
+}
+
+function ClassList(node) {
+ this._node = node;
+ this._names = classArray(node.getAttribute("class") || "");
+}
+
+ClassList.prototype = {
+ add: function(name) {
+ var i = this._names.indexOf(name);
+ if (i < 0) {
+ this._names.push(name);
+ this._node.setAttribute("class", this._names.join(" "));
+ }
+ },
+ remove: function(name) {
+ var i = this._names.indexOf(name);
+ if (i >= 0) {
+ this._names.splice(i, 1);
+ this._node.setAttribute("class", this._names.join(" "));
+ }
+ },
+ contains: function(name) {
+ return this._names.indexOf(name) >= 0;
+ }
+};
+
+function classedAdd(node, names) {
+ var list = classList(node), i = -1, n = names.length;
+ while (++i < n) list.add(names[i]);
+}
+
+function classedRemove(node, names) {
+ var list = classList(node), i = -1, n = names.length;
+ while (++i < n) list.remove(names[i]);
+}
+
+function classedTrue(names) {
+ return function() {
+ classedAdd(this, names);
+ };
+}
+
+function classedFalse(names) {
+ return function() {
+ classedRemove(this, names);
+ };
+}
+
+function classedFunction(names, value) {
+ return function() {
+ (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);
+ };
+}
+
+function selection_classed(name, value) {
+ var names = classArray(name + "");
+
+ if (arguments.length < 2) {
+ var list = classList(this.node()), i = -1, n = names.length;
+ while (++i < n) if (!list.contains(names[i])) return false;
+ return true;
+ }
+
+ return this.each((typeof value === "function"
+ ? classedFunction : value
+ ? classedTrue
+ : classedFalse)(names, value));
+}
+
+function textRemove() {
+ this.textContent = "";
+}
+
+function textConstant(value) {
+ return function() {
+ this.textContent = value;
+ };
+}
+
+function textFunction(value) {
+ return function() {
+ var v = value.apply(this, arguments);
+ this.textContent = v == null ? "" : v;
+ };
+}
+
+function selection_text(value) {
+ return arguments.length
+ ? this.each(value == null
+ ? textRemove : (typeof value === "function"
+ ? textFunction
+ : textConstant)(value))
+ : this.node().textContent;
+}
+
+function htmlRemove() {
+ this.innerHTML = "";
+}
+
+function htmlConstant(value) {
+ return function() {
+ this.innerHTML = value;
+ };
+}
+
+function htmlFunction(value) {
+ return function() {
+ var v = value.apply(this, arguments);
+ this.innerHTML = v == null ? "" : v;
+ };
+}
+
+function selection_html(value) {
+ return arguments.length
+ ? this.each(value == null
+ ? htmlRemove : (typeof value === "function"
+ ? htmlFunction
+ : htmlConstant)(value))
+ : this.node().innerHTML;
+}
+
+function raise() {
+ if (this.nextSibling) this.parentNode.appendChild(this);
+}
+
+function selection_raise() {
+ return this.each(raise);
+}
+
+function lower() {
+ if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);
+}
+
+function selection_lower() {
+ return this.each(lower);
+}
+
+function selection_append(name) {
+ var create = typeof name === "function" ? name : creator(name);
+ return this.select(function() {
+ return this.appendChild(create.apply(this, arguments));
+ });
+}
+
+function constantNull() {
+ return null;
+}
+
+function selection_insert(name, before) {
+ var create = typeof name === "function" ? name : creator(name),
+ select = before == null ? constantNull : typeof before === "function" ? before : selector(before);
+ return this.select(function() {
+ return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);
+ });
+}
+
+function remove() {
+ var parent = this.parentNode;
+ if (parent) parent.removeChild(this);
+}
+
+function selection_remove() {
+ return this.each(remove);
+}
+
+function selection_cloneShallow() {
+ var clone = this.cloneNode(false), parent = this.parentNode;
+ return parent ? parent.insertBefore(clone, this.nextSibling) : clone;
+}
+
+function selection_cloneDeep() {
+ var clone = this.cloneNode(true), parent = this.parentNode;
+ return parent ? parent.insertBefore(clone, this.nextSibling) : clone;
+}
+
+function selection_clone(deep) {
+ return this.select(deep ? selection_cloneDeep : selection_cloneShallow);
+}
+
+function selection_datum(value) {
+ return arguments.length
+ ? this.property("__data__", value)
+ : this.node().__data__;
+}
+
+function contextListener(listener) {
+ return function(event) {
+ listener.call(this, event, this.__data__);
+ };
+}
+
+function parseTypenames(typenames) {
+ return typenames.trim().split(/^|\s+/).map(function(t) {
+ var name = "", i = t.indexOf(".");
+ if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
+ return {type: t, name: name};
+ });
+}
+
+function onRemove(typename) {
+ return function() {
+ var on = this.__on;
+ if (!on) return;
+ for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {
+ if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {
+ this.removeEventListener(o.type, o.listener, o.options);
+ } else {
+ on[++i] = o;
+ }
+ }
+ if (++i) on.length = i;
+ else delete this.__on;
+ };
+}
+
+function onAdd(typename, value, options) {
+ return function() {
+ var on = this.__on, o, listener = contextListener(value);
+ if (on) for (var j = 0, m = on.length; j < m; ++j) {
+ if ((o = on[j]).type === typename.type && o.name === typename.name) {
+ this.removeEventListener(o.type, o.listener, o.options);
+ this.addEventListener(o.type, o.listener = listener, o.options = options);
+ o.value = value;
+ return;
+ }
+ }
+ this.addEventListener(typename.type, listener, options);
+ o = {type: typename.type, name: typename.name, value: value, listener: listener, options: options};
+ if (!on) this.__on = [o];
+ else on.push(o);
+ };
+}
+
+function selection_on(typename, value, options) {
+ var typenames = parseTypenames(typename + ""), i, n = typenames.length, t;
+
+ if (arguments.length < 2) {
+ var on = this.node().__on;
+ if (on) for (var j = 0, m = on.length, o; j < m; ++j) {
+ for (i = 0, o = on[j]; i < n; ++i) {
+ if ((t = typenames[i]).type === o.type && t.name === o.name) {
+ return o.value;
+ }
+ }
+ }
+ return;
+ }
+
+ on = value ? onAdd : onRemove;
+ for (i = 0; i < n; ++i) this.each(on(typenames[i], value, options));
+ return this;
+}
+
+function dispatchEvent(node, type, params) {
+ var window = defaultView(node),
+ event = window.CustomEvent;
+
+ if (typeof event === "function") {
+ event = new event(type, params);
+ } else {
+ event = window.document.createEvent("Event");
+ if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;
+ else event.initEvent(type, false, false);
+ }
+
+ node.dispatchEvent(event);
+}
+
+function dispatchConstant(type, params) {
+ return function() {
+ return dispatchEvent(this, type, params);
+ };
+}
+
+function dispatchFunction(type, params) {
+ return function() {
+ return dispatchEvent(this, type, params.apply(this, arguments));
+ };
+}
+
+function selection_dispatch(type, params) {
+ return this.each((typeof params === "function"
+ ? dispatchFunction
+ : dispatchConstant)(type, params));
+}
+
+function* selection_iterator() {
+ for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
+ for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {
+ if (node = group[i]) yield node;
+ }
+ }
+}
+
+var root = [null];
+
+function Selection(groups, parents) {
+ this._groups = groups;
+ this._parents = parents;
+}
+
+function selection() {
+ return new Selection([[document.documentElement]], root);
+}
+
+function selection_selection() {
+ return this;
+}
+
+Selection.prototype = selection.prototype = {
+ constructor: Selection,
+ select: selection_select,
+ selectAll: selection_selectAll,
+ selectChild: selection_selectChild,
+ selectChildren: selection_selectChildren,
+ filter: selection_filter,
+ data: selection_data,
+ enter: selection_enter,
+ exit: selection_exit,
+ join: selection_join,
+ merge: selection_merge,
+ selection: selection_selection,
+ order: selection_order,
+ sort: selection_sort,
+ call: selection_call,
+ nodes: selection_nodes,
+ node: selection_node,
+ size: selection_size,
+ empty: selection_empty,
+ each: selection_each,
+ attr: selection_attr,
+ style: selection_style,
+ property: selection_property,
+ classed: selection_classed,
+ text: selection_text,
+ html: selection_html,
+ raise: selection_raise,
+ lower: selection_lower,
+ append: selection_append,
+ insert: selection_insert,
+ remove: selection_remove,
+ clone: selection_clone,
+ datum: selection_datum,
+ on: selection_on,
+ dispatch: selection_dispatch,
+ [Symbol.iterator]: selection_iterator
+};
+
+function select(selector) {
+ return typeof selector === "string"
+ ? new Selection([[document.querySelector(selector)]], [document.documentElement])
+ : new Selection([[selector]], root);
+}
+
+function create(name) {
+ return select(creator(name).call(document.documentElement));
+}
+
+var nextId = 0;
+
+function local() {
+ return new Local;
+}
+
+function Local() {
+ this._ = "@" + (++nextId).toString(36);
+}
+
+Local.prototype = local.prototype = {
+ constructor: Local,
+ get: function(node) {
+ var id = this._;
+ while (!(id in node)) if (!(node = node.parentNode)) return;
+ return node[id];
+ },
+ set: function(node, value) {
+ return node[this._] = value;
+ },
+ remove: function(node) {
+ return this._ in node && delete node[this._];
+ },
+ toString: function() {
+ return this._;
+ }
+};
+
+function sourceEvent(event) {
+ let sourceEvent;
+ while (sourceEvent = event.sourceEvent) event = sourceEvent;
+ return event;
+}
+
+function pointer(event, node) {
+ event = sourceEvent(event);
+ if (node === undefined) node = event.currentTarget;
+ if (node) {
+ var svg = node.ownerSVGElement || node;
+ if (svg.createSVGPoint) {
+ var point = svg.createSVGPoint();
+ point.x = event.clientX, point.y = event.clientY;
+ point = point.matrixTransform(node.getScreenCTM().inverse());
+ return [point.x, point.y];
+ }
+ if (node.getBoundingClientRect) {
+ var rect = node.getBoundingClientRect();
+ return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
+ }
+ }
+ return [event.pageX, event.pageY];
+}
+
+function pointers(events, node) {
+ if (events.target) { // i.e., instanceof Event, not TouchList or iterable
+ events = sourceEvent(events);
+ if (node === undefined) node = events.currentTarget;
+ events = events.touches || [events];
+ }
+ return Array.from(events, event => pointer(event, node));
+}
+
+function selectAll(selector) {
+ return typeof selector === "string"
+ ? new Selection([document.querySelectorAll(selector)], [document.documentElement])
+ : new Selection([array(selector)], root);
+}
+
+exports.create = create;
+exports.creator = creator;
+exports.local = local;
+exports.matcher = matcher;
+exports.namespace = namespace;
+exports.namespaces = namespaces;
+exports.pointer = pointer;
+exports.pointers = pointers;
+exports.select = select;
+exports.selectAll = selectAll;
+exports.selection = selection;
+exports.selector = selector;
+exports.selectorAll = selectorAll;
+exports.style = styleValue;
+exports.window = defaultView;
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+})));
diff --git a/node_modules/d3-selection/dist/d3-selection.min.js b/node_modules/d3-selection/dist/d3-selection.min.js
new file mode 100644
index 00000000..37a57073
--- /dev/null
+++ b/node_modules/d3-selection/dist/d3-selection.min.js
@@ -0,0 +1,2 @@
+// https://d3js.org/d3-selection/ v3.0.0 Copyright 2010-2021 Mike Bostock
+!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self).d3=t.d3||{})}(this,(function(t){"use strict";var n="http://www.w3.org/1999/xhtml",e={svg:"http://www.w3.org/2000/svg",xhtml:n,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function r(t){var n=t+="",r=n.indexOf(":");return r>=0&&"xmlns"!==(n=t.slice(0,r))&&(t=t.slice(r+1)),e.hasOwnProperty(n)?{space:e[n],local:t}:t}function i(t){return function(){var e=this.ownerDocument,r=this.namespaceURI;return r===n&&e.documentElement.namespaceURI===n?e.createElement(t):e.createElementNS(r,t)}}function o(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}function u(t){var n=r(t);return(n.local?o:i)(n)}function s(){}function c(t){return null==t?s:function(){return this.querySelector(t)}}function l(t){return null==t?[]:Array.isArray(t)?t:Array.from(t)}function a(){return[]}function f(t){return null==t?a:function(){return this.querySelectorAll(t)}}function h(t){return function(){return this.matches(t)}}function p(t){return function(n){return n.matches(t)}}var _=Array.prototype.find;function d(){return this.firstElementChild}var y=Array.prototype.filter;function m(){return Array.from(this.children)}function v(t){return new Array(t.length)}function g(t,n){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=n}function w(t){return function(){return t}}function A(t,n,e,r,i,o){for(var u,s=0,c=n.length,l=o.length;sn?1:t>=n?0:NaN}function N(t){return function(){this.removeAttribute(t)}}function C(t){return function(){this.removeAttributeNS(t.space,t.local)}}function L(t,n){return function(){this.setAttribute(t,n)}}function P(t,n){return function(){this.setAttributeNS(t.space,t.local,n)}}function T(t,n){return function(){var e=n.apply(this,arguments);null==e?this.removeAttribute(t):this.setAttribute(t,e)}}function B(t,n){return function(){var e=n.apply(this,arguments);null==e?this.removeAttributeNS(t.space,t.local):this.setAttributeNS(t.space,t.local,e)}}function M(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}function q(t){return function(){this.style.removeProperty(t)}}function D(t,n,e){return function(){this.style.setProperty(t,n,e)}}function O(t,n,e){return function(){var r=n.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,e)}}function V(t,n){return t.style.getPropertyValue(n)||M(t).getComputedStyle(t,null).getPropertyValue(n)}function j(t){return function(){delete this[t]}}function R(t,n){return function(){this[t]=n}}function H(t,n){return function(){var e=n.apply(this,arguments);null==e?delete this[t]:this[t]=e}}function I(t){return t.trim().split(/^|\s+/)}function U(t){return t.classList||new X(t)}function X(t){this._node=t,this._names=I(t.getAttribute("class")||"")}function G(t,n){for(var e=U(t),r=-1,i=n.length;++r=0&&(n=t.slice(e+1),t=t.slice(0,e)),{type:t,name:n}}))}function st(t){return function(){var n=this.__on;if(n){for(var e,r=0,i=-1,o=n.length;r=0&&(this._names.splice(n,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};var ht=[null];function pt(t,n){this._groups=t,this._parents=n}function _t(){return new pt([[document.documentElement]],ht)}function dt(t){return"string"==typeof t?new pt([[document.querySelector(t)]],[document.documentElement]):new pt([[t]],ht)}pt.prototype=_t.prototype={constructor:pt,select:function(t){"function"!=typeof t&&(t=c(t));for(var n=this._groups,e=n.length,r=new Array(e),i=0;i=N&&(N=E+1);!(g=y[N])&&++N<_;);v._next=g||null}}return(u=new pt(u,r))._enter=s,u._exit=c,u},enter:function(){return new pt(this._enter||this._groups.map(v),this._parents)},exit:function(){return new pt(this._exit||this._groups.map(v),this._parents)},join:function(t,n,e){var r=this.enter(),i=this,o=this.exit();return"function"==typeof t?(r=t(r))&&(r=r.selection()):r=r.append(t+""),null!=n&&(i=n(i))&&(i=i.selection()),null==e?o.remove():e(o),r&&i?r.merge(i).order():i},merge:function(t){for(var n=t.selection?t.selection():t,e=this._groups,r=n._groups,i=e.length,o=r.length,u=Math.min(i,o),s=new Array(i),c=0;c=0;)(r=i[o])&&(u&&4^r.compareDocumentPosition(u)&&u.parentNode.insertBefore(r,u),u=r);return this},sort:function(t){function n(n,e){return n&&e?t(n.__data__,e.__data__):!n-!e}t||(t=E);for(var e=this._groups,r=e.length,i=new Array(r),o=0;o1?this.each((null==n?q:"function"==typeof n?O:D)(t,n,null==e?"":e)):V(this.node(),t)},property:function(t,n){return arguments.length>1?this.each((null==n?j:"function"==typeof n?H:R)(t,n)):this.node()[t]},classed:function(t,n){var e=I(t+"");if(arguments.length<2){for(var r=U(this.node()),i=-1,o=e.length;++iwt(t,n)))},t.select=dt,t.selectAll=function(t){return"string"==typeof t?new pt([document.querySelectorAll(t)],[document.documentElement]):new pt([l(t)],ht)},t.selection=_t,t.selector=c,t.selectorAll=f,t.style=V,t.window=M,Object.defineProperty(t,"__esModule",{value:!0})}));
diff --git a/node_modules/d3-selection/package.json b/node_modules/d3-selection/package.json
new file mode 100644
index 00000000..bb8d4431
--- /dev/null
+++ b/node_modules/d3-selection/package.json
@@ -0,0 +1,82 @@
+{
+ "_from": "d3-selection@3",
+ "_id": "d3-selection@3.0.0",
+ "_inBundle": false,
+ "_integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
+ "_location": "/d3-selection",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "range",
+ "registry": true,
+ "raw": "d3-selection@3",
+ "name": "d3-selection",
+ "escapedName": "d3-selection",
+ "rawSpec": "3",
+ "saveSpec": null,
+ "fetchSpec": "3"
+ },
+ "_requiredBy": [
+ "/d3",
+ "/d3-brush",
+ "/d3-drag",
+ "/d3-zoom"
+ ],
+ "_resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
+ "_shasum": "c25338207efa72cc5b9bd1458a1a41901f1e1b31",
+ "_spec": "d3-selection@3",
+ "_where": "C:\\Users\\colbs\\CS4241\\d3a4\\node_modules\\d3",
+ "author": {
+ "name": "Mike Bostock",
+ "url": "https://bost.ocks.org/mike"
+ },
+ "bugs": {
+ "url": "https://github.com/d3/d3-selection/issues"
+ },
+ "bundleDependencies": false,
+ "deprecated": false,
+ "description": "Data-driven DOM manipulation: select elements and join them to data.",
+ "devDependencies": {
+ "eslint": "7",
+ "jsdom": "16",
+ "mocha": "9",
+ "rollup": "2",
+ "rollup-plugin-terser": "7"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "exports": {
+ "umd": "./dist/d3-selection.min.js",
+ "default": "./src/index.js"
+ },
+ "files": [
+ "dist/**/*.js",
+ "src/**/*.js"
+ ],
+ "homepage": "https://d3js.org/d3-selection/",
+ "jsdelivr": "dist/d3-selection.min.js",
+ "keywords": [
+ "d3",
+ "d3-module",
+ "dom",
+ "selection",
+ "data-join"
+ ],
+ "license": "ISC",
+ "main": "src/index.js",
+ "module": "src/index.js",
+ "name": "d3-selection",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/d3/d3-selection.git"
+ },
+ "scripts": {
+ "postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -",
+ "prepublishOnly": "rm -rf dist && yarn test && rollup -c",
+ "test": "mocha 'test/**/*-test.js' && eslint src test"
+ },
+ "sideEffects": false,
+ "type": "module",
+ "unpkg": "dist/d3-selection.min.js",
+ "version": "3.0.0"
+}
diff --git a/node_modules/d3-selection/src/array.js b/node_modules/d3-selection/src/array.js
new file mode 100644
index 00000000..978c22a2
--- /dev/null
+++ b/node_modules/d3-selection/src/array.js
@@ -0,0 +1,9 @@
+// Given something array like (or null), returns something that is strictly an
+// array. This is used to ensure that array-like objects passed to d3.selectAll
+// or selection.selectAll are converted into proper arrays when creating a
+// selection; we don’t ever want to create a selection backed by a live
+// HTMLCollection or NodeList. However, note that selection.selectAll will use a
+// static NodeList as a group, since it safely derived from querySelectorAll.
+export default function array(x) {
+ return x == null ? [] : Array.isArray(x) ? x : Array.from(x);
+}
diff --git a/node_modules/d3-selection/src/constant.js b/node_modules/d3-selection/src/constant.js
new file mode 100644
index 00000000..b7d42e71
--- /dev/null
+++ b/node_modules/d3-selection/src/constant.js
@@ -0,0 +1,5 @@
+export default function(x) {
+ return function() {
+ return x;
+ };
+}
diff --git a/node_modules/d3-selection/src/create.js b/node_modules/d3-selection/src/create.js
new file mode 100644
index 00000000..077a6a3d
--- /dev/null
+++ b/node_modules/d3-selection/src/create.js
@@ -0,0 +1,6 @@
+import creator from "./creator.js";
+import select from "./select.js";
+
+export default function(name) {
+ return select(creator(name).call(document.documentElement));
+}
diff --git a/node_modules/d3-selection/src/creator.js b/node_modules/d3-selection/src/creator.js
new file mode 100644
index 00000000..4f1b1621
--- /dev/null
+++ b/node_modules/d3-selection/src/creator.js
@@ -0,0 +1,25 @@
+import namespace from "./namespace.js";
+import {xhtml} from "./namespaces.js";
+
+function creatorInherit(name) {
+ return function() {
+ var document = this.ownerDocument,
+ uri = this.namespaceURI;
+ return uri === xhtml && document.documentElement.namespaceURI === xhtml
+ ? document.createElement(name)
+ : document.createElementNS(uri, name);
+ };
+}
+
+function creatorFixed(fullname) {
+ return function() {
+ return this.ownerDocument.createElementNS(fullname.space, fullname.local);
+ };
+}
+
+export default function(name) {
+ var fullname = namespace(name);
+ return (fullname.local
+ ? creatorFixed
+ : creatorInherit)(fullname);
+}
diff --git a/node_modules/d3-selection/src/identity.js b/node_modules/d3-selection/src/identity.js
new file mode 100644
index 00000000..b2f94b2e
--- /dev/null
+++ b/node_modules/d3-selection/src/identity.js
@@ -0,0 +1,3 @@
+export default function(x) {
+ return x;
+}
diff --git a/node_modules/d3-selection/src/index.js b/node_modules/d3-selection/src/index.js
new file mode 100644
index 00000000..dc51a3bd
--- /dev/null
+++ b/node_modules/d3-selection/src/index.js
@@ -0,0 +1,15 @@
+export {default as create} from "./create.js";
+export {default as creator} from "./creator.js";
+export {default as local} from "./local.js";
+export {default as matcher} from "./matcher.js";
+export {default as namespace} from "./namespace.js";
+export {default as namespaces} from "./namespaces.js";
+export {default as pointer} from "./pointer.js";
+export {default as pointers} from "./pointers.js";
+export {default as select} from "./select.js";
+export {default as selectAll} from "./selectAll.js";
+export {default as selection} from "./selection/index.js";
+export {default as selector} from "./selector.js";
+export {default as selectorAll} from "./selectorAll.js";
+export {styleValue as style} from "./selection/style.js";
+export {default as window} from "./window.js";
diff --git a/node_modules/d3-selection/src/local.js b/node_modules/d3-selection/src/local.js
new file mode 100644
index 00000000..ab4c20f9
--- /dev/null
+++ b/node_modules/d3-selection/src/local.js
@@ -0,0 +1,27 @@
+var nextId = 0;
+
+export default function local() {
+ return new Local;
+}
+
+function Local() {
+ this._ = "@" + (++nextId).toString(36);
+}
+
+Local.prototype = local.prototype = {
+ constructor: Local,
+ get: function(node) {
+ var id = this._;
+ while (!(id in node)) if (!(node = node.parentNode)) return;
+ return node[id];
+ },
+ set: function(node, value) {
+ return node[this._] = value;
+ },
+ remove: function(node) {
+ return this._ in node && delete node[this._];
+ },
+ toString: function() {
+ return this._;
+ }
+};
diff --git a/node_modules/d3-selection/src/matcher.js b/node_modules/d3-selection/src/matcher.js
new file mode 100644
index 00000000..854b0d92
--- /dev/null
+++ b/node_modules/d3-selection/src/matcher.js
@@ -0,0 +1,12 @@
+export default function(selector) {
+ return function() {
+ return this.matches(selector);
+ };
+}
+
+export function childMatcher(selector) {
+ return function(node) {
+ return node.matches(selector);
+ };
+}
+
diff --git a/node_modules/d3-selection/src/namespace.js b/node_modules/d3-selection/src/namespace.js
new file mode 100644
index 00000000..72db9df5
--- /dev/null
+++ b/node_modules/d3-selection/src/namespace.js
@@ -0,0 +1,7 @@
+import namespaces from "./namespaces.js";
+
+export default function(name) {
+ var prefix = name += "", i = prefix.indexOf(":");
+ if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1);
+ return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name; // eslint-disable-line no-prototype-builtins
+}
diff --git a/node_modules/d3-selection/src/namespaces.js b/node_modules/d3-selection/src/namespaces.js
new file mode 100644
index 00000000..01749bdc
--- /dev/null
+++ b/node_modules/d3-selection/src/namespaces.js
@@ -0,0 +1,9 @@
+export var xhtml = "http://www.w3.org/1999/xhtml";
+
+export default {
+ svg: "http://www.w3.org/2000/svg",
+ xhtml: xhtml,
+ xlink: "http://www.w3.org/1999/xlink",
+ xml: "http://www.w3.org/XML/1998/namespace",
+ xmlns: "http://www.w3.org/2000/xmlns/"
+};
diff --git a/node_modules/d3-selection/src/pointer.js b/node_modules/d3-selection/src/pointer.js
new file mode 100644
index 00000000..3e2298f6
--- /dev/null
+++ b/node_modules/d3-selection/src/pointer.js
@@ -0,0 +1,20 @@
+import sourceEvent from "./sourceEvent.js";
+
+export default function(event, node) {
+ event = sourceEvent(event);
+ if (node === undefined) node = event.currentTarget;
+ if (node) {
+ var svg = node.ownerSVGElement || node;
+ if (svg.createSVGPoint) {
+ var point = svg.createSVGPoint();
+ point.x = event.clientX, point.y = event.clientY;
+ point = point.matrixTransform(node.getScreenCTM().inverse());
+ return [point.x, point.y];
+ }
+ if (node.getBoundingClientRect) {
+ var rect = node.getBoundingClientRect();
+ return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop];
+ }
+ }
+ return [event.pageX, event.pageY];
+}
diff --git a/node_modules/d3-selection/src/pointers.js b/node_modules/d3-selection/src/pointers.js
new file mode 100644
index 00000000..43d17d19
--- /dev/null
+++ b/node_modules/d3-selection/src/pointers.js
@@ -0,0 +1,11 @@
+import pointer from "./pointer.js";
+import sourceEvent from "./sourceEvent.js";
+
+export default function(events, node) {
+ if (events.target) { // i.e., instanceof Event, not TouchList or iterable
+ events = sourceEvent(events);
+ if (node === undefined) node = events.currentTarget;
+ events = events.touches || [events];
+ }
+ return Array.from(events, event => pointer(event, node));
+}
diff --git a/node_modules/d3-selection/src/select.js b/node_modules/d3-selection/src/select.js
new file mode 100644
index 00000000..dcea22e8
--- /dev/null
+++ b/node_modules/d3-selection/src/select.js
@@ -0,0 +1,7 @@
+import {Selection, root} from "./selection/index.js";
+
+export default function(selector) {
+ return typeof selector === "string"
+ ? new Selection([[document.querySelector(selector)]], [document.documentElement])
+ : new Selection([[selector]], root);
+}
diff --git a/node_modules/d3-selection/src/selectAll.js b/node_modules/d3-selection/src/selectAll.js
new file mode 100644
index 00000000..b6ecc3d2
--- /dev/null
+++ b/node_modules/d3-selection/src/selectAll.js
@@ -0,0 +1,8 @@
+import array from "./array.js";
+import {Selection, root} from "./selection/index.js";
+
+export default function(selector) {
+ return typeof selector === "string"
+ ? new Selection([document.querySelectorAll(selector)], [document.documentElement])
+ : new Selection([array(selector)], root);
+}
diff --git a/node_modules/d3-selection/src/selection/append.js b/node_modules/d3-selection/src/selection/append.js
new file mode 100644
index 00000000..33336331
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/append.js
@@ -0,0 +1,8 @@
+import creator from "../creator.js";
+
+export default function(name) {
+ var create = typeof name === "function" ? name : creator(name);
+ return this.select(function() {
+ return this.appendChild(create.apply(this, arguments));
+ });
+}
diff --git a/node_modules/d3-selection/src/selection/attr.js b/node_modules/d3-selection/src/selection/attr.js
new file mode 100644
index 00000000..5e933538
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/attr.js
@@ -0,0 +1,57 @@
+import namespace from "../namespace.js";
+
+function attrRemove(name) {
+ return function() {
+ this.removeAttribute(name);
+ };
+}
+
+function attrRemoveNS(fullname) {
+ return function() {
+ this.removeAttributeNS(fullname.space, fullname.local);
+ };
+}
+
+function attrConstant(name, value) {
+ return function() {
+ this.setAttribute(name, value);
+ };
+}
+
+function attrConstantNS(fullname, value) {
+ return function() {
+ this.setAttributeNS(fullname.space, fullname.local, value);
+ };
+}
+
+function attrFunction(name, value) {
+ return function() {
+ var v = value.apply(this, arguments);
+ if (v == null) this.removeAttribute(name);
+ else this.setAttribute(name, v);
+ };
+}
+
+function attrFunctionNS(fullname, value) {
+ return function() {
+ var v = value.apply(this, arguments);
+ if (v == null) this.removeAttributeNS(fullname.space, fullname.local);
+ else this.setAttributeNS(fullname.space, fullname.local, v);
+ };
+}
+
+export default function(name, value) {
+ var fullname = namespace(name);
+
+ if (arguments.length < 2) {
+ var node = this.node();
+ return fullname.local
+ ? node.getAttributeNS(fullname.space, fullname.local)
+ : node.getAttribute(fullname);
+ }
+
+ return this.each((value == null
+ ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function"
+ ? (fullname.local ? attrFunctionNS : attrFunction)
+ : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value));
+}
diff --git a/node_modules/d3-selection/src/selection/call.js b/node_modules/d3-selection/src/selection/call.js
new file mode 100644
index 00000000..2c41eeef
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/call.js
@@ -0,0 +1,6 @@
+export default function() {
+ var callback = arguments[0];
+ arguments[0] = this;
+ callback.apply(null, arguments);
+ return this;
+}
diff --git a/node_modules/d3-selection/src/selection/classed.js b/node_modules/d3-selection/src/selection/classed.js
new file mode 100644
index 00000000..b3563731
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/classed.js
@@ -0,0 +1,75 @@
+function classArray(string) {
+ return string.trim().split(/^|\s+/);
+}
+
+function classList(node) {
+ return node.classList || new ClassList(node);
+}
+
+function ClassList(node) {
+ this._node = node;
+ this._names = classArray(node.getAttribute("class") || "");
+}
+
+ClassList.prototype = {
+ add: function(name) {
+ var i = this._names.indexOf(name);
+ if (i < 0) {
+ this._names.push(name);
+ this._node.setAttribute("class", this._names.join(" "));
+ }
+ },
+ remove: function(name) {
+ var i = this._names.indexOf(name);
+ if (i >= 0) {
+ this._names.splice(i, 1);
+ this._node.setAttribute("class", this._names.join(" "));
+ }
+ },
+ contains: function(name) {
+ return this._names.indexOf(name) >= 0;
+ }
+};
+
+function classedAdd(node, names) {
+ var list = classList(node), i = -1, n = names.length;
+ while (++i < n) list.add(names[i]);
+}
+
+function classedRemove(node, names) {
+ var list = classList(node), i = -1, n = names.length;
+ while (++i < n) list.remove(names[i]);
+}
+
+function classedTrue(names) {
+ return function() {
+ classedAdd(this, names);
+ };
+}
+
+function classedFalse(names) {
+ return function() {
+ classedRemove(this, names);
+ };
+}
+
+function classedFunction(names, value) {
+ return function() {
+ (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names);
+ };
+}
+
+export default function(name, value) {
+ var names = classArray(name + "");
+
+ if (arguments.length < 2) {
+ var list = classList(this.node()), i = -1, n = names.length;
+ while (++i < n) if (!list.contains(names[i])) return false;
+ return true;
+ }
+
+ return this.each((typeof value === "function"
+ ? classedFunction : value
+ ? classedTrue
+ : classedFalse)(names, value));
+}
diff --git a/node_modules/d3-selection/src/selection/clone.js b/node_modules/d3-selection/src/selection/clone.js
new file mode 100644
index 00000000..5e273bf1
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/clone.js
@@ -0,0 +1,13 @@
+function selection_cloneShallow() {
+ var clone = this.cloneNode(false), parent = this.parentNode;
+ return parent ? parent.insertBefore(clone, this.nextSibling) : clone;
+}
+
+function selection_cloneDeep() {
+ var clone = this.cloneNode(true), parent = this.parentNode;
+ return parent ? parent.insertBefore(clone, this.nextSibling) : clone;
+}
+
+export default function(deep) {
+ return this.select(deep ? selection_cloneDeep : selection_cloneShallow);
+}
diff --git a/node_modules/d3-selection/src/selection/data.js b/node_modules/d3-selection/src/selection/data.js
new file mode 100644
index 00000000..8eb07133
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/data.js
@@ -0,0 +1,128 @@
+import {Selection} from "./index.js";
+import {EnterNode} from "./enter.js";
+import constant from "../constant.js";
+
+function bindIndex(parent, group, enter, update, exit, data) {
+ var i = 0,
+ node,
+ groupLength = group.length,
+ dataLength = data.length;
+
+ // Put any non-null nodes that fit into update.
+ // Put any null nodes into enter.
+ // Put any remaining data into enter.
+ for (; i < dataLength; ++i) {
+ if (node = group[i]) {
+ node.__data__ = data[i];
+ update[i] = node;
+ } else {
+ enter[i] = new EnterNode(parent, data[i]);
+ }
+ }
+
+ // Put any non-null nodes that don’t fit into exit.
+ for (; i < groupLength; ++i) {
+ if (node = group[i]) {
+ exit[i] = node;
+ }
+ }
+}
+
+function bindKey(parent, group, enter, update, exit, data, key) {
+ var i,
+ node,
+ nodeByKeyValue = new Map,
+ groupLength = group.length,
+ dataLength = data.length,
+ keyValues = new Array(groupLength),
+ keyValue;
+
+ // Compute the key for each node.
+ // If multiple nodes have the same key, the duplicates are added to exit.
+ for (i = 0; i < groupLength; ++i) {
+ if (node = group[i]) {
+ keyValues[i] = keyValue = key.call(node, node.__data__, i, group) + "";
+ if (nodeByKeyValue.has(keyValue)) {
+ exit[i] = node;
+ } else {
+ nodeByKeyValue.set(keyValue, node);
+ }
+ }
+ }
+
+ // Compute the key for each datum.
+ // If there a node associated with this key, join and add it to update.
+ // If there is not (or the key is a duplicate), add it to enter.
+ for (i = 0; i < dataLength; ++i) {
+ keyValue = key.call(parent, data[i], i, data) + "";
+ if (node = nodeByKeyValue.get(keyValue)) {
+ update[i] = node;
+ node.__data__ = data[i];
+ nodeByKeyValue.delete(keyValue);
+ } else {
+ enter[i] = new EnterNode(parent, data[i]);
+ }
+ }
+
+ // Add any remaining nodes that were not bound to data to exit.
+ for (i = 0; i < groupLength; ++i) {
+ if ((node = group[i]) && (nodeByKeyValue.get(keyValues[i]) === node)) {
+ exit[i] = node;
+ }
+ }
+}
+
+function datum(node) {
+ return node.__data__;
+}
+
+export default function(value, key) {
+ if (!arguments.length) return Array.from(this, datum);
+
+ var bind = key ? bindKey : bindIndex,
+ parents = this._parents,
+ groups = this._groups;
+
+ if (typeof value !== "function") value = constant(value);
+
+ for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) {
+ var parent = parents[j],
+ group = groups[j],
+ groupLength = group.length,
+ data = arraylike(value.call(parent, parent && parent.__data__, j, parents)),
+ dataLength = data.length,
+ enterGroup = enter[j] = new Array(dataLength),
+ updateGroup = update[j] = new Array(dataLength),
+ exitGroup = exit[j] = new Array(groupLength);
+
+ bind(parent, group, enterGroup, updateGroup, exitGroup, data, key);
+
+ // Now connect the enter nodes to their following update node, such that
+ // appendChild can insert the materialized enter node before this node,
+ // rather than at the end of the parent node.
+ for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) {
+ if (previous = enterGroup[i0]) {
+ if (i0 >= i1) i1 = i0 + 1;
+ while (!(next = updateGroup[i1]) && ++i1 < dataLength);
+ previous._next = next || null;
+ }
+ }
+ }
+
+ update = new Selection(update, parents);
+ update._enter = enter;
+ update._exit = exit;
+ return update;
+}
+
+// Given some data, this returns an array-like view of it: an object that
+// exposes a length property and allows numeric indexing. Note that unlike
+// selectAll, this isn’t worried about “live” collections because the resulting
+// array will only be used briefly while data is being bound. (It is possible to
+// cause the data to change while iterating by using a key function, but please
+// don’t; we’d rather avoid a gratuitous copy.)
+function arraylike(data) {
+ return typeof data === "object" && "length" in data
+ ? data // Array, TypedArray, NodeList, array-like
+ : Array.from(data); // Map, Set, iterable, string, or anything else
+}
diff --git a/node_modules/d3-selection/src/selection/datum.js b/node_modules/d3-selection/src/selection/datum.js
new file mode 100644
index 00000000..5de4e580
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/datum.js
@@ -0,0 +1,5 @@
+export default function(value) {
+ return arguments.length
+ ? this.property("__data__", value)
+ : this.node().__data__;
+}
diff --git a/node_modules/d3-selection/src/selection/dispatch.js b/node_modules/d3-selection/src/selection/dispatch.js
new file mode 100644
index 00000000..8f57915f
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/dispatch.js
@@ -0,0 +1,34 @@
+import defaultView from "../window.js";
+
+function dispatchEvent(node, type, params) {
+ var window = defaultView(node),
+ event = window.CustomEvent;
+
+ if (typeof event === "function") {
+ event = new event(type, params);
+ } else {
+ event = window.document.createEvent("Event");
+ if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail;
+ else event.initEvent(type, false, false);
+ }
+
+ node.dispatchEvent(event);
+}
+
+function dispatchConstant(type, params) {
+ return function() {
+ return dispatchEvent(this, type, params);
+ };
+}
+
+function dispatchFunction(type, params) {
+ return function() {
+ return dispatchEvent(this, type, params.apply(this, arguments));
+ };
+}
+
+export default function(type, params) {
+ return this.each((typeof params === "function"
+ ? dispatchFunction
+ : dispatchConstant)(type, params));
+}
diff --git a/node_modules/d3-selection/src/selection/each.js b/node_modules/d3-selection/src/selection/each.js
new file mode 100644
index 00000000..260af8f2
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/each.js
@@ -0,0 +1,10 @@
+export default function(callback) {
+
+ for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
+ for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {
+ if (node = group[i]) callback.call(node, node.__data__, i, group);
+ }
+ }
+
+ return this;
+}
diff --git a/node_modules/d3-selection/src/selection/empty.js b/node_modules/d3-selection/src/selection/empty.js
new file mode 100644
index 00000000..4e2cf428
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/empty.js
@@ -0,0 +1,3 @@
+export default function() {
+ return !this.node();
+}
diff --git a/node_modules/d3-selection/src/selection/enter.js b/node_modules/d3-selection/src/selection/enter.js
new file mode 100644
index 00000000..83a3ed4d
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/enter.js
@@ -0,0 +1,22 @@
+import sparse from "./sparse.js";
+import {Selection} from "./index.js";
+
+export default function() {
+ return new Selection(this._enter || this._groups.map(sparse), this._parents);
+}
+
+export function EnterNode(parent, datum) {
+ this.ownerDocument = parent.ownerDocument;
+ this.namespaceURI = parent.namespaceURI;
+ this._next = null;
+ this._parent = parent;
+ this.__data__ = datum;
+}
+
+EnterNode.prototype = {
+ constructor: EnterNode,
+ appendChild: function(child) { return this._parent.insertBefore(child, this._next); },
+ insertBefore: function(child, next) { return this._parent.insertBefore(child, next); },
+ querySelector: function(selector) { return this._parent.querySelector(selector); },
+ querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); }
+};
diff --git a/node_modules/d3-selection/src/selection/exit.js b/node_modules/d3-selection/src/selection/exit.js
new file mode 100644
index 00000000..f5d7b45d
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/exit.js
@@ -0,0 +1,6 @@
+import sparse from "./sparse.js";
+import {Selection} from "./index.js";
+
+export default function() {
+ return new Selection(this._exit || this._groups.map(sparse), this._parents);
+}
diff --git a/node_modules/d3-selection/src/selection/filter.js b/node_modules/d3-selection/src/selection/filter.js
new file mode 100644
index 00000000..74b3d6f2
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/filter.js
@@ -0,0 +1,16 @@
+import {Selection} from "./index.js";
+import matcher from "../matcher.js";
+
+export default function(match) {
+ if (typeof match !== "function") match = matcher(match);
+
+ for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
+ for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
+ if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
+ subgroup.push(node);
+ }
+ }
+ }
+
+ return new Selection(subgroups, this._parents);
+}
diff --git a/node_modules/d3-selection/src/selection/html.js b/node_modules/d3-selection/src/selection/html.js
new file mode 100644
index 00000000..df274428
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/html.js
@@ -0,0 +1,25 @@
+function htmlRemove() {
+ this.innerHTML = "";
+}
+
+function htmlConstant(value) {
+ return function() {
+ this.innerHTML = value;
+ };
+}
+
+function htmlFunction(value) {
+ return function() {
+ var v = value.apply(this, arguments);
+ this.innerHTML = v == null ? "" : v;
+ };
+}
+
+export default function(value) {
+ return arguments.length
+ ? this.each(value == null
+ ? htmlRemove : (typeof value === "function"
+ ? htmlFunction
+ : htmlConstant)(value))
+ : this.node().innerHTML;
+}
diff --git a/node_modules/d3-selection/src/selection/index.js b/node_modules/d3-selection/src/selection/index.js
new file mode 100644
index 00000000..a593a219
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/index.js
@@ -0,0 +1,90 @@
+import selection_select from "./select.js";
+import selection_selectAll from "./selectAll.js";
+import selection_selectChild from "./selectChild.js";
+import selection_selectChildren from "./selectChildren.js";
+import selection_filter from "./filter.js";
+import selection_data from "./data.js";
+import selection_enter from "./enter.js";
+import selection_exit from "./exit.js";
+import selection_join from "./join.js";
+import selection_merge from "./merge.js";
+import selection_order from "./order.js";
+import selection_sort from "./sort.js";
+import selection_call from "./call.js";
+import selection_nodes from "./nodes.js";
+import selection_node from "./node.js";
+import selection_size from "./size.js";
+import selection_empty from "./empty.js";
+import selection_each from "./each.js";
+import selection_attr from "./attr.js";
+import selection_style from "./style.js";
+import selection_property from "./property.js";
+import selection_classed from "./classed.js";
+import selection_text from "./text.js";
+import selection_html from "./html.js";
+import selection_raise from "./raise.js";
+import selection_lower from "./lower.js";
+import selection_append from "./append.js";
+import selection_insert from "./insert.js";
+import selection_remove from "./remove.js";
+import selection_clone from "./clone.js";
+import selection_datum from "./datum.js";
+import selection_on from "./on.js";
+import selection_dispatch from "./dispatch.js";
+import selection_iterator from "./iterator.js";
+
+export var root = [null];
+
+export function Selection(groups, parents) {
+ this._groups = groups;
+ this._parents = parents;
+}
+
+function selection() {
+ return new Selection([[document.documentElement]], root);
+}
+
+function selection_selection() {
+ return this;
+}
+
+Selection.prototype = selection.prototype = {
+ constructor: Selection,
+ select: selection_select,
+ selectAll: selection_selectAll,
+ selectChild: selection_selectChild,
+ selectChildren: selection_selectChildren,
+ filter: selection_filter,
+ data: selection_data,
+ enter: selection_enter,
+ exit: selection_exit,
+ join: selection_join,
+ merge: selection_merge,
+ selection: selection_selection,
+ order: selection_order,
+ sort: selection_sort,
+ call: selection_call,
+ nodes: selection_nodes,
+ node: selection_node,
+ size: selection_size,
+ empty: selection_empty,
+ each: selection_each,
+ attr: selection_attr,
+ style: selection_style,
+ property: selection_property,
+ classed: selection_classed,
+ text: selection_text,
+ html: selection_html,
+ raise: selection_raise,
+ lower: selection_lower,
+ append: selection_append,
+ insert: selection_insert,
+ remove: selection_remove,
+ clone: selection_clone,
+ datum: selection_datum,
+ on: selection_on,
+ dispatch: selection_dispatch,
+ [Symbol.iterator]: selection_iterator
+};
+
+export default selection;
diff --git a/node_modules/d3-selection/src/selection/insert.js b/node_modules/d3-selection/src/selection/insert.js
new file mode 100644
index 00000000..1733de54
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/insert.js
@@ -0,0 +1,14 @@
+import creator from "../creator.js";
+import selector from "../selector.js";
+
+function constantNull() {
+ return null;
+}
+
+export default function(name, before) {
+ var create = typeof name === "function" ? name : creator(name),
+ select = before == null ? constantNull : typeof before === "function" ? before : selector(before);
+ return this.select(function() {
+ return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null);
+ });
+}
diff --git a/node_modules/d3-selection/src/selection/iterator.js b/node_modules/d3-selection/src/selection/iterator.js
new file mode 100644
index 00000000..58728191
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/iterator.js
@@ -0,0 +1,7 @@
+export default function*() {
+ for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
+ for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) {
+ if (node = group[i]) yield node;
+ }
+ }
+}
diff --git a/node_modules/d3-selection/src/selection/join.js b/node_modules/d3-selection/src/selection/join.js
new file mode 100644
index 00000000..8b472813
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/join.js
@@ -0,0 +1,15 @@
+export default function(onenter, onupdate, onexit) {
+ var enter = this.enter(), update = this, exit = this.exit();
+ if (typeof onenter === "function") {
+ enter = onenter(enter);
+ if (enter) enter = enter.selection();
+ } else {
+ enter = enter.append(onenter + "");
+ }
+ if (onupdate != null) {
+ update = onupdate(update);
+ if (update) update = update.selection();
+ }
+ if (onexit == null) exit.remove(); else onexit(exit);
+ return enter && update ? enter.merge(update).order() : update;
+}
diff --git a/node_modules/d3-selection/src/selection/lower.js b/node_modules/d3-selection/src/selection/lower.js
new file mode 100644
index 00000000..d7247132
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/lower.js
@@ -0,0 +1,7 @@
+function lower() {
+ if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild);
+}
+
+export default function() {
+ return this.each(lower);
+}
diff --git a/node_modules/d3-selection/src/selection/merge.js b/node_modules/d3-selection/src/selection/merge.js
new file mode 100644
index 00000000..fd68d6c5
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/merge.js
@@ -0,0 +1,19 @@
+import {Selection} from "./index.js";
+
+export default function(context) {
+ var selection = context.selection ? context.selection() : context;
+
+ for (var groups0 = this._groups, groups1 = selection._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
+ for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
+ if (node = group0[i] || group1[i]) {
+ merge[i] = node;
+ }
+ }
+ }
+
+ for (; j < m0; ++j) {
+ merges[j] = groups0[j];
+ }
+
+ return new Selection(merges, this._parents);
+}
diff --git a/node_modules/d3-selection/src/selection/node.js b/node_modules/d3-selection/src/selection/node.js
new file mode 100644
index 00000000..0691cbc0
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/node.js
@@ -0,0 +1,11 @@
+export default function() {
+
+ for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) {
+ for (var group = groups[j], i = 0, n = group.length; i < n; ++i) {
+ var node = group[i];
+ if (node) return node;
+ }
+ }
+
+ return null;
+}
diff --git a/node_modules/d3-selection/src/selection/nodes.js b/node_modules/d3-selection/src/selection/nodes.js
new file mode 100644
index 00000000..7f38090d
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/nodes.js
@@ -0,0 +1,3 @@
+export default function() {
+ return Array.from(this);
+}
diff --git a/node_modules/d3-selection/src/selection/on.js b/node_modules/d3-selection/src/selection/on.js
new file mode 100644
index 00000000..7906c8ca
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/on.js
@@ -0,0 +1,67 @@
+function contextListener(listener) {
+ return function(event) {
+ listener.call(this, event, this.__data__);
+ };
+}
+
+function parseTypenames(typenames) {
+ return typenames.trim().split(/^|\s+/).map(function(t) {
+ var name = "", i = t.indexOf(".");
+ if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i);
+ return {type: t, name: name};
+ });
+}
+
+function onRemove(typename) {
+ return function() {
+ var on = this.__on;
+ if (!on) return;
+ for (var j = 0, i = -1, m = on.length, o; j < m; ++j) {
+ if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) {
+ this.removeEventListener(o.type, o.listener, o.options);
+ } else {
+ on[++i] = o;
+ }
+ }
+ if (++i) on.length = i;
+ else delete this.__on;
+ };
+}
+
+function onAdd(typename, value, options) {
+ return function() {
+ var on = this.__on, o, listener = contextListener(value);
+ if (on) for (var j = 0, m = on.length; j < m; ++j) {
+ if ((o = on[j]).type === typename.type && o.name === typename.name) {
+ this.removeEventListener(o.type, o.listener, o.options);
+ this.addEventListener(o.type, o.listener = listener, o.options = options);
+ o.value = value;
+ return;
+ }
+ }
+ this.addEventListener(typename.type, listener, options);
+ o = {type: typename.type, name: typename.name, value: value, listener: listener, options: options};
+ if (!on) this.__on = [o];
+ else on.push(o);
+ };
+}
+
+export default function(typename, value, options) {
+ var typenames = parseTypenames(typename + ""), i, n = typenames.length, t;
+
+ if (arguments.length < 2) {
+ var on = this.node().__on;
+ if (on) for (var j = 0, m = on.length, o; j < m; ++j) {
+ for (i = 0, o = on[j]; i < n; ++i) {
+ if ((t = typenames[i]).type === o.type && t.name === o.name) {
+ return o.value;
+ }
+ }
+ }
+ return;
+ }
+
+ on = value ? onAdd : onRemove;
+ for (i = 0; i < n; ++i) this.each(on(typenames[i], value, options));
+ return this;
+}
diff --git a/node_modules/d3-selection/src/selection/order.js b/node_modules/d3-selection/src/selection/order.js
new file mode 100644
index 00000000..f8c52b4b
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/order.js
@@ -0,0 +1,13 @@
+export default function() {
+
+ for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) {
+ for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) {
+ if (node = group[i]) {
+ if (next && node.compareDocumentPosition(next) ^ 4) next.parentNode.insertBefore(node, next);
+ next = node;
+ }
+ }
+ }
+
+ return this;
+}
diff --git a/node_modules/d3-selection/src/selection/property.js b/node_modules/d3-selection/src/selection/property.js
new file mode 100644
index 00000000..3b7efd39
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/property.js
@@ -0,0 +1,28 @@
+function propertyRemove(name) {
+ return function() {
+ delete this[name];
+ };
+}
+
+function propertyConstant(name, value) {
+ return function() {
+ this[name] = value;
+ };
+}
+
+function propertyFunction(name, value) {
+ return function() {
+ var v = value.apply(this, arguments);
+ if (v == null) delete this[name];
+ else this[name] = v;
+ };
+}
+
+export default function(name, value) {
+ return arguments.length > 1
+ ? this.each((value == null
+ ? propertyRemove : typeof value === "function"
+ ? propertyFunction
+ : propertyConstant)(name, value))
+ : this.node()[name];
+}
diff --git a/node_modules/d3-selection/src/selection/raise.js b/node_modules/d3-selection/src/selection/raise.js
new file mode 100644
index 00000000..3e9e1c9b
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/raise.js
@@ -0,0 +1,7 @@
+function raise() {
+ if (this.nextSibling) this.parentNode.appendChild(this);
+}
+
+export default function() {
+ return this.each(raise);
+}
diff --git a/node_modules/d3-selection/src/selection/remove.js b/node_modules/d3-selection/src/selection/remove.js
new file mode 100644
index 00000000..12a81060
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/remove.js
@@ -0,0 +1,8 @@
+function remove() {
+ var parent = this.parentNode;
+ if (parent) parent.removeChild(this);
+}
+
+export default function() {
+ return this.each(remove);
+}
diff --git a/node_modules/d3-selection/src/selection/select.js b/node_modules/d3-selection/src/selection/select.js
new file mode 100644
index 00000000..223cc243
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/select.js
@@ -0,0 +1,17 @@
+import {Selection} from "./index.js";
+import selector from "../selector.js";
+
+export default function(select) {
+ if (typeof select !== "function") select = selector(select);
+
+ for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
+ for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
+ if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
+ if ("__data__" in node) subnode.__data__ = node.__data__;
+ subgroup[i] = subnode;
+ }
+ }
+ }
+
+ return new Selection(subgroups, this._parents);
+}
diff --git a/node_modules/d3-selection/src/selection/selectAll.js b/node_modules/d3-selection/src/selection/selectAll.js
new file mode 100644
index 00000000..2a87a27b
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/selectAll.js
@@ -0,0 +1,25 @@
+import {Selection} from "./index.js";
+import array from "../array.js";
+import selectorAll from "../selectorAll.js";
+
+function arrayAll(select) {
+ return function() {
+ return array(select.apply(this, arguments));
+ };
+}
+
+export default function(select) {
+ if (typeof select === "function") select = arrayAll(select);
+ else select = selectorAll(select);
+
+ for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
+ for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
+ if (node = group[i]) {
+ subgroups.push(select.call(node, node.__data__, i, group));
+ parents.push(node);
+ }
+ }
+ }
+
+ return new Selection(subgroups, parents);
+}
diff --git a/node_modules/d3-selection/src/selection/selectChild.js b/node_modules/d3-selection/src/selection/selectChild.js
new file mode 100644
index 00000000..d0427947
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/selectChild.js
@@ -0,0 +1,18 @@
+import {childMatcher} from "../matcher.js";
+
+var find = Array.prototype.find;
+
+function childFind(match) {
+ return function() {
+ return find.call(this.children, match);
+ };
+}
+
+function childFirst() {
+ return this.firstElementChild;
+}
+
+export default function(match) {
+ return this.select(match == null ? childFirst
+ : childFind(typeof match === "function" ? match : childMatcher(match)));
+}
diff --git a/node_modules/d3-selection/src/selection/selectChildren.js b/node_modules/d3-selection/src/selection/selectChildren.js
new file mode 100644
index 00000000..d514d3b3
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/selectChildren.js
@@ -0,0 +1,18 @@
+import {childMatcher} from "../matcher.js";
+
+var filter = Array.prototype.filter;
+
+function children() {
+ return Array.from(this.children);
+}
+
+function childrenFilter(match) {
+ return function() {
+ return filter.call(this.children, match);
+ };
+}
+
+export default function(match) {
+ return this.selectAll(match == null ? children
+ : childrenFilter(typeof match === "function" ? match : childMatcher(match)));
+}
diff --git a/node_modules/d3-selection/src/selection/size.js b/node_modules/d3-selection/src/selection/size.js
new file mode 100644
index 00000000..e07eaa4f
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/size.js
@@ -0,0 +1,5 @@
+export default function() {
+ let size = 0;
+ for (const node of this) ++size; // eslint-disable-line no-unused-vars
+ return size;
+}
diff --git a/node_modules/d3-selection/src/selection/sort.js b/node_modules/d3-selection/src/selection/sort.js
new file mode 100644
index 00000000..336760f1
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/sort.js
@@ -0,0 +1,24 @@
+import {Selection} from "./index.js";
+
+export default function(compare) {
+ if (!compare) compare = ascending;
+
+ function compareNode(a, b) {
+ return a && b ? compare(a.__data__, b.__data__) : !a - !b;
+ }
+
+ for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) {
+ for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) {
+ if (node = group[i]) {
+ sortgroup[i] = node;
+ }
+ }
+ sortgroup.sort(compareNode);
+ }
+
+ return new Selection(sortgroups, this._parents).order();
+}
+
+function ascending(a, b) {
+ return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
+}
diff --git a/node_modules/d3-selection/src/selection/sparse.js b/node_modules/d3-selection/src/selection/sparse.js
new file mode 100644
index 00000000..7b261ad1
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/sparse.js
@@ -0,0 +1,3 @@
+export default function(update) {
+ return new Array(update.length);
+}
diff --git a/node_modules/d3-selection/src/selection/style.js b/node_modules/d3-selection/src/selection/style.js
new file mode 100644
index 00000000..7e0f0586
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/style.js
@@ -0,0 +1,35 @@
+import defaultView from "../window.js";
+
+function styleRemove(name) {
+ return function() {
+ this.style.removeProperty(name);
+ };
+}
+
+function styleConstant(name, value, priority) {
+ return function() {
+ this.style.setProperty(name, value, priority);
+ };
+}
+
+function styleFunction(name, value, priority) {
+ return function() {
+ var v = value.apply(this, arguments);
+ if (v == null) this.style.removeProperty(name);
+ else this.style.setProperty(name, v, priority);
+ };
+}
+
+export default function(name, value, priority) {
+ return arguments.length > 1
+ ? this.each((value == null
+ ? styleRemove : typeof value === "function"
+ ? styleFunction
+ : styleConstant)(name, value, priority == null ? "" : priority))
+ : styleValue(this.node(), name);
+}
+
+export function styleValue(node, name) {
+ return node.style.getPropertyValue(name)
+ || defaultView(node).getComputedStyle(node, null).getPropertyValue(name);
+}
diff --git a/node_modules/d3-selection/src/selection/text.js b/node_modules/d3-selection/src/selection/text.js
new file mode 100644
index 00000000..a902980c
--- /dev/null
+++ b/node_modules/d3-selection/src/selection/text.js
@@ -0,0 +1,25 @@
+function textRemove() {
+ this.textContent = "";
+}
+
+function textConstant(value) {
+ return function() {
+ this.textContent = value;
+ };
+}
+
+function textFunction(value) {
+ return function() {
+ var v = value.apply(this, arguments);
+ this.textContent = v == null ? "" : v;
+ };
+}
+
+export default function(value) {
+ return arguments.length
+ ? this.each(value == null
+ ? textRemove : (typeof value === "function"
+ ? textFunction
+ : textConstant)(value))
+ : this.node().textContent;
+}
diff --git a/node_modules/d3-selection/src/selector.js b/node_modules/d3-selection/src/selector.js
new file mode 100644
index 00000000..058bd73a
--- /dev/null
+++ b/node_modules/d3-selection/src/selector.js
@@ -0,0 +1,7 @@
+function none() {}
+
+export default function(selector) {
+ return selector == null ? none : function() {
+ return this.querySelector(selector);
+ };
+}
diff --git a/node_modules/d3-selection/src/selectorAll.js b/node_modules/d3-selection/src/selectorAll.js
new file mode 100644
index 00000000..ea42ffa3
--- /dev/null
+++ b/node_modules/d3-selection/src/selectorAll.js
@@ -0,0 +1,9 @@
+function empty() {
+ return [];
+}
+
+export default function(selector) {
+ return selector == null ? empty : function() {
+ return this.querySelectorAll(selector);
+ };
+}
diff --git a/node_modules/d3-selection/src/sourceEvent.js b/node_modules/d3-selection/src/sourceEvent.js
new file mode 100644
index 00000000..8ab130e2
--- /dev/null
+++ b/node_modules/d3-selection/src/sourceEvent.js
@@ -0,0 +1,5 @@
+export default function(event) {
+ let sourceEvent;
+ while (sourceEvent = event.sourceEvent) event = sourceEvent;
+ return event;
+}
diff --git a/node_modules/d3-selection/src/window.js b/node_modules/d3-selection/src/window.js
new file mode 100644
index 00000000..ca1105bd
--- /dev/null
+++ b/node_modules/d3-selection/src/window.js
@@ -0,0 +1,5 @@
+export default function(node) {
+ return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node
+ || (node.document && node) // node is a Window
+ || node.defaultView; // node is a Document
+}
diff --git a/node_modules/d3-shape/LICENSE b/node_modules/d3-shape/LICENSE
new file mode 100644
index 00000000..b0145150
--- /dev/null
+++ b/node_modules/d3-shape/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2010-2021 Mike Bostock
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/node_modules/d3-shape/README.md b/node_modules/d3-shape/README.md
new file mode 100644
index 00000000..0d53ef09
--- /dev/null
+++ b/node_modules/d3-shape/README.md
@@ -0,0 +1,1207 @@
+# d3-shape
+
+Visualizations typically consist of discrete graphical marks, such as [symbols](#symbols), [arcs](#arcs), [lines](#lines) and [areas](#areas). While the rectangles of a bar chart may be easy enough to generate directly using [SVG](http://www.w3.org/TR/SVG/paths.html#PathData) or [Canvas](http://www.w3.org/TR/2dcontext/#canvaspathmethods), other shapes are complex, such as rounded annular sectors and centripetal Catmull–Rom splines. This module provides a variety of shape generators for your convenience.
+
+As with other aspects of D3, these shapes are driven by data: each shape generator exposes accessors that control how the input data are mapped to a visual representation. For example, you might define a line generator for a time series by [scaling](https://github.com/d3/d3-scale) fields of your data to fit the chart:
+
+```js
+const line = d3.line()
+ .x(d => x(d.date))
+ .y(d => y(d.value));
+```
+
+This line generator can then be used to compute the `d` attribute of an SVG path element:
+
+```js
+path.datum(data).attr("d", line);
+```
+
+Or you can use it to render to a Canvas 2D context:
+
+```js
+line.context(context)(data);
+```
+
+For more, read [Introducing d3-shape](https://medium.com/@mbostock/introducing-d3-shape-73f8367e6d12).
+
+## Installing
+
+If you use npm, `npm install d3-shape`. You can also download the [latest release on GitHub](https://github.com/d3/d3-shape/releases/latest). For vanilla HTML in modern browsers, import d3-shape from Skypack:
+
+```html
+
+```
+
+For legacy environments, you can load d3-shape’s UMD bundle from an npm-based CDN such as jsDelivr; a `d3` global is exported:
+
+```html
+
+
+
+```
+
+## API Reference
+
+* [Arcs](#arcs)
+* [Pies](#pies)
+* [Lines](#lines)
+* [Areas](#areas)
+* [Curves](#curves)
+* [Custom Curves](#custom-curves)
+* [Links](#links)
+* [Symbols](#symbols)
+* [Custom Symbol Types](#custom-symbol-types)
+* [Stacks](#stacks)
+
+Note: all the methods that accept arrays also accept iterables and convert them to arrays internally.
+
+### Arcs
+
+[
](http://bl.ocks.org/mbostock/8878e7fd82034f1d63cf)[
](http://bl.ocks.org/mbostock/2394b23da1994fc202e1)
+
+The arc generator produces a [circular](https://en.wikipedia.org/wiki/Circular_sector) or [annular](https://en.wikipedia.org/wiki/Annulus_\(mathematics\)) sector, as in a pie or donut chart. If the absolute difference between the [start](#arc_startAngle) and [end](#arc_endAngle) angles (the *angular span*) is greater than [τ](https://en.wikipedia.org/wiki/Turn_\(geometry\)#Tau_proposal), the arc generator will produce a complete circle or annulus. If it is less than τ, the arc’s angular length will be equal to the absolute difference between the two angles (going clockwise if the signed difference is positive and anticlockwise if it is negative). If the absolute difference is less than τ, the arc may have [rounded corners](#arc_cornerRadius) and [angular padding](#arc_padAngle). Arcs are always centered at ⟨0,0⟩; use a transform (see: [SVG](http://www.w3.org/TR/SVG/coords.html#TransformAttribute), [Canvas](http://www.w3.org/TR/2dcontext/#transformations)) to move the arc to a different position.
+
+See also the [pie generator](#pies), which computes the necessary angles to represent an array of data as a pie or donut chart; these angles can then be passed to an arc generator.
+
+# d3.arc() · [Source](https://github.com/d3/d3-shape/blob/main/src/arc.js)
+
+Constructs a new arc generator with the default settings.
+
+# arc(arguments…) · [Source](https://github.com/d3/d3-shape/blob/main/src/arc.js)
+
+Generates an arc for the given *arguments*. The *arguments* are arbitrary; they are simply propagated to the arc generator’s accessor functions along with the `this` object. For example, with the default settings, an object with radii and angles is expected:
+
+```js
+const arc = d3.arc();
+
+arc({
+ innerRadius: 0,
+ outerRadius: 100,
+ startAngle: 0,
+ endAngle: Math.PI / 2
+}); // "M0,-100A100,100,0,0,1,100,0L0,0Z"
+```
+
+If the radii and angles are instead defined as constants, you can generate an arc without any arguments:
+
+```js
+const arc = d3.arc()
+ .innerRadius(0)
+ .outerRadius(100)
+ .startAngle(0)
+ .endAngle(Math.PI / 2);
+
+arc(); // "M0,-100A100,100,0,0,1,100,0L0,0Z"
+```
+
+If the arc generator has a [context](#arc_context), then the arc is rendered to this context as a sequence of [path method](http://www.w3.org/TR/2dcontext/#canvaspathmethods) calls and this function returns void. Otherwise, a [path data](http://www.w3.org/TR/SVG/paths.html#PathData) string is returned.
+
+# arc.centroid(arguments…) · [Source](https://github.com/d3/d3-shape/blob/main/src/arc.js)
+
+Computes the midpoint [*x*, *y*] of the center line of the arc that would be [generated](#_arc) by the given *arguments*. The *arguments* are arbitrary; they are simply propagated to the arc generator’s accessor functions along with the `this` object. To be consistent with the generated arc, the accessors must be deterministic, *i.e.*, return the same value given the same arguments. The midpoint is defined as ([startAngle](#arc_startAngle) + [endAngle](#arc_endAngle)) / 2 and ([innerRadius](#arc_innerRadius) + [outerRadius](#arc_outerRadius)) / 2. For example:
+
+[
](https://observablehq.com/@d3/pie-settings)[
](https://observablehq.com/@d3/pie-settings)
+
+Note that this is **not the geometric center** of the arc, which may be outside the arc; this method is merely a convenience for positioning labels.
+
+# arc.innerRadius([radius]) · [Source](https://github.com/d3/d3-shape/blob/main/src/arc.js)
+
+If *radius* is specified, sets the inner radius to the specified function or number and returns this arc generator. If *radius* is not specified, returns the current inner radius accessor, which defaults to:
+
+```js
+function innerRadius(d) {
+ return d.innerRadius;
+}
+```
+
+Specifying the inner radius as a function is useful for constructing a stacked polar bar chart, often in conjunction with a [sqrt scale](https://github.com/d3/d3-scale#sqrt). More commonly, a constant inner radius is used for a donut or pie chart. If the outer radius is smaller than the inner radius, the inner and outer radii are swapped. A negative value is treated as zero.
+
+# arc.outerRadius([radius]) · [Source](https://github.com/d3/d3-shape/blob/main/src/arc.js)
+
+If *radius* is specified, sets the outer radius to the specified function or number and returns this arc generator. If *radius* is not specified, returns the current outer radius accessor, which defaults to:
+
+```js
+function outerRadius(d) {
+ return d.outerRadius;
+}
+```
+
+Specifying the outer radius as a function is useful for constructing a coxcomb or polar bar chart, often in conjunction with a [sqrt scale](https://github.com/d3/d3-scale#sqrt). More commonly, a constant outer radius is used for a pie or donut chart. If the outer radius is smaller than the inner radius, the inner and outer radii are swapped. A negative value is treated as zero.
+
+# arc.cornerRadius([radius]) · [Source](https://github.com/d3/d3-shape/blob/main/src/arc.js)
+
+If *radius* is specified, sets the corner radius to the specified function or number and returns this arc generator. If *radius* is not specified, returns the current corner radius accessor, which defaults to:
+
+```js
+function cornerRadius() {
+ return 0;
+}
+```
+
+If the corner radius is greater than zero, the corners of the arc are rounded using circles of the given radius. For a circular sector, the two outer corners are rounded; for an annular sector, all four corners are rounded. The corner circles are shown in this diagram:
+
+[
](https://observablehq.com/@d3/pie-settings)[
](https://observablehq.com/@d3/pie-settings)
+
+The corner radius may not be larger than ([outerRadius](#arc_outerRadius) - [innerRadius](#arc_innerRadius)) / 2. In addition, for arcs whose angular span is less than π, the corner radius may be reduced as two adjacent rounded corners intersect. This is occurs more often with the inner corners. See the [arc corners animation](http://bl.ocks.org/mbostock/b7671cb38efdfa5da3af) for illustration.
+
+# arc.startAngle([angle]) · [Source](https://github.com/d3/d3-shape/blob/main/src/arc.js)
+
+If *angle* is specified, sets the start angle to the specified function or number and returns this arc generator. If *angle* is not specified, returns the current start angle accessor, which defaults to:
+
+```js
+function startAngle(d) {
+ return d.startAngle;
+}
+```
+
+The *angle* is specified in radians, with 0 at -*y* (12 o’clock) and positive angles proceeding clockwise. If |endAngle - startAngle| ≥ τ, a complete circle or annulus is generated rather than a sector.
+
+# arc.endAngle([angle]) · [Source](https://github.com/d3/d3-shape/blob/main/src/arc.js)
+
+If *angle* is specified, sets the end angle to the specified function or number and returns this arc generator. If *angle* is not specified, returns the current end angle accessor, which defaults to:
+
+```js
+function endAngle(d) {
+ return d.endAngle;
+}
+```
+
+The *angle* is specified in radians, with 0 at -*y* (12 o’clock) and positive angles proceeding clockwise. If |endAngle - startAngle| ≥ τ, a complete circle or annulus is generated rather than a sector.
+
+# arc.padAngle([angle]) · [Source](https://github.com/d3/d3-shape/blob/main/src/arc.js)
+
+If *angle* is specified, sets the pad angle to the specified function or number and returns this arc generator. If *angle* is not specified, returns the current pad angle accessor, which defaults to:
+
+```js
+function padAngle() {
+ return d && d.padAngle;
+}
+```
+
+The pad angle is converted to a fixed linear distance separating adjacent arcs, defined as [padRadius](#arc_padRadius) * padAngle. This distance is subtracted equally from the [start](#arc_startAngle) and [end](#arc_endAngle) of the arc. If the arc forms a complete circle or annulus, as when |endAngle - startAngle| ≥ τ, the pad angle is ignored.
+
+If the [inner radius](#arc_innerRadius) or angular span is small relative to the pad angle, it may not be possible to maintain parallel edges between adjacent arcs. In this case, the inner edge of the arc may collapse to a point, similar to a circular sector. For this reason, padding is typically only applied to annular sectors (*i.e.*, when innerRadius is positive), as shown in this diagram:
+
+[
](https://observablehq.com/@d3/pie-settings)[
](https://observablehq.com/@d3/pie-settings)
+
+The recommended minimum inner radius when using padding is outerRadius \* padAngle / sin(θ), where θ is the angular span of the smallest arc before padding. For example, if the outer radius is 200 pixels and the pad angle is 0.02 radians, a reasonable θ is 0.04 radians, and a reasonable inner radius is 100 pixels. See the [arc padding animation](http://bl.ocks.org/mbostock/053fcc2295a445afab07) for illustration.
+
+Often, the pad angle is not set directly on the arc generator, but is instead computed by the [pie generator](#pies) so as to ensure that the area of padded arcs is proportional to their value; see [*pie*.padAngle](#pie_padAngle). See the [pie padding animation](http://bl.ocks.org/mbostock/3e961b4c97a1b543fff2) for illustration. If you apply a constant pad angle to the arc generator directly, it tends to subtract disproportionately from smaller arcs, introducing distortion.
+
+# arc.padRadius([radius]) · [Source](https://github.com/d3/d3-shape/blob/main/src/arc.js)
+
+If *radius* is specified, sets the pad radius to the specified function or number and returns this arc generator. If *radius* is not specified, returns the current pad radius accessor, which defaults to null, indicating that the pad radius should be automatically computed as sqrt([innerRadius](#arc_innerRadius) * innerRadius + [outerRadius](#arc_outerRadius) * outerRadius). The pad radius determines the fixed linear distance separating adjacent arcs, defined as padRadius * [padAngle](#arc_padAngle).
+
+# arc.context([context]) · [Source](https://github.com/d3/d3-shape/blob/main/src/arc.js)
+
+If *context* is specified, sets the context and returns this arc generator. If *context* is not specified, returns the current context, which defaults to null. If the context is not null, then the [generated arc](#_arc) is rendered to this context as a sequence of [path method](http://www.w3.org/TR/2dcontext/#canvaspathmethods) calls. Otherwise, a [path data](http://www.w3.org/TR/SVG/paths.html#PathData) string representing the generated arc is returned.
+
+### Pies
+
+The pie generator does not produce a shape directly, but instead computes the necessary angles to represent a tabular dataset as a pie or donut chart; these angles can then be passed to an [arc generator](#arcs).
+
+# d3.pie() · [Source](https://github.com/d3/d3-shape/blob/main/src/pie.js)
+
+Constructs a new pie generator with the default settings.
+
+# pie(data[, arguments…]) · [Source](https://github.com/d3/d3-shape/blob/main/src/pie.js)
+
+Generates a pie for the given array of *data*, returning an array of objects representing each datum’s arc angles. Any additional *arguments* are arbitrary; they are simply propagated to the pie generator’s accessor functions along with the `this` object. The length of the returned array is the same as *data*, and each element *i* in the returned array corresponds to the element *i* in the input data. Each object in the returned array has the following properties:
+
+* `data` - the input datum; the corresponding element in the input data array.
+* `value` - the numeric [value](#pie_value) of the arc.
+* `index` - the zero-based [sorted index](#pie_sort) of the arc.
+* `startAngle` - the [start angle](#pie_startAngle) of the arc.
+* `endAngle` - the [end angle](#pie_endAngle) of the arc.
+* `padAngle` - the [pad angle](#pie_padAngle) of the arc.
+
+This representation is designed to work with the arc generator’s default [startAngle](#arc_startAngle), [endAngle](#arc_endAngle) and [padAngle](#arc_padAngle) accessors. The angular units are arbitrary, but if you plan to use the pie generator in conjunction with an [arc generator](#arcs), you should specify angles in radians, with 0 at -*y* (12 o’clock) and positive angles proceeding clockwise.
+
+Given a small dataset of numbers, here is how to compute the arc angles to render this data as a pie chart:
+
+```js
+const data = [1, 1, 2, 3, 5, 8, 13, 21];
+const arcs = d3.pie()(data);
+```
+
+The first pair of parens, `pie()`, [constructs](#pie) a default pie generator. The second, `pie()(data)`, [invokes](#_pie) this generator on the dataset, returning an array of objects:
+
+```json
+[
+ {"data": 1, "value": 1, "index": 6, "startAngle": 6.050474740247008, "endAngle": 6.166830023713296, "padAngle": 0},
+ {"data": 1, "value": 1, "index": 7, "startAngle": 6.166830023713296, "endAngle": 6.283185307179584, "padAngle": 0},
+ {"data": 2, "value": 2, "index": 5, "startAngle": 5.817764173314431, "endAngle": 6.050474740247008, "padAngle": 0},
+ {"data": 3, "value": 3, "index": 4, "startAngle": 5.468698322915565, "endAngle": 5.817764173314431, "padAngle": 0},
+ {"data": 5, "value": 5, "index": 3, "startAngle": 4.886921905584122, "endAngle": 5.468698322915565, "padAngle": 0},
+ {"data": 8, "value": 8, "index": 2, "startAngle": 3.956079637853813, "endAngle": 4.886921905584122, "padAngle": 0},
+ {"data": 13, "value": 13, "index": 1, "startAngle": 2.443460952792061, "endAngle": 3.956079637853813, "padAngle": 0},
+ {"data": 21, "value": 21, "index": 0, "startAngle": 0.000000000000000, "endAngle": 2.443460952792061, "padAngle": 0}
+]
+```
+
+Note that the returned array is in the same order as the data, even though this pie chart is [sorted](#pie_sortValues) by descending value, starting with the arc for the last datum (value 21) at 12 o’clock.
+
+# pie.value([value]) · [Source](https://github.com/d3/d3-shape/blob/main/src/pie.js)
+
+If *value* is specified, sets the value accessor to the specified function or number and returns this pie generator. If *value* is not specified, returns the current value accessor, which defaults to:
+
+```js
+function value(d) {
+ return d;
+}
+```
+
+When a pie is [generated](#_pie), the value accessor will be invoked for each element in the input data array, being passed the element `d`, the index `i`, and the array `data` as three arguments. The default value accessor assumes that the input data are numbers, or that they are coercible to numbers using [valueOf](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf). If your data are not simply numbers, then you should specify an accessor that returns the corresponding numeric value for a given datum. For example:
+
+```js
+const data = [
+ {"number": 4, "name": "Locke"},
+ {"number": 8, "name": "Reyes"},
+ {"number": 15, "name": "Ford"},
+ {"number": 16, "name": "Jarrah"},
+ {"number": 23, "name": "Shephard"},
+ {"number": 42, "name": "Kwon"}
+];
+
+const arcs = d3.pie()
+ .value(d => d.number)
+ (data);
+```
+
+This is similar to [mapping](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map) your data to values before invoking the pie generator:
+
+```js
+const arcs = d3.pie()(data.map(d => d.number));
+```
+
+The benefit of an accessor is that the input data remains associated with the returned objects, thereby making it easier to access other fields of the data, for example to set the color or to add text labels.
+
+# pie.sort([compare]) · [Source](https://github.com/d3/d3-shape/blob/main/src/pie.js)
+
+If *compare* is specified, sets the data comparator to the specified function and returns this pie generator. If *compare* is not specified, returns the current data comparator, which defaults to null. If both the data comparator and the value comparator are null, then arcs are positioned in the original input order. Otherwise, the data is sorted according to the data comparator, and the resulting order is used. Setting the data comparator implicitly sets the [value comparator](#pie_sortValues) to null.
+
+The *compare* function takes two arguments *a* and *b*, each elements from the input data array. If the arc for *a* should be before the arc for *b*, then the comparator must return a number less than zero; if the arc for *a* should be after the arc for *b*, then the comparator must return a number greater than zero; returning zero means that the relative order of *a* and *b* is unspecified. For example, to sort arcs by their associated name:
+
+```js
+pie.sort((a, b) => a.name.localeCompare(b.name));
+```
+
+Sorting does not affect the order of the [generated arc array](#_pie) which is always in the same order as the input data array; it merely affects the computed angles of each arc. The first arc starts at the [start angle](#pie_startAngle) and the last arc ends at the [end angle](#pie_endAngle).
+
+# pie.sortValues([compare]) · [Source](https://github.com/d3/d3-shape/blob/main/src/pie.js)
+
+If *compare* is specified, sets the value comparator to the specified function and returns this pie generator. If *compare* is not specified, returns the current value comparator, which defaults to descending value. The default value comparator is implemented as:
+
+```js
+function compare(a, b) {
+ return b - a;
+}
+```
+
+If both the data comparator and the value comparator are null, then arcs are positioned in the original input order. Otherwise, the data is sorted according to the data comparator, and the resulting order is used. Setting the value comparator implicitly sets the [data comparator](#pie_sort) to null.
+
+The value comparator is similar to the [data comparator](#pie_sort), except the two arguments *a* and *b* are values derived from the input data array using the [value accessor](#pie_value), not the data elements. If the arc for *a* should be before the arc for *b*, then the comparator must return a number less than zero; if the arc for *a* should be after the arc for *b*, then the comparator must return a number greater than zero; returning zero means that the relative order of *a* and *b* is unspecified. For example, to sort arcs by ascending value:
+
+```js
+pie.sortValues((a, b) => a - b);
+```
+
+Sorting does not affect the order of the [generated arc array](#_pie) which is always in the same order as the input data array; it merely affects the computed angles of each arc. The first arc starts at the [start angle](#pie_startAngle) and the last arc ends at the [end angle](#pie_endAngle).
+
+# pie.startAngle([angle]) · [Source](https://github.com/d3/d3-shape/blob/main/src/pie.js)
+
+If *angle* is specified, sets the overall start angle of the pie to the specified function or number and returns this pie generator. If *angle* is not specified, returns the current start angle accessor, which defaults to:
+
+```js
+function startAngle() {
+ return 0;
+}
+```
+
+The start angle here means the *overall* start angle of the pie, *i.e.*, the start angle of the first arc. The start angle accessor is invoked once, being passed the same arguments and `this` context as the [pie generator](#_pie). The units of *angle* are arbitrary, but if you plan to use the pie generator in conjunction with an [arc generator](#arcs), you should specify an angle in radians, with 0 at -*y* (12 o’clock) and positive angles proceeding clockwise.
+
+# pie.endAngle([angle]) · [Source](https://github.com/d3/d3-shape/blob/main/src/pie.js)
+
+If *angle* is specified, sets the overall end angle of the pie to the specified function or number and returns this pie generator. If *angle* is not specified, returns the current end angle accessor, which defaults to:
+
+```js
+function endAngle() {
+ return 2 * Math.PI;
+}
+```
+
+The end angle here means the *overall* end angle of the pie, *i.e.*, the end angle of the last arc. The end angle accessor is invoked once, being passed the same arguments and `this` context as the [pie generator](#_pie). The units of *angle* are arbitrary, but if you plan to use the pie generator in conjunction with an [arc generator](#arcs), you should specify an angle in radians, with 0 at -*y* (12 o’clock) and positive angles proceeding clockwise.
+
+The value of the end angle is constrained to [startAngle](#pie_startAngle) ± τ, such that |endAngle - startAngle| ≤ τ.
+
+# pie.padAngle([angle]) · [Source](https://github.com/d3/d3-shape/blob/main/src/pie.js)
+
+If *angle* is specified, sets the pad angle to the specified function or number and returns this pie generator. If *angle* is not specified, returns the current pad angle accessor, which defaults to:
+
+```js
+function padAngle() {
+ return 0;
+}
+```
+
+The pad angle here means the angular separation between each adjacent arc. The total amount of padding reserved is the specified *angle* times the number of elements in the input data array, and at most |endAngle - startAngle|; the remaining space is then divided proportionally by [value](#pie_value) such that the relative area of each arc is preserved. See the [pie padding animation](http://bl.ocks.org/mbostock/3e961b4c97a1b543fff2) for illustration. The pad angle accessor is invoked once, being passed the same arguments and `this` context as the [pie generator](#_pie). The units of *angle* are arbitrary, but if you plan to use the pie generator in conjunction with an [arc generator](#arcs), you should specify an angle in radians.
+
+### Lines
+
+[
](https://observablehq.com/@d3/line-chart)
+
+The line generator produces a [spline](https://en.wikipedia.org/wiki/Spline_\(mathematics\)) or [polyline](https://en.wikipedia.org/wiki/Polygonal_chain), as in a line chart. Lines also appear in many other visualization types, such as the links in [hierarchical edge bundling](https://observablehq.com/@d3/hierarchical-edge-bundling).
+
+# d3.line([x][, y]) · [Source](https://github.com/d3/d3-shape/blob/main/src/line.js), [Examples](https://observablehq.com/@d3/d3-line)
+
+Constructs a new line generator with the default settings. If *x* or *y* are specified, sets the corresponding accessors to the specified function or number and returns this line generator.
+
+# line(data) · [Source](https://github.com/d3/d3-shape/blob/main/src/line.js), [Examples](https://observablehq.com/@d3/d3-line)
+
+Generates a line for the given array of *data*. Depending on this line generator’s associated [curve](#line_curve), the given input *data* may need to be sorted by *x*-value before being passed to the line generator. If the line generator has a [context](#line_context), then the line is rendered to this context as a sequence of [path method](http://www.w3.org/TR/2dcontext/#canvaspathmethods) calls and this function returns void. Otherwise, a [path data](http://www.w3.org/TR/SVG/paths.html#PathData) string is returned.
+
+# line.x([x]) · [Source](https://github.com/d3/d3-shape/blob/main/src/line.js), [Examples](https://observablehq.com/@d3/d3-line)
+
+If *x* is specified, sets the x accessor to the specified function or number and returns this line generator. If *x* is not specified, returns the current x accessor, which defaults to:
+
+```js
+function x(d) {
+ return d[0];
+}
+```
+
+When a line is [generated](#_line), the x accessor will be invoked for each [defined](#line_defined) element in the input data array, being passed the element `d`, the index `i`, and the array `data` as three arguments. The default x accessor assumes that the input data are two-element arrays of numbers. If your data are in a different format, or if you wish to transform the data before rendering, then you should specify a custom accessor. For example, if `x` is a [time scale](https://github.com/d3/d3-scale#time-scales) and `y` is a [linear scale](https://github.com/d3/d3-scale#linear-scales):
+
+```js
+const data = [
+ {date: new Date(2007, 3, 24), value: 93.24},
+ {date: new Date(2007, 3, 25), value: 95.35},
+ {date: new Date(2007, 3, 26), value: 98.84},
+ {date: new Date(2007, 3, 27), value: 99.92},
+ {date: new Date(2007, 3, 30), value: 99.80},
+ {date: new Date(2007, 4, 1), value: 99.47},
+ …
+];
+
+const line = d3.line()
+ .x(d => x(d.date))
+ .y(d => y(d.value));
+```
+
+# line.y([y]) · [Source](https://github.com/d3/d3-shape/blob/main/src/line.js), [Examples](https://observablehq.com/@d3/d3-line)
+
+If *y* is specified, sets the y accessor to the specified function or number and returns this line generator. If *y* is not specified, returns the current y accessor, which defaults to:
+
+```js
+function y(d) {
+ return d[1];
+}
+```
+
+When a line is [generated](#_line), the y accessor will be invoked for each [defined](#line_defined) element in the input data array, being passed the element `d`, the index `i`, and the array `data` as three arguments. The default y accessor assumes that the input data are two-element arrays of numbers. See [*line*.x](#line_x) for more information.
+
+# line.defined([defined]) · [Source](https://github.com/d3/d3-shape/blob/main/src/line.js), [Examples](https://observablehq.com/@d3/d3-line)
+
+If *defined* is specified, sets the defined accessor to the specified function or boolean and returns this line generator. If *defined* is not specified, returns the current defined accessor, which defaults to:
+
+```js
+function defined() {
+ return true;
+}
+```
+
+The default accessor thus assumes that the input data is always defined. When a line is [generated](#_line), the defined accessor will be invoked for each element in the input data array, being passed the element `d`, the index `i`, and the array `data` as three arguments. If the given element is defined (*i.e.*, if the defined accessor returns a truthy value for this element), the [x](#line_x) and [y](#line_y) accessors will subsequently be evaluated and the point will be added to the current line segment. Otherwise, the element will be skipped, the current line segment will be ended, and a new line segment will be generated for the next defined point. As a result, the generated line may have several discrete segments. For example:
+
+[
](http://bl.ocks.org/mbostock/0533f44f2cfabecc5e3a)
+
+Note that if a line segment consists of only a single point, it may appear invisible unless rendered with rounded or square [line caps](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap). In addition, some curves such as [curveCardinalOpen](#curveCardinalOpen) only render a visible segment if it contains multiple points.
+
+# line.curve([curve]) · [Source](https://github.com/d3/d3-shape/blob/main/src/line.js), [Examples](https://observablehq.com/@d3/d3-line)
+
+If *curve* is specified, sets the [curve factory](#curves) and returns this line generator. If *curve* is not specified, returns the current curve factory, which defaults to [curveLinear](#curveLinear).
+
+# line.context([context]) · [Source](https://github.com/d3/d3-shape/blob/main/src/line.js), [Examples](https://observablehq.com/@d3/d3-line)
+
+If *context* is specified, sets the context and returns this line generator. If *context* is not specified, returns the current context, which defaults to null. If the context is not null, then the [generated line](#_line) is rendered to this context as a sequence of [path method](http://www.w3.org/TR/2dcontext/#canvaspathmethods) calls. Otherwise, a [path data](http://www.w3.org/TR/SVG/paths.html#PathData) string representing the generated line is returned.
+
+# d3.lineRadial() · [Source](https://github.com/d3/d3-shape/blob/main/src/lineRadial.js), [Examples](https://observablehq.com/@d3/d3-lineradial)
+
+
+
+Constructs a new radial line generator with the default settings. A radial line generator is equivalent to the standard Cartesian [line generator](#line), except the [x](#line_x) and [y](#line_y) accessors are replaced with [angle](#lineRadial_angle) and [radius](#lineRadial_radius) accessors. Radial lines are always positioned relative to ⟨0,0⟩; use a transform (see: [SVG](http://www.w3.org/TR/SVG/coords.html#TransformAttribute), [Canvas](http://www.w3.org/TR/2dcontext/#transformations)) to change the origin.
+
+# lineRadial(data) · [Source](https://github.com/d3/d3-shape/blob/main/src/lineRadial.js#L4), [Examples](https://observablehq.com/@d3/d3-lineradial)
+
+Equivalent to [*line*](#_line).
+
+# lineRadial.angle([angle]) · [Source](https://github.com/d3/d3-shape/blob/main/src/lineRadial.js#L7), [Examples](https://observablehq.com/@d3/d3-lineradial)
+
+Equivalent to [*line*.x](#line_x), except the accessor returns the angle in radians, with 0 at -*y* (12 o’clock).
+
+# lineRadial.radius([radius]) · [Source](https://github.com/d3/d3-shape/blob/main/src/lineRadial.js#L8), [Examples](https://observablehq.com/@d3/d3-lineradial)
+
+Equivalent to [*line*.y](#line_y), except the accessor returns the radius: the distance from the origin ⟨0,0⟩.
+
+# lineRadial.defined([defined])
+
+Equivalent to [*line*.defined](#line_defined).
+
+# lineRadial.curve([curve]) · [Source](https://github.com/d3/d3-shape/blob/main/src/lineRadial.js), [Examples](https://observablehq.com/@d3/d3-lineradial)
+
+Equivalent to [*line*.curve](#line_curve). Note that [curveMonotoneX](#curveMonotoneX) or [curveMonotoneY](#curveMonotoneY) are not recommended for radial lines because they assume that the data is monotonic in *x* or *y*, which is typically untrue of radial lines.
+
+# lineRadial.context([context])
+
+Equivalent to [*line*.context](#line_context).
+
+### Areas
+
+[
](https://observablehq.com/@d3/area-chart)[
](https://observablehq.com/@d3/stacked-area-chart)[
](https://observablehq.com/@d3/difference-chart)
+
+The area generator produces an area, as in an area chart. An area is defined by two bounding [lines](#lines), either splines or polylines. Typically, the two lines share the same [*x*-values](#area_x) ([x0](#area_x0) = [x1](#area_x1)), differing only in *y*-value ([y0](#area_y0) and [y1](#area_y1)); most commonly, y0 is defined as a constant representing [zero](http://www.vox.com/2015/11/19/9758062/y-axis-zero-chart). The first line (the topline) is defined by x1 and y1 and is rendered first; the second line (the baseline) is defined by x0 and y0 and is rendered second, with the points in reverse order. With a [curveLinear](#curveLinear) [curve](#area_curve), this produces a clockwise polygon.
+
+# d3.area([x][, y0][, y1]) · [Source](https://github.com/d3/d3-shape/blob/main/src/area.js)
+
+Constructs a new area generator with the default settings. If *x*, *y0* or *y1* are specified, sets the corresponding accessors to the specified function or number and returns this area generator.
+
+# area(data) · [Source](https://github.com/d3/d3-shape/blob/main/src/area.js)
+
+Generates an area for the given array of *data*. Depending on this area generator’s associated [curve](#area_curve), the given input *data* may need to be sorted by *x*-value before being passed to the area generator. If the area generator has a [context](#line_context), then the area is rendered to this context as a sequence of [path method](http://www.w3.org/TR/2dcontext/#canvaspathmethods) calls and this function returns void. Otherwise, a [path data](http://www.w3.org/TR/SVG/paths.html#PathData) string is returned.
+
+# area.x([x]) · [Source](https://github.com/d3/d3-shape/blob/main/src/area.js)
+
+If *x* is specified, sets [x0](#area_x0) to *x* and [x1](#area_x1) to null and returns this area generator. If *x* is not specified, returns the current x0 accessor.
+
+# area.x0([x]) · [Source](https://github.com/d3/d3-shape/blob/main/src/area.js)
+
+If *x* is specified, sets the x0 accessor to the specified function or number and returns this area generator. If *x* is not specified, returns the current x0 accessor, which defaults to:
+
+```js
+function x(d) {
+ return d[0];
+}
+```
+
+When an area is [generated](#_area), the x0 accessor will be invoked for each [defined](#area_defined) element in the input data array, being passed the element `d`, the index `i`, and the array `data` as three arguments. The default x0 accessor assumes that the input data are two-element arrays of numbers. If your data are in a different format, or if you wish to transform the data before rendering, then you should specify a custom accessor. For example, if `x` is a [time scale](https://github.com/d3/d3-scale#time-scales) and `y` is a [linear scale](https://github.com/d3/d3-scale#linear-scales):
+
+```js
+const data = [
+ {date: new Date(2007, 3, 24), value: 93.24},
+ {date: new Date(2007, 3, 25), value: 95.35},
+ {date: new Date(2007, 3, 26), value: 98.84},
+ {date: new Date(2007, 3, 27), value: 99.92},
+ {date: new Date(2007, 3, 30), value: 99.80},
+ {date: new Date(2007, 4, 1), value: 99.47},
+ …
+];
+
+const area = d3.area()
+ .x(d => x(d.date))
+ .y1(d => y(d.value))
+ .y0(y(0));
+```
+
+# area.x1([x]) · [Source](https://github.com/d3/d3-shape/blob/main/src/area.js)
+
+If *x* is specified, sets the x1 accessor to the specified function or number and returns this area generator. If *x* is not specified, returns the current x1 accessor, which defaults to null, indicating that the previously-computed [x0](#area_x0) value should be reused for the x1 value.
+
+When an area is [generated](#_area), the x1 accessor will be invoked for each [defined](#area_defined) element in the input data array, being passed the element `d`, the index `i`, and the array `data` as three arguments. See [*area*.x0](#area_x0) for more information.
+
+# area.y([y]) · [Source](https://github.com/d3/d3-shape/blob/main/src/area.js)
+
+If *y* is specified, sets [y0](#area_y0) to *y* and [y1](#area_y1) to null and returns this area generator. If *y* is not specified, returns the current y0 accessor.
+
+# area.y0([y]) · [Source](https://github.com/d3/d3-shape/blob/main/src/area.js)
+
+If *y* is specified, sets the y0 accessor to the specified function or number and returns this area generator. If *y* is not specified, returns the current y0 accessor, which defaults to:
+
+```js
+function y() {
+ return 0;
+}
+```
+
+When an area is [generated](#_area), the y0 accessor will be invoked for each [defined](#area_defined) element in the input data array, being passed the element `d`, the index `i`, and the array `data` as three arguments. See [*area*.x0](#area_x0) for more information.
+
+# area.y1([y]) · [Source](https://github.com/d3/d3-shape/blob/main/src/area.js)
+
+If *y* is specified, sets the y1 accessor to the specified function or number and returns this area generator. If *y* is not specified, returns the current y1 accessor, which defaults to:
+
+```js
+function y(d) {
+ return d[1];
+}
+```
+
+A null accessor is also allowed, indicating that the previously-computed [y0](#area_y0) value should be reused for the y1 value. When an area is [generated](#_area), the y1 accessor will be invoked for each [defined](#area_defined) element in the input data array, being passed the element `d`, the index `i`, and the array `data` as three arguments. See [*area*.x0](#area_x0) for more information.
+
+# area.defined([defined]) · [Source](https://github.com/d3/d3-shape/blob/main/src/area.js)
+
+If *defined* is specified, sets the defined accessor to the specified function or boolean and returns this area generator. If *defined* is not specified, returns the current defined accessor, which defaults to:
+
+```js
+function defined() {
+ return true;
+}
+```
+
+The default accessor thus assumes that the input data is always defined. When an area is [generated](#_area), the defined accessor will be invoked for each element in the input data array, being passed the element `d`, the index `i`, and the array `data` as three arguments. If the given element is defined (*i.e.*, if the defined accessor returns a truthy value for this element), the [x0](#area_x0), [x1](#area_x1), [y0](#area_y0) and [y1](#area_y1) accessors will subsequently be evaluated and the point will be added to the current area segment. Otherwise, the element will be skipped, the current area segment will be ended, and a new area segment will be generated for the next defined point. As a result, the generated area may have several discrete segments. For example:
+
+[
](http://bl.ocks.org/mbostock/3035090)
+
+Note that if an area segment consists of only a single point, it may appear invisible unless rendered with rounded or square [line caps](https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-linecap). In addition, some curves such as [curveCardinalOpen](#curveCardinalOpen) only render a visible segment if it contains multiple points.
+
+# area.curve([curve]) · [Source](https://github.com/d3/d3-shape/blob/main/src/area.js)
+
+If *curve* is specified, sets the [curve factory](#curves) and returns this area generator. If *curve* is not specified, returns the current curve factory, which defaults to [curveLinear](#curveLinear).
+
+# area.context([context]) · [Source](https://github.com/d3/d3-shape/blob/main/src/area.js)
+
+If *context* is specified, sets the context and returns this area generator. If *context* is not specified, returns the current context, which defaults to null. If the context is not null, then the [generated area](#_area) is rendered to this context as a sequence of [path method](http://www.w3.org/TR/2dcontext/#canvaspathmethods) calls. Otherwise, a [path data](http://www.w3.org/TR/SVG/paths.html#PathData) string representing the generated area is returned.
+
+# area.lineX0() · [Source](https://github.com/d3/d3-shape/blob/main/src/area.js)
+
# area.lineY0() · [Source](https://github.com/d3/d3-shape/blob/main/src/area.js)
+
+Returns a new [line generator](#lines) that has this area generator’s current [defined accessor](#area_defined), [curve](#area_curve) and [context](#area_context). The line’s [*x*-accessor](#line_x) is this area’s [*x0*-accessor](#area_x0), and the line’s [*y*-accessor](#line_y) is this area’s [*y0*-accessor](#area_y0).
+
+# area.lineX1() · [Source](https://github.com/d3/d3-shape/blob/main/src/area.js)
+
+Returns a new [line generator](#lines) that has this area generator’s current [defined accessor](#area_defined), [curve](#area_curve) and [context](#area_context). The line’s [*x*-accessor](#line_x) is this area’s [*x1*-accessor](#area_x1), and the line’s [*y*-accessor](#line_y) is this area’s [*y0*-accessor](#area_y0).
+
+# area.lineY1() · [Source](https://github.com/d3/d3-shape/blob/main/src/area.js)
+
+Returns a new [line generator](#lines) that has this area generator’s current [defined accessor](#area_defined), [curve](#area_curve) and [context](#area_context). The line’s [*x*-accessor](#line_x) is this area’s [*x0*-accessor](#area_x0), and the line’s [*y*-accessor](#line_y) is this area’s [*y1*-accessor](#area_y1).
+
+# d3.areaRadial() · [Source](https://github.com/d3/d3-shape/blob/main/src/areaRadial.js)
+
+
+
+Constructs a new radial area generator with the default settings. A radial area generator is equivalent to the standard Cartesian [area generator](#area), except the [x](#area_x) and [y](#area_y) accessors are replaced with [angle](#areaRadial_angle) and [radius](#areaRadial_radius) accessors. Radial areas are always positioned relative to ⟨0,0⟩; use a transform (see: [SVG](http://www.w3.org/TR/SVG/coords.html#TransformAttribute), [Canvas](http://www.w3.org/TR/2dcontext/#transformations)) to change the origin.
+
+# areaRadial(data)
+
+Equivalent to [*area*](#_area).
+
+# areaRadial.angle([angle]) · [Source](https://github.com/d3/d3-shape/blob/main/src/areaRadial.js)
+
+Equivalent to [*area*.x](#area_x), except the accessor returns the angle in radians, with 0 at -*y* (12 o’clock).
+
+# areaRadial.startAngle([angle]) · [Source](https://github.com/d3/d3-shape/blob/main/src/areaRadial.js)
+
+Equivalent to [*area*.x0](#area_x0), except the accessor returns the angle in radians, with 0 at -*y* (12 o’clock). Note: typically [angle](#areaRadial_angle) is used instead of setting separate start and end angles.
+
+# areaRadial.endAngle([angle]) · [Source](https://github.com/d3/d3-shape/blob/main/src/areaRadial.js)
+
+Equivalent to [*area*.x1](#area_x1), except the accessor returns the angle in radians, with 0 at -*y* (12 o’clock). Note: typically [angle](#areaRadial_angle) is used instead of setting separate start and end angles.
+
+# areaRadial.radius([radius]) · [Source](https://github.com/d3/d3-shape/blob/main/src/areaRadial.js)
+
+Equivalent to [*area*.y](#area_y), except the accessor returns the radius: the distance from the origin ⟨0,0⟩.
+
+# areaRadial.innerRadius([radius]) · [Source](https://github.com/d3/d3-shape/blob/main/src/areaRadial.js)
+
+Equivalent to [*area*.y0](#area_y0), except the accessor returns the radius: the distance from the origin ⟨0,0⟩.
+
+# areaRadial.outerRadius([radius]) · [Source](https://github.com/d3/d3-shape/blob/main/src/areaRadial.js)
+
+Equivalent to [*area*.y1](#area_y1), except the accessor returns the radius: the distance from the origin ⟨0,0⟩.
+
+# areaRadial.defined([defined])
+
+Equivalent to [*area*.defined](#area_defined).
+
+# areaRadial.curve([curve]) · [Source](https://github.com/d3/d3-shape/blob/main/src/areaRadial.js)
+
+Equivalent to [*area*.curve](#area_curve). Note that [curveMonotoneX](#curveMonotoneX) or [curveMonotoneY](#curveMonotoneY) are not recommended for radial areas because they assume that the data is monotonic in *x* or *y*, which is typically untrue of radial areas.
+
+# areaRadial.context([context])
+
+Equivalent to [*line*.context](#line_context).
+
+# areaRadial.lineStartAngle() · [Source](https://github.com/d3/d3-shape/blob/main/src/areaRadial.js)
+
# areaRadial.lineInnerRadius() · [Source](https://github.com/d3/d3-shape/blob/main/src/areaRadial.js)
+
+Returns a new [radial line generator](#lineRadial) that has this radial area generator’s current [defined accessor](#areaRadial_defined), [curve](#areaRadial_curve) and [context](#areaRadial_context). The line’s [angle accessor](#lineRadial_angle) is this area’s [start angle accessor](#areaRadial_startAngle), and the line’s [radius accessor](#lineRadial_radius) is this area’s [inner radius accessor](#areaRadial_innerRadius).
+
+# areaRadial.lineEndAngle() · [Source](https://github.com/d3/d3-shape/blob/main/src/areaRadial.js)
+
+Returns a new [radial line generator](#lineRadial) that has this radial area generator’s current [defined accessor](#areaRadial_defined), [curve](#areaRadial_curve) and [context](#areaRadial_context). The line’s [angle accessor](#lineRadial_angle) is this area’s [end angle accessor](#areaRadial_endAngle), and the line’s [radius accessor](#lineRadial_radius) is this area’s [inner radius accessor](#areaRadial_innerRadius).
+
+# areaRadial.lineOuterRadius() · [Source](https://github.com/d3/d3-shape/blob/main/src/areaRadial.js)
+
+Returns a new [radial line generator](#lineRadial) that has this radial area generator’s current [defined accessor](#areaRadial_defined), [curve](#areaRadial_curve) and [context](#areaRadial_context). The line’s [angle accessor](#lineRadial_angle) is this area’s [start angle accessor](#areaRadial_startAngle), and the line’s [radius accessor](#lineRadial_radius) is this area’s [outer radius accessor](#areaRadial_outerRadius).
+
+### Curves
+
+While [lines](#lines) are defined as a sequence of two-dimensional [*x*, *y*] points, and [areas](#areas) are similarly defined by a topline and a baseline, there remains the task of transforming this discrete representation into a continuous shape: *i.e.*, how to interpolate between the points. A variety of curves are provided for this purpose.
+
+Curves are typically not constructed or used directly, instead being passed to [*line*.curve](#line_curve) and [*area*.curve](#area_curve). For example:
+
+```js
+const line = d3.line(d => d.date, d => d.value)
+ .curve(d3.curveCatmullRom.alpha(0.5));
+```
+
+# d3.curveBasis(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/basis.js)
+
+
+
+Produces a cubic [basis spline](https://en.wikipedia.org/wiki/B-spline) using the specified control points. The first and last points are triplicated such that the spline starts at the first point and ends at the last point, and is tangent to the line between the first and second points, and to the line between the penultimate and last points.
+
+# d3.curveBasisClosed(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/basisClosed.js)
+
+
+
+Produces a closed cubic [basis spline](https://en.wikipedia.org/wiki/B-spline) using the specified control points. When a line segment ends, the first three control points are repeated, producing a closed loop with C2 continuity.
+
+# d3.curveBasisOpen(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/basisOpen.js)
+
+
+
+Produces a cubic [basis spline](https://en.wikipedia.org/wiki/B-spline) using the specified control points. Unlike [basis](#basis), the first and last points are not repeated, and thus the curve typically does not intersect these points.
+
+# d3.curveBumpX(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/bump.js)
+
+
+
+Produces a Bézier curve between each pair of points, with horizontal tangents at each point.
+
+# d3.curveBumpY(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/bump.js)
+
+
+
+Produces a Bézier curve between each pair of points, with vertical tangents at each point.
+
+# d3.curveBundle(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/bundle.js)
+
+
+
+Produces a straightened cubic [basis spline](https://en.wikipedia.org/wiki/B-spline) using the specified control points, with the spline straightened according to the curve’s [*beta*](#curveBundle_beta), which defaults to 0.85. This curve is typically used in [hierarchical edge bundling](https://observablehq.com/@d3/hierarchical-edge-bundling) to disambiguate connections, as proposed by [Danny Holten](https://www.win.tue.nl/vis1/home/dholten/) in [Hierarchical Edge Bundles: Visualization of Adjacency Relations in Hierarchical Data](https://www.win.tue.nl/vis1/home/dholten/papers/bundles_infovis.pdf). This curve does not implement [*curve*.areaStart](#curve_areaStart) and [*curve*.areaEnd](#curve_areaEnd); it is intended to work with [d3.line](#lines), not [d3.area](#areas).
+
+# bundle.beta(beta) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/bundle.js)
+
+Returns a bundle curve with the specified *beta* in the range [0, 1], representing the bundle strength. If *beta* equals zero, a straight line between the first and last point is produced; if *beta* equals one, a standard [basis](#basis) spline is produced. For example:
+
+```js
+const line = d3.line().curve(d3.curveBundle.beta(0.5));
+```
+
+# d3.curveCardinal(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/cardinal.js)
+
+
+
+Produces a cubic [cardinal spline](https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Cardinal_spline) using the specified control points, with one-sided differences used for the first and last piece. The default [tension](#curveCardinal_tension) is 0.
+
+# d3.curveCardinalClosed(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/cardinalClosed.js)
+
+
+
+Produces a closed cubic [cardinal spline](https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Cardinal_spline) using the specified control points. When a line segment ends, the first three control points are repeated, producing a closed loop. The default [tension](#curveCardinal_tension) is 0.
+
+# d3.curveCardinalOpen(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/cardinalOpen.js)
+
+
+
+Produces a cubic [cardinal spline](https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Cardinal_spline) using the specified control points. Unlike [curveCardinal](#curveCardinal), one-sided differences are not used for the first and last piece, and thus the curve starts at the second point and ends at the penultimate point. The default [tension](#curveCardinal_tension) is 0.
+
+# cardinal.tension(tension) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/cardinalOpen.js)
+
+Returns a cardinal curve with the specified *tension* in the range [0, 1]. The *tension* determines the length of the tangents: a *tension* of one yields all zero tangents, equivalent to [curveLinear](#curveLinear); a *tension* of zero produces a uniform [Catmull–Rom](#curveCatmullRom) spline. For example:
+
+```js
+const line = d3.line().curve(d3.curveCardinal.tension(0.5));
+```
+
+# d3.curveCatmullRom(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/catmullRom.js)
+
+
+
+Produces a cubic Catmull–Rom spline using the specified control points and the parameter [*alpha*](#curveCatmullRom_alpha), which defaults to 0.5, as proposed by Yuksel et al. in [On the Parameterization of Catmull–Rom Curves](http://www.cemyuksel.com/research/catmullrom_param/), with one-sided differences used for the first and last piece.
+
+# d3.curveCatmullRomClosed(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/catmullRomClosed.js)
+
+
+
+Produces a closed cubic Catmull–Rom spline using the specified control points and the parameter [*alpha*](#curveCatmullRom_alpha), which defaults to 0.5, as proposed by Yuksel et al. When a line segment ends, the first three control points are repeated, producing a closed loop.
+
+# d3.curveCatmullRomOpen(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/catmullRomOpen.js)
+
+
+
+Produces a cubic Catmull–Rom spline using the specified control points and the parameter [*alpha*](#curveCatmullRom_alpha), which defaults to 0.5, as proposed by Yuksel et al. Unlike [curveCatmullRom](#curveCatmullRom), one-sided differences are not used for the first and last piece, and thus the curve starts at the second point and ends at the penultimate point.
+
+# catmullRom.alpha(alpha) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/catmullRom.js)
+
+Returns a cubic Catmull–Rom curve with the specified *alpha* in the range [0, 1]. If *alpha* is zero, produces a uniform spline, equivalent to [curveCardinal](#curveCardinal) with a tension of zero; if *alpha* is one, produces a chordal spline; if *alpha* is 0.5, produces a [centripetal spline](https://en.wikipedia.org/wiki/Centripetal_Catmull–Rom_spline). Centripetal splines are recommended to avoid self-intersections and overshoot. For example:
+
+```js
+const line = d3.line().curve(d3.curveCatmullRom.alpha(0.5));
+```
+
+# d3.curveLinear(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/linear.js)
+
+
+
+Produces a polyline through the specified points.
+
+# d3.curveLinearClosed(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/linearClosed.js)
+
+
+
+Produces a closed polyline through the specified points by repeating the first point when the line segment ends.
+
+# d3.curveMonotoneX(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/monotone.js)
+
+
+
+Produces a cubic spline that [preserves monotonicity](https://en.wikipedia.org/wiki/Monotone_cubic_interpolation) in *y*, assuming monotonicity in *x*, as proposed by Steffen in [A simple method for monotonic interpolation in one dimension](http://adsabs.harvard.edu/full/1990A%26A...239..443S): “a smooth curve with continuous first-order derivatives that passes through any given set of data points without spurious oscillations. Local extrema can occur only at grid points where they are given by the data, but not in between two adjacent grid points.”
+
+# d3.curveMonotoneY(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/monotone.js)
+
+
+
+Produces a cubic spline that [preserves monotonicity](https://en.wikipedia.org/wiki/Monotone_cubic_interpolation) in *x*, assuming monotonicity in *y*, as proposed by Steffen in [A simple method for monotonic interpolation in one dimension](http://adsabs.harvard.edu/full/1990A%26A...239..443S): “a smooth curve with continuous first-order derivatives that passes through any given set of data points without spurious oscillations. Local extrema can occur only at grid points where they are given by the data, but not in between two adjacent grid points.”
+
+# d3.curveNatural(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/natural.js)
+
+
+
+Produces a [natural](https://en.wikipedia.org/wiki/Spline_interpolation) [cubic spline](http://mathworld.wolfram.com/CubicSpline.html) with the second derivative of the spline set to zero at the endpoints.
+
+# d3.curveStep(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/step.js)
+
+
+
+Produces a piecewise constant function (a [step function](https://en.wikipedia.org/wiki/Step_function)) consisting of alternating horizontal and vertical lines. The *y*-value changes at the midpoint of each pair of adjacent *x*-values.
+
+# d3.curveStepAfter(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/step.js)
+
+
+
+Produces a piecewise constant function (a [step function](https://en.wikipedia.org/wiki/Step_function)) consisting of alternating horizontal and vertical lines. The *y*-value changes after the *x*-value.
+
+# d3.curveStepBefore(context) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/step.js)
+
+
+
+Produces a piecewise constant function (a [step function](https://en.wikipedia.org/wiki/Step_function)) consisting of alternating horizontal and vertical lines. The *y*-value changes before the *x*-value.
+
+### Custom Curves
+
+Curves are typically not used directly, instead being passed to [*line*.curve](#line_curve) and [*area*.curve](#area_curve). However, you can define your own curve implementation should none of the built-in curves satisfy your needs using the following interface. You can also use this low-level interface with a built-in curve type as an alternative to the line and area generators.
+
+# curve.areaStart() · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/step.js#L7)
+
+Indicates the start of a new area segment. Each area segment consists of exactly two [line segments](#curve_lineStart): the topline, followed by the baseline, with the baseline points in reverse order.
+
+# curve.areaEnd() · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/step.js)
+
+Indicates the end of the current area segment.
+
+# curve.lineStart() · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/step.js)
+
+Indicates the start of a new line segment. Zero or more [points](#curve_point) will follow.
+
+# curve.lineEnd() · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/step.js)
+
+Indicates the end of the current line segment.
+
+# curve.point(x, y) · [Source](https://github.com/d3/d3-shape/blob/main/src/curve/step.js)
+
+Indicates a new point in the current line segment with the given *x*- and *y*-values.
+
+### Links
+
+[
](https://observablehq.com/@d3/tidy-tree)
+
+The **link** shape generates a smooth cubic Bézier curve from a source point to a target point. The tangents of the curve at the start and end are either [vertical](#linkVertical), [horizontal](#linkHorizontal) or [radial](#linkRadial).
+
+# d3.link(curve) · [Source](https://github.com/d3/d3-shape/blob/main/src/link.js)
+
+Returns a new [link generator](#_link) using the specified curve. For example, to visualize [links](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_links) in a [tree diagram](https://github.com/d3/d3-hierarchy/blob/master/README.md#tree) rooted on the top edge of the display, you might say:
+
+```js
+const link = d3.link(d3.curveBumpY)
+ .x(d => d.x)
+ .y(d => d.y);
+```
+
+# d3.linkVertical() · [Source](https://github.com/d3/d3-shape/blob/main/src/link.js)
+
+Shorthand for [d3.link](#link) with [d3.curveBumpY](#curveBumpY); suitable for visualizing [links](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_links) in a [tree diagram](https://github.com/d3/d3-hierarchy/blob/master/README.md#tree) rooted on the top edge of the display. Equivalent to:
+
+```js
+const link = d3.link(d3.curveBumpY);
+```
+
+# d3.linkHorizontal() · [Source](https://github.com/d3/d3-shape/blob/main/src/link.js)
+
+Shorthand for [d3.link](#link) with [d3.curveBumpX](#curveBumpX); suitable for visualizing [links](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_links) in a [tree diagram](https://github.com/d3/d3-hierarchy/blob/master/README.md#tree) rooted on the left edge of the display. Equivalent to:
+
+```js
+const link = d3.link(d3.curveBumpX);
+```
+
+# link(arguments…) · [Source](https://github.com/d3/d3-shape/blob/main/src/link.js)
+
+Generates a link for the given *arguments*. The *arguments* are arbitrary; they are simply propagated to the link generator’s accessor functions along with the `this` object. For example, with the default settings, an object expected:
+
+```js
+link({
+ source: [100, 100],
+ target: [300, 300]
+});
+```
+
+# link.source([source]) · [Source](https://github.com/d3/d3-shape/blob/main/src/link.js)
+
+If *source* is specified, sets the source accessor to the specified function and returns this link generator. If *source* is not specified, returns the current source accessor, which defaults to:
+
+```js
+function source(d) {
+ return d.source;
+}
+```
+
+# link.target([target]) · [Source](https://github.com/d3/d3-shape/blob/main/src/link.js)
+
+If *target* is specified, sets the target accessor to the specified function and returns this link generator. If *target* is not specified, returns the current target accessor, which defaults to:
+
+```js
+function target(d) {
+ return d.target;
+}
+```
+
+# link.x([x]) · [Source](https://github.com/d3/d3-shape/blob/main/src/link.js)
+
+If *x* is specified, sets the *x*-accessor to the specified function or number and returns this link generator. If *x* is not specified, returns the current *x*-accessor, which defaults to:
+
+```js
+function x(d) {
+ return d[0];
+}
+```
+
+# link.y([y]) · [Source](https://github.com/d3/d3-shape/blob/main/src/link.js)
+
+If *y* is specified, sets the *y*-accessor to the specified function or number and returns this link generator. If *y* is not specified, returns the current *y*-accessor, which defaults to:
+
+```js
+function y(d) {
+ return d[1];
+}
+```
+
+# link.context([context]) · [Source](https://github.com/d3/d3-shape/blob/main/src/link.js)
+
+If *context* is specified, sets the context and returns this link generator. If *context* is not specified, returns the current context, which defaults to null. If the context is not null, then the [generated link](#_link) is rendered to this context as a sequence of [path method](http://www.w3.org/TR/2dcontext/#canvaspathmethods) calls. Otherwise, a [path data](http://www.w3.org/TR/SVG/paths.html#PathData) string representing the generated link is returned. See also [d3-path](https://github.com/d3/d3-path).
+
+# d3.linkRadial() · [Source](https://github.com/d3/d3-shape/blob/main/src/link.js)
+
+Returns a new [link generator](#_link) with radial tangents. For example, to visualize [links](https://github.com/d3/d3-hierarchy/blob/master/README.md#node_links) in a [tree diagram](https://github.com/d3/d3-hierarchy/blob/master/README.md#tree) rooted in the center of the display, you might say:
+
+```js
+const link = d3.linkRadial()
+ .angle(d => d.x)
+ .radius(d => d.y);
+```
+
+# linkRadial.angle([angle]) · [Source](https://github.com/d3/d3-shape/blob/main/src/link.js)
+
+Equivalent to [*link*.x](#link_x), except the accessor returns the angle in radians, with 0 at -*y* (12 o’clock).
+
+# linkRadial.radius([radius]) · [Source](https://github.com/d3/d3-shape/blob/main/src/link.js)
+
+Equivalent to [*link*.y](#link_y), except the accessor returns the radius: the distance from the origin ⟨0,0⟩.
+
+### Symbols
+
+





+
+Symbols provide a categorical shape encoding as is commonly used in scatterplots. Symbols are always centered at ⟨0,0⟩; use a transform (see: [SVG](http://www.w3.org/TR/SVG/coords.html#TransformAttribute), [Canvas](http://www.w3.org/TR/2dcontext/#transformations)) to move the symbol to a different position.
+
+# d3.symbol([type][, size]) · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol.js), [Examples](https://observablehq.com/@d3/fitted-symbols)
+
+Constructs a new symbol generator of the specified [type](#symbol_type) and [size](#symbol_size). If not specified, *type* defaults to a circle, and *size* defaults to 64.
+
+# symbol(arguments…) · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol.js)
+
+Generates a symbol for the given *arguments*. The *arguments* are arbitrary; they are simply propagated to the symbol generator’s accessor functions along with the `this` object. For example, with the default settings, no arguments are needed to produce a circle with area 64 square pixels. If the symbol generator has a [context](#symbol_context), then the symbol is rendered to this context as a sequence of [path method](http://www.w3.org/TR/2dcontext/#canvaspathmethods) calls and this function returns void. Otherwise, a [path data](http://www.w3.org/TR/SVG/paths.html#PathData) string is returned.
+
+# symbol.type([type]) · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol.js)
+
+If *type* is specified, sets the symbol type to the specified function or symbol type and returns this symbol generator. If *type* is a function, the symbol generator’s arguments and *this* are passed through. (See [*selection*.attr](https://github.com/d3/d3-selection/blob/master/README.md#selection_attr) if you are using d3-selection.) If *type* is not specified, returns the current symbol type accessor, which defaults to:
+
+```js
+function type() {
+ return circle;
+}
+```
+
+See [symbolsFill](#symbolsFill) and [symbolsStroke](#symbolsStroke) for built-in symbol types. To implement a custom symbol type, pass an object that implements [*symbolType*.draw](#symbolType_draw).
+
+# symbol.size([size]) · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol.js)
+
+If *size* is specified, sets the size to the specified function or number and returns this symbol generator. If *size* is a function, the symbol generator’s arguments and *this* are passed through. (See [*selection*.attr](https://github.com/d3/d3-selection/blob/master/README.md#selection_attr) if you are using d3-selection.) If *size* is not specified, returns the current size accessor, which defaults to:
+
+```js
+function size() {
+ return 64;
+}
+```
+
+Specifying the size as a function is useful for constructing a scatterplot with a size encoding. If you wish to scale the symbol to fit a given bounding box, rather than by area, try [SVG’s getBBox](https://observablehq.com/d/1fac2626b9e1b65f).
+
+# symbol.context([context]) · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol.js)
+
+If *context* is specified, sets the context and returns this symbol generator. If *context* is not specified, returns the current context, which defaults to null. If the context is not null, then the [generated symbol](#_symbol) is rendered to this context as a sequence of [path method](http://www.w3.org/TR/2dcontext/#canvaspathmethods) calls. Otherwise, a [path data](http://www.w3.org/TR/SVG/paths.html#PathData) string representing the generated symbol is returned.
+
+# d3.symbolsFill · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol.js)
+
+An array containing a set of symbol types designed for filling: [circle](#symbolCircle), [cross](#symbolCross), [diamond](#symbolDiamond), [square](#symbolSquare), [star](#symbolStar), [triangle](#symbolTriangle), and [wye](#symbolWye). Useful for constructing the range of an [ordinal scale](https://github.com/d3/d3-scale#ordinal-scales) should you wish to use a shape encoding for categorical data.
+
+# d3.symbolsStroke · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol.js)
+
+An array containing a set of symbol types designed for stroking: [circle](#symbolCircle), [plus](#symbolPlus), [x](#symbolX), [triangle2](#symbolTriangle2), [asterisk](#symbolAsterisk), [square2](#symbolSquare2), and [diamond2](#symbolDiamond2). Useful for constructing the range of an [ordinal scale](https://github.com/d3/d3-scale#ordinal-scales) should you wish to use a shape encoding for categorical data.
+
+# d3.symbolAsterisk · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol/asterisk.js)
+
+The asterisk symbol type; intended for stroking.
+
+# d3.symbolCircle · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol/circle.js)
+
+The circle symbol type; intended for either filling or stroking.
+
+# d3.symbolCross · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol/cross.js)
+
+The Greek cross symbol type, with arms of equal length; intended for filling.
+
+# d3.symbolDiamond · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol/diamond.js)
+
+The rhombus symbol type; intended for filling.
+
+# d3.symbolDiamond2 · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol/diamond.js)
+
+The rotated square symbol type; intended for stroking.
+
+# d3.symbolPlus · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol/plus.js)
+
+The plus symbol type; intended for stroking.
+
+# d3.symbolSquare · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol/square.js)
+
+The square symbol type; intended for filling.
+
+# d3.symbolSquare2 · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol/square2.js)
+
+The square2 symbol type; intended for stroking.
+
+# d3.symbolStar · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol/star.js)
+
+The pentagonal star (pentagram) symbol type; intended for filling.
+
+# d3.symbolTriangle · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol/triangle.js)
+
+The up-pointing triangle symbol type; intended for filling.
+
+# d3.symbolTriangle2 · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol/triangle2.js)
+
+The up-pointing triangle symbol type; intended for stroking.
+
+# d3.symbolWye · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol/wye.js)
+
+The Y-shape symbol type; intended for filling.
+
+# d3.symbolX · [Source](https://github.com/d3/d3-shape/blob/main/src/symbol/x.js)
+
+The X-shape symbol type; intended for stroking.
+
+# d3.pointRadial(angle, radius) · [Source](https://github.com/d3/d3-shape/blob/main/src/pointRadial.js), [Examples](https://observablehq.com/@d3/radial-area-chart)
+
+Returns the point [x, y] for the given *angle* in radians, with 0 at -*y* (12 o’clock) and positive angles proceeding clockwise, and the given *radius*.
+
+### Custom Symbol Types
+
+Symbol types are typically not used directly, instead being passed to [*symbol*.type](#symbol_type). However, you can define your own symbol type implementation should none of the built-in types satisfy your needs using the following interface. You can also use this low-level interface with a built-in symbol type as an alternative to the symbol generator.
+
+# symbolType.draw(context, size)
+
+Renders this symbol type to the specified *context* with the specified *size* in square pixels. The *context* implements the [CanvasPathMethods](http://www.w3.org/TR/2dcontext/#canvaspathmethods) interface. (Note that this is a subset of the CanvasRenderingContext2D interface!)
+
+### Stacks
+
+[
](https://observablehq.com/@d3/stacked-bar-chart)[
](https://observablehq.com/@mbostock/streamgraph-transitions)
+
+Some shape types can be stacked, placing one shape adjacent to another. For example, a bar chart of monthly sales might be broken down into a multi-series bar chart by product category, stacking bars vertically. This is equivalent to subdividing a bar chart by an ordinal dimension (such as product category) and applying a color encoding.
+
+Stacked charts can show overall value and per-category value simultaneously; however, it is typically harder to compare across categories, as only the bottom layer of the stack is aligned. So, chose the [stack order](#stack_order) carefully, and consider a [streamgraph](#stackOffsetWiggle). (See also [grouped charts](https://observablehq.com/@d3/grouped-bar-chart).)
+
+Like the [pie generator](#pies), the stack generator does not produce a shape directly. Instead it computes positions which you can then pass to an [area generator](#areas) or use directly, say to position bars.
+
+# d3.stack() · [Source](https://github.com/d3/d3-shape/blob/main/src/stack.js)
+
+Constructs a new stack generator with the default settings.
+
+# stack(data[, arguments…]) · [Source](https://github.com/d3/d3-shape/blob/main/src/stack.js)
+
+Generates a stack for the given array of *data*, returning an array representing each series. Any additional *arguments* are arbitrary; they are simply propagated to accessors along with the `this` object.
+
+The series are determined by the [keys accessor](#stack_keys); each series *i* in the returned array corresponds to the *i*th key. Each series is an array of points, where each point *j* corresponds to the *j*th element in the input *data*. Lastly, each point is represented as an array [*y0*, *y1*] where *y0* is the lower value (baseline) and *y1* is the upper value (topline); the difference between *y0* and *y1* corresponds to the computed [value](#stack_value) for this point. The key for each series is available as *series*.key, and the [index](#stack_order) as *series*.index. The input data element for each point is available as *point*.data.
+
+For example, consider the following table representing monthly sales of fruits:
+
+Month | Apples | Bananas | Cherries | Dates
+--------|--------|---------|----------|-------
+ 1/2015 | 3840 | 1920 | 960 | 400
+ 2/2015 | 1600 | 1440 | 960 | 400
+ 3/2015 | 640 | 960 | 640 | 400
+ 4/2015 | 320 | 480 | 640 | 400
+
+This might be represented in JavaScript as an array of objects:
+
+```js
+const data = [
+ {month: new Date(2015, 0, 1), apples: 3840, bananas: 1920, cherries: 960, dates: 400},
+ {month: new Date(2015, 1, 1), apples: 1600, bananas: 1440, cherries: 960, dates: 400},
+ {month: new Date(2015, 2, 1), apples: 640, bananas: 960, cherries: 640, dates: 400},
+ {month: new Date(2015, 3, 1), apples: 320, bananas: 480, cherries: 640, dates: 400}
+];
+```
+
+To produce a stack for this data:
+
+```js
+const stack = d3.stack()
+ .keys(["apples", "bananas", "cherries", "dates"])
+ .order(d3.stackOrderNone)
+ .offset(d3.stackOffsetNone);
+
+const series = stack(data);
+```
+
+The resulting array has one element per *series*. Each series has one point per month, and each point has a lower and upper value defining the baseline and topline:
+
+```js
+[
+ [[ 0, 3840], [ 0, 1600], [ 0, 640], [ 0, 320]], // apples
+ [[3840, 5760], [1600, 3040], [ 640, 1600], [ 320, 800]], // bananas
+ [[5760, 6720], [3040, 4000], [1600, 2240], [ 800, 1440]], // cherries
+ [[6720, 7120], [4000, 4400], [2240, 2640], [1440, 1840]], // dates
+]
+```
+
+Each series in then typically passed to an [area generator](#areas) to render an area chart, or used to construct rectangles for a bar chart.
+
+# stack.keys([keys]) · [Source](https://github.com/d3/d3-shape/blob/main/src/stack.js)
+
+If *keys* is specified, sets the keys accessor to the specified function or array and returns this stack generator. If *keys* is not specified, returns the current keys accessor, which defaults to the empty array. A series (layer) is [generated](#_stack) for each key. Keys are typically strings, but they may be arbitrary values. The series’ key is passed to the [value accessor](#stack_value), along with each data point, to compute the point’s value.
+
+# stack.value([value]) · [Source](https://github.com/d3/d3-shape/blob/main/src/stack.js)
+
+If *value* is specified, sets the value accessor to the specified function or number and returns this stack generator. If *value* is not specified, returns the current value accessor, which defaults to:
+
+```js
+function value(d, key) {
+ return d[key];
+}
+```
+
+Thus, by default the stack generator assumes that the input data is an array of objects, with each object exposing named properties with numeric values; see [*stack*](#_stack) for an example.
+
+# stack.order([order]) · [Source](https://github.com/d3/d3-shape/blob/main/src/stack.js)
+
+If *order* is specified, sets the order accessor to the specified function or array and returns this stack generator. If *order* is not specified, returns the current order accessor, which defaults to [stackOrderNone](#stackOrderNone); this uses the order given by the [key accessor](#stack_key). See [stack orders](#stack-orders) for the built-in orders.
+
+If *order* is a function, it is passed the generated series array and must return an array of numeric indexes representing the stack order. For example, the default order is defined as:
+
+```js
+function orderNone(series) {
+ let n = series.length;
+ const o = new Array(n);
+ while (--n >= 0) o[n] = n;
+ return o;
+}
+```
+
+The stack order is computed prior to the [offset](#stack_offset); thus, the lower value for all points is zero at the time the order is computed. The index attribute for each series is also not set until after the order is computed.
+
+# stack.offset([offset]) · [Source](https://github.com/d3/d3-shape/blob/main/src/stack.js)
+
+If *offset* is specified, sets the offset accessor to the specified function and returns this stack generator. If *offset* is not specified, returns the current offset acccesor, which defaults to [stackOffsetNone](#stackOffsetNone); this uses a zero baseline. See [stack offsets](#stack-offsets) for the built-in offsets.
+
+The offset function is passed the generated series array and the order index array; it is then responsible for updating the lower and upper values in the series array. For example, the default offset is defined as:
+
+```js
+function offsetNone(series, order) {
+ if (!((n = series.length) > 1)) return;
+ for (let i = 1, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {
+ s0 = s1, s1 = series[order[i]];
+ for (let j = 0; j < m; ++j) {
+ s1[j][1] += s1[j][0] = s0[j][1];
+ }
+ }
+}
+```
+
+### Stack Orders
+
+Stack orders are typically not used directly, but are instead passed to [*stack*.order](#stack_order).
+
+# d3.stackOrderAppearance(series) · [Source](https://github.com/d3/d3-shape/blob/main/src/order/appearance.js)
+
+Returns a series order such that the earliest series (according to the maximum value) is at the bottom.
+
+# d3.stackOrderAscending(series) · [Source](https://github.com/d3/d3-shape/blob/main/src/order/ascending.js)
+
+Returns a series order such that the smallest series (according to the sum of values) is at the bottom.
+
+# d3.stackOrderDescending(series) · [Source](https://github.com/d3/d3-shape/blob/main/src/order/descending.js)
+
+Returns a series order such that the largest series (according to the sum of values) is at the bottom.
+
+# d3.stackOrderInsideOut(series) · [Source](https://github.com/d3/d3-shape/blob/main/src/order/insideOut.js)
+
+Returns a series order such that the earliest series (according to the maximum value) are on the inside and the later series are on the outside. This order is recommended for streamgraphs in conjunction with the [wiggle offset](#stackOffsetWiggle). See [Stacked Graphs—Geometry & Aesthetics](http://leebyron.com/streamgraph/) by Byron & Wattenberg for more information.
+
+# d3.stackOrderNone(series) · [Source](https://github.com/d3/d3-shape/blob/main/src/order/none.js)
+
+Returns the given series order [0, 1, … *n* - 1] where *n* is the number of elements in *series*. Thus, the stack order is given by the [key accessor](#stack_keys).
+
+# d3.stackOrderReverse(series) · [Source](https://github.com/d3/d3-shape/blob/main/src/order/reverse.js)
+
+Returns the reverse of the given series order [*n* - 1, *n* - 2, … 0] where *n* is the number of elements in *series*. Thus, the stack order is given by the reverse of the [key accessor](#stack_keys).
+
+### Stack Offsets
+
+Stack offsets are typically not used directly, but are instead passed to [*stack*.offset](#stack_offset).
+
+# d3.stackOffsetExpand(series, order) · [Source](https://github.com/d3/d3-shape/blob/main/src/offset/expand.js)
+
+Applies a zero baseline and normalizes the values for each point such that the topline is always one.
+
+# d3.stackOffsetDiverging(series, order) · [Source](https://github.com/d3/d3-shape/blob/main/src/offset/diverging.js)
+
+Positive values are stacked above zero, negative values are [stacked below zero](https://bl.ocks.org/mbostock/b5935342c6d21928111928401e2c8608), and zero values are stacked at zero.
+
+# d3.stackOffsetNone(series, order) · [Source](https://github.com/d3/d3-shape/blob/main/src/offset/none.js)
+
+Applies a zero baseline.
+
+# d3.stackOffsetSilhouette(series, order) · [Source](https://github.com/d3/d3-shape/blob/main/src/offset/silhouette.js)
+
+Shifts the baseline down such that the center of the streamgraph is always at zero.
+
+# d3.stackOffsetWiggle(series, order) · [Source](https://github.com/d3/d3-shape/blob/main/src/offset/wiggle.js)
+
+Shifts the baseline so as to minimize the weighted wiggle of layers. This offset is recommended for streamgraphs in conjunction with the [inside-out order](#stackOrderInsideOut). See [Stacked Graphs—Geometry & Aesthetics](http://leebyron.com/streamgraph/) by Bryon & Wattenberg for more information.
diff --git a/node_modules/d3-shape/dist/d3-shape.js b/node_modules/d3-shape/dist/d3-shape.js
new file mode 100644
index 00000000..b82ec7fe
--- /dev/null
+++ b/node_modules/d3-shape/dist/d3-shape.js
@@ -0,0 +1,2112 @@
+// https://d3js.org/d3-shape/ v3.1.0 Copyright 2010-2021 Mike Bostock
+(function (global, factory) {
+typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-path')) :
+typeof define === 'function' && define.amd ? define(['exports', 'd3-path'], factory) :
+(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}, global.d3));
+})(this, (function (exports, d3Path) { 'use strict';
+
+function constant(x) {
+ return function constant() {
+ return x;
+ };
+}
+
+const abs = Math.abs;
+const atan2 = Math.atan2;
+const cos = Math.cos;
+const max = Math.max;
+const min = Math.min;
+const sin = Math.sin;
+const sqrt = Math.sqrt;
+
+const epsilon = 1e-12;
+const pi = Math.PI;
+const halfPi = pi / 2;
+const tau = 2 * pi;
+
+function acos(x) {
+ return x > 1 ? 0 : x < -1 ? pi : Math.acos(x);
+}
+
+function asin(x) {
+ return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x);
+}
+
+function arcInnerRadius(d) {
+ return d.innerRadius;
+}
+
+function arcOuterRadius(d) {
+ return d.outerRadius;
+}
+
+function arcStartAngle(d) {
+ return d.startAngle;
+}
+
+function arcEndAngle(d) {
+ return d.endAngle;
+}
+
+function arcPadAngle(d) {
+ return d && d.padAngle; // Note: optional!
+}
+
+function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
+ var x10 = x1 - x0, y10 = y1 - y0,
+ x32 = x3 - x2, y32 = y3 - y2,
+ t = y32 * x10 - x32 * y10;
+ if (t * t < epsilon) return;
+ t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / t;
+ return [x0 + t * x10, y0 + t * y10];
+}
+
+// Compute perpendicular offset line of length rc.
+// http://mathworld.wolfram.com/Circle-LineIntersection.html
+function cornerTangents(x0, y0, x1, y1, r1, rc, cw) {
+ var x01 = x0 - x1,
+ y01 = y0 - y1,
+ lo = (cw ? rc : -rc) / sqrt(x01 * x01 + y01 * y01),
+ ox = lo * y01,
+ oy = -lo * x01,
+ x11 = x0 + ox,
+ y11 = y0 + oy,
+ x10 = x1 + ox,
+ y10 = y1 + oy,
+ x00 = (x11 + x10) / 2,
+ y00 = (y11 + y10) / 2,
+ dx = x10 - x11,
+ dy = y10 - y11,
+ d2 = dx * dx + dy * dy,
+ r = r1 - rc,
+ D = x11 * y10 - x10 * y11,
+ d = (dy < 0 ? -1 : 1) * sqrt(max(0, r * r * d2 - D * D)),
+ cx0 = (D * dy - dx * d) / d2,
+ cy0 = (-D * dx - dy * d) / d2,
+ cx1 = (D * dy + dx * d) / d2,
+ cy1 = (-D * dx + dy * d) / d2,
+ dx0 = cx0 - x00,
+ dy0 = cy0 - y00,
+ dx1 = cx1 - x00,
+ dy1 = cy1 - y00;
+
+ // Pick the closer of the two intersection points.
+ // TODO Is there a faster way to determine which intersection to use?
+ if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;
+
+ return {
+ cx: cx0,
+ cy: cy0,
+ x01: -ox,
+ y01: -oy,
+ x11: cx0 * (r1 / r - 1),
+ y11: cy0 * (r1 / r - 1)
+ };
+}
+
+function arc() {
+ var innerRadius = arcInnerRadius,
+ outerRadius = arcOuterRadius,
+ cornerRadius = constant(0),
+ padRadius = null,
+ startAngle = arcStartAngle,
+ endAngle = arcEndAngle,
+ padAngle = arcPadAngle,
+ context = null;
+
+ function arc() {
+ var buffer,
+ r,
+ r0 = +innerRadius.apply(this, arguments),
+ r1 = +outerRadius.apply(this, arguments),
+ a0 = startAngle.apply(this, arguments) - halfPi,
+ a1 = endAngle.apply(this, arguments) - halfPi,
+ da = abs(a1 - a0),
+ cw = a1 > a0;
+
+ if (!context) context = buffer = d3Path.path();
+
+ // Ensure that the outer radius is always larger than the inner radius.
+ if (r1 < r0) r = r1, r1 = r0, r0 = r;
+
+ // Is it a point?
+ if (!(r1 > epsilon)) context.moveTo(0, 0);
+
+ // Or is it a circle or annulus?
+ else if (da > tau - epsilon) {
+ context.moveTo(r1 * cos(a0), r1 * sin(a0));
+ context.arc(0, 0, r1, a0, a1, !cw);
+ if (r0 > epsilon) {
+ context.moveTo(r0 * cos(a1), r0 * sin(a1));
+ context.arc(0, 0, r0, a1, a0, cw);
+ }
+ }
+
+ // Or is it a circular or annular sector?
+ else {
+ var a01 = a0,
+ a11 = a1,
+ a00 = a0,
+ a10 = a1,
+ da0 = da,
+ da1 = da,
+ ap = padAngle.apply(this, arguments) / 2,
+ rp = (ap > epsilon) && (padRadius ? +padRadius.apply(this, arguments) : sqrt(r0 * r0 + r1 * r1)),
+ rc = min(abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),
+ rc0 = rc,
+ rc1 = rc,
+ t0,
+ t1;
+
+ // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.
+ if (rp > epsilon) {
+ var p0 = asin(rp / r0 * sin(ap)),
+ p1 = asin(rp / r1 * sin(ap));
+ if ((da0 -= p0 * 2) > epsilon) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;
+ else da0 = 0, a00 = a10 = (a0 + a1) / 2;
+ if ((da1 -= p1 * 2) > epsilon) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;
+ else da1 = 0, a01 = a11 = (a0 + a1) / 2;
+ }
+
+ var x01 = r1 * cos(a01),
+ y01 = r1 * sin(a01),
+ x10 = r0 * cos(a10),
+ y10 = r0 * sin(a10);
+
+ // Apply rounded corners?
+ if (rc > epsilon) {
+ var x11 = r1 * cos(a11),
+ y11 = r1 * sin(a11),
+ x00 = r0 * cos(a00),
+ y00 = r0 * sin(a00),
+ oc;
+
+ // Restrict the corner radius according to the sector angle.
+ if (da < pi && (oc = intersect(x01, y01, x00, y00, x11, y11, x10, y10))) {
+ var ax = x01 - oc[0],
+ ay = y01 - oc[1],
+ bx = x11 - oc[0],
+ by = y11 - oc[1],
+ kc = 1 / sin(acos((ax * bx + ay * by) / (sqrt(ax * ax + ay * ay) * sqrt(bx * bx + by * by))) / 2),
+ lc = sqrt(oc[0] * oc[0] + oc[1] * oc[1]);
+ rc0 = min(rc, (r0 - lc) / (kc - 1));
+ rc1 = min(rc, (r1 - lc) / (kc + 1));
+ }
+ }
+
+ // Is the sector collapsed to a line?
+ if (!(da1 > epsilon)) context.moveTo(x01, y01);
+
+ // Does the sector’s outer ring have rounded corners?
+ else if (rc1 > epsilon) {
+ t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);
+ t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);
+
+ context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);
+
+ // Have the corners merged?
+ if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);
+
+ // Otherwise, draw the two corners and the ring.
+ else {
+ context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);
+ context.arc(0, 0, r1, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw);
+ context.arc(t1.cx, t1.cy, rc1, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);
+ }
+ }
+
+ // Or is the outer ring just a circular arc?
+ else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);
+
+ // Is there no inner ring, and it’s a circular sector?
+ // Or perhaps it’s an annular sector collapsed due to padding?
+ if (!(r0 > epsilon) || !(da0 > epsilon)) context.lineTo(x10, y10);
+
+ // Does the sector’s inner ring (or point) have rounded corners?
+ else if (rc0 > epsilon) {
+ t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);
+ t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);
+
+ context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);
+
+ // Have the corners merged?
+ if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);
+
+ // Otherwise, draw the two corners and the ring.
+ else {
+ context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);
+ context.arc(0, 0, r0, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw);
+ context.arc(t1.cx, t1.cy, rc0, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);
+ }
+ }
+
+ // Or is the inner ring just a circular arc?
+ else context.arc(0, 0, r0, a10, a00, cw);
+ }
+
+ context.closePath();
+
+ if (buffer) return context = null, buffer + "" || null;
+ }
+
+ arc.centroid = function() {
+ var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,
+ a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi / 2;
+ return [cos(a) * r, sin(a) * r];
+ };
+
+ arc.innerRadius = function(_) {
+ return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant(+_), arc) : innerRadius;
+ };
+
+ arc.outerRadius = function(_) {
+ return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant(+_), arc) : outerRadius;
+ };
+
+ arc.cornerRadius = function(_) {
+ return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant(+_), arc) : cornerRadius;
+ };
+
+ arc.padRadius = function(_) {
+ return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant(+_), arc) : padRadius;
+ };
+
+ arc.startAngle = function(_) {
+ return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant(+_), arc) : startAngle;
+ };
+
+ arc.endAngle = function(_) {
+ return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant(+_), arc) : endAngle;
+ };
+
+ arc.padAngle = function(_) {
+ return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant(+_), arc) : padAngle;
+ };
+
+ arc.context = function(_) {
+ return arguments.length ? ((context = _ == null ? null : _), arc) : context;
+ };
+
+ return arc;
+}
+
+var slice = Array.prototype.slice;
+
+function array(x) {
+ return typeof x === "object" && "length" in x
+ ? x // Array, TypedArray, NodeList, array-like
+ : Array.from(x); // Map, Set, iterable, string, or anything else
+}
+
+function Linear(context) {
+ this._context = context;
+}
+
+Linear.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._point = 0;
+ },
+ lineEnd: function() {
+ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
+ this._line = 1 - this._line;
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+ switch (this._point) {
+ case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
+ case 1: this._point = 2; // falls through
+ default: this._context.lineTo(x, y); break;
+ }
+ }
+};
+
+function curveLinear(context) {
+ return new Linear(context);
+}
+
+function x$1(p) {
+ return p[0];
+}
+
+function y(p) {
+ return p[1];
+}
+
+function line(x, y$1) {
+ var defined = constant(true),
+ context = null,
+ curve = curveLinear,
+ output = null;
+
+ x = typeof x === "function" ? x : (x === undefined) ? x$1 : constant(x);
+ y$1 = typeof y$1 === "function" ? y$1 : (y$1 === undefined) ? y : constant(y$1);
+
+ function line(data) {
+ var i,
+ n = (data = array(data)).length,
+ d,
+ defined0 = false,
+ buffer;
+
+ if (context == null) output = curve(buffer = d3Path.path());
+
+ for (i = 0; i <= n; ++i) {
+ if (!(i < n && defined(d = data[i], i, data)) === defined0) {
+ if (defined0 = !defined0) output.lineStart();
+ else output.lineEnd();
+ }
+ if (defined0) output.point(+x(d, i, data), +y$1(d, i, data));
+ }
+
+ if (buffer) return output = null, buffer + "" || null;
+ }
+
+ line.x = function(_) {
+ return arguments.length ? (x = typeof _ === "function" ? _ : constant(+_), line) : x;
+ };
+
+ line.y = function(_) {
+ return arguments.length ? (y$1 = typeof _ === "function" ? _ : constant(+_), line) : y$1;
+ };
+
+ line.defined = function(_) {
+ return arguments.length ? (defined = typeof _ === "function" ? _ : constant(!!_), line) : defined;
+ };
+
+ line.curve = function(_) {
+ return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;
+ };
+
+ line.context = function(_) {
+ return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;
+ };
+
+ return line;
+}
+
+function area(x0, y0, y1) {
+ var x1 = null,
+ defined = constant(true),
+ context = null,
+ curve = curveLinear,
+ output = null;
+
+ x0 = typeof x0 === "function" ? x0 : (x0 === undefined) ? x$1 : constant(+x0);
+ y0 = typeof y0 === "function" ? y0 : (y0 === undefined) ? constant(0) : constant(+y0);
+ y1 = typeof y1 === "function" ? y1 : (y1 === undefined) ? y : constant(+y1);
+
+ function area(data) {
+ var i,
+ j,
+ k,
+ n = (data = array(data)).length,
+ d,
+ defined0 = false,
+ buffer,
+ x0z = new Array(n),
+ y0z = new Array(n);
+
+ if (context == null) output = curve(buffer = d3Path.path());
+
+ for (i = 0; i <= n; ++i) {
+ if (!(i < n && defined(d = data[i], i, data)) === defined0) {
+ if (defined0 = !defined0) {
+ j = i;
+ output.areaStart();
+ output.lineStart();
+ } else {
+ output.lineEnd();
+ output.lineStart();
+ for (k = i - 1; k >= j; --k) {
+ output.point(x0z[k], y0z[k]);
+ }
+ output.lineEnd();
+ output.areaEnd();
+ }
+ }
+ if (defined0) {
+ x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);
+ output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);
+ }
+ }
+
+ if (buffer) return output = null, buffer + "" || null;
+ }
+
+ function arealine() {
+ return line().defined(defined).curve(curve).context(context);
+ }
+
+ area.x = function(_) {
+ return arguments.length ? (x0 = typeof _ === "function" ? _ : constant(+_), x1 = null, area) : x0;
+ };
+
+ area.x0 = function(_) {
+ return arguments.length ? (x0 = typeof _ === "function" ? _ : constant(+_), area) : x0;
+ };
+
+ area.x1 = function(_) {
+ return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant(+_), area) : x1;
+ };
+
+ area.y = function(_) {
+ return arguments.length ? (y0 = typeof _ === "function" ? _ : constant(+_), y1 = null, area) : y0;
+ };
+
+ area.y0 = function(_) {
+ return arguments.length ? (y0 = typeof _ === "function" ? _ : constant(+_), area) : y0;
+ };
+
+ area.y1 = function(_) {
+ return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant(+_), area) : y1;
+ };
+
+ area.lineX0 =
+ area.lineY0 = function() {
+ return arealine().x(x0).y(y0);
+ };
+
+ area.lineY1 = function() {
+ return arealine().x(x0).y(y1);
+ };
+
+ area.lineX1 = function() {
+ return arealine().x(x1).y(y0);
+ };
+
+ area.defined = function(_) {
+ return arguments.length ? (defined = typeof _ === "function" ? _ : constant(!!_), area) : defined;
+ };
+
+ area.curve = function(_) {
+ return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;
+ };
+
+ area.context = function(_) {
+ return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;
+ };
+
+ return area;
+}
+
+function descending$1(a, b) {
+ return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
+}
+
+function identity(d) {
+ return d;
+}
+
+function pie() {
+ var value = identity,
+ sortValues = descending$1,
+ sort = null,
+ startAngle = constant(0),
+ endAngle = constant(tau),
+ padAngle = constant(0);
+
+ function pie(data) {
+ var i,
+ n = (data = array(data)).length,
+ j,
+ k,
+ sum = 0,
+ index = new Array(n),
+ arcs = new Array(n),
+ a0 = +startAngle.apply(this, arguments),
+ da = Math.min(tau, Math.max(-tau, endAngle.apply(this, arguments) - a0)),
+ a1,
+ p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),
+ pa = p * (da < 0 ? -1 : 1),
+ v;
+
+ for (i = 0; i < n; ++i) {
+ if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) {
+ sum += v;
+ }
+ }
+
+ // Optionally sort the arcs by previously-computed values or by data.
+ if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); });
+ else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); });
+
+ // Compute the arcs! They are stored in the original data's order.
+ for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) {
+ j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = {
+ data: data[j],
+ index: i,
+ value: v,
+ startAngle: a0,
+ endAngle: a1,
+ padAngle: p
+ };
+ }
+
+ return arcs;
+ }
+
+ pie.value = function(_) {
+ return arguments.length ? (value = typeof _ === "function" ? _ : constant(+_), pie) : value;
+ };
+
+ pie.sortValues = function(_) {
+ return arguments.length ? (sortValues = _, sort = null, pie) : sortValues;
+ };
+
+ pie.sort = function(_) {
+ return arguments.length ? (sort = _, sortValues = null, pie) : sort;
+ };
+
+ pie.startAngle = function(_) {
+ return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant(+_), pie) : startAngle;
+ };
+
+ pie.endAngle = function(_) {
+ return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant(+_), pie) : endAngle;
+ };
+
+ pie.padAngle = function(_) {
+ return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant(+_), pie) : padAngle;
+ };
+
+ return pie;
+}
+
+var curveRadialLinear = curveRadial(curveLinear);
+
+function Radial(curve) {
+ this._curve = curve;
+}
+
+Radial.prototype = {
+ areaStart: function() {
+ this._curve.areaStart();
+ },
+ areaEnd: function() {
+ this._curve.areaEnd();
+ },
+ lineStart: function() {
+ this._curve.lineStart();
+ },
+ lineEnd: function() {
+ this._curve.lineEnd();
+ },
+ point: function(a, r) {
+ this._curve.point(r * Math.sin(a), r * -Math.cos(a));
+ }
+};
+
+function curveRadial(curve) {
+
+ function radial(context) {
+ return new Radial(curve(context));
+ }
+
+ radial._curve = curve;
+
+ return radial;
+}
+
+function lineRadial(l) {
+ var c = l.curve;
+
+ l.angle = l.x, delete l.x;
+ l.radius = l.y, delete l.y;
+
+ l.curve = function(_) {
+ return arguments.length ? c(curveRadial(_)) : c()._curve;
+ };
+
+ return l;
+}
+
+function lineRadial$1() {
+ return lineRadial(line().curve(curveRadialLinear));
+}
+
+function areaRadial() {
+ var a = area().curve(curveRadialLinear),
+ c = a.curve,
+ x0 = a.lineX0,
+ x1 = a.lineX1,
+ y0 = a.lineY0,
+ y1 = a.lineY1;
+
+ a.angle = a.x, delete a.x;
+ a.startAngle = a.x0, delete a.x0;
+ a.endAngle = a.x1, delete a.x1;
+ a.radius = a.y, delete a.y;
+ a.innerRadius = a.y0, delete a.y0;
+ a.outerRadius = a.y1, delete a.y1;
+ a.lineStartAngle = function() { return lineRadial(x0()); }, delete a.lineX0;
+ a.lineEndAngle = function() { return lineRadial(x1()); }, delete a.lineX1;
+ a.lineInnerRadius = function() { return lineRadial(y0()); }, delete a.lineY0;
+ a.lineOuterRadius = function() { return lineRadial(y1()); }, delete a.lineY1;
+
+ a.curve = function(_) {
+ return arguments.length ? c(curveRadial(_)) : c()._curve;
+ };
+
+ return a;
+}
+
+function pointRadial(x, y) {
+ return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)];
+}
+
+class Bump {
+ constructor(context, x) {
+ this._context = context;
+ this._x = x;
+ }
+ areaStart() {
+ this._line = 0;
+ }
+ areaEnd() {
+ this._line = NaN;
+ }
+ lineStart() {
+ this._point = 0;
+ }
+ lineEnd() {
+ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
+ this._line = 1 - this._line;
+ }
+ point(x, y) {
+ x = +x, y = +y;
+ switch (this._point) {
+ case 0: {
+ this._point = 1;
+ if (this._line) this._context.lineTo(x, y);
+ else this._context.moveTo(x, y);
+ break;
+ }
+ case 1: this._point = 2; // falls through
+ default: {
+ if (this._x) this._context.bezierCurveTo(this._x0 = (this._x0 + x) / 2, this._y0, this._x0, y, x, y);
+ else this._context.bezierCurveTo(this._x0, this._y0 = (this._y0 + y) / 2, x, this._y0, x, y);
+ break;
+ }
+ }
+ this._x0 = x, this._y0 = y;
+ }
+}
+
+class BumpRadial {
+ constructor(context) {
+ this._context = context;
+ }
+ lineStart() {
+ this._point = 0;
+ }
+ lineEnd() {}
+ point(x, y) {
+ x = +x, y = +y;
+ if (this._point++ === 0) {
+ this._x0 = x, this._y0 = y;
+ } else {
+ const p0 = pointRadial(this._x0, this._y0);
+ const p1 = pointRadial(this._x0, this._y0 = (this._y0 + y) / 2);
+ const p2 = pointRadial(x, this._y0);
+ const p3 = pointRadial(x, y);
+ this._context.moveTo(...p0);
+ this._context.bezierCurveTo(...p1, ...p2, ...p3);
+ }
+ }
+}
+
+function bumpX(context) {
+ return new Bump(context, true);
+}
+
+function bumpY(context) {
+ return new Bump(context, false);
+}
+
+function bumpRadial(context) {
+ return new BumpRadial(context);
+}
+
+function linkSource(d) {
+ return d.source;
+}
+
+function linkTarget(d) {
+ return d.target;
+}
+
+function link(curve) {
+ let source = linkSource;
+ let target = linkTarget;
+ let x = x$1;
+ let y$1 = y;
+ let context = null;
+ let output = null;
+
+ function link() {
+ let buffer;
+ const argv = slice.call(arguments);
+ const s = source.apply(this, argv);
+ const t = target.apply(this, argv);
+ if (context == null) output = curve(buffer = d3Path.path());
+ output.lineStart();
+ argv[0] = s, output.point(+x.apply(this, argv), +y$1.apply(this, argv));
+ argv[0] = t, output.point(+x.apply(this, argv), +y$1.apply(this, argv));
+ output.lineEnd();
+ if (buffer) return output = null, buffer + "" || null;
+ }
+
+ link.source = function(_) {
+ return arguments.length ? (source = _, link) : source;
+ };
+
+ link.target = function(_) {
+ return arguments.length ? (target = _, link) : target;
+ };
+
+ link.x = function(_) {
+ return arguments.length ? (x = typeof _ === "function" ? _ : constant(+_), link) : x;
+ };
+
+ link.y = function(_) {
+ return arguments.length ? (y$1 = typeof _ === "function" ? _ : constant(+_), link) : y$1;
+ };
+
+ link.context = function(_) {
+ return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), link) : context;
+ };
+
+ return link;
+}
+
+function linkHorizontal() {
+ return link(bumpX);
+}
+
+function linkVertical() {
+ return link(bumpY);
+}
+
+function linkRadial() {
+ const l = link(bumpRadial);
+ l.angle = l.x, delete l.x;
+ l.radius = l.y, delete l.y;
+ return l;
+}
+
+const sqrt3$2 = sqrt(3);
+
+var asterisk = {
+ draw(context, size) {
+ const r = sqrt(size + min(size / 28, 0.75)) * 0.59436;
+ const t = r / 2;
+ const u = t * sqrt3$2;
+ context.moveTo(0, r);
+ context.lineTo(0, -r);
+ context.moveTo(-u, -t);
+ context.lineTo(u, t);
+ context.moveTo(-u, t);
+ context.lineTo(u, -t);
+ }
+};
+
+var circle = {
+ draw(context, size) {
+ const r = sqrt(size / pi);
+ context.moveTo(r, 0);
+ context.arc(0, 0, r, 0, tau);
+ }
+};
+
+var cross = {
+ draw(context, size) {
+ const r = sqrt(size / 5) / 2;
+ context.moveTo(-3 * r, -r);
+ context.lineTo(-r, -r);
+ context.lineTo(-r, -3 * r);
+ context.lineTo(r, -3 * r);
+ context.lineTo(r, -r);
+ context.lineTo(3 * r, -r);
+ context.lineTo(3 * r, r);
+ context.lineTo(r, r);
+ context.lineTo(r, 3 * r);
+ context.lineTo(-r, 3 * r);
+ context.lineTo(-r, r);
+ context.lineTo(-3 * r, r);
+ context.closePath();
+ }
+};
+
+const tan30 = sqrt(1 / 3);
+const tan30_2 = tan30 * 2;
+
+var diamond = {
+ draw(context, size) {
+ const y = sqrt(size / tan30_2);
+ const x = y * tan30;
+ context.moveTo(0, -y);
+ context.lineTo(x, 0);
+ context.lineTo(0, y);
+ context.lineTo(-x, 0);
+ context.closePath();
+ }
+};
+
+var diamond2 = {
+ draw(context, size) {
+ const r = sqrt(size) * 0.62625;
+ context.moveTo(0, -r);
+ context.lineTo(r, 0);
+ context.lineTo(0, r);
+ context.lineTo(-r, 0);
+ context.closePath();
+ }
+};
+
+var plus = {
+ draw(context, size) {
+ const r = sqrt(size - min(size / 7, 2)) * 0.87559;
+ context.moveTo(-r, 0);
+ context.lineTo(r, 0);
+ context.moveTo(0, r);
+ context.lineTo(0, -r);
+ }
+};
+
+var square = {
+ draw(context, size) {
+ const w = sqrt(size);
+ const x = -w / 2;
+ context.rect(x, x, w, w);
+ }
+};
+
+var square2 = {
+ draw(context, size) {
+ const r = sqrt(size) * 0.4431;
+ context.moveTo(r, r);
+ context.lineTo(r, -r);
+ context.lineTo(-r, -r);
+ context.lineTo(-r, r);
+ context.closePath();
+ }
+};
+
+const ka = 0.89081309152928522810;
+const kr = sin(pi / 10) / sin(7 * pi / 10);
+const kx = sin(tau / 10) * kr;
+const ky = -cos(tau / 10) * kr;
+
+var star = {
+ draw(context, size) {
+ const r = sqrt(size * ka);
+ const x = kx * r;
+ const y = ky * r;
+ context.moveTo(0, -r);
+ context.lineTo(x, y);
+ for (let i = 1; i < 5; ++i) {
+ const a = tau * i / 5;
+ const c = cos(a);
+ const s = sin(a);
+ context.lineTo(s * r, -c * r);
+ context.lineTo(c * x - s * y, s * x + c * y);
+ }
+ context.closePath();
+ }
+};
+
+const sqrt3$1 = sqrt(3);
+
+var triangle = {
+ draw(context, size) {
+ const y = -sqrt(size / (sqrt3$1 * 3));
+ context.moveTo(0, y * 2);
+ context.lineTo(-sqrt3$1 * y, -y);
+ context.lineTo(sqrt3$1 * y, -y);
+ context.closePath();
+ }
+};
+
+const sqrt3 = sqrt(3);
+
+var triangle2 = {
+ draw(context, size) {
+ const s = sqrt(size) * 0.6824;
+ const t = s / 2;
+ const u = (s * sqrt3) / 2; // cos(Math.PI / 6)
+ context.moveTo(0, -s);
+ context.lineTo(u, t);
+ context.lineTo(-u, t);
+ context.closePath();
+ }
+};
+
+const c = -0.5;
+const s = sqrt(3) / 2;
+const k = 1 / sqrt(12);
+const a = (k / 2 + 1) * 3;
+
+var wye = {
+ draw(context, size) {
+ const r = sqrt(size / a);
+ const x0 = r / 2, y0 = r * k;
+ const x1 = x0, y1 = r * k + r;
+ const x2 = -x1, y2 = y1;
+ context.moveTo(x0, y0);
+ context.lineTo(x1, y1);
+ context.lineTo(x2, y2);
+ context.lineTo(c * x0 - s * y0, s * x0 + c * y0);
+ context.lineTo(c * x1 - s * y1, s * x1 + c * y1);
+ context.lineTo(c * x2 - s * y2, s * x2 + c * y2);
+ context.lineTo(c * x0 + s * y0, c * y0 - s * x0);
+ context.lineTo(c * x1 + s * y1, c * y1 - s * x1);
+ context.lineTo(c * x2 + s * y2, c * y2 - s * x2);
+ context.closePath();
+ }
+};
+
+var x = {
+ draw(context, size) {
+ const r = sqrt(size - min(size / 6, 1.7)) * 0.6189;
+ context.moveTo(-r, -r);
+ context.lineTo(r, r);
+ context.moveTo(-r, r);
+ context.lineTo(r, -r);
+ }
+};
+
+// These symbols are designed to be filled.
+const symbolsFill = [
+ circle,
+ cross,
+ diamond,
+ square,
+ star,
+ triangle,
+ wye
+];
+
+// These symbols are designed to be stroked (with a width of 1.5px and round caps).
+const symbolsStroke = [
+ circle,
+ plus,
+ x,
+ triangle2,
+ asterisk,
+ square2,
+ diamond2
+];
+
+function Symbol(type, size) {
+ let context = null;
+
+ type = typeof type === "function" ? type : constant(type || circle);
+ size = typeof size === "function" ? size : constant(size === undefined ? 64 : +size);
+
+ function symbol() {
+ let buffer;
+ if (!context) context = buffer = d3Path.path();
+ type.apply(this, arguments).draw(context, +size.apply(this, arguments));
+ if (buffer) return context = null, buffer + "" || null;
+ }
+
+ symbol.type = function(_) {
+ return arguments.length ? (type = typeof _ === "function" ? _ : constant(_), symbol) : type;
+ };
+
+ symbol.size = function(_) {
+ return arguments.length ? (size = typeof _ === "function" ? _ : constant(+_), symbol) : size;
+ };
+
+ symbol.context = function(_) {
+ return arguments.length ? (context = _ == null ? null : _, symbol) : context;
+ };
+
+ return symbol;
+}
+
+function noop() {}
+
+function point$3(that, x, y) {
+ that._context.bezierCurveTo(
+ (2 * that._x0 + that._x1) / 3,
+ (2 * that._y0 + that._y1) / 3,
+ (that._x0 + 2 * that._x1) / 3,
+ (that._y0 + 2 * that._y1) / 3,
+ (that._x0 + 4 * that._x1 + x) / 6,
+ (that._y0 + 4 * that._y1 + y) / 6
+ );
+}
+
+function Basis(context) {
+ this._context = context;
+}
+
+Basis.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._x0 = this._x1 =
+ this._y0 = this._y1 = NaN;
+ this._point = 0;
+ },
+ lineEnd: function() {
+ switch (this._point) {
+ case 3: point$3(this, this._x1, this._y1); // falls through
+ case 2: this._context.lineTo(this._x1, this._y1); break;
+ }
+ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
+ this._line = 1 - this._line;
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+ switch (this._point) {
+ case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
+ case 1: this._point = 2; break;
+ case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // falls through
+ default: point$3(this, x, y); break;
+ }
+ this._x0 = this._x1, this._x1 = x;
+ this._y0 = this._y1, this._y1 = y;
+ }
+};
+
+function basis(context) {
+ return new Basis(context);
+}
+
+function BasisClosed(context) {
+ this._context = context;
+}
+
+BasisClosed.prototype = {
+ areaStart: noop,
+ areaEnd: noop,
+ lineStart: function() {
+ this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =
+ this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;
+ this._point = 0;
+ },
+ lineEnd: function() {
+ switch (this._point) {
+ case 1: {
+ this._context.moveTo(this._x2, this._y2);
+ this._context.closePath();
+ break;
+ }
+ case 2: {
+ this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);
+ this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);
+ this._context.closePath();
+ break;
+ }
+ case 3: {
+ this.point(this._x2, this._y2);
+ this.point(this._x3, this._y3);
+ this.point(this._x4, this._y4);
+ break;
+ }
+ }
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+ switch (this._point) {
+ case 0: this._point = 1; this._x2 = x, this._y2 = y; break;
+ case 1: this._point = 2; this._x3 = x, this._y3 = y; break;
+ case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break;
+ default: point$3(this, x, y); break;
+ }
+ this._x0 = this._x1, this._x1 = x;
+ this._y0 = this._y1, this._y1 = y;
+ }
+};
+
+function basisClosed(context) {
+ return new BasisClosed(context);
+}
+
+function BasisOpen(context) {
+ this._context = context;
+}
+
+BasisOpen.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._x0 = this._x1 =
+ this._y0 = this._y1 = NaN;
+ this._point = 0;
+ },
+ lineEnd: function() {
+ if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
+ this._line = 1 - this._line;
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+ switch (this._point) {
+ case 0: this._point = 1; break;
+ case 1: this._point = 2; break;
+ case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break;
+ case 3: this._point = 4; // falls through
+ default: point$3(this, x, y); break;
+ }
+ this._x0 = this._x1, this._x1 = x;
+ this._y0 = this._y1, this._y1 = y;
+ }
+};
+
+function basisOpen(context) {
+ return new BasisOpen(context);
+}
+
+function Bundle(context, beta) {
+ this._basis = new Basis(context);
+ this._beta = beta;
+}
+
+Bundle.prototype = {
+ lineStart: function() {
+ this._x = [];
+ this._y = [];
+ this._basis.lineStart();
+ },
+ lineEnd: function() {
+ var x = this._x,
+ y = this._y,
+ j = x.length - 1;
+
+ if (j > 0) {
+ var x0 = x[0],
+ y0 = y[0],
+ dx = x[j] - x0,
+ dy = y[j] - y0,
+ i = -1,
+ t;
+
+ while (++i <= j) {
+ t = i / j;
+ this._basis.point(
+ this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),
+ this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)
+ );
+ }
+ }
+
+ this._x = this._y = null;
+ this._basis.lineEnd();
+ },
+ point: function(x, y) {
+ this._x.push(+x);
+ this._y.push(+y);
+ }
+};
+
+var bundle = (function custom(beta) {
+
+ function bundle(context) {
+ return beta === 1 ? new Basis(context) : new Bundle(context, beta);
+ }
+
+ bundle.beta = function(beta) {
+ return custom(+beta);
+ };
+
+ return bundle;
+})(0.85);
+
+function point$2(that, x, y) {
+ that._context.bezierCurveTo(
+ that._x1 + that._k * (that._x2 - that._x0),
+ that._y1 + that._k * (that._y2 - that._y0),
+ that._x2 + that._k * (that._x1 - x),
+ that._y2 + that._k * (that._y1 - y),
+ that._x2,
+ that._y2
+ );
+}
+
+function Cardinal(context, tension) {
+ this._context = context;
+ this._k = (1 - tension) / 6;
+}
+
+Cardinal.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._x0 = this._x1 = this._x2 =
+ this._y0 = this._y1 = this._y2 = NaN;
+ this._point = 0;
+ },
+ lineEnd: function() {
+ switch (this._point) {
+ case 2: this._context.lineTo(this._x2, this._y2); break;
+ case 3: point$2(this, this._x1, this._y1); break;
+ }
+ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
+ this._line = 1 - this._line;
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+ switch (this._point) {
+ case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
+ case 1: this._point = 2; this._x1 = x, this._y1 = y; break;
+ case 2: this._point = 3; // falls through
+ default: point$2(this, x, y); break;
+ }
+ this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
+ this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
+ }
+};
+
+var cardinal = (function custom(tension) {
+
+ function cardinal(context) {
+ return new Cardinal(context, tension);
+ }
+
+ cardinal.tension = function(tension) {
+ return custom(+tension);
+ };
+
+ return cardinal;
+})(0);
+
+function CardinalClosed(context, tension) {
+ this._context = context;
+ this._k = (1 - tension) / 6;
+}
+
+CardinalClosed.prototype = {
+ areaStart: noop,
+ areaEnd: noop,
+ lineStart: function() {
+ this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
+ this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
+ this._point = 0;
+ },
+ lineEnd: function() {
+ switch (this._point) {
+ case 1: {
+ this._context.moveTo(this._x3, this._y3);
+ this._context.closePath();
+ break;
+ }
+ case 2: {
+ this._context.lineTo(this._x3, this._y3);
+ this._context.closePath();
+ break;
+ }
+ case 3: {
+ this.point(this._x3, this._y3);
+ this.point(this._x4, this._y4);
+ this.point(this._x5, this._y5);
+ break;
+ }
+ }
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+ switch (this._point) {
+ case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
+ case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
+ case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
+ default: point$2(this, x, y); break;
+ }
+ this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
+ this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
+ }
+};
+
+var cardinalClosed = (function custom(tension) {
+
+ function cardinal(context) {
+ return new CardinalClosed(context, tension);
+ }
+
+ cardinal.tension = function(tension) {
+ return custom(+tension);
+ };
+
+ return cardinal;
+})(0);
+
+function CardinalOpen(context, tension) {
+ this._context = context;
+ this._k = (1 - tension) / 6;
+}
+
+CardinalOpen.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._x0 = this._x1 = this._x2 =
+ this._y0 = this._y1 = this._y2 = NaN;
+ this._point = 0;
+ },
+ lineEnd: function() {
+ if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
+ this._line = 1 - this._line;
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+ switch (this._point) {
+ case 0: this._point = 1; break;
+ case 1: this._point = 2; break;
+ case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
+ case 3: this._point = 4; // falls through
+ default: point$2(this, x, y); break;
+ }
+ this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
+ this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
+ }
+};
+
+var cardinalOpen = (function custom(tension) {
+
+ function cardinal(context) {
+ return new CardinalOpen(context, tension);
+ }
+
+ cardinal.tension = function(tension) {
+ return custom(+tension);
+ };
+
+ return cardinal;
+})(0);
+
+function point$1(that, x, y) {
+ var x1 = that._x1,
+ y1 = that._y1,
+ x2 = that._x2,
+ y2 = that._y2;
+
+ if (that._l01_a > epsilon) {
+ var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,
+ n = 3 * that._l01_a * (that._l01_a + that._l12_a);
+ x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;
+ y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;
+ }
+
+ if (that._l23_a > epsilon) {
+ var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,
+ m = 3 * that._l23_a * (that._l23_a + that._l12_a);
+ x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;
+ y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;
+ }
+
+ that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);
+}
+
+function CatmullRom(context, alpha) {
+ this._context = context;
+ this._alpha = alpha;
+}
+
+CatmullRom.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._x0 = this._x1 = this._x2 =
+ this._y0 = this._y1 = this._y2 = NaN;
+ this._l01_a = this._l12_a = this._l23_a =
+ this._l01_2a = this._l12_2a = this._l23_2a =
+ this._point = 0;
+ },
+ lineEnd: function() {
+ switch (this._point) {
+ case 2: this._context.lineTo(this._x2, this._y2); break;
+ case 3: this.point(this._x2, this._y2); break;
+ }
+ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
+ this._line = 1 - this._line;
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+
+ if (this._point) {
+ var x23 = this._x2 - x,
+ y23 = this._y2 - y;
+ this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
+ }
+
+ switch (this._point) {
+ case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
+ case 1: this._point = 2; break;
+ case 2: this._point = 3; // falls through
+ default: point$1(this, x, y); break;
+ }
+
+ this._l01_a = this._l12_a, this._l12_a = this._l23_a;
+ this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
+ this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
+ this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
+ }
+};
+
+var catmullRom = (function custom(alpha) {
+
+ function catmullRom(context) {
+ return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);
+ }
+
+ catmullRom.alpha = function(alpha) {
+ return custom(+alpha);
+ };
+
+ return catmullRom;
+})(0.5);
+
+function CatmullRomClosed(context, alpha) {
+ this._context = context;
+ this._alpha = alpha;
+}
+
+CatmullRomClosed.prototype = {
+ areaStart: noop,
+ areaEnd: noop,
+ lineStart: function() {
+ this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
+ this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
+ this._l01_a = this._l12_a = this._l23_a =
+ this._l01_2a = this._l12_2a = this._l23_2a =
+ this._point = 0;
+ },
+ lineEnd: function() {
+ switch (this._point) {
+ case 1: {
+ this._context.moveTo(this._x3, this._y3);
+ this._context.closePath();
+ break;
+ }
+ case 2: {
+ this._context.lineTo(this._x3, this._y3);
+ this._context.closePath();
+ break;
+ }
+ case 3: {
+ this.point(this._x3, this._y3);
+ this.point(this._x4, this._y4);
+ this.point(this._x5, this._y5);
+ break;
+ }
+ }
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+
+ if (this._point) {
+ var x23 = this._x2 - x,
+ y23 = this._y2 - y;
+ this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
+ }
+
+ switch (this._point) {
+ case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
+ case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
+ case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
+ default: point$1(this, x, y); break;
+ }
+
+ this._l01_a = this._l12_a, this._l12_a = this._l23_a;
+ this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
+ this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
+ this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
+ }
+};
+
+var catmullRomClosed = (function custom(alpha) {
+
+ function catmullRom(context) {
+ return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);
+ }
+
+ catmullRom.alpha = function(alpha) {
+ return custom(+alpha);
+ };
+
+ return catmullRom;
+})(0.5);
+
+function CatmullRomOpen(context, alpha) {
+ this._context = context;
+ this._alpha = alpha;
+}
+
+CatmullRomOpen.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._x0 = this._x1 = this._x2 =
+ this._y0 = this._y1 = this._y2 = NaN;
+ this._l01_a = this._l12_a = this._l23_a =
+ this._l01_2a = this._l12_2a = this._l23_2a =
+ this._point = 0;
+ },
+ lineEnd: function() {
+ if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
+ this._line = 1 - this._line;
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+
+ if (this._point) {
+ var x23 = this._x2 - x,
+ y23 = this._y2 - y;
+ this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
+ }
+
+ switch (this._point) {
+ case 0: this._point = 1; break;
+ case 1: this._point = 2; break;
+ case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
+ case 3: this._point = 4; // falls through
+ default: point$1(this, x, y); break;
+ }
+
+ this._l01_a = this._l12_a, this._l12_a = this._l23_a;
+ this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
+ this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
+ this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
+ }
+};
+
+var catmullRomOpen = (function custom(alpha) {
+
+ function catmullRom(context) {
+ return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);
+ }
+
+ catmullRom.alpha = function(alpha) {
+ return custom(+alpha);
+ };
+
+ return catmullRom;
+})(0.5);
+
+function LinearClosed(context) {
+ this._context = context;
+}
+
+LinearClosed.prototype = {
+ areaStart: noop,
+ areaEnd: noop,
+ lineStart: function() {
+ this._point = 0;
+ },
+ lineEnd: function() {
+ if (this._point) this._context.closePath();
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+ if (this._point) this._context.lineTo(x, y);
+ else this._point = 1, this._context.moveTo(x, y);
+ }
+};
+
+function linearClosed(context) {
+ return new LinearClosed(context);
+}
+
+function sign(x) {
+ return x < 0 ? -1 : 1;
+}
+
+// Calculate the slopes of the tangents (Hermite-type interpolation) based on
+// the following paper: Steffen, M. 1990. A Simple Method for Monotonic
+// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.
+// NOV(II), P. 443, 1990.
+function slope3(that, x2, y2) {
+ var h0 = that._x1 - that._x0,
+ h1 = x2 - that._x1,
+ s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),
+ s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),
+ p = (s0 * h1 + s1 * h0) / (h0 + h1);
+ return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;
+}
+
+// Calculate a one-sided slope.
+function slope2(that, t) {
+ var h = that._x1 - that._x0;
+ return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;
+}
+
+// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations
+// "you can express cubic Hermite interpolation in terms of cubic Bézier curves
+// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1".
+function point(that, t0, t1) {
+ var x0 = that._x0,
+ y0 = that._y0,
+ x1 = that._x1,
+ y1 = that._y1,
+ dx = (x1 - x0) / 3;
+ that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);
+}
+
+function MonotoneX(context) {
+ this._context = context;
+}
+
+MonotoneX.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._x0 = this._x1 =
+ this._y0 = this._y1 =
+ this._t0 = NaN;
+ this._point = 0;
+ },
+ lineEnd: function() {
+ switch (this._point) {
+ case 2: this._context.lineTo(this._x1, this._y1); break;
+ case 3: point(this, this._t0, slope2(this, this._t0)); break;
+ }
+ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
+ this._line = 1 - this._line;
+ },
+ point: function(x, y) {
+ var t1 = NaN;
+
+ x = +x, y = +y;
+ if (x === this._x1 && y === this._y1) return; // Ignore coincident points.
+ switch (this._point) {
+ case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
+ case 1: this._point = 2; break;
+ case 2: this._point = 3; point(this, slope2(this, t1 = slope3(this, x, y)), t1); break;
+ default: point(this, this._t0, t1 = slope3(this, x, y)); break;
+ }
+
+ this._x0 = this._x1, this._x1 = x;
+ this._y0 = this._y1, this._y1 = y;
+ this._t0 = t1;
+ }
+};
+
+function MonotoneY(context) {
+ this._context = new ReflectContext(context);
+}
+
+(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {
+ MonotoneX.prototype.point.call(this, y, x);
+};
+
+function ReflectContext(context) {
+ this._context = context;
+}
+
+ReflectContext.prototype = {
+ moveTo: function(x, y) { this._context.moveTo(y, x); },
+ closePath: function() { this._context.closePath(); },
+ lineTo: function(x, y) { this._context.lineTo(y, x); },
+ bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }
+};
+
+function monotoneX(context) {
+ return new MonotoneX(context);
+}
+
+function monotoneY(context) {
+ return new MonotoneY(context);
+}
+
+function Natural(context) {
+ this._context = context;
+}
+
+Natural.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._x = [];
+ this._y = [];
+ },
+ lineEnd: function() {
+ var x = this._x,
+ y = this._y,
+ n = x.length;
+
+ if (n) {
+ this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);
+ if (n === 2) {
+ this._context.lineTo(x[1], y[1]);
+ } else {
+ var px = controlPoints(x),
+ py = controlPoints(y);
+ for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {
+ this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
+ }
+ }
+ }
+
+ if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();
+ this._line = 1 - this._line;
+ this._x = this._y = null;
+ },
+ point: function(x, y) {
+ this._x.push(+x);
+ this._y.push(+y);
+ }
+};
+
+// See https://www.particleincell.com/2012/bezier-splines/ for derivation.
+function controlPoints(x) {
+ var i,
+ n = x.length - 1,
+ m,
+ a = new Array(n),
+ b = new Array(n),
+ r = new Array(n);
+ a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];
+ for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];
+ a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];
+ for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];
+ a[n - 1] = r[n - 1] / b[n - 1];
+ for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];
+ b[n - 1] = (x[n] + a[n - 1]) / 2;
+ for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];
+ return [a, b];
+}
+
+function natural(context) {
+ return new Natural(context);
+}
+
+function Step(context, t) {
+ this._context = context;
+ this._t = t;
+}
+
+Step.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._x = this._y = NaN;
+ this._point = 0;
+ },
+ lineEnd: function() {
+ if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);
+ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
+ if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+ switch (this._point) {
+ case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
+ case 1: this._point = 2; // falls through
+ default: {
+ if (this._t <= 0) {
+ this._context.lineTo(this._x, y);
+ this._context.lineTo(x, y);
+ } else {
+ var x1 = this._x * (1 - this._t) + x * this._t;
+ this._context.lineTo(x1, this._y);
+ this._context.lineTo(x1, y);
+ }
+ break;
+ }
+ }
+ this._x = x, this._y = y;
+ }
+};
+
+function step(context) {
+ return new Step(context, 0.5);
+}
+
+function stepBefore(context) {
+ return new Step(context, 0);
+}
+
+function stepAfter(context) {
+ return new Step(context, 1);
+}
+
+function none$1(series, order) {
+ if (!((n = series.length) > 1)) return;
+ for (var i = 1, j, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {
+ s0 = s1, s1 = series[order[i]];
+ for (j = 0; j < m; ++j) {
+ s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1];
+ }
+ }
+}
+
+function none(series) {
+ var n = series.length, o = new Array(n);
+ while (--n >= 0) o[n] = n;
+ return o;
+}
+
+function stackValue(d, key) {
+ return d[key];
+}
+
+function stackSeries(key) {
+ const series = [];
+ series.key = key;
+ return series;
+}
+
+function stack() {
+ var keys = constant([]),
+ order = none,
+ offset = none$1,
+ value = stackValue;
+
+ function stack(data) {
+ var sz = Array.from(keys.apply(this, arguments), stackSeries),
+ i, n = sz.length, j = -1,
+ oz;
+
+ for (const d of data) {
+ for (i = 0, ++j; i < n; ++i) {
+ (sz[i][j] = [0, +value(d, sz[i].key, j, data)]).data = d;
+ }
+ }
+
+ for (i = 0, oz = array(order(sz)); i < n; ++i) {
+ sz[oz[i]].index = i;
+ }
+
+ offset(sz, oz);
+ return sz;
+ }
+
+ stack.keys = function(_) {
+ return arguments.length ? (keys = typeof _ === "function" ? _ : constant(Array.from(_)), stack) : keys;
+ };
+
+ stack.value = function(_) {
+ return arguments.length ? (value = typeof _ === "function" ? _ : constant(+_), stack) : value;
+ };
+
+ stack.order = function(_) {
+ return arguments.length ? (order = _ == null ? none : typeof _ === "function" ? _ : constant(Array.from(_)), stack) : order;
+ };
+
+ stack.offset = function(_) {
+ return arguments.length ? (offset = _ == null ? none$1 : _, stack) : offset;
+ };
+
+ return stack;
+}
+
+function expand(series, order) {
+ if (!((n = series.length) > 0)) return;
+ for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) {
+ for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0;
+ if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y;
+ }
+ none$1(series, order);
+}
+
+function diverging(series, order) {
+ if (!((n = series.length) > 0)) return;
+ for (var i, j = 0, d, dy, yp, yn, n, m = series[order[0]].length; j < m; ++j) {
+ for (yp = yn = 0, i = 0; i < n; ++i) {
+ if ((dy = (d = series[order[i]][j])[1] - d[0]) > 0) {
+ d[0] = yp, d[1] = yp += dy;
+ } else if (dy < 0) {
+ d[1] = yn, d[0] = yn += dy;
+ } else {
+ d[0] = 0, d[1] = dy;
+ }
+ }
+ }
+}
+
+function silhouette(series, order) {
+ if (!((n = series.length) > 0)) return;
+ for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) {
+ for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0;
+ s0[j][1] += s0[j][0] = -y / 2;
+ }
+ none$1(series, order);
+}
+
+function wiggle(series, order) {
+ if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return;
+ for (var y = 0, j = 1, s0, m, n; j < m; ++j) {
+ for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) {
+ var si = series[order[i]],
+ sij0 = si[j][1] || 0,
+ sij1 = si[j - 1][1] || 0,
+ s3 = (sij0 - sij1) / 2;
+ for (var k = 0; k < i; ++k) {
+ var sk = series[order[k]],
+ skj0 = sk[j][1] || 0,
+ skj1 = sk[j - 1][1] || 0;
+ s3 += skj0 - skj1;
+ }
+ s1 += sij0, s2 += s3 * sij0;
+ }
+ s0[j - 1][1] += s0[j - 1][0] = y;
+ if (s1) y -= s2 / s1;
+ }
+ s0[j - 1][1] += s0[j - 1][0] = y;
+ none$1(series, order);
+}
+
+function appearance(series) {
+ var peaks = series.map(peak);
+ return none(series).sort(function(a, b) { return peaks[a] - peaks[b]; });
+}
+
+function peak(series) {
+ var i = -1, j = 0, n = series.length, vi, vj = -Infinity;
+ while (++i < n) if ((vi = +series[i][1]) > vj) vj = vi, j = i;
+ return j;
+}
+
+function ascending(series) {
+ var sums = series.map(sum);
+ return none(series).sort(function(a, b) { return sums[a] - sums[b]; });
+}
+
+function sum(series) {
+ var s = 0, i = -1, n = series.length, v;
+ while (++i < n) if (v = +series[i][1]) s += v;
+ return s;
+}
+
+function descending(series) {
+ return ascending(series).reverse();
+}
+
+function insideOut(series) {
+ var n = series.length,
+ i,
+ j,
+ sums = series.map(sum),
+ order = appearance(series),
+ top = 0,
+ bottom = 0,
+ tops = [],
+ bottoms = [];
+
+ for (i = 0; i < n; ++i) {
+ j = order[i];
+ if (top < bottom) {
+ top += sums[j];
+ tops.push(j);
+ } else {
+ bottom += sums[j];
+ bottoms.push(j);
+ }
+ }
+
+ return bottoms.reverse().concat(tops);
+}
+
+function reverse(series) {
+ return none(series).reverse();
+}
+
+exports.arc = arc;
+exports.area = area;
+exports.areaRadial = areaRadial;
+exports.curveBasis = basis;
+exports.curveBasisClosed = basisClosed;
+exports.curveBasisOpen = basisOpen;
+exports.curveBumpX = bumpX;
+exports.curveBumpY = bumpY;
+exports.curveBundle = bundle;
+exports.curveCardinal = cardinal;
+exports.curveCardinalClosed = cardinalClosed;
+exports.curveCardinalOpen = cardinalOpen;
+exports.curveCatmullRom = catmullRom;
+exports.curveCatmullRomClosed = catmullRomClosed;
+exports.curveCatmullRomOpen = catmullRomOpen;
+exports.curveLinear = curveLinear;
+exports.curveLinearClosed = linearClosed;
+exports.curveMonotoneX = monotoneX;
+exports.curveMonotoneY = monotoneY;
+exports.curveNatural = natural;
+exports.curveStep = step;
+exports.curveStepAfter = stepAfter;
+exports.curveStepBefore = stepBefore;
+exports.line = line;
+exports.lineRadial = lineRadial$1;
+exports.link = link;
+exports.linkHorizontal = linkHorizontal;
+exports.linkRadial = linkRadial;
+exports.linkVertical = linkVertical;
+exports.pie = pie;
+exports.pointRadial = pointRadial;
+exports.radialArea = areaRadial;
+exports.radialLine = lineRadial$1;
+exports.stack = stack;
+exports.stackOffsetDiverging = diverging;
+exports.stackOffsetExpand = expand;
+exports.stackOffsetNone = none$1;
+exports.stackOffsetSilhouette = silhouette;
+exports.stackOffsetWiggle = wiggle;
+exports.stackOrderAppearance = appearance;
+exports.stackOrderAscending = ascending;
+exports.stackOrderDescending = descending;
+exports.stackOrderInsideOut = insideOut;
+exports.stackOrderNone = none;
+exports.stackOrderReverse = reverse;
+exports.symbol = Symbol;
+exports.symbolAsterisk = asterisk;
+exports.symbolCircle = circle;
+exports.symbolCross = cross;
+exports.symbolDiamond = diamond;
+exports.symbolDiamond2 = diamond2;
+exports.symbolPlus = plus;
+exports.symbolSquare = square;
+exports.symbolSquare2 = square2;
+exports.symbolStar = star;
+exports.symbolTriangle = triangle;
+exports.symbolTriangle2 = triangle2;
+exports.symbolWye = wye;
+exports.symbolX = x;
+exports.symbols = symbolsFill;
+exports.symbolsFill = symbolsFill;
+exports.symbolsStroke = symbolsStroke;
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+}));
diff --git a/node_modules/d3-shape/dist/d3-shape.min.js b/node_modules/d3-shape/dist/d3-shape.min.js
new file mode 100644
index 00000000..b7019cc1
--- /dev/null
+++ b/node_modules/d3-shape/dist/d3-shape.min.js
@@ -0,0 +1,2 @@
+// https://d3js.org/d3-shape/ v3.1.0 Copyright 2010-2021 Mike Bostock
+!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("d3-path")):"function"==typeof define&&define.amd?define(["exports","d3-path"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self).d3=t.d3||{},t.d3)}(this,(function(t,n){"use strict";function i(t){return function(){return t}}const e=Math.abs,s=Math.atan2,o=Math.cos,h=Math.max,_=Math.min,r=Math.sin,a=Math.sqrt,l=1e-12,c=Math.PI,u=c/2,f=2*c;function y(t){return t>1?0:t<-1?c:Math.acos(t)}function x(t){return t>=1?u:t<=-1?-u:Math.asin(t)}function p(t){return t.innerRadius}function v(t){return t.outerRadius}function d(t){return t.startAngle}function T(t){return t.endAngle}function g(t){return t&&t.padAngle}function b(t,n,i,e,s,o,h,_){var r=i-t,a=e-n,c=h-s,u=_-o,f=u*r-c*a;if(!(f*fO*O+R*R&&(S=A,E=P),{cx:S,cy:E,x01:-u,y01:-f,x11:S*(s/w-1),y11:E*(s/w-1)}}var w=Array.prototype.slice;function k(t){return"object"==typeof t&&"length"in t?t:Array.from(t)}function N(t){this._context=t}function S(t){return new N(t)}function E(t){return t[0]}function A(t){return t[1]}function P(t,e){var s=i(!0),o=null,h=S,_=null;function r(i){var r,a,l,c=(i=k(i)).length,u=!1;for(null==o&&(_=h(l=n.path())),r=0;r<=c;++r)!(r=c;--u)a.point(v[u],d[u]);a.lineEnd(),a.areaEnd()}p&&(v[l]=+t(f,l,i),d[l]=+e(f,l,i),a.point(o?+o(f,l,i):v[l],s?+s(f,l,i):d[l]))}if(y)return a=null,y+""||null}function c(){return P().defined(h).curve(r).context(_)}return t="function"==typeof t?t:void 0===t?E:i(+t),e="function"==typeof e?e:i(void 0===e?0:+e),s="function"==typeof s?s:void 0===s?A:i(+s),l.x=function(n){return arguments.length?(t="function"==typeof n?n:i(+n),o=null,l):t},l.x0=function(n){return arguments.length?(t="function"==typeof n?n:i(+n),l):t},l.x1=function(t){return arguments.length?(o=null==t?null:"function"==typeof t?t:i(+t),l):o},l.y=function(t){return arguments.length?(e="function"==typeof t?t:i(+t),s=null,l):e},l.y0=function(t){return arguments.length?(e="function"==typeof t?t:i(+t),l):e},l.y1=function(t){return arguments.length?(s=null==t?null:"function"==typeof t?t:i(+t),l):s},l.lineX0=l.lineY0=function(){return c().x(t).y(e)},l.lineY1=function(){return c().x(t).y(s)},l.lineX1=function(){return c().x(o).y(e)},l.defined=function(t){return arguments.length?(h="function"==typeof t?t:i(!!t),l):h},l.curve=function(t){return arguments.length?(r=t,null!=_&&(a=r(_)),l):r},l.context=function(t){return arguments.length?(null==t?_=a=null:a=r(_=t),l):_},l}function C(t,n){return nt?1:n>=t?0:NaN}function O(t){return t}N.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;default:this._context.lineTo(t,n)}}};var R=X(S);function z(t){this._curve=t}function X(t){function n(n){return new z(t(n))}return n._curve=t,n}function Y(t){var n=t.curve;return t.angle=t.x,delete t.x,t.radius=t.y,delete t.y,t.curve=function(t){return arguments.length?n(X(t)):n()._curve},t}function q(){return Y(P().curve(R))}function B(){var t=M().curve(R),n=t.curve,i=t.lineX0,e=t.lineX1,s=t.lineY0,o=t.lineY1;return t.angle=t.x,delete t.x,t.startAngle=t.x0,delete t.x0,t.endAngle=t.x1,delete t.x1,t.radius=t.y,delete t.y,t.innerRadius=t.y0,delete t.y0,t.outerRadius=t.y1,delete t.y1,t.lineStartAngle=function(){return Y(i())},delete t.lineX0,t.lineEndAngle=function(){return Y(e())},delete t.lineX1,t.lineInnerRadius=function(){return Y(s())},delete t.lineY0,t.lineOuterRadius=function(){return Y(o())},delete t.lineY1,t.curve=function(t){return arguments.length?n(X(t)):n()._curve},t}function j(t,n){return[(n=+n)*Math.cos(t-=Math.PI/2),n*Math.sin(t)]}z.prototype={areaStart:function(){this._curve.areaStart()},areaEnd:function(){this._curve.areaEnd()},lineStart:function(){this._curve.lineStart()},lineEnd:function(){this._curve.lineEnd()},point:function(t,n){this._curve.point(n*Math.sin(t),n*-Math.cos(t))}};class D{constructor(t,n){this._context=t,this._x=n}areaStart(){this._line=0}areaEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line}point(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;default:this._x?this._context.bezierCurveTo(this._x0=(this._x0+t)/2,this._y0,this._x0,n,t,n):this._context.bezierCurveTo(this._x0,this._y0=(this._y0+n)/2,t,this._y0,t,n)}this._x0=t,this._y0=n}}class I{constructor(t){this._context=t}lineStart(){this._point=0}lineEnd(){}point(t,n){if(t=+t,n=+n,0==this._point++)this._x0=t,this._y0=n;else{const i=j(this._x0,this._y0),e=j(this._x0,this._y0=(this._y0+n)/2),s=j(t,this._y0),o=j(t,n);this._context.moveTo(...i),this._context.bezierCurveTo(...e,...s,...o)}}}function L(t){return new D(t,!0)}function V(t){return new D(t,!1)}function W(t){return new I(t)}function F(t){return t.source}function H(t){return t.target}function G(t){let e=F,s=H,o=E,h=A,_=null,r=null;function a(){let i;const a=w.call(arguments),l=e.apply(this,a),c=s.apply(this,a);if(null==_&&(r=t(i=n.path())),r.lineStart(),a[0]=l,r.point(+o.apply(this,a),+h.apply(this,a)),a[0]=c,r.point(+o.apply(this,a),+h.apply(this,a)),r.lineEnd(),i)return r=null,i+""||null}return a.source=function(t){return arguments.length?(e=t,a):e},a.target=function(t){return arguments.length?(s=t,a):s},a.x=function(t){return arguments.length?(o="function"==typeof t?t:i(+t),a):o},a.y=function(t){return arguments.length?(h="function"==typeof t?t:i(+t),a):h},a.context=function(n){return arguments.length?(null==n?_=r=null:r=t(_=n),a):_},a}const J=a(3);var K={draw(t,n){const i=.59436*a(n+_(n/28,.75)),e=i/2,s=e*J;t.moveTo(0,i),t.lineTo(0,-i),t.moveTo(-s,-e),t.lineTo(s,e),t.moveTo(-s,e),t.lineTo(s,-e)}},Q={draw(t,n){const i=a(n/c);t.moveTo(i,0),t.arc(0,0,i,0,f)}},U={draw(t,n){const i=a(n/5)/2;t.moveTo(-3*i,-i),t.lineTo(-i,-i),t.lineTo(-i,-3*i),t.lineTo(i,-3*i),t.lineTo(i,-i),t.lineTo(3*i,-i),t.lineTo(3*i,i),t.lineTo(i,i),t.lineTo(i,3*i),t.lineTo(-i,3*i),t.lineTo(-i,i),t.lineTo(-3*i,i),t.closePath()}};const Z=a(1/3),$=2*Z;var tt={draw(t,n){const i=a(n/$),e=i*Z;t.moveTo(0,-i),t.lineTo(e,0),t.lineTo(0,i),t.lineTo(-e,0),t.closePath()}},nt={draw(t,n){const i=.62625*a(n);t.moveTo(0,-i),t.lineTo(i,0),t.lineTo(0,i),t.lineTo(-i,0),t.closePath()}},it={draw(t,n){const i=.87559*a(n-_(n/7,2));t.moveTo(-i,0),t.lineTo(i,0),t.moveTo(0,i),t.lineTo(0,-i)}},et={draw(t,n){const i=a(n),e=-i/2;t.rect(e,e,i,i)}},st={draw(t,n){const i=.4431*a(n);t.moveTo(i,i),t.lineTo(i,-i),t.lineTo(-i,-i),t.lineTo(-i,i),t.closePath()}};const ot=r(c/10)/r(7*c/10),ht=r(f/10)*ot,_t=-o(f/10)*ot;var rt={draw(t,n){const i=a(.8908130915292852*n),e=ht*i,s=_t*i;t.moveTo(0,-i),t.lineTo(e,s);for(let n=1;n<5;++n){const h=f*n/5,_=o(h),a=r(h);t.lineTo(a*i,-_*i),t.lineTo(_*e-a*s,a*e+_*s)}t.closePath()}};const at=a(3);var lt={draw(t,n){const i=-a(n/(3*at));t.moveTo(0,2*i),t.lineTo(-at*i,-i),t.lineTo(at*i,-i),t.closePath()}};const ct=a(3);var ut={draw(t,n){const i=.6824*a(n),e=i/2,s=i*ct/2;t.moveTo(0,-i),t.lineTo(s,e),t.lineTo(-s,e),t.closePath()}};const ft=-.5,yt=a(3)/2,xt=1/a(12),pt=3*(xt/2+1);var vt={draw(t,n){const i=a(n/pt),e=i/2,s=i*xt,o=e,h=i*xt+i,_=-o,r=h;t.moveTo(e,s),t.lineTo(o,h),t.lineTo(_,r),t.lineTo(ft*e-yt*s,yt*e+ft*s),t.lineTo(ft*o-yt*h,yt*o+ft*h),t.lineTo(ft*_-yt*r,yt*_+ft*r),t.lineTo(ft*e+yt*s,ft*s-yt*e),t.lineTo(ft*o+yt*h,ft*h-yt*o),t.lineTo(ft*_+yt*r,ft*r-yt*_),t.closePath()}},dt={draw(t,n){const i=.6189*a(n-_(n/6,1.7));t.moveTo(-i,-i),t.lineTo(i,i),t.moveTo(-i,i),t.lineTo(i,-i)}};const Tt=[Q,U,tt,et,rt,lt,vt],gt=[Q,it,dt,ut,K,st,nt];function bt(){}function mt(t,n,i){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+n)/6,(t._y0+4*t._y1+i)/6)}function wt(t){this._context=t}function kt(t){this._context=t}function Nt(t){this._context=t}function St(t,n){this._basis=new wt(t),this._beta=n}wt.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:mt(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:mt(this,t,n)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=n}},kt.prototype={areaStart:bt,areaEnd:bt,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._x2=t,this._y2=n;break;case 1:this._point=2,this._x3=t,this._y3=n;break;case 2:this._point=3,this._x4=t,this._y4=n,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+n)/6);break;default:mt(this,t,n)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=n}},Nt.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var i=(this._x0+4*this._x1+t)/6,e=(this._y0+4*this._y1+n)/6;this._line?this._context.lineTo(i,e):this._context.moveTo(i,e);break;case 3:this._point=4;default:mt(this,t,n)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=n}},St.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var t=this._x,n=this._y,i=t.length-1;if(i>0)for(var e,s=t[0],o=n[0],h=t[i]-s,_=n[i]-o,r=-1;++r<=i;)e=r/i,this._basis.point(this._beta*t[r]+(1-this._beta)*(s+e*h),this._beta*n[r]+(1-this._beta)*(o+e*_));this._x=this._y=null,this._basis.lineEnd()},point:function(t,n){this._x.push(+t),this._y.push(+n)}};var Et=function t(n){function i(t){return 1===n?new wt(t):new St(t,n)}return i.beta=function(n){return t(+n)},i}(.85);function At(t,n,i){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-n),t._y2+t._k*(t._y1-i),t._x2,t._y2)}function Pt(t,n){this._context=t,this._k=(1-n)/6}Pt.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:At(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2,this._x1=t,this._y1=n;break;case 2:this._point=3;default:At(this,t,n)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var Mt=function t(n){function i(t){return new Pt(t,n)}return i.tension=function(n){return t(+n)},i}(0);function Ct(t,n){this._context=t,this._k=(1-n)/6}Ct.prototype={areaStart:bt,areaEnd:bt,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._x3=t,this._y3=n;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=n);break;case 2:this._point=3,this._x5=t,this._y5=n;break;default:At(this,t,n)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var Ot=function t(n){function i(t){return new Ct(t,n)}return i.tension=function(n){return t(+n)},i}(0);function Rt(t,n){this._context=t,this._k=(1-n)/6}Rt.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:At(this,t,n)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var zt=function t(n){function i(t){return new Rt(t,n)}return i.tension=function(n){return t(+n)},i}(0);function Xt(t,n,i){var e=t._x1,s=t._y1,o=t._x2,h=t._y2;if(t._l01_a>l){var _=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,r=3*t._l01_a*(t._l01_a+t._l12_a);e=(e*_-t._x0*t._l12_2a+t._x2*t._l01_2a)/r,s=(s*_-t._y0*t._l12_2a+t._y2*t._l01_2a)/r}if(t._l23_a>l){var a=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,c=3*t._l23_a*(t._l23_a+t._l12_a);o=(o*a+t._x1*t._l23_2a-n*t._l12_2a)/c,h=(h*a+t._y1*t._l23_2a-i*t._l12_2a)/c}t._context.bezierCurveTo(e,s,o,h,t._x2,t._y2)}function Yt(t,n){this._context=t,this._alpha=n}Yt.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){if(t=+t,n=+n,this._point){var i=this._x2-t,e=this._y2-n;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(i*i+e*e,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;break;case 2:this._point=3;default:Xt(this,t,n)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var qt=function t(n){function i(t){return n?new Yt(t,n):new Pt(t,0)}return i.alpha=function(n){return t(+n)},i}(.5);function Bt(t,n){this._context=t,this._alpha=n}Bt.prototype={areaStart:bt,areaEnd:bt,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,n){if(t=+t,n=+n,this._point){var i=this._x2-t,e=this._y2-n;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(i*i+e*e,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=n;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=n);break;case 2:this._point=3,this._x5=t,this._y5=n;break;default:Xt(this,t,n)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var jt=function t(n){function i(t){return n?new Bt(t,n):new Ct(t,0)}return i.alpha=function(n){return t(+n)},i}(.5);function Dt(t,n){this._context=t,this._alpha=n}Dt.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,n){if(t=+t,n=+n,this._point){var i=this._x2-t,e=this._y2-n;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(i*i+e*e,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Xt(this,t,n)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=n}};var It=function t(n){function i(t){return n?new Dt(t,n):new Rt(t,0)}return i.alpha=function(n){return t(+n)},i}(.5);function Lt(t){this._context=t}function Vt(t){return t<0?-1:1}function Wt(t,n,i){var e=t._x1-t._x0,s=n-t._x1,o=(t._y1-t._y0)/(e||s<0&&-0),h=(i-t._y1)/(s||e<0&&-0),_=(o*s+h*e)/(e+s);return(Vt(o)+Vt(h))*Math.min(Math.abs(o),Math.abs(h),.5*Math.abs(_))||0}function Ft(t,n){var i=t._x1-t._x0;return i?(3*(t._y1-t._y0)/i-n)/2:n}function Ht(t,n,i){var e=t._x0,s=t._y0,o=t._x1,h=t._y1,_=(o-e)/3;t._context.bezierCurveTo(e+_,s+_*n,o-_,h-_*i,o,h)}function Gt(t){this._context=t}function Jt(t){this._context=new Kt(t)}function Kt(t){this._context=t}function Qt(t){this._context=t}function Ut(t){var n,i,e=t.length-1,s=new Array(e),o=new Array(e),h=new Array(e);for(s[0]=0,o[0]=2,h[0]=t[0]+2*t[1],n=1;n=0;--n)s[n]=(h[n]-s[n+1])/o[n];for(o[e-1]=(t[e]+s[e-1])/2,n=0;n1)for(var i,e,s,o=1,h=t[n[0]],_=h.length;o=0;)i[n]=n;return i}function nn(t,n){return t[n]}function en(t){const n=[];return n.key=t,n}function sn(t){var n=t.map(on);return tn(t).sort((function(t,i){return n[t]-n[i]}))}function on(t){for(var n,i=-1,e=0,s=t.length,o=-1/0;++io&&(o=n,e=i);return e}function hn(t){var n=t.map(_n);return tn(t).sort((function(t,i){return n[t]-n[i]}))}function _n(t){for(var n,i=0,e=-1,s=t.length;++e=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,n){switch(t=+t,n=+n,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,n):this._context.moveTo(t,n);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,n),this._context.lineTo(t,n);else{var i=this._x*(1-this._t)+t*this._t;this._context.lineTo(i,this._y),this._context.lineTo(i,n)}}this._x=t,this._y=n}},t.arc=function(){var t=p,h=v,w=i(0),k=null,N=d,S=T,E=g,A=null;function P(){var i,p,v=+t.apply(this,arguments),d=+h.apply(this,arguments),T=N.apply(this,arguments)-u,g=S.apply(this,arguments)-u,P=e(g-T),M=g>T;if(A||(A=i=n.path()),dl)if(P>f-l)A.moveTo(d*o(T),d*r(T)),A.arc(0,0,d,T,g,!M),v>l&&(A.moveTo(v*o(g),v*r(g)),A.arc(0,0,v,g,T,M));else{var C,O,R=T,z=g,X=T,Y=g,q=P,B=P,j=E.apply(this,arguments)/2,D=j>l&&(k?+k.apply(this,arguments):a(v*v+d*d)),I=_(e(d-v)/2,+w.apply(this,arguments)),L=I,V=I;if(D>l){var W=x(D/v*r(j)),F=x(D/d*r(j));(q-=2*W)>l?(X+=W*=M?1:-1,Y-=W):(q=0,X=Y=(T+g)/2),(B-=2*F)>l?(R+=F*=M?1:-1,z-=F):(B=0,R=z=(T+g)/2)}var H=d*o(R),G=d*r(R),J=v*o(Y),K=v*r(Y);if(I>l){var Q,U=d*o(z),Z=d*r(z),$=v*o(X),tt=v*r(X);if(Pl?V>l?(C=m($,tt,H,G,d,V,M),O=m(U,Z,J,K,d,V,M),A.moveTo(C.cx+C.x01,C.cy+C.y01),Vl&&q>l?L>l?(C=m(J,K,U,Z,v,-L,M),O=m(H,G,$,tt,v,-L,M),A.lineTo(C.cx+C.x01,C.cy+C.y01),L0&&(y+=c);for(null!=n?x.sort((function(t,i){return n(p[t],p[i])})):null!=e&&x.sort((function(t,n){return e(i[t],i[n])})),_=0,a=y?(d-u*g)/y:0;_0?c*a:0)+g,p[r]={data:i[r],index:_,value:c,startAngle:v,endAngle:l,padAngle:T};return p}return _.value=function(n){return arguments.length?(t="function"==typeof n?n:i(+n),_):t},_.sortValues=function(t){return arguments.length?(n=t,e=null,_):n},_.sort=function(t){return arguments.length?(e=t,n=null,_):e},_.startAngle=function(t){return arguments.length?(s="function"==typeof t?t:i(+t),_):s},_.endAngle=function(t){return arguments.length?(o="function"==typeof t?t:i(+t),_):o},_.padAngle=function(t){return arguments.length?(h="function"==typeof t?t:i(+t),_):h},_},t.pointRadial=j,t.radialArea=B,t.radialLine=q,t.stack=function(){var t=i([]),n=tn,e=$t,s=nn;function o(i){var o,h,_=Array.from(t.apply(this,arguments),en),r=_.length,a=-1;for(const t of i)for(o=0,++a;o0)for(var i,e,s,o,h,_,r=0,a=t[n[0]].length;r0?(e[0]=o,e[1]=o+=s):s<0?(e[1]=h,e[0]=h+=s):(e[0]=0,e[1]=s)},t.stackOffsetExpand=function(t,n){if((e=t.length)>0){for(var i,e,s,o=0,h=t[0].length;o0){for(var i,e=0,s=t[n[0]],o=s.length;e0&&(e=(i=t[n[0]]).length)>0){for(var i,e,s,o=0,h=1;h=12"
+ },
+ "exports": {
+ "umd": "./dist/d3-shape.min.js",
+ "default": "./src/index.js"
+ },
+ "files": [
+ "dist/**/*.js",
+ "src/**/*.js"
+ ],
+ "homepage": "https://d3js.org/d3-shape/",
+ "jsdelivr": "dist/d3-shape.min.js",
+ "keywords": [
+ "d3",
+ "d3-module",
+ "graphics",
+ "visualization",
+ "canvas",
+ "svg"
+ ],
+ "license": "ISC",
+ "main": "src/index.js",
+ "module": "src/index.js",
+ "name": "d3-shape",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/d3/d3-shape.git"
+ },
+ "scripts": {
+ "postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -",
+ "prepublishOnly": "rm -rf dist && yarn test && rollup -c",
+ "test": "mocha 'test/**/*-test.js' && eslint src test"
+ },
+ "sideEffects": false,
+ "type": "module",
+ "unpkg": "dist/d3-shape.min.js",
+ "version": "3.1.0"
+}
diff --git a/node_modules/d3-shape/src/arc.js b/node_modules/d3-shape/src/arc.js
new file mode 100644
index 00000000..2032882d
--- /dev/null
+++ b/node_modules/d3-shape/src/arc.js
@@ -0,0 +1,261 @@
+import {path} from "d3-path";
+import constant from "./constant.js";
+import {abs, acos, asin, atan2, cos, epsilon, halfPi, max, min, pi, sin, sqrt, tau} from "./math.js";
+
+function arcInnerRadius(d) {
+ return d.innerRadius;
+}
+
+function arcOuterRadius(d) {
+ return d.outerRadius;
+}
+
+function arcStartAngle(d) {
+ return d.startAngle;
+}
+
+function arcEndAngle(d) {
+ return d.endAngle;
+}
+
+function arcPadAngle(d) {
+ return d && d.padAngle; // Note: optional!
+}
+
+function intersect(x0, y0, x1, y1, x2, y2, x3, y3) {
+ var x10 = x1 - x0, y10 = y1 - y0,
+ x32 = x3 - x2, y32 = y3 - y2,
+ t = y32 * x10 - x32 * y10;
+ if (t * t < epsilon) return;
+ t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / t;
+ return [x0 + t * x10, y0 + t * y10];
+}
+
+// Compute perpendicular offset line of length rc.
+// http://mathworld.wolfram.com/Circle-LineIntersection.html
+function cornerTangents(x0, y0, x1, y1, r1, rc, cw) {
+ var x01 = x0 - x1,
+ y01 = y0 - y1,
+ lo = (cw ? rc : -rc) / sqrt(x01 * x01 + y01 * y01),
+ ox = lo * y01,
+ oy = -lo * x01,
+ x11 = x0 + ox,
+ y11 = y0 + oy,
+ x10 = x1 + ox,
+ y10 = y1 + oy,
+ x00 = (x11 + x10) / 2,
+ y00 = (y11 + y10) / 2,
+ dx = x10 - x11,
+ dy = y10 - y11,
+ d2 = dx * dx + dy * dy,
+ r = r1 - rc,
+ D = x11 * y10 - x10 * y11,
+ d = (dy < 0 ? -1 : 1) * sqrt(max(0, r * r * d2 - D * D)),
+ cx0 = (D * dy - dx * d) / d2,
+ cy0 = (-D * dx - dy * d) / d2,
+ cx1 = (D * dy + dx * d) / d2,
+ cy1 = (-D * dx + dy * d) / d2,
+ dx0 = cx0 - x00,
+ dy0 = cy0 - y00,
+ dx1 = cx1 - x00,
+ dy1 = cy1 - y00;
+
+ // Pick the closer of the two intersection points.
+ // TODO Is there a faster way to determine which intersection to use?
+ if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1;
+
+ return {
+ cx: cx0,
+ cy: cy0,
+ x01: -ox,
+ y01: -oy,
+ x11: cx0 * (r1 / r - 1),
+ y11: cy0 * (r1 / r - 1)
+ };
+}
+
+export default function() {
+ var innerRadius = arcInnerRadius,
+ outerRadius = arcOuterRadius,
+ cornerRadius = constant(0),
+ padRadius = null,
+ startAngle = arcStartAngle,
+ endAngle = arcEndAngle,
+ padAngle = arcPadAngle,
+ context = null;
+
+ function arc() {
+ var buffer,
+ r,
+ r0 = +innerRadius.apply(this, arguments),
+ r1 = +outerRadius.apply(this, arguments),
+ a0 = startAngle.apply(this, arguments) - halfPi,
+ a1 = endAngle.apply(this, arguments) - halfPi,
+ da = abs(a1 - a0),
+ cw = a1 > a0;
+
+ if (!context) context = buffer = path();
+
+ // Ensure that the outer radius is always larger than the inner radius.
+ if (r1 < r0) r = r1, r1 = r0, r0 = r;
+
+ // Is it a point?
+ if (!(r1 > epsilon)) context.moveTo(0, 0);
+
+ // Or is it a circle or annulus?
+ else if (da > tau - epsilon) {
+ context.moveTo(r1 * cos(a0), r1 * sin(a0));
+ context.arc(0, 0, r1, a0, a1, !cw);
+ if (r0 > epsilon) {
+ context.moveTo(r0 * cos(a1), r0 * sin(a1));
+ context.arc(0, 0, r0, a1, a0, cw);
+ }
+ }
+
+ // Or is it a circular or annular sector?
+ else {
+ var a01 = a0,
+ a11 = a1,
+ a00 = a0,
+ a10 = a1,
+ da0 = da,
+ da1 = da,
+ ap = padAngle.apply(this, arguments) / 2,
+ rp = (ap > epsilon) && (padRadius ? +padRadius.apply(this, arguments) : sqrt(r0 * r0 + r1 * r1)),
+ rc = min(abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)),
+ rc0 = rc,
+ rc1 = rc,
+ t0,
+ t1;
+
+ // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0.
+ if (rp > epsilon) {
+ var p0 = asin(rp / r0 * sin(ap)),
+ p1 = asin(rp / r1 * sin(ap));
+ if ((da0 -= p0 * 2) > epsilon) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0;
+ else da0 = 0, a00 = a10 = (a0 + a1) / 2;
+ if ((da1 -= p1 * 2) > epsilon) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1;
+ else da1 = 0, a01 = a11 = (a0 + a1) / 2;
+ }
+
+ var x01 = r1 * cos(a01),
+ y01 = r1 * sin(a01),
+ x10 = r0 * cos(a10),
+ y10 = r0 * sin(a10);
+
+ // Apply rounded corners?
+ if (rc > epsilon) {
+ var x11 = r1 * cos(a11),
+ y11 = r1 * sin(a11),
+ x00 = r0 * cos(a00),
+ y00 = r0 * sin(a00),
+ oc;
+
+ // Restrict the corner radius according to the sector angle.
+ if (da < pi && (oc = intersect(x01, y01, x00, y00, x11, y11, x10, y10))) {
+ var ax = x01 - oc[0],
+ ay = y01 - oc[1],
+ bx = x11 - oc[0],
+ by = y11 - oc[1],
+ kc = 1 / sin(acos((ax * bx + ay * by) / (sqrt(ax * ax + ay * ay) * sqrt(bx * bx + by * by))) / 2),
+ lc = sqrt(oc[0] * oc[0] + oc[1] * oc[1]);
+ rc0 = min(rc, (r0 - lc) / (kc - 1));
+ rc1 = min(rc, (r1 - lc) / (kc + 1));
+ }
+ }
+
+ // Is the sector collapsed to a line?
+ if (!(da1 > epsilon)) context.moveTo(x01, y01);
+
+ // Does the sector’s outer ring have rounded corners?
+ else if (rc1 > epsilon) {
+ t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw);
+ t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw);
+
+ context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01);
+
+ // Have the corners merged?
+ if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);
+
+ // Otherwise, draw the two corners and the ring.
+ else {
+ context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);
+ context.arc(0, 0, r1, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw);
+ context.arc(t1.cx, t1.cy, rc1, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);
+ }
+ }
+
+ // Or is the outer ring just a circular arc?
+ else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw);
+
+ // Is there no inner ring, and it’s a circular sector?
+ // Or perhaps it’s an annular sector collapsed due to padding?
+ if (!(r0 > epsilon) || !(da0 > epsilon)) context.lineTo(x10, y10);
+
+ // Does the sector’s inner ring (or point) have rounded corners?
+ else if (rc0 > epsilon) {
+ t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw);
+ t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw);
+
+ context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01);
+
+ // Have the corners merged?
+ if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw);
+
+ // Otherwise, draw the two corners and the ring.
+ else {
+ context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw);
+ context.arc(0, 0, r0, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw);
+ context.arc(t1.cx, t1.cy, rc0, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw);
+ }
+ }
+
+ // Or is the inner ring just a circular arc?
+ else context.arc(0, 0, r0, a10, a00, cw);
+ }
+
+ context.closePath();
+
+ if (buffer) return context = null, buffer + "" || null;
+ }
+
+ arc.centroid = function() {
+ var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2,
+ a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi / 2;
+ return [cos(a) * r, sin(a) * r];
+ };
+
+ arc.innerRadius = function(_) {
+ return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant(+_), arc) : innerRadius;
+ };
+
+ arc.outerRadius = function(_) {
+ return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant(+_), arc) : outerRadius;
+ };
+
+ arc.cornerRadius = function(_) {
+ return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant(+_), arc) : cornerRadius;
+ };
+
+ arc.padRadius = function(_) {
+ return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant(+_), arc) : padRadius;
+ };
+
+ arc.startAngle = function(_) {
+ return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant(+_), arc) : startAngle;
+ };
+
+ arc.endAngle = function(_) {
+ return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant(+_), arc) : endAngle;
+ };
+
+ arc.padAngle = function(_) {
+ return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant(+_), arc) : padAngle;
+ };
+
+ arc.context = function(_) {
+ return arguments.length ? ((context = _ == null ? null : _), arc) : context;
+ };
+
+ return arc;
+}
diff --git a/node_modules/d3-shape/src/area.js b/node_modules/d3-shape/src/area.js
new file mode 100644
index 00000000..8726630a
--- /dev/null
+++ b/node_modules/d3-shape/src/area.js
@@ -0,0 +1,111 @@
+import {path} from "d3-path";
+import array from "./array.js";
+import constant from "./constant.js";
+import curveLinear from "./curve/linear.js";
+import line from "./line.js";
+import {x as pointX, y as pointY} from "./point.js";
+
+export default function(x0, y0, y1) {
+ var x1 = null,
+ defined = constant(true),
+ context = null,
+ curve = curveLinear,
+ output = null;
+
+ x0 = typeof x0 === "function" ? x0 : (x0 === undefined) ? pointX : constant(+x0);
+ y0 = typeof y0 === "function" ? y0 : (y0 === undefined) ? constant(0) : constant(+y0);
+ y1 = typeof y1 === "function" ? y1 : (y1 === undefined) ? pointY : constant(+y1);
+
+ function area(data) {
+ var i,
+ j,
+ k,
+ n = (data = array(data)).length,
+ d,
+ defined0 = false,
+ buffer,
+ x0z = new Array(n),
+ y0z = new Array(n);
+
+ if (context == null) output = curve(buffer = path());
+
+ for (i = 0; i <= n; ++i) {
+ if (!(i < n && defined(d = data[i], i, data)) === defined0) {
+ if (defined0 = !defined0) {
+ j = i;
+ output.areaStart();
+ output.lineStart();
+ } else {
+ output.lineEnd();
+ output.lineStart();
+ for (k = i - 1; k >= j; --k) {
+ output.point(x0z[k], y0z[k]);
+ }
+ output.lineEnd();
+ output.areaEnd();
+ }
+ }
+ if (defined0) {
+ x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data);
+ output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]);
+ }
+ }
+
+ if (buffer) return output = null, buffer + "" || null;
+ }
+
+ function arealine() {
+ return line().defined(defined).curve(curve).context(context);
+ }
+
+ area.x = function(_) {
+ return arguments.length ? (x0 = typeof _ === "function" ? _ : constant(+_), x1 = null, area) : x0;
+ };
+
+ area.x0 = function(_) {
+ return arguments.length ? (x0 = typeof _ === "function" ? _ : constant(+_), area) : x0;
+ };
+
+ area.x1 = function(_) {
+ return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant(+_), area) : x1;
+ };
+
+ area.y = function(_) {
+ return arguments.length ? (y0 = typeof _ === "function" ? _ : constant(+_), y1 = null, area) : y0;
+ };
+
+ area.y0 = function(_) {
+ return arguments.length ? (y0 = typeof _ === "function" ? _ : constant(+_), area) : y0;
+ };
+
+ area.y1 = function(_) {
+ return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant(+_), area) : y1;
+ };
+
+ area.lineX0 =
+ area.lineY0 = function() {
+ return arealine().x(x0).y(y0);
+ };
+
+ area.lineY1 = function() {
+ return arealine().x(x0).y(y1);
+ };
+
+ area.lineX1 = function() {
+ return arealine().x(x1).y(y0);
+ };
+
+ area.defined = function(_) {
+ return arguments.length ? (defined = typeof _ === "function" ? _ : constant(!!_), area) : defined;
+ };
+
+ area.curve = function(_) {
+ return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve;
+ };
+
+ area.context = function(_) {
+ return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context;
+ };
+
+ return area;
+}
diff --git a/node_modules/d3-shape/src/areaRadial.js b/node_modules/d3-shape/src/areaRadial.js
new file mode 100644
index 00000000..61e01d78
--- /dev/null
+++ b/node_modules/d3-shape/src/areaRadial.js
@@ -0,0 +1,29 @@
+import curveRadial, {curveRadialLinear} from "./curve/radial.js";
+import area from "./area.js";
+import {lineRadial} from "./lineRadial.js";
+
+export default function() {
+ var a = area().curve(curveRadialLinear),
+ c = a.curve,
+ x0 = a.lineX0,
+ x1 = a.lineX1,
+ y0 = a.lineY0,
+ y1 = a.lineY1;
+
+ a.angle = a.x, delete a.x;
+ a.startAngle = a.x0, delete a.x0;
+ a.endAngle = a.x1, delete a.x1;
+ a.radius = a.y, delete a.y;
+ a.innerRadius = a.y0, delete a.y0;
+ a.outerRadius = a.y1, delete a.y1;
+ a.lineStartAngle = function() { return lineRadial(x0()); }, delete a.lineX0;
+ a.lineEndAngle = function() { return lineRadial(x1()); }, delete a.lineX1;
+ a.lineInnerRadius = function() { return lineRadial(y0()); }, delete a.lineY0;
+ a.lineOuterRadius = function() { return lineRadial(y1()); }, delete a.lineY1;
+
+ a.curve = function(_) {
+ return arguments.length ? c(curveRadial(_)) : c()._curve;
+ };
+
+ return a;
+}
diff --git a/node_modules/d3-shape/src/array.js b/node_modules/d3-shape/src/array.js
new file mode 100644
index 00000000..90808ffe
--- /dev/null
+++ b/node_modules/d3-shape/src/array.js
@@ -0,0 +1,7 @@
+export var slice = Array.prototype.slice;
+
+export default function(x) {
+ return typeof x === "object" && "length" in x
+ ? x // Array, TypedArray, NodeList, array-like
+ : Array.from(x); // Map, Set, iterable, string, or anything else
+}
diff --git a/node_modules/d3-shape/src/constant.js b/node_modules/d3-shape/src/constant.js
new file mode 100644
index 00000000..6fa95b71
--- /dev/null
+++ b/node_modules/d3-shape/src/constant.js
@@ -0,0 +1,5 @@
+export default function(x) {
+ return function constant() {
+ return x;
+ };
+}
diff --git a/node_modules/d3-shape/src/curve/basis.js b/node_modules/d3-shape/src/curve/basis.js
new file mode 100644
index 00000000..e6b1ea3c
--- /dev/null
+++ b/node_modules/d3-shape/src/curve/basis.js
@@ -0,0 +1,51 @@
+export function point(that, x, y) {
+ that._context.bezierCurveTo(
+ (2 * that._x0 + that._x1) / 3,
+ (2 * that._y0 + that._y1) / 3,
+ (that._x0 + 2 * that._x1) / 3,
+ (that._y0 + 2 * that._y1) / 3,
+ (that._x0 + 4 * that._x1 + x) / 6,
+ (that._y0 + 4 * that._y1 + y) / 6
+ );
+}
+
+export function Basis(context) {
+ this._context = context;
+}
+
+Basis.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._x0 = this._x1 =
+ this._y0 = this._y1 = NaN;
+ this._point = 0;
+ },
+ lineEnd: function() {
+ switch (this._point) {
+ case 3: point(this, this._x1, this._y1); // falls through
+ case 2: this._context.lineTo(this._x1, this._y1); break;
+ }
+ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
+ this._line = 1 - this._line;
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+ switch (this._point) {
+ case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
+ case 1: this._point = 2; break;
+ case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // falls through
+ default: point(this, x, y); break;
+ }
+ this._x0 = this._x1, this._x1 = x;
+ this._y0 = this._y1, this._y1 = y;
+ }
+};
+
+export default function(context) {
+ return new Basis(context);
+}
diff --git a/node_modules/d3-shape/src/curve/basisClosed.js b/node_modules/d3-shape/src/curve/basisClosed.js
new file mode 100644
index 00000000..535df90f
--- /dev/null
+++ b/node_modules/d3-shape/src/curve/basisClosed.js
@@ -0,0 +1,52 @@
+import noop from "../noop.js";
+import {point} from "./basis.js";
+
+function BasisClosed(context) {
+ this._context = context;
+}
+
+BasisClosed.prototype = {
+ areaStart: noop,
+ areaEnd: noop,
+ lineStart: function() {
+ this._x0 = this._x1 = this._x2 = this._x3 = this._x4 =
+ this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN;
+ this._point = 0;
+ },
+ lineEnd: function() {
+ switch (this._point) {
+ case 1: {
+ this._context.moveTo(this._x2, this._y2);
+ this._context.closePath();
+ break;
+ }
+ case 2: {
+ this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3);
+ this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3);
+ this._context.closePath();
+ break;
+ }
+ case 3: {
+ this.point(this._x2, this._y2);
+ this.point(this._x3, this._y3);
+ this.point(this._x4, this._y4);
+ break;
+ }
+ }
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+ switch (this._point) {
+ case 0: this._point = 1; this._x2 = x, this._y2 = y; break;
+ case 1: this._point = 2; this._x3 = x, this._y3 = y; break;
+ case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break;
+ default: point(this, x, y); break;
+ }
+ this._x0 = this._x1, this._x1 = x;
+ this._y0 = this._y1, this._y1 = y;
+ }
+};
+
+export default function(context) {
+ return new BasisClosed(context);
+}
diff --git a/node_modules/d3-shape/src/curve/basisOpen.js b/node_modules/d3-shape/src/curve/basisOpen.js
new file mode 100644
index 00000000..4ef5343b
--- /dev/null
+++ b/node_modules/d3-shape/src/curve/basisOpen.js
@@ -0,0 +1,39 @@
+import {point} from "./basis.js";
+
+function BasisOpen(context) {
+ this._context = context;
+}
+
+BasisOpen.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._x0 = this._x1 =
+ this._y0 = this._y1 = NaN;
+ this._point = 0;
+ },
+ lineEnd: function() {
+ if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
+ this._line = 1 - this._line;
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+ switch (this._point) {
+ case 0: this._point = 1; break;
+ case 1: this._point = 2; break;
+ case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break;
+ case 3: this._point = 4; // falls through
+ default: point(this, x, y); break;
+ }
+ this._x0 = this._x1, this._x1 = x;
+ this._y0 = this._y1, this._y1 = y;
+ }
+};
+
+export default function(context) {
+ return new BasisOpen(context);
+}
diff --git a/node_modules/d3-shape/src/curve/bump.js b/node_modules/d3-shape/src/curve/bump.js
new file mode 100644
index 00000000..8c5cab17
--- /dev/null
+++ b/node_modules/d3-shape/src/curve/bump.js
@@ -0,0 +1,74 @@
+import pointRadial from "../pointRadial.js";
+
+class Bump {
+ constructor(context, x) {
+ this._context = context;
+ this._x = x;
+ }
+ areaStart() {
+ this._line = 0;
+ }
+ areaEnd() {
+ this._line = NaN;
+ }
+ lineStart() {
+ this._point = 0;
+ }
+ lineEnd() {
+ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
+ this._line = 1 - this._line;
+ }
+ point(x, y) {
+ x = +x, y = +y;
+ switch (this._point) {
+ case 0: {
+ this._point = 1;
+ if (this._line) this._context.lineTo(x, y);
+ else this._context.moveTo(x, y);
+ break;
+ }
+ case 1: this._point = 2; // falls through
+ default: {
+ if (this._x) this._context.bezierCurveTo(this._x0 = (this._x0 + x) / 2, this._y0, this._x0, y, x, y);
+ else this._context.bezierCurveTo(this._x0, this._y0 = (this._y0 + y) / 2, x, this._y0, x, y);
+ break;
+ }
+ }
+ this._x0 = x, this._y0 = y;
+ }
+}
+
+class BumpRadial {
+ constructor(context) {
+ this._context = context;
+ }
+ lineStart() {
+ this._point = 0;
+ }
+ lineEnd() {}
+ point(x, y) {
+ x = +x, y = +y;
+ if (this._point++ === 0) {
+ this._x0 = x, this._y0 = y;
+ } else {
+ const p0 = pointRadial(this._x0, this._y0);
+ const p1 = pointRadial(this._x0, this._y0 = (this._y0 + y) / 2);
+ const p2 = pointRadial(x, this._y0);
+ const p3 = pointRadial(x, y);
+ this._context.moveTo(...p0);
+ this._context.bezierCurveTo(...p1, ...p2, ...p3);
+ }
+ }
+}
+
+export function bumpX(context) {
+ return new Bump(context, true);
+}
+
+export function bumpY(context) {
+ return new Bump(context, false);
+}
+
+export function bumpRadial(context) {
+ return new BumpRadial(context);
+}
diff --git a/node_modules/d3-shape/src/curve/bundle.js b/node_modules/d3-shape/src/curve/bundle.js
new file mode 100644
index 00000000..ac1014eb
--- /dev/null
+++ b/node_modules/d3-shape/src/curve/bundle.js
@@ -0,0 +1,56 @@
+import {Basis} from "./basis.js";
+
+function Bundle(context, beta) {
+ this._basis = new Basis(context);
+ this._beta = beta;
+}
+
+Bundle.prototype = {
+ lineStart: function() {
+ this._x = [];
+ this._y = [];
+ this._basis.lineStart();
+ },
+ lineEnd: function() {
+ var x = this._x,
+ y = this._y,
+ j = x.length - 1;
+
+ if (j > 0) {
+ var x0 = x[0],
+ y0 = y[0],
+ dx = x[j] - x0,
+ dy = y[j] - y0,
+ i = -1,
+ t;
+
+ while (++i <= j) {
+ t = i / j;
+ this._basis.point(
+ this._beta * x[i] + (1 - this._beta) * (x0 + t * dx),
+ this._beta * y[i] + (1 - this._beta) * (y0 + t * dy)
+ );
+ }
+ }
+
+ this._x = this._y = null;
+ this._basis.lineEnd();
+ },
+ point: function(x, y) {
+ this._x.push(+x);
+ this._y.push(+y);
+ }
+};
+
+export default (function custom(beta) {
+
+ function bundle(context) {
+ return beta === 1 ? new Basis(context) : new Bundle(context, beta);
+ }
+
+ bundle.beta = function(beta) {
+ return custom(+beta);
+ };
+
+ return bundle;
+})(0.85);
diff --git a/node_modules/d3-shape/src/curve/cardinal.js b/node_modules/d3-shape/src/curve/cardinal.js
new file mode 100644
index 00000000..7e64c14c
--- /dev/null
+++ b/node_modules/d3-shape/src/curve/cardinal.js
@@ -0,0 +1,61 @@
+export function point(that, x, y) {
+ that._context.bezierCurveTo(
+ that._x1 + that._k * (that._x2 - that._x0),
+ that._y1 + that._k * (that._y2 - that._y0),
+ that._x2 + that._k * (that._x1 - x),
+ that._y2 + that._k * (that._y1 - y),
+ that._x2,
+ that._y2
+ );
+}
+
+export function Cardinal(context, tension) {
+ this._context = context;
+ this._k = (1 - tension) / 6;
+}
+
+Cardinal.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._x0 = this._x1 = this._x2 =
+ this._y0 = this._y1 = this._y2 = NaN;
+ this._point = 0;
+ },
+ lineEnd: function() {
+ switch (this._point) {
+ case 2: this._context.lineTo(this._x2, this._y2); break;
+ case 3: point(this, this._x1, this._y1); break;
+ }
+ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
+ this._line = 1 - this._line;
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+ switch (this._point) {
+ case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
+ case 1: this._point = 2; this._x1 = x, this._y1 = y; break;
+ case 2: this._point = 3; // falls through
+ default: point(this, x, y); break;
+ }
+ this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
+ this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
+ }
+};
+
+export default (function custom(tension) {
+
+ function cardinal(context) {
+ return new Cardinal(context, tension);
+ }
+
+ cardinal.tension = function(tension) {
+ return custom(+tension);
+ };
+
+ return cardinal;
+})(0);
diff --git a/node_modules/d3-shape/src/curve/cardinalClosed.js b/node_modules/d3-shape/src/curve/cardinalClosed.js
new file mode 100644
index 00000000..acef52e3
--- /dev/null
+++ b/node_modules/d3-shape/src/curve/cardinalClosed.js
@@ -0,0 +1,61 @@
+import noop from "../noop.js";
+import {point} from "./cardinal.js";
+
+export function CardinalClosed(context, tension) {
+ this._context = context;
+ this._k = (1 - tension) / 6;
+}
+
+CardinalClosed.prototype = {
+ areaStart: noop,
+ areaEnd: noop,
+ lineStart: function() {
+ this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
+ this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
+ this._point = 0;
+ },
+ lineEnd: function() {
+ switch (this._point) {
+ case 1: {
+ this._context.moveTo(this._x3, this._y3);
+ this._context.closePath();
+ break;
+ }
+ case 2: {
+ this._context.lineTo(this._x3, this._y3);
+ this._context.closePath();
+ break;
+ }
+ case 3: {
+ this.point(this._x3, this._y3);
+ this.point(this._x4, this._y4);
+ this.point(this._x5, this._y5);
+ break;
+ }
+ }
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+ switch (this._point) {
+ case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
+ case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
+ case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
+ default: point(this, x, y); break;
+ }
+ this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
+ this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
+ }
+};
+
+export default (function custom(tension) {
+
+ function cardinal(context) {
+ return new CardinalClosed(context, tension);
+ }
+
+ cardinal.tension = function(tension) {
+ return custom(+tension);
+ };
+
+ return cardinal;
+})(0);
diff --git a/node_modules/d3-shape/src/curve/cardinalOpen.js b/node_modules/d3-shape/src/curve/cardinalOpen.js
new file mode 100644
index 00000000..f73ac8b0
--- /dev/null
+++ b/node_modules/d3-shape/src/curve/cardinalOpen.js
@@ -0,0 +1,49 @@
+import {point} from "./cardinal.js";
+
+export function CardinalOpen(context, tension) {
+ this._context = context;
+ this._k = (1 - tension) / 6;
+}
+
+CardinalOpen.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._x0 = this._x1 = this._x2 =
+ this._y0 = this._y1 = this._y2 = NaN;
+ this._point = 0;
+ },
+ lineEnd: function() {
+ if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
+ this._line = 1 - this._line;
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+ switch (this._point) {
+ case 0: this._point = 1; break;
+ case 1: this._point = 2; break;
+ case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
+ case 3: this._point = 4; // falls through
+ default: point(this, x, y); break;
+ }
+ this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
+ this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
+ }
+};
+
+export default (function custom(tension) {
+
+ function cardinal(context) {
+ return new CardinalOpen(context, tension);
+ }
+
+ cardinal.tension = function(tension) {
+ return custom(+tension);
+ };
+
+ return cardinal;
+})(0);
diff --git a/node_modules/d3-shape/src/curve/catmullRom.js b/node_modules/d3-shape/src/curve/catmullRom.js
new file mode 100644
index 00000000..3a4b1a75
--- /dev/null
+++ b/node_modules/d3-shape/src/curve/catmullRom.js
@@ -0,0 +1,88 @@
+import {epsilon} from "../math.js";
+import {Cardinal} from "./cardinal.js";
+
+export function point(that, x, y) {
+ var x1 = that._x1,
+ y1 = that._y1,
+ x2 = that._x2,
+ y2 = that._y2;
+
+ if (that._l01_a > epsilon) {
+ var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a,
+ n = 3 * that._l01_a * (that._l01_a + that._l12_a);
+ x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n;
+ y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n;
+ }
+
+ if (that._l23_a > epsilon) {
+ var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a,
+ m = 3 * that._l23_a * (that._l23_a + that._l12_a);
+ x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m;
+ y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m;
+ }
+
+ that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2);
+}
+
+function CatmullRom(context, alpha) {
+ this._context = context;
+ this._alpha = alpha;
+}
+
+CatmullRom.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._x0 = this._x1 = this._x2 =
+ this._y0 = this._y1 = this._y2 = NaN;
+ this._l01_a = this._l12_a = this._l23_a =
+ this._l01_2a = this._l12_2a = this._l23_2a =
+ this._point = 0;
+ },
+ lineEnd: function() {
+ switch (this._point) {
+ case 2: this._context.lineTo(this._x2, this._y2); break;
+ case 3: this.point(this._x2, this._y2); break;
+ }
+ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
+ this._line = 1 - this._line;
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+
+ if (this._point) {
+ var x23 = this._x2 - x,
+ y23 = this._y2 - y;
+ this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
+ }
+
+ switch (this._point) {
+ case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
+ case 1: this._point = 2; break;
+ case 2: this._point = 3; // falls through
+ default: point(this, x, y); break;
+ }
+
+ this._l01_a = this._l12_a, this._l12_a = this._l23_a;
+ this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
+ this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
+ this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
+ }
+};
+
+export default (function custom(alpha) {
+
+ function catmullRom(context) {
+ return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0);
+ }
+
+ catmullRom.alpha = function(alpha) {
+ return custom(+alpha);
+ };
+
+ return catmullRom;
+})(0.5);
diff --git a/node_modules/d3-shape/src/curve/catmullRomClosed.js b/node_modules/d3-shape/src/curve/catmullRomClosed.js
new file mode 100644
index 00000000..6c6b9655
--- /dev/null
+++ b/node_modules/d3-shape/src/curve/catmullRomClosed.js
@@ -0,0 +1,74 @@
+import {CardinalClosed} from "./cardinalClosed.js";
+import noop from "../noop.js";
+import {point} from "./catmullRom.js";
+
+function CatmullRomClosed(context, alpha) {
+ this._context = context;
+ this._alpha = alpha;
+}
+
+CatmullRomClosed.prototype = {
+ areaStart: noop,
+ areaEnd: noop,
+ lineStart: function() {
+ this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 =
+ this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN;
+ this._l01_a = this._l12_a = this._l23_a =
+ this._l01_2a = this._l12_2a = this._l23_2a =
+ this._point = 0;
+ },
+ lineEnd: function() {
+ switch (this._point) {
+ case 1: {
+ this._context.moveTo(this._x3, this._y3);
+ this._context.closePath();
+ break;
+ }
+ case 2: {
+ this._context.lineTo(this._x3, this._y3);
+ this._context.closePath();
+ break;
+ }
+ case 3: {
+ this.point(this._x3, this._y3);
+ this.point(this._x4, this._y4);
+ this.point(this._x5, this._y5);
+ break;
+ }
+ }
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+
+ if (this._point) {
+ var x23 = this._x2 - x,
+ y23 = this._y2 - y;
+ this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
+ }
+
+ switch (this._point) {
+ case 0: this._point = 1; this._x3 = x, this._y3 = y; break;
+ case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break;
+ case 2: this._point = 3; this._x5 = x, this._y5 = y; break;
+ default: point(this, x, y); break;
+ }
+
+ this._l01_a = this._l12_a, this._l12_a = this._l23_a;
+ this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
+ this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
+ this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
+ }
+};
+
+export default (function custom(alpha) {
+
+ function catmullRom(context) {
+ return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0);
+ }
+
+ catmullRom.alpha = function(alpha) {
+ return custom(+alpha);
+ };
+
+ return catmullRom;
+})(0.5);
diff --git a/node_modules/d3-shape/src/curve/catmullRomOpen.js b/node_modules/d3-shape/src/curve/catmullRomOpen.js
new file mode 100644
index 00000000..a372a70d
--- /dev/null
+++ b/node_modules/d3-shape/src/curve/catmullRomOpen.js
@@ -0,0 +1,62 @@
+import {CardinalOpen} from "./cardinalOpen.js";
+import {point} from "./catmullRom.js";
+
+function CatmullRomOpen(context, alpha) {
+ this._context = context;
+ this._alpha = alpha;
+}
+
+CatmullRomOpen.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._x0 = this._x1 = this._x2 =
+ this._y0 = this._y1 = this._y2 = NaN;
+ this._l01_a = this._l12_a = this._l23_a =
+ this._l01_2a = this._l12_2a = this._l23_2a =
+ this._point = 0;
+ },
+ lineEnd: function() {
+ if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath();
+ this._line = 1 - this._line;
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+
+ if (this._point) {
+ var x23 = this._x2 - x,
+ y23 = this._y2 - y;
+ this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha));
+ }
+
+ switch (this._point) {
+ case 0: this._point = 1; break;
+ case 1: this._point = 2; break;
+ case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break;
+ case 3: this._point = 4; // falls through
+ default: point(this, x, y); break;
+ }
+
+ this._l01_a = this._l12_a, this._l12_a = this._l23_a;
+ this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a;
+ this._x0 = this._x1, this._x1 = this._x2, this._x2 = x;
+ this._y0 = this._y1, this._y1 = this._y2, this._y2 = y;
+ }
+};
+
+export default (function custom(alpha) {
+
+ function catmullRom(context) {
+ return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0);
+ }
+
+ catmullRom.alpha = function(alpha) {
+ return custom(+alpha);
+ };
+
+ return catmullRom;
+})(0.5);
diff --git a/node_modules/d3-shape/src/curve/linear.js b/node_modules/d3-shape/src/curve/linear.js
new file mode 100644
index 00000000..68e169ad
--- /dev/null
+++ b/node_modules/d3-shape/src/curve/linear.js
@@ -0,0 +1,31 @@
+function Linear(context) {
+ this._context = context;
+}
+
+Linear.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._point = 0;
+ },
+ lineEnd: function() {
+ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
+ this._line = 1 - this._line;
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+ switch (this._point) {
+ case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
+ case 1: this._point = 2; // falls through
+ default: this._context.lineTo(x, y); break;
+ }
+ }
+};
+
+export default function(context) {
+ return new Linear(context);
+}
diff --git a/node_modules/d3-shape/src/curve/linearClosed.js b/node_modules/d3-shape/src/curve/linearClosed.js
new file mode 100644
index 00000000..e25606ff
--- /dev/null
+++ b/node_modules/d3-shape/src/curve/linearClosed.js
@@ -0,0 +1,25 @@
+import noop from "../noop.js";
+
+function LinearClosed(context) {
+ this._context = context;
+}
+
+LinearClosed.prototype = {
+ areaStart: noop,
+ areaEnd: noop,
+ lineStart: function() {
+ this._point = 0;
+ },
+ lineEnd: function() {
+ if (this._point) this._context.closePath();
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+ if (this._point) this._context.lineTo(x, y);
+ else this._point = 1, this._context.moveTo(x, y);
+ }
+};
+
+export default function(context) {
+ return new LinearClosed(context);
+}
diff --git a/node_modules/d3-shape/src/curve/monotone.js b/node_modules/d3-shape/src/curve/monotone.js
new file mode 100644
index 00000000..2599031c
--- /dev/null
+++ b/node_modules/d3-shape/src/curve/monotone.js
@@ -0,0 +1,104 @@
+function sign(x) {
+ return x < 0 ? -1 : 1;
+}
+
+// Calculate the slopes of the tangents (Hermite-type interpolation) based on
+// the following paper: Steffen, M. 1990. A Simple Method for Monotonic
+// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO.
+// NOV(II), P. 443, 1990.
+function slope3(that, x2, y2) {
+ var h0 = that._x1 - that._x0,
+ h1 = x2 - that._x1,
+ s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0),
+ s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0),
+ p = (s0 * h1 + s1 * h0) / (h0 + h1);
+ return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0;
+}
+
+// Calculate a one-sided slope.
+function slope2(that, t) {
+ var h = that._x1 - that._x0;
+ return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t;
+}
+
+// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations
+// "you can express cubic Hermite interpolation in terms of cubic Bézier curves
+// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1".
+function point(that, t0, t1) {
+ var x0 = that._x0,
+ y0 = that._y0,
+ x1 = that._x1,
+ y1 = that._y1,
+ dx = (x1 - x0) / 3;
+ that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1);
+}
+
+function MonotoneX(context) {
+ this._context = context;
+}
+
+MonotoneX.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._x0 = this._x1 =
+ this._y0 = this._y1 =
+ this._t0 = NaN;
+ this._point = 0;
+ },
+ lineEnd: function() {
+ switch (this._point) {
+ case 2: this._context.lineTo(this._x1, this._y1); break;
+ case 3: point(this, this._t0, slope2(this, this._t0)); break;
+ }
+ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
+ this._line = 1 - this._line;
+ },
+ point: function(x, y) {
+ var t1 = NaN;
+
+ x = +x, y = +y;
+ if (x === this._x1 && y === this._y1) return; // Ignore coincident points.
+ switch (this._point) {
+ case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
+ case 1: this._point = 2; break;
+ case 2: this._point = 3; point(this, slope2(this, t1 = slope3(this, x, y)), t1); break;
+ default: point(this, this._t0, t1 = slope3(this, x, y)); break;
+ }
+
+ this._x0 = this._x1, this._x1 = x;
+ this._y0 = this._y1, this._y1 = y;
+ this._t0 = t1;
+ }
+}
+
+function MonotoneY(context) {
+ this._context = new ReflectContext(context);
+}
+
+(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) {
+ MonotoneX.prototype.point.call(this, y, x);
+};
+
+function ReflectContext(context) {
+ this._context = context;
+}
+
+ReflectContext.prototype = {
+ moveTo: function(x, y) { this._context.moveTo(y, x); },
+ closePath: function() { this._context.closePath(); },
+ lineTo: function(x, y) { this._context.lineTo(y, x); },
+ bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); }
+};
+
+export function monotoneX(context) {
+ return new MonotoneX(context);
+}
+
+export function monotoneY(context) {
+ return new MonotoneY(context);
+}
diff --git a/node_modules/d3-shape/src/curve/natural.js b/node_modules/d3-shape/src/curve/natural.js
new file mode 100644
index 00000000..d51eb513
--- /dev/null
+++ b/node_modules/d3-shape/src/curve/natural.js
@@ -0,0 +1,65 @@
+function Natural(context) {
+ this._context = context;
+}
+
+Natural.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._x = [];
+ this._y = [];
+ },
+ lineEnd: function() {
+ var x = this._x,
+ y = this._y,
+ n = x.length;
+
+ if (n) {
+ this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]);
+ if (n === 2) {
+ this._context.lineTo(x[1], y[1]);
+ } else {
+ var px = controlPoints(x),
+ py = controlPoints(y);
+ for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) {
+ this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]);
+ }
+ }
+ }
+
+ if (this._line || (this._line !== 0 && n === 1)) this._context.closePath();
+ this._line = 1 - this._line;
+ this._x = this._y = null;
+ },
+ point: function(x, y) {
+ this._x.push(+x);
+ this._y.push(+y);
+ }
+};
+
+// See https://www.particleincell.com/2012/bezier-splines/ for derivation.
+function controlPoints(x) {
+ var i,
+ n = x.length - 1,
+ m,
+ a = new Array(n),
+ b = new Array(n),
+ r = new Array(n);
+ a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1];
+ for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1];
+ a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n];
+ for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1];
+ a[n - 1] = r[n - 1] / b[n - 1];
+ for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i];
+ b[n - 1] = (x[n] + a[n - 1]) / 2;
+ for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1];
+ return [a, b];
+}
+
+export default function(context) {
+ return new Natural(context);
+}
diff --git a/node_modules/d3-shape/src/curve/radial.js b/node_modules/d3-shape/src/curve/radial.js
new file mode 100644
index 00000000..730c989f
--- /dev/null
+++ b/node_modules/d3-shape/src/curve/radial.js
@@ -0,0 +1,36 @@
+import curveLinear from "./linear.js";
+
+export var curveRadialLinear = curveRadial(curveLinear);
+
+function Radial(curve) {
+ this._curve = curve;
+}
+
+Radial.prototype = {
+ areaStart: function() {
+ this._curve.areaStart();
+ },
+ areaEnd: function() {
+ this._curve.areaEnd();
+ },
+ lineStart: function() {
+ this._curve.lineStart();
+ },
+ lineEnd: function() {
+ this._curve.lineEnd();
+ },
+ point: function(a, r) {
+ this._curve.point(r * Math.sin(a), r * -Math.cos(a));
+ }
+};
+
+export default function curveRadial(curve) {
+
+ function radial(context) {
+ return new Radial(curve(context));
+ }
+
+ radial._curve = curve;
+
+ return radial;
+}
diff --git a/node_modules/d3-shape/src/curve/step.js b/node_modules/d3-shape/src/curve/step.js
new file mode 100644
index 00000000..6f6aa05a
--- /dev/null
+++ b/node_modules/d3-shape/src/curve/step.js
@@ -0,0 +1,53 @@
+function Step(context, t) {
+ this._context = context;
+ this._t = t;
+}
+
+Step.prototype = {
+ areaStart: function() {
+ this._line = 0;
+ },
+ areaEnd: function() {
+ this._line = NaN;
+ },
+ lineStart: function() {
+ this._x = this._y = NaN;
+ this._point = 0;
+ },
+ lineEnd: function() {
+ if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y);
+ if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath();
+ if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line;
+ },
+ point: function(x, y) {
+ x = +x, y = +y;
+ switch (this._point) {
+ case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break;
+ case 1: this._point = 2; // falls through
+ default: {
+ if (this._t <= 0) {
+ this._context.lineTo(this._x, y);
+ this._context.lineTo(x, y);
+ } else {
+ var x1 = this._x * (1 - this._t) + x * this._t;
+ this._context.lineTo(x1, this._y);
+ this._context.lineTo(x1, y);
+ }
+ break;
+ }
+ }
+ this._x = x, this._y = y;
+ }
+};
+
+export default function(context) {
+ return new Step(context, 0.5);
+}
+
+export function stepBefore(context) {
+ return new Step(context, 0);
+}
+
+export function stepAfter(context) {
+ return new Step(context, 1);
+}
diff --git a/node_modules/d3-shape/src/descending.js b/node_modules/d3-shape/src/descending.js
new file mode 100644
index 00000000..a4e2d7fb
--- /dev/null
+++ b/node_modules/d3-shape/src/descending.js
@@ -0,0 +1,3 @@
+export default function(a, b) {
+ return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;
+}
diff --git a/node_modules/d3-shape/src/identity.js b/node_modules/d3-shape/src/identity.js
new file mode 100644
index 00000000..ca161abe
--- /dev/null
+++ b/node_modules/d3-shape/src/identity.js
@@ -0,0 +1,3 @@
+export default function(d) {
+ return d;
+}
diff --git a/node_modules/d3-shape/src/index.js b/node_modules/d3-shape/src/index.js
new file mode 100644
index 00000000..5bc320f8
--- /dev/null
+++ b/node_modules/d3-shape/src/index.js
@@ -0,0 +1,53 @@
+export {default as arc} from "./arc.js";
+export {default as area} from "./area.js";
+export {default as line} from "./line.js";
+export {default as pie} from "./pie.js";
+export {default as areaRadial, default as radialArea} from "./areaRadial.js"; // Note: radialArea is deprecated!
+export {default as lineRadial, default as radialLine} from "./lineRadial.js"; // Note: radialLine is deprecated!
+export {default as pointRadial} from "./pointRadial.js";
+export {link, linkHorizontal, linkVertical, linkRadial} from "./link.js";
+
+export {default as symbol, symbolsStroke, symbolsFill, symbolsFill as symbols} from "./symbol.js";
+export {default as symbolAsterisk} from "./symbol/asterisk.js";
+export {default as symbolCircle} from "./symbol/circle.js";
+export {default as symbolCross} from "./symbol/cross.js";
+export {default as symbolDiamond} from "./symbol/diamond.js";
+export {default as symbolDiamond2} from "./symbol/diamond2.js";
+export {default as symbolPlus} from "./symbol/plus.js";
+export {default as symbolSquare} from "./symbol/square.js";
+export {default as symbolSquare2} from "./symbol/square2.js";
+export {default as symbolStar} from "./symbol/star.js";
+export {default as symbolTriangle} from "./symbol/triangle.js";
+export {default as symbolTriangle2} from "./symbol/triangle2.js";
+export {default as symbolWye} from "./symbol/wye.js";
+export {default as symbolX} from "./symbol/x.js";
+
+export {default as curveBasisClosed} from "./curve/basisClosed.js";
+export {default as curveBasisOpen} from "./curve/basisOpen.js";
+export {default as curveBasis} from "./curve/basis.js";
+export {bumpX as curveBumpX, bumpY as curveBumpY} from "./curve/bump.js";
+export {default as curveBundle} from "./curve/bundle.js";
+export {default as curveCardinalClosed} from "./curve/cardinalClosed.js";
+export {default as curveCardinalOpen} from "./curve/cardinalOpen.js";
+export {default as curveCardinal} from "./curve/cardinal.js";
+export {default as curveCatmullRomClosed} from "./curve/catmullRomClosed.js";
+export {default as curveCatmullRomOpen} from "./curve/catmullRomOpen.js";
+export {default as curveCatmullRom} from "./curve/catmullRom.js";
+export {default as curveLinearClosed} from "./curve/linearClosed.js";
+export {default as curveLinear} from "./curve/linear.js";
+export {monotoneX as curveMonotoneX, monotoneY as curveMonotoneY} from "./curve/monotone.js";
+export {default as curveNatural} from "./curve/natural.js";
+export {default as curveStep, stepAfter as curveStepAfter, stepBefore as curveStepBefore} from "./curve/step.js";
+
+export {default as stack} from "./stack.js";
+export {default as stackOffsetExpand} from "./offset/expand.js";
+export {default as stackOffsetDiverging} from "./offset/diverging.js";
+export {default as stackOffsetNone} from "./offset/none.js";
+export {default as stackOffsetSilhouette} from "./offset/silhouette.js";
+export {default as stackOffsetWiggle} from "./offset/wiggle.js";
+export {default as stackOrderAppearance} from "./order/appearance.js";
+export {default as stackOrderAscending} from "./order/ascending.js";
+export {default as stackOrderDescending} from "./order/descending.js";
+export {default as stackOrderInsideOut} from "./order/insideOut.js";
+export {default as stackOrderNone} from "./order/none.js";
+export {default as stackOrderReverse} from "./order/reverse.js";
diff --git a/node_modules/d3-shape/src/line.js b/node_modules/d3-shape/src/line.js
new file mode 100644
index 00000000..1ad92b23
--- /dev/null
+++ b/node_modules/d3-shape/src/line.js
@@ -0,0 +1,57 @@
+import {path} from "d3-path";
+import array from "./array.js";
+import constant from "./constant.js";
+import curveLinear from "./curve/linear.js";
+import {x as pointX, y as pointY} from "./point.js";
+
+export default function(x, y) {
+ var defined = constant(true),
+ context = null,
+ curve = curveLinear,
+ output = null;
+
+ x = typeof x === "function" ? x : (x === undefined) ? pointX : constant(x);
+ y = typeof y === "function" ? y : (y === undefined) ? pointY : constant(y);
+
+ function line(data) {
+ var i,
+ n = (data = array(data)).length,
+ d,
+ defined0 = false,
+ buffer;
+
+ if (context == null) output = curve(buffer = path());
+
+ for (i = 0; i <= n; ++i) {
+ if (!(i < n && defined(d = data[i], i, data)) === defined0) {
+ if (defined0 = !defined0) output.lineStart();
+ else output.lineEnd();
+ }
+ if (defined0) output.point(+x(d, i, data), +y(d, i, data));
+ }
+
+ if (buffer) return output = null, buffer + "" || null;
+ }
+
+ line.x = function(_) {
+ return arguments.length ? (x = typeof _ === "function" ? _ : constant(+_), line) : x;
+ };
+
+ line.y = function(_) {
+ return arguments.length ? (y = typeof _ === "function" ? _ : constant(+_), line) : y;
+ };
+
+ line.defined = function(_) {
+ return arguments.length ? (defined = typeof _ === "function" ? _ : constant(!!_), line) : defined;
+ };
+
+ line.curve = function(_) {
+ return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve;
+ };
+
+ line.context = function(_) {
+ return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context;
+ };
+
+ return line;
+}
diff --git a/node_modules/d3-shape/src/lineRadial.js b/node_modules/d3-shape/src/lineRadial.js
new file mode 100644
index 00000000..beaf5773
--- /dev/null
+++ b/node_modules/d3-shape/src/lineRadial.js
@@ -0,0 +1,19 @@
+import curveRadial, {curveRadialLinear} from "./curve/radial.js";
+import line from "./line.js";
+
+export function lineRadial(l) {
+ var c = l.curve;
+
+ l.angle = l.x, delete l.x;
+ l.radius = l.y, delete l.y;
+
+ l.curve = function(_) {
+ return arguments.length ? c(curveRadial(_)) : c()._curve;
+ };
+
+ return l;
+}
+
+export default function() {
+ return lineRadial(line().curve(curveRadialLinear));
+}
diff --git a/node_modules/d3-shape/src/link.js b/node_modules/d3-shape/src/link.js
new file mode 100644
index 00000000..bb4542ca
--- /dev/null
+++ b/node_modules/d3-shape/src/link.js
@@ -0,0 +1,72 @@
+import {path} from "d3-path";
+import {slice} from "./array.js";
+import constant from "./constant.js";
+import {bumpX, bumpY, bumpRadial} from "./curve/bump.js";
+import {x as pointX, y as pointY} from "./point.js";
+
+function linkSource(d) {
+ return d.source;
+}
+
+function linkTarget(d) {
+ return d.target;
+}
+
+export function link(curve) {
+ let source = linkSource;
+ let target = linkTarget;
+ let x = pointX;
+ let y = pointY;
+ let context = null;
+ let output = null;
+
+ function link() {
+ let buffer;
+ const argv = slice.call(arguments);
+ const s = source.apply(this, argv);
+ const t = target.apply(this, argv);
+ if (context == null) output = curve(buffer = path());
+ output.lineStart();
+ argv[0] = s, output.point(+x.apply(this, argv), +y.apply(this, argv));
+ argv[0] = t, output.point(+x.apply(this, argv), +y.apply(this, argv));
+ output.lineEnd();
+ if (buffer) return output = null, buffer + "" || null;
+ }
+
+ link.source = function(_) {
+ return arguments.length ? (source = _, link) : source;
+ };
+
+ link.target = function(_) {
+ return arguments.length ? (target = _, link) : target;
+ };
+
+ link.x = function(_) {
+ return arguments.length ? (x = typeof _ === "function" ? _ : constant(+_), link) : x;
+ };
+
+ link.y = function(_) {
+ return arguments.length ? (y = typeof _ === "function" ? _ : constant(+_), link) : y;
+ };
+
+ link.context = function(_) {
+ return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), link) : context;
+ };
+
+ return link;
+}
+
+export function linkHorizontal() {
+ return link(bumpX);
+}
+
+export function linkVertical() {
+ return link(bumpY);
+}
+
+export function linkRadial() {
+ const l = link(bumpRadial);
+ l.angle = l.x, delete l.x;
+ l.radius = l.y, delete l.y;
+ return l;
+}
diff --git a/node_modules/d3-shape/src/math.js b/node_modules/d3-shape/src/math.js
new file mode 100644
index 00000000..272303db
--- /dev/null
+++ b/node_modules/d3-shape/src/math.js
@@ -0,0 +1,20 @@
+export const abs = Math.abs;
+export const atan2 = Math.atan2;
+export const cos = Math.cos;
+export const max = Math.max;
+export const min = Math.min;
+export const sin = Math.sin;
+export const sqrt = Math.sqrt;
+
+export const epsilon = 1e-12;
+export const pi = Math.PI;
+export const halfPi = pi / 2;
+export const tau = 2 * pi;
+
+export function acos(x) {
+ return x > 1 ? 0 : x < -1 ? pi : Math.acos(x);
+}
+
+export function asin(x) {
+ return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x);
+}
diff --git a/node_modules/d3-shape/src/noop.js b/node_modules/d3-shape/src/noop.js
new file mode 100644
index 00000000..6ab80bc8
--- /dev/null
+++ b/node_modules/d3-shape/src/noop.js
@@ -0,0 +1 @@
+export default function() {}
diff --git a/node_modules/d3-shape/src/offset/diverging.js b/node_modules/d3-shape/src/offset/diverging.js
new file mode 100644
index 00000000..45a5fff6
--- /dev/null
+++ b/node_modules/d3-shape/src/offset/diverging.js
@@ -0,0 +1,14 @@
+export default function(series, order) {
+ if (!((n = series.length) > 0)) return;
+ for (var i, j = 0, d, dy, yp, yn, n, m = series[order[0]].length; j < m; ++j) {
+ for (yp = yn = 0, i = 0; i < n; ++i) {
+ if ((dy = (d = series[order[i]][j])[1] - d[0]) > 0) {
+ d[0] = yp, d[1] = yp += dy;
+ } else if (dy < 0) {
+ d[1] = yn, d[0] = yn += dy;
+ } else {
+ d[0] = 0, d[1] = dy;
+ }
+ }
+ }
+}
diff --git a/node_modules/d3-shape/src/offset/expand.js b/node_modules/d3-shape/src/offset/expand.js
new file mode 100644
index 00000000..965bea1e
--- /dev/null
+++ b/node_modules/d3-shape/src/offset/expand.js
@@ -0,0 +1,10 @@
+import none from "./none.js";
+
+export default function(series, order) {
+ if (!((n = series.length) > 0)) return;
+ for (var i, n, j = 0, m = series[0].length, y; j < m; ++j) {
+ for (y = i = 0; i < n; ++i) y += series[i][j][1] || 0;
+ if (y) for (i = 0; i < n; ++i) series[i][j][1] /= y;
+ }
+ none(series, order);
+}
diff --git a/node_modules/d3-shape/src/offset/none.js b/node_modules/d3-shape/src/offset/none.js
new file mode 100644
index 00000000..d8e11dcb
--- /dev/null
+++ b/node_modules/d3-shape/src/offset/none.js
@@ -0,0 +1,9 @@
+export default function(series, order) {
+ if (!((n = series.length) > 1)) return;
+ for (var i = 1, j, s0, s1 = series[order[0]], n, m = s1.length; i < n; ++i) {
+ s0 = s1, s1 = series[order[i]];
+ for (j = 0; j < m; ++j) {
+ s1[j][1] += s1[j][0] = isNaN(s0[j][1]) ? s0[j][0] : s0[j][1];
+ }
+ }
+}
diff --git a/node_modules/d3-shape/src/offset/silhouette.js b/node_modules/d3-shape/src/offset/silhouette.js
new file mode 100644
index 00000000..87829bec
--- /dev/null
+++ b/node_modules/d3-shape/src/offset/silhouette.js
@@ -0,0 +1,10 @@
+import none from "./none.js";
+
+export default function(series, order) {
+ if (!((n = series.length) > 0)) return;
+ for (var j = 0, s0 = series[order[0]], n, m = s0.length; j < m; ++j) {
+ for (var i = 0, y = 0; i < n; ++i) y += series[i][j][1] || 0;
+ s0[j][1] += s0[j][0] = -y / 2;
+ }
+ none(series, order);
+}
diff --git a/node_modules/d3-shape/src/offset/wiggle.js b/node_modules/d3-shape/src/offset/wiggle.js
new file mode 100644
index 00000000..8db717cd
--- /dev/null
+++ b/node_modules/d3-shape/src/offset/wiggle.js
@@ -0,0 +1,24 @@
+import none from "./none.js";
+
+export default function(series, order) {
+ if (!((n = series.length) > 0) || !((m = (s0 = series[order[0]]).length) > 0)) return;
+ for (var y = 0, j = 1, s0, m, n; j < m; ++j) {
+ for (var i = 0, s1 = 0, s2 = 0; i < n; ++i) {
+ var si = series[order[i]],
+ sij0 = si[j][1] || 0,
+ sij1 = si[j - 1][1] || 0,
+ s3 = (sij0 - sij1) / 2;
+ for (var k = 0; k < i; ++k) {
+ var sk = series[order[k]],
+ skj0 = sk[j][1] || 0,
+ skj1 = sk[j - 1][1] || 0;
+ s3 += skj0 - skj1;
+ }
+ s1 += sij0, s2 += s3 * sij0;
+ }
+ s0[j - 1][1] += s0[j - 1][0] = y;
+ if (s1) y -= s2 / s1;
+ }
+ s0[j - 1][1] += s0[j - 1][0] = y;
+ none(series, order);
+}
diff --git a/node_modules/d3-shape/src/order/appearance.js b/node_modules/d3-shape/src/order/appearance.js
new file mode 100644
index 00000000..e052924b
--- /dev/null
+++ b/node_modules/d3-shape/src/order/appearance.js
@@ -0,0 +1,12 @@
+import none from "./none.js";
+
+export default function(series) {
+ var peaks = series.map(peak);
+ return none(series).sort(function(a, b) { return peaks[a] - peaks[b]; });
+}
+
+function peak(series) {
+ var i = -1, j = 0, n = series.length, vi, vj = -Infinity;
+ while (++i < n) if ((vi = +series[i][1]) > vj) vj = vi, j = i;
+ return j;
+}
diff --git a/node_modules/d3-shape/src/order/ascending.js b/node_modules/d3-shape/src/order/ascending.js
new file mode 100644
index 00000000..e0d28e3e
--- /dev/null
+++ b/node_modules/d3-shape/src/order/ascending.js
@@ -0,0 +1,12 @@
+import none from "./none.js";
+
+export default function(series) {
+ var sums = series.map(sum);
+ return none(series).sort(function(a, b) { return sums[a] - sums[b]; });
+}
+
+export function sum(series) {
+ var s = 0, i = -1, n = series.length, v;
+ while (++i < n) if (v = +series[i][1]) s += v;
+ return s;
+}
diff --git a/node_modules/d3-shape/src/order/descending.js b/node_modules/d3-shape/src/order/descending.js
new file mode 100644
index 00000000..dd272014
--- /dev/null
+++ b/node_modules/d3-shape/src/order/descending.js
@@ -0,0 +1,5 @@
+import ascending from "./ascending.js";
+
+export default function(series) {
+ return ascending(series).reverse();
+}
diff --git a/node_modules/d3-shape/src/order/insideOut.js b/node_modules/d3-shape/src/order/insideOut.js
new file mode 100644
index 00000000..b0b2abda
--- /dev/null
+++ b/node_modules/d3-shape/src/order/insideOut.js
@@ -0,0 +1,27 @@
+import appearance from "./appearance.js";
+import {sum} from "./ascending.js";
+
+export default function(series) {
+ var n = series.length,
+ i,
+ j,
+ sums = series.map(sum),
+ order = appearance(series),
+ top = 0,
+ bottom = 0,
+ tops = [],
+ bottoms = [];
+
+ for (i = 0; i < n; ++i) {
+ j = order[i];
+ if (top < bottom) {
+ top += sums[j];
+ tops.push(j);
+ } else {
+ bottom += sums[j];
+ bottoms.push(j);
+ }
+ }
+
+ return bottoms.reverse().concat(tops);
+}
diff --git a/node_modules/d3-shape/src/order/none.js b/node_modules/d3-shape/src/order/none.js
new file mode 100644
index 00000000..b0d7d6f5
--- /dev/null
+++ b/node_modules/d3-shape/src/order/none.js
@@ -0,0 +1,5 @@
+export default function(series) {
+ var n = series.length, o = new Array(n);
+ while (--n >= 0) o[n] = n;
+ return o;
+}
diff --git a/node_modules/d3-shape/src/order/reverse.js b/node_modules/d3-shape/src/order/reverse.js
new file mode 100644
index 00000000..8380ca04
--- /dev/null
+++ b/node_modules/d3-shape/src/order/reverse.js
@@ -0,0 +1,5 @@
+import none from "./none.js";
+
+export default function(series) {
+ return none(series).reverse();
+}
diff --git a/node_modules/d3-shape/src/pie.js b/node_modules/d3-shape/src/pie.js
new file mode 100644
index 00000000..6748f45f
--- /dev/null
+++ b/node_modules/d3-shape/src/pie.js
@@ -0,0 +1,80 @@
+import array from "./array.js";
+import constant from "./constant.js";
+import descending from "./descending.js";
+import identity from "./identity.js";
+import {tau} from "./math.js";
+
+export default function() {
+ var value = identity,
+ sortValues = descending,
+ sort = null,
+ startAngle = constant(0),
+ endAngle = constant(tau),
+ padAngle = constant(0);
+
+ function pie(data) {
+ var i,
+ n = (data = array(data)).length,
+ j,
+ k,
+ sum = 0,
+ index = new Array(n),
+ arcs = new Array(n),
+ a0 = +startAngle.apply(this, arguments),
+ da = Math.min(tau, Math.max(-tau, endAngle.apply(this, arguments) - a0)),
+ a1,
+ p = Math.min(Math.abs(da) / n, padAngle.apply(this, arguments)),
+ pa = p * (da < 0 ? -1 : 1),
+ v;
+
+ for (i = 0; i < n; ++i) {
+ if ((v = arcs[index[i] = i] = +value(data[i], i, data)) > 0) {
+ sum += v;
+ }
+ }
+
+ // Optionally sort the arcs by previously-computed values or by data.
+ if (sortValues != null) index.sort(function(i, j) { return sortValues(arcs[i], arcs[j]); });
+ else if (sort != null) index.sort(function(i, j) { return sort(data[i], data[j]); });
+
+ // Compute the arcs! They are stored in the original data's order.
+ for (i = 0, k = sum ? (da - n * pa) / sum : 0; i < n; ++i, a0 = a1) {
+ j = index[i], v = arcs[j], a1 = a0 + (v > 0 ? v * k : 0) + pa, arcs[j] = {
+ data: data[j],
+ index: i,
+ value: v,
+ startAngle: a0,
+ endAngle: a1,
+ padAngle: p
+ };
+ }
+
+ return arcs;
+ }
+
+ pie.value = function(_) {
+ return arguments.length ? (value = typeof _ === "function" ? _ : constant(+_), pie) : value;
+ };
+
+ pie.sortValues = function(_) {
+ return arguments.length ? (sortValues = _, sort = null, pie) : sortValues;
+ };
+
+ pie.sort = function(_) {
+ return arguments.length ? (sort = _, sortValues = null, pie) : sort;
+ };
+
+ pie.startAngle = function(_) {
+ return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant(+_), pie) : startAngle;
+ };
+
+ pie.endAngle = function(_) {
+ return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant(+_), pie) : endAngle;
+ };
+
+ pie.padAngle = function(_) {
+ return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant(+_), pie) : padAngle;
+ };
+
+ return pie;
+}
diff --git a/node_modules/d3-shape/src/point.js b/node_modules/d3-shape/src/point.js
new file mode 100644
index 00000000..c3452573
--- /dev/null
+++ b/node_modules/d3-shape/src/point.js
@@ -0,0 +1,7 @@
+export function x(p) {
+ return p[0];
+}
+
+export function y(p) {
+ return p[1];
+}
diff --git a/node_modules/d3-shape/src/pointRadial.js b/node_modules/d3-shape/src/pointRadial.js
new file mode 100644
index 00000000..1cccb705
--- /dev/null
+++ b/node_modules/d3-shape/src/pointRadial.js
@@ -0,0 +1,3 @@
+export default function(x, y) {
+ return [(y = +y) * Math.cos(x -= Math.PI / 2), y * Math.sin(x)];
+}
diff --git a/node_modules/d3-shape/src/stack.js b/node_modules/d3-shape/src/stack.js
new file mode 100644
index 00000000..c4d30b1b
--- /dev/null
+++ b/node_modules/d3-shape/src/stack.js
@@ -0,0 +1,58 @@
+import array from "./array.js";
+import constant from "./constant.js";
+import offsetNone from "./offset/none.js";
+import orderNone from "./order/none.js";
+
+function stackValue(d, key) {
+ return d[key];
+}
+
+function stackSeries(key) {
+ const series = [];
+ series.key = key;
+ return series;
+}
+
+export default function() {
+ var keys = constant([]),
+ order = orderNone,
+ offset = offsetNone,
+ value = stackValue;
+
+ function stack(data) {
+ var sz = Array.from(keys.apply(this, arguments), stackSeries),
+ i, n = sz.length, j = -1,
+ oz;
+
+ for (const d of data) {
+ for (i = 0, ++j; i < n; ++i) {
+ (sz[i][j] = [0, +value(d, sz[i].key, j, data)]).data = d;
+ }
+ }
+
+ for (i = 0, oz = array(order(sz)); i < n; ++i) {
+ sz[oz[i]].index = i;
+ }
+
+ offset(sz, oz);
+ return sz;
+ }
+
+ stack.keys = function(_) {
+ return arguments.length ? (keys = typeof _ === "function" ? _ : constant(Array.from(_)), stack) : keys;
+ };
+
+ stack.value = function(_) {
+ return arguments.length ? (value = typeof _ === "function" ? _ : constant(+_), stack) : value;
+ };
+
+ stack.order = function(_) {
+ return arguments.length ? (order = _ == null ? orderNone : typeof _ === "function" ? _ : constant(Array.from(_)), stack) : order;
+ };
+
+ stack.offset = function(_) {
+ return arguments.length ? (offset = _ == null ? offsetNone : _, stack) : offset;
+ };
+
+ return stack;
+}
diff --git a/node_modules/d3-shape/src/symbol.js b/node_modules/d3-shape/src/symbol.js
new file mode 100644
index 00000000..2882cc02
--- /dev/null
+++ b/node_modules/d3-shape/src/symbol.js
@@ -0,0 +1,65 @@
+import {path} from "d3-path";
+import constant from "./constant.js";
+import asterisk from "./symbol/asterisk.js";
+import circle from "./symbol/circle.js";
+import cross from "./symbol/cross.js";
+import diamond from "./symbol/diamond.js";
+import diamond2 from "./symbol/diamond2.js";
+import plus from "./symbol/plus.js";
+import square from "./symbol/square.js";
+import square2 from "./symbol/square2.js";
+import star from "./symbol/star.js";
+import triangle from "./symbol/triangle.js";
+import triangle2 from "./symbol/triangle2.js";
+import wye from "./symbol/wye.js";
+import x from "./symbol/x.js";
+
+// These symbols are designed to be filled.
+export const symbolsFill = [
+ circle,
+ cross,
+ diamond,
+ square,
+ star,
+ triangle,
+ wye
+];
+
+// These symbols are designed to be stroked (with a width of 1.5px and round caps).
+export const symbolsStroke = [
+ circle,
+ plus,
+ x,
+ triangle2,
+ asterisk,
+ square2,
+ diamond2
+];
+
+export default function Symbol(type, size) {
+ let context = null;
+
+ type = typeof type === "function" ? type : constant(type || circle);
+ size = typeof size === "function" ? size : constant(size === undefined ? 64 : +size);
+
+ function symbol() {
+ let buffer;
+ if (!context) context = buffer = path();
+ type.apply(this, arguments).draw(context, +size.apply(this, arguments));
+ if (buffer) return context = null, buffer + "" || null;
+ }
+
+ symbol.type = function(_) {
+ return arguments.length ? (type = typeof _ === "function" ? _ : constant(_), symbol) : type;
+ };
+
+ symbol.size = function(_) {
+ return arguments.length ? (size = typeof _ === "function" ? _ : constant(+_), symbol) : size;
+ };
+
+ symbol.context = function(_) {
+ return arguments.length ? (context = _ == null ? null : _, symbol) : context;
+ };
+
+ return symbol;
+}
diff --git a/node_modules/d3-shape/src/symbol/asterisk.js b/node_modules/d3-shape/src/symbol/asterisk.js
new file mode 100644
index 00000000..05eb9a2b
--- /dev/null
+++ b/node_modules/d3-shape/src/symbol/asterisk.js
@@ -0,0 +1,17 @@
+import {min, sqrt} from "../math.js";
+
+const sqrt3 = sqrt(3);
+
+export default {
+ draw(context, size) {
+ const r = sqrt(size + min(size / 28, 0.75)) * 0.59436;
+ const t = r / 2;
+ const u = t * sqrt3;
+ context.moveTo(0, r);
+ context.lineTo(0, -r);
+ context.moveTo(-u, -t);
+ context.lineTo(u, t);
+ context.moveTo(-u, t);
+ context.lineTo(u, -t);
+ }
+};
diff --git a/node_modules/d3-shape/src/symbol/circle.js b/node_modules/d3-shape/src/symbol/circle.js
new file mode 100644
index 00000000..485e06c3
--- /dev/null
+++ b/node_modules/d3-shape/src/symbol/circle.js
@@ -0,0 +1,9 @@
+import {pi, sqrt, tau} from "../math.js";
+
+export default {
+ draw(context, size) {
+ const r = sqrt(size / pi);
+ context.moveTo(r, 0);
+ context.arc(0, 0, r, 0, tau);
+ }
+};
diff --git a/node_modules/d3-shape/src/symbol/cross.js b/node_modules/d3-shape/src/symbol/cross.js
new file mode 100644
index 00000000..5e586e91
--- /dev/null
+++ b/node_modules/d3-shape/src/symbol/cross.js
@@ -0,0 +1,20 @@
+import {sqrt} from "../math.js";
+
+export default {
+ draw(context, size) {
+ const r = sqrt(size / 5) / 2;
+ context.moveTo(-3 * r, -r);
+ context.lineTo(-r, -r);
+ context.lineTo(-r, -3 * r);
+ context.lineTo(r, -3 * r);
+ context.lineTo(r, -r);
+ context.lineTo(3 * r, -r);
+ context.lineTo(3 * r, r);
+ context.lineTo(r, r);
+ context.lineTo(r, 3 * r);
+ context.lineTo(-r, 3 * r);
+ context.lineTo(-r, r);
+ context.lineTo(-3 * r, r);
+ context.closePath();
+ }
+};
diff --git a/node_modules/d3-shape/src/symbol/diamond.js b/node_modules/d3-shape/src/symbol/diamond.js
new file mode 100644
index 00000000..7f4d60ab
--- /dev/null
+++ b/node_modules/d3-shape/src/symbol/diamond.js
@@ -0,0 +1,16 @@
+import {sqrt} from "../math.js";
+
+const tan30 = sqrt(1 / 3);
+const tan30_2 = tan30 * 2;
+
+export default {
+ draw(context, size) {
+ const y = sqrt(size / tan30_2);
+ const x = y * tan30;
+ context.moveTo(0, -y);
+ context.lineTo(x, 0);
+ context.lineTo(0, y);
+ context.lineTo(-x, 0);
+ context.closePath();
+ }
+};
diff --git a/node_modules/d3-shape/src/symbol/diamond2.js b/node_modules/d3-shape/src/symbol/diamond2.js
new file mode 100644
index 00000000..f4df0b35
--- /dev/null
+++ b/node_modules/d3-shape/src/symbol/diamond2.js
@@ -0,0 +1,12 @@
+import {sqrt} from "../math.js";
+
+export default {
+ draw(context, size) {
+ const r = sqrt(size) * 0.62625;
+ context.moveTo(0, -r);
+ context.lineTo(r, 0);
+ context.lineTo(0, r);
+ context.lineTo(-r, 0);
+ context.closePath();
+ }
+};
diff --git a/node_modules/d3-shape/src/symbol/plus.js b/node_modules/d3-shape/src/symbol/plus.js
new file mode 100644
index 00000000..bbb77415
--- /dev/null
+++ b/node_modules/d3-shape/src/symbol/plus.js
@@ -0,0 +1,11 @@
+import {min, sqrt} from "../math.js";
+
+export default {
+ draw(context, size) {
+ const r = sqrt(size - min(size / 7, 2)) * 0.87559;
+ context.moveTo(-r, 0);
+ context.lineTo(r, 0);
+ context.moveTo(0, r);
+ context.lineTo(0, -r);
+ }
+};
diff --git a/node_modules/d3-shape/src/symbol/square.js b/node_modules/d3-shape/src/symbol/square.js
new file mode 100644
index 00000000..6a8d5dd4
--- /dev/null
+++ b/node_modules/d3-shape/src/symbol/square.js
@@ -0,0 +1,9 @@
+import {sqrt} from "../math.js";
+
+export default {
+ draw(context, size) {
+ const w = sqrt(size);
+ const x = -w / 2;
+ context.rect(x, x, w, w);
+ }
+};
diff --git a/node_modules/d3-shape/src/symbol/square2.js b/node_modules/d3-shape/src/symbol/square2.js
new file mode 100644
index 00000000..508d5041
--- /dev/null
+++ b/node_modules/d3-shape/src/symbol/square2.js
@@ -0,0 +1,12 @@
+import {sqrt} from "../math.js";
+
+export default {
+ draw(context, size) {
+ const r = sqrt(size) * 0.4431;
+ context.moveTo(r, r);
+ context.lineTo(r, -r);
+ context.lineTo(-r, -r);
+ context.lineTo(-r, r);
+ context.closePath();
+ }
+};
diff --git a/node_modules/d3-shape/src/symbol/star.js b/node_modules/d3-shape/src/symbol/star.js
new file mode 100644
index 00000000..e5000d94
--- /dev/null
+++ b/node_modules/d3-shape/src/symbol/star.js
@@ -0,0 +1,24 @@
+import {sin, cos, sqrt, pi, tau} from "../math.js";
+
+const ka = 0.89081309152928522810;
+const kr = sin(pi / 10) / sin(7 * pi / 10);
+const kx = sin(tau / 10) * kr;
+const ky = -cos(tau / 10) * kr;
+
+export default {
+ draw(context, size) {
+ const r = sqrt(size * ka);
+ const x = kx * r;
+ const y = ky * r;
+ context.moveTo(0, -r);
+ context.lineTo(x, y);
+ for (let i = 1; i < 5; ++i) {
+ const a = tau * i / 5;
+ const c = cos(a);
+ const s = sin(a);
+ context.lineTo(s * r, -c * r);
+ context.lineTo(c * x - s * y, s * x + c * y);
+ }
+ context.closePath();
+ }
+};
diff --git a/node_modules/d3-shape/src/symbol/triangle.js b/node_modules/d3-shape/src/symbol/triangle.js
new file mode 100644
index 00000000..023e8243
--- /dev/null
+++ b/node_modules/d3-shape/src/symbol/triangle.js
@@ -0,0 +1,13 @@
+import {sqrt} from "../math.js";
+
+const sqrt3 = sqrt(3);
+
+export default {
+ draw(context, size) {
+ const y = -sqrt(size / (sqrt3 * 3));
+ context.moveTo(0, y * 2);
+ context.lineTo(-sqrt3 * y, -y);
+ context.lineTo(sqrt3 * y, -y);
+ context.closePath();
+ }
+};
diff --git a/node_modules/d3-shape/src/symbol/triangle2.js b/node_modules/d3-shape/src/symbol/triangle2.js
new file mode 100644
index 00000000..6b189e47
--- /dev/null
+++ b/node_modules/d3-shape/src/symbol/triangle2.js
@@ -0,0 +1,15 @@
+import {sqrt} from "../math.js";
+
+const sqrt3 = sqrt(3);
+
+export default {
+ draw(context, size) {
+ const s = sqrt(size) * 0.6824;
+ const t = s / 2;
+ const u = (s * sqrt3) / 2; // cos(Math.PI / 6)
+ context.moveTo(0, -s);
+ context.lineTo(u, t);
+ context.lineTo(-u, t);
+ context.closePath();
+ }
+};
diff --git a/node_modules/d3-shape/src/symbol/wye.js b/node_modules/d3-shape/src/symbol/wye.js
new file mode 100644
index 00000000..b8fad359
--- /dev/null
+++ b/node_modules/d3-shape/src/symbol/wye.js
@@ -0,0 +1,25 @@
+import {sqrt} from "../math.js";
+
+const c = -0.5;
+const s = sqrt(3) / 2;
+const k = 1 / sqrt(12);
+const a = (k / 2 + 1) * 3;
+
+export default {
+ draw(context, size) {
+ const r = sqrt(size / a);
+ const x0 = r / 2, y0 = r * k;
+ const x1 = x0, y1 = r * k + r;
+ const x2 = -x1, y2 = y1;
+ context.moveTo(x0, y0);
+ context.lineTo(x1, y1);
+ context.lineTo(x2, y2);
+ context.lineTo(c * x0 - s * y0, s * x0 + c * y0);
+ context.lineTo(c * x1 - s * y1, s * x1 + c * y1);
+ context.lineTo(c * x2 - s * y2, s * x2 + c * y2);
+ context.lineTo(c * x0 + s * y0, c * y0 - s * x0);
+ context.lineTo(c * x1 + s * y1, c * y1 - s * x1);
+ context.lineTo(c * x2 + s * y2, c * y2 - s * x2);
+ context.closePath();
+ }
+};
diff --git a/node_modules/d3-shape/src/symbol/x.js b/node_modules/d3-shape/src/symbol/x.js
new file mode 100644
index 00000000..1d8c829a
--- /dev/null
+++ b/node_modules/d3-shape/src/symbol/x.js
@@ -0,0 +1,11 @@
+import {min, sqrt} from "../math.js";
+
+export default {
+ draw(context, size) {
+ const r = sqrt(size - min(size / 6, 1.7)) * 0.6189;
+ context.moveTo(-r, -r);
+ context.lineTo(r, r);
+ context.moveTo(-r, r);
+ context.lineTo(r, -r);
+ }
+};
diff --git a/node_modules/d3-time-format/LICENSE b/node_modules/d3-time-format/LICENSE
new file mode 100644
index 00000000..b0145150
--- /dev/null
+++ b/node_modules/d3-time-format/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2010-2021 Mike Bostock
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/node_modules/d3-time-format/README.md b/node_modules/d3-time-format/README.md
new file mode 100644
index 00000000..6388cc15
--- /dev/null
+++ b/node_modules/d3-time-format/README.md
@@ -0,0 +1,209 @@
+# d3-time-format
+
+This module provides a JavaScript implementation of the venerable [strptime](http://pubs.opengroup.org/onlinepubs/009695399/functions/strptime.html) and [strftime](http://pubs.opengroup.org/onlinepubs/007908799/xsh/strftime.html) functions from the C standard library, and can be used to parse or format [dates](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) in a variety of locale-specific representations. To format a date, create a [formatter](#locale_format) from a specifier (a string with the desired format *directives*, indicated by `%`); then pass a date to the formatter, which returns a string. For example, to convert the current date to a human-readable string:
+
+```js
+const formatTime = d3.timeFormat("%B %d, %Y");
+formatTime(new Date); // "June 30, 2015"
+```
+
+Likewise, to convert a string back to a date, create a [parser](#locale_parse):
+
+```js
+const parseTime = d3.timeParse("%B %d, %Y");
+parseTime("June 30, 2015"); // Tue Jun 30 2015 00:00:00 GMT-0700 (PDT)
+```
+
+You can implement more elaborate conditional time formats, too. For example, here’s a [multi-scale time format](https://bl.ocks.org/mbostock/4149176) using [time intervals](https://github.com/d3/d3-time):
+
+```js
+const formatMillisecond = d3.timeFormat(".%L"),
+ formatSecond = d3.timeFormat(":%S"),
+ formatMinute = d3.timeFormat("%I:%M"),
+ formatHour = d3.timeFormat("%I %p"),
+ formatDay = d3.timeFormat("%a %d"),
+ formatWeek = d3.timeFormat("%b %d"),
+ formatMonth = d3.timeFormat("%B"),
+ formatYear = d3.timeFormat("%Y");
+
+function multiFormat(date) {
+ return (d3.timeSecond(date) < date ? formatMillisecond
+ : d3.timeMinute(date) < date ? formatSecond
+ : d3.timeHour(date) < date ? formatMinute
+ : d3.timeDay(date) < date ? formatHour
+ : d3.timeMonth(date) < date ? (d3.timeWeek(date) < date ? formatDay : formatWeek)
+ : d3.timeYear(date) < date ? formatMonth
+ : formatYear)(date);
+}
+```
+
+This module is used by D3 [time scales](https://github.com/d3/d3-scale/blob/main/README.md#time-scales) to generate human-readable ticks.
+
+## Installing
+
+If you use npm, `npm install d3-time-format`. You can also download the [latest release on GitHub](https://github.com/d3/d3-time-format/releases/latest). For vanilla HTML in modern browsers, import d3-time-format from Skypack:
+
+```html
+
+```
+
+For legacy environments, you can load d3-time-format’s UMD bundle from an npm-based CDN such as jsDelivr; a `d3` global is exported:
+
+```html
+
+
+
+
+
+Locale files are published to npm and can be loaded using [d3.json](https://github.com/d3/d3-fetch/blob/main/README.md#json). For example, to set Russian as the default locale:
+
+```js
+d3.json("https://cdn.jsdelivr.net/npm/d3-time-format@3/locale/ru-RU.json").then(locale => {
+ d3.timeFormatDefaultLocale(locale);
+
+ const format = d3.timeFormat("%c");
+
+ console.log(format(new Date)); // понедельник, 5 декабря 2016 г. 10:31:59
+});
+```
+
+## API Reference
+
+# d3.timeFormat(specifier) · [Source](https://github.com/d3/d3-time-format/blob/main/src/defaultLocale.js)
+
+An alias for [*locale*.format](#locale_format) on the [default locale](#timeFormatDefaultLocale).
+
+# d3.timeParse(specifier) · [Source](https://github.com/d3/d3-time-format/blob/main/src/defaultLocale.js)
+
+An alias for [*locale*.parse](#locale_parse) on the [default locale](#timeFormatDefaultLocale).
+
+# d3.utcFormat(specifier) · [Source](https://github.com/d3/d3-time-format/blob/main/src/defaultLocale.js)
+
+An alias for [*locale*.utcFormat](#locale_utcFormat) on the [default locale](#timeFormatDefaultLocale).
+
+# d3.utcParse(specifier) · [Source](https://github.com/d3/d3-time-format/blob/main/src/defaultLocale.js)
+
+An alias for [*locale*.utcParse](#locale_utcParse) on the [default locale](#timeFormatDefaultLocale).
+
+# d3.isoFormat · [Source](https://github.com/d3/d3-time-format/blob/main/src/isoFormat.js)
+
+The full [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) UTC time formatter. Where available, this method will use [Date.toISOString](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/toISOString) to format.
+
+# d3.isoParse · [Source](https://github.com/d3/d3-time-format/blob/main/src/isoParse.js)
+
+The full [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) UTC time parser. Where available, this method will use the [Date constructor](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date) to parse strings. If you depend on strict validation of the input format according to ISO 8601, you should construct a [UTC parser function](#utcParse):
+
+```js
+const strictIsoParse = d3.utcParse("%Y-%m-%dT%H:%M:%S.%LZ");
+```
+
+# locale.format(specifier) · [Source](https://github.com/d3/d3-time-format/blob/main/src/locale.js)
+
+Returns a new formatter for the given string *specifier*. The specifier string may contain the following directives:
+
+* `%a` - abbreviated weekday name.*
+* `%A` - full weekday name.*
+* `%b` - abbreviated month name.*
+* `%B` - full month name.*
+* `%c` - the locale’s date and time, such as `%x, %X`.*
+* `%d` - zero-padded day of the month as a decimal number [01,31].
+* `%e` - space-padded day of the month as a decimal number [ 1,31]; equivalent to `%_d`.
+* `%f` - microseconds as a decimal number [000000, 999999].
+* `%g` - ISO 8601 week-based year without century as a decimal number [00,99].
+* `%G` - ISO 8601 week-based year with century as a decimal number.
+* `%H` - hour (24-hour clock) as a decimal number [00,23].
+* `%I` - hour (12-hour clock) as a decimal number [01,12].
+* `%j` - day of the year as a decimal number [001,366].
+* `%m` - month as a decimal number [01,12].
+* `%M` - minute as a decimal number [00,59].
+* `%L` - milliseconds as a decimal number [000, 999].
+* `%p` - either AM or PM.*
+* `%q` - quarter of the year as a decimal number [1,4].
+* `%Q` - milliseconds since UNIX epoch.
+* `%s` - seconds since UNIX epoch.
+* `%S` - second as a decimal number [00,61].
+* `%u` - Monday-based (ISO 8601) weekday as a decimal number [1,7].
+* `%U` - Sunday-based week of the year as a decimal number [00,53].
+* `%V` - ISO 8601 week of the year as a decimal number [01, 53].
+* `%w` - Sunday-based weekday as a decimal number [0,6].
+* `%W` - Monday-based week of the year as a decimal number [00,53].
+* `%x` - the locale’s date, such as `%-m/%-d/%Y`.*
+* `%X` - the locale’s time, such as `%-I:%M:%S %p`.*
+* `%y` - year without century as a decimal number [00,99].
+* `%Y` - year with century as a decimal number, such as `1999`.
+* `%Z` - time zone offset, such as `-0700`, `-07:00`, `-07`, or `Z`.
+* `%%` - a literal percent sign (`%`).
+
+Directives marked with an asterisk (\*) may be affected by the [locale definition](#locales).
+
+For `%U`, all days in a new year preceding the first Sunday are considered to be in week 0. For `%W`, all days in a new year preceding the first Monday are considered to be in week 0. Week numbers are computed using [*interval*.count](https://github.com/d3/d3-time/blob/main/README.md#interval_count). For example, 2015-52 and 2016-00 represent Monday, December 28, 2015, while 2015-53 and 2016-01 represent Monday, January 4, 2016. This differs from the [ISO week date](https://en.wikipedia.org/wiki/ISO_week_date) specification (`%V`), which uses a more complicated definition!
+
+For `%V`,`%g` and `%G`, per the [strftime man page](http://man7.org/linux/man-pages/man3/strftime.3.html):
+
+> In this system, weeks start on a Monday, and are numbered from 01, for the first week, up to 52 or 53, for the last week. Week 1 is the first week where four or more days fall within the new year (or, synonymously, week 01 is: the first week of the year that contains a Thursday; or, the week that has 4 January in it). If the ISO week number belongs to the previous or next year, that year is used instead.
+
+The `%` sign indicating a directive may be immediately followed by a padding modifier:
+
+* `0` - zero-padding
+* `_` - space-padding
+* `-` - disable padding
+
+If no padding modifier is specified, the default is `0` for all directives except `%e`, which defaults to `_`. (In some implementations of strftime and strptime, a directive may include an optional field width or precision; this feature is not yet implemented.)
+
+The returned function formats a specified *[date](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date)*, returning the corresponding string.
+
+```js
+const formatMonth = d3.timeFormat("%B"),
+ formatDay = d3.timeFormat("%A"),
+ date = new Date(2014, 4, 1); // Thu May 01 2014 00:00:00 GMT-0700 (PDT)
+
+formatMonth(date); // "May"
+formatDay(date); // "Thursday"
+```
+
+# locale.parse(specifier) · [Source](https://github.com/d3/d3-time-format/blob/main/src/locale.js)
+
+Returns a new parser for the given string *specifier*. The specifier string may contain the same directives as [*locale*.format](#locale_format). The `%d` and `%e` directives are considered equivalent for parsing.
+
+The returned function parses a specified *string*, returning the corresponding [date](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Date) or null if the string could not be parsed according to this format’s specifier. Parsing is strict: if the specified string does not exactly match the associated specifier, this method returns null. For example, if the associated specifier is `%Y-%m-%dT%H:%M:%SZ`, then the string `"2011-07-01T19:15:28Z"` will be parsed as expected, but `"2011-07-01T19:15:28"`, `"2011-07-01 19:15:28"` and `"2011-07-01"` will return null. (Note that the literal `Z` here is different from the time zone offset directive `%Z`.) If a more flexible parser is desired, try multiple formats sequentially until one returns non-null.
+
+# locale.utcFormat(specifier) · [Source](https://github.com/d3/d3-time-format/blob/main/src/locale.js)
+
+Equivalent to [*locale*.format](#locale_format), except all directives are interpreted as [Coordinated Universal Time (UTC)](https://en.wikipedia.org/wiki/Coordinated_Universal_Time) rather than local time.
+
+# locale.utcParse(specifier) · [Source](https://github.com/d3/d3-time-format/blob/main/src/locale.js)
+
+Equivalent to [*locale*.parse](#locale_parse), except all directives are interpreted as [Coordinated Universal Time (UTC)](https://en.wikipedia.org/wiki/Coordinated_Universal_Time) rather than local time.
+
+### Locales
+
+# d3.timeFormatLocale(definition) · [Source](https://github.com/d3/d3-time-format/blob/main/src/locale.js)
+
+Returns a *locale* object for the specified *definition* with [*locale*.format](#locale_format), [*locale*.parse](#locale_parse), [*locale*.utcFormat](#locale_utcFormat), [*locale*.utcParse](#locale_utcParse) methods. The *definition* must include the following properties:
+
+* `dateTime` - the date and time (`%c`) format specifier (e.g., `"%a %b %e %X %Y"`).
+* `date` - the date (`%x`) format specifier (e.g., `"%m/%d/%Y"`).
+* `time` - the time (`%X`) format specifier (e.g., `"%H:%M:%S"`).
+* `periods` - the A.M. and P.M. equivalents (e.g., `["AM", "PM"]`).
+* `days` - the full names of the weekdays, starting with Sunday.
+* `shortDays` - the abbreviated names of the weekdays, starting with Sunday.
+* `months` - the full names of the months (starting with January).
+* `shortMonths` - the abbreviated names of the months (starting with January).
+
+For an example, see [Localized Time Axis II](https://bl.ocks.org/mbostock/805115ebaa574e771db1875a6d828949).
+
+# d3.timeFormatDefaultLocale(definition) · [Source](https://github.com/d3/d3-time-format/blob/main/src/defaultLocale.js)
+
+Equivalent to [d3.timeFormatLocale](#timeFormatLocale), except it also redefines [d3.timeFormat](#timeFormat), [d3.timeParse](#timeParse), [d3.utcFormat](#utcFormat) and [d3.utcParse](#utcParse) to the new locale’s [*locale*.format](#locale_format), [*locale*.parse](#locale_parse), [*locale*.utcFormat](#locale_utcFormat) and [*locale*.utcParse](#locale_utcParse). If you do not set a default locale, it defaults to [U.S. English](https://github.com/d3/d3-time-format/blob/main/locale/en-US.json).
+
+For an example, see [Localized Time Axis](https://bl.ocks.org/mbostock/6f1cc065d4d172bcaf322e399aa8d62f).
diff --git a/node_modules/d3-time-format/dist/d3-time-format.js b/node_modules/d3-time-format/dist/d3-time-format.js
new file mode 100644
index 00000000..8fc09984
--- /dev/null
+++ b/node_modules/d3-time-format/dist/d3-time-format.js
@@ -0,0 +1,745 @@
+// https://d3js.org/d3-time-format/ v4.1.0 Copyright 2010-2021 Mike Bostock
+(function (global, factory) {
+typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-time')) :
+typeof define === 'function' && define.amd ? define(['exports', 'd3-time'], factory) :
+(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}, global.d3));
+})(this, (function (exports, d3Time) { 'use strict';
+
+function localDate(d) {
+ if (0 <= d.y && d.y < 100) {
+ var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);
+ date.setFullYear(d.y);
+ return date;
+ }
+ return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);
+}
+
+function utcDate(d) {
+ if (0 <= d.y && d.y < 100) {
+ var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));
+ date.setUTCFullYear(d.y);
+ return date;
+ }
+ return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));
+}
+
+function newDate(y, m, d) {
+ return {y: y, m: m, d: d, H: 0, M: 0, S: 0, L: 0};
+}
+
+function formatLocale(locale) {
+ var locale_dateTime = locale.dateTime,
+ locale_date = locale.date,
+ locale_time = locale.time,
+ locale_periods = locale.periods,
+ locale_weekdays = locale.days,
+ locale_shortWeekdays = locale.shortDays,
+ locale_months = locale.months,
+ locale_shortMonths = locale.shortMonths;
+
+ var periodRe = formatRe(locale_periods),
+ periodLookup = formatLookup(locale_periods),
+ weekdayRe = formatRe(locale_weekdays),
+ weekdayLookup = formatLookup(locale_weekdays),
+ shortWeekdayRe = formatRe(locale_shortWeekdays),
+ shortWeekdayLookup = formatLookup(locale_shortWeekdays),
+ monthRe = formatRe(locale_months),
+ monthLookup = formatLookup(locale_months),
+ shortMonthRe = formatRe(locale_shortMonths),
+ shortMonthLookup = formatLookup(locale_shortMonths);
+
+ var formats = {
+ "a": formatShortWeekday,
+ "A": formatWeekday,
+ "b": formatShortMonth,
+ "B": formatMonth,
+ "c": null,
+ "d": formatDayOfMonth,
+ "e": formatDayOfMonth,
+ "f": formatMicroseconds,
+ "g": formatYearISO,
+ "G": formatFullYearISO,
+ "H": formatHour24,
+ "I": formatHour12,
+ "j": formatDayOfYear,
+ "L": formatMilliseconds,
+ "m": formatMonthNumber,
+ "M": formatMinutes,
+ "p": formatPeriod,
+ "q": formatQuarter,
+ "Q": formatUnixTimestamp,
+ "s": formatUnixTimestampSeconds,
+ "S": formatSeconds,
+ "u": formatWeekdayNumberMonday,
+ "U": formatWeekNumberSunday,
+ "V": formatWeekNumberISO,
+ "w": formatWeekdayNumberSunday,
+ "W": formatWeekNumberMonday,
+ "x": null,
+ "X": null,
+ "y": formatYear,
+ "Y": formatFullYear,
+ "Z": formatZone,
+ "%": formatLiteralPercent
+ };
+
+ var utcFormats = {
+ "a": formatUTCShortWeekday,
+ "A": formatUTCWeekday,
+ "b": formatUTCShortMonth,
+ "B": formatUTCMonth,
+ "c": null,
+ "d": formatUTCDayOfMonth,
+ "e": formatUTCDayOfMonth,
+ "f": formatUTCMicroseconds,
+ "g": formatUTCYearISO,
+ "G": formatUTCFullYearISO,
+ "H": formatUTCHour24,
+ "I": formatUTCHour12,
+ "j": formatUTCDayOfYear,
+ "L": formatUTCMilliseconds,
+ "m": formatUTCMonthNumber,
+ "M": formatUTCMinutes,
+ "p": formatUTCPeriod,
+ "q": formatUTCQuarter,
+ "Q": formatUnixTimestamp,
+ "s": formatUnixTimestampSeconds,
+ "S": formatUTCSeconds,
+ "u": formatUTCWeekdayNumberMonday,
+ "U": formatUTCWeekNumberSunday,
+ "V": formatUTCWeekNumberISO,
+ "w": formatUTCWeekdayNumberSunday,
+ "W": formatUTCWeekNumberMonday,
+ "x": null,
+ "X": null,
+ "y": formatUTCYear,
+ "Y": formatUTCFullYear,
+ "Z": formatUTCZone,
+ "%": formatLiteralPercent
+ };
+
+ var parses = {
+ "a": parseShortWeekday,
+ "A": parseWeekday,
+ "b": parseShortMonth,
+ "B": parseMonth,
+ "c": parseLocaleDateTime,
+ "d": parseDayOfMonth,
+ "e": parseDayOfMonth,
+ "f": parseMicroseconds,
+ "g": parseYear,
+ "G": parseFullYear,
+ "H": parseHour24,
+ "I": parseHour24,
+ "j": parseDayOfYear,
+ "L": parseMilliseconds,
+ "m": parseMonthNumber,
+ "M": parseMinutes,
+ "p": parsePeriod,
+ "q": parseQuarter,
+ "Q": parseUnixTimestamp,
+ "s": parseUnixTimestampSeconds,
+ "S": parseSeconds,
+ "u": parseWeekdayNumberMonday,
+ "U": parseWeekNumberSunday,
+ "V": parseWeekNumberISO,
+ "w": parseWeekdayNumberSunday,
+ "W": parseWeekNumberMonday,
+ "x": parseLocaleDate,
+ "X": parseLocaleTime,
+ "y": parseYear,
+ "Y": parseFullYear,
+ "Z": parseZone,
+ "%": parseLiteralPercent
+ };
+
+ // These recursive directive definitions must be deferred.
+ formats.x = newFormat(locale_date, formats);
+ formats.X = newFormat(locale_time, formats);
+ formats.c = newFormat(locale_dateTime, formats);
+ utcFormats.x = newFormat(locale_date, utcFormats);
+ utcFormats.X = newFormat(locale_time, utcFormats);
+ utcFormats.c = newFormat(locale_dateTime, utcFormats);
+
+ function newFormat(specifier, formats) {
+ return function(date) {
+ var string = [],
+ i = -1,
+ j = 0,
+ n = specifier.length,
+ c,
+ pad,
+ format;
+
+ if (!(date instanceof Date)) date = new Date(+date);
+
+ while (++i < n) {
+ if (specifier.charCodeAt(i) === 37) {
+ string.push(specifier.slice(j, i));
+ if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);
+ else pad = c === "e" ? " " : "0";
+ if (format = formats[c]) c = format(date, pad);
+ string.push(c);
+ j = i + 1;
+ }
+ }
+
+ string.push(specifier.slice(j, i));
+ return string.join("");
+ };
+ }
+
+ function newParse(specifier, Z) {
+ return function(string) {
+ var d = newDate(1900, undefined, 1),
+ i = parseSpecifier(d, specifier, string += "", 0),
+ week, day;
+ if (i != string.length) return null;
+
+ // If a UNIX timestamp is specified, return it.
+ if ("Q" in d) return new Date(d.Q);
+ if ("s" in d) return new Date(d.s * 1000 + ("L" in d ? d.L : 0));
+
+ // If this is utcParse, never use the local timezone.
+ if (Z && !("Z" in d)) d.Z = 0;
+
+ // The am-pm flag is 0 for AM, and 1 for PM.
+ if ("p" in d) d.H = d.H % 12 + d.p * 12;
+
+ // If the month was not specified, inherit from the quarter.
+ if (d.m === undefined) d.m = "q" in d ? d.q : 0;
+
+ // Convert day-of-week and week-of-year to day-of-year.
+ if ("V" in d) {
+ if (d.V < 1 || d.V > 53) return null;
+ if (!("w" in d)) d.w = 1;
+ if ("Z" in d) {
+ week = utcDate(newDate(d.y, 0, 1)), day = week.getUTCDay();
+ week = day > 4 || day === 0 ? d3Time.utcMonday.ceil(week) : d3Time.utcMonday(week);
+ week = d3Time.utcDay.offset(week, (d.V - 1) * 7);
+ d.y = week.getUTCFullYear();
+ d.m = week.getUTCMonth();
+ d.d = week.getUTCDate() + (d.w + 6) % 7;
+ } else {
+ week = localDate(newDate(d.y, 0, 1)), day = week.getDay();
+ week = day > 4 || day === 0 ? d3Time.timeMonday.ceil(week) : d3Time.timeMonday(week);
+ week = d3Time.timeDay.offset(week, (d.V - 1) * 7);
+ d.y = week.getFullYear();
+ d.m = week.getMonth();
+ d.d = week.getDate() + (d.w + 6) % 7;
+ }
+ } else if ("W" in d || "U" in d) {
+ if (!("w" in d)) d.w = "u" in d ? d.u % 7 : "W" in d ? 1 : 0;
+ day = "Z" in d ? utcDate(newDate(d.y, 0, 1)).getUTCDay() : localDate(newDate(d.y, 0, 1)).getDay();
+ d.m = 0;
+ d.d = "W" in d ? (d.w + 6) % 7 + d.W * 7 - (day + 5) % 7 : d.w + d.U * 7 - (day + 6) % 7;
+ }
+
+ // If a time zone is specified, all fields are interpreted as UTC and then
+ // offset according to the specified time zone.
+ if ("Z" in d) {
+ d.H += d.Z / 100 | 0;
+ d.M += d.Z % 100;
+ return utcDate(d);
+ }
+
+ // Otherwise, all fields are in local time.
+ return localDate(d);
+ };
+ }
+
+ function parseSpecifier(d, specifier, string, j) {
+ var i = 0,
+ n = specifier.length,
+ m = string.length,
+ c,
+ parse;
+
+ while (i < n) {
+ if (j >= m) return -1;
+ c = specifier.charCodeAt(i++);
+ if (c === 37) {
+ c = specifier.charAt(i++);
+ parse = parses[c in pads ? specifier.charAt(i++) : c];
+ if (!parse || ((j = parse(d, string, j)) < 0)) return -1;
+ } else if (c != string.charCodeAt(j++)) {
+ return -1;
+ }
+ }
+
+ return j;
+ }
+
+ function parsePeriod(d, string, i) {
+ var n = periodRe.exec(string.slice(i));
+ return n ? (d.p = periodLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
+ }
+
+ function parseShortWeekday(d, string, i) {
+ var n = shortWeekdayRe.exec(string.slice(i));
+ return n ? (d.w = shortWeekdayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
+ }
+
+ function parseWeekday(d, string, i) {
+ var n = weekdayRe.exec(string.slice(i));
+ return n ? (d.w = weekdayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
+ }
+
+ function parseShortMonth(d, string, i) {
+ var n = shortMonthRe.exec(string.slice(i));
+ return n ? (d.m = shortMonthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
+ }
+
+ function parseMonth(d, string, i) {
+ var n = monthRe.exec(string.slice(i));
+ return n ? (d.m = monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
+ }
+
+ function parseLocaleDateTime(d, string, i) {
+ return parseSpecifier(d, locale_dateTime, string, i);
+ }
+
+ function parseLocaleDate(d, string, i) {
+ return parseSpecifier(d, locale_date, string, i);
+ }
+
+ function parseLocaleTime(d, string, i) {
+ return parseSpecifier(d, locale_time, string, i);
+ }
+
+ function formatShortWeekday(d) {
+ return locale_shortWeekdays[d.getDay()];
+ }
+
+ function formatWeekday(d) {
+ return locale_weekdays[d.getDay()];
+ }
+
+ function formatShortMonth(d) {
+ return locale_shortMonths[d.getMonth()];
+ }
+
+ function formatMonth(d) {
+ return locale_months[d.getMonth()];
+ }
+
+ function formatPeriod(d) {
+ return locale_periods[+(d.getHours() >= 12)];
+ }
+
+ function formatQuarter(d) {
+ return 1 + ~~(d.getMonth() / 3);
+ }
+
+ function formatUTCShortWeekday(d) {
+ return locale_shortWeekdays[d.getUTCDay()];
+ }
+
+ function formatUTCWeekday(d) {
+ return locale_weekdays[d.getUTCDay()];
+ }
+
+ function formatUTCShortMonth(d) {
+ return locale_shortMonths[d.getUTCMonth()];
+ }
+
+ function formatUTCMonth(d) {
+ return locale_months[d.getUTCMonth()];
+ }
+
+ function formatUTCPeriod(d) {
+ return locale_periods[+(d.getUTCHours() >= 12)];
+ }
+
+ function formatUTCQuarter(d) {
+ return 1 + ~~(d.getUTCMonth() / 3);
+ }
+
+ return {
+ format: function(specifier) {
+ var f = newFormat(specifier += "", formats);
+ f.toString = function() { return specifier; };
+ return f;
+ },
+ parse: function(specifier) {
+ var p = newParse(specifier += "", false);
+ p.toString = function() { return specifier; };
+ return p;
+ },
+ utcFormat: function(specifier) {
+ var f = newFormat(specifier += "", utcFormats);
+ f.toString = function() { return specifier; };
+ return f;
+ },
+ utcParse: function(specifier) {
+ var p = newParse(specifier += "", true);
+ p.toString = function() { return specifier; };
+ return p;
+ }
+ };
+}
+
+var pads = {"-": "", "_": " ", "0": "0"},
+ numberRe = /^\s*\d+/, // note: ignores next directive
+ percentRe = /^%/,
+ requoteRe = /[\\^$*+?|[\]().{}]/g;
+
+function pad(value, fill, width) {
+ var sign = value < 0 ? "-" : "",
+ string = (sign ? -value : value) + "",
+ length = string.length;
+ return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);
+}
+
+function requote(s) {
+ return s.replace(requoteRe, "\\$&");
+}
+
+function formatRe(names) {
+ return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i");
+}
+
+function formatLookup(names) {
+ return new Map(names.map((name, i) => [name.toLowerCase(), i]));
+}
+
+function parseWeekdayNumberSunday(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 1));
+ return n ? (d.w = +n[0], i + n[0].length) : -1;
+}
+
+function parseWeekdayNumberMonday(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 1));
+ return n ? (d.u = +n[0], i + n[0].length) : -1;
+}
+
+function parseWeekNumberSunday(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.U = +n[0], i + n[0].length) : -1;
+}
+
+function parseWeekNumberISO(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.V = +n[0], i + n[0].length) : -1;
+}
+
+function parseWeekNumberMonday(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.W = +n[0], i + n[0].length) : -1;
+}
+
+function parseFullYear(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 4));
+ return n ? (d.y = +n[0], i + n[0].length) : -1;
+}
+
+function parseYear(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;
+}
+
+function parseZone(d, string, i) {
+ var n = /^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(string.slice(i, i + 6));
+ return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1;
+}
+
+function parseQuarter(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 1));
+ return n ? (d.q = n[0] * 3 - 3, i + n[0].length) : -1;
+}
+
+function parseMonthNumber(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.m = n[0] - 1, i + n[0].length) : -1;
+}
+
+function parseDayOfMonth(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.d = +n[0], i + n[0].length) : -1;
+}
+
+function parseDayOfYear(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 3));
+ return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;
+}
+
+function parseHour24(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.H = +n[0], i + n[0].length) : -1;
+}
+
+function parseMinutes(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.M = +n[0], i + n[0].length) : -1;
+}
+
+function parseSeconds(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.S = +n[0], i + n[0].length) : -1;
+}
+
+function parseMilliseconds(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 3));
+ return n ? (d.L = +n[0], i + n[0].length) : -1;
+}
+
+function parseMicroseconds(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 6));
+ return n ? (d.L = Math.floor(n[0] / 1000), i + n[0].length) : -1;
+}
+
+function parseLiteralPercent(d, string, i) {
+ var n = percentRe.exec(string.slice(i, i + 1));
+ return n ? i + n[0].length : -1;
+}
+
+function parseUnixTimestamp(d, string, i) {
+ var n = numberRe.exec(string.slice(i));
+ return n ? (d.Q = +n[0], i + n[0].length) : -1;
+}
+
+function parseUnixTimestampSeconds(d, string, i) {
+ var n = numberRe.exec(string.slice(i));
+ return n ? (d.s = +n[0], i + n[0].length) : -1;
+}
+
+function formatDayOfMonth(d, p) {
+ return pad(d.getDate(), p, 2);
+}
+
+function formatHour24(d, p) {
+ return pad(d.getHours(), p, 2);
+}
+
+function formatHour12(d, p) {
+ return pad(d.getHours() % 12 || 12, p, 2);
+}
+
+function formatDayOfYear(d, p) {
+ return pad(1 + d3Time.timeDay.count(d3Time.timeYear(d), d), p, 3);
+}
+
+function formatMilliseconds(d, p) {
+ return pad(d.getMilliseconds(), p, 3);
+}
+
+function formatMicroseconds(d, p) {
+ return formatMilliseconds(d, p) + "000";
+}
+
+function formatMonthNumber(d, p) {
+ return pad(d.getMonth() + 1, p, 2);
+}
+
+function formatMinutes(d, p) {
+ return pad(d.getMinutes(), p, 2);
+}
+
+function formatSeconds(d, p) {
+ return pad(d.getSeconds(), p, 2);
+}
+
+function formatWeekdayNumberMonday(d) {
+ var day = d.getDay();
+ return day === 0 ? 7 : day;
+}
+
+function formatWeekNumberSunday(d, p) {
+ return pad(d3Time.timeSunday.count(d3Time.timeYear(d) - 1, d), p, 2);
+}
+
+function dISO(d) {
+ var day = d.getDay();
+ return (day >= 4 || day === 0) ? d3Time.timeThursday(d) : d3Time.timeThursday.ceil(d);
+}
+
+function formatWeekNumberISO(d, p) {
+ d = dISO(d);
+ return pad(d3Time.timeThursday.count(d3Time.timeYear(d), d) + (d3Time.timeYear(d).getDay() === 4), p, 2);
+}
+
+function formatWeekdayNumberSunday(d) {
+ return d.getDay();
+}
+
+function formatWeekNumberMonday(d, p) {
+ return pad(d3Time.timeMonday.count(d3Time.timeYear(d) - 1, d), p, 2);
+}
+
+function formatYear(d, p) {
+ return pad(d.getFullYear() % 100, p, 2);
+}
+
+function formatYearISO(d, p) {
+ d = dISO(d);
+ return pad(d.getFullYear() % 100, p, 2);
+}
+
+function formatFullYear(d, p) {
+ return pad(d.getFullYear() % 10000, p, 4);
+}
+
+function formatFullYearISO(d, p) {
+ var day = d.getDay();
+ d = (day >= 4 || day === 0) ? d3Time.timeThursday(d) : d3Time.timeThursday.ceil(d);
+ return pad(d.getFullYear() % 10000, p, 4);
+}
+
+function formatZone(d) {
+ var z = d.getTimezoneOffset();
+ return (z > 0 ? "-" : (z *= -1, "+"))
+ + pad(z / 60 | 0, "0", 2)
+ + pad(z % 60, "0", 2);
+}
+
+function formatUTCDayOfMonth(d, p) {
+ return pad(d.getUTCDate(), p, 2);
+}
+
+function formatUTCHour24(d, p) {
+ return pad(d.getUTCHours(), p, 2);
+}
+
+function formatUTCHour12(d, p) {
+ return pad(d.getUTCHours() % 12 || 12, p, 2);
+}
+
+function formatUTCDayOfYear(d, p) {
+ return pad(1 + d3Time.utcDay.count(d3Time.utcYear(d), d), p, 3);
+}
+
+function formatUTCMilliseconds(d, p) {
+ return pad(d.getUTCMilliseconds(), p, 3);
+}
+
+function formatUTCMicroseconds(d, p) {
+ return formatUTCMilliseconds(d, p) + "000";
+}
+
+function formatUTCMonthNumber(d, p) {
+ return pad(d.getUTCMonth() + 1, p, 2);
+}
+
+function formatUTCMinutes(d, p) {
+ return pad(d.getUTCMinutes(), p, 2);
+}
+
+function formatUTCSeconds(d, p) {
+ return pad(d.getUTCSeconds(), p, 2);
+}
+
+function formatUTCWeekdayNumberMonday(d) {
+ var dow = d.getUTCDay();
+ return dow === 0 ? 7 : dow;
+}
+
+function formatUTCWeekNumberSunday(d, p) {
+ return pad(d3Time.utcSunday.count(d3Time.utcYear(d) - 1, d), p, 2);
+}
+
+function UTCdISO(d) {
+ var day = d.getUTCDay();
+ return (day >= 4 || day === 0) ? d3Time.utcThursday(d) : d3Time.utcThursday.ceil(d);
+}
+
+function formatUTCWeekNumberISO(d, p) {
+ d = UTCdISO(d);
+ return pad(d3Time.utcThursday.count(d3Time.utcYear(d), d) + (d3Time.utcYear(d).getUTCDay() === 4), p, 2);
+}
+
+function formatUTCWeekdayNumberSunday(d) {
+ return d.getUTCDay();
+}
+
+function formatUTCWeekNumberMonday(d, p) {
+ return pad(d3Time.utcMonday.count(d3Time.utcYear(d) - 1, d), p, 2);
+}
+
+function formatUTCYear(d, p) {
+ return pad(d.getUTCFullYear() % 100, p, 2);
+}
+
+function formatUTCYearISO(d, p) {
+ d = UTCdISO(d);
+ return pad(d.getUTCFullYear() % 100, p, 2);
+}
+
+function formatUTCFullYear(d, p) {
+ return pad(d.getUTCFullYear() % 10000, p, 4);
+}
+
+function formatUTCFullYearISO(d, p) {
+ var day = d.getUTCDay();
+ d = (day >= 4 || day === 0) ? d3Time.utcThursday(d) : d3Time.utcThursday.ceil(d);
+ return pad(d.getUTCFullYear() % 10000, p, 4);
+}
+
+function formatUTCZone() {
+ return "+0000";
+}
+
+function formatLiteralPercent() {
+ return "%";
+}
+
+function formatUnixTimestamp(d) {
+ return +d;
+}
+
+function formatUnixTimestampSeconds(d) {
+ return Math.floor(+d / 1000);
+}
+
+var locale;
+exports.timeFormat = void 0;
+exports.timeParse = void 0;
+exports.utcFormat = void 0;
+exports.utcParse = void 0;
+
+defaultLocale({
+ dateTime: "%x, %X",
+ date: "%-m/%-d/%Y",
+ time: "%-I:%M:%S %p",
+ periods: ["AM", "PM"],
+ days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
+ shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
+ months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
+ shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+});
+
+function defaultLocale(definition) {
+ locale = formatLocale(definition);
+ exports.timeFormat = locale.format;
+ exports.timeParse = locale.parse;
+ exports.utcFormat = locale.utcFormat;
+ exports.utcParse = locale.utcParse;
+ return locale;
+}
+
+var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ";
+
+function formatIsoNative(date) {
+ return date.toISOString();
+}
+
+var formatIso = Date.prototype.toISOString
+ ? formatIsoNative
+ : exports.utcFormat(isoSpecifier);
+
+function parseIsoNative(string) {
+ var date = new Date(string);
+ return isNaN(date) ? null : date;
+}
+
+var parseIso = +new Date("2000-01-01T00:00:00.000Z")
+ ? parseIsoNative
+ : exports.utcParse(isoSpecifier);
+
+exports.isoFormat = formatIso;
+exports.isoParse = parseIso;
+exports.timeFormatDefaultLocale = defaultLocale;
+exports.timeFormatLocale = formatLocale;
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+}));
diff --git a/node_modules/d3-time-format/dist/d3-time-format.min.js b/node_modules/d3-time-format/dist/d3-time-format.min.js
new file mode 100644
index 00000000..816bce23
--- /dev/null
+++ b/node_modules/d3-time-format/dist/d3-time-format.min.js
@@ -0,0 +1,2 @@
+// https://d3js.org/d3-time-format/ v4.1.0 Copyright 2010-2021 Mike Bostock
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("d3-time")):"function"==typeof define&&define.amd?define(["exports","d3-time"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).d3=e.d3||{},e.d3)}(this,(function(e,t){"use strict";function n(e){if(0<=e.y&&e.y<100){var t=new Date(-1,e.m,e.d,e.H,e.M,e.S,e.L);return t.setFullYear(e.y),t}return new Date(e.y,e.m,e.d,e.H,e.M,e.S,e.L)}function r(e){if(0<=e.y&&e.y<100){var t=new Date(Date.UTC(-1,e.m,e.d,e.H,e.M,e.S,e.L));return t.setUTCFullYear(e.y),t}return new Date(Date.UTC(e.y,e.m,e.d,e.H,e.M,e.S,e.L))}function u(e,t,n){return{y:e,m:t,d:n,H:0,M:0,S:0,L:0}}function i(e){var i=e.dateTime,c=e.date,a=e.time,f=e.periods,l=e.days,s=e.shortDays,g=e.months,G=e.shortMonths,ge=d(f),pe=y(f),we=d(l),Se=y(l),Ye=d(s),Fe=y(s),Le=d(g),He=y(g),Ae=d(G),Ze=y(G),be={a:function(e){return s[e.getDay()]},A:function(e){return l[e.getDay()]},b:function(e){return G[e.getMonth()]},B:function(e){return g[e.getMonth()]},c:null,d:W,e:W,f:J,g:R,G:K,H:V,I:j,j:q,L:I,m:O,M:Q,p:function(e){return f[+(e.getHours()>=12)]},q:function(e){return 1+~~(e.getMonth()/3)},Q:Ue,s:xe,S:X,u:N,U:B,V:_,w:$,W:z,x:null,X:null,y:E,Y:k,Z:ee,"%":Ce},Pe={a:function(e){return s[e.getUTCDay()]},A:function(e){return l[e.getUTCDay()]},b:function(e){return G[e.getUTCMonth()]},B:function(e){return g[e.getUTCMonth()]},c:null,d:te,e:te,f:ce,g:ve,G:Me,H:ne,I:re,j:ue,L:ie,m:oe,M:ae,p:function(e){return f[+(e.getUTCHours()>=12)]},q:function(e){return 1+~~(e.getUTCMonth()/3)},Q:Ue,s:xe,S:fe,u:le,U:se,V:de,w:ye,W:he,x:null,X:null,y:me,Y:Te,Z:De,"%":Ce},We={a:function(e,t,n){var r=Ye.exec(t.slice(n));return r?(e.w=Fe.get(r[0].toLowerCase()),n+r[0].length):-1},A:function(e,t,n){var r=we.exec(t.slice(n));return r?(e.w=Se.get(r[0].toLowerCase()),n+r[0].length):-1},b:function(e,t,n){var r=Ae.exec(t.slice(n));return r?(e.m=Ze.get(r[0].toLowerCase()),n+r[0].length):-1},B:function(e,t,n){var r=Le.exec(t.slice(n));return r?(e.m=He.get(r[0].toLowerCase()),n+r[0].length):-1},c:function(e,t,n){return qe(e,i,t,n)},d:w,e:w,f:A,g:C,G:D,H:Y,I:Y,j:S,L:H,m:p,M:F,p:function(e,t,n){var r=ge.exec(t.slice(n));return r?(e.p=pe.get(r[0].toLowerCase()),n+r[0].length):-1},q:x,Q:b,s:P,S:L,u:m,U:v,V:T,w:h,W:M,x:function(e,t,n){return qe(e,c,t,n)},X:function(e,t,n){return qe(e,a,t,n)},y:C,Y:D,Z:U,"%":Z};function Ve(e,t){return function(n){var r,u,i,c=[],a=-1,f=0,l=e.length;for(n instanceof Date||(n=new Date(+n));++a53)return null;"w"in f||(f.w=1),"Z"in f?(a=(o=r(u(f.y,0,1))).getUTCDay(),o=a>4||0===a?t.utcMonday.ceil(o):t.utcMonday(o),o=t.utcDay.offset(o,7*(f.V-1)),f.y=o.getUTCFullYear(),f.m=o.getUTCMonth(),f.d=o.getUTCDate()+(f.w+6)%7):(a=(o=n(u(f.y,0,1))).getDay(),o=a>4||0===a?t.timeMonday.ceil(o):t.timeMonday(o),o=t.timeDay.offset(o,7*(f.V-1)),f.y=o.getFullYear(),f.m=o.getMonth(),f.d=o.getDate()+(f.w+6)%7)}else("W"in f||"U"in f)&&("w"in f||(f.w="u"in f?f.u%7:"W"in f?1:0),a="Z"in f?r(u(f.y,0,1)).getUTCDay():n(u(f.y,0,1)).getDay(),f.m=0,f.d="W"in f?(f.w+6)%7+7*f.W-(a+5)%7:f.w+7*f.U-(a+6)%7);return"Z"in f?(f.H+=f.Z/100|0,f.M+=f.Z%100,r(f)):n(f)}}function qe(e,t,n,r){for(var u,i,c=0,a=t.length,f=n.length;c=f)return-1;if(37===(u=t.charCodeAt(c++))){if(u=t.charAt(c++),!(i=We[u in o?t.charAt(c++):u])||(r=i(e,n,r))<0)return-1}else if(u!=n.charCodeAt(r++))return-1}return r}return be.x=Ve(c,be),be.X=Ve(a,be),be.c=Ve(i,be),Pe.x=Ve(c,Pe),Pe.X=Ve(a,Pe),Pe.c=Ve(i,Pe),{format:function(e){var t=Ve(e+="",be);return t.toString=function(){return e},t},parse:function(e){var t=je(e+="",!1);return t.toString=function(){return e},t},utcFormat:function(e){var t=Ve(e+="",Pe);return t.toString=function(){return e},t},utcParse:function(e){var t=je(e+="",!0);return t.toString=function(){return e},t}}}var c,o={"-":"",_:" ",0:"0"},a=/^\s*\d+/,f=/^%/,l=/[\\^$*+?|[\]().{}]/g;function s(e,t,n){var r=e<0?"-":"",u=(r?-e:e)+"",i=u.length;return r+(i[e.toLowerCase(),t])))}function h(e,t,n){var r=a.exec(t.slice(n,n+1));return r?(e.w=+r[0],n+r[0].length):-1}function m(e,t,n){var r=a.exec(t.slice(n,n+1));return r?(e.u=+r[0],n+r[0].length):-1}function v(e,t,n){var r=a.exec(t.slice(n,n+2));return r?(e.U=+r[0],n+r[0].length):-1}function T(e,t,n){var r=a.exec(t.slice(n,n+2));return r?(e.V=+r[0],n+r[0].length):-1}function M(e,t,n){var r=a.exec(t.slice(n,n+2));return r?(e.W=+r[0],n+r[0].length):-1}function D(e,t,n){var r=a.exec(t.slice(n,n+4));return r?(e.y=+r[0],n+r[0].length):-1}function C(e,t,n){var r=a.exec(t.slice(n,n+2));return r?(e.y=+r[0]+(+r[0]>68?1900:2e3),n+r[0].length):-1}function U(e,t,n){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(t.slice(n,n+6));return r?(e.Z=r[1]?0:-(r[2]+(r[3]||"00")),n+r[0].length):-1}function x(e,t,n){var r=a.exec(t.slice(n,n+1));return r?(e.q=3*r[0]-3,n+r[0].length):-1}function p(e,t,n){var r=a.exec(t.slice(n,n+2));return r?(e.m=r[0]-1,n+r[0].length):-1}function w(e,t,n){var r=a.exec(t.slice(n,n+2));return r?(e.d=+r[0],n+r[0].length):-1}function S(e,t,n){var r=a.exec(t.slice(n,n+3));return r?(e.m=0,e.d=+r[0],n+r[0].length):-1}function Y(e,t,n){var r=a.exec(t.slice(n,n+2));return r?(e.H=+r[0],n+r[0].length):-1}function F(e,t,n){var r=a.exec(t.slice(n,n+2));return r?(e.M=+r[0],n+r[0].length):-1}function L(e,t,n){var r=a.exec(t.slice(n,n+2));return r?(e.S=+r[0],n+r[0].length):-1}function H(e,t,n){var r=a.exec(t.slice(n,n+3));return r?(e.L=+r[0],n+r[0].length):-1}function A(e,t,n){var r=a.exec(t.slice(n,n+6));return r?(e.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function Z(e,t,n){var r=f.exec(t.slice(n,n+1));return r?n+r[0].length:-1}function b(e,t,n){var r=a.exec(t.slice(n));return r?(e.Q=+r[0],n+r[0].length):-1}function P(e,t,n){var r=a.exec(t.slice(n));return r?(e.s=+r[0],n+r[0].length):-1}function W(e,t){return s(e.getDate(),t,2)}function V(e,t){return s(e.getHours(),t,2)}function j(e,t){return s(e.getHours()%12||12,t,2)}function q(e,n){return s(1+t.timeDay.count(t.timeYear(e),e),n,3)}function I(e,t){return s(e.getMilliseconds(),t,3)}function J(e,t){return I(e,t)+"000"}function O(e,t){return s(e.getMonth()+1,t,2)}function Q(e,t){return s(e.getMinutes(),t,2)}function X(e,t){return s(e.getSeconds(),t,2)}function N(e){var t=e.getDay();return 0===t?7:t}function B(e,n){return s(t.timeSunday.count(t.timeYear(e)-1,e),n,2)}function G(e){var n=e.getDay();return n>=4||0===n?t.timeThursday(e):t.timeThursday.ceil(e)}function _(e,n){return e=G(e),s(t.timeThursday.count(t.timeYear(e),e)+(4===t.timeYear(e).getDay()),n,2)}function $(e){return e.getDay()}function z(e,n){return s(t.timeMonday.count(t.timeYear(e)-1,e),n,2)}function E(e,t){return s(e.getFullYear()%100,t,2)}function R(e,t){return s((e=G(e)).getFullYear()%100,t,2)}function k(e,t){return s(e.getFullYear()%1e4,t,4)}function K(e,n){var r=e.getDay();return s((e=r>=4||0===r?t.timeThursday(e):t.timeThursday.ceil(e)).getFullYear()%1e4,n,4)}function ee(e){var t=e.getTimezoneOffset();return(t>0?"-":(t*=-1,"+"))+s(t/60|0,"0",2)+s(t%60,"0",2)}function te(e,t){return s(e.getUTCDate(),t,2)}function ne(e,t){return s(e.getUTCHours(),t,2)}function re(e,t){return s(e.getUTCHours()%12||12,t,2)}function ue(e,n){return s(1+t.utcDay.count(t.utcYear(e),e),n,3)}function ie(e,t){return s(e.getUTCMilliseconds(),t,3)}function ce(e,t){return ie(e,t)+"000"}function oe(e,t){return s(e.getUTCMonth()+1,t,2)}function ae(e,t){return s(e.getUTCMinutes(),t,2)}function fe(e,t){return s(e.getUTCSeconds(),t,2)}function le(e){var t=e.getUTCDay();return 0===t?7:t}function se(e,n){return s(t.utcSunday.count(t.utcYear(e)-1,e),n,2)}function ge(e){var n=e.getUTCDay();return n>=4||0===n?t.utcThursday(e):t.utcThursday.ceil(e)}function de(e,n){return e=ge(e),s(t.utcThursday.count(t.utcYear(e),e)+(4===t.utcYear(e).getUTCDay()),n,2)}function ye(e){return e.getUTCDay()}function he(e,n){return s(t.utcMonday.count(t.utcYear(e)-1,e),n,2)}function me(e,t){return s(e.getUTCFullYear()%100,t,2)}function ve(e,t){return s((e=ge(e)).getUTCFullYear()%100,t,2)}function Te(e,t){return s(e.getUTCFullYear()%1e4,t,4)}function Me(e,n){var r=e.getUTCDay();return s((e=r>=4||0===r?t.utcThursday(e):t.utcThursday.ceil(e)).getUTCFullYear()%1e4,n,4)}function De(){return"+0000"}function Ce(){return"%"}function Ue(e){return+e}function xe(e){return Math.floor(+e/1e3)}function pe(t){return c=i(t),e.timeFormat=c.format,e.timeParse=c.parse,e.utcFormat=c.utcFormat,e.utcParse=c.utcParse,c}e.timeFormat=void 0,e.timeParse=void 0,e.utcFormat=void 0,e.utcParse=void 0,pe({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});var we="%Y-%m-%dT%H:%M:%S.%LZ";var Se=Date.prototype.toISOString?function(e){return e.toISOString()}:e.utcFormat(we);var Ye=+new Date("2000-01-01T00:00:00.000Z")?function(e){var t=new Date(e);return isNaN(t)?null:t}:e.utcParse(we);e.isoFormat=Se,e.isoParse=Ye,e.timeFormatDefaultLocale=pe,e.timeFormatLocale=i,Object.defineProperty(e,"__esModule",{value:!0})}));
diff --git a/node_modules/d3-time-format/locale/ar-EG.json b/node_modules/d3-time-format/locale/ar-EG.json
new file mode 100644
index 00000000..8ac02650
--- /dev/null
+++ b/node_modules/d3-time-format/locale/ar-EG.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%x, %X",
+ "date": "%-d/%-m/%Y",
+ "time": "%-I:%M:%S %p",
+ "periods": ["ص", "م"],
+ "days": ["الأحد", "الإثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت"],
+ "shortDays": ["أحد", "إثنين", "ثلاثاء", "أربعاء", "خميس", "جمعة", "سبت"],
+ "months": ["يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو", "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر"],
+ "shortMonths": ["يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو", "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر"]
+}
diff --git a/node_modules/d3-time-format/locale/ar-SY.json b/node_modules/d3-time-format/locale/ar-SY.json
new file mode 100644
index 00000000..866fa5ef
--- /dev/null
+++ b/node_modules/d3-time-format/locale/ar-SY.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%x, %X",
+ "date": "%-d/%-m/%Y",
+ "time": "%-I:%M:%S %p",
+ "periods": ["ص", "م"],
+ "days": ["الأحد", "الإثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت"],
+ "shortDays": ["أحد", "إثنين", "ثلاثاء", "أربعاء", "خميس", "جمعة", "سبت"],
+ "months": ["كانون الثاني", "شباط", "آذار", "نيسان", "أيار", "حزيران", "تموز", "آب", "أيلول", "تشرين الأول", "تشرين الثاني", "كانون الأول"],
+ "shortMonths": ["ك٢", "شباط", "آذار", "نيسان", "أيار", "حزيران", "تموز", "آب", "أيلول", "ت١", "ت٢", "ك١"]
+}
diff --git a/node_modules/d3-time-format/locale/ca-ES.json b/node_modules/d3-time-format/locale/ca-ES.json
new file mode 100644
index 00000000..a2708735
--- /dev/null
+++ b/node_modules/d3-time-format/locale/ca-ES.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%A, %e de %B de %Y, %X",
+ "date": "%d/%m/%Y",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["diumenge", "dilluns", "dimarts", "dimecres", "dijous", "divendres", "dissabte"],
+ "shortDays": ["dg.", "dl.", "dt.", "dc.", "dj.", "dv.", "ds."],
+ "months": ["gener", "febrer", "març", "abril", "maig", "juny", "juliol", "agost", "setembre", "octubre", "novembre", "desembre"],
+ "shortMonths": ["gen.", "febr.", "març", "abr.", "maig", "juny", "jul.", "ag.", "set.", "oct.", "nov.", "des."]
+}
diff --git a/node_modules/d3-time-format/locale/cs-CZ.json b/node_modules/d3-time-format/locale/cs-CZ.json
new file mode 100644
index 00000000..ced34ea5
--- /dev/null
+++ b/node_modules/d3-time-format/locale/cs-CZ.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%A,%e.%B %Y, %X",
+ "date": "%-d.%-m.%Y",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["neděle", "pondělí", "úterý", "středa", "čvrtek", "pátek", "sobota"],
+ "shortDays": ["ne.", "po.", "út.", "st.", "čt.", "pá.", "so."],
+ "months": ["leden", "únor", "březen", "duben", "květen", "červen", "červenec", "srpen", "září", "říjen", "listopad", "prosinec"],
+ "shortMonths": ["led", "úno", "břez", "dub", "kvě", "čer", "červ", "srp", "zář", "říj", "list", "pros"]
+}
diff --git a/node_modules/d3-time-format/locale/da-DK.json b/node_modules/d3-time-format/locale/da-DK.json
new file mode 100644
index 00000000..f0c2349c
--- /dev/null
+++ b/node_modules/d3-time-format/locale/da-DK.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%A den %d %B %Y %X",
+ "date": "%d-%m-%Y",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["søndag", "mandag", "tirsdag", "onsdag", "torsdag", "fredag", "lørdag"],
+ "shortDays": ["søn", "man", "tir", "ons", "tor", "fre", "lør"],
+ "months": ["januar", "februar", "marts", "april", "maj", "juni", "juli", "august", "september", "oktober", "november", "december"],
+ "shortMonths": ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"]
+}
diff --git a/node_modules/d3-time-format/locale/de-CH.json b/node_modules/d3-time-format/locale/de-CH.json
new file mode 100644
index 00000000..466b749b
--- /dev/null
+++ b/node_modules/d3-time-format/locale/de-CH.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%A, der %e. %B %Y, %X",
+ "date": "%d.%m.%Y",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"],
+ "shortDays": ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"],
+ "months": ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"],
+ "shortMonths": ["Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"]
+}
diff --git a/node_modules/d3-time-format/locale/de-DE.json b/node_modules/d3-time-format/locale/de-DE.json
new file mode 100644
index 00000000..466b749b
--- /dev/null
+++ b/node_modules/d3-time-format/locale/de-DE.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%A, der %e. %B %Y, %X",
+ "date": "%d.%m.%Y",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"],
+ "shortDays": ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"],
+ "months": ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"],
+ "shortMonths": ["Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"]
+}
diff --git a/node_modules/d3-time-format/locale/en-CA.json b/node_modules/d3-time-format/locale/en-CA.json
new file mode 100644
index 00000000..5c13ae3c
--- /dev/null
+++ b/node_modules/d3-time-format/locale/en-CA.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%a %b %e %X %Y",
+ "date": "%Y-%m-%d",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
+ "shortDays": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
+ "months": ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
+ "shortMonths": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+}
diff --git a/node_modules/d3-time-format/locale/en-GB.json b/node_modules/d3-time-format/locale/en-GB.json
new file mode 100644
index 00000000..9f651c5c
--- /dev/null
+++ b/node_modules/d3-time-format/locale/en-GB.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%a %e %b %X %Y",
+ "date": "%d/%m/%Y",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
+ "shortDays": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
+ "months": ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
+ "shortMonths": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+}
diff --git a/node_modules/d3-time-format/locale/en-US.json b/node_modules/d3-time-format/locale/en-US.json
new file mode 100644
index 00000000..a7ac9513
--- /dev/null
+++ b/node_modules/d3-time-format/locale/en-US.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%x, %X",
+ "date": "%-m/%-d/%Y",
+ "time": "%-I:%M:%S %p",
+ "periods": ["AM", "PM"],
+ "days": ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
+ "shortDays": ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
+ "months": ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
+ "shortMonths": ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+}
diff --git a/node_modules/d3-time-format/locale/es-ES.json b/node_modules/d3-time-format/locale/es-ES.json
new file mode 100644
index 00000000..8c5f754f
--- /dev/null
+++ b/node_modules/d3-time-format/locale/es-ES.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%A, %e de %B de %Y, %X",
+ "date": "%d/%m/%Y",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado"],
+ "shortDays": ["dom", "lun", "mar", "mié", "jue", "vie", "sáb"],
+ "months": ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"],
+ "shortMonths": ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"]
+}
diff --git a/node_modules/d3-time-format/locale/es-MX.json b/node_modules/d3-time-format/locale/es-MX.json
new file mode 100644
index 00000000..4dc2077e
--- /dev/null
+++ b/node_modules/d3-time-format/locale/es-MX.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%x, %X",
+ "date": "%d/%m/%Y",
+ "time": "%-I:%M:%S %p",
+ "periods": ["AM", "PM"],
+ "days": ["domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado"],
+ "shortDays": ["dom", "lun", "mar", "mié", "jue", "vie", "sáb"],
+ "months": ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"],
+ "shortMonths": ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"]
+}
diff --git a/node_modules/d3-time-format/locale/fa-IR.json b/node_modules/d3-time-format/locale/fa-IR.json
new file mode 100644
index 00000000..badff07b
--- /dev/null
+++ b/node_modules/d3-time-format/locale/fa-IR.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%x, %X",
+ "date": "%-d/%-m/%Y",
+ "time": "%-I:%M:%S %p",
+ "periods": ["صبح", "عصر"],
+ "days": ["یکشنبه", "دوشنبه", "سه شنبه", "چهارشنبه", "پنجشنبه", "جمعه", "شنبه"],
+ "shortDays": ["یکشنبه", "دوشنبه", "سه شنبه", "چهارشنبه", "پنجشنبه", "جمعه", "شنبه"],
+ "months": ["ژانویه", "فوریه", "مارس", "آوریل", "مه", "ژوئن", "ژوئیه", "اوت", "سپتامبر", "اکتبر", "نوامبر", "دسامبر"],
+ "shortMonths": ["ژانویه", "فوریه", "مارس", "آوریل", "مه", "ژوئن", "ژوئیه", "اوت", "سپتامبر", "اکتبر", "نوامبر", "دسامبر"]
+}
diff --git a/node_modules/d3-time-format/locale/fi-FI.json b/node_modules/d3-time-format/locale/fi-FI.json
new file mode 100644
index 00000000..2422199e
--- /dev/null
+++ b/node_modules/d3-time-format/locale/fi-FI.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%A, %-d. %Bta %Y klo %X",
+ "date": "%-d.%-m.%Y",
+ "time": "%H:%M:%S",
+ "periods": ["a.m.", "p.m."],
+ "days": ["sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai"],
+ "shortDays": ["Su", "Ma", "Ti", "Ke", "To", "Pe", "La"],
+ "months": ["tammikuu", "helmikuu", "maaliskuu", "huhtikuu", "toukokuu", "kesäkuu", "heinäkuu", "elokuu", "syyskuu", "lokakuu", "marraskuu", "joulukuu"],
+ "shortMonths": ["Tammi", "Helmi", "Maalis", "Huhti", "Touko", "Kesä", "Heinä", "Elo", "Syys", "Loka", "Marras", "Joulu"]
+}
diff --git a/node_modules/d3-time-format/locale/fr-CA.json b/node_modules/d3-time-format/locale/fr-CA.json
new file mode 100644
index 00000000..1300cabd
--- /dev/null
+++ b/node_modules/d3-time-format/locale/fr-CA.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%a %e %b %Y %X",
+ "date": "%Y-%m-%d",
+ "time": "%H:%M:%S",
+ "periods": ["", ""],
+ "days": ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"],
+ "shortDays": ["dim", "lun", "mar", "mer", "jeu", "ven", "sam"],
+ "months": ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"],
+ "shortMonths": ["jan", "fév", "mar", "avr", "mai", "jui", "jul", "aoû", "sep", "oct", "nov", "déc"]
+}
diff --git a/node_modules/d3-time-format/locale/fr-FR.json b/node_modules/d3-time-format/locale/fr-FR.json
new file mode 100644
index 00000000..6ac05ee2
--- /dev/null
+++ b/node_modules/d3-time-format/locale/fr-FR.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%A %e %B %Y à %X",
+ "date": "%d/%m/%Y",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"],
+ "shortDays": ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."],
+ "months": ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"],
+ "shortMonths": ["janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc."]
+}
diff --git a/node_modules/d3-time-format/locale/he-IL.json b/node_modules/d3-time-format/locale/he-IL.json
new file mode 100644
index 00000000..0ce27cdd
--- /dev/null
+++ b/node_modules/d3-time-format/locale/he-IL.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%A, %e ב%B %Y %X",
+ "date": "%d.%m.%Y",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["ראשון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת"],
+ "shortDays": ["א׳", "ב׳", "ג׳", "ד׳", "ה׳", "ו׳", "ש׳"],
+ "months": ["ינואר", "פברואר", "מרץ", "אפריל", "מאי", "יוני", "יולי", "אוגוסט", "ספטמבר", "אוקטובר", "נובמבר", "דצמבר"],
+ "shortMonths": ["ינו׳", "פבר׳", "מרץ", "אפר׳", "מאי", "יוני", "יולי", "אוג׳", "ספט׳", "אוק׳", "נוב׳", "דצמ׳"]
+}
diff --git a/node_modules/d3-time-format/locale/hr-HR.json b/node_modules/d3-time-format/locale/hr-HR.json
new file mode 100644
index 00000000..b82dea66
--- /dev/null
+++ b/node_modules/d3-time-format/locale/hr-HR.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%A, %e. %B %Y., %X",
+ "date": "%d. %m. %Y.",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["Nedjelja", "Ponedjeljak", "Utorak", "Srijeda", "Četvtrak", "Petak", "Subota"],
+ "shortDays": ["Ne", "Po", "Ut", "Sr", "Če", "Pe", "Su"],
+ "months": ["Siječanj", "Veljača", "Ožujak", "Travanj", "Svibanj", "Lipanj", "Srpanj", "Kolovoz", "Rujan", "Listopad", "Studeni", "Prosinac"],
+ "shortMonths": ["Sij", "Velj", "Ožu", "Tra", "Svi", "Lip", "Srp", "Kol", "Ruj", "Lis", "Stu", "Pro"]
+}
diff --git a/node_modules/d3-time-format/locale/hu-HU.json b/node_modules/d3-time-format/locale/hu-HU.json
new file mode 100644
index 00000000..d81acf22
--- /dev/null
+++ b/node_modules/d3-time-format/locale/hu-HU.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%Y. %B %-e., %A %X",
+ "date": "%Y. %m. %d.",
+ "time": "%H:%M:%S",
+ "periods": ["de.", "du."],
+ "days": ["vasárnap", "hétfő", "kedd", "szerda", "csütörtök", "péntek", "szombat"],
+ "shortDays": ["V", "H", "K", "Sze", "Cs", "P", "Szo"],
+ "months": ["január", "február", "március", "április", "május", "június", "július", "augusztus", "szeptember", "október", "november", "december"],
+ "shortMonths": ["jan.", "feb.", "már.", "ápr.", "máj.", "jún.", "júl.", "aug.", "szept.", "okt.", "nov.", "dec."]
+}
diff --git a/node_modules/d3-time-format/locale/it-IT.json b/node_modules/d3-time-format/locale/it-IT.json
new file mode 100644
index 00000000..0fc08e02
--- /dev/null
+++ b/node_modules/d3-time-format/locale/it-IT.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%A %e %B %Y, %X",
+ "date": "%d/%m/%Y",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"],
+ "shortDays": ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"],
+ "months": ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"],
+ "shortMonths": ["Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"]
+}
diff --git a/node_modules/d3-time-format/locale/ja-JP.json b/node_modules/d3-time-format/locale/ja-JP.json
new file mode 100644
index 00000000..72c460d7
--- /dev/null
+++ b/node_modules/d3-time-format/locale/ja-JP.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%x %a %X",
+ "date": "%Y/%m/%d",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"],
+ "shortDays": ["日", "月", "火", "水", "木", "金", "土"],
+ "months": ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
+ "shortMonths": ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"]
+}
diff --git a/node_modules/d3-time-format/locale/ko-KR.json b/node_modules/d3-time-format/locale/ko-KR.json
new file mode 100644
index 00000000..7055666a
--- /dev/null
+++ b/node_modules/d3-time-format/locale/ko-KR.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%Y/%m/%d %a %X",
+ "date": "%Y/%m/%d",
+ "time": "%H:%M:%S",
+ "periods": ["오전", "오후"],
+ "days": ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"],
+ "shortDays": ["일", "월", "화", "수", "목", "금", "토"],
+ "months": ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"],
+ "shortMonths": ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"]
+}
diff --git a/node_modules/d3-time-format/locale/mk-MK.json b/node_modules/d3-time-format/locale/mk-MK.json
new file mode 100644
index 00000000..4a47fd11
--- /dev/null
+++ b/node_modules/d3-time-format/locale/mk-MK.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%A, %e %B %Y г. %X",
+ "date": "%d.%m.%Y",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["недела", "понеделник", "вторник", "среда", "четврток", "петок", "сабота"],
+ "shortDays": ["нед", "пон", "вто", "сре", "чет", "пет", "саб"],
+ "months": ["јануари", "февруари", "март", "април", "мај", "јуни", "јули", "август", "септември", "октомври", "ноември", "декември"],
+ "shortMonths": ["јан", "фев", "мар", "апр", "мај", "јун", "јул", "авг", "сеп", "окт", "ное", "дек"]
+}
diff --git a/node_modules/d3-time-format/locale/nb-NO.json b/node_modules/d3-time-format/locale/nb-NO.json
new file mode 100644
index 00000000..a8bfd20e
--- /dev/null
+++ b/node_modules/d3-time-format/locale/nb-NO.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%A den %d. %B %Y %X",
+ "date": "%d.%m.%Y",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["søndag", "mandag", "tirsdag", "onsdag", "torsdag", "fredag", "lørdag"],
+ "shortDays": ["søn", "man", "tir", "ons", "tor", "fre", "lør"],
+ "months": ["januar", "februar", "mars", "april", "mai", "juni", "juli", "august", "september", "oktober", "november", "desember"],
+ "shortMonths": ["jan", "feb", "mars", "apr", "mai", "juni", "juli", "aug", "sep", "okt", "nov", "des"]
+}
diff --git a/node_modules/d3-time-format/locale/nl-BE.json b/node_modules/d3-time-format/locale/nl-BE.json
new file mode 100644
index 00000000..69d587e8
--- /dev/null
+++ b/node_modules/d3-time-format/locale/nl-BE.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%a %e %B %Y %X",
+ "date": "%d/%m/%Y",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"],
+ "shortDays": ["zo", "ma", "di", "wo", "do", "vr", "za"],
+ "months": ["januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"],
+ "shortMonths": ["jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec"]
+}
diff --git a/node_modules/d3-time-format/locale/nl-NL.json b/node_modules/d3-time-format/locale/nl-NL.json
new file mode 100644
index 00000000..375b0feb
--- /dev/null
+++ b/node_modules/d3-time-format/locale/nl-NL.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%a %e %B %Y %X",
+ "date": "%d-%m-%Y",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"],
+ "shortDays": ["zo", "ma", "di", "wo", "do", "vr", "za"],
+ "months": ["januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"],
+ "shortMonths": ["jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec"]
+}
diff --git a/node_modules/d3-time-format/locale/pl-PL.json b/node_modules/d3-time-format/locale/pl-PL.json
new file mode 100644
index 00000000..616b4cd1
--- /dev/null
+++ b/node_modules/d3-time-format/locale/pl-PL.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%A, %e %B %Y, %X",
+ "date": "%d/%m/%Y",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota"],
+ "shortDays": ["Niedz.", "Pon.", "Wt.", "Śr.", "Czw.", "Pt.", "Sob."],
+ "months": ["Styczeń", "Luty", "Marzec", "Kwiecień", "Maj", "Czerwiec", "Lipiec", "Sierpień", "Wrzesień", "Październik", "Listopad", "Grudzień"],
+ "shortMonths": ["Stycz.", "Luty", "Marz.", "Kwie.", "Maj", "Czerw.", "Lipc.", "Sierp.", "Wrz.", "Paźdz.", "Listop.", "Grudz."]
+}
diff --git a/node_modules/d3-time-format/locale/pt-BR.json b/node_modules/d3-time-format/locale/pt-BR.json
new file mode 100644
index 00000000..4e9ff893
--- /dev/null
+++ b/node_modules/d3-time-format/locale/pt-BR.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%A, %e de %B de %Y. %X",
+ "date": "%d/%m/%Y",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"],
+ "shortDays": ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"],
+ "months": ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"],
+ "shortMonths": ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"]
+}
diff --git a/node_modules/d3-time-format/locale/ru-RU.json b/node_modules/d3-time-format/locale/ru-RU.json
new file mode 100644
index 00000000..c0423183
--- /dev/null
+++ b/node_modules/d3-time-format/locale/ru-RU.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%A, %e %B %Y г. %X",
+ "date": "%d.%m.%Y",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["воскресенье", "понедельник", "вторник", "среда", "четверг", "пятница", "суббота"],
+ "shortDays": ["вс", "пн", "вт", "ср", "чт", "пт", "сб"],
+ "months": ["января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"],
+ "shortMonths": ["янв", "фев", "мар", "апр", "май", "июн", "июл", "авг", "сен", "окт", "ноя", "дек"]
+}
diff --git a/node_modules/d3-time-format/locale/sv-SE.json b/node_modules/d3-time-format/locale/sv-SE.json
new file mode 100644
index 00000000..23183880
--- /dev/null
+++ b/node_modules/d3-time-format/locale/sv-SE.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%A den %d %B %Y %X",
+ "date": "%Y-%m-%d",
+ "time": "%H:%M:%S",
+ "periods": ["fm", "em"],
+ "days": ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"],
+ "shortDays": ["Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"],
+ "months": ["Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"],
+ "shortMonths": ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"]
+}
diff --git a/node_modules/d3-time-format/locale/tr-TR.json b/node_modules/d3-time-format/locale/tr-TR.json
new file mode 100644
index 00000000..ea0557e1
--- /dev/null
+++ b/node_modules/d3-time-format/locale/tr-TR.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%a %e %b %X %Y",
+ "date": "%d/%m/%Y",
+ "time": "%H:%M:%S",
+ "periods": ["AM", "PM"],
+ "days": ["Pazar", "Pazartesi", "Salı", "Çarşamba", "Perşembe", "Cuma", "Cumartesi"],
+ "shortDays": ["Paz", "Pzt", "Sal", "Çar", "Per", "Cum", "Cmt"],
+ "months": ["Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık"],
+ "shortMonths": ["Oca", "Şub", "Mar", "Nis", "May", "Haz", "Tem", "Ağu", "Eyl", "Eki", "Kas", "Ara"]
+}
diff --git a/node_modules/d3-time-format/locale/uk-UA.json b/node_modules/d3-time-format/locale/uk-UA.json
new file mode 100644
index 00000000..555eed4a
--- /dev/null
+++ b/node_modules/d3-time-format/locale/uk-UA.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%A, %e %B %Y р. %X",
+ "date": "%d.%m.%Y",
+ "time": "%H:%M:%S",
+ "periods": ["дп", "пп"],
+ "days": ["неділя", "понеділок", "вівторок", "середа", "четвер", "п'ятниця", "субота"],
+ "shortDays": ["нд", "пн", "вт", "ср", "чт", "пт", "сб"],
+ "months": ["січня", "лютого", "березня", "квітня", "травня", "червня", "липня", "серпня", "вересня", "жовтня", "листопада", "грудня"],
+ "shortMonths": ["січ.", "лют.", "бер.", "квіт.", "трав.", "черв.", "лип.", "серп.", "вер.", "жовт.", "лист.", "груд."]
+}
diff --git a/node_modules/d3-time-format/locale/zh-CN.json b/node_modules/d3-time-format/locale/zh-CN.json
new file mode 100644
index 00000000..762f212a
--- /dev/null
+++ b/node_modules/d3-time-format/locale/zh-CN.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%x %A %X",
+ "date": "%Y年%-m月%-d日",
+ "time": "%H:%M:%S",
+ "periods": ["上午", "下午"],
+ "days": ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
+ "shortDays": ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
+ "months": ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
+ "shortMonths": ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"]
+}
diff --git a/node_modules/d3-time-format/locale/zh-TW.json b/node_modules/d3-time-format/locale/zh-TW.json
new file mode 100644
index 00000000..767b2baf
--- /dev/null
+++ b/node_modules/d3-time-format/locale/zh-TW.json
@@ -0,0 +1,10 @@
+{
+ "dateTime": "%x %A %X",
+ "date": "%Y年%-m月%-d日",
+ "time": "%H:%M:%S",
+ "periods": ["上午", "下午"],
+ "days": ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
+ "shortDays": ["日", "一", "二", "三", "四", "五", "六"],
+ "months": ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
+ "shortMonths": ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"]
+}
diff --git a/node_modules/d3-time-format/package.json b/node_modules/d3-time-format/package.json
new file mode 100644
index 00000000..6fbba893
--- /dev/null
+++ b/node_modules/d3-time-format/package.json
@@ -0,0 +1,89 @@
+{
+ "_from": "d3-time-format@4",
+ "_id": "d3-time-format@4.1.0",
+ "_inBundle": false,
+ "_integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
+ "_location": "/d3-time-format",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "range",
+ "registry": true,
+ "raw": "d3-time-format@4",
+ "name": "d3-time-format",
+ "escapedName": "d3-time-format",
+ "rawSpec": "4",
+ "saveSpec": null,
+ "fetchSpec": "4"
+ },
+ "_requiredBy": [
+ "/d3",
+ "/d3-scale"
+ ],
+ "_resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
+ "_shasum": "7ab5257a5041d11ecb4fe70a5c7d16a195bb408a",
+ "_spec": "d3-time-format@4",
+ "_where": "C:\\Users\\colbs\\CS4241\\d3a4\\node_modules\\d3",
+ "author": {
+ "name": "Mike Bostock",
+ "url": "http://bost.ocks.org/mike"
+ },
+ "bugs": {
+ "url": "https://github.com/d3/d3-time-format/issues"
+ },
+ "bundleDependencies": false,
+ "dependencies": {
+ "d3-time": "1 - 3"
+ },
+ "deprecated": false,
+ "description": "A JavaScript time formatter and parser inspired by strftime and strptime.",
+ "devDependencies": {
+ "eslint": "8",
+ "mocha": "9",
+ "rollup": "2",
+ "rollup-plugin-terser": "7"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "exports": {
+ ".": {
+ "umd": "./dist/d3-time-format.min.js",
+ "default": "./src/index.js"
+ },
+ "./locale/*": "./locale/*.json"
+ },
+ "files": [
+ "dist/**/*.js",
+ "src/**/*.js",
+ "locale/*.json"
+ ],
+ "homepage": "https://d3js.org/d3-time-format/",
+ "jsdelivr": "dist/d3-time-format.min.js",
+ "keywords": [
+ "d3",
+ "d3-module",
+ "time",
+ "format",
+ "strftime",
+ "strptime"
+ ],
+ "license": "ISC",
+ "main": "src/index.js",
+ "module": "src/index.js",
+ "name": "d3-time-format",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/d3/d3-time-format.git"
+ },
+ "scripts": {
+ "postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -",
+ "prepublishOnly": "rm -rf dist && yarn test && rollup -c",
+ "test": "TZ=America/Los_Angeles mocha 'test/**/*-test.js' && eslint src test"
+ },
+ "sideEffects": [
+ "./src/defaultLocale.js"
+ ],
+ "type": "module",
+ "unpkg": "dist/d3-time-format.min.js",
+ "version": "4.1.0"
+}
diff --git a/node_modules/d3-time-format/src/defaultLocale.js b/node_modules/d3-time-format/src/defaultLocale.js
new file mode 100644
index 00000000..d762db51
--- /dev/null
+++ b/node_modules/d3-time-format/src/defaultLocale.js
@@ -0,0 +1,27 @@
+import formatLocale from "./locale.js";
+
+var locale;
+export var timeFormat;
+export var timeParse;
+export var utcFormat;
+export var utcParse;
+
+defaultLocale({
+ dateTime: "%x, %X",
+ date: "%-m/%-d/%Y",
+ time: "%-I:%M:%S %p",
+ periods: ["AM", "PM"],
+ days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
+ shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
+ months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
+ shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
+});
+
+export default function defaultLocale(definition) {
+ locale = formatLocale(definition);
+ timeFormat = locale.format;
+ timeParse = locale.parse;
+ utcFormat = locale.utcFormat;
+ utcParse = locale.utcParse;
+ return locale;
+}
diff --git a/node_modules/d3-time-format/src/index.js b/node_modules/d3-time-format/src/index.js
new file mode 100644
index 00000000..6c93971d
--- /dev/null
+++ b/node_modules/d3-time-format/src/index.js
@@ -0,0 +1,4 @@
+export {default as timeFormatDefaultLocale, timeFormat, timeParse, utcFormat, utcParse} from "./defaultLocale.js";
+export {default as timeFormatLocale} from "./locale.js";
+export {default as isoFormat} from "./isoFormat.js";
+export {default as isoParse} from "./isoParse.js";
diff --git a/node_modules/d3-time-format/src/isoFormat.js b/node_modules/d3-time-format/src/isoFormat.js
new file mode 100644
index 00000000..43185a37
--- /dev/null
+++ b/node_modules/d3-time-format/src/isoFormat.js
@@ -0,0 +1,13 @@
+import {utcFormat} from "./defaultLocale.js";
+
+export var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ";
+
+function formatIsoNative(date) {
+ return date.toISOString();
+}
+
+var formatIso = Date.prototype.toISOString
+ ? formatIsoNative
+ : utcFormat(isoSpecifier);
+
+export default formatIso;
diff --git a/node_modules/d3-time-format/src/isoParse.js b/node_modules/d3-time-format/src/isoParse.js
new file mode 100644
index 00000000..381d1c96
--- /dev/null
+++ b/node_modules/d3-time-format/src/isoParse.js
@@ -0,0 +1,13 @@
+import {isoSpecifier} from "./isoFormat.js";
+import {utcParse} from "./defaultLocale.js";
+
+function parseIsoNative(string) {
+ var date = new Date(string);
+ return isNaN(date) ? null : date;
+}
+
+var parseIso = +new Date("2000-01-01T00:00:00.000Z")
+ ? parseIsoNative
+ : utcParse(isoSpecifier);
+
+export default parseIso;
diff --git a/node_modules/d3-time-format/src/locale.js b/node_modules/d3-time-format/src/locale.js
new file mode 100644
index 00000000..cc0dac25
--- /dev/null
+++ b/node_modules/d3-time-format/src/locale.js
@@ -0,0 +1,697 @@
+import {
+ timeDay,
+ timeSunday,
+ timeMonday,
+ timeThursday,
+ timeYear,
+ utcDay,
+ utcSunday,
+ utcMonday,
+ utcThursday,
+ utcYear
+} from "d3-time";
+
+function localDate(d) {
+ if (0 <= d.y && d.y < 100) {
+ var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L);
+ date.setFullYear(d.y);
+ return date;
+ }
+ return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L);
+}
+
+function utcDate(d) {
+ if (0 <= d.y && d.y < 100) {
+ var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L));
+ date.setUTCFullYear(d.y);
+ return date;
+ }
+ return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L));
+}
+
+function newDate(y, m, d) {
+ return {y: y, m: m, d: d, H: 0, M: 0, S: 0, L: 0};
+}
+
+export default function formatLocale(locale) {
+ var locale_dateTime = locale.dateTime,
+ locale_date = locale.date,
+ locale_time = locale.time,
+ locale_periods = locale.periods,
+ locale_weekdays = locale.days,
+ locale_shortWeekdays = locale.shortDays,
+ locale_months = locale.months,
+ locale_shortMonths = locale.shortMonths;
+
+ var periodRe = formatRe(locale_periods),
+ periodLookup = formatLookup(locale_periods),
+ weekdayRe = formatRe(locale_weekdays),
+ weekdayLookup = formatLookup(locale_weekdays),
+ shortWeekdayRe = formatRe(locale_shortWeekdays),
+ shortWeekdayLookup = formatLookup(locale_shortWeekdays),
+ monthRe = formatRe(locale_months),
+ monthLookup = formatLookup(locale_months),
+ shortMonthRe = formatRe(locale_shortMonths),
+ shortMonthLookup = formatLookup(locale_shortMonths);
+
+ var formats = {
+ "a": formatShortWeekday,
+ "A": formatWeekday,
+ "b": formatShortMonth,
+ "B": formatMonth,
+ "c": null,
+ "d": formatDayOfMonth,
+ "e": formatDayOfMonth,
+ "f": formatMicroseconds,
+ "g": formatYearISO,
+ "G": formatFullYearISO,
+ "H": formatHour24,
+ "I": formatHour12,
+ "j": formatDayOfYear,
+ "L": formatMilliseconds,
+ "m": formatMonthNumber,
+ "M": formatMinutes,
+ "p": formatPeriod,
+ "q": formatQuarter,
+ "Q": formatUnixTimestamp,
+ "s": formatUnixTimestampSeconds,
+ "S": formatSeconds,
+ "u": formatWeekdayNumberMonday,
+ "U": formatWeekNumberSunday,
+ "V": formatWeekNumberISO,
+ "w": formatWeekdayNumberSunday,
+ "W": formatWeekNumberMonday,
+ "x": null,
+ "X": null,
+ "y": formatYear,
+ "Y": formatFullYear,
+ "Z": formatZone,
+ "%": formatLiteralPercent
+ };
+
+ var utcFormats = {
+ "a": formatUTCShortWeekday,
+ "A": formatUTCWeekday,
+ "b": formatUTCShortMonth,
+ "B": formatUTCMonth,
+ "c": null,
+ "d": formatUTCDayOfMonth,
+ "e": formatUTCDayOfMonth,
+ "f": formatUTCMicroseconds,
+ "g": formatUTCYearISO,
+ "G": formatUTCFullYearISO,
+ "H": formatUTCHour24,
+ "I": formatUTCHour12,
+ "j": formatUTCDayOfYear,
+ "L": formatUTCMilliseconds,
+ "m": formatUTCMonthNumber,
+ "M": formatUTCMinutes,
+ "p": formatUTCPeriod,
+ "q": formatUTCQuarter,
+ "Q": formatUnixTimestamp,
+ "s": formatUnixTimestampSeconds,
+ "S": formatUTCSeconds,
+ "u": formatUTCWeekdayNumberMonday,
+ "U": formatUTCWeekNumberSunday,
+ "V": formatUTCWeekNumberISO,
+ "w": formatUTCWeekdayNumberSunday,
+ "W": formatUTCWeekNumberMonday,
+ "x": null,
+ "X": null,
+ "y": formatUTCYear,
+ "Y": formatUTCFullYear,
+ "Z": formatUTCZone,
+ "%": formatLiteralPercent
+ };
+
+ var parses = {
+ "a": parseShortWeekday,
+ "A": parseWeekday,
+ "b": parseShortMonth,
+ "B": parseMonth,
+ "c": parseLocaleDateTime,
+ "d": parseDayOfMonth,
+ "e": parseDayOfMonth,
+ "f": parseMicroseconds,
+ "g": parseYear,
+ "G": parseFullYear,
+ "H": parseHour24,
+ "I": parseHour24,
+ "j": parseDayOfYear,
+ "L": parseMilliseconds,
+ "m": parseMonthNumber,
+ "M": parseMinutes,
+ "p": parsePeriod,
+ "q": parseQuarter,
+ "Q": parseUnixTimestamp,
+ "s": parseUnixTimestampSeconds,
+ "S": parseSeconds,
+ "u": parseWeekdayNumberMonday,
+ "U": parseWeekNumberSunday,
+ "V": parseWeekNumberISO,
+ "w": parseWeekdayNumberSunday,
+ "W": parseWeekNumberMonday,
+ "x": parseLocaleDate,
+ "X": parseLocaleTime,
+ "y": parseYear,
+ "Y": parseFullYear,
+ "Z": parseZone,
+ "%": parseLiteralPercent
+ };
+
+ // These recursive directive definitions must be deferred.
+ formats.x = newFormat(locale_date, formats);
+ formats.X = newFormat(locale_time, formats);
+ formats.c = newFormat(locale_dateTime, formats);
+ utcFormats.x = newFormat(locale_date, utcFormats);
+ utcFormats.X = newFormat(locale_time, utcFormats);
+ utcFormats.c = newFormat(locale_dateTime, utcFormats);
+
+ function newFormat(specifier, formats) {
+ return function(date) {
+ var string = [],
+ i = -1,
+ j = 0,
+ n = specifier.length,
+ c,
+ pad,
+ format;
+
+ if (!(date instanceof Date)) date = new Date(+date);
+
+ while (++i < n) {
+ if (specifier.charCodeAt(i) === 37) {
+ string.push(specifier.slice(j, i));
+ if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);
+ else pad = c === "e" ? " " : "0";
+ if (format = formats[c]) c = format(date, pad);
+ string.push(c);
+ j = i + 1;
+ }
+ }
+
+ string.push(specifier.slice(j, i));
+ return string.join("");
+ };
+ }
+
+ function newParse(specifier, Z) {
+ return function(string) {
+ var d = newDate(1900, undefined, 1),
+ i = parseSpecifier(d, specifier, string += "", 0),
+ week, day;
+ if (i != string.length) return null;
+
+ // If a UNIX timestamp is specified, return it.
+ if ("Q" in d) return new Date(d.Q);
+ if ("s" in d) return new Date(d.s * 1000 + ("L" in d ? d.L : 0));
+
+ // If this is utcParse, never use the local timezone.
+ if (Z && !("Z" in d)) d.Z = 0;
+
+ // The am-pm flag is 0 for AM, and 1 for PM.
+ if ("p" in d) d.H = d.H % 12 + d.p * 12;
+
+ // If the month was not specified, inherit from the quarter.
+ if (d.m === undefined) d.m = "q" in d ? d.q : 0;
+
+ // Convert day-of-week and week-of-year to day-of-year.
+ if ("V" in d) {
+ if (d.V < 1 || d.V > 53) return null;
+ if (!("w" in d)) d.w = 1;
+ if ("Z" in d) {
+ week = utcDate(newDate(d.y, 0, 1)), day = week.getUTCDay();
+ week = day > 4 || day === 0 ? utcMonday.ceil(week) : utcMonday(week);
+ week = utcDay.offset(week, (d.V - 1) * 7);
+ d.y = week.getUTCFullYear();
+ d.m = week.getUTCMonth();
+ d.d = week.getUTCDate() + (d.w + 6) % 7;
+ } else {
+ week = localDate(newDate(d.y, 0, 1)), day = week.getDay();
+ week = day > 4 || day === 0 ? timeMonday.ceil(week) : timeMonday(week);
+ week = timeDay.offset(week, (d.V - 1) * 7);
+ d.y = week.getFullYear();
+ d.m = week.getMonth();
+ d.d = week.getDate() + (d.w + 6) % 7;
+ }
+ } else if ("W" in d || "U" in d) {
+ if (!("w" in d)) d.w = "u" in d ? d.u % 7 : "W" in d ? 1 : 0;
+ day = "Z" in d ? utcDate(newDate(d.y, 0, 1)).getUTCDay() : localDate(newDate(d.y, 0, 1)).getDay();
+ d.m = 0;
+ d.d = "W" in d ? (d.w + 6) % 7 + d.W * 7 - (day + 5) % 7 : d.w + d.U * 7 - (day + 6) % 7;
+ }
+
+ // If a time zone is specified, all fields are interpreted as UTC and then
+ // offset according to the specified time zone.
+ if ("Z" in d) {
+ d.H += d.Z / 100 | 0;
+ d.M += d.Z % 100;
+ return utcDate(d);
+ }
+
+ // Otherwise, all fields are in local time.
+ return localDate(d);
+ };
+ }
+
+ function parseSpecifier(d, specifier, string, j) {
+ var i = 0,
+ n = specifier.length,
+ m = string.length,
+ c,
+ parse;
+
+ while (i < n) {
+ if (j >= m) return -1;
+ c = specifier.charCodeAt(i++);
+ if (c === 37) {
+ c = specifier.charAt(i++);
+ parse = parses[c in pads ? specifier.charAt(i++) : c];
+ if (!parse || ((j = parse(d, string, j)) < 0)) return -1;
+ } else if (c != string.charCodeAt(j++)) {
+ return -1;
+ }
+ }
+
+ return j;
+ }
+
+ function parsePeriod(d, string, i) {
+ var n = periodRe.exec(string.slice(i));
+ return n ? (d.p = periodLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
+ }
+
+ function parseShortWeekday(d, string, i) {
+ var n = shortWeekdayRe.exec(string.slice(i));
+ return n ? (d.w = shortWeekdayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
+ }
+
+ function parseWeekday(d, string, i) {
+ var n = weekdayRe.exec(string.slice(i));
+ return n ? (d.w = weekdayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
+ }
+
+ function parseShortMonth(d, string, i) {
+ var n = shortMonthRe.exec(string.slice(i));
+ return n ? (d.m = shortMonthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
+ }
+
+ function parseMonth(d, string, i) {
+ var n = monthRe.exec(string.slice(i));
+ return n ? (d.m = monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1;
+ }
+
+ function parseLocaleDateTime(d, string, i) {
+ return parseSpecifier(d, locale_dateTime, string, i);
+ }
+
+ function parseLocaleDate(d, string, i) {
+ return parseSpecifier(d, locale_date, string, i);
+ }
+
+ function parseLocaleTime(d, string, i) {
+ return parseSpecifier(d, locale_time, string, i);
+ }
+
+ function formatShortWeekday(d) {
+ return locale_shortWeekdays[d.getDay()];
+ }
+
+ function formatWeekday(d) {
+ return locale_weekdays[d.getDay()];
+ }
+
+ function formatShortMonth(d) {
+ return locale_shortMonths[d.getMonth()];
+ }
+
+ function formatMonth(d) {
+ return locale_months[d.getMonth()];
+ }
+
+ function formatPeriod(d) {
+ return locale_periods[+(d.getHours() >= 12)];
+ }
+
+ function formatQuarter(d) {
+ return 1 + ~~(d.getMonth() / 3);
+ }
+
+ function formatUTCShortWeekday(d) {
+ return locale_shortWeekdays[d.getUTCDay()];
+ }
+
+ function formatUTCWeekday(d) {
+ return locale_weekdays[d.getUTCDay()];
+ }
+
+ function formatUTCShortMonth(d) {
+ return locale_shortMonths[d.getUTCMonth()];
+ }
+
+ function formatUTCMonth(d) {
+ return locale_months[d.getUTCMonth()];
+ }
+
+ function formatUTCPeriod(d) {
+ return locale_periods[+(d.getUTCHours() >= 12)];
+ }
+
+ function formatUTCQuarter(d) {
+ return 1 + ~~(d.getUTCMonth() / 3);
+ }
+
+ return {
+ format: function(specifier) {
+ var f = newFormat(specifier += "", formats);
+ f.toString = function() { return specifier; };
+ return f;
+ },
+ parse: function(specifier) {
+ var p = newParse(specifier += "", false);
+ p.toString = function() { return specifier; };
+ return p;
+ },
+ utcFormat: function(specifier) {
+ var f = newFormat(specifier += "", utcFormats);
+ f.toString = function() { return specifier; };
+ return f;
+ },
+ utcParse: function(specifier) {
+ var p = newParse(specifier += "", true);
+ p.toString = function() { return specifier; };
+ return p;
+ }
+ };
+}
+
+var pads = {"-": "", "_": " ", "0": "0"},
+ numberRe = /^\s*\d+/, // note: ignores next directive
+ percentRe = /^%/,
+ requoteRe = /[\\^$*+?|[\]().{}]/g;
+
+function pad(value, fill, width) {
+ var sign = value < 0 ? "-" : "",
+ string = (sign ? -value : value) + "",
+ length = string.length;
+ return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string);
+}
+
+function requote(s) {
+ return s.replace(requoteRe, "\\$&");
+}
+
+function formatRe(names) {
+ return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i");
+}
+
+function formatLookup(names) {
+ return new Map(names.map((name, i) => [name.toLowerCase(), i]));
+}
+
+function parseWeekdayNumberSunday(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 1));
+ return n ? (d.w = +n[0], i + n[0].length) : -1;
+}
+
+function parseWeekdayNumberMonday(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 1));
+ return n ? (d.u = +n[0], i + n[0].length) : -1;
+}
+
+function parseWeekNumberSunday(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.U = +n[0], i + n[0].length) : -1;
+}
+
+function parseWeekNumberISO(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.V = +n[0], i + n[0].length) : -1;
+}
+
+function parseWeekNumberMonday(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.W = +n[0], i + n[0].length) : -1;
+}
+
+function parseFullYear(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 4));
+ return n ? (d.y = +n[0], i + n[0].length) : -1;
+}
+
+function parseYear(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1;
+}
+
+function parseZone(d, string, i) {
+ var n = /^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(string.slice(i, i + 6));
+ return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1;
+}
+
+function parseQuarter(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 1));
+ return n ? (d.q = n[0] * 3 - 3, i + n[0].length) : -1;
+}
+
+function parseMonthNumber(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.m = n[0] - 1, i + n[0].length) : -1;
+}
+
+function parseDayOfMonth(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.d = +n[0], i + n[0].length) : -1;
+}
+
+function parseDayOfYear(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 3));
+ return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1;
+}
+
+function parseHour24(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.H = +n[0], i + n[0].length) : -1;
+}
+
+function parseMinutes(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.M = +n[0], i + n[0].length) : -1;
+}
+
+function parseSeconds(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 2));
+ return n ? (d.S = +n[0], i + n[0].length) : -1;
+}
+
+function parseMilliseconds(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 3));
+ return n ? (d.L = +n[0], i + n[0].length) : -1;
+}
+
+function parseMicroseconds(d, string, i) {
+ var n = numberRe.exec(string.slice(i, i + 6));
+ return n ? (d.L = Math.floor(n[0] / 1000), i + n[0].length) : -1;
+}
+
+function parseLiteralPercent(d, string, i) {
+ var n = percentRe.exec(string.slice(i, i + 1));
+ return n ? i + n[0].length : -1;
+}
+
+function parseUnixTimestamp(d, string, i) {
+ var n = numberRe.exec(string.slice(i));
+ return n ? (d.Q = +n[0], i + n[0].length) : -1;
+}
+
+function parseUnixTimestampSeconds(d, string, i) {
+ var n = numberRe.exec(string.slice(i));
+ return n ? (d.s = +n[0], i + n[0].length) : -1;
+}
+
+function formatDayOfMonth(d, p) {
+ return pad(d.getDate(), p, 2);
+}
+
+function formatHour24(d, p) {
+ return pad(d.getHours(), p, 2);
+}
+
+function formatHour12(d, p) {
+ return pad(d.getHours() % 12 || 12, p, 2);
+}
+
+function formatDayOfYear(d, p) {
+ return pad(1 + timeDay.count(timeYear(d), d), p, 3);
+}
+
+function formatMilliseconds(d, p) {
+ return pad(d.getMilliseconds(), p, 3);
+}
+
+function formatMicroseconds(d, p) {
+ return formatMilliseconds(d, p) + "000";
+}
+
+function formatMonthNumber(d, p) {
+ return pad(d.getMonth() + 1, p, 2);
+}
+
+function formatMinutes(d, p) {
+ return pad(d.getMinutes(), p, 2);
+}
+
+function formatSeconds(d, p) {
+ return pad(d.getSeconds(), p, 2);
+}
+
+function formatWeekdayNumberMonday(d) {
+ var day = d.getDay();
+ return day === 0 ? 7 : day;
+}
+
+function formatWeekNumberSunday(d, p) {
+ return pad(timeSunday.count(timeYear(d) - 1, d), p, 2);
+}
+
+function dISO(d) {
+ var day = d.getDay();
+ return (day >= 4 || day === 0) ? timeThursday(d) : timeThursday.ceil(d);
+}
+
+function formatWeekNumberISO(d, p) {
+ d = dISO(d);
+ return pad(timeThursday.count(timeYear(d), d) + (timeYear(d).getDay() === 4), p, 2);
+}
+
+function formatWeekdayNumberSunday(d) {
+ return d.getDay();
+}
+
+function formatWeekNumberMonday(d, p) {
+ return pad(timeMonday.count(timeYear(d) - 1, d), p, 2);
+}
+
+function formatYear(d, p) {
+ return pad(d.getFullYear() % 100, p, 2);
+}
+
+function formatYearISO(d, p) {
+ d = dISO(d);
+ return pad(d.getFullYear() % 100, p, 2);
+}
+
+function formatFullYear(d, p) {
+ return pad(d.getFullYear() % 10000, p, 4);
+}
+
+function formatFullYearISO(d, p) {
+ var day = d.getDay();
+ d = (day >= 4 || day === 0) ? timeThursday(d) : timeThursday.ceil(d);
+ return pad(d.getFullYear() % 10000, p, 4);
+}
+
+function formatZone(d) {
+ var z = d.getTimezoneOffset();
+ return (z > 0 ? "-" : (z *= -1, "+"))
+ + pad(z / 60 | 0, "0", 2)
+ + pad(z % 60, "0", 2);
+}
+
+function formatUTCDayOfMonth(d, p) {
+ return pad(d.getUTCDate(), p, 2);
+}
+
+function formatUTCHour24(d, p) {
+ return pad(d.getUTCHours(), p, 2);
+}
+
+function formatUTCHour12(d, p) {
+ return pad(d.getUTCHours() % 12 || 12, p, 2);
+}
+
+function formatUTCDayOfYear(d, p) {
+ return pad(1 + utcDay.count(utcYear(d), d), p, 3);
+}
+
+function formatUTCMilliseconds(d, p) {
+ return pad(d.getUTCMilliseconds(), p, 3);
+}
+
+function formatUTCMicroseconds(d, p) {
+ return formatUTCMilliseconds(d, p) + "000";
+}
+
+function formatUTCMonthNumber(d, p) {
+ return pad(d.getUTCMonth() + 1, p, 2);
+}
+
+function formatUTCMinutes(d, p) {
+ return pad(d.getUTCMinutes(), p, 2);
+}
+
+function formatUTCSeconds(d, p) {
+ return pad(d.getUTCSeconds(), p, 2);
+}
+
+function formatUTCWeekdayNumberMonday(d) {
+ var dow = d.getUTCDay();
+ return dow === 0 ? 7 : dow;
+}
+
+function formatUTCWeekNumberSunday(d, p) {
+ return pad(utcSunday.count(utcYear(d) - 1, d), p, 2);
+}
+
+function UTCdISO(d) {
+ var day = d.getUTCDay();
+ return (day >= 4 || day === 0) ? utcThursday(d) : utcThursday.ceil(d);
+}
+
+function formatUTCWeekNumberISO(d, p) {
+ d = UTCdISO(d);
+ return pad(utcThursday.count(utcYear(d), d) + (utcYear(d).getUTCDay() === 4), p, 2);
+}
+
+function formatUTCWeekdayNumberSunday(d) {
+ return d.getUTCDay();
+}
+
+function formatUTCWeekNumberMonday(d, p) {
+ return pad(utcMonday.count(utcYear(d) - 1, d), p, 2);
+}
+
+function formatUTCYear(d, p) {
+ return pad(d.getUTCFullYear() % 100, p, 2);
+}
+
+function formatUTCYearISO(d, p) {
+ d = UTCdISO(d);
+ return pad(d.getUTCFullYear() % 100, p, 2);
+}
+
+function formatUTCFullYear(d, p) {
+ return pad(d.getUTCFullYear() % 10000, p, 4);
+}
+
+function formatUTCFullYearISO(d, p) {
+ var day = d.getUTCDay();
+ d = (day >= 4 || day === 0) ? utcThursday(d) : utcThursday.ceil(d);
+ return pad(d.getUTCFullYear() % 10000, p, 4);
+}
+
+function formatUTCZone() {
+ return "+0000";
+}
+
+function formatLiteralPercent() {
+ return "%";
+}
+
+function formatUnixTimestamp(d) {
+ return +d;
+}
+
+function formatUnixTimestampSeconds(d) {
+ return Math.floor(+d / 1000);
+}
diff --git a/node_modules/d3-time/LICENSE b/node_modules/d3-time/LICENSE
new file mode 100644
index 00000000..b0145150
--- /dev/null
+++ b/node_modules/d3-time/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2010-2021 Mike Bostock
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/node_modules/d3-time/README.md b/node_modules/d3-time/README.md
new file mode 100644
index 00000000..106ee7a7
--- /dev/null
+++ b/node_modules/d3-time/README.md
@@ -0,0 +1,378 @@
+# d3-time
+
+When visualizing time series data, analyzing temporal patterns, or working with time in general, the irregularities of conventional time units quickly become apparent. In the [Gregorian calendar](https://en.wikipedia.org/wiki/Gregorian_calendar), for example, most months have 31 days but some have 28, 29 or 30; most years have 365 days but [leap years](https://en.wikipedia.org/wiki/Leap_year) have 366; and with [daylight saving](https://en.wikipedia.org/wiki/Daylight_saving_time), most days have 24 hours but some have 23 or 25. Adding to complexity, daylight saving conventions vary around the world.
+
+As a result of these temporal peculiarities, it can be difficult to perform seemingly-trivial tasks. For example, if you want to compute the number of days that have passed between two dates, you can’t simply subtract and divide by 24 hours (86,400,000 ms):
+
+```js
+start = new Date(2015, 02, 01) // 2015-03-01T00:00
+end = new Date(2015, 03, 01) // 2015-04-01T00:00
+(end - start) / 864e5 // 30.958333333333332, oops! 🤯
+```
+
+You can, however, use [d3.timeDay](#timeDay).[count](#interval_count):
+
+```js
+d3.timeDay.count(start, end) // 31 😌
+```
+
+The [day](#day) [interval](#api-reference) is one of several provided by d3-time. Each interval represents a conventional unit of time—[hours](#timeHour), [weeks](#timeWeek), [months](#timeMonth), *etc.*—and has methods to calculate boundary dates. For example, [d3.timeDay](#timeDay) computes midnight (typically 12:00 AM local time) of the corresponding day. In addition to [rounding](#interval_round) and [counting](#interval_count), intervals can also be used to generate arrays of boundary dates. For example, to compute each Sunday in the current month:
+
+```js
+start = d3.timeMonth.floor() // 2015-01-01T00:00
+stop = d3.timeMonth.ceil() // 2015-02-01T00:00
+d3.timeWeek.range(start, stop) // [2015-01-07T00:00, 2015-01-14T00:00, 2015-01-21T00:00, 2015-01-28T00:00]
+```
+
+The d3-time module does not implement its own calendaring system; it merely implements a convenient API for calendar math on top of ECMAScript [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date). Thus, it ignores leap seconds and can only work with the local time zone and [Coordinated Universal Time](https://en.wikipedia.org/wiki/Coordinated_Universal_Time) (UTC).
+
+This module is used by D3’s time scales to generate sensible ticks, by D3’s time format, and can also be used directly to do things like [calendar layouts](http://bl.ocks.org/mbostock/4063318).
+
+## Installing
+
+If you use npm, `npm install d3-time`. You can also download the [latest release on GitHub](https://github.com/d3/d3-time/releases/latest). For vanilla HTML in modern browsers, import d3-time from Skypack:
+
+```html
+
+```
+
+For legacy environments, you can load d3-time’s UMD bundle from an npm-based CDN such as jsDelivr; a `d3` global is exported:
+
+```html
+
+
+
+```
+
+[Try d3-time in your browser.](https://observablehq.com/collection/@d3/d3-time)
+
+## API Reference
+
+# interval([date]) · [Source](https://github.com/d3/d3-time/blob/master/src/interval.js)
+
+Equivalent to [*interval*.floor](#interval_floor), except if *date* is not specified, it defaults to the current time. For example, [d3.timeYear](#timeYear)(*date*) and d3.timeYear.floor(*date*) are equivalent.
+
+```js
+monday = d3.timeMonday() // the latest preceeding Monday, local time
+```
+
+# interval.floor(date) · [Source](https://github.com/d3/d3-time/blob/master/src/interval.js)
+
+Returns a new date representing the latest interval boundary date before or equal to *date*. For example, [d3.timeDay](#timeDay).floor(*date*) typically returns 12:00 AM local time on the given *date*.
+
+This method is idempotent: if the specified *date* is already floored to the current interval, a new date with an identical time is returned. Furthermore, the returned date is the minimum expressible value of the associated interval, such that *interval*.floor(*interval*.floor(*date*) - 1) returns the preceeding interval boundary date.
+
+Note that the `==` and `===` operators do not compare by value with [Date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date) objects, and thus you cannot use them to tell whether the specified *date* has already been floored. Instead, coerce to a number and then compare:
+
+```js
+// Returns true if the specified date is a day boundary.
+function isDay(date) {
+ return +d3.timeDay.floor(date) === +date;
+}
+```
+
+This is more reliable than testing whether the time is 12:00 AM, as in some time zones midnight may not exist due to daylight saving.
+
+# interval.round(date) · [Source](https://github.com/d3/d3-time/blob/master/src/interval.js)
+
+Returns a new date representing the closest interval boundary date to *date*. For example, [d3.timeDay](#timeDay).round(*date*) typically returns 12:00 AM local time on the given *date* if it is on or before noon, and 12:00 AM of the following day if it is after noon.
+
+This method is idempotent: if the specified *date* is already rounded to the current interval, a new date with an identical time is returned.
+
+# interval.ceil(date) · [Source](https://github.com/d3/d3-time/blob/master/src/interval.js)
+
+Returns a new date representing the earliest interval boundary date after or equal to *date*. For example, [d3.timeDay](#timeDay).ceil(*date*) typically returns 12:00 AM local time on the date following the given *date*.
+
+This method is idempotent: if the specified *date* is already ceilinged to the current interval, a new date with an identical time is returned. Furthermore, the returned date is the maximum expressible value of the associated interval, such that *interval*.ceil(*interval*.ceil(*date*) + 1) returns the following interval boundary date.
+
+# interval.offset(date[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/interval.js)
+
+Returns a new date equal to *date* plus *step* intervals. If *step* is not specified it defaults to 1. If *step* is negative, then the returned date will be before the specified *date*; if *step* is zero, then a copy of the specified *date* is returned; if *step* is not an integer, it is [floored](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor). This method does not round the specified *date* to the interval. For example, if *date* is today at 5:34 PM, then [d3.timeDay](#timeDay).offset(*date*, 1) returns 5:34 PM tomorrow (even if daylight saving changes!).
+
+# interval.range(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/interval.js)
+
+Returns an array of dates representing every interval boundary after or equal to *start* (inclusive) and before *stop* (exclusive). If *step* is specified, then every *step*th boundary will be returned; for example, for the [d3.timeDay](#timeDay) interval a *step* of 2 will return every other day. If *step* is not an integer, it is [floored](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/floor).
+
+The first date in the returned array is the earliest boundary after or equal to *start*; subsequent dates are [offset](#interval_offset) by *step* intervals and [floored](#interval_floor). Thus, two overlapping ranges may be consistent. For example, this range contains odd days:
+
+```js
+d3.timeDay.range(new Date(2015, 0, 1), new Date(2015, 0, 7), 2) // [2015-01-01T00:00, 2015-01-03T00:00, 2015-01-05T00:00]
+```
+
+While this contains even days:
+
+```js
+d3.timeDay.range(new Date(2015, 0, 2), new Date(2015, 0, 8), 2) // [2015-01-02T00:00, 2015-01-04T00:00, 2015-01-06T00:00]
+```
+
+To make ranges consistent when a *step* is specified, use [*interval*.every](#interval_every) instead.
+
+# interval.filter(test) · [Source](https://github.com/d3/d3-time/blob/master/src/interval.js)
+
+Returns a new interval that is a filtered subset of this interval using the specified *test* function. The *test* function is passed a date and should return true if and only if the specified date should be considered part of the interval. For example, to create an interval that returns the 1st, 11th, 21th and 31th (if it exists) of each month:
+
+```js
+d3.timeDay.filter(d => (d.getDate() - 1) % 10 === 0)
+```
+
+The returned filtered interval does not support [*interval*.count](#interval_count). See also [*interval*.every](#interval_every).
+
+# interval.every(step) · [Source](https://github.com/d3/d3-time/blob/master/src/interval.js)
+
+Returns a [filtered](#interval_filter) view of this interval representing every *step*th date. The meaning of *step* is dependent on this interval’s parent interval as defined by the field function. For example, [d3.timeMinute](#timeMinute).every(15) returns an interval representing every fifteen minutes, starting on the hour: :00, :15, :30, :45, etc. Note that for some intervals, the resulting dates may not be uniformly-spaced; [d3.timeDay](#timeDay)’s parent interval is [d3.timeMonth](#timeMonth), and thus the interval number resets at the start of each month. If *step* is not valid, returns null. If *step* is one, returns this interval.
+
+This method can be used in conjunction with [*interval*.range](#interval_range) to ensure that two overlapping ranges are consistent. For example, this range contains odd days:
+
+```js
+d3.timeDay.every(2).range(new Date(2015, 0, 1), new Date(2015, 0, 7)) // [2015-01-01T00:00, 2015-01-03T00:00, 2015-01-05T00:00]
+```
+
+As does this one:
+
+```js
+d3.timeDay.every(2).range(new Date(2015, 0, 2), new Date(2015, 0, 8)) // [2015-01-03T00:00, 2015-01-05T00:00, 2015-01-07T00:00]
+```
+
+The returned filtered interval does not support [*interval*.count](#interval_count). See also [*interval*.filter](#interval_filter).
+
+# interval.count(start, end) · [Source](https://github.com/d3/d3-time/blob/master/src/interval.js)
+
+Returns the number of interval boundaries after *start* (exclusive) and before or equal to *end* (inclusive). Note that this behavior is slightly different than [*interval*.range](#interval_range) because its purpose is to return the zero-based number of the specified *end* date relative to the specified *start* date. For example, to compute the current zero-based day-of-year number:
+
+```js
+d3.timeDay.count(d3.timeYear(now), now) // 177
+```
+
+Likewise, to compute the current zero-based week-of-year number for weeks that start on Sunday:
+
+```js
+d3.timeSunday.count(d3.timeYear(now), now) // 25
+```
+
+# d3.timeInterval(floor, offset[, count[, field]]) · [Source](https://github.com/d3/d3-time/blob/master/src/interval.js)
+
+Constructs a new custom interval given the specified *floor* and *offset* functions and an optional *count* function.
+
+The *floor* function takes a single date as an argument and rounds it down to the nearest interval boundary.
+
+The *offset* function takes a date and an integer step as arguments and advances the specified date by the specified number of boundaries; the step may be positive, negative or zero.
+
+The optional *count* function takes a start date and an end date, already floored to the current interval, and returns the number of boundaries between the start (exclusive) and end (inclusive). If a *count* function is not specified, the returned interval does not expose [*interval*.count](#interval_count) or [*interval*.every](#interval_every) methods. Note: due to an internal optimization, the specified *count* function must not invoke *interval*.count on other time intervals.
+
+The optional *field* function takes a date, already floored to the current interval, and returns the field value of the specified date, corresponding to the number of boundaries between this date (exclusive) and the latest previous parent boundary. For example, for the [d3.timeDay](#timeDay) interval, this returns the number of days since the start of the month. If a *field* function is not specified, it defaults to counting the number of interval boundaries since the UNIX epoch of January 1, 1970 UTC. The *field* function defines the behavior of [*interval*.every](#interval_every).
+
+### Intervals
+
+The following intervals are provided:
+
+# d3.timeMillisecond · [Source](https://github.com/d3/d3-time/blob/master/src/millisecond.js "Source")
+
# d3.utcMillisecond
+
+Milliseconds; the shortest available time unit.
+
+# d3.timeSecond · [Source](https://github.com/d3/d3-time/blob/master/src/second.js "Source")
+
# d3.utcSecond
+
+Seconds (e.g., 01:23:45.0000 AM); 1,000 milliseconds.
+
+# d3.timeMinute · [Source](https://github.com/d3/d3-time/blob/master/src/minute.js "Source")
+
# d3.utcMinute · [Source](https://github.com/d3/d3-time/blob/master/src/utcMinute.js "Source")
+
+Minutes (e.g., 01:02:00 AM); 60 seconds. Note that ECMAScript [ignores leap seconds](http://www.ecma-international.org/ecma-262/5.1/#sec-15.9.1.1).
+
+# d3.timeHour · [Source](https://github.com/d3/d3-time/blob/master/src/hour.js "Source")
+
# d3.utcHour · [Source](https://github.com/d3/d3-time/blob/master/src/utcHour.js "Source")
+
+Hours (e.g., 01:00 AM); 60 minutes. Note that advancing time by one hour in local time can return the same hour or skip an hour due to daylight saving.
+
+# d3.timeDay · [Source](https://github.com/d3/d3-time/blob/master/src/day.js "Source")
+
# d3.utcDay · [Source](https://github.com/d3/d3-time/blob/master/src/utcDay.js "Source")
+
+Days (e.g., February 7, 2012 at 12:00 AM); typically 24 hours. Days in local time may range from 23 to 25 hours due to daylight saving.
+
+# d3.timeWeek · [Source](https://github.com/d3/d3-time/blob/master/src/week.js "Source")
+
# d3.utcWeek · [Source](https://github.com/d3/d3-time/blob/master/src/utcWeek.js "Source")
+
+Alias for [d3.timeSunday](#timeSunday); 7 days and typically 168 hours. Weeks in local time may range from 167 to 169 hours due on daylight saving.
+
+# d3.timeSunday · [Source](https://github.com/d3/d3-time/blob/master/src/week.js)
+
# d3.utcSunday · [Source](https://github.com/d3/d3-time/blob/master/src/utcWeek.js)
+
+Sunday-based weeks (e.g., February 5, 2012 at 12:00 AM).
+
+# d3.timeMonday · [Source](https://github.com/d3/d3-time/blob/master/src/week.js)
+
# d3.utcMonday · [Source](https://github.com/d3/d3-time/blob/master/src/utcWeek.js)
+
+Monday-based weeks (e.g., February 6, 2012 at 12:00 AM).
+
+# d3.timeTuesday · [Source](https://github.com/d3/d3-time/blob/master/src/week.js)
+
# d3.utcTuesday · [Source](https://github.com/d3/d3-time/blob/master/src/utcWeek.js)
+
+Tuesday-based weeks (e.g., February 7, 2012 at 12:00 AM).
+
+# d3.timeWednesday · [Source](https://github.com/d3/d3-time/blob/master/src/week.js)
+
# d3.utcWednesday · [Source](https://github.com/d3/d3-time/blob/master/src/utcWeek.js)
+
+Wednesday-based weeks (e.g., February 8, 2012 at 12:00 AM).
+
+# d3.timeThursday · [Source](https://github.com/d3/d3-time/blob/master/src/week.js)
+
# d3.utcThursday · [Source](https://github.com/d3/d3-time/blob/master/src/utcWeek.js)
+
+Thursday-based weeks (e.g., February 9, 2012 at 12:00 AM).
+
+# d3.timeFriday · [Source](https://github.com/d3/d3-time/blob/master/src/week.js)
+
# d3.utcFriday · [Source](https://github.com/d3/d3-time/blob/master/src/utcWeek.js)
+
+Friday-based weeks (e.g., February 10, 2012 at 12:00 AM).
+
+# d3.timeSaturday · [Source](https://github.com/d3/d3-time/blob/master/src/week.js)
+
# d3.utcSaturday · [Source](https://github.com/d3/d3-time/blob/master/src/utcWeek.js)
+
+Saturday-based weeks (e.g., February 11, 2012 at 12:00 AM).
+
+# d3.timeMonth · [Source](https://github.com/d3/d3-time/blob/master/src/month.js "Source")
+
# d3.utcMonth · [Source](https://github.com/d3/d3-time/blob/master/src/utcMonth.js "Source")
+
+Months (e.g., February 1, 2012 at 12:00 AM); ranges from 28 to 31 days.
+
+# d3.timeYear · [Source](https://github.com/d3/d3-time/blob/master/src/year.js "Source")
+
# d3.utcYear · [Source](https://github.com/d3/d3-time/blob/master/src/utcYear.js "Source")
+
+Years (e.g., January 1, 2012 at 12:00 AM); ranges from 365 to 366 days.
+
+### Ranges
+
+For convenience, aliases for [*interval*.range](#interval_range) are also provided as plural forms of the corresponding interval.
+
+# d3.timeMilliseconds(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/millisecond.js)
+
# d3.utcMilliseconds(start, stop[, step])
+
+Aliases for [d3.timeMillisecond](#timeMillisecond).[range](#interval_range) and [d3.utcMillisecond](#timeMillisecond).[range](#interval_range).
+
+# d3.timeSeconds(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/second.js)
+
# d3.utcSeconds(start, stop[, step])
+
+Aliases for [d3.timeSecond](#timeSecond).[range](#interval_range) and [d3.utcSecond](#timeSecond).[range](#interval_range).
+
+# d3.timeMinutes(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/minute.js)
+
# d3.utcMinutes(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/utcMinute.js)
+
+Aliases for [d3.timeMinute](#timeMinute).[range](#interval_range) and [d3.utcMinute](#timeMinute).[range](#interval_range).
+
+# d3.timeHours(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/hour.js)
+
# d3.utcHours(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/utcHour.js)
+
+Aliases for [d3.timeHour](#timeHour).[range](#interval_range) and [d3.utcHour](#timeHour).[range](#interval_range).
+
+# d3.timeDays(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/day.js)
+
# d3.utcDays(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/utcDay.js)
+
+Aliases for [d3.timeDay](#timeDay).[range](#interval_range) and [d3.utcDay](#timeDay).[range](#interval_range).
+
+# d3.timeWeeks(start, stop[, step])
+
# d3.utcWeeks(start, stop[, step])
+
+Aliases for [d3.timeWeek](#timeWeek).[range](#interval_range) and [d3.utcWeek](#timeWeek).[range](#interval_range).
+
+# d3.timeSundays(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/week.js)
+
# d3.utcSundays(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/utcWeek.js)
+
+Aliases for [d3.timeSunday](#timeSunday).[range](#interval_range) and [d3.utcSunday](#timeSunday).[range](#interval_range).
+
+# d3.timeMondays(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/week.js)
+
# d3.utcMondays(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/utcWeek.js)
+
+Aliases for [d3.timeMonday](#timeMonday).[range](#interval_range) and [d3.utcMonday](#timeMonday).[range](#interval_range).
+
+# d3.timeTuesdays(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/week.js)
+
# d3.utcTuesdays(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/utcWeek.js)
+
+Aliases for [d3.timeTuesday](#timeTuesday).[range](#interval_range) and [d3.utcTuesday](#timeTuesday).[range](#interval_range).
+
+# d3.timeWednesdays(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/week.js)
+
# d3.utcWednesdays(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/utcWeek.js)
+
+Aliases for [d3.timeWednesday](#timeWednesday).[range](#interval_range) and [d3.utcWednesday](#timeWednesday).[range](#interval_range).
+
+# d3.timeThursdays(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/week.js)
+
# d3.utcThursdays(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/utcWeek.js)
+
+Aliases for [d3.timeThursday](#timeThursday).[range](#interval_range) and [d3.utcThursday](#timeThursday).[range](#interval_range).
+
+# d3.timeFridays(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/week.js)
+
# d3.utcFridays(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/utcWeek.js)
+
+Aliases for [d3.timeFriday](#timeFriday).[range](#interval_range) and [d3.utcFriday](#timeFriday).[range](#interval_range).
+
+# d3.timeSaturdays(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/week.js)
+
# d3.utcSaturdays(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/utcWeek.js)
+
+Aliases for [d3.timeSaturday](#timeSaturday).[range](#interval_range) and [d3.utcSaturday](#timeSaturday).[range](#interval_range).
+
+# d3.timeMonths(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/month.js)
+
# d3.utcMonths(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/utcMonth.js)
+
+Aliases for [d3.timeMonth](#timeMonth).[range](#interval_range) and [d3.utcMonth](#timeMonth).[range](#interval_range).
+
+# d3.timeYears(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/year.js)
+
# d3.utcYears(start, stop[, step]) · [Source](https://github.com/d3/d3-time/blob/master/src/utcYear.js)
+
+Aliases for [d3.timeYear](#timeYear).[range](#interval_range) and [d3.utcYear](#timeYear).[range](#interval_range).
+
+### Ticks
+
+# d3.timeTicks(start, stop, count) · [Source](https://github.com/d3/d3-time/blob/master/src/ticks.js)
+
+Equivalent to [d3.utcTicks](#utcTicks), but in local time.
+
+# d3.timeTickInterval(start, stop, count) · [Source](https://github.com/d3/d3-time/blob/master/src/ticks.js)
+
+Returns the time interval that would be used by [d3.timeTicks](#timeTicks) given the same arguments.
+
+# d3.utcTicks(start, stop, count) · [Source](https://github.com/d3/d3-time/blob/master/src/ticks.js)
+
+Returns an array of approximately *count* dates at regular intervals between *start* and *stop* (inclusive). If *stop* is before *start*, dates are returned in reverse chronological order; otherwise dates are returned in chronological order. The following UTC time intervals are considered:
+
+* 1 second
+* 5 seconds
+* 15 seconds
+* 30 seconds
+* 1 minute
+* 5 minutes
+* 15 minutes
+* 30 minutes
+* 1 hour
+* 3 hours
+* 6 hours
+* 12 hours
+* 1 day
+* 2 days
+* 1 week
+* 1 month
+* 3 months
+* 1 year
+
+Multiples of milliseconds (for small ranges) and years (for large ranges) are also considered, following the rules of [d3.ticks](https://github.com/d3/d3-array/blob/master/README.md#ticks). The interval producing the number of dates that is closest to *count* is used. For example:
+
+```js
+start = new Date(Date.UTC(1970, 2, 1))
+stop = new Date(Date.UTC(1996, 2, 19))
+count = 4
+d3.utcTicks(start, stop, count) // [1975-01-01, 1980-01-01, 1985-01-01, 1990-01-01, 1995-01-01]
+```
+
+If *count* is a time interval, this function behaves similarly to [*interval*.range](#interval_range) except that both *start* and *stop* are inclusive and it may return dates in reverse chronological order if *stop* is before *start*.
+
+# d3.utcTickInterval(start, stop, count) · [Source](https://github.com/d3/d3-time/blob/master/src/ticks.js)
+
+Returns the time interval that would be used by [d3.utcTicks](#utcTicks) given the same arguments. If there is no associated interval, such as when *start* or *stop* is invalid, returns null.
diff --git a/node_modules/d3-time/dist/d3-time.js b/node_modules/d3-time/dist/d3-time.js
new file mode 100644
index 00000000..cde0a51e
--- /dev/null
+++ b/node_modules/d3-time/dist/d3-time.js
@@ -0,0 +1,422 @@
+// https://d3js.org/d3-time/ v3.0.0 Copyright 2010-2021 Mike Bostock
+(function (global, factory) {
+typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-array')) :
+typeof define === 'function' && define.amd ? define(['exports', 'd3-array'], factory) :
+(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}, global.d3));
+}(this, (function (exports, d3Array) { 'use strict';
+
+var t0 = new Date,
+ t1 = new Date;
+
+function newInterval(floori, offseti, count, field) {
+
+ function interval(date) {
+ return floori(date = arguments.length === 0 ? new Date : new Date(+date)), date;
+ }
+
+ interval.floor = function(date) {
+ return floori(date = new Date(+date)), date;
+ };
+
+ interval.ceil = function(date) {
+ return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;
+ };
+
+ interval.round = function(date) {
+ var d0 = interval(date),
+ d1 = interval.ceil(date);
+ return date - d0 < d1 - date ? d0 : d1;
+ };
+
+ interval.offset = function(date, step) {
+ return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;
+ };
+
+ interval.range = function(start, stop, step) {
+ var range = [], previous;
+ start = interval.ceil(start);
+ step = step == null ? 1 : Math.floor(step);
+ if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date
+ do range.push(previous = new Date(+start)), offseti(start, step), floori(start);
+ while (previous < start && start < stop);
+ return range;
+ };
+
+ interval.filter = function(test) {
+ return newInterval(function(date) {
+ if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);
+ }, function(date, step) {
+ if (date >= date) {
+ if (step < 0) while (++step <= 0) {
+ while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty
+ } else while (--step >= 0) {
+ while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty
+ }
+ }
+ });
+ };
+
+ if (count) {
+ interval.count = function(start, end) {
+ t0.setTime(+start), t1.setTime(+end);
+ floori(t0), floori(t1);
+ return Math.floor(count(t0, t1));
+ };
+
+ interval.every = function(step) {
+ step = Math.floor(step);
+ return !isFinite(step) || !(step > 0) ? null
+ : !(step > 1) ? interval
+ : interval.filter(field
+ ? function(d) { return field(d) % step === 0; }
+ : function(d) { return interval.count(0, d) % step === 0; });
+ };
+ }
+
+ return interval;
+}
+
+var millisecond = newInterval(function() {
+ // noop
+}, function(date, step) {
+ date.setTime(+date + step);
+}, function(start, end) {
+ return end - start;
+});
+
+// An optimized implementation for this simple case.
+millisecond.every = function(k) {
+ k = Math.floor(k);
+ if (!isFinite(k) || !(k > 0)) return null;
+ if (!(k > 1)) return millisecond;
+ return newInterval(function(date) {
+ date.setTime(Math.floor(date / k) * k);
+ }, function(date, step) {
+ date.setTime(+date + step * k);
+ }, function(start, end) {
+ return (end - start) / k;
+ });
+};
+var milliseconds = millisecond.range;
+
+const durationSecond = 1000;
+const durationMinute = durationSecond * 60;
+const durationHour = durationMinute * 60;
+const durationDay = durationHour * 24;
+const durationWeek = durationDay * 7;
+const durationMonth = durationDay * 30;
+const durationYear = durationDay * 365;
+
+var second = newInterval(function(date) {
+ date.setTime(date - date.getMilliseconds());
+}, function(date, step) {
+ date.setTime(+date + step * durationSecond);
+}, function(start, end) {
+ return (end - start) / durationSecond;
+}, function(date) {
+ return date.getUTCSeconds();
+});
+var seconds = second.range;
+
+var minute = newInterval(function(date) {
+ date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond);
+}, function(date, step) {
+ date.setTime(+date + step * durationMinute);
+}, function(start, end) {
+ return (end - start) / durationMinute;
+}, function(date) {
+ return date.getMinutes();
+});
+var minutes = minute.range;
+
+var hour = newInterval(function(date) {
+ date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond - date.getMinutes() * durationMinute);
+}, function(date, step) {
+ date.setTime(+date + step * durationHour);
+}, function(start, end) {
+ return (end - start) / durationHour;
+}, function(date) {
+ return date.getHours();
+});
+var hours = hour.range;
+
+var day = newInterval(
+ date => date.setHours(0, 0, 0, 0),
+ (date, step) => date.setDate(date.getDate() + step),
+ (start, end) => (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay,
+ date => date.getDate() - 1
+);
+var days = day.range;
+
+function weekday(i) {
+ return newInterval(function(date) {
+ date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);
+ date.setHours(0, 0, 0, 0);
+ }, function(date, step) {
+ date.setDate(date.getDate() + step * 7);
+ }, function(start, end) {
+ return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek;
+ });
+}
+
+var sunday = weekday(0);
+var monday = weekday(1);
+var tuesday = weekday(2);
+var wednesday = weekday(3);
+var thursday = weekday(4);
+var friday = weekday(5);
+var saturday = weekday(6);
+
+var sundays = sunday.range;
+var mondays = monday.range;
+var tuesdays = tuesday.range;
+var wednesdays = wednesday.range;
+var thursdays = thursday.range;
+var fridays = friday.range;
+var saturdays = saturday.range;
+
+var month = newInterval(function(date) {
+ date.setDate(1);
+ date.setHours(0, 0, 0, 0);
+}, function(date, step) {
+ date.setMonth(date.getMonth() + step);
+}, function(start, end) {
+ return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;
+}, function(date) {
+ return date.getMonth();
+});
+var months = month.range;
+
+var year = newInterval(function(date) {
+ date.setMonth(0, 1);
+ date.setHours(0, 0, 0, 0);
+}, function(date, step) {
+ date.setFullYear(date.getFullYear() + step);
+}, function(start, end) {
+ return end.getFullYear() - start.getFullYear();
+}, function(date) {
+ return date.getFullYear();
+});
+
+// An optimized implementation for this simple case.
+year.every = function(k) {
+ return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
+ date.setFullYear(Math.floor(date.getFullYear() / k) * k);
+ date.setMonth(0, 1);
+ date.setHours(0, 0, 0, 0);
+ }, function(date, step) {
+ date.setFullYear(date.getFullYear() + step * k);
+ });
+};
+var years = year.range;
+
+var utcMinute = newInterval(function(date) {
+ date.setUTCSeconds(0, 0);
+}, function(date, step) {
+ date.setTime(+date + step * durationMinute);
+}, function(start, end) {
+ return (end - start) / durationMinute;
+}, function(date) {
+ return date.getUTCMinutes();
+});
+var utcMinutes = utcMinute.range;
+
+var utcHour = newInterval(function(date) {
+ date.setUTCMinutes(0, 0, 0);
+}, function(date, step) {
+ date.setTime(+date + step * durationHour);
+}, function(start, end) {
+ return (end - start) / durationHour;
+}, function(date) {
+ return date.getUTCHours();
+});
+var utcHours = utcHour.range;
+
+var utcDay = newInterval(function(date) {
+ date.setUTCHours(0, 0, 0, 0);
+}, function(date, step) {
+ date.setUTCDate(date.getUTCDate() + step);
+}, function(start, end) {
+ return (end - start) / durationDay;
+}, function(date) {
+ return date.getUTCDate() - 1;
+});
+var utcDays = utcDay.range;
+
+function utcWeekday(i) {
+ return newInterval(function(date) {
+ date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);
+ date.setUTCHours(0, 0, 0, 0);
+ }, function(date, step) {
+ date.setUTCDate(date.getUTCDate() + step * 7);
+ }, function(start, end) {
+ return (end - start) / durationWeek;
+ });
+}
+
+var utcSunday = utcWeekday(0);
+var utcMonday = utcWeekday(1);
+var utcTuesday = utcWeekday(2);
+var utcWednesday = utcWeekday(3);
+var utcThursday = utcWeekday(4);
+var utcFriday = utcWeekday(5);
+var utcSaturday = utcWeekday(6);
+
+var utcSundays = utcSunday.range;
+var utcMondays = utcMonday.range;
+var utcTuesdays = utcTuesday.range;
+var utcWednesdays = utcWednesday.range;
+var utcThursdays = utcThursday.range;
+var utcFridays = utcFriday.range;
+var utcSaturdays = utcSaturday.range;
+
+var utcMonth = newInterval(function(date) {
+ date.setUTCDate(1);
+ date.setUTCHours(0, 0, 0, 0);
+}, function(date, step) {
+ date.setUTCMonth(date.getUTCMonth() + step);
+}, function(start, end) {
+ return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;
+}, function(date) {
+ return date.getUTCMonth();
+});
+var utcMonths = utcMonth.range;
+
+var utcYear = newInterval(function(date) {
+ date.setUTCMonth(0, 1);
+ date.setUTCHours(0, 0, 0, 0);
+}, function(date, step) {
+ date.setUTCFullYear(date.getUTCFullYear() + step);
+}, function(start, end) {
+ return end.getUTCFullYear() - start.getUTCFullYear();
+}, function(date) {
+ return date.getUTCFullYear();
+});
+
+// An optimized implementation for this simple case.
+utcYear.every = function(k) {
+ return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) {
+ date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);
+ date.setUTCMonth(0, 1);
+ date.setUTCHours(0, 0, 0, 0);
+ }, function(date, step) {
+ date.setUTCFullYear(date.getUTCFullYear() + step * k);
+ });
+};
+var utcYears = utcYear.range;
+
+function ticker(year, month, week, day, hour, minute) {
+
+ const tickIntervals = [
+ [second, 1, durationSecond],
+ [second, 5, 5 * durationSecond],
+ [second, 15, 15 * durationSecond],
+ [second, 30, 30 * durationSecond],
+ [minute, 1, durationMinute],
+ [minute, 5, 5 * durationMinute],
+ [minute, 15, 15 * durationMinute],
+ [minute, 30, 30 * durationMinute],
+ [ hour, 1, durationHour ],
+ [ hour, 3, 3 * durationHour ],
+ [ hour, 6, 6 * durationHour ],
+ [ hour, 12, 12 * durationHour ],
+ [ day, 1, durationDay ],
+ [ day, 2, 2 * durationDay ],
+ [ week, 1, durationWeek ],
+ [ month, 1, durationMonth ],
+ [ month, 3, 3 * durationMonth ],
+ [ year, 1, durationYear ]
+ ];
+
+ function ticks(start, stop, count) {
+ const reverse = stop < start;
+ if (reverse) [start, stop] = [stop, start];
+ const interval = count && typeof count.range === "function" ? count : tickInterval(start, stop, count);
+ const ticks = interval ? interval.range(start, +stop + 1) : []; // inclusive stop
+ return reverse ? ticks.reverse() : ticks;
+ }
+
+ function tickInterval(start, stop, count) {
+ const target = Math.abs(stop - start) / count;
+ const i = d3Array.bisector(([,, step]) => step).right(tickIntervals, target);
+ if (i === tickIntervals.length) return year.every(d3Array.tickStep(start / durationYear, stop / durationYear, count));
+ if (i === 0) return millisecond.every(Math.max(d3Array.tickStep(start, stop, count), 1));
+ const [t, step] = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i];
+ return t.every(step);
+ }
+
+ return [ticks, tickInterval];
+}
+
+const [utcTicks, utcTickInterval] = ticker(utcYear, utcMonth, utcSunday, utcDay, utcHour, utcMinute);
+const [timeTicks, timeTickInterval] = ticker(year, month, sunday, day, hour, minute);
+
+exports.timeDay = day;
+exports.timeDays = days;
+exports.timeFriday = friday;
+exports.timeFridays = fridays;
+exports.timeHour = hour;
+exports.timeHours = hours;
+exports.timeInterval = newInterval;
+exports.timeMillisecond = millisecond;
+exports.timeMilliseconds = milliseconds;
+exports.timeMinute = minute;
+exports.timeMinutes = minutes;
+exports.timeMonday = monday;
+exports.timeMondays = mondays;
+exports.timeMonth = month;
+exports.timeMonths = months;
+exports.timeSaturday = saturday;
+exports.timeSaturdays = saturdays;
+exports.timeSecond = second;
+exports.timeSeconds = seconds;
+exports.timeSunday = sunday;
+exports.timeSundays = sundays;
+exports.timeThursday = thursday;
+exports.timeThursdays = thursdays;
+exports.timeTickInterval = timeTickInterval;
+exports.timeTicks = timeTicks;
+exports.timeTuesday = tuesday;
+exports.timeTuesdays = tuesdays;
+exports.timeWednesday = wednesday;
+exports.timeWednesdays = wednesdays;
+exports.timeWeek = sunday;
+exports.timeWeeks = sundays;
+exports.timeYear = year;
+exports.timeYears = years;
+exports.utcDay = utcDay;
+exports.utcDays = utcDays;
+exports.utcFriday = utcFriday;
+exports.utcFridays = utcFridays;
+exports.utcHour = utcHour;
+exports.utcHours = utcHours;
+exports.utcMillisecond = millisecond;
+exports.utcMilliseconds = milliseconds;
+exports.utcMinute = utcMinute;
+exports.utcMinutes = utcMinutes;
+exports.utcMonday = utcMonday;
+exports.utcMondays = utcMondays;
+exports.utcMonth = utcMonth;
+exports.utcMonths = utcMonths;
+exports.utcSaturday = utcSaturday;
+exports.utcSaturdays = utcSaturdays;
+exports.utcSecond = second;
+exports.utcSeconds = seconds;
+exports.utcSunday = utcSunday;
+exports.utcSundays = utcSundays;
+exports.utcThursday = utcThursday;
+exports.utcThursdays = utcThursdays;
+exports.utcTickInterval = utcTickInterval;
+exports.utcTicks = utcTicks;
+exports.utcTuesday = utcTuesday;
+exports.utcTuesdays = utcTuesdays;
+exports.utcWednesday = utcWednesday;
+exports.utcWednesdays = utcWednesdays;
+exports.utcWeek = utcSunday;
+exports.utcWeeks = utcSundays;
+exports.utcYear = utcYear;
+exports.utcYears = utcYears;
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+})));
diff --git a/node_modules/d3-time/dist/d3-time.min.js b/node_modules/d3-time/dist/d3-time.min.js
new file mode 100644
index 00000000..b7e6e8c0
--- /dev/null
+++ b/node_modules/d3-time/dist/d3-time.min.js
@@ -0,0 +1,2 @@
+// https://d3js.org/d3-time/ v3.0.0 Copyright 2010-2021 Mike Bostock
+!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("d3-array")):"function"==typeof define&&define.amd?define(["exports","d3-array"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).d3=e.d3||{},e.d3)}(this,(function(e,t){"use strict";var n=new Date,u=new Date;function r(e,t,i,o){function a(t){return e(t=0===arguments.length?new Date:new Date(+t)),t}return a.floor=function(t){return e(t=new Date(+t)),t},a.ceil=function(n){return e(n=new Date(n-1)),t(n,1),e(n),n},a.round=function(e){var t=a(e),n=a.ceil(e);return e-t0))return o;do{o.push(i=new Date(+n)),t(n,r),e(n)}while(i=t)for(;e(t),!n(t);)t.setTime(t-1)}),(function(e,u){if(e>=e)if(u<0)for(;++u<=0;)for(;t(e,-1),!n(e););else for(;--u>=0;)for(;t(e,1),!n(e););}))},i&&(a.count=function(t,r){return n.setTime(+t),u.setTime(+r),e(n),e(u),Math.floor(i(n,u))},a.every=function(e){return e=Math.floor(e),isFinite(e)&&e>0?e>1?a.filter(o?function(t){return o(t)%e==0}:function(t){return a.count(0,t)%e==0}):a:null}),a}var i=r((function(){}),(function(e,t){e.setTime(+e+t)}),(function(e,t){return t-e}));i.every=function(e){return e=Math.floor(e),isFinite(e)&&e>0?e>1?r((function(t){t.setTime(Math.floor(t/e)*e)}),(function(t,n){t.setTime(+t+n*e)}),(function(t,n){return(n-t)/e})):i:null};var o=i.range;const a=1e3,c=6e4,s=36e5,f=864e5,l=6048e5,g=2592e6,T=31536e6;var d=r((function(e){e.setTime(e-e.getMilliseconds())}),(function(e,t){e.setTime(+e+t*a)}),(function(e,t){return(t-e)/a}),(function(e){return e.getUTCSeconds()})),m=d.range,M=r((function(e){e.setTime(e-e.getMilliseconds()-e.getSeconds()*a)}),(function(e,t){e.setTime(+e+t*c)}),(function(e,t){return(t-e)/c}),(function(e){return e.getMinutes()})),y=M.range,h=r((function(e){e.setTime(e-e.getMilliseconds()-e.getSeconds()*a-e.getMinutes()*c)}),(function(e,t){e.setTime(+e+t*s)}),(function(e,t){return(t-e)/s}),(function(e){return e.getHours()})),C=h.range,U=r((e=>e.setHours(0,0,0,0)),((e,t)=>e.setDate(e.getDate()+t)),((e,t)=>(t-e-(t.getTimezoneOffset()-e.getTimezoneOffset())*c)/f),(e=>e.getDate()-1)),D=U.range;function F(e){return r((function(t){t.setDate(t.getDate()-(t.getDay()+7-e)%7),t.setHours(0,0,0,0)}),(function(e,t){e.setDate(e.getDate()+7*t)}),(function(e,t){return(t-e-(t.getTimezoneOffset()-e.getTimezoneOffset())*c)/l}))}var Y=F(0),v=F(1),S=F(2),H=F(3),p=F(4),k=F(5),w=F(6),W=Y.range,b=v.range,O=S.range,x=H.range,z=p.range,I=k.range,j=w.range,_=r((function(e){e.setDate(1),e.setHours(0,0,0,0)}),(function(e,t){e.setMonth(e.getMonth()+t)}),(function(e,t){return t.getMonth()-e.getMonth()+12*(t.getFullYear()-e.getFullYear())}),(function(e){return e.getMonth()})),q=_.range,P=r((function(e){e.setMonth(0,1),e.setHours(0,0,0,0)}),(function(e,t){e.setFullYear(e.getFullYear()+t)}),(function(e,t){return t.getFullYear()-e.getFullYear()}),(function(e){return e.getFullYear()}));P.every=function(e){return isFinite(e=Math.floor(e))&&e>0?r((function(t){t.setFullYear(Math.floor(t.getFullYear()/e)*e),t.setMonth(0,1),t.setHours(0,0,0,0)}),(function(t,n){t.setFullYear(t.getFullYear()+n*e)})):null};var A=P.range,B=r((function(e){e.setUTCSeconds(0,0)}),(function(e,t){e.setTime(+e+t*c)}),(function(e,t){return(t-e)/c}),(function(e){return e.getUTCMinutes()})),E=B.range,G=r((function(e){e.setUTCMinutes(0,0,0)}),(function(e,t){e.setTime(+e+t*s)}),(function(e,t){return(t-e)/s}),(function(e){return e.getUTCHours()})),J=G.range,K=r((function(e){e.setUTCHours(0,0,0,0)}),(function(e,t){e.setUTCDate(e.getUTCDate()+t)}),(function(e,t){return(t-e)/f}),(function(e){return e.getUTCDate()-1})),L=K.range;function N(e){return r((function(t){t.setUTCDate(t.getUTCDate()-(t.getUTCDay()+7-e)%7),t.setUTCHours(0,0,0,0)}),(function(e,t){e.setUTCDate(e.getUTCDate()+7*t)}),(function(e,t){return(t-e)/l}))}var Q=N(0),R=N(1),V=N(2),X=N(3),Z=N(4),$=N(5),ee=N(6),te=Q.range,ne=R.range,ue=V.range,re=X.range,ie=Z.range,oe=$.range,ae=ee.range,ce=r((function(e){e.setUTCDate(1),e.setUTCHours(0,0,0,0)}),(function(e,t){e.setUTCMonth(e.getUTCMonth()+t)}),(function(e,t){return t.getUTCMonth()-e.getUTCMonth()+12*(t.getUTCFullYear()-e.getUTCFullYear())}),(function(e){return e.getUTCMonth()})),se=ce.range,fe=r((function(e){e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)}),(function(e,t){e.setUTCFullYear(e.getUTCFullYear()+t)}),(function(e,t){return t.getUTCFullYear()-e.getUTCFullYear()}),(function(e){return e.getUTCFullYear()}));fe.every=function(e){return isFinite(e=Math.floor(e))&&e>0?r((function(t){t.setUTCFullYear(Math.floor(t.getUTCFullYear()/e)*e),t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)}),(function(t,n){t.setUTCFullYear(t.getUTCFullYear()+n*e)})):null};var le=fe.range;function ge(e,n,u,r,o,m){const M=[[d,1,a],[d,5,5e3],[d,15,15e3],[d,30,3e4],[m,1,c],[m,5,3e5],[m,15,9e5],[m,30,18e5],[o,1,s],[o,3,108e5],[o,6,216e5],[o,12,432e5],[r,1,f],[r,2,1728e5],[u,1,l],[n,1,g],[n,3,7776e6],[e,1,T]];function y(n,u,r){const o=Math.abs(u-n)/r,a=t.bisector((([,,e])=>e)).right(M,o);if(a===M.length)return e.every(t.tickStep(n/T,u/T,r));if(0===a)return i.every(Math.max(t.tickStep(n,u,r),1));const[c,s]=M[o/M[a-1][2]=12"
+ },
+ "exports": {
+ "umd": "./dist/d3-time.min.js",
+ "default": "./src/index.js"
+ },
+ "files": [
+ "dist/**/*.js",
+ "src/**/*.js"
+ ],
+ "homepage": "https://d3js.org/d3-time/",
+ "jsdelivr": "dist/d3-time.min.js",
+ "keywords": [
+ "d3",
+ "d3-module",
+ "time",
+ "interval",
+ "calendar"
+ ],
+ "license": "ISC",
+ "main": "src/index.js",
+ "module": "src/index.js",
+ "name": "d3-time",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/d3/d3-time.git"
+ },
+ "scripts": {
+ "postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -",
+ "prepublishOnly": "rm -rf dist && yarn test && rollup -c",
+ "test": "TZ=America/Los_Angeles mocha 'test/**/*-test.js' && eslint src test"
+ },
+ "sideEffects": false,
+ "type": "module",
+ "unpkg": "dist/d3-time.min.js",
+ "version": "3.0.0"
+}
diff --git a/node_modules/d3-time/src/day.js b/node_modules/d3-time/src/day.js
new file mode 100644
index 00000000..6c3f9ca2
--- /dev/null
+++ b/node_modules/d3-time/src/day.js
@@ -0,0 +1,12 @@
+import interval from "./interval.js";
+import {durationDay, durationMinute} from "./duration.js";
+
+var day = interval(
+ date => date.setHours(0, 0, 0, 0),
+ (date, step) => date.setDate(date.getDate() + step),
+ (start, end) => (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay,
+ date => date.getDate() - 1
+);
+
+export default day;
+export var days = day.range;
diff --git a/node_modules/d3-time/src/duration.js b/node_modules/d3-time/src/duration.js
new file mode 100644
index 00000000..341fa8fe
--- /dev/null
+++ b/node_modules/d3-time/src/duration.js
@@ -0,0 +1,7 @@
+export const durationSecond = 1000;
+export const durationMinute = durationSecond * 60;
+export const durationHour = durationMinute * 60;
+export const durationDay = durationHour * 24;
+export const durationWeek = durationDay * 7;
+export const durationMonth = durationDay * 30;
+export const durationYear = durationDay * 365;
diff --git a/node_modules/d3-time/src/hour.js b/node_modules/d3-time/src/hour.js
new file mode 100644
index 00000000..9b944d62
--- /dev/null
+++ b/node_modules/d3-time/src/hour.js
@@ -0,0 +1,15 @@
+import interval from "./interval.js";
+import {durationHour, durationMinute, durationSecond} from "./duration.js";
+
+var hour = interval(function(date) {
+ date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond - date.getMinutes() * durationMinute);
+}, function(date, step) {
+ date.setTime(+date + step * durationHour);
+}, function(start, end) {
+ return (end - start) / durationHour;
+}, function(date) {
+ return date.getHours();
+});
+
+export default hour;
+export var hours = hour.range;
diff --git a/node_modules/d3-time/src/index.js b/node_modules/d3-time/src/index.js
new file mode 100644
index 00000000..c163d635
--- /dev/null
+++ b/node_modules/d3-time/src/index.js
@@ -0,0 +1,112 @@
+export {
+ default as timeInterval
+} from "./interval.js";
+
+export {
+ default as timeMillisecond,
+ milliseconds as timeMilliseconds,
+ default as utcMillisecond,
+ milliseconds as utcMilliseconds
+} from "./millisecond.js";
+
+export {
+ default as timeSecond,
+ seconds as timeSeconds,
+ default as utcSecond,
+ seconds as utcSeconds
+} from "./second.js";
+
+export {
+ default as timeMinute,
+ minutes as timeMinutes
+} from "./minute.js";
+
+export {
+ default as timeHour,
+ hours as timeHours
+} from "./hour.js";
+
+export {
+ default as timeDay,
+ days as timeDays
+} from "./day.js";
+
+export {
+ sunday as timeWeek,
+ sundays as timeWeeks,
+ sunday as timeSunday,
+ sundays as timeSundays,
+ monday as timeMonday,
+ mondays as timeMondays,
+ tuesday as timeTuesday,
+ tuesdays as timeTuesdays,
+ wednesday as timeWednesday,
+ wednesdays as timeWednesdays,
+ thursday as timeThursday,
+ thursdays as timeThursdays,
+ friday as timeFriday,
+ fridays as timeFridays,
+ saturday as timeSaturday,
+ saturdays as timeSaturdays
+} from "./week.js";
+
+export {
+ default as timeMonth,
+ months as timeMonths
+} from "./month.js";
+
+export {
+ default as timeYear,
+ years as timeYears
+} from "./year.js";
+
+export {
+ default as utcMinute,
+ utcMinutes as utcMinutes
+} from "./utcMinute.js";
+
+export {
+ default as utcHour,
+ utcHours as utcHours
+} from "./utcHour.js";
+
+export {
+ default as utcDay,
+ utcDays as utcDays
+} from "./utcDay.js";
+
+export {
+ utcSunday as utcWeek,
+ utcSundays as utcWeeks,
+ utcSunday as utcSunday,
+ utcSundays as utcSundays,
+ utcMonday as utcMonday,
+ utcMondays as utcMondays,
+ utcTuesday as utcTuesday,
+ utcTuesdays as utcTuesdays,
+ utcWednesday as utcWednesday,
+ utcWednesdays as utcWednesdays,
+ utcThursday as utcThursday,
+ utcThursdays as utcThursdays,
+ utcFriday as utcFriday,
+ utcFridays as utcFridays,
+ utcSaturday as utcSaturday,
+ utcSaturdays as utcSaturdays
+} from "./utcWeek.js";
+
+export {
+ default as utcMonth,
+ utcMonths as utcMonths
+} from "./utcMonth.js";
+
+export {
+ default as utcYear,
+ utcYears as utcYears
+} from "./utcYear.js";
+
+export {
+ utcTicks,
+ utcTickInterval,
+ timeTicks,
+ timeTickInterval
+} from "./ticks.js";
diff --git a/node_modules/d3-time/src/interval.js b/node_modules/d3-time/src/interval.js
new file mode 100644
index 00000000..2714a81d
--- /dev/null
+++ b/node_modules/d3-time/src/interval.js
@@ -0,0 +1,70 @@
+var t0 = new Date,
+ t1 = new Date;
+
+export default function newInterval(floori, offseti, count, field) {
+
+ function interval(date) {
+ return floori(date = arguments.length === 0 ? new Date : new Date(+date)), date;
+ }
+
+ interval.floor = function(date) {
+ return floori(date = new Date(+date)), date;
+ };
+
+ interval.ceil = function(date) {
+ return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date;
+ };
+
+ interval.round = function(date) {
+ var d0 = interval(date),
+ d1 = interval.ceil(date);
+ return date - d0 < d1 - date ? d0 : d1;
+ };
+
+ interval.offset = function(date, step) {
+ return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date;
+ };
+
+ interval.range = function(start, stop, step) {
+ var range = [], previous;
+ start = interval.ceil(start);
+ step = step == null ? 1 : Math.floor(step);
+ if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date
+ do range.push(previous = new Date(+start)), offseti(start, step), floori(start);
+ while (previous < start && start < stop);
+ return range;
+ };
+
+ interval.filter = function(test) {
+ return newInterval(function(date) {
+ if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1);
+ }, function(date, step) {
+ if (date >= date) {
+ if (step < 0) while (++step <= 0) {
+ while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty
+ } else while (--step >= 0) {
+ while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty
+ }
+ }
+ });
+ };
+
+ if (count) {
+ interval.count = function(start, end) {
+ t0.setTime(+start), t1.setTime(+end);
+ floori(t0), floori(t1);
+ return Math.floor(count(t0, t1));
+ };
+
+ interval.every = function(step) {
+ step = Math.floor(step);
+ return !isFinite(step) || !(step > 0) ? null
+ : !(step > 1) ? interval
+ : interval.filter(field
+ ? function(d) { return field(d) % step === 0; }
+ : function(d) { return interval.count(0, d) % step === 0; });
+ };
+ }
+
+ return interval;
+}
diff --git a/node_modules/d3-time/src/millisecond.js b/node_modules/d3-time/src/millisecond.js
new file mode 100644
index 00000000..d89585c2
--- /dev/null
+++ b/node_modules/d3-time/src/millisecond.js
@@ -0,0 +1,26 @@
+import interval from "./interval.js";
+
+var millisecond = interval(function() {
+ // noop
+}, function(date, step) {
+ date.setTime(+date + step);
+}, function(start, end) {
+ return end - start;
+});
+
+// An optimized implementation for this simple case.
+millisecond.every = function(k) {
+ k = Math.floor(k);
+ if (!isFinite(k) || !(k > 0)) return null;
+ if (!(k > 1)) return millisecond;
+ return interval(function(date) {
+ date.setTime(Math.floor(date / k) * k);
+ }, function(date, step) {
+ date.setTime(+date + step * k);
+ }, function(start, end) {
+ return (end - start) / k;
+ });
+};
+
+export default millisecond;
+export var milliseconds = millisecond.range;
diff --git a/node_modules/d3-time/src/minute.js b/node_modules/d3-time/src/minute.js
new file mode 100644
index 00000000..2ed894bf
--- /dev/null
+++ b/node_modules/d3-time/src/minute.js
@@ -0,0 +1,15 @@
+import interval from "./interval.js";
+import {durationMinute, durationSecond} from "./duration.js";
+
+var minute = interval(function(date) {
+ date.setTime(date - date.getMilliseconds() - date.getSeconds() * durationSecond);
+}, function(date, step) {
+ date.setTime(+date + step * durationMinute);
+}, function(start, end) {
+ return (end - start) / durationMinute;
+}, function(date) {
+ return date.getMinutes();
+});
+
+export default minute;
+export var minutes = minute.range;
diff --git a/node_modules/d3-time/src/month.js b/node_modules/d3-time/src/month.js
new file mode 100644
index 00000000..ac995dec
--- /dev/null
+++ b/node_modules/d3-time/src/month.js
@@ -0,0 +1,15 @@
+import interval from "./interval.js";
+
+var month = interval(function(date) {
+ date.setDate(1);
+ date.setHours(0, 0, 0, 0);
+}, function(date, step) {
+ date.setMonth(date.getMonth() + step);
+}, function(start, end) {
+ return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12;
+}, function(date) {
+ return date.getMonth();
+});
+
+export default month;
+export var months = month.range;
diff --git a/node_modules/d3-time/src/second.js b/node_modules/d3-time/src/second.js
new file mode 100644
index 00000000..62069ef1
--- /dev/null
+++ b/node_modules/d3-time/src/second.js
@@ -0,0 +1,15 @@
+import interval from "./interval.js";
+import {durationSecond} from "./duration.js";
+
+var second = interval(function(date) {
+ date.setTime(date - date.getMilliseconds());
+}, function(date, step) {
+ date.setTime(+date + step * durationSecond);
+}, function(start, end) {
+ return (end - start) / durationSecond;
+}, function(date) {
+ return date.getUTCSeconds();
+});
+
+export default second;
+export var seconds = second.range;
diff --git a/node_modules/d3-time/src/ticks.js b/node_modules/d3-time/src/ticks.js
new file mode 100644
index 00000000..e2219365
--- /dev/null
+++ b/node_modules/d3-time/src/ticks.js
@@ -0,0 +1,64 @@
+import {bisector, tickStep} from "d3-array";
+import {durationDay, durationHour, durationMinute, durationMonth, durationSecond, durationWeek, durationYear} from "./duration.js";
+import millisecond from "./millisecond.js";
+import second from "./second.js";
+import minute from "./minute.js";
+import hour from "./hour.js";
+import day from "./day.js";
+import {sunday as week} from "./week.js";
+import month from "./month.js";
+import year from "./year.js";
+import utcMinute from "./utcMinute.js";
+import utcHour from "./utcHour.js";
+import utcDay from "./utcDay.js";
+import {utcSunday as utcWeek} from "./utcWeek.js";
+import utcMonth from "./utcMonth.js";
+import utcYear from "./utcYear.js";
+
+function ticker(year, month, week, day, hour, minute) {
+
+ const tickIntervals = [
+ [second, 1, durationSecond],
+ [second, 5, 5 * durationSecond],
+ [second, 15, 15 * durationSecond],
+ [second, 30, 30 * durationSecond],
+ [minute, 1, durationMinute],
+ [minute, 5, 5 * durationMinute],
+ [minute, 15, 15 * durationMinute],
+ [minute, 30, 30 * durationMinute],
+ [ hour, 1, durationHour ],
+ [ hour, 3, 3 * durationHour ],
+ [ hour, 6, 6 * durationHour ],
+ [ hour, 12, 12 * durationHour ],
+ [ day, 1, durationDay ],
+ [ day, 2, 2 * durationDay ],
+ [ week, 1, durationWeek ],
+ [ month, 1, durationMonth ],
+ [ month, 3, 3 * durationMonth ],
+ [ year, 1, durationYear ]
+ ];
+
+ function ticks(start, stop, count) {
+ const reverse = stop < start;
+ if (reverse) [start, stop] = [stop, start];
+ const interval = count && typeof count.range === "function" ? count : tickInterval(start, stop, count);
+ const ticks = interval ? interval.range(start, +stop + 1) : []; // inclusive stop
+ return reverse ? ticks.reverse() : ticks;
+ }
+
+ function tickInterval(start, stop, count) {
+ const target = Math.abs(stop - start) / count;
+ const i = bisector(([,, step]) => step).right(tickIntervals, target);
+ if (i === tickIntervals.length) return year.every(tickStep(start / durationYear, stop / durationYear, count));
+ if (i === 0) return millisecond.every(Math.max(tickStep(start, stop, count), 1));
+ const [t, step] = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i];
+ return t.every(step);
+ }
+
+ return [ticks, tickInterval];
+}
+
+const [utcTicks, utcTickInterval] = ticker(utcYear, utcMonth, utcWeek, utcDay, utcHour, utcMinute);
+const [timeTicks, timeTickInterval] = ticker(year, month, week, day, hour, minute);
+
+export {utcTicks, utcTickInterval, timeTicks, timeTickInterval};
diff --git a/node_modules/d3-time/src/utcDay.js b/node_modules/d3-time/src/utcDay.js
new file mode 100644
index 00000000..8023be15
--- /dev/null
+++ b/node_modules/d3-time/src/utcDay.js
@@ -0,0 +1,15 @@
+import interval from "./interval.js";
+import {durationDay} from "./duration.js";
+
+var utcDay = interval(function(date) {
+ date.setUTCHours(0, 0, 0, 0);
+}, function(date, step) {
+ date.setUTCDate(date.getUTCDate() + step);
+}, function(start, end) {
+ return (end - start) / durationDay;
+}, function(date) {
+ return date.getUTCDate() - 1;
+});
+
+export default utcDay;
+export var utcDays = utcDay.range;
diff --git a/node_modules/d3-time/src/utcHour.js b/node_modules/d3-time/src/utcHour.js
new file mode 100644
index 00000000..98b88222
--- /dev/null
+++ b/node_modules/d3-time/src/utcHour.js
@@ -0,0 +1,15 @@
+import interval from "./interval.js";
+import {durationHour} from "./duration.js";
+
+var utcHour = interval(function(date) {
+ date.setUTCMinutes(0, 0, 0);
+}, function(date, step) {
+ date.setTime(+date + step * durationHour);
+}, function(start, end) {
+ return (end - start) / durationHour;
+}, function(date) {
+ return date.getUTCHours();
+});
+
+export default utcHour;
+export var utcHours = utcHour.range;
diff --git a/node_modules/d3-time/src/utcMinute.js b/node_modules/d3-time/src/utcMinute.js
new file mode 100644
index 00000000..4e5e7e56
--- /dev/null
+++ b/node_modules/d3-time/src/utcMinute.js
@@ -0,0 +1,15 @@
+import interval from "./interval.js";
+import {durationMinute} from "./duration.js";
+
+var utcMinute = interval(function(date) {
+ date.setUTCSeconds(0, 0);
+}, function(date, step) {
+ date.setTime(+date + step * durationMinute);
+}, function(start, end) {
+ return (end - start) / durationMinute;
+}, function(date) {
+ return date.getUTCMinutes();
+});
+
+export default utcMinute;
+export var utcMinutes = utcMinute.range;
diff --git a/node_modules/d3-time/src/utcMonth.js b/node_modules/d3-time/src/utcMonth.js
new file mode 100644
index 00000000..3991b180
--- /dev/null
+++ b/node_modules/d3-time/src/utcMonth.js
@@ -0,0 +1,15 @@
+import interval from "./interval.js";
+
+var utcMonth = interval(function(date) {
+ date.setUTCDate(1);
+ date.setUTCHours(0, 0, 0, 0);
+}, function(date, step) {
+ date.setUTCMonth(date.getUTCMonth() + step);
+}, function(start, end) {
+ return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12;
+}, function(date) {
+ return date.getUTCMonth();
+});
+
+export default utcMonth;
+export var utcMonths = utcMonth.range;
diff --git a/node_modules/d3-time/src/utcWeek.js b/node_modules/d3-time/src/utcWeek.js
new file mode 100644
index 00000000..e36fac8b
--- /dev/null
+++ b/node_modules/d3-time/src/utcWeek.js
@@ -0,0 +1,29 @@
+import interval from "./interval.js";
+import {durationWeek} from "./duration.js";
+
+function utcWeekday(i) {
+ return interval(function(date) {
+ date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7);
+ date.setUTCHours(0, 0, 0, 0);
+ }, function(date, step) {
+ date.setUTCDate(date.getUTCDate() + step * 7);
+ }, function(start, end) {
+ return (end - start) / durationWeek;
+ });
+}
+
+export var utcSunday = utcWeekday(0);
+export var utcMonday = utcWeekday(1);
+export var utcTuesday = utcWeekday(2);
+export var utcWednesday = utcWeekday(3);
+export var utcThursday = utcWeekday(4);
+export var utcFriday = utcWeekday(5);
+export var utcSaturday = utcWeekday(6);
+
+export var utcSundays = utcSunday.range;
+export var utcMondays = utcMonday.range;
+export var utcTuesdays = utcTuesday.range;
+export var utcWednesdays = utcWednesday.range;
+export var utcThursdays = utcThursday.range;
+export var utcFridays = utcFriday.range;
+export var utcSaturdays = utcSaturday.range;
diff --git a/node_modules/d3-time/src/utcYear.js b/node_modules/d3-time/src/utcYear.js
new file mode 100644
index 00000000..ee897648
--- /dev/null
+++ b/node_modules/d3-time/src/utcYear.js
@@ -0,0 +1,26 @@
+import interval from "./interval.js";
+
+var utcYear = interval(function(date) {
+ date.setUTCMonth(0, 1);
+ date.setUTCHours(0, 0, 0, 0);
+}, function(date, step) {
+ date.setUTCFullYear(date.getUTCFullYear() + step);
+}, function(start, end) {
+ return end.getUTCFullYear() - start.getUTCFullYear();
+}, function(date) {
+ return date.getUTCFullYear();
+});
+
+// An optimized implementation for this simple case.
+utcYear.every = function(k) {
+ return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : interval(function(date) {
+ date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k);
+ date.setUTCMonth(0, 1);
+ date.setUTCHours(0, 0, 0, 0);
+ }, function(date, step) {
+ date.setUTCFullYear(date.getUTCFullYear() + step * k);
+ });
+};
+
+export default utcYear;
+export var utcYears = utcYear.range;
diff --git a/node_modules/d3-time/src/week.js b/node_modules/d3-time/src/week.js
new file mode 100644
index 00000000..c0f1b030
--- /dev/null
+++ b/node_modules/d3-time/src/week.js
@@ -0,0 +1,29 @@
+import interval from "./interval.js";
+import {durationMinute, durationWeek} from "./duration.js";
+
+function weekday(i) {
+ return interval(function(date) {
+ date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7);
+ date.setHours(0, 0, 0, 0);
+ }, function(date, step) {
+ date.setDate(date.getDate() + step * 7);
+ }, function(start, end) {
+ return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek;
+ });
+}
+
+export var sunday = weekday(0);
+export var monday = weekday(1);
+export var tuesday = weekday(2);
+export var wednesday = weekday(3);
+export var thursday = weekday(4);
+export var friday = weekday(5);
+export var saturday = weekday(6);
+
+export var sundays = sunday.range;
+export var mondays = monday.range;
+export var tuesdays = tuesday.range;
+export var wednesdays = wednesday.range;
+export var thursdays = thursday.range;
+export var fridays = friday.range;
+export var saturdays = saturday.range;
diff --git a/node_modules/d3-time/src/year.js b/node_modules/d3-time/src/year.js
new file mode 100644
index 00000000..a86872d7
--- /dev/null
+++ b/node_modules/d3-time/src/year.js
@@ -0,0 +1,26 @@
+import interval from "./interval.js";
+
+var year = interval(function(date) {
+ date.setMonth(0, 1);
+ date.setHours(0, 0, 0, 0);
+}, function(date, step) {
+ date.setFullYear(date.getFullYear() + step);
+}, function(start, end) {
+ return end.getFullYear() - start.getFullYear();
+}, function(date) {
+ return date.getFullYear();
+});
+
+// An optimized implementation for this simple case.
+year.every = function(k) {
+ return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : interval(function(date) {
+ date.setFullYear(Math.floor(date.getFullYear() / k) * k);
+ date.setMonth(0, 1);
+ date.setHours(0, 0, 0, 0);
+ }, function(date, step) {
+ date.setFullYear(date.getFullYear() + step * k);
+ });
+};
+
+export default year;
+export var years = year.range;
diff --git a/node_modules/d3-timer/LICENSE b/node_modules/d3-timer/LICENSE
new file mode 100644
index 00000000..b0145150
--- /dev/null
+++ b/node_modules/d3-timer/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2010-2021 Mike Bostock
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/node_modules/d3-timer/README.md b/node_modules/d3-timer/README.md
new file mode 100644
index 00000000..a78ce3e6
--- /dev/null
+++ b/node_modules/d3-timer/README.md
@@ -0,0 +1,87 @@
+# d3-timer
+
+This module provides an efficient queue capable of managing thousands of concurrent animations, while guaranteeing consistent, synchronized timing with concurrent or staged animations. Internally, it uses [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) for fluid animation (if available), switching to [setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout) for delays longer than 24ms.
+
+## Installing
+
+If you use npm, `npm install d3-timer`. You can also download the [latest release on GitHub](https://github.com/d3/d3-timer/releases/latest). For vanilla HTML in modern browsers, import d3-timer from Skypack:
+
+```html
+
+```
+
+For legacy environments, you can load d3-timer’s UMD bundle from an npm-based CDN such as jsDelivr; a `d3` global is exported:
+
+```html
+
+
+```
+
+## API Reference
+
+# d3.now() [<>](https://github.com/d3/d3-timer/blob/master/src/timer.js "Source")
+
+Returns the current time as defined by [performance.now](https://developer.mozilla.org/en-US/docs/Web/API/Performance/now) if available, and [Date.now](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Date/now) if not. The current time is updated at the start of a frame; it is thus consistent during the frame, and any timers scheduled during the same frame will be synchronized. If this method is called outside of a frame, such as in response to a user event, the current time is calculated and then fixed until the next frame, again ensuring consistent timing during event handling.
+
+# d3.timer(callback[, delay[, time]]) [<>](https://github.com/d3/d3-timer/blob/master/src/timer.js "Source")
+
+Schedules a new timer, invoking the specified *callback* repeatedly until the timer is [stopped](#timer_stop). An optional numeric *delay* in milliseconds may be specified to invoke the given *callback* after a delay; if *delay* is not specified, it defaults to zero. The delay is relative to the specified *time* in milliseconds; if *time* is not specified, it defaults to [now](#now).
+
+The *callback* is passed the (apparent) *elapsed* time since the timer became active. For example:
+
+```js
+const t = d3.timer((elapsed) => {
+ console.log(elapsed);
+ if (elapsed > 200) t.stop();
+}, 150);
+```
+
+This produces roughly the following console output:
+
+```
+3
+25
+48
+65
+85
+106
+125
+146
+167
+189
+209
+```
+
+(The exact values may vary depending on your JavaScript runtime and what else your computer is doing.) Note that the first *elapsed* time is 3ms: this is the elapsed time since the timer started, not since the timer was scheduled. Here the timer started 150ms after it was scheduled due to the specified delay. The apparent *elapsed* time may be less than the true *elapsed* time if the page is backgrounded and [requestAnimationFrame](https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame) is paused; in the background, apparent time is frozen.
+
+If [timer](#timer) is called within the callback of another timer, the new timer callback (if eligible as determined by the specified *delay* and *time*) will be invoked immediately at the end of the current frame, rather than waiting until the next frame. Within a frame, timer callbacks are guaranteed to be invoked in the order they were scheduled, regardless of their start time.
+
+# timer.restart(callback[, delay[, time]]) [<>](https://github.com/d3/d3-timer/blob/master/src/timer.js "Source")
+
+Restart a timer with the specified *callback* and optional *delay* and *time*. This is equivalent to stopping this timer and creating a new timer with the specified arguments, although this timer retains the original invocation priority.
+
+# timer.stop() [<>](https://github.com/d3/d3-timer/blob/master/src/timer.js "Source")
+
+Stops this timer, preventing subsequent callbacks. This method has no effect if the timer has already stopped.
+
+# d3.timerFlush() [<>](https://github.com/d3/d3-timer/blob/master/src/timer.js "Source")
+
+Immediately invoke any eligible timer callbacks. Note that zero-delay timers are normally first executed after one frame (~17ms). This can cause a brief flicker because the browser renders the page twice: once at the end of the first event loop, then again immediately on the first timer callback. By flushing the timer queue at the end of the first event loop, you can run any zero-delay timers immediately and avoid the flicker.
+
+# d3.timeout(callback[, delay[, time]]) [<>](https://github.com/d3/d3-timer/blob/master/src/timeout.js "Source")
+
+Like [timer](#timer), except the timer automatically [stops](#timer_stop) on its first callback. A suitable replacement for [setTimeout](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout) that is guaranteed to not run in the background. The *callback* is passed the elapsed time.
+
+# d3.interval(callback[, delay[, time]]) [<>](https://github.com/d3/d3-timer/blob/master/src/interval.js "Source")
+
+Like [timer](#timer), except the *callback* is invoked only every *delay* milliseconds; if *delay* is not specified, this is equivalent to [timer](#timer). A suitable replacement for [setInterval](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval) that is guaranteed to not run in the background. The *callback* is passed the elapsed time.
diff --git a/node_modules/d3-timer/dist/d3-timer.js b/node_modules/d3-timer/dist/d3-timer.js
new file mode 100644
index 00000000..023aa5c0
--- /dev/null
+++ b/node_modules/d3-timer/dist/d3-timer.js
@@ -0,0 +1,153 @@
+// https://d3js.org/d3-timer/ v3.0.1 Copyright 2010-2021 Mike Bostock
+(function (global, factory) {
+typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+typeof define === 'function' && define.amd ? define(['exports'], factory) :
+(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}));
+}(this, (function (exports) { 'use strict';
+
+var frame = 0, // is an animation frame pending?
+ timeout$1 = 0, // is a timeout pending?
+ interval$1 = 0, // are any timers active?
+ pokeDelay = 1000, // how frequently we check for clock skew
+ taskHead,
+ taskTail,
+ clockLast = 0,
+ clockNow = 0,
+ clockSkew = 0,
+ clock = typeof performance === "object" && performance.now ? performance : Date,
+ setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); };
+
+function now() {
+ return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);
+}
+
+function clearNow() {
+ clockNow = 0;
+}
+
+function Timer() {
+ this._call =
+ this._time =
+ this._next = null;
+}
+
+Timer.prototype = timer.prototype = {
+ constructor: Timer,
+ restart: function(callback, delay, time) {
+ if (typeof callback !== "function") throw new TypeError("callback is not a function");
+ time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);
+ if (!this._next && taskTail !== this) {
+ if (taskTail) taskTail._next = this;
+ else taskHead = this;
+ taskTail = this;
+ }
+ this._call = callback;
+ this._time = time;
+ sleep();
+ },
+ stop: function() {
+ if (this._call) {
+ this._call = null;
+ this._time = Infinity;
+ sleep();
+ }
+ }
+};
+
+function timer(callback, delay, time) {
+ var t = new Timer;
+ t.restart(callback, delay, time);
+ return t;
+}
+
+function timerFlush() {
+ now(); // Get the current time, if not already set.
+ ++frame; // Pretend we’ve set an alarm, if we haven’t already.
+ var t = taskHead, e;
+ while (t) {
+ if ((e = clockNow - t._time) >= 0) t._call.call(undefined, e);
+ t = t._next;
+ }
+ --frame;
+}
+
+function wake() {
+ clockNow = (clockLast = clock.now()) + clockSkew;
+ frame = timeout$1 = 0;
+ try {
+ timerFlush();
+ } finally {
+ frame = 0;
+ nap();
+ clockNow = 0;
+ }
+}
+
+function poke() {
+ var now = clock.now(), delay = now - clockLast;
+ if (delay > pokeDelay) clockSkew -= delay, clockLast = now;
+}
+
+function nap() {
+ var t0, t1 = taskHead, t2, time = Infinity;
+ while (t1) {
+ if (t1._call) {
+ if (time > t1._time) time = t1._time;
+ t0 = t1, t1 = t1._next;
+ } else {
+ t2 = t1._next, t1._next = null;
+ t1 = t0 ? t0._next = t2 : taskHead = t2;
+ }
+ }
+ taskTail = t0;
+ sleep(time);
+}
+
+function sleep(time) {
+ if (frame) return; // Soonest alarm already set, or will be.
+ if (timeout$1) timeout$1 = clearTimeout(timeout$1);
+ var delay = time - clockNow; // Strictly less than if we recomputed clockNow.
+ if (delay > 24) {
+ if (time < Infinity) timeout$1 = setTimeout(wake, time - clock.now() - clockSkew);
+ if (interval$1) interval$1 = clearInterval(interval$1);
+ } else {
+ if (!interval$1) clockLast = clock.now(), interval$1 = setInterval(poke, pokeDelay);
+ frame = 1, setFrame(wake);
+ }
+}
+
+function timeout(callback, delay, time) {
+ var t = new Timer;
+ delay = delay == null ? 0 : +delay;
+ t.restart(elapsed => {
+ t.stop();
+ callback(elapsed + delay);
+ }, delay, time);
+ return t;
+}
+
+function interval(callback, delay, time) {
+ var t = new Timer, total = delay;
+ if (delay == null) return t.restart(callback, delay, time), t;
+ t._restart = t.restart;
+ t.restart = function(callback, delay, time) {
+ delay = +delay, time = time == null ? now() : +time;
+ t._restart(function tick(elapsed) {
+ elapsed += total;
+ t._restart(tick, total += delay, time);
+ callback(elapsed);
+ }, delay, time);
+ };
+ t.restart(callback, delay, time);
+ return t;
+}
+
+exports.interval = interval;
+exports.now = now;
+exports.timeout = timeout;
+exports.timer = timer;
+exports.timerFlush = timerFlush;
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+})));
diff --git a/node_modules/d3-timer/dist/d3-timer.min.js b/node_modules/d3-timer/dist/d3-timer.min.js
new file mode 100644
index 00000000..7fee9675
--- /dev/null
+++ b/node_modules/d3-timer/dist/d3-timer.min.js
@@ -0,0 +1,2 @@
+// https://d3js.org/d3-timer/ v3.0.1 Copyright 2010-2021 Mike Bostock
+!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self).d3=t.d3||{})}(this,(function(t){"use strict";var n,e,o=0,i=0,r=0,l=0,u=0,a=0,s="object"==typeof performance&&performance.now?performance:Date,c="object"==typeof window&&window.requestAnimationFrame?window.requestAnimationFrame.bind(window):function(t){setTimeout(t,17)};function f(){return u||(c(_),u=s.now()+a)}function _(){u=0}function m(){this._call=this._time=this._next=null}function p(t,n,e){var o=new m;return o.restart(t,n,e),o}function w(){f(),++o;for(var t,e=n;e;)(t=u-e._time)>=0&&e._call.call(void 0,t),e=e._next;--o}function d(){u=(l=s.now())+a,o=i=0;try{w()}finally{o=0,function(){var t,o,i=n,r=1/0;for(;i;)i._call?(r>i._time&&(r=i._time),t=i,i=i._next):(o=i._next,i._next=null,i=t?t._next=o:n=o);e=t,y(r)}(),u=0}}function h(){var t=s.now(),n=t-l;n>1e3&&(a-=n,l=t)}function y(t){o||(i&&(i=clearTimeout(i)),t-u>24?(t<1/0&&(i=setTimeout(d,t-s.now()-a)),r&&(r=clearInterval(r))):(r||(l=s.now(),r=setInterval(h,1e3)),o=1,c(d)))}m.prototype=p.prototype={constructor:m,restart:function(t,o,i){if("function"!=typeof t)throw new TypeError("callback is not a function");i=(null==i?f():+i)+(null==o?0:+o),this._next||e===this||(e?e._next=this:n=this,e=this),this._call=t,this._time=i,y()},stop:function(){this._call&&(this._call=null,this._time=1/0,y())}},t.interval=function(t,n,e){var o=new m,i=n;return null==n?(o.restart(t,n,e),o):(o._restart=o.restart,o.restart=function(t,n,e){n=+n,e=null==e?f():+e,o._restart((function r(l){l+=i,o._restart(r,i+=n,e),t(l)}),n,e)},o.restart(t,n,e),o)},t.now=f,t.timeout=function(t,n,e){var o=new m;return n=null==n?0:+n,o.restart((e=>{o.stop(),t(e+n)}),n,e),o},t.timer=p,t.timerFlush=w,Object.defineProperty(t,"__esModule",{value:!0})}));
diff --git a/node_modules/d3-timer/package.json b/node_modules/d3-timer/package.json
new file mode 100644
index 00000000..77486ecd
--- /dev/null
+++ b/node_modules/d3-timer/package.json
@@ -0,0 +1,83 @@
+{
+ "_from": "d3-timer@3",
+ "_id": "d3-timer@3.0.1",
+ "_inBundle": false,
+ "_integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
+ "_location": "/d3-timer",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "range",
+ "registry": true,
+ "raw": "d3-timer@3",
+ "name": "d3-timer",
+ "escapedName": "d3-timer",
+ "rawSpec": "3",
+ "saveSpec": null,
+ "fetchSpec": "3"
+ },
+ "_requiredBy": [
+ "/d3",
+ "/d3-force",
+ "/d3-transition"
+ ],
+ "_resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
+ "_shasum": "6284d2a2708285b1abb7e201eda4380af35e63b0",
+ "_spec": "d3-timer@3",
+ "_where": "C:\\Users\\colbs\\CS4241\\d3a4\\node_modules\\d3",
+ "author": {
+ "name": "Mike Bostock",
+ "url": "http://bost.ocks.org/mike"
+ },
+ "bugs": {
+ "url": "https://github.com/d3/d3-timer/issues"
+ },
+ "bundleDependencies": false,
+ "deprecated": false,
+ "description": "An efficient queue capable of managing thousands of concurrent animations.",
+ "devDependencies": {
+ "eslint": "7",
+ "mocha": "8",
+ "rollup": "2",
+ "rollup-plugin-terser": "7"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "exports": {
+ "umd": "./dist/d3-timer.min.js",
+ "default": "./src/index.js"
+ },
+ "files": [
+ "dist/**/*.js",
+ "src/**/*.js"
+ ],
+ "homepage": "https://d3js.org/d3-timer/",
+ "jsdelivr": "dist/d3-timer.min.js",
+ "keywords": [
+ "d3",
+ "d3-module",
+ "timer",
+ "transition",
+ "animation",
+ "requestAnimationFrame",
+ "setTimeout",
+ "setInterval"
+ ],
+ "license": "ISC",
+ "main": "src/index.js",
+ "module": "src/index.js",
+ "name": "d3-timer",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/d3/d3-timer.git"
+ },
+ "scripts": {
+ "postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../${npm_package_name}/dist/${npm_package_name}.js ${npm_package_name}.v${npm_package_version%%.*}.js && cp ../${npm_package_name}/dist/${npm_package_name}.min.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git add ${npm_package_name}.v${npm_package_version%%.*}.js ${npm_package_name}.v${npm_package_version%%.*}.min.js && git commit -m \"${npm_package_name} ${npm_package_version}\" && git push && cd -",
+ "prepublishOnly": "rm -rf dist && yarn test && rollup -c",
+ "test": "mocha 'test/**/*-test.js' && eslint src test"
+ },
+ "sideEffects": false,
+ "type": "module",
+ "unpkg": "dist/d3-timer.min.js",
+ "version": "3.0.1"
+}
diff --git a/node_modules/d3-timer/src/index.js b/node_modules/d3-timer/src/index.js
new file mode 100644
index 00000000..66fb8c97
--- /dev/null
+++ b/node_modules/d3-timer/src/index.js
@@ -0,0 +1,13 @@
+export {
+ now,
+ timer,
+ timerFlush
+} from "./timer.js";
+
+export {
+ default as timeout
+} from "./timeout.js";
+
+export {
+ default as interval
+} from "./interval.js";
diff --git a/node_modules/d3-timer/src/interval.js b/node_modules/d3-timer/src/interval.js
new file mode 100644
index 00000000..e38e1bd8
--- /dev/null
+++ b/node_modules/d3-timer/src/interval.js
@@ -0,0 +1,17 @@
+import {Timer, now} from "./timer.js";
+
+export default function(callback, delay, time) {
+ var t = new Timer, total = delay;
+ if (delay == null) return t.restart(callback, delay, time), t;
+ t._restart = t.restart;
+ t.restart = function(callback, delay, time) {
+ delay = +delay, time = time == null ? now() : +time;
+ t._restart(function tick(elapsed) {
+ elapsed += total;
+ t._restart(tick, total += delay, time);
+ callback(elapsed);
+ }, delay, time);
+ }
+ t.restart(callback, delay, time);
+ return t;
+}
diff --git a/node_modules/d3-timer/src/timeout.js b/node_modules/d3-timer/src/timeout.js
new file mode 100644
index 00000000..29b4dd2d
--- /dev/null
+++ b/node_modules/d3-timer/src/timeout.js
@@ -0,0 +1,11 @@
+import {Timer} from "./timer.js";
+
+export default function(callback, delay, time) {
+ var t = new Timer;
+ delay = delay == null ? 0 : +delay;
+ t.restart(elapsed => {
+ t.stop();
+ callback(elapsed + delay);
+ }, delay, time);
+ return t;
+}
diff --git a/node_modules/d3-timer/src/timer.js b/node_modules/d3-timer/src/timer.js
new file mode 100644
index 00000000..79cdf107
--- /dev/null
+++ b/node_modules/d3-timer/src/timer.js
@@ -0,0 +1,110 @@
+var frame = 0, // is an animation frame pending?
+ timeout = 0, // is a timeout pending?
+ interval = 0, // are any timers active?
+ pokeDelay = 1000, // how frequently we check for clock skew
+ taskHead,
+ taskTail,
+ clockLast = 0,
+ clockNow = 0,
+ clockSkew = 0,
+ clock = typeof performance === "object" && performance.now ? performance : Date,
+ setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); };
+
+export function now() {
+ return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew);
+}
+
+function clearNow() {
+ clockNow = 0;
+}
+
+export function Timer() {
+ this._call =
+ this._time =
+ this._next = null;
+}
+
+Timer.prototype = timer.prototype = {
+ constructor: Timer,
+ restart: function(callback, delay, time) {
+ if (typeof callback !== "function") throw new TypeError("callback is not a function");
+ time = (time == null ? now() : +time) + (delay == null ? 0 : +delay);
+ if (!this._next && taskTail !== this) {
+ if (taskTail) taskTail._next = this;
+ else taskHead = this;
+ taskTail = this;
+ }
+ this._call = callback;
+ this._time = time;
+ sleep();
+ },
+ stop: function() {
+ if (this._call) {
+ this._call = null;
+ this._time = Infinity;
+ sleep();
+ }
+ }
+};
+
+export function timer(callback, delay, time) {
+ var t = new Timer;
+ t.restart(callback, delay, time);
+ return t;
+}
+
+export function timerFlush() {
+ now(); // Get the current time, if not already set.
+ ++frame; // Pretend we’ve set an alarm, if we haven’t already.
+ var t = taskHead, e;
+ while (t) {
+ if ((e = clockNow - t._time) >= 0) t._call.call(undefined, e);
+ t = t._next;
+ }
+ --frame;
+}
+
+function wake() {
+ clockNow = (clockLast = clock.now()) + clockSkew;
+ frame = timeout = 0;
+ try {
+ timerFlush();
+ } finally {
+ frame = 0;
+ nap();
+ clockNow = 0;
+ }
+}
+
+function poke() {
+ var now = clock.now(), delay = now - clockLast;
+ if (delay > pokeDelay) clockSkew -= delay, clockLast = now;
+}
+
+function nap() {
+ var t0, t1 = taskHead, t2, time = Infinity;
+ while (t1) {
+ if (t1._call) {
+ if (time > t1._time) time = t1._time;
+ t0 = t1, t1 = t1._next;
+ } else {
+ t2 = t1._next, t1._next = null;
+ t1 = t0 ? t0._next = t2 : taskHead = t2;
+ }
+ }
+ taskTail = t0;
+ sleep(time);
+}
+
+function sleep(time) {
+ if (frame) return; // Soonest alarm already set, or will be.
+ if (timeout) timeout = clearTimeout(timeout);
+ var delay = time - clockNow; // Strictly less than if we recomputed clockNow.
+ if (delay > 24) {
+ if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew);
+ if (interval) interval = clearInterval(interval);
+ } else {
+ if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay);
+ frame = 1, setFrame(wake);
+ }
+}
diff --git a/node_modules/d3-transition/LICENSE b/node_modules/d3-transition/LICENSE
new file mode 100644
index 00000000..b0145150
--- /dev/null
+++ b/node_modules/d3-transition/LICENSE
@@ -0,0 +1,13 @@
+Copyright 2010-2021 Mike Bostock
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
diff --git a/node_modules/d3-transition/README.md b/node_modules/d3-transition/README.md
new file mode 100644
index 00000000..3802a99e
--- /dev/null
+++ b/node_modules/d3-transition/README.md
@@ -0,0 +1,490 @@
+# d3-transition
+
+A transition is a [selection](https://github.com/d3/d3-selection)-like interface for animating changes to the DOM. Instead of applying changes instantaneously, transitions smoothly interpolate the DOM from its current state to the desired target state over a given duration.
+
+To apply a transition, select elements, call [*selection*.transition](#selection_transition), and then make the desired changes. For example:
+
+```js
+d3.select("body")
+ .transition()
+ .style("background-color", "red");
+```
+
+Transitions support most selection methods (such as [*transition*.attr](#transition_attr) and [*transition*.style](#transition_style) in place of [*selection*.attr](https://github.com/d3/d3-selection#selection_attr) and [*selection*.style](https://github.com/d3/d3-selection#selection_style)), but not all methods are supported; for example, you must [append](https://github.com/d3/d3-selection#selection_append) elements or [bind data](https://github.com/d3/d3-selection#joining-data) before a transition starts. A [*transition*.remove](#transition_remove) operator is provided for convenient removal of elements when the transition ends.
+
+To compute intermediate state, transitions leverage a variety of [built-in interpolators](https://github.com/d3/d3-interpolate). [Colors](https://github.com/d3/d3-interpolate#interpolateRgb), [numbers](https://github.com/d3/d3-interpolate#interpolateNumber), and [transforms](https://github.com/d3/d3-interpolate#interpolateTransform) are automatically detected. [Strings](https://github.com/d3/d3-interpolate#interpolateString) with embedded numbers are also detected, as is common with many styles (such as padding or font sizes) and paths. To specify a custom interpolator, use [*transition*.attrTween](#transition_attrTween), [*transition*.styleTween](#transition_styleTween) or [*transition*.tween](#transition_tween).
+
+## Installing
+
+If you use npm, `npm install d3-transition`. You can also download the [latest release on GitHub](https://github.com/d3/d3-transition/releases/latest). For vanilla HTML in modern browsers, import d3-transition from Skypack:
+
+```html
+
+```
+
+For legacy environments, you can load d3-transition’s UMD bundle from an npm-based CDN such as jsDelivr; a `d3` global is exported:
+
+```html
+
+
+
+
+
+
+
+
+```
+
+[Try d3-transition in your browser.](https://observablehq.com/collection/@d3/d3-transition)
+
+## API Reference
+
+* [Selecting Elements](#selecting-elements)
+* [Modifying Elements](#modifying-elements)
+* [Timing](#timing)
+* [Control Flow](#control-flow)
+* [The Life of a Transition](#the-life-of-a-transition)
+
+### Selecting Elements
+
+Transitions are derived from [selections](https://github.com/d3/d3-selection) via [*selection*.transition](#selection_transition). You can also create a transition on the document root element using [d3.transition](#transition).
+
+# selection.transition([name]) · [Source](https://github.com/d3/d3-transition/blob/master/src/selection/transition.js)
+
+Returns a new transition on the given *selection* with the specified *name*. If a *name* is not specified, null is used. The new transition is only exclusive with other transitions of the same name.
+
+If the *name* is a [transition](#transition) instance, the returned transition has the same id and name as the specified transition. If a transition with the same id already exists on a selected element, the existing transition is returned for that element. Otherwise, the timing of the returned transition is inherited from the existing transition of the same id on the nearest ancestor of each selected element. Thus, this method can be used to synchronize a transition across multiple selections, or to re-select a transition for specific elements and modify its configuration. For example:
+
+```js
+var t = d3.transition()
+ .duration(750)
+ .ease(d3.easeLinear);
+
+d3.selectAll(".apple").transition(t)
+ .style("fill", "red");
+
+d3.selectAll(".orange").transition(t)
+ .style("fill", "orange");
+```
+
+If the specified *transition* is not found on a selected node or its ancestors (such as if the transition [already ended](#the-life-of-a-transition)), the default timing parameters are used; however, in a future release, this will likely be changed to throw an error. See [#59](https://github.com/d3/d3-transition/issues/59).
+
+# selection.interrupt([name]) · [Source](https://github.com/d3/d3-transition/blob/master/src/selection/interrupt.js)
+
+Interrupts the active transition of the specified *name* on the selected elements, and cancels any pending transitions with the specified *name*, if any. If a name is not specified, null is used.
+
+Interrupting a transition on an element has no effect on any transitions on any descendant elements. For example, an [axis transition](https://github.com/d3/d3-axis) consists of multiple independent, synchronized transitions on the descendants of the axis [G element](https://www.w3.org/TR/SVG/struct.html#Groups) (the tick lines, the tick labels, the domain path, *etc.*). To interrupt the axis transition, you must therefore interrupt the descendants:
+
+```js
+selection.selectAll("*").interrupt();
+```
+
+The [universal selector](https://developer.mozilla.org/en-US/docs/Web/CSS/Universal_selectors), `*`, selects all descendant elements. If you also want to interrupt the G element itself:
+
+```js
+selection.interrupt().selectAll("*").interrupt();
+```
+
+# d3.interrupt(node[, name]) · [Source](https://github.com/d3/d3-transition/blob/master/src/interrupt.js)
+
+Interrupts the active transition of the specified *name* on the specified *node*, and cancels any pending transitions with the specified *name*, if any. If a name is not specified, null is used. See also [*selection*.interrupt](#selection_interrupt).
+
+# d3.transition([name]) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/index.js#L29)
+
+Returns a new transition on the root element, `document.documentElement`, with the specified *name*. If a *name* is not specified, null is used. The new transition is only exclusive with other transitions of the same name. The *name* may also be a [transition](#transition) instance; see [*selection*.transition](#selection_transition). This method is equivalent to:
+
+```js
+d3.selection()
+ .transition(name)
+```
+
+This function can also be used to test for transitions (`instanceof d3.transition`) or to extend the transition prototype.
+
+# transition.select(selector) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/select.js)
+
+For each selected element, selects the first descendant element that matches the specified *selector* string, if any, and returns a transition on the resulting selection. The *selector* may be specified either as a selector string or a function. If a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The new transition has the same id, name and timing as this transition; however, if a transition with the same id already exists on a selected element, the existing transition is returned for that element.
+
+This method is equivalent to deriving the selection for this transition via [*transition*.selection](#transition_selection), creating a subselection via [*selection*.select](https://github.com/d3/d3-selection#selection_select), and then creating a new transition via [*selection*.transition](#selection_transition):
+
+```js
+transition
+ .selection()
+ .select(selector)
+ .transition(transition)
+```
+
+# transition.selectAll(selector) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/selectAll.js)
+
+For each selected element, selects all descendant elements that match the specified *selector* string, if any, and returns a transition on the resulting selection. The *selector* may be specified either as a selector string or a function. If a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The new transition has the same id, name and timing as this transition; however, if a transition with the same id already exists on a selected element, the existing transition is returned for that element.
+
+This method is equivalent to deriving the selection for this transition via [*transition*.selection](#transition_selection), creating a subselection via [*selection*.selectAll](https://github.com/d3/d3-selection#selection_selectAll), and then creating a new transition via [*selection*.transition](#selection_transition):
+
+```js
+transition
+ .selection()
+ .selectAll(selector)
+ .transition(transition)
+```
+
+# transition.selectChild([selector]) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/select.js)
+
+For each selected element, selects the first child element that matches the specified *selector* string, if any, and returns a transition on the resulting selection. The *selector* may be specified either as a selector string or a function. If a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The new transition has the same id, name and timing as this transition; however, if a transition with the same id already exists on a selected element, the existing transition is returned for that element.
+
+This method is equivalent to deriving the selection for this transition via [*transition*.selection](#transition_selection), creating a subselection via [*selection*.selectChild](https://github.com/d3/d3-selection#selection_selectChild), and then creating a new transition via [*selection*.transition](#selection_transition):
+
+```js
+transition
+ .selection()
+ .selectChild(selector)
+ .transition(transition)
+```
+
+# transition.selectChildren([selector]) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/selectAll.js)
+
+For each selected element, selects all children that match the specified *selector* string, if any, and returns a transition on the resulting selection. The *selector* may be specified either as a selector string or a function. If a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The new transition has the same id, name and timing as this transition; however, if a transition with the same id already exists on a selected element, the existing transition is returned for that element.
+
+This method is equivalent to deriving the selection for this transition via [*transition*.selection](#transition_selection), creating a subselection via [*selection*.selectChildren](https://github.com/d3/d3-selection#selection_selectChildren), and then creating a new transition via [*selection*.transition](#selection_transition):
+
+```js
+transition
+ .selection()
+ .selectChildren(selector)
+ .transition(transition)
+```
+
+# transition.filter(filter) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/filter.js)
+
+For each selected element, selects only the elements that match the specified *filter*, and returns a transition on the resulting selection. The *filter* may be specified either as a selector string or a function. If a function, it is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The new transition has the same id, name and timing as this transition; however, if a transition with the same id already exists on a selected element, the existing transition is returned for that element.
+
+This method is equivalent to deriving the selection for this transition via [*transition*.selection](#transition_selection), creating a subselection via [*selection*.filter](https://github.com/d3/d3-selection#selection_filter), and then creating a new transition via [*selection*.transition](#selection_transition):
+
+```js
+transition
+ .selection()
+ .filter(filter)
+ .transition(transition)
+```
+
+# transition.merge(other) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/merge.js)
+
+Returns a new transition merging this transition with the specified *other* transition, which must have the same id as this transition. The returned transition has the same number of groups, the same parents, the same name and the same id as this transition. Any missing (null) elements in this transition are filled with the corresponding element, if present (not null), from the *other* transition.
+
+This method is equivalent to deriving the selection for this transition via [*transition*.selection](#transition_selection), merging with the selection likewise derived from the *other* transition via [*selection*.merge](https://github.com/d3/d3-selection#selection_merge), and then creating a new transition via [*selection*.transition](#selection_transition):
+
+```js
+transition
+ .selection()
+ .merge(other.selection())
+ .transition(transition)
+```
+
+# transition.transition() · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/transition.js)
+
+Returns a new transition on the same selected elements as this transition, scheduled to start when this transition ends. The new transition inherits a reference time equal to this transition’s time plus its [delay](#transition_delay) and [duration](#transition_duration). The new transition also inherits this transition’s name, duration, and [easing](#transition_ease). This method can be used to schedule a sequence of chained transitions. For example:
+
+```js
+d3.selectAll(".apple")
+ .transition() // First fade to green.
+ .style("fill", "green")
+ .transition() // Then red.
+ .style("fill", "red")
+ .transition() // Wait one second. Then brown, and remove.
+ .delay(1000)
+ .style("fill", "brown")
+ .remove();
+```
+
+The delay for each transition is relative to its previous transition. Thus, in the above example, apples will stay red for one second before the last transition to brown starts.
+
+# transition.selection() · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/selection.js)
+
+Returns the [selection](https://github.com/d3/d3-selection#selection) corresponding to this transition.
+
+# d3.active(node[, name]) · [Source](https://github.com/d3/d3-transition/blob/master/src/active.js)
+
+Returns the active transition on the specified *node* with the specified *name*, if any. If no *name* is specified, null is used. Returns null if there is no such active transition on the specified node. This method is useful for creating chained transitions. For example, to initiate disco mode:
+
+```js
+d3.selectAll("circle").transition()
+ .delay(function(d, i) { return i * 50; })
+ .on("start", function repeat() {
+ d3.active(this)
+ .style("fill", "red")
+ .transition()
+ .style("fill", "green")
+ .transition()
+ .style("fill", "blue")
+ .transition()
+ .on("start", repeat);
+ });
+```
+
+See [chained transitions](https://bl.ocks.org/mbostock/70d5541b547cc222aa02) for an example.
+
+### Modifying Elements
+
+After selecting elements and creating a transition with [*selection*.transition](#selection_transition), use the transition’s transformation methods to affect document content.
+
+# transition.attr(name, value) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/attr.js)
+
+For each selected element, assigns the [attribute tween](#transition_attrTween) for the attribute with the specified *name* to the specified target *value*. The starting value of the tween is the attribute’s value when the transition starts. The target *value* may be specified either as a constant or a function. If a function, it is immediately evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element.
+
+If the target value is null, the attribute is removed when the transition starts. Otherwise, an interpolator is chosen based on the type of the target value, using the following algorithm:
+
+1. If *value* is a number, use [interpolateNumber](https://github.com/d3/d3-interpolate#interpolateNumber).
+2. If *value* is a [color](https://github.com/d3/d3-color#color) or a string coercible to a color, use [interpolateRgb](https://github.com/d3/d3-interpolate#interpolateRgb).
+3. Use [interpolateString](https://github.com/d3/d3-interpolate#interpolateString).
+
+To apply a different interpolator, use [*transition*.attrTween](#transition_attrTween).
+
+# transition.attrTween(name[, factory]) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/attrTween.js)
+
+If *factory* is specified and not null, assigns the attribute [tween](#transition_tween) for the attribute with the specified *name* to the specified interpolator *factory*. An interpolator factory is a function that returns an [interpolator](https://github.com/d3/d3-interpolate); when the transition starts, the *factory* is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The returned interpolator will then be invoked for each frame of the transition, in order, being passed the [eased](#transition_ease) time *t*, typically in the range [0, 1]. Lastly, the return value of the interpolator will be used to set the attribute value. The interpolator must return a string. (To remove an attribute at the start of a transition, use [*transition*.attr](#transition_attr); to remove an attribute at the end of a transition, use [*transition*.on](#transition_on) to listen for the *end* event.)
+
+If the specified *factory* is null, removes the previously-assigned attribute tween of the specified *name*, if any. If *factory* is not specified, returns the current interpolator factory for attribute with the specified *name*, or undefined if no such tween exists.
+
+For example, to interpolate the fill attribute from red to blue:
+
+```js
+transition.attrTween("fill", function() {
+ return d3.interpolateRgb("red", "blue");
+});
+```
+
+Or to interpolate from the current fill to blue, like [*transition*.attr](#transition_attr):
+
+```js
+transition.attrTween("fill", function() {
+ return d3.interpolateRgb(this.getAttribute("fill"), "blue");
+});
+```
+
+Or to apply a custom rainbow interpolator:
+
+```js
+transition.attrTween("fill", function() {
+ return function(t) {
+ return "hsl(" + t * 360 + ",100%,50%)";
+ };
+});
+```
+
+This method is useful to specify a custom interpolator, such as one that understands [SVG paths](https://bl.ocks.org/mbostock/3916621). A useful technique is *data interpolation*, where [d3.interpolateObject](https://github.com/d3/d3-interpolate#interpolateObject) is used to interpolate two data values, and the resulting value is then used (say, with a [shape](https://github.com/d3/d3-shape)) to compute the new attribute value.
+
+# transition.style(name, value[, priority]) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/style.js)
+
+For each selected element, assigns the [style tween](#transition_styleTween) for the style with the specified *name* to the specified target *value* with the specified *priority*. The starting value of the tween is the style’s inline value if present, and otherwise its computed value, when the transition starts. The target *value* may be specified either as a constant or a function. If a function, it is immediately evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element.
+
+If the target value is null, the style is removed when the transition starts. Otherwise, an interpolator is chosen based on the type of the target value, using the following algorithm:
+
+1. If *value* is a number, use [interpolateNumber](https://github.com/d3/d3-interpolate#interpolateNumber).
+2. If *value* is a [color](https://github.com/d3/d3-color#color) or a string coercible to a color, use [interpolateRgb](https://github.com/d3/d3-interpolate#interpolateRgb).
+3. Use [interpolateString](https://github.com/d3/d3-interpolate#interpolateString).
+
+To apply a different interpolator, use [*transition*.styleTween](#transition_styleTween).
+
+# transition.styleTween(name[, factory[, priority]]) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/styleTween.js)
+
+If *factory* is specified and not null, assigns the style [tween](#transition_tween) for the style with the specified *name* to the specified interpolator *factory*. An interpolator factory is a function that returns an [interpolator](https://github.com/d3/d3-interpolate); when the transition starts, the *factory* is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The returned interpolator will then be invoked for each frame of the transition, in order, being passed the [eased](#transition_ease) time *t*, typically in the range [0, 1]. Lastly, the return value of the interpolator will be used to set the style value with the specified *priority*. The interpolator must return a string. (To remove an style at the start of a transition, use [*transition*.style](#transition_style); to remove an style at the end of a transition, use [*transition*.on](#transition_on) to listen for the *end* event.)
+
+If the specified *factory* is null, removes the previously-assigned style tween of the specified *name*, if any. If *factory* is not specified, returns the current interpolator factory for style with the specified *name*, or undefined if no such tween exists.
+
+For example, to interpolate the fill style from red to blue:
+
+```js
+transition.styleTween("fill", function() {
+ return d3.interpolateRgb("red", "blue");
+});
+```
+
+Or to interpolate from the current fill to blue, like [*transition*.style](#transition_style):
+
+```js
+transition.styleTween("fill", function() {
+ return d3.interpolateRgb(this.style.fill, "blue");
+});
+```
+
+Or to apply a custom rainbow interpolator:
+
+```js
+transition.styleTween("fill", function() {
+ return function(t) {
+ return "hsl(" + t * 360 + ",100%,50%)";
+ };
+});
+```
+
+This method is useful to specify a custom interpolator, such as with *data interpolation*, where [d3.interpolateObject](https://github.com/d3/d3-interpolate#interpolateObject) is used to interpolate two data values, and the resulting value is then used to compute the new style value.
+
+# transition.text(value) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/text.js)
+
+For each selected element, sets the [text content](http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-textContent) to the specified target *value* when the transition starts. The *value* may be specified either as a constant or a function. If a function, it is immediately evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The function’s return value is then used to set each element’s text content. A null value will clear the content.
+
+To interpolate text rather than to set it on start, use [*transition*.textTween](#transition_textTween) or append a replacement element and cross-fade opacity. Text is not interpolated by default because it is usually undesirable.
+
+# transition.textTween(factory) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/textTween.js), [Examples](https://observablehq.com/@d3/transition-texttween)
+
+If *factory* is specified and not null, assigns the text [tween](#transition_tween) to the specified interpolator *factory*. An interpolator factory is a function that returns an [interpolator](https://github.com/d3/d3-interpolate); when the transition starts, the *factory* is evaluated for each selected element, in order, being passed the current datum `d` and index `i`, with the `this` context as the current DOM element. The returned interpolator will then be invoked for each frame of the transition, in order, being passed the [eased](#transition_ease) time *t*, typically in the range [0, 1]. Lastly, the return value of the interpolator will be used to set the text. The interpolator must return a string.
+
+For example, to interpolate the text with integers from 0 to 100:
+
+```js
+transition.textTween(function() {
+ return d3.interpolateRound(0, 100);
+});
+```
+
+If the specified *factory* is null, removes the previously-assigned text tween, if any. If *factory* is not specified, returns the current interpolator factory for text, or undefined if no such tween exists.
+
+# transition.remove() · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/remove.js)
+
+For each selected element, [removes](https://github.com/d3/d3-selection#selection_remove) the element when the transition ends, as long as the element has no other active or pending transitions. If the element has other active or pending transitions, does nothing.
+
+# transition.tween(name[, value]) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/tween.js)
+
+For each selected element, assigns the tween with the specified *name* with the specified *value* function. The *value* must be specified as a function that returns a function. When the transition starts, the *value* function is evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The returned function is then invoked for each frame of the transition, in order, being passed the [eased](#transition_ease) time *t*, typically in the range [0, 1]. If the specified *value* is null, removes the previously-assigned tween of the specified *name*, if any.
+
+For example, to interpolate the fill attribute to blue, like [*transition*.attr](#transition_attr):
+
+```js
+transition.tween("attr.fill", function() {
+ var i = d3.interpolateRgb(this.getAttribute("fill"), "blue");
+ return function(t) {
+ this.setAttribute("fill", i(t));
+ };
+});
+```
+
+This method is useful to specify a custom interpolator, or to perform side-effects, say to animate the [scroll offset](https://bl.ocks.org/mbostock/1649463).
+
+### Timing
+
+The [easing](#transition_ease), [delay](#transition_delay) and [duration](#transition_duration) of a transition is configurable. For example, a per-element delay can be used to [stagger the reordering](https://observablehq.com/@d3/sortable-bar-chart) of elements, improving perception. See [Animated Transitions in Statistical Data Graphics](http://vis.berkeley.edu/papers/animated_transitions/) for recommendations.
+
+# transition.delay([value]) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/delay.js)
+
+For each selected element, sets the transition delay to the specified *value* in milliseconds. The *value* may be specified either as a constant or a function. If a function, it is immediately evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The function’s return value is then used to set each element’s transition delay. If a delay is not specified, it defaults to zero.
+
+If a *value* is not specified, returns the current value of the delay for the first (non-null) element in the transition. This is generally useful only if you know that the transition contains exactly one element.
+
+Setting the delay to a multiple of the index `i` is a convenient way to stagger transitions across a set of elements. For example:
+
+```js
+transition.delay(function(d, i) { return i * 10; });
+```
+
+Of course, you can also compute the delay as a function of the data, or [sort the selection](https://github.com/d3/d3-selection#selection_sort) before computed an index-based delay.
+
+# transition.duration([value]) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/duration.js)
+
+For each selected element, sets the transition duration to the specified *value* in milliseconds. The *value* may be specified either as a constant or a function. If a function, it is immediately evaluated for each selected element, in order, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. The function’s return value is then used to set each element’s transition duration. If a duration is not specified, it defaults to 250ms.
+
+If a *value* is not specified, returns the current value of the duration for the first (non-null) element in the transition. This is generally useful only if you know that the transition contains exactly one element.
+
+# transition.ease([value]) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/ease.js)
+
+Specifies the transition [easing function](https://github.com/d3/d3-ease) for all selected elements. The *value* must be specified as a function. The easing function is invoked for each frame of the animation, being passed the normalized time *t* in the range [0, 1]; it must then return the eased time *tʹ* which is typically also in the range [0, 1]. A good easing function should return 0 if *t* = 0 and 1 if *t* = 1. If an easing function is not specified, it defaults to [d3.easeCubic](https://github.com/d3/d3-ease#easeCubic).
+
+If a *value* is not specified, returns the current easing function for the first (non-null) element in the transition. This is generally useful only if you know that the transition contains exactly one element.
+
+# transition.easeVarying(factory) [<>](https://github.com/d3/d3-transition/blob/master/src/transition/easeVarying.js "Source")
+
+Specifies a factory for the transition [easing function](https://github.com/d3/d3-ease). The *factory* must be a function. It is invoked for each node of the selection, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. It must return an easing function.
+
+### Control Flow
+
+For advanced usage, transitions provide methods for custom control flow.
+
+# transition.end() · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/end.js)
+
+Returns a promise that resolves when every selected element finishes transitioning. If any element’s transition is cancelled or interrupted, the promise rejects.
+
+# transition.on(typenames[, listener]) · [Source](https://github.com/d3/d3-transition/blob/master/src/transition/on.js)
+
+Adds or removes a *listener* to each selected element for the specified event *typenames*. The *typenames* is one of the following string event types:
+
+* `start` - when the transition starts.
+* `end` - when the transition ends.
+* `interrupt` - when the transition is interrupted.
+* `cancel` - when the transition is cancelled.
+
+See [The Life of a Transition](#the-life-of-a-transition) for more. Note that these are *not* native DOM events as implemented by [*selection*.on](https://github.com/d3/d3-selection#selection_on) and [*selection*.dispatch](https://github.com/d3/d3-selection#selection_dispatch), but transition events!
+
+The type may be optionally followed by a period (`.`) and a name; the optional name allows multiple callbacks to be registered to receive events of the same type, such as `start.foo` and `start.bar`. To specify multiple typenames, separate typenames with spaces, such as `interrupt end` or `start.foo start.bar`.
+
+When a specified transition event is dispatched on a selected node, the specified *listener* will be invoked for the transitioning element, being passed the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. Listeners always see the latest datum for their element, but the index is a property of the selection and is fixed when the listener is assigned; to update the index, re-assign the listener.
+
+If an event listener was previously registered for the same *typename* on a selected element, the old listener is removed before the new listener is added. To remove a listener, pass null as the *listener*. To remove all listeners for a given name, pass null as the *listener* and `.foo` as the *typename*, where `foo` is the name; to remove all listeners with no name, specify `.` as the *typename*.
+
+If a *listener* is not specified, returns the currently-assigned listener for the specified event *typename* on the first (non-null) selected element, if any. If multiple typenames are specified, the first matching listener is returned.
+
+# transition.each(function) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/each.js)
+
+Invokes the specified *function* for each selected element, passing in the current datum (*d*), the current index (*i*), and the current group (*nodes*), with *this* as the current DOM element. This method can be used to invoke arbitrary code for each selected element, and is useful for creating a context to access parent and child data simultaneously. Equivalent to [*selection*.each](https://github.com/d3/d3-selection#selection_each).
+
+# transition.call(function[, arguments…]) · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/call.js)
+
+Invokes the specified *function* exactly once, passing in this transition along with any optional *arguments*. Returns this transition. This is equivalent to invoking the function by hand but facilitates method chaining. For example, to set several attributes in a reusable function:
+
+```js
+function color(transition, fill, stroke) {
+ transition
+ .style("fill", fill)
+ .style("stroke", stroke);
+}
+```
+
+Now say:
+
+```js
+d3.selectAll("div").transition().call(color, "red", "blue");
+```
+
+This is equivalent to:
+
+```js
+color(d3.selectAll("div").transition(), "red", "blue");
+```
+
+Equivalent to [*selection*.call](https://github.com/d3/d3-selection#selection_call).
+
+# transition.empty() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/empty.js)
+
+Returns true if this transition contains no (non-null) elements. Equivalent to [*selection*.empty](https://github.com/d3/d3-selection#selection_empty).
+
+# transition.nodes() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/nodes.js)
+
+Returns an array of all (non-null) elements in this transition. Equivalent to [*selection*.nodes](https://github.com/d3/d3-selection#selection_nodes).
+
+# transition.node() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/node.js)
+
+Returns the first (non-null) element in this transition. If the transition is empty, returns null. Equivalent to [*selection*.node](https://github.com/d3/d3-selection#selection_node).
+
+# transition.size() · [Source](https://github.com/d3/d3-selection/blob/master/src/selection/size.js)
+
+Returns the total number of elements in this transition. Equivalent to [*selection*.size](https://github.com/d3/d3-selection#selection_size).
+
+### The Life of a Transition
+
+Immediately after creating a transition, such as by [*selection*.transition](#selection_transition) or [*transition*.transition](#transition_transition), you may configure the transition using methods such as [*transition*.delay](#transition_delay), [*transition*.duration](#transition_duration), [*transition*.attr](#transition_attr) and [*transition*.style](#transition_style). Methods that specify target values (such as *transition*.attr) are evaluated synchronously; however, methods that require the starting value for interpolation, such as [*transition*.attrTween](#transition_attrTween) and [*transition*.styleTween](#transition_styleTween), must be deferred until the transition starts.
+
+Shortly after creation, either at the end of the current frame or during the next frame, the transition is scheduled. At this point, the delay and `start` event listeners may no longer be changed; attempting to do so throws an error with the message “too late: already scheduled” (or if the transition has ended, “transition not found”).
+
+When the transition subsequently starts, it interrupts the active transition of the same name on the same element, if any, dispatching an `interrupt` event to registered listeners. (Note that interrupts happen on start, not creation, and thus even a zero-delay transition will not immediately interrupt the active transition: the old transition is given a final frame. Use [*selection*.interrupt](#selection_interrupt) to interrupt immediately.) The starting transition also cancels any pending transitions of the same name on the same element that were created before the starting transition. The transition then dispatches a `start` event to registered listeners. This is the last moment at which the transition may be modified: the transition’s timing, tweens, and listeners may not be changed when it is running; attempting to do so throws an error with the message “too late: already running” (or if the transition has ended, “transition not found”). The transition initializes its tweens immediately after starting.
+
+During the frame the transition starts, but *after* all transitions starting this frame have been started, the transition invokes its tweens for the first time. Batching tween initialization, which typically involves reading from the DOM, improves performance by avoiding interleaved DOM reads and writes.
+
+For each frame that a transition is active, it invokes its tweens with an [eased](#transition_ease) *t*-value ranging from 0 to 1. Within each frame, the transition invokes its tweens in the order they were registered.
+
+When a transition ends, it invokes its tweens a final time with a (non-eased) *t*-value of 1. It then dispatches an `end` event to registered listeners. This is the last moment at which the transition may be inspected: after ending, the transition is deleted from the element, and its configuration is destroyed. (A transition’s configuration is also destroyed on interrupt or cancel.) Attempting to inspect a transition after it is destroyed throws an error with the message “transition not found”.
diff --git a/node_modules/d3-transition/dist/d3-transition.js b/node_modules/d3-transition/dist/d3-transition.js
new file mode 100644
index 00000000..81849c2a
--- /dev/null
+++ b/node_modules/d3-transition/dist/d3-transition.js
@@ -0,0 +1,900 @@
+// https://d3js.org/d3-transition/ v3.0.1 Copyright 2010-2021 Mike Bostock
+(function (global, factory) {
+typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-selection'), require('d3-dispatch'), require('d3-timer'), require('d3-interpolate'), require('d3-color'), require('d3-ease')) :
+typeof define === 'function' && define.amd ? define(['exports', 'd3-selection', 'd3-dispatch', 'd3-timer', 'd3-interpolate', 'd3-color', 'd3-ease'], factory) :
+(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}, global.d3, global.d3, global.d3, global.d3, global.d3, global.d3));
+}(this, (function (exports, d3Selection, d3Dispatch, d3Timer, d3Interpolate, d3Color, d3Ease) { 'use strict';
+
+var emptyOn = d3Dispatch.dispatch("start", "end", "cancel", "interrupt");
+var emptyTween = [];
+
+var CREATED = 0;
+var SCHEDULED = 1;
+var STARTING = 2;
+var STARTED = 3;
+var RUNNING = 4;
+var ENDING = 5;
+var ENDED = 6;
+
+function schedule(node, name, id, index, group, timing) {
+ var schedules = node.__transition;
+ if (!schedules) node.__transition = {};
+ else if (id in schedules) return;
+ create(node, id, {
+ name: name,
+ index: index, // For context during callback.
+ group: group, // For context during callback.
+ on: emptyOn,
+ tween: emptyTween,
+ time: timing.time,
+ delay: timing.delay,
+ duration: timing.duration,
+ ease: timing.ease,
+ timer: null,
+ state: CREATED
+ });
+}
+
+function init(node, id) {
+ var schedule = get(node, id);
+ if (schedule.state > CREATED) throw new Error("too late; already scheduled");
+ return schedule;
+}
+
+function set(node, id) {
+ var schedule = get(node, id);
+ if (schedule.state > STARTED) throw new Error("too late; already running");
+ return schedule;
+}
+
+function get(node, id) {
+ var schedule = node.__transition;
+ if (!schedule || !(schedule = schedule[id])) throw new Error("transition not found");
+ return schedule;
+}
+
+function create(node, id, self) {
+ var schedules = node.__transition,
+ tween;
+
+ // Initialize the self timer when the transition is created.
+ // Note the actual delay is not known until the first callback!
+ schedules[id] = self;
+ self.timer = d3Timer.timer(schedule, 0, self.time);
+
+ function schedule(elapsed) {
+ self.state = SCHEDULED;
+ self.timer.restart(start, self.delay, self.time);
+
+ // If the elapsed delay is less than our first sleep, start immediately.
+ if (self.delay <= elapsed) start(elapsed - self.delay);
+ }
+
+ function start(elapsed) {
+ var i, j, n, o;
+
+ // If the state is not SCHEDULED, then we previously errored on start.
+ if (self.state !== SCHEDULED) return stop();
+
+ for (i in schedules) {
+ o = schedules[i];
+ if (o.name !== self.name) continue;
+
+ // While this element already has a starting transition during this frame,
+ // defer starting an interrupting transition until that transition has a
+ // chance to tick (and possibly end); see d3/d3-transition#54!
+ if (o.state === STARTED) return d3Timer.timeout(start);
+
+ // Interrupt the active transition, if any.
+ if (o.state === RUNNING) {
+ o.state = ENDED;
+ o.timer.stop();
+ o.on.call("interrupt", node, node.__data__, o.index, o.group);
+ delete schedules[i];
+ }
+
+ // Cancel any pre-empted transitions.
+ else if (+i < id) {
+ o.state = ENDED;
+ o.timer.stop();
+ o.on.call("cancel", node, node.__data__, o.index, o.group);
+ delete schedules[i];
+ }
+ }
+
+ // Defer the first tick to end of the current frame; see d3/d3#1576.
+ // Note the transition may be canceled after start and before the first tick!
+ // Note this must be scheduled before the start event; see d3/d3-transition#16!
+ // Assuming this is successful, subsequent callbacks go straight to tick.
+ d3Timer.timeout(function() {
+ if (self.state === STARTED) {
+ self.state = RUNNING;
+ self.timer.restart(tick, self.delay, self.time);
+ tick(elapsed);
+ }
+ });
+
+ // Dispatch the start event.
+ // Note this must be done before the tween are initialized.
+ self.state = STARTING;
+ self.on.call("start", node, node.__data__, self.index, self.group);
+ if (self.state !== STARTING) return; // interrupted
+ self.state = STARTED;
+
+ // Initialize the tween, deleting null tween.
+ tween = new Array(n = self.tween.length);
+ for (i = 0, j = -1; i < n; ++i) {
+ if (o = self.tween[i].value.call(node, node.__data__, self.index, self.group)) {
+ tween[++j] = o;
+ }
+ }
+ tween.length = j + 1;
+ }
+
+ function tick(elapsed) {
+ var t = elapsed < self.duration ? self.ease.call(null, elapsed / self.duration) : (self.timer.restart(stop), self.state = ENDING, 1),
+ i = -1,
+ n = tween.length;
+
+ while (++i < n) {
+ tween[i].call(node, t);
+ }
+
+ // Dispatch the end event.
+ if (self.state === ENDING) {
+ self.on.call("end", node, node.__data__, self.index, self.group);
+ stop();
+ }
+ }
+
+ function stop() {
+ self.state = ENDED;
+ self.timer.stop();
+ delete schedules[id];
+ for (var i in schedules) return; // eslint-disable-line no-unused-vars
+ delete node.__transition;
+ }
+}
+
+function interrupt(node, name) {
+ var schedules = node.__transition,
+ schedule,
+ active,
+ empty = true,
+ i;
+
+ if (!schedules) return;
+
+ name = name == null ? null : name + "";
+
+ for (i in schedules) {
+ if ((schedule = schedules[i]).name !== name) { empty = false; continue; }
+ active = schedule.state > STARTING && schedule.state < ENDING;
+ schedule.state = ENDED;
+ schedule.timer.stop();
+ schedule.on.call(active ? "interrupt" : "cancel", node, node.__data__, schedule.index, schedule.group);
+ delete schedules[i];
+ }
+
+ if (empty) delete node.__transition;
+}
+
+function selection_interrupt(name) {
+ return this.each(function() {
+ interrupt(this, name);
+ });
+}
+
+function tweenRemove(id, name) {
+ var tween0, tween1;
+ return function() {
+ var schedule = set(this, id),
+ tween = schedule.tween;
+
+ // If this node shared tween with the previous node,
+ // just assign the updated shared tween and we’re done!
+ // Otherwise, copy-on-write.
+ if (tween !== tween0) {
+ tween1 = tween0 = tween;
+ for (var i = 0, n = tween1.length; i < n; ++i) {
+ if (tween1[i].name === name) {
+ tween1 = tween1.slice();
+ tween1.splice(i, 1);
+ break;
+ }
+ }
+ }
+
+ schedule.tween = tween1;
+ };
+}
+
+function tweenFunction(id, name, value) {
+ var tween0, tween1;
+ if (typeof value !== "function") throw new Error;
+ return function() {
+ var schedule = set(this, id),
+ tween = schedule.tween;
+
+ // If this node shared tween with the previous node,
+ // just assign the updated shared tween and we’re done!
+ // Otherwise, copy-on-write.
+ if (tween !== tween0) {
+ tween1 = (tween0 = tween).slice();
+ for (var t = {name: name, value: value}, i = 0, n = tween1.length; i < n; ++i) {
+ if (tween1[i].name === name) {
+ tween1[i] = t;
+ break;
+ }
+ }
+ if (i === n) tween1.push(t);
+ }
+
+ schedule.tween = tween1;
+ };
+}
+
+function transition_tween(name, value) {
+ var id = this._id;
+
+ name += "";
+
+ if (arguments.length < 2) {
+ var tween = get(this.node(), id).tween;
+ for (var i = 0, n = tween.length, t; i < n; ++i) {
+ if ((t = tween[i]).name === name) {
+ return t.value;
+ }
+ }
+ return null;
+ }
+
+ return this.each((value == null ? tweenRemove : tweenFunction)(id, name, value));
+}
+
+function tweenValue(transition, name, value) {
+ var id = transition._id;
+
+ transition.each(function() {
+ var schedule = set(this, id);
+ (schedule.value || (schedule.value = {}))[name] = value.apply(this, arguments);
+ });
+
+ return function(node) {
+ return get(node, id).value[name];
+ };
+}
+
+function interpolate(a, b) {
+ var c;
+ return (typeof b === "number" ? d3Interpolate.interpolateNumber
+ : b instanceof d3Color.color ? d3Interpolate.interpolateRgb
+ : (c = d3Color.color(b)) ? (b = c, d3Interpolate.interpolateRgb)
+ : d3Interpolate.interpolateString)(a, b);
+}
+
+function attrRemove(name) {
+ return function() {
+ this.removeAttribute(name);
+ };
+}
+
+function attrRemoveNS(fullname) {
+ return function() {
+ this.removeAttributeNS(fullname.space, fullname.local);
+ };
+}
+
+function attrConstant(name, interpolate, value1) {
+ var string00,
+ string1 = value1 + "",
+ interpolate0;
+ return function() {
+ var string0 = this.getAttribute(name);
+ return string0 === string1 ? null
+ : string0 === string00 ? interpolate0
+ : interpolate0 = interpolate(string00 = string0, value1);
+ };
+}
+
+function attrConstantNS(fullname, interpolate, value1) {
+ var string00,
+ string1 = value1 + "",
+ interpolate0;
+ return function() {
+ var string0 = this.getAttributeNS(fullname.space, fullname.local);
+ return string0 === string1 ? null
+ : string0 === string00 ? interpolate0
+ : interpolate0 = interpolate(string00 = string0, value1);
+ };
+}
+
+function attrFunction(name, interpolate, value) {
+ var string00,
+ string10,
+ interpolate0;
+ return function() {
+ var string0, value1 = value(this), string1;
+ if (value1 == null) return void this.removeAttribute(name);
+ string0 = this.getAttribute(name);
+ string1 = value1 + "";
+ return string0 === string1 ? null
+ : string0 === string00 && string1 === string10 ? interpolate0
+ : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));
+ };
+}
+
+function attrFunctionNS(fullname, interpolate, value) {
+ var string00,
+ string10,
+ interpolate0;
+ return function() {
+ var string0, value1 = value(this), string1;
+ if (value1 == null) return void this.removeAttributeNS(fullname.space, fullname.local);
+ string0 = this.getAttributeNS(fullname.space, fullname.local);
+ string1 = value1 + "";
+ return string0 === string1 ? null
+ : string0 === string00 && string1 === string10 ? interpolate0
+ : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));
+ };
+}
+
+function transition_attr(name, value) {
+ var fullname = d3Selection.namespace(name), i = fullname === "transform" ? d3Interpolate.interpolateTransformSvg : interpolate;
+ return this.attrTween(name, typeof value === "function"
+ ? (fullname.local ? attrFunctionNS : attrFunction)(fullname, i, tweenValue(this, "attr." + name, value))
+ : value == null ? (fullname.local ? attrRemoveNS : attrRemove)(fullname)
+ : (fullname.local ? attrConstantNS : attrConstant)(fullname, i, value));
+}
+
+function attrInterpolate(name, i) {
+ return function(t) {
+ this.setAttribute(name, i.call(this, t));
+ };
+}
+
+function attrInterpolateNS(fullname, i) {
+ return function(t) {
+ this.setAttributeNS(fullname.space, fullname.local, i.call(this, t));
+ };
+}
+
+function attrTweenNS(fullname, value) {
+ var t0, i0;
+ function tween() {
+ var i = value.apply(this, arguments);
+ if (i !== i0) t0 = (i0 = i) && attrInterpolateNS(fullname, i);
+ return t0;
+ }
+ tween._value = value;
+ return tween;
+}
+
+function attrTween(name, value) {
+ var t0, i0;
+ function tween() {
+ var i = value.apply(this, arguments);
+ if (i !== i0) t0 = (i0 = i) && attrInterpolate(name, i);
+ return t0;
+ }
+ tween._value = value;
+ return tween;
+}
+
+function transition_attrTween(name, value) {
+ var key = "attr." + name;
+ if (arguments.length < 2) return (key = this.tween(key)) && key._value;
+ if (value == null) return this.tween(key, null);
+ if (typeof value !== "function") throw new Error;
+ var fullname = d3Selection.namespace(name);
+ return this.tween(key, (fullname.local ? attrTweenNS : attrTween)(fullname, value));
+}
+
+function delayFunction(id, value) {
+ return function() {
+ init(this, id).delay = +value.apply(this, arguments);
+ };
+}
+
+function delayConstant(id, value) {
+ return value = +value, function() {
+ init(this, id).delay = value;
+ };
+}
+
+function transition_delay(value) {
+ var id = this._id;
+
+ return arguments.length
+ ? this.each((typeof value === "function"
+ ? delayFunction
+ : delayConstant)(id, value))
+ : get(this.node(), id).delay;
+}
+
+function durationFunction(id, value) {
+ return function() {
+ set(this, id).duration = +value.apply(this, arguments);
+ };
+}
+
+function durationConstant(id, value) {
+ return value = +value, function() {
+ set(this, id).duration = value;
+ };
+}
+
+function transition_duration(value) {
+ var id = this._id;
+
+ return arguments.length
+ ? this.each((typeof value === "function"
+ ? durationFunction
+ : durationConstant)(id, value))
+ : get(this.node(), id).duration;
+}
+
+function easeConstant(id, value) {
+ if (typeof value !== "function") throw new Error;
+ return function() {
+ set(this, id).ease = value;
+ };
+}
+
+function transition_ease(value) {
+ var id = this._id;
+
+ return arguments.length
+ ? this.each(easeConstant(id, value))
+ : get(this.node(), id).ease;
+}
+
+function easeVarying(id, value) {
+ return function() {
+ var v = value.apply(this, arguments);
+ if (typeof v !== "function") throw new Error;
+ set(this, id).ease = v;
+ };
+}
+
+function transition_easeVarying(value) {
+ if (typeof value !== "function") throw new Error;
+ return this.each(easeVarying(this._id, value));
+}
+
+function transition_filter(match) {
+ if (typeof match !== "function") match = d3Selection.matcher(match);
+
+ for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
+ for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) {
+ if ((node = group[i]) && match.call(node, node.__data__, i, group)) {
+ subgroup.push(node);
+ }
+ }
+ }
+
+ return new Transition(subgroups, this._parents, this._name, this._id);
+}
+
+function transition_merge(transition) {
+ if (transition._id !== this._id) throw new Error;
+
+ for (var groups0 = this._groups, groups1 = transition._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) {
+ for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) {
+ if (node = group0[i] || group1[i]) {
+ merge[i] = node;
+ }
+ }
+ }
+
+ for (; j < m0; ++j) {
+ merges[j] = groups0[j];
+ }
+
+ return new Transition(merges, this._parents, this._name, this._id);
+}
+
+function start(name) {
+ return (name + "").trim().split(/^|\s+/).every(function(t) {
+ var i = t.indexOf(".");
+ if (i >= 0) t = t.slice(0, i);
+ return !t || t === "start";
+ });
+}
+
+function onFunction(id, name, listener) {
+ var on0, on1, sit = start(name) ? init : set;
+ return function() {
+ var schedule = sit(this, id),
+ on = schedule.on;
+
+ // If this node shared a dispatch with the previous node,
+ // just assign the updated shared dispatch and we’re done!
+ // Otherwise, copy-on-write.
+ if (on !== on0) (on1 = (on0 = on).copy()).on(name, listener);
+
+ schedule.on = on1;
+ };
+}
+
+function transition_on(name, listener) {
+ var id = this._id;
+
+ return arguments.length < 2
+ ? get(this.node(), id).on.on(name)
+ : this.each(onFunction(id, name, listener));
+}
+
+function removeFunction(id) {
+ return function() {
+ var parent = this.parentNode;
+ for (var i in this.__transition) if (+i !== id) return;
+ if (parent) parent.removeChild(this);
+ };
+}
+
+function transition_remove() {
+ return this.on("end.remove", removeFunction(this._id));
+}
+
+function transition_select(select) {
+ var name = this._name,
+ id = this._id;
+
+ if (typeof select !== "function") select = d3Selection.selector(select);
+
+ for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) {
+ for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) {
+ if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) {
+ if ("__data__" in node) subnode.__data__ = node.__data__;
+ subgroup[i] = subnode;
+ schedule(subgroup[i], name, id, i, subgroup, get(node, id));
+ }
+ }
+ }
+
+ return new Transition(subgroups, this._parents, name, id);
+}
+
+function transition_selectAll(select) {
+ var name = this._name,
+ id = this._id;
+
+ if (typeof select !== "function") select = d3Selection.selectorAll(select);
+
+ for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) {
+ for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
+ if (node = group[i]) {
+ for (var children = select.call(node, node.__data__, i, group), child, inherit = get(node, id), k = 0, l = children.length; k < l; ++k) {
+ if (child = children[k]) {
+ schedule(child, name, id, k, children, inherit);
+ }
+ }
+ subgroups.push(children);
+ parents.push(node);
+ }
+ }
+ }
+
+ return new Transition(subgroups, parents, name, id);
+}
+
+var Selection = d3Selection.selection.prototype.constructor;
+
+function transition_selection() {
+ return new Selection(this._groups, this._parents);
+}
+
+function styleNull(name, interpolate) {
+ var string00,
+ string10,
+ interpolate0;
+ return function() {
+ var string0 = d3Selection.style(this, name),
+ string1 = (this.style.removeProperty(name), d3Selection.style(this, name));
+ return string0 === string1 ? null
+ : string0 === string00 && string1 === string10 ? interpolate0
+ : interpolate0 = interpolate(string00 = string0, string10 = string1);
+ };
+}
+
+function styleRemove(name) {
+ return function() {
+ this.style.removeProperty(name);
+ };
+}
+
+function styleConstant(name, interpolate, value1) {
+ var string00,
+ string1 = value1 + "",
+ interpolate0;
+ return function() {
+ var string0 = d3Selection.style(this, name);
+ return string0 === string1 ? null
+ : string0 === string00 ? interpolate0
+ : interpolate0 = interpolate(string00 = string0, value1);
+ };
+}
+
+function styleFunction(name, interpolate, value) {
+ var string00,
+ string10,
+ interpolate0;
+ return function() {
+ var string0 = d3Selection.style(this, name),
+ value1 = value(this),
+ string1 = value1 + "";
+ if (value1 == null) string1 = value1 = (this.style.removeProperty(name), d3Selection.style(this, name));
+ return string0 === string1 ? null
+ : string0 === string00 && string1 === string10 ? interpolate0
+ : (string10 = string1, interpolate0 = interpolate(string00 = string0, value1));
+ };
+}
+
+function styleMaybeRemove(id, name) {
+ var on0, on1, listener0, key = "style." + name, event = "end." + key, remove;
+ return function() {
+ var schedule = set(this, id),
+ on = schedule.on,
+ listener = schedule.value[key] == null ? remove || (remove = styleRemove(name)) : undefined;
+
+ // If this node shared a dispatch with the previous node,
+ // just assign the updated shared dispatch and we’re done!
+ // Otherwise, copy-on-write.
+ if (on !== on0 || listener0 !== listener) (on1 = (on0 = on).copy()).on(event, listener0 = listener);
+
+ schedule.on = on1;
+ };
+}
+
+function transition_style(name, value, priority) {
+ var i = (name += "") === "transform" ? d3Interpolate.interpolateTransformCss : interpolate;
+ return value == null ? this
+ .styleTween(name, styleNull(name, i))
+ .on("end.style." + name, styleRemove(name))
+ : typeof value === "function" ? this
+ .styleTween(name, styleFunction(name, i, tweenValue(this, "style." + name, value)))
+ .each(styleMaybeRemove(this._id, name))
+ : this
+ .styleTween(name, styleConstant(name, i, value), priority)
+ .on("end.style." + name, null);
+}
+
+function styleInterpolate(name, i, priority) {
+ return function(t) {
+ this.style.setProperty(name, i.call(this, t), priority);
+ };
+}
+
+function styleTween(name, value, priority) {
+ var t, i0;
+ function tween() {
+ var i = value.apply(this, arguments);
+ if (i !== i0) t = (i0 = i) && styleInterpolate(name, i, priority);
+ return t;
+ }
+ tween._value = value;
+ return tween;
+}
+
+function transition_styleTween(name, value, priority) {
+ var key = "style." + (name += "");
+ if (arguments.length < 2) return (key = this.tween(key)) && key._value;
+ if (value == null) return this.tween(key, null);
+ if (typeof value !== "function") throw new Error;
+ return this.tween(key, styleTween(name, value, priority == null ? "" : priority));
+}
+
+function textConstant(value) {
+ return function() {
+ this.textContent = value;
+ };
+}
+
+function textFunction(value) {
+ return function() {
+ var value1 = value(this);
+ this.textContent = value1 == null ? "" : value1;
+ };
+}
+
+function transition_text(value) {
+ return this.tween("text", typeof value === "function"
+ ? textFunction(tweenValue(this, "text", value))
+ : textConstant(value == null ? "" : value + ""));
+}
+
+function textInterpolate(i) {
+ return function(t) {
+ this.textContent = i.call(this, t);
+ };
+}
+
+function textTween(value) {
+ var t0, i0;
+ function tween() {
+ var i = value.apply(this, arguments);
+ if (i !== i0) t0 = (i0 = i) && textInterpolate(i);
+ return t0;
+ }
+ tween._value = value;
+ return tween;
+}
+
+function transition_textTween(value) {
+ var key = "text";
+ if (arguments.length < 1) return (key = this.tween(key)) && key._value;
+ if (value == null) return this.tween(key, null);
+ if (typeof value !== "function") throw new Error;
+ return this.tween(key, textTween(value));
+}
+
+function transition_transition() {
+ var name = this._name,
+ id0 = this._id,
+ id1 = newId();
+
+ for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
+ for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
+ if (node = group[i]) {
+ var inherit = get(node, id0);
+ schedule(node, name, id1, i, group, {
+ time: inherit.time + inherit.delay + inherit.duration,
+ delay: 0,
+ duration: inherit.duration,
+ ease: inherit.ease
+ });
+ }
+ }
+ }
+
+ return new Transition(groups, this._parents, name, id1);
+}
+
+function transition_end() {
+ var on0, on1, that = this, id = that._id, size = that.size();
+ return new Promise(function(resolve, reject) {
+ var cancel = {value: reject},
+ end = {value: function() { if (--size === 0) resolve(); }};
+
+ that.each(function() {
+ var schedule = set(this, id),
+ on = schedule.on;
+
+ // If this node shared a dispatch with the previous node,
+ // just assign the updated shared dispatch and we’re done!
+ // Otherwise, copy-on-write.
+ if (on !== on0) {
+ on1 = (on0 = on).copy();
+ on1._.cancel.push(cancel);
+ on1._.interrupt.push(cancel);
+ on1._.end.push(end);
+ }
+
+ schedule.on = on1;
+ });
+
+ // The selection was empty, resolve end immediately
+ if (size === 0) resolve();
+ });
+}
+
+var id = 0;
+
+function Transition(groups, parents, name, id) {
+ this._groups = groups;
+ this._parents = parents;
+ this._name = name;
+ this._id = id;
+}
+
+function transition(name) {
+ return d3Selection.selection().transition(name);
+}
+
+function newId() {
+ return ++id;
+}
+
+var selection_prototype = d3Selection.selection.prototype;
+
+Transition.prototype = transition.prototype = {
+ constructor: Transition,
+ select: transition_select,
+ selectAll: transition_selectAll,
+ selectChild: selection_prototype.selectChild,
+ selectChildren: selection_prototype.selectChildren,
+ filter: transition_filter,
+ merge: transition_merge,
+ selection: transition_selection,
+ transition: transition_transition,
+ call: selection_prototype.call,
+ nodes: selection_prototype.nodes,
+ node: selection_prototype.node,
+ size: selection_prototype.size,
+ empty: selection_prototype.empty,
+ each: selection_prototype.each,
+ on: transition_on,
+ attr: transition_attr,
+ attrTween: transition_attrTween,
+ style: transition_style,
+ styleTween: transition_styleTween,
+ text: transition_text,
+ textTween: transition_textTween,
+ remove: transition_remove,
+ tween: transition_tween,
+ delay: transition_delay,
+ duration: transition_duration,
+ ease: transition_ease,
+ easeVarying: transition_easeVarying,
+ end: transition_end,
+ [Symbol.iterator]: selection_prototype[Symbol.iterator]
+};
+
+var defaultTiming = {
+ time: null, // Set on use.
+ delay: 0,
+ duration: 250,
+ ease: d3Ease.easeCubicInOut
+};
+
+function inherit(node, id) {
+ var timing;
+ while (!(timing = node.__transition) || !(timing = timing[id])) {
+ if (!(node = node.parentNode)) {
+ throw new Error(`transition ${id} not found`);
+ }
+ }
+ return timing;
+}
+
+function selection_transition(name) {
+ var id,
+ timing;
+
+ if (name instanceof Transition) {
+ id = name._id, name = name._name;
+ } else {
+ id = newId(), (timing = defaultTiming).time = d3Timer.now(), name = name == null ? null : name + "";
+ }
+
+ for (var groups = this._groups, m = groups.length, j = 0; j < m; ++j) {
+ for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) {
+ if (node = group[i]) {
+ schedule(node, name, id, i, group, timing || inherit(node, id));
+ }
+ }
+ }
+
+ return new Transition(groups, this._parents, name, id);
+}
+
+d3Selection.selection.prototype.interrupt = selection_interrupt;
+d3Selection.selection.prototype.transition = selection_transition;
+
+var root = [null];
+
+function active(node, name) {
+ var schedules = node.__transition,
+ schedule,
+ i;
+
+ if (schedules) {
+ name = name == null ? null : name + "";
+ for (i in schedules) {
+ if ((schedule = schedules[i]).state > SCHEDULED && schedule.name === name) {
+ return new Transition([[node]], root, name, +i);
+ }
+ }
+ }
+
+ return null;
+}
+
+exports.active = active;
+exports.interrupt = interrupt;
+exports.transition = transition;
+
+Object.defineProperty(exports, '__esModule', { value: true });
+
+})));
diff --git a/node_modules/d3-transition/dist/d3-transition.min.js b/node_modules/d3-transition/dist/d3-transition.min.js
new file mode 100644
index 00000000..8e9bffd1
--- /dev/null
+++ b/node_modules/d3-transition/dist/d3-transition.min.js
@@ -0,0 +1,2 @@
+// https://d3js.org/d3-transition/ v3.0.1 Copyright 2010-2021 Mike Bostock
+!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("d3-selection"),require("d3-dispatch"),require("d3-timer"),require("d3-interpolate"),require("d3-color"),require("d3-ease")):"function"==typeof define&&define.amd?define(["exports","d3-selection","d3-dispatch","d3-timer","d3-interpolate","d3-color","d3-ease"],n):n((t="undefined"!=typeof globalThis?globalThis:t||self).d3=t.d3||{},t.d3,t.d3,t.d3,t.d3,t.d3,t.d3)}(this,(function(t,n,e,r,i,o,u){"use strict";var a=e.dispatch("start","end","cancel","interrupt"),s=[];function l(t,n,e,i,o,u){var l=t.__transition;if(l){if(e in l)return}else t.__transition={};!function(t,n,e){var i,o=t.__transition;function u(t){e.state=1,e.timer.restart(a,e.delay,e.time),e.delay<=t&&a(t-e.delay)}function a(u){var f,c,h,d;if(1!==e.state)return l();for(f in o)if((d=o[f]).name===e.name){if(3===d.state)return r.timeout(a);4===d.state?(d.state=6,d.timer.stop(),d.on.call("interrupt",t,t.__data__,d.index,d.group),delete o[f]):+f0)throw new Error("too late; already scheduled");return e}function c(t,n){var e=h(t,n);if(e.state>3)throw new Error("too late; already running");return e}function h(t,n){var e=t.__transition;if(!e||!(e=e[n]))throw new Error("transition not found");return e}function d(t,n){var e,r,i,o=t.__transition,u=!0;if(o){for(i in n=null==n?null:n+"",o)(e=o[i]).name===n?(r=e.state>2&&e.state<5,e.state=6,e.timer.stop(),e.on.call(r?"interrupt":"cancel",t,t.__data__,e.index,e.group),delete o[i]):u=!1;u&&delete t.__transition}}function p(t,n){var e,r;return function(){var i=c(this,t),o=i.tween;if(o!==e)for(var u=0,a=(r=e=o).length;u=0&&(t=t.slice(0,n)),!t||"start"===t}))}(n)?f:c;return function(){var u=o(this,t),a=u.on;a!==r&&(i=(r=a).copy()).on(n,e),u.on=i}}var k=n.selection.prototype.constructor;function M(t){return function(){this.style.removeProperty(t)}}function R(t,n,e){return function(r){this.style.setProperty(t,n.call(this,r),e)}}function I(t,n,e){var r,i;function o(){var o=n.apply(this,arguments);return o!==i&&(r=(i=o)&&R(t,o,e)),r}return o._value=n,o}function V(t){return function(n){this.textContent=t.call(this,n)}}function $(t){var n,e;function r(){var r=t.apply(this,arguments);return r!==e&&(n=(e=r)&&V(r)),n}return r._value=t,r}var B=0;function D(t,n,e,r){this._groups=t,this._parents=n,this._name=e,this._id=r}function F(t){return n.selection().transition(t)}function G(){return++B}var H=n.selection.prototype;D.prototype=F.prototype={constructor:D,select:function(t){var e=this._name,r=this._id;"function"!=typeof t&&(t=n.selector(t));for(var i=this._groups,o=i.length,u=new Array(o),a=0;a