From 4813d41b01a4fe1323370c09331dd20ccc8d0533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Fri, 2 Aug 2019 22:15:20 +0200 Subject: [PATCH 01/18] New features: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - using hexbin.context([context]), hexbin.hexagon() and hexbin.mesh() support canvas ; fixes https://github.com/d3/d3-hexbin/issues/1 - incremental updates: bins.add(point); bins.addAll(points); remove(point); bins.removeAll(points); fixes https://github.com/d3/d3-hexbin/issues/3 - hexbin.angle([angle]) sets or reads an angle (default 0°, use 90° for flat-topped hexagons) ; fixes https://github.com/d3/d3-hexbin/issues/8 --- README.md | 32 +++++++- src/hexbin.js | 189 ++++++++++++++++++++++++++++++++++---------- test/hexbin-test.js | 33 ++++++++ 3 files changed, 212 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index ef0dac6..d736ee4 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,23 @@ svg.selectAll("path") This method ignores the hexbin’s [extent](#hexbin_extent); it may return bins outside the extent if necessary to contain the specified points. +# bins.add(point) + +Adds a point and returns the bins. + +# bins.addAll(points) + +Adds points and returns the bins. + +# bins.remove(point) + +Removes the point (if it is referenced in its bin), and returns the bins. Empty bins are pruned. + +# bins.removeAll(points) + +Removes all the points from the bins, and returns the bins. Empty bins are pruned. + + # hexbin.hexagon([radius]) Returns the SVG path string for the hexagon centered at the origin ⟨0,0⟩. The path string is defined with relative coordinates such that you can easily translate the hexagon to the desired position. If *radius* is not specified, the hexbin’s [current radius](#hexbin_radius) is used. If *radius* is specified, a hexagon with the specified radius is returned; this is useful for area-encoded bivariate hexbins. @@ -97,9 +114,13 @@ function y(d) { The *y*-coordinate accessor is used by [*hexbin*](#_hexbin) to compute the *y*-coordinate of each point. The default value assumes each point is specified as a two-element array of numbers [*x*, *y*]. +# hexbin.angle([angle]) + +If *angle* is specified, sets the angle of the hexagonal grid to the specified number, in degrees. If *angle* is not specified, returns the current angle, which defaults to pointy-topped hexagons. + # hexbin.radius([radius]) -If *radius* is specified, sets the radius of the hexagon to the specified number. If *radius* is not specified, returns the current radius, which defaults to 1. The hexagons are pointy-topped (rather than flat-topped); the width of each hexagon is *radius* × 2 × sin(π / 3) and the height of each hexagon is *radius* × 3 / 2. +If *radius* is specified, sets the radius of the hexagon to the specified number. If *radius* is not specified, returns the current radius, which defaults to 1. The width of each hexagon is *radius* × 2 × sin(π / 3) and the height of each hexagon is *radius* × 3 / 2. # hexbin.extent([extent]) @@ -113,3 +134,12 @@ If *size* is specified, sets the [extent](#hexbin_extent) to the specified bound hexbin.extent([[0, 0], [width, height]]); hexbin.size([width, height]); ``` + +# hexbin.context([context]) [<>](https://github.com/d3/d3-hexbin/blob/master/src/hexbin.js "Source") + +If *context* is specified, sets the current render context and returns the hexbin. If the *context* is null, hexbin.mesh and hexbin.hexagon will return SVG path strings; if the context is non-null, hexbin.mesh and hexbin.hexagon will instead call methods on the specified context to render geometry. The context must implement the following subset of the [CanvasRenderingContext2D API](https://www.w3.org/TR/2dcontext/#canvasrenderingcontext2d): + +* *context*.moveTo(*x*, *y*) +* *context*.lineTo(*x*, *y*) + +If a *context* is not specified, returns the current render context which defaults to null. diff --git a/src/hexbin.js b/src/hexbin.js index c898b7f..e5df2f8 100644 --- a/src/hexbin.js +++ b/src/hexbin.js @@ -18,74 +18,157 @@ export default function() { y = pointY, r, dx, - dy; + dy, + angle = 0, + ca = 1, + sa = 0, + context = null, + binsById = {}, + bins = []; + + // from pixels to grid + function transform(x, y) { + if (ca === 1) return [x, y]; + return [x * ca - y * sa, x * sa + y * ca]; + } + + // from grid to pixels + function untransform(x, y) { + if (ca === 1) return [x, y]; + return [x * ca + y * sa, - x * sa + y * ca]; + } function hexbin(points) { - var binsById = {}, bins = [], i, n = points.length; + binsById = {}; + bins.splice(0, bins.length); + addAll(points); + return bins; + } + + function getBin(px, py) { + var u = transform(px, py); + px = u[0]; + py = u[1]; + var pj = Math.round(py = py / dy), + pi = Math.round(px = px / dx - (pj & 1) / 2), + py1 = py - pj; + + if (Math.abs(py1) * 3 > 1) { + var px1 = px - pi, + pi2 = pi + (px < pi ? -1 : 1) / 2, + pj2 = pj + (py < pj ? -1 : 1), + px2 = px - pi2, + py2 = py - pj2; + if (px1 * px1 + py1 * py1 > px2 * px2 + py2 * py2) pi = pi2 + (pj & 1 ? 1 : -1) / 2, pj = pj2; + } + return [pi, pj]; + } + + function addOne(point, px, py) { + var b = getBin(px, py), pi = b[0], pj = b[1], id = b[0] + "-" + b[1], bin = binsById[id]; + if (bin) bin.push(point); + else { + bins.push(bin = binsById[id] = [point]); + var u = untransform((pi + (pj & 1) / 2) * dx, pj * dy); + bin.x = u[0]; + bin.y = u[1]; + } + } + + function addAll(points) { + var i, point, px, py, n = points.length; for (i = 0; i < n; ++i) { if (isNaN(px = +x.call(null, point = points[i], i, points)) || isNaN(py = +y.call(null, point, i, points))) continue; + addOne(point, px, py); + } + } - var point, - px, - py, - pj = Math.round(py = py / dy), - pi = Math.round(px = px / dx - (pj & 1) / 2), - py1 = py - pj; - - if (Math.abs(py1) * 3 > 1) { - var px1 = px - pi, - pi2 = pi + (px < pi ? -1 : 1) / 2, - pj2 = pj + (py < pj ? -1 : 1), - px2 = px - pi2, - py2 = py - pj2; - if (px1 * px1 + py1 * py1 > px2 * px2 + py2 * py2) pi = pi2 + (pj & 1 ? 1 : -1) / 2, pj = pj2; - } - - var id = pi + "-" + pj, bin = binsById[id]; - if (bin) bin.push(point); - else { - bins.push(bin = binsById[id] = [point]); - bin.x = (pi + (pj & 1) / 2) * dx; - bin.y = pj * dy; + function remove(point) { + var px, py; + if (isNaN(px = +x.call(null, point)) + || isNaN(py = +y.call(null, point))) return; + var b = getBin(px, py), id = b[0] + "-" + b[1], bin = binsById[id]; + if (bin) { + var i = bin.indexOf(point); + if (i > -1) { + bin.splice(i, 1); + if (bin.length == 0) { + i = bins.indexOf(bin); + bins.splice(i, 1); + delete binsById[id]; + } } } - return bins; } function hexagon(radius) { - var x0 = 0, y0 = 0; return angles.map(function(angle) { - var x1 = Math.sin(angle) * radius, - y1 = -Math.cos(angle) * radius, - dx = x1 - x0, - dy = y1 - y0; - x0 = x1, y0 = y1; - return [dx, dy]; + return untransform( Math.sin(angle) * radius, -Math.cos(angle) * radius ); }); } + + function vectors(points) { + for (var i = points.length - 1; i > 0; i--) { + points[i][0] -= points[i-1][0]; + points[i][1] -= points[i-1][1]; + } + } hexbin.hexagon = function(radius) { - return "m" + hexagon(radius == null ? r : +radius).join("l") + "z"; + var points = hexagon(radius == null ? r : +radius); + if (!context) { + vectors(points); + return "m" + points.join("l") + "z"; + } + context.moveTo(points[0][0], points[0][1]); + for (var i = 1; i < 6; i++) + context.lineTo(points[i][0], points[i][1]); }; hexbin.centers = function() { - var centers = [], - j = Math.round(y0 / dy), - i = Math.round(x0 / dx); - for (var y = j * dy; y < y1 + r; y += dy, ++j) { - for (var x = i * dx + (j & 1) * dx / 2; x < x1 + dx / 2; x += dx) { - centers.push([x, y]); + var u00 = transform(x0, y0), tx00 = u00[0], ty00 = u00[1], + u10 = transform(x1, y0), tx10 = u10[0], ty10 = u10[1], + u01 = transform(x0, y1), tx01 = u01[0], ty01 = u01[1], + u11 = transform(x1, y1), tx11 = u11[0], ty11 = u11[1], + tx0 = Math.min(tx00, tx01, tx10, tx11), + ty0 = Math.min(ty00, ty01, ty10, ty11), + tx1 = Math.max(tx00, tx01, tx10, tx11), + ty1 = Math.max(ty00, ty01, ty10, ty11), + centers = [], + j = Math.round(ty0 / dy), + i = Math.round(tx0 / dx); + + for (var y = j * dy; y < ty1 + r; y += dy, ++j) { + for (var x = i * dx + (j & 1) * dx / 2; x < tx1 + dx / 2; x += dx) { + var [ux, uy] = untransform(x, y); + if (ux >= x0 - dx && ux <= x1 + dx && uy >= y0 - dy && uy <= y1 + dy) + centers.push([ux, uy]); } } return centers; }; hexbin.mesh = function() { - var fragment = hexagon(r).slice(0, 4).join("l"); - return hexbin.centers().map(function(p) { return "M" + p + "m" + fragment; }).join(""); + var points = hexagon(r).slice(0, 4), + centers = hexbin.centers(); + if (!context) { + vectors(points); + var fragment = points.join("l"); + return centers.map(function(p) { return "M" + p + "m" + fragment; }).join(""); + } + for (var i = 0, l = centers.length; i < l; i++) { + var x0 = centers[i][0], y0 = centers[i][1]; + context.moveTo(x0 + points[0][0], y0 + points[0][1]); + for (var j = 1; j < 4; j++) + context.lineTo(x0 + points[j][0], y0 + points[j][1]); + } + }; + + hexbin.angle = function(_) { + return arguments.length ? (angle = _, ca = Math.cos(angle * Math.PI/180), sa = Math.sin(angle * Math.PI/180), hexbin) : x; }; hexbin.x = function(_) { @@ -108,5 +191,29 @@ export default function() { return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], hexbin) : [[x0, y0], [x1, y1]]; }; + hexbin.context = function(_) { + return arguments.length ? (context = _, hexbin) : context; + } + + bins.add = function(point) { + var px, py; + if (isNaN(px = +x.call(null, point)) + || isNaN(py = +y.call(null, point))) return; + addOne(point, px, py); + return bins; + } + + bins.addAll = function(points) { + addAll(points); + return bins; + } + + bins.remove = remove; + + bins.removeAll = function(points) { + for (var i = 0, l = points.length; i < l; i++) remove(points[i]); + return bins; + } + return hexbin.radius(1); } diff --git a/test/hexbin-test.js b/test/hexbin-test.js index 4626e8a..7691165 100644 --- a/test/hexbin-test.js +++ b/test/hexbin-test.js @@ -185,6 +185,39 @@ tape("hexbin.mesh() observes the extent", function(test) { test.end(); }); +tape("hexbin.add() adds a point", function(test) { + var bins = d3.hexbin()([[0,0]]).addAll([[0.1,0.1], [10,10]]).add([2,2]), + expected = [[[0,0],[0.1,0.1]],[[10,10]],[[2,2]]]; + test.equal(JSON.stringify(bins), JSON.stringify(expected)); + test.end(); +}); + +tape("hexbin.remove() removes a point", function(test) { + var points = [[0,0], [1,1], [2,2]]; + var bins = d3.hexbin()(points).remove(points[1]), + expected = [ [[0,0]], [[2,2]] ]; + test.equal(JSON.stringify(bins), JSON.stringify(expected)); + test.end(); +}); + +tape("hexbin.removeAll() removes several points", function(test) { + var points = [[0,0], [1,1], [2,2]]; + var bins = d3.hexbin()(points).removeAll(points.slice(0,2)), + expected = [[[2,2]]]; + test.equal(JSON.stringify(bins), JSON.stringify(expected)); + test.end(); +}); + +tape("hexbin.angle(…) returns the expected centers", function(test) { + test.deepEqual(d3.hexbin().radius(0.5).extent([[-1.1, -1.1], [1.1, 1.1]]).angle(90).centers().map(function(c) { + return c.map(function(p) { return +p.toFixed(4); }) + }), [ [ -0.75, 0.433 ], [ -0.75, -0.433 ], [ -0.75, -1.299 ], [ 0, 0.866 ], [ 0, 0 ], [ 0, -0.866 ], [ 0.75, 0.433 ], [ 0.75, -0.433 ], [ 0.75, -1.299 ], [ 1.5, 0.866 ], [ 1.5, 0 ], [ 1.5, -0.866 ] ]); + test.deepEqual(d3.hexbin().radius(0.5).extent([[-1.1, -1.1], [1.1, 1.1]]).angle(45).centers().map(function(c) { + return c.map(function(p) { return +p.toFixed(4); }) + }), [ [ -1.673, -0.4483 ], [ -1.0607, -1.0607 ], [ -0.4483, -1.673 ], [ -1.4489, 0.3882 ], [ -0.8365, -0.2241 ], [ -0.2241, -0.8365 ], [ 0.3882, -1.4489 ], [ -1.2247, 1.2247 ], [ -0.6124, 0.6124 ], [ 0, 0 ], [ 0.6124, -0.6124 ], [ 1.2247, -1.2247 ], [ -0.3882, 1.4489 ], [ 0.2241, 0.8365 ], [ 0.8365, 0.2241 ], [ 1.4489, -0.3882 ], [ 0.4483, 1.673 ], [ 1.0607, 1.0607 ], [ 1.673, 0.4483 ] ]); + test.end(); +}); + function noxy(bins) { return bins.map(function(bin) { return bin.slice(); From 8b0c038d6993ca172158637b3c09a525b1ac2a78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Fri, 2 Aug 2019 23:25:20 +0200 Subject: [PATCH 02/18] Add hexbin.translate() --- README.md | 6 +++++- src/hexbin.js | 17 +++++++++++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index d736ee4..b5a3a03 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,11 @@ The *y*-coordinate accessor is used by [*hexbin*](#_hexbin) to compute the *y*-c # hexbin.angle([angle]) -If *angle* is specified, sets the angle of the hexagonal grid to the specified number, in degrees. If *angle* is not specified, returns the current angle, which defaults to pointy-topped hexagons. +If *angle* is specified, sets the angle of the hexagonal grid to the specified number, in degrees. If *angle* is not specified, returns the current angle, which defaults to 0 (pointy-topped hexagons). + +# hexbin.translate([translate]) + +If *translate* is specified, translates the hexagonal grid to the specified value [tx, ty]. If *translate* is not specified, returns the current translate, which defaults to [0, 0]. # hexbin.radius([radius]) diff --git a/src/hexbin.js b/src/hexbin.js index e5df2f8..806ec38 100644 --- a/src/hexbin.js +++ b/src/hexbin.js @@ -19,6 +19,8 @@ export default function() { r, dx, dy, + tx = 0, + ty = 0, angle = 0, ca = 1, sa = 0, @@ -28,6 +30,8 @@ export default function() { // from pixels to grid function transform(x, y) { + x -= tx; + y -= ty; if (ca === 1) return [x, y]; return [x * ca - y * sa, x * sa + y * ca]; } @@ -35,7 +39,7 @@ export default function() { // from grid to pixels function untransform(x, y) { if (ca === 1) return [x, y]; - return [x * ca + y * sa, - x * sa + y * ca]; + return [x * ca + y * sa + tx, - x * sa + y * ca + ty]; } function hexbin(points) { @@ -105,8 +109,9 @@ export default function() { } function hexagon(radius) { - return angles.map(function(angle) { - return untransform( Math.sin(angle) * radius, -Math.cos(angle) * radius ); + return angles.map(function(a) { + a -= angle / 180 * Math.PI; + return [ Math.sin(a) * radius, -Math.cos(a) * radius ]; }); } @@ -143,7 +148,7 @@ export default function() { for (var y = j * dy; y < ty1 + r; y += dy, ++j) { for (var x = i * dx + (j & 1) * dx / 2; x < tx1 + dx / 2; x += dx) { - var [ux, uy] = untransform(x, y); + var u = untransform(x, y), ux = u[0], uy = u[1]; if (ux >= x0 - dx && ux <= x1 + dx && uy >= y0 - dy && uy <= y1 + dy) centers.push([ux, uy]); } @@ -171,6 +176,10 @@ export default function() { return arguments.length ? (angle = _, ca = Math.cos(angle * Math.PI/180), sa = Math.sin(angle * Math.PI/180), hexbin) : x; }; + hexbin.translate = function(_) { + return arguments.length ? (tx = _[0], ty = _[1], hexbin) : [tx, ty]; + }; + hexbin.x = function(_) { return arguments.length ? (x = _, hexbin) : x; }; From ae63ed58943bdc1b809e63465b45e42769d3f3f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Fri, 2 Aug 2019 23:47:45 +0200 Subject: [PATCH 03/18] bug with angle=0 and translate --- src/hexbin.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hexbin.js b/src/hexbin.js index 806ec38..b60848c 100644 --- a/src/hexbin.js +++ b/src/hexbin.js @@ -38,7 +38,7 @@ export default function() { // from grid to pixels function untransform(x, y) { - if (ca === 1) return [x, y]; + if (ca === 1) return [x + tx, y + ty]; return [x * ca + y * sa + tx, - x * sa + y * ca + ty]; } From 64a6ad06f10badb78119e32e971cb56b263125f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Fri, 2 Aug 2019 23:48:11 +0200 Subject: [PATCH 04/18] rebin after changing angle or translate --- src/hexbin.js | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/hexbin.js b/src/hexbin.js index b60848c..6c0186c 100644 --- a/src/hexbin.js +++ b/src/hexbin.js @@ -108,6 +108,20 @@ export default function() { return bins; } + function data() { + var data = []; + bins.forEach(function(bin) { + bin.forEach(function(d) { + data.push(d); + }); + }); + return data; + } + + function rebin() { + hexbin(data()); + } + function hexagon(radius) { return angles.map(function(a) { a -= angle / 180 * Math.PI; @@ -173,11 +187,11 @@ export default function() { }; hexbin.angle = function(_) { - return arguments.length ? (angle = _, ca = Math.cos(angle * Math.PI/180), sa = Math.sin(angle * Math.PI/180), hexbin) : x; + return arguments.length ? (angle = _, ca = Math.cos(angle * Math.PI/180), sa = Math.sin(angle * Math.PI/180), rebin(), hexbin) : angle; }; hexbin.translate = function(_) { - return arguments.length ? (tx = _[0], ty = _[1], hexbin) : [tx, ty]; + return arguments.length ? (tx = _[0], ty = _[1], rebin(), hexbin) : [tx, ty]; }; hexbin.x = function(_) { From 70ecdcc4f0544d47d7dac97e279d3ecd6fbd16d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Fri, 2 Aug 2019 23:49:33 +0200 Subject: [PATCH 05/18] expose hexbin.data() which returns the whole dataset (in a possibly different order) note: I made it be a setter, which sort of duplicates hexbin(data) --- src/hexbin.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hexbin.js b/src/hexbin.js index 6c0186c..8985a39 100644 --- a/src/hexbin.js +++ b/src/hexbin.js @@ -218,6 +218,10 @@ export default function() { return arguments.length ? (context = _, hexbin) : context; } + hexbin.data = function(_) { + return arguments.length ? (hexbin(_), hexbin) : data(); + } + bins.add = function(point) { var px, py; if (isNaN(px = +x.call(null, point)) From fee02572a26b99ce6e326e3163d74f7362fa4cc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Sat, 3 Aug 2019 00:12:17 +0200 Subject: [PATCH 06/18] document hexbin.data() --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index b5a3a03..7b20783 100644 --- a/README.md +++ b/README.md @@ -147,3 +147,9 @@ If *context* is specified, sets the current render context and returns the hexbi * *context*.lineTo(*x*, *y*) If a *context* is not specified, returns the current render context which defaults to null. + + +# hexbin.data([points]) [<>](https://github.com/d3/d3-hexbin/blob/master/src/hexbin.js "Source") + +If *points* is specified, resets the hexbin with the new data points. If the *points* is null, returns the current data points, in a possibly different order. + From 7df064427125fe822e0258be1547fc81af022cfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Sat, 3 Aug 2019 00:15:11 +0200 Subject: [PATCH 07/18] hexbin.bin(point) returns the bin that correspond to a point, without adding it see https://github.com/d3/d3-hexbin/issues/18 --- README.md | 3 +++ src/hexbin.js | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/README.md b/README.md index 7b20783..49e2f73 100644 --- a/README.md +++ b/README.md @@ -153,3 +153,6 @@ If a *context* is not specified, returns the current render context which defaul If *points* is specified, resets the hexbin with the new data points. If the *points* is null, returns the current data points, in a possibly different order. +# hexbin.bin(point) [<>](https://github.com/d3/d3-hexbin/blob/master/src/hexbin.js "Source") + +Returns the bin that would contain the point if we added it. If there is no such bin, returns an empty array with properties *x* and *y*. That bin is not guaranteed to keep in sync with data additions and removals, or changes of parameters such as radius, angle and translate. \ No newline at end of file diff --git a/src/hexbin.js b/src/hexbin.js index 8985a39..ee2aa5e 100644 --- a/src/hexbin.js +++ b/src/hexbin.js @@ -222,6 +222,20 @@ export default function() { return arguments.length ? (hexbin(_), hexbin) : data(); } + hexbin.bin = function(point) { + var px, py; + if (isNaN(px = +x.call(null, point)) + || isNaN(py = +y.call(null, point))) return; + var b = getBin(px, py), pi = b[0], pj = b[1], id = b[0] + "-" + b[1], bin = binsById[id]; + if (!bin) { + bin = []; + var u = untransform((pi + (pj & 1) / 2) * dx, pj * dy); + bin.x = u[0]; + bin.y = u[1]; + } + return bin; + } + bins.add = function(point) { var px, py; if (isNaN(px = +x.call(null, point)) From 91c885d0b34d485de79b3efe3428ebd3efe2faa3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Sat, 3 Aug 2019 00:19:57 +0200 Subject: [PATCH 08/18] all parameters should rebin the data --- src/hexbin.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hexbin.js b/src/hexbin.js index ee2aa5e..4413033 100644 --- a/src/hexbin.js +++ b/src/hexbin.js @@ -195,15 +195,15 @@ export default function() { }; hexbin.x = function(_) { - return arguments.length ? (x = _, hexbin) : x; + return arguments.length ? (x = _, rebin(), hexbin) : x; }; hexbin.y = function(_) { - return arguments.length ? (y = _, hexbin) : y; + return arguments.length ? (y = _, rebin(), hexbin) : y; }; hexbin.radius = function(_) { - return arguments.length ? (r = +_, dx = r * 2 * Math.sin(thirdPi), dy = r * 1.5, hexbin) : r; + return arguments.length ? (r = +_, dx = r * 2 * Math.sin(thirdPi), dy = r * 1.5, rebin(), hexbin) : r; }; hexbin.size = function(_) { From 19248c01ce3e6cba4f202669448af8183a50cc8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Sat, 3 Aug 2019 05:29:58 +0200 Subject: [PATCH 09/18] Simplify things a bit: - remove .data(), instead use bins.flat() to get the data, and hexbin() to update without adding points. - don't rebin aggressively when changing parameters, only on update ie when calling hexbin() - all the new methods are on hexbin not on bins --- README.md | 21 ++++------- src/hexbin.js | 89 +++++++++++++++++++++++---------------------- test/hexbin-test.js | 32 +++++++++++++--- 3 files changed, 81 insertions(+), 61 deletions(-) diff --git a/README.md b/README.md index 49e2f73..3aca4dc 100644 --- a/README.md +++ b/README.md @@ -61,22 +61,21 @@ svg.selectAll("path") This method ignores the hexbin’s [extent](#hexbin_extent); it may return bins outside the extent if necessary to contain the specified points. -# bins.add(point) +# hexbin.add(point) -Adds a point and returns the bins. +Adds the *point* and returns the hexbin generator. -# bins.addAll(points) +# hexbin.addAll(points) -Adds points and returns the bins. +Adds the *points* and returns the hexbin generator. -# bins.remove(point) +# hexbin.remove(point) -Removes the point (if it is referenced in its bin), and returns the bins. Empty bins are pruned. +Removes the *point*, and returns the hexbin generator. Empty bins are pruned. -# bins.removeAll(points) - -Removes all the points from the bins, and returns the bins. Empty bins are pruned. +# hexbin.removeAll(points) +Removes all the *points* and returns the hexbin generator. Empty bins are pruned. # hexbin.hexagon([radius]) @@ -149,10 +148,6 @@ If *context* is specified, sets the current render context and returns the hexbi If a *context* is not specified, returns the current render context which defaults to null. -# hexbin.data([points]) [<>](https://github.com/d3/d3-hexbin/blob/master/src/hexbin.js "Source") - -If *points* is specified, resets the hexbin with the new data points. If the *points* is null, returns the current data points, in a possibly different order. - # hexbin.bin(point) [<>](https://github.com/d3/d3-hexbin/blob/master/src/hexbin.js "Source") Returns the bin that would contain the point if we added it. If there is no such bin, returns an empty array with properties *x* and *y*. That bin is not guaranteed to keep in sync with data additions and removals, or changes of parameters such as radius, angle and translate. \ No newline at end of file diff --git a/src/hexbin.js b/src/hexbin.js index 4413033..9c03398 100644 --- a/src/hexbin.js +++ b/src/hexbin.js @@ -26,7 +26,9 @@ export default function() { sa = 0, context = null, binsById = {}, - bins = []; + bins = [], + unbinned = [], + dirty = false; // from pixels to grid function transform(x, y) { @@ -43,9 +45,23 @@ export default function() { } function hexbin(points) { - binsById = {}; - bins.splice(0, bins.length); - addAll(points); + if (points) { + binsById = {}; + bins.splice(0, bins.length); + unbinned.splice(0, unbinned.length); + addAll(points); + } else if (dirty) { + bins.forEach(function(bin) { + bin.forEach(function(d) { + unbinned.push(d); + }); + }); + binsById = {}; + bins.splice(0, bins.length); + } + addAll(unbinned); + unbinned.splice(0, unbinned.length); + dirty = false; return bins; } @@ -93,33 +109,20 @@ export default function() { var px, py; if (isNaN(px = +x.call(null, point)) || isNaN(py = +y.call(null, point))) return; - var b = getBin(px, py), id = b[0] + "-" + b[1], bin = binsById[id]; + var b = getBin(px, py), id = b[0] + "-" + b[1], bin = binsById[id] || unbinned; if (bin) { var i = bin.indexOf(point); if (i > -1) { bin.splice(i, 1); if (bin.length == 0) { i = bins.indexOf(bin); - bins.splice(i, 1); - delete binsById[id]; + if (i > -1) { + bins.splice(i, 1); + delete binsById[id]; + } } } } - return bins; - } - - function data() { - var data = []; - bins.forEach(function(bin) { - bin.forEach(function(d) { - data.push(d); - }); - }); - return data; - } - - function rebin() { - hexbin(data()); } function hexagon(radius) { @@ -187,23 +190,23 @@ export default function() { }; hexbin.angle = function(_) { - return arguments.length ? (angle = _, ca = Math.cos(angle * Math.PI/180), sa = Math.sin(angle * Math.PI/180), rebin(), hexbin) : angle; + return arguments.length ? (angle = _, ca = Math.cos(angle * Math.PI/180), sa = Math.sin(angle * Math.PI/180), dirty = true, hexbin) : angle; }; hexbin.translate = function(_) { - return arguments.length ? (tx = _[0], ty = _[1], rebin(), hexbin) : [tx, ty]; + return arguments.length ? (tx = _[0], ty = _[1], dirty = true, hexbin) : [tx, ty]; }; hexbin.x = function(_) { - return arguments.length ? (x = _, rebin(), hexbin) : x; + return arguments.length ? (x = _, dirty = true, hexbin) : x; }; hexbin.y = function(_) { - return arguments.length ? (y = _, rebin(), hexbin) : y; + return arguments.length ? (y = _, dirty = true, hexbin) : y; }; hexbin.radius = function(_) { - return arguments.length ? (r = +_, dx = r * 2 * Math.sin(thirdPi), dy = r * 1.5, rebin(), hexbin) : r; + return arguments.length ? (r = +_, dx = r * 2 * Math.sin(thirdPi), dy = r * 1.5, dirty = true, hexbin) : r; }; hexbin.size = function(_) { @@ -218,10 +221,6 @@ export default function() { return arguments.length ? (context = _, hexbin) : context; } - hexbin.data = function(_) { - return arguments.length ? (hexbin(_), hexbin) : data(); - } - hexbin.bin = function(point) { var px, py; if (isNaN(px = +x.call(null, point)) @@ -236,24 +235,28 @@ export default function() { return bin; } - bins.add = function(point) { - var px, py; - if (isNaN(px = +x.call(null, point)) - || isNaN(py = +y.call(null, point))) return; - addOne(point, px, py); - return bins; + hexbin.add = function(point) { + unbinned.push(point); + dirty = true; + return hexbin; } - bins.addAll = function(points) { - addAll(points); - return bins; + hexbin.addAll = function(points) { + points.forEach(function(point) { + unbinned.push(point); + }); + dirty = true; + return hexbin; } - bins.remove = remove; + hexbin.remove = function(point) { + remove(point); + return hexbin; + } - bins.removeAll = function(points) { + hexbin.removeAll = function(points) { for (var i = 0, l = points.length; i < l; i++) remove(points[i]); - return bins; + return hexbin; } return hexbin.radius(1); diff --git a/test/hexbin-test.js b/test/hexbin-test.js index 7691165..b91fe8d 100644 --- a/test/hexbin-test.js +++ b/test/hexbin-test.js @@ -186,7 +186,7 @@ tape("hexbin.mesh() observes the extent", function(test) { }); tape("hexbin.add() adds a point", function(test) { - var bins = d3.hexbin()([[0,0]]).addAll([[0.1,0.1], [10,10]]).add([2,2]), + var bins = d3.hexbin().add([0,0]).addAll([[0.1,0.1], [10,10]]).add([2,2])(), expected = [[[0,0],[0.1,0.1]],[[10,10]],[[2,2]]]; test.equal(JSON.stringify(bins), JSON.stringify(expected)); test.end(); @@ -194,17 +194,39 @@ tape("hexbin.add() adds a point", function(test) { tape("hexbin.remove() removes a point", function(test) { var points = [[0,0], [1,1], [2,2]]; - var bins = d3.hexbin()(points).remove(points[1]), + var hexbin = d3.hexbin(), expected = [ [[0,0]], [[2,2]] ]; - test.equal(JSON.stringify(bins), JSON.stringify(expected)); + hexbin(points); + hexbin.remove(points[1]); + test.equal(JSON.stringify(hexbin()), JSON.stringify(expected)); + test.end(); +}); + +tape("hexbin.remove() doesn't remove a point that isn't there", function(test) { + var points = [[0,0], [1,1], [2,2]]; + var hexbin = d3.hexbin(), + expected = [ [[0,0]], [[1,1]] ]; + hexbin(points.slice(0,2)); + hexbin.remove(points[2]); + test.equal(JSON.stringify(hexbin()), JSON.stringify(expected)); test.end(); }); tape("hexbin.removeAll() removes several points", function(test) { var points = [[0,0], [1,1], [2,2]]; - var bins = d3.hexbin()(points).removeAll(points.slice(0,2)), + var hexbin = d3.hexbin(), expected = [[[2,2]]]; - test.equal(JSON.stringify(bins), JSON.stringify(expected)); + hexbin(points); + hexbin.removeAll(points.slice(0,2)); + test.equal(JSON.stringify(hexbin()), JSON.stringify(expected)); + test.end(); +}); + +tape("hexbin.removeAll() removes unbinned points", function(test) { + var points = [[0,0], [1,1], [2,2]]; + var hexbin = d3.hexbin().addAll(points).removeAll(points.slice(0,2)), + expected = [[[2,2]]]; + test.equal(JSON.stringify(hexbin()), JSON.stringify(expected)); test.end(); }); From 30f4a0c1396179fd36b7e2f128128589532aa936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Sun, 4 Aug 2019 15:48:48 +0200 Subject: [PATCH 10/18] points can be removed both from unbinned even if the corresponding bin exists. --- src/hexbin.js | 25 +++++++++++++++---------- test/hexbin-test.js | 4 ++++ 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/src/hexbin.js b/src/hexbin.js index 9c03398..b96dcad 100644 --- a/src/hexbin.js +++ b/src/hexbin.js @@ -105,21 +105,26 @@ export default function() { } } + function removeFromBin(point, bin) { + var i = bin.indexOf(point); + if (i > -1) { + bin.splice(i, 1); + } + } + function remove(point) { var px, py; if (isNaN(px = +x.call(null, point)) || isNaN(py = +y.call(null, point))) return; - var b = getBin(px, py), id = b[0] + "-" + b[1], bin = binsById[id] || unbinned; + var b = getBin(px, py), id = b[0] + "-" + b[1], bin = binsById[id]; + removeFromBin(point, unbinned); if (bin) { - var i = bin.indexOf(point); - if (i > -1) { - bin.splice(i, 1); - if (bin.length == 0) { - i = bins.indexOf(bin); - if (i > -1) { - bins.splice(i, 1); - delete binsById[id]; - } + removeFromBin(point, bin); + if (bin.length == 0) { + var i = bins.indexOf(bin); + if (i > -1) { + bins.splice(i, 1); + delete binsById[id]; } } } diff --git a/test/hexbin-test.js b/test/hexbin-test.js index b91fe8d..0e6af92 100644 --- a/test/hexbin-test.js +++ b/test/hexbin-test.js @@ -227,6 +227,10 @@ tape("hexbin.removeAll() removes unbinned points", function(test) { var hexbin = d3.hexbin().addAll(points).removeAll(points.slice(0,2)), expected = [[[2,2]]]; test.equal(JSON.stringify(hexbin()), JSON.stringify(expected)); + hexbin = d3.hexbin(); + hexbin(points) + hexbin.removeAll(points.slice(0,2)); + test.equal(JSON.stringify(hexbin()), JSON.stringify(expected)); test.end(); }); From 9cb8403a1d4d8df91dfdc39b6d2561581bff7297 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Sat, 3 Aug 2019 15:34:45 +0200 Subject: [PATCH 11/18] In some cases the mesh was incomplete (ex: angle=-19, translate.x = -4). Including a bit more centers solves the issue. The solution breaks a test on centers() in the angle=0 case, which we could keep backwards compatible by testing for angle===0; but I don't think it's a problem if we have a few more centers (better safe than sorry). --- src/hexbin.js | 4 ++-- test/hexbin-test.js | 21 ++++----------------- 2 files changed, 6 insertions(+), 19 deletions(-) diff --git a/src/hexbin.js b/src/hexbin.js index b96dcad..45ae6f2 100644 --- a/src/hexbin.js +++ b/src/hexbin.js @@ -165,8 +165,8 @@ export default function() { tx1 = Math.max(tx00, tx01, tx10, tx11), ty1 = Math.max(ty00, ty01, ty10, ty11), centers = [], - j = Math.round(ty0 / dy), - i = Math.round(tx0 / dx); + j = Math.floor(ty0 / dy), + i = Math.floor(tx0 / dx); for (var y = j * dy; y < ty1 + r; y += dy, ++j) { for (var x = i * dx + (j & 1) * dx / 2; x < tx1 + dx / 2; x += dx) { diff --git a/test/hexbin-test.js b/test/hexbin-test.js index 0e6af92..67c0581 100644 --- a/test/hexbin-test.js +++ b/test/hexbin-test.js @@ -153,20 +153,7 @@ tape("hexbin.centers() observes the current bin radius", function(test) { }); tape("hexbin.centers() observes the current extent", function(test) { - test.deepEqual(d3.hexbin().radius(0.5).extent([[-1.1, -1.1], [1.1, 1.1]]).centers(), [ - [-0.4330127018922193, -0.75], - [0.4330127018922193, -0.75], - [1.299038105676658, -0.75], - [-0.8660254037844386, 0], - [0, 0], - [0.8660254037844386, 0], - [-0.4330127018922193, 0.75], - [0.4330127018922193, 0.75], - [1.299038105676658, 0.75], - [-0.8660254037844386, 1.5], - [0, 1.5], - [0.8660254037844386, 1.5] - ]); + test.deepEqual(d3.hexbin().radius(0.5).extent([[-1.1, -1.1], [1.1, 1.1]]).centers(), [ [ -1.7320508075688772, -1.5 ], [ -0.8660254037844386, -1.5 ], [ 0, -1.5 ], [ 0.8660254037844386, -1.5 ], [ -1.299038105676658, -0.75 ], [ -0.4330127018922194, -0.75 ], [ 0.4330127018922192, -0.75 ], [ 1.2990381056766578, -0.75 ], [ -1.7320508075688772, 0 ], [ -0.8660254037844386, 0 ], [ 0, 0 ], [ 0.8660254037844386, 0 ], [ -1.299038105676658, 0.75 ], [ -0.4330127018922194, 0.75 ], [ 0.4330127018922192, 0.75 ], [ 1.2990381056766578, 0.75 ], [ -1.7320508075688772, 1.5 ], [ -0.8660254037844386, 1.5 ], [ 0, 1.5 ], [ 0.8660254037844386, 1.5 ] ]); test.end(); }); @@ -181,7 +168,7 @@ tape("hexbin.mesh() observes the bin radius", function(test) { }); tape("hexbin.mesh() observes the extent", function(test) { - test.pathEqual(d3.hexbin().radius(0.5).extent([[-1.1, -1.1], [1.1, 1.1]]).mesh(), "M-0.433013,-0.750000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M0.433013,-0.750000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M1.299038,-0.750000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M-0.866025,0m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M0,0m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M0.866025,0m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M-0.433013,0.750000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M0.433013,0.750000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M1.299038,0.750000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M-0.866025,1.500000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M0,1.500000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M0.866025,1.500000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000"); + test.pathEqual(d3.hexbin().radius(0.5).extent([[-1.1, -1.1], [1.1, 1.1]]).mesh(), "M-1.732051,-1.500000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M-0.866025,-1.500000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M0,-1.500000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M0.866025,-1.500000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M-1.299038,-0.750000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M-0.433013,-0.750000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M0.433013,-0.750000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M1.299038,-0.750000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M-1.732051,0m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M-0.866025,0m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M0,0m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M0.866025,0m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M-1.299038,0.750000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M-0.433013,0.750000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M0.433013,0.750000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M1.299038,0.750000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M-1.732051,1.500000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M-0.866025,1.500000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M0,1.500000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000M0.866025,1.500000m0,-0.500000l0.433013,0.250000l0,0.500000l-0.433013,0.250000"); test.end(); }); @@ -237,10 +224,10 @@ tape("hexbin.removeAll() removes unbinned points", function(test) { tape("hexbin.angle(…) returns the expected centers", function(test) { test.deepEqual(d3.hexbin().radius(0.5).extent([[-1.1, -1.1], [1.1, 1.1]]).angle(90).centers().map(function(c) { return c.map(function(p) { return +p.toFixed(4); }) - }), [ [ -0.75, 0.433 ], [ -0.75, -0.433 ], [ -0.75, -1.299 ], [ 0, 0.866 ], [ 0, 0 ], [ 0, -0.866 ], [ 0.75, 0.433 ], [ 0.75, -0.433 ], [ 0.75, -1.299 ], [ 1.5, 0.866 ], [ 1.5, 0 ], [ 1.5, -0.866 ] ]); + }), [ [ -1.5, 1.7321 ], [ -1.5, 0.866 ], [ -1.5, -0 ], [ -1.5, -0.866 ], [ -0.75, 1.299 ], [ -0.75, 0.433 ], [ -0.75, -0.433 ], [ -0.75, -1.299 ], [ -0, 1.7321 ], [ -0, 0.866 ], [ 0, 0 ], [ 0, -0.866 ], [ 0.75, 1.299 ], [ 0.75, 0.433 ], [ 0.75, -0.433 ], [ 0.75, -1.299 ], [ 1.5, 1.7321 ], [ 1.5, 0.866 ], [ 1.5, 0 ], [ 1.5, -0.866 ] ]); test.deepEqual(d3.hexbin().radius(0.5).extent([[-1.1, -1.1], [1.1, 1.1]]).angle(45).centers().map(function(c) { return c.map(function(p) { return +p.toFixed(4); }) - }), [ [ -1.673, -0.4483 ], [ -1.0607, -1.0607 ], [ -0.4483, -1.673 ], [ -1.4489, 0.3882 ], [ -0.8365, -0.2241 ], [ -0.2241, -0.8365 ], [ 0.3882, -1.4489 ], [ -1.2247, 1.2247 ], [ -0.6124, 0.6124 ], [ 0, 0 ], [ 0.6124, -0.6124 ], [ 1.2247, -1.2247 ], [ -0.3882, 1.4489 ], [ 0.2241, 0.8365 ], [ 0.8365, 0.2241 ], [ 1.4489, -0.3882 ], [ 0.4483, 1.673 ], [ 1.0607, 1.0607 ], [ 1.673, 0.4483 ] ]); + }), [ [ -1.8972, -1.2848 ], [ -1.673, -0.4483 ], [ -1.0607, -1.0607 ], [ -0.4483, -1.673 ], [ -1.4489, 0.3882 ], [ -0.8365, -0.2241 ], [ -0.2241, -0.8365 ], [ 0.3882, -1.4489 ], [ -1.2247, 1.2247 ], [ -0.6124, 0.6124 ], [ 0, 0 ], [ 0.6124, -0.6124 ], [ 1.2247, -1.2247 ], [ -0.3882, 1.4489 ], [ 0.2241, 0.8365 ], [ 0.8365, 0.2241 ], [ 1.4489, -0.3882 ], [ 0.4483, 1.673 ], [ 1.0607, 1.0607 ], [ 1.673, 0.4483 ] ]); test.end(); }); From c1a3a72143ff230c0c7b8c57323247be9ccb9289 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Fri, 2 Aug 2019 22:08:59 +0200 Subject: [PATCH 12/18] tooling test canvas An optional [translate] argument in binhex.hexagon() allows easier manipulation under canvas, for example to draw all the hexagons in one context.fill() without having to do lots of context.save/translate/restore. --- .gitignore | 2 +- README.md | 6 +- img/hexagons.png | Bin 0 -> 42076 bytes package.json | 28 +- rollup.config.js | 36 ++ src/hexbin.js | 14 +- src/index.js | 1 + test/compare-images | 16 + test/render-canvas | 39 ++ yarn.lock | 1117 +++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 1240 insertions(+), 19 deletions(-) create mode 100644 img/hexagons.png create mode 100644 rollup.config.js create mode 100644 src/index.js create mode 100755 test/compare-images create mode 100755 test/render-canvas create mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore index 75704c6..8abcf6a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ *.sublime-workspace .DS_Store -build/ +dist/ node_modules npm-debug.log diff --git a/README.md b/README.md index 3aca4dc..dd41fac 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ You could display a hexagon for each non-empty bin as follows: svg.selectAll("path") .data(hexbin(points)) .enter().append("path") - .attr("d", function(d) { return "M" + d.x + "," + d.y + hexbin.hexagon(); }); + .attr("d", function(d) { return hexbin.hexagon([d.x, d.y]); }); ``` Alternatively, using a transform: @@ -77,9 +77,9 @@ Removes the *point*, and returns the hexbin generator. Empty bins are pruned. Removes all the *points* and returns the hexbin generator. Empty bins are pruned. -# hexbin.hexagon([radius]) +# hexbin.hexagon([radius][, translate]) -Returns the SVG path string for the hexagon centered at the origin ⟨0,0⟩. The path string is defined with relative coordinates such that you can easily translate the hexagon to the desired position. If *radius* is not specified, the hexbin’s [current radius](#hexbin_radius) is used. If *radius* is specified, a hexagon with the specified radius is returned; this is useful for area-encoded bivariate hexbins. +Returns the SVG path string for the hexagon centered at the origin ⟨0,0⟩. If *translate* is specified, the path is translated. Otherwise, the path string is defined with relative coordinates. If *radius* is not specified, the hexbin’s [current radius](#hexbin_radius) is used. If *radius* is specified, a hexagon with the specified radius is returned; this is useful for area-encoded bivariate hexbins. # hexbin.centers() diff --git a/img/hexagons.png b/img/hexagons.png new file mode 100644 index 0000000000000000000000000000000000000000..f9ee416d59cf80d615a88f71af7138de5d95718f GIT binary patch literal 42076 zcmd43XH=6-AFq3d2&goXE=@vFItT~?iXy!#9i&O`L^@K8O0R|{9qGMFuMtp?BE7eu zAksoniXd7xr?GRrh=w#x;hX-0<^@}Buo6U_@DX&K6Tuh+-@HvBM$Go zRZV==Trt6Rs@g!h%7RU~JxM!0DL!8Ri4IP`Vb)7(HiW`DG)2^99T)S}AHCYq-`6A7 z7E({Q^5<;D;#QJMUUr;@(#h;V*V(28b~@~A`NoSor_M8SjXQ0#XA4^Gd#ucnXERj? zzrMcs{b3>OY^ECR|A&9!Ok(E+Jz{tMj2-d%(4=)eI_BPox-)%^r6*^%PM!N(lcN~? z1Xk0Vn4->_F4bAMFGb0FTNukbou~{Kw`{s9q93Y%Jex!5J{d*Z-^*|tSmy6MGYa-` z5qH_)-gz-`J!S&^`ln)fZQZ*#4P`ptk7olCy*p=Jm;W5cw665i@4V zc)dAdxm6VNmB|_P-hSH>hIzL8E(E4m_`&XW?B}wFY>cM4N5x4h98Kh$1Qi-5RM!Nd zUeJGIz!x783zcY<$9=Z=F1k223>*I}WD@8@j1iYL%>pkfw>B(E#VV5k?S^tU;5D#1 z?|8&Uf<40fD%$h_(kU{+jHKgF$|PS&BEcxtxPa$acqO$(a>e#Lc)QH2Jf${eeEHe& z7AoG3$LdxR`ynf2n!6_a6;@#^@^tzq!K8{QrD<-XEJG#4U8BvD8A66pa^y|24Z|zZ zvM!83P@6J=o-xiuTRRsp2aV29@o(^Yx!b}t`oIwGwje|-tVD~oEy}o`&@}hj9f{4S zsQ98-g=-kQiu6FIYy7uQ37>Yq z(Bt#JLy}-B{KS8+Nv8bo44$-6x*x7A9Lahv#U9U}R!Qtm_~8CndoJ;N&c#2IzgPK_e%71uWOY`QuaWi4 zr>kyh7A@ubvyKWp9KLAv`%FjoXTHt<09+{H+&Iy%erE3MyA>uhd|dis&(9v$U4GVk zP%6PXXX4XAro9o=etIRV)_-qLs%kZFMc4SiT-!S5q}Sw>!s*qMwnIy)F{HfzX=;YO zIBS2#NmYjP9oEQfnVcj@RPD}-`j>2_Kfw8oY}H#=E_FVKrYe7*;*Qh#2zY(2}-#z`EU z?QCuSK8UI|INXQ7IFe{;9YE_$c^YkpMyDOzlQ-~NeZv1Id_jDRkkNLpN7Qf6cWGVR_ndc9i02xXFvD8!z@|nLTsHq*}i1ww=T`oGmF7uWZ$?EuP&v$gq#n z-`cl7#nG(zPos6tyn5X;j(*?KHMqN16U=ndaDMb##My5nf92Ffeu;VhNF?L*^LgvD zj>WDQW?$lUG8%9R1Ah)vxl8Z)^>4m7%U)?5UPE(7ryee*l~o@#^)BpmlBFM{M0G!W z>vv+k;5qM{QXO{f4Npe%Qd-8zsSy~oUVfT4;5UFxMlN{1z!?!rEhg@tnr^in&(;|qzAYS3A4;+eY_KXpG363oOFH*cJ_J&Z{8bX+$!fB`!g6tR#|Q5 z=e0s;uOwoT^LsIkxulCc0eNJ}#Voni!INcT_3ibFpO>cW!fI#=1;l~_j&x2UbL9pBbx_lX2#z-}CLbMD4v( zRwv0Y;GbbhenOBx@4@<_`>-peT#9@k{0xIo@1i?7tf{-(i^%^f>b0>}_j3~)yF)Me ze2j6Rvioz2lQ`XgzsVcT<&}7ijK;5Ot&e@dAgTPgqtRv0-QXnovc_-TxuZMbQU0N_ z_uQA$OdcsQwr$^BAYBs`^Zzi!6WzT0g(hC3i;OAl2E^QkX}+jl{Ee_be7joQADk!` z|9JWOfak|!spmVd*<7&cvO;SXLE%xGt-Aa>Ce6nhsXDLCo3_T}{rHC)oRJQ1r!?=m zuGeI+pnu|w1eI?n7SDHiF66VSFQ^O`9q$+&l(uJujT9XZH5{z7r{`)PWV>#ax4VRo z*sW(vs08H3r*nOK+;;NQrAX^m=`XE93xiC$x4Bfw&-DKuXfw*%7-(-q^bTL{|9HD} zTT4+058;RyTS5-(&eQ@!e+otjBAby0gFWCuFim^ZDdW-&7BeWTx397-hufQ7OKN z(P2ALG+>lMy1kUq88WF*$cw#vMC4M&c~L!{r}QSRSgFm?w`yt4+^A8b7ccGnZMuRD zT#9luuPC1pglidr#~0134>j4-Y`Rx+Qd&7ev8v2-sb5Qt%x!WW?pyfX(dKGgEq>F# zdUg8OkYjQBt1mCpvdt|i=pWI>ef5j#=1L>=HsEbQq_~MMb+F%lCtzp>pFXN!Dw9nl z{f!JQwf*@};%mrcayzo6FC);je#5Ohcs=|N=cVB=wRo@k^hI^aH#%-bowj?Uix1W7 znegJo_iE{-)}LQQI^2JHb5$#pFhVWKevj7( z4d{6|nYko^-?W;o$xgg{XD&MR_+{9k_sNOGnY`zETmKxtKZC(>W?I|Sx~~`R_17Ek z#+b#n>W()}l8+U4Qp|t18ZmFx`9H;3cSb+V-I_Z&BS~gXK7Moftl)6|?wS4IVN!$1 z6)70+T+@M`)>&bL$yF)X@d2w$LnX$R-8jJP{#MbZ;aiZRO*4$NB(f|t1{fC z&3&+WR3Fm3?e6?rLi=cbu8rIO$M5zuU4JF2g{GAQ*`Azz%Pft~IQ=Oxs9!-zx=DDCsNT@tpW!=nCI7vVS$;RS^%pPANqk6Z z{pt4?TIIgqK6c42?bti}=&1Q@cV6cZeRq<9YyPUa)7k1^&&cH8Ys6o)f~!|zT0H5` zUD%F!zF(Wj@50!2NN<9s$O2!m$7C0F*?(eG%B9+{GgU4wno5OI63Bs9M;npO672pO z$FV=#So75kU;G?F?8+avahKn7-7Nk3gG0Rb;I6X6R>8!`!ott3@b52^^`80-mcXp<{5xZbvgtm5W3A%S7v$_%YXA5=7q1a~q zu3F1x(8)r)=bYjPNg2Ni;8Fyxt=V|OuSa*Mn z1rHp`}u|0g{fWgPr?(A)&+02Bhk0>L3uqoAI5zc+79;{j?;n#Ubqj< z3~7bh%bfms#p)`xESc_&#h@E9+!+UCUbvj5MHSvsEB1U>Sd|p~Jo?Avyr)=Rk63A| z)0b13sfq()@Y5MZoqxuh9hNl>YK5-dJv#f@-1Oz-X4rjO!!1#d`P_UZ%_qr`gjvT! zu3IiD@k)ib7g7g&U0Q{4(?{j5o_F$;a_8v*^{F`K zDSz<2vGCL9kf}M=kIcW@@oTr|=`)QbqYQ;G-=AlKnkjsY0eCachbcMT5~t3?o=Ay% zKr6 zCyi7Zt(~Y;o$AZ)`z>1yTOWsUG!gc=n3SK%mv^$R+|1?9*o=4P%xx_1djFh}*Q>uA z<0=~E;BTp6;ZC~$@<>(Zm#6M*8l}FZ)aqEP+v8!~?crRnJxo&pzhNk=mz~#lamh`~ zM;Ul{^}4mp5qNzFW9UFBiMU8m4)RpCq6mOFWx<9&zlLyp-^MQ!3xr=s)rHls;=%h6 z*RYM7KW=@_hIz;|LpVyLL=db#DEWe0q#$0s5hn5)fob(oB6=IIKE5mR8ZB1m-h0y- zL1D~bs->GGRf5!%m-sF(=yO4ihd}@sVHNr*U71=tCf=cAO^R$V#FK=#yOTxx;`)$ZiX2FcvwyGkaJoHuk`uO~mE6k|9 zEc~`(J(M>afmlzBdPNuv_aVP`?gb{}{81c6>M^hBxFZ!G2sN9ReuzFs^Dx^$K3P)E}jJpAXhO*+^lv!i^lJO(`6L5dNQu3%;k8N{^A0+mW0h1R5T zSH@kg8O)>>AC)fN)FJYtc4sA#7QNagEjp|}6?vg|N`ElYEnyEn<1{NYLN?2%_t9gX z%)xU_^9P|^*kNfqNg>(E zO!(Fb<pELxVGIw@tT$a8tYxEige!F{Ehe-?Dm`dbOZ*-RS1Me{8Fw+H zD88dY!JS}0k*pUfC|tRwKoQw@O58$ zoHHh%-NQ&xtdX#+Rrp7nlYYJ^E(LtY{#L9pzNA%XSQO{?izby%yC*7@OS_7TU6nhN z$nQZG->(PEMn9CVx@Ueql6A}ER~`<`Tc;TcY>ir%errTQG8A}ElFG=2@s8pc6FF_P zNo)y`>NtN9(MhvC+2UxR6X(Q{h#^hmW}?loTc$)*s8vGaU{i~G=E3tH(ix(ad~WGK zq@82#21N7yiehOTJPiG{?0L<`*FAGHT=)~xs-P*2&cIwusCp!oZjvI$|MjypI)Ym< zU;8TfKP0h8@mdG9uu2Fm1&ax7NPVAPJH8_%$&QuU~qGI4{5~+0% zg-el)Yvs48T}m+_WH#Sj8i_PIC;F+R#UYk2#PV{URv`=b#e{CIMp}>sp0uDhhWHQU zs?fGxtWyu4zHrW=Rw1&^5RJKev<>`xGSd-)=06hTdG@MF7dQHV(SAgpyd`{Yw~DX#gq1ry8gI;YSZ-% zmm3>AnIq2Xp6#T3lgXJ9EO!Hvz=%NQhA+1~+dm=1efHgMu;m)2;{s~%m+nT*UCLg= z6ZiRq3lNT3QY&~PRZ$jJWxKpcR?@reVDM6^A{3*zD07Nw@QnI5 ze0@aq3Blqb8IMw)^%5CRS?HgavVwd1OJuY9S$o#^&ab$hI1u%2VX1aK@)g%h4mn$MnQ4-3%Esvqv_)ZRT0Zdx1hB_Y4)(5DL zXt|XhOC5R$o0UG=qQvSj$qQp1-M5RqL1n5{>45tHiMkftPK9RsGA|?XkgsL_KxNC1 z(nMj2a>5w+lVyiiZDIip?|evJn_&koHr?mg2+JdfS8$S7vWL-{mh3vgz{~m0M2yt> zJjRCk!F1wBk7{CP5`?ltPIX2g9QriIEE-QzuipyEeV-Wl_SajU173`<#+oMTnA;*# z9p5Y5tvHU5(p2YCAq@BCdrdqHzg`!S0>2;-eF*ifF_L2>ufkQheBaxn$uO$3RIx_Z zkTb94t)!2Qa4c!K9_pKdIU8yQzsm7GRA(ERLqJ=H1eHrVOsOwN?B^N=sBSmMzJ~~F z#TWbFSnGnoh~)&Ni+npEod%oLV;hUTh9z-Pe+@G<>9kxYz`FaY|M9a&O(^7qLLM^1 zkX4!=39$fWPCMysf_kMbTLY9ny&@6Z;h4rQ9dZ_HBqhOA2z)612$hfc)Cyn*bD=^T zs1}_kirEFlT^^}7If58Vc~|5$Oxbr+IPyiLqX=Y5CkS=y!WENA1$fviR)nEm1!Clf zA#h>B0WIq3Z^4v%WT-v0Ih-8Klza%{@1{0|>g^MR-q(yk)|RdU(5$}M6A}`noCnt@ zNSNUBS?>$ z2n1^p=%+>L%Ca$HsgiLQu~i{CaKkLcNXYm*IT$`8n&e~5-lYJKHqZG&8HGM7PczS1cJz#(ynIKRMgHc}yBsY?NF^8C4d z-=yUXm8RIpHI+hp5PNmW#!9xaU89R%HF^j*Ejn}K+^>GfjT8R*L`h$fC$~gQiL>

!d-7hZR^?Hr_B}C+=kiQ^>Sivrha2DWJO4fu(|JZD6CQD zu@}B~wopu)y`q@*vnGdBU6xsqu}q|V`Hp<-XsD~7L5z4M(?+b8p9<&TW8XgpEQPL@ z+1&39VAYbvbiT~cGQ^AvbIibF*g%zX^a z@~{YE&GLB55jvgOpf32h$-bdrE=*sXLUz+BJ*>cpD&a}0jsiD2mx{cG)umKx6n6&{ zF_tN7>|-BWYvyXGJ(gg7BpOyQN4?auN?tSbjn}Sj;Nhs#L}!-A9fX}OS~K?=pPi_v z%xD=`zS1(kU6+L=+K@Xo9@K8A;=4Y9O2rlZDf(CoOU0uBHJyEQaTMF<9%J-PZl62o z__>D`mL_Zz{Z;F(xAgT>PqlOs!n(}#r{MB53Kx2NGh_aIW$~)#^%eOm9wv>t%FpkK%S@gq#8gNupbVaRw!#8o68_}LT%S>) zBtN+2RRf&C*eSIKg>P|D!MC16>hWGTbA6BB*L@l%8>+l}ur#^F{<$4DapO|cdM1O> zSxEVo{9=Q!8ucdI-Dg)>vN{{F^Zonbo{SD|Db zrtemfvKpfg`uoL|_aF66%n~m=?C-ZRcj$soH0K zcXW~)=^27OWSe?Bxkh`97^?hg!r<_zX+va8EBv`mRed&s; zHF4_)Q6|#qg}u<6&+Kzp2{o5yV%pcvKQvH25g$Zlu6vVyBh)ebrb^uUdD(Vb)uB1^ zgQy!P=I$!N!mV3{A4FSLxRb?R(Uebk#v;Vz6)zCCX37l3Ex-C8S|Y{q_31V*pTHsY zffucB2bX!REd`w~85}^LcF{Gg&ApB?St2Bn$fX~Y4*>t|vuc8+&oChnmba`yYf9}s zAej4H|8y#W2ScK@T|UA^g%xj<*Y#mVg&v7R5z4>Z3sVSa<=u9#qeA(b2r=EW(-Gw7 z;HOG+&6G`#=-@i)$?rbAbEp(`J*UUn&c+P_?8O?qL_ujt^vB(c*iQ(jQVcX%7HgL-Vr^WR7G6V9w^xR0 zKM{F$siS~a2US82Qh);Qb`iVLXhLx~z&e2C2J0u=OWIRswP^&xM}CyH~7Dub60 z8e#h6FhOWKU6{B@j@lEOtPX?arG-tk;(JBP5nM3U?3vxh_X@;`An+>6it22s;C=fy zC{0@grj}qR*$WVLZl54VR*>K#wiMy0RSkt-gi7A>%=EfODTUaeepb;xf~UsbeL;=& zc$pw|3^`m*Xu>mP8iEFTo$eD=jGF`_tce7obKtY@*VgY!p^SJj1lTga8W_G8Q9{fg z)L+(%ij?sO%d-J$1j_6F_#B@AJ1)7U5e+lWJ^00gp={7A$AGUqyQh1?|6Kn(!M)HP z^>+2{1#Ge-u^AvcE_i*irP10o)9D{g_n}&fRdIMd0zqI(KV^EyPQFGOGG@!T9u4J1 zw&LRnM0k3P(3=*Y8Jk1p+aUy#LwLl{40VAxeDXH0h%XFR;g&&+rB=2h0^moC(Ma!r zW=$El@|gkO30?x{=2rn90`fcWX;vCxgf$}oDZX7@3x@bYftBrXO=K|2W89*^b9ez6 z?GWg7yFwW0fDSm8A)^!U-@Q=$|1JJ|^}pc1Y4S@ogVvtBZa?HM&naZmD;7G=M8*Ns zvzV_z-diW+OZZ|TRWVhtCeJxf)-3KKg>0(0Jc529Rgu4dlJz7aIL2F9lJy=p zKNd;WGqB_B5~)n?5Uw;U6v+%7qkTwG93@;?U}#^(L47g)QiD!OsO+-A1B!K91ak;s zL=PcX(ccC;#|x@FgA;xZAspk3iphGCRHYo$y1lPpth+BQKmoja$>4#>1Xt-A(J%MX zVJ?;O=a`b=qNz|jKcli@TSAp0OOlb!Mixa1aWZA@9z}77{H8^5x*SCs#t*bOJt?$%Xa=i;2?D!oG_;k@Kxet*0gbm zqBtTKX-ZoWm3Wt~&Z0O=u)e;~?g^^nTFy)58aphC69Fx6xh$Da@bi`9t61}u;!Bhi zN0fd@o4hF?@*9+=If{`nvZ?YXH~P^V)W~1> z^lgG|T{?Czd`((vYx<#>d*+j#8h?_BKqm=~WMQKpQRZ1mxqQEzoQ;08Ff|UYsFo0= z-Dn(4u^?N_CTcMc;S=^p`29{JxMpHxbBu@-Or=|MvJM)j{X)DcY)!C#p>V;}&^qX4 zL=FHwWu#TNdT-Lxt?no_S`F|lM3tu@_X41+Q7wU8t0AzSbqBidq+mW;w zkjgb=xZzbRiT{Oowm^B{qndTljGTv+ms^NX2YM(CFyfUj#7fUuGiA2-<*H~7QumLk5Z~C0H6lBv?2nlPA;O7=jz)+;vas z=j;s>T!8!d$X=K}1DIGZ2}sZO_7c${JiNDqSU|Jnapp>@|r-i@xjchhjIqxm8YV2>gD~;(o8PDNVXr7YGfW;~1 z>y@3|9DtACY4!+>ag8t>^|K4`W^EpKd3-PX!ckZFtUlKP8>Tj9GKY$wUi0R`9Kgnc z9IDf6G*tEUKcs>w&~pka41H&rOAtVEn>iG3u7v=60)&g#Yesv zqmDi2Na3sSW?6$#CBMtajByDBN}oN42GeqNHF6lLQw;7^vVb|olD-`a!2>)gg5mX5 zzunq}*R0)Vf&9=0LLg?SlzKnDrZ3RE0m4YL5E4c98hN~i&2n1Ys`oR!!KKeif0;zU zX;EP21`$$1y_Td9(tXC??;8)B?Ln7uUO)=T-=@4~Iy;-$Hl~FVMRH@L8DT1{Bm_u5 z^e;^o6!@ouW2f;7>t&$#7xC(Ak)-qaco-{&cW)*j;uE4PiiETYJPHmV3}h;L4Q`le zBLn6Yz_qlUi!DQq8aq0ZfIRVWxn{}APt!o%!}qpT{8t}%7yt^rTG}1 z8lM&h35@e|uRzQd1+81a5VHuq~zifQ|_G2&^$ij35S zY?oKO6xTw!zX&U)wOoo3542TW+o0FixFIT|vEs{H_*0R32R*uI@Y5jO6$}xZ$Y(F4 zSpRTOajYv2kMUzyIaQ2!{(X&LXTppNii~`<+3u8SG2(U6JcU2I0T)Whza0%-z7v=e z6_2IN@*o7zMtT@BZIpV`PJYQCv|uh*G0VdSr>QcEGvKqUGfVg)^SCJ`A7EMFGIc)H zu#$zXtjuPJAvaZxkD6M%(jD2&X^YV*;JP$Nzg!%RMA+5gH@G~P+1&REpWgg=rDjH? zvcM=RWLg{4B7?%G`$@=aihBw*euqyB>g%&j^jKJy*V@W1S3WbiD7WPT-M33k19VRhP96r#P3f4BO(1AIoJlA=qFK%Crx_kjw!93OW4`*t zudYIZctWU-nA}5Z@%hC^YlR)b>BzemY~JH98%%WqGwyQX=|QefP0mU-m?@g=Qqxb8 z0xFLcAnYr?(U6dPI2RkaWU029M8e^qa{@S%eO04Wq4T(0#6I55RS2y!IUA8j zm6(!b$8y3dAtJiY$A92ppladtX(TKWU|ailDEgr63DW;eV7mw+h4&M!_p;_k0 z8VAf4AKh|OoynfRhxOimRtYu5RQPW7ZY7Q7+qW$?)}fSz*Z)O5Z-f3G~9Yv`Wnx$JXRhgp$d zK$goOm=8lV;L{&6XB31ns#@da_7UWmIZH!dkPvJlgf(k-s?rc(KV?lap1Z%Kjps{v ziIf`Nc(a^ue6C<*-ZDaESvpXf&PA*TOw`B}^~C$?gTJdo`~Z&@D}g}KR1n}Q4)PN} zAJ}a7q6aZC(i{+;DQaE#>dMWcsoUmDgh)qlsSWCJzXu0>^aX;%I6ZPyFa#Dl^Wh|kU3{>5|Aw+ms8Bx*oau>URztb)_h=@Dw`3p)Z@pY{fd@UIR0T*W8> zRT%pNDVXTN#fLz>Wd!5*+ATa2{u%JQvPJS)6t#uuJ2H%8UT+!f%Vz*{$P}tOPry%p zZ3r4s`xrxmaZ7tr3CTx=;Op_f9E4dwxDV}d>yJ^7bJStDFc9EO5gu%ZoTmtKUh-oY z>+`QXMp*(4ndbkBml)}jeo#)2dh)aR#a%}1cgZaiQApHLh#Xe0A~gfSXS=IT-J$w) z%ae7eBCCV#1sS`5HFkch9b(vkRWNR;;#Fkdp@o91 zwjJVO#F`GZa*&5GVLo0ede9!lNDfWb-WRzE)E(eCYETr9TS>g|SJ@$rx?O3(dI^wD z`+O}dtBUeuMsZ66yfY;K&$?MbxhMdY1H7A*+ZDq9TaQ&nn1SN)GAG2dbVm~6vzYuv z08n&|4$teQx-$&>-%{&8!Q%g(wv9ui|8aaXhq^zIqzqqPcHG&%eUFedUN7@1x0adX ziV{z*G;g)WU&+_&^JUH8$Aqb6Gdl0Wu&Ys?^71j4$2x!z8~D}RX0q3K!vAemt$WAi!lt?T}RcRV85BupLK(gL(kc}DoqC)9%J%^5KB8Lu74To^$ zHFF!YF*FBtyuIppCtl_)mWeR14jFRWnB7%fg72Un|GqCPQu%|FK4)BRuoKU3t_#dE zht3K8s5xY3_N<17Rsg}QK(KKbs8U9C4t7P}hr&mVI<{1Kx_3==Y{xcaYFhaw#;V~Q zV^u-6W^-?HLUUK5hD0hY3>F_eEsC>w1fESN*Y|k{*K#JCwi04OTtZvv4^VeK+!WfJ z<=2binnJmjiEO4HzLs7xDCA9s8KS4$wU_!*i1*wQ-Pl*`O_G zUAm5uLN%GstxIsIPlM)pT^-*qV=|*3KRLz&zfc(cP^}8y9txZnl%csMg>L<$29GS~ ztM)^G0$}G}C-l&s*gD7~SqSd)YSdYvOsM0&oJK0$KD(IEQvPyZg{Ose(4Q;TK_^{? zPyD2;gMvT)JYgp*dVCISi3vgv{}9}8Zv4F1hm=-}x8d`Ue3Fi5P2e<|yJD6v)Zqxc zprm+b(qi|IFT^|a7p)0I!bCL)2UAK#uPTv$kF+p~trv}nME*556lgYz;t1Ocl>pH3hP#9PT%Af(0gl5A3Z1Ot*8L4Hw{MFIsr63Bje2 zvRY=cvzJ!$$eJjINm4T;o;t$3qmLUX&5u^49Bo)Xp0bMo`Nn@S0LfxYKR+A2~wZFUO)qW2-3NPQ7(XgE+gXU1(p>MtL# zWDbb?BW<*7&69xf{#2b}X7MM1C+t0fhqEdItkhI-^xEGc96v}rdT;T<6c6dyP|pr? znkLA}yHMZMJnIf`uBn~{^v43C{Pwl|1*)(F@F50N;!L2+0tqr4ln_fLqij%_Dx(|# z_~K1An_y1Mk45TkVEP$a3E?WN*Gz9-uZcgT#mbRtM^c<4VE^VNWaMl%Os=Nyd(#M% z-Dp8^9y(zty4Lmg;U_RwDGjQk7-8^9H`ZpA5(N8n?j;LevC?7-Vu}?}K9&ZiDzK>A z+jl`(&+-27LJ=9}SxdHR04~h7Xx-KD8jwMf91pxQe)MO z<;+mF7MAy6xOfFAD!fE_9?V<}@BO;J7-%O0vl59pFFUR#@8Tscn8W_^-Zkteyh1f= zsB0{igb=?CEblHuCD%(BZ36SnB@yW1g<&p6 z?1yVJk06X6Iq023>Er#ijRdA4_YHF4#NouV6mUc2FV;`cie)xGKuPt=UMMJJ3S2Rm zYg+38)@2)%ttj>?jCSp)pOhN9%}96!hGH>0C)wody%$WMsS^v>lky$IfJGdJIb8y% zClL1Qe7XDP1~;St=@nDXcEEX*;O%psZt;5fZ>YtTPLa?{`+Nn|6*64B&WLphvS(Jo z+rIS{VBcFIl|=}mMgY*e8tnz~$bkHcWHf}iUG<%08=)(9@qgBe|I=DWh%y<2+Jd6c z5jr!sCFFWI7+6W#1&6Dn(Fw6p=-Myy<~fhL$jMLIvDK~DcQ$vYzwO;8T!+35P39}P4ZYzFZJ+ThHHW=rH8Q73-*`Cukt(MyRYgEk!cpV&cTAG*L4z+^Q|WX0VBdC;trd!$TUe-hI+;#dV$uFx z+7*O#4zPDVVD<9CiB0lLoA#sJiTE+2vkd zHSV1F?%}YIY4QdgF1v$NuoAk2P1k%bcn@Nl`2}g@1@y9`PDC!tze1)rcc^P-R#@!n z?9CoGF#z=JF4Q2QsY#&+KpU@_yGv7JUR9+~77zTP<49PK`M2ulb|EDjk$^nePONWm zA9riZ#{fiCh>LGY?e4*`R8{fEgj!AQ-AO9pQG3C~t^CovvSj0BHWAw^OUptp2mBNK zI}?;_7M3d<3GqfO=*O0pDf3lT+7pz*wIwAdXs`Mbhk>0t*1X*IqWQ{9RaM_EHqmUk z$`n*IDHNjv=2jvqj!#+IaSp}h!S-mPrn;a@O82&i~W|EHynEOpIdKqBoP2$O&aB$hk z|0k#DCpXTuL|9{5dbLDb3xKCkrOt!zR&yHUF=G?6B~1?OrEePOnhF}|RJk3Tg18?5 z7$nqwb(oyup0M$Z=3m4NTE7cMlpSn~h}u(aWKy3u2ln?@xPhaNAe-0}0H)8+GqLTn zCFtOe_eseqXvgG?27RrXTY97C+ECTONlp~$50qk^ftgcKIUrAgN*Vg<=fhpbZWU@< zL;G1#>vM`Ch;HNRHn}w}G;oTCli~ZiLP>qis@woLW4pSHt93ctW1n!bc)+0PPS$fNo2hYIlGU>lTM$9$-874r!zajLfS%YnExcdt(HFoBT}bUzOC zWN2QeP|V<+!_ptoy!$l{Y-A`xW|*YalE3}QGZ;zb&TWDPBuJ)Sd%bna6@5tOJF@;q z)|bpU#DgXl@d--D)`1PHa;& ztLZkQ{Py>KC58{09bn|$z$^~fIVu{{(U{NyV0so!gV`7p#vG2hJxC##1i8+UtK4v; z&<)%UUi}lc@;q2A74}UIDDPc>sq|DqriSC?8B$j;8%!hut@2XJogmIbIkdn9WTU)x zc{&vPiWd*b9bHR8V5$WpHU0^fIMO<#DJmtL?JGXgmE2L}B8KGZ5JXmzSZ4eF12jQB zSo;!EVf6<`NFqW!v7(rZ;EwOzv<@il-T@N<{TbSp%He2WcNMj_YfiyJP_MRS>x~CY zUlV;Ktn5xB%p6r*P2m&{mC$g^yrqCQD{iem$15pbbL0mL&pCbaV%DQBLbE2Bp!&Lf zt;PC2M7_2yh~ZvJ|J@BzrlfXik0zwA zE2CgIK$`am>eo>B7_q#10=sZx0a?D0T1c0H9FFX&rIV!vOEwWw9JA>?-^K)2L5FK! zGDGPyf?n5jHd06h-FpQ^uRoq!2ICt7)XyUgmCfukJEQDD8|ix&z-iBDa8d9w%-344AM;6az{E*TDCIHDc^7uwK^M7Jh)J!O}Y;eXb8v z{@$;jCr8UJpVwT=D%^+83$?&6+JpQKgWtOLs4n4yBBUA^lr-4VMII-%Ur8 zrx1--C)|{!9R{rc@B3v(kr=8av!W-);xk?Pe_NFO1OI`~Iy#DO@HYC&i__! zi%^cSdE^ISt&cr0jCkZ{{@Ag?efUgh*a3Vd#8XOO4ZF8V=ro=FWSlIb@!7y5DI{;3 z_xL{C*}!OD_v!z`E^@Ip zAr;Z5APVRSFytQZ%yKDx7rG~mChLUDEyJnCI zajeP|6XJWF4%7*6HRueUCrQ6Aj{I0R$kk3X-b3lb;g1>i#f> zBOzTvZlW{BHjpr|P$TO>rc0?_{O&4CQCx707H6p8`i2(gjtNGKvs^_hxA|3p29BdB zj{lu48Odd|eQr^lVR_ZY5m6!+`&jX;tQIHDQozk&yF{+#s8DUrUJxTaEs7&?*6vZg zqg}M4&1nx>K$P^}5s@0ui}GsmT>9}bdGUjRt=AvZ9K8c!PxjEpL5p+Re9OKnJ+c=L zlw+5BW^Y+&&<|S(j3#|%C3dUv zoKf489w<8JkiP2znbPI0$Wa2r22l-qf3{s92szt<5OhB4qyPL*W>l?%K2$Q>3s}Z% z6I`SPD}cyxSSSdVhI_Nh?lWyf=7fL#^_ve+=z$kdlb|)TpB9{zDFX78{qjaMrlo5E zFz86$kH{QKfQ?K6fHI9i%CzMcNN!Jvk{%=RlVOTwdN5UhP z_$`>khVd&NfJ?vQ40c%z^Q0KzL&RUa1ng*p za_qeh+GMWF0x=1KsUOSP=HRE8BPM%W=41G`t2!N`Ak2Ep9@GrMG|wMuxWC#X#C>8P zQ4Zo*C+lPMQ*V<(2FI%$1E2Y@)Ak4s$B-1T-3~>;=D89YvmwLa=T9}AY@jm!?TZBU z@3n9ZFdXG0UJ+Qmk=|+(h?tU`o5a8n5HX!p1Jnt=o8!&OG;TlwaiLbXkPJY)Rxr0POuzFm04foZievaLn;P|~L8=8F|`QUkk0Om2fZY)Uhl=LJ+430}{PN-}WEz3=q0OjlU z=V34=vHvm8x}7dWg2i3+uhCclF7XXH5%NW#1MCXskY2&eX>i0QmCI#AeOxR+M9%WZ8in&<`em;^g`BBA*FJ#HUOy-S1z!xW=M)K) z=pMdy+D?lVZ^&h)GQh0tREiMdwO3#{XB$DDT%htqAykzj6_K?!KubNM(5jVPo;#L5YRCyMxq zwIuxHs3zIkyF(z=nvVdf)~rqN#{tL{;bK|lk2wCS#}KGazj5F)Ht6Kw9)3N`d4|{K{0n$;9hTY^!oDVrI zZ|2T^%8m2L5Pt#qt?#aNQPNXEVWD@Q0tWjk?xvg*9i9D+RH<*90Yui05>NT6DW2E- zpNfm7i7D2VqsTUb6j($v@IVhXpkBx5kTPR?^qc-%kuyBqSZvv5m@0@%A88o|Xq^D7~~ zv@!2pCD4hlfB(;k(Jpci{`r*<70pS%FBhA(m=POaYLA}RQ#Vxj*e6!_FpxhP`A*x8 zBVpS(eKWb%6gc;^KE1&*q~iEI9IBztc<)!hI?MeO-kTFW9AHat9P7m<{<&iIyUdJ; z4SzPp$u#HtrRP!6b`)cqO-O~r9IDl2ROS%K$Cyn@uwNbLbu*iA8*JCr=&6(Pv3EGR z!Z_oq9(7_I!?WS<7gN#1)H4(~_xju)UK;0`nKZypN*= z6ywVq^t~-yg?!0GMS%wd1eQky2Gm;j%@WIk@qgo?zQ2=GScYFXG zDi#O*S$1ET0)R8DdihgWv?Kod=q&M*+%!7Z_cpA~e%H68R&tc;tt|P)^;l~XL2UEJ zKpopyNME0EoVMZfb0Y{;VxNo~h=BUHK7XJQ8S+;S#+9qs@b?Vp`fbQcRDZoX6UnHXdWOm9}x@w={|HfT?LIJ&(~KJMM{cgp(L#{URMEB4S$-U_3c_6D*-mxgO$Fx0YRU=^oojwWh<3CrUW*c9lY zPP|Rfl5Y+6#I=%P?0==d#Gj-BK}}Afb26j<8`&HuqHv%W#;~8$Rf+w||Ha;W2Sv5U zdETdKa+C~$s6&1RFB+e;DiaRIt<}DF!Te6XEHAz-9nq@ zE+cW|Ed_1}t9x%CHUM1DI7s1)#aMOe{WE}_7zrv$z;a~KgO>ndS0@MLw*AYSN>tUA z7O`;`5zb!o%IrKO(!B~nwZe0$lqi;w4PJzwl`hF?tp5ZsbG8@SJ5i$8ip0=8@&wS7 zS^+V!ANDS_E=hggRUD%J{pT4HZ2qZv4U+ncU%{~Sb!F^+H5u^1OoRC-YSk5icfd%{ zg1M+fdw~=Z_ZX~SLaNf>XUMekUIKv&c@oIk7a?c>f%OT($Z#P3ocf&;^Dipj|1tqk_%EDfSVLmEK!apXi zQ=Dmxw@R4NFoz+G%Zux+hYyn%m(C=Og;2~i4RD8L<^%MK|M_5wsARnV=YvfZiLemt z@e$AkUB3$6X+B&35{Q2_Gxc0R_hW{yY0VyK4u+r@WW-J|k9OrLZFhfVeWZnTz)l~d zuPl1>PKIheI)?O45uZ9HrBvvnRj&RYc|3i`&(%miOS@#Y3|vN-|wv%+4r>fGm)RO-p<r}tCV#ccHAR)Chs^-2!dL(iqLCjL-Uio)XknhjEPvgd$5 z^Md~iDSe8ND=*6cM}Z_?Y366~=J<{GK-yzP?xe%zJ7%unq|S9ij!e>&!v` zU@=l~iq_37_oFN<4SL1ZNzqMC`Ui4RoofL)Bi=B&GPX_V#+_FP>wqG@N@hV}Gh`Fl zOdfo>%szY@N#DtKHh_$`xC|u19FL+XpaO2AV4LX2^a=ya@<>7>{pSVN1>FlYHWlzA zHgzM}sTSS>?kZz1M(zHCWMJrt*93!rCfK#Os;hxN@po*nh~zwQiyA+Z%T@vawT&Z@ zyoh;fg#DxLF$2AC8OwTz_k#MJN*0^C90>w~@4Z)wa!CPEJzIre)zm#@m@w6S-0=%j zA3Acg7_C@wA%72mo;Eg_Z|2JaO|K=oOi{EAgb3fq=K}cSPmz>2zYqGefL^Heg9LoU zj_$FP0&2g$F~~i`K(<2Sey3oxDsNLP@&xq|~ z%Q3&{%kcqPV4|+BtOEbv6v~V1`-u7^E=vP=K-zZ<0Z-`Q9PkDG#W+Qa0a+Xc;7JXp z_0?fTkKL2Haa`sI2MNJMPWb7XCh*VHQ7twSqgJfZ8k7|!GSX*Y+~R_aS4wIw;p2jD z>aTV{l(ZW4UTB+3k7n*t;)-9%j6*_Ommm;)0b-%ao_sFiS`$Jnp2#mnjTCcILm7A$ zDGKg;b{c)20Cs#@5k}@BEZpIRaIpjy0#hbJA%JfwGlj%{fB6UyfJ!)s#fLHf_BayT zPv^3G8M<@3z?RZIF&_9oEBtD_&~hMI08QJU*-AiwH3~?7q;O;%xIBsKc|k0}*tD~W z1|#`knHA0x;*Fry2)~$`IWv$a?11o@L%}yEK1yh9@uC*IrxTx5$A=ceC=H}>5IDR> z2wb5539*j|`pM2^2=Gf%L2d2YJWJ7UM+G&3C^%E-_ph14{xEidM1289E&e3(yhO*q z=la|0*CfP*LhXsk-0#}ETY?1N8~S3GVcq&S!c$~BcP9fkYw4NnKkKrbK2lb0)6dSf zb{Pl{5iS~HSJp3>e?IIGcfM#yGhx^!UMt5vHaRyoa^qUU@I>mlB7+ytbNgH4dAvQ8 zxxM>=Csdv>nA_X$nWKOICvNXA7Mag;bxTQpavPpCAopT8+h(M(mPVj?ru9q^9k+M= zco-Z>zlQnv15IK3~8bgg7mdnxiUQXeelzE`1!TwIK zZy>)n=5eEmvD%CG@#Ks=pIPcT{9yJXI@9CZhC;I9%q4;1d!@nBMU7Jb(6ZShhw|CIU9_4 z1p{kz1O?(^hSrLJcqYZ$)&1;8W_sxcm+=|RXGtxbH;nc?I0c&`K6bZi@V>MgTfSXY zC4EvI%zn0guko|-MW5C0q#Xt9JqpWgQ*~@uAL1r&dv#R3fuI9UM0T#f<1NlC7pp*GIsrU6c%B=5w?CWz5eUUmJS>C|f z3iP;%Nm@W;L!*JcpQkCUM}C&I+EC?d#iRL z-JDk7kt*9IYkwO#@7RlUUz8>Z2X;$i^jqH~^(SwA(=-l}qTWh1z|_@3`T;wo)>~&s z*}AaBptqU;=uI=$w-;z&0kqhRDaG_3XV^c`ly;N?t}|bE+bQe+fHk)QIQN->oh@i6 z5Qu6Eq*ggrbB6pfzJQAq`|a|qBnoY+f_#!n_@m@J2+r4s zwL>t+8H6)q(s`zVso?|BZ&^)RUk`nvi0d0PI31u@vTkAlr%`lKApI==l$H|MGwW`l&<=!13-hbq#l*m{;W!-GNec3K zT_C$x*oZclZpP>E!j8t{MOEQTU!<+f7 zUO0Egl3)V5s`fh|5xGVL0-yUMKOn>6&ip*nVvYu@)9HnR zW~-<)kobj;*suN485Xo0&Jk3xOlK@xu3ZA4Inu}ir}C`h5Izzl1xS1xj|F=fB>9Nz z<6)nsyF$;=7y`v+`klD`IXH0|_4y*OZ&6}WO-I|Pp{egycOYXGZYmV{Eowxw2B$w^ z#VaD<*8JY@dKvAK+YKL$l449{ZUDKAsJI`xxD!c&sZB4sB=dLXPQH`-PlO@HyZI-) za`D1hyIf@RTO&mZoUD!`Ar782;#WaD!d(WZ+%;8nr9k=)30=gI{&8yd-vhNQ(w%&O z9zPJm7<+F0K$=^E zhL+~b??bRYHjKOize7-R4LY+l)4k=HHE>bOBIQ2PxXiX`l)J*08z(UHRj z3H3jvEVus8OIhyg?I-eX|F?$rpV!bF8VApGsw|9#*~^7p`Y+?QQ|3bsGJwO}xARlk z`ziUp-i%tZ?W|tpcelr?Sq5D6krkVktP*Q~rJTkZ`{WxC+#a~wUmyDZCx{2cvoCxATj>dZ7+NfujU?KBJ9(A>bhAWXCoF7OmSx!_HQ0flWBe*>G&4PD zWs{ayz!%AGEHU|}3aSoJr@}FyrULYs7!Lu)Yg&UDR}A0FzWM5WaxZc2V^jU_njpB!f>G8cYZaFAy21 z5P$dU67dU35)nTFpm{Z$QMy}69udGk%WL-`ROE|IGFbGQhzWp%zQH+mT~(;Qx!^#`%hlUg&4NIyk6N(qCrKSi^zd-g8Cm z?|t6H<{0QN?*W$MVC5|GTwVc%EAjIq?KL06X3X0|XBI$9tz_pZ zAGdQh`w<;RbHW?c?Yq6gAVi0+r43laW%F6kASRvvYA}+lM1*Ct|1}=GY9+jSxB~iB zxByTEAsxej*O39_HdMiFtHeK&Uh%$@0s@+ILDsOgZ>KV=0=hs;K2g8*WWxN`dc?|j zM&OFu3-H6s_2_)Ylw}$#em*HR%<1zlj3b4?j3|TWVNG{pnIW(?9>zcTJ4ZKTCtVMy zD?e7__c5qY!E+WqPsd#r*3%JS5}7pRToeTAnMWHWt zB9pm{$>6=^iXgVvr)t6Za8s2{{Bnntc$B^qu8g4?wk-~}Rowm6N)x0K-z{za&>nD` z8}-)hAsEAEyIM&UztUB^g20`jU+05M2emDvOM&7*d()CScus4J(*fp2^F7XHM&`j& zY+LIYnn%tFr-KX@TyEinU7CHF6TZROJLf+RNTD&{nPNEgzybuu19q97CZ8ZW3A1TQy|&knx#R+Vrbva@*YZvyyz2+h#j@V_p8(y0hj~W z=vdpQaTl%0{j2p71{iI?1hZy;<nC0)s1LqV8;lz#L80CIvzjQNtHt*qf?>jPK?ylL563 zb}%x5teMJb2Do$O%qgJFRsUf*2-Ap~;H3fmDQDTD5EtVIYBdm&L_IFnXomt@4n*_U z$POrhT4E+VC^m%yo+YG8_1-=<0Bl6d$9}`J? zfJ=Ss6Ow+=^rL}vumYAOe$GFOF|S29T!k|t?wx9!Hb!!r|%k40P1wC+rECX_2_o<|jdr z740^A0UO@($n1Zc6HQ@}af=h}iT}R2Jo_I`C;xFhT1$ZBohKF_xvTpw<6hW74oB{s ze{pQ8Rge%&iaW}{;jtKH^QBpXPTSOj{7VG0EXMf)#zoP zW$`|F9D-sg&OX6Z8-mmWkt%iGLr!&hLt@p~)jvHe|LuhQuW&;Cp*S&Z%axhg#=$@Z zuk3+T6J}XGuWYFA#$sh$R%n!_{wlx3i4WzwOaa)V62 z?QMNOC6ZMW=xoW@-lv(*#oA}%(^H+ zUgeDtYbTR2%xM_^?(9#V#+tFL_v^dGhL?T43&`)OgKAE8))}DBA?JIua^VEt!mP%b zt8S-Zy$wX=HnMTfE%EN#*FlQzB}mb|4F2&%>5uC6r-E|~ufYMIq=W&`)l7Q8k^Kgx zKbI*p_C+rU+>tCN zaEfh{Fufmk(YYEjrK!NIFEh;AA<3heH5&nwS)4nGwPy1fe!+Q7=(MAS3E-? z6ZYaNrzt)=x55=jFl~LFLII@XY|(WZbz1&c5%!NaNl_f%5uka~(%>{!a`l#Jj1cBE zh+KoR6d&On;7-&mfb(>==zFi!ctKT4tP}S-7pO>i8X`dDenx7+4!G7O%i=*#3=_4% z{4HSFymznhET)WowE%RLdBVE@`9Qs16B3vtp(AGsZ$e!7lU#yk-ER(}==JEkOMDs86-#?D#k@g9Mkh-gcK8ePfr#z_?)1N9tkuwV7jlk z{Z`>mcM7OSIfHeL+SSCT<6vq7#hXJ*SRO)LGx%qw@$3uHqji!Ajvo`kePy5@#l7HZ z*EK5a^OOD8B7YL#r+~Nq#v>0E#Oo+v69 z{3f_r6A9I_eFU5qrLHT7@oBH=hpfKRLVoelzy|W4K(m7yLU(C3+4N4039{IDS>RS2 z3I11E3{-7qC(`M2C+dgmcW)YNIT+l#A})3T0VJ`ja^qu4V(p)69qdUrL+_NPyZ@5- ztouSeVXCAx{nVBIRR=ywsuLiK6@gaE+B?c^KoW}ul9;>p+8fYpxtgoFR-wUjL%LI2 zUtPr~A9SARJRRo0rmcTx4ir*0oPQ>}?4+5lR}~otdM)*Z2V`CXm*P6$wWwWGX71W8 ztp~AR7RJam(+vQL)jiUCm`lw(^-1=zu4ej_`txD`+koiOUumy(Y^N#dcWSwl-)MRS zGG!z|Dw`K|8Q`8ufMK7xZ^+5+)BZo!Xc?FxX<<~me2`ZCJgFvih=;~>;$G-X^u7$| zP0)an6j2da-hAa8ym!cdp+xpSZxWK1=yrc^bo}VNZ0&Le`_C3`)A5rdZW~{P#8(te z10T)8jGW+|AIQ2yKe8NT|Y5@3~ga&n+#8D_e)L4#bJSL#o^ z40b72_diqM1eGPArUYMi36!<6W(E1wJUFnX=vl2c%Mp457#*io|MXa%R~EPStS)@{ zXe1nD(5ToiNpZD(JA#dl;JlcH0)VuSZZ#c1F9V)Nwj9H)y1krF#5LqFU?syXl%pVy z_WV6#@&~IokGjQgwSvBqMOu9PY!Wss-WE9xKB(&e?Q5tT<<+J3;MbN+c(MKYhQyt_9`SDwK61-@VJZbs3-6z# z0dHC%Xt1zRAv zr-D9d!(sBQHa8HWj)ONR5PArvdSVnKABo(>BA5aQ-09b=*w9?VP#K}fxj z5d(K(wnmx@f`LzJdrHakr?Jf&ht*JB%0*zIIN}(;4(O}vXW|7+^RX%NnsNSR(0p=d z5Rpjit|G^1yqRoJ@MHKAMgfe73m{)$u6V+Uq{Q(CX96ec8IzE0TB30^a#|u2HA*;w z26p{xR#Ut>M$o(j?_5ylEEX??=@Y^?q2M<-u*k_oLly&77rmizH6s>`1ns3iO_${H z5(J=unmvu$J#4?+3EtxX13B}3CP(<)*q9N*82vtRl zLCvLF0a)fAJxQYmMv@7>j%}wJY>>PL=`-4+2lLS{ z9l$mRZiXJgKOfv6+4}l_jT3U0=)cQQ{_iY9;c1D#&Iy`J0uMpD4Bp^?JMc#jIQJOj z%4$$%SP(p0js%xT_tiN00grtYBM0gmNi*2(fNopH7Qh=EU4xMrc&pddYda8gD7HAhF5CgFgMmG_6((0GywPGofTb;i=ZP#Dj1yh zLM|`rvKTTCYVNIk3nd3OMhaj-gf~UdDRnUeWhTlgHBrE=hzGUGbm2$PeH8rzP~gGn0w(VA`5tgbTA+QOCs?_t{ld&}R_bS_C{{=x zO{Xw?|4zabsQst(L}P!KPwt|*%!8fRTtVYWP{S5+eb|pV1l(;RAr23rfHxsqcFPOBdo!x%^d&GF zD~6;X<&;7lj(-Fqrd}ePxg#VasJgkkKLHo(SLS625$SZ)6#3KQOzc;OQHU`&itYa~Oqr zb;mA$YS}gZ*X;h3m1IN+x(;bYhV%>k)chGT5WC=VB#rT-Cg}Bjejaku&8B~bXuhJ8 z1-{FN)5b~=G+((#wL*L<0Gxoy#?z2;4DCem*5;LH0+M7+O7}TddTMs+KAb zvi@FfFKI-Lbr94v;jBgYeY|548%}_ApwG`|!6fiHUtqz!>*D|t0zqIg5%ncw;u^M1eBq1DFSDNPXd)Ogo6fB z!VuTu&K^0kVwMj^n5eOy1ElW66>iew1lMSICkxEb-aJSaK8a^F$ojY>Dv}pV%y&&e ztLOW2VyJwe!wA@dhR_nkxJ&(_1Q_wQt3Ab(*xHv&-q3pabHoNKH7|NK-mdO6A+AcW zmWr^V_!OpC2@=^9`REF8dTq8Y2|};3H<5Kgv%CTN@sQE-1#}CN zN(nlvO$Llfx}o!E$hAug!f3stg({|uELG547+Nf;JE1fIJ0ccR|6gC$F=AV+xTqGK za?OuUJA^>!F}*dX+>C&j;l99_H}&Vs<88UroxeuLu-DbaKax@muhG9K+mdF~tr{V9 zdD2LW&#tD;#W`;y(2Rd(akebUW7Phcxnth2OMHIPGl^@H>nL-6%jkv5x}=?Cn|+~Tj!n24yFDr{Q@YnZI-GU3Gl{YjW{QdWd^>ML(0i5Q zJaJ!|$}i;gN8}F2pH;kaE-yB5lO-<4xM=59dXlUg^9ApaswREDAy0w4SOa%~q8W+? z{ibE*Tpy7otxYU7iGGvFvgRgk791Go4u9*oBI}vwGba~0?5YuG-dg%X@P?4!)5!;~ z8S{MZf3E8m-__c*cOQ9Qc3G!IUrw-aO4YG0t7iLduFw9%JRcf@TpwRS?ai0xYS>oH z?aYK~0voS7N)3biEFAgXR9zbrcvCg!-b21S9%LGPGb`!DHN%MM`R`o^ySZOS?eb+C zJq>0P)*CS`RwDQ4#e?h4_$MV!8xD%FZg_t*{ti>_|O zvJL9ZRWLRn^0fJV$Q_QxGVPN+ehP+^d`;G0pZb09Na)Ds=Tb}N!klPy$G5qD`leLv zhNf|ab7ppd{wgQ5W2|KaJpyVa9e0z&)k<>nJ_!g-Q~vsheb?t)_td}6L}8jTnK3N2 z$c~Z8RZ`I>pm=TGzM}LTIBRH9Kaoh3V@M;_Zuh>ukGFIV+1_WO8k$;J_y!r8I$uRj zA$2SL9Ov{Cx6OC$ebdnu7?9xzx~!u#Fs_C z=V*_joEjsG-$!@zZ0|I4#Ao?^D!o6{qFTlzA|QCt>gL6gr+%O8Xv}U1e2DJeFS%&t zH4zq04=xG_S&6Tgc=Z&UH5XbKo&TP*BPpI%;dkROWVi8)>U$X>tD84XnhS$2TN*bP zlG56J&-sGZEtUD*_G@=ef91YsyZo$W5bDMuX z@%6_@NpOBvDx|}e2})v9Jr;`i$B2UrxHt`+F;a^~Lv;SHW01a^PYZ*>E~L z6vNMd`f7*tOS;9p>#NejNGYUj$S~l_Y@7M9=D{^inK;_m zGRQB`zhmGMwBvbg-wncy=ITZ-TmROHkxB6vBY3f~Zcc{Vv$#nB<%chp5sn}0S_*m+ zi|PuDGC>sz%UTF$4%63kP{m<-qn#>LqD3s)&owFuRk)aN2%-%I#lZhNN{bj5b!SNg zS-(|u8`{s(ry(+_xlE5)ieD5UtSIZHMWx+zK95=YzK|aTEHPb`&Q~W8@=goznwRkS z46!>>z>;uWQb>dmQ)LT%;6t57WQf~@1Al+UOFp2{r3D8wlH)$7SF52-?dZvI@2JkX zoWeGgILly|56b#vFyGSlm=GDCwhGQr;(loKgQ>P<9uoSgh8D&oyiBvMgW{ZQwbG%{ zBuZ??9YSg3xDLIN%jbtfu^@9NzBnC9w99Z*zndfr!cNx zf6_s(+htscaq;kLadyKdIw ze1tQ()*Jzq?y@ss1uF}cAr1ku2qKepnQjC}WI-nKKneU@vw`o0h%1_3V+IKDZw%pd zb6bR*6x12fNg1!`Fj@nDK~0$}LM*7f<;Z_;nf+%G{!M-c|K~*IH=}GTN$l2xg+Q$N zF^9B|?R(wQ@hI<9xysMtdrHg*_Q33+af-6mNvf5w*ddL~E{9yzG_?Sw{P^zW2b*dm zkvnd)^0=-$Asl`i_JQx^MN1<6vG<&CEj`q@yXLDgV~ZTK&D< zvddI;`mvA75|fXNQogz6HG>6m_)eZhbtd+PDgQD!xn$0N&y-)}2eU`Zph&1+wsrTe zQu_`?^PqLtj?w~rF!#)ArFBaUX|*y&^Ce6&Y5&vSM~vTo>Y>$LzmRO^Bl{j#tV@dA%Zu81K0t~AGwQ`*tXz5g>M zjCYt~v-P82-0kpq#T1)H^~>$0LMeX*Jrw_qY3-t9v*g#b_j{VqJ1Beea{Ebo0;?HO z7v(_f>eN~UkJzzMaO?fmvDMdIVAD?b!rS2+XZ?QHjLCOVZmpX0G%*KWF%Qw`qP$$# zGacR1MX5L~lQN(F@OF4a6Q9`a-)Jp+4c{)cm-GSi6B-*tDIe8demWcVt~%a=N1mn&eug)_HLmRCp=f?Rn^>WFc>}8hQ{AUO@lY?)_)7>_hU; zWPCcK8bqt1^)(dQd>v($CbIK|Z)Zi7WzXN_P?tS#e`?!H>H8Y*g>?782B#|(4(*;Z zA&5iFT2>HhAfsP%AdmCOW5@{ zN1N_f!dvbsFjC_fgCwX$tDCtnQ|HUw(RJ;->r{16xkGG+n!Y)Dte}dHShNnliU3y| zdS<{P(L?P{joW*eX+VvuO6B&4-1;5K=HA*vA~uh6o7B+Nuhr^Qx*@AKHja*)c=)UQ zJa-OLa>bdN1yl6}vf4#aprDMmp*>wp2&=tk+%h?moW!^)3Il_`AQ4$nw)fC;@avr{ zGr1_80$t6~6;Fa~C=7+<-S{*=vrwSbgILNXQP2)8byKhhG+!u(1%&!hcm2bg`{)nPO29Lwon|KsKk4S!{$8{)K5ZDH79_?qo5t+R(&St zEGqEK-OQJWps)nZThyWoRd)}cBLK#A4I|_+-M#PeFi~_U?VR~Z6uY)xz4<$$lt^rpq9vnwx zz(2R@_YBz4$TJZsZx|4(PK9T{@|*ABH3zIVU|BlQe=-*i0YGFz3C~|38Sg8XBEsCU zJ(eWI8t}{)5`ddc&^4j$1k*{31of$;?QbOzrQGad()R{IeGQ`#=b; z;^?VxcUB~x6;FQ~(?|uG#hruG4#{I0GtFZf(WyUA^GkYksKt(dyqC%*^I6=|$Im<$ zz#4NcAj9VP%I2ic!i0fmoCWjDNt4K ztfN{oUEtojeuc6`-EPNnTDQE8CG}Y?nTJ{?f;_d-fG`WJHlvNSj4RvRX0^!r;s&*% z7@hOjmjLudbJgg}b~ZMs4Qu&7^clgzm>6o*9nJf5J}Ze%pf>4QEtNP=yE(tq^0oVH zpS33V30UIRIqWMKWqPm2wNn-mNK=a)#7g&`>LeSI)_w8e-aGM@^o7uSS&Gy@3LMy1 z^xT%Ow%u5}ws(E)$%$6_1cz3-e~P~PP2z?xX@J{`uYSAgF8_UrX&70k0k6#}!Hn z%T{mGRQ`MsHFN(J*kq_u&hoWlP}|jwUm076?0}3gK@TEGz0-Z=Un%q*^I(8-F~F{+!1k7bbqPu2-$yaKhMT zxUF5ZyLtckFQ$`<;GNll?`|(tZTH=lqh|W@rY$!(PL&Z*oc|ZxTh)m&vYEHwV`0r2NMk(X>qLMpXTB}ggt$c~Z4^#hUVNPAyBF-3cyyXkj#F^<4+z;JY@T|dxJ z0`}XbA1J$QIB!qS6zP-x=Yr3OmqXksS7Nq$fP4q*7eiCO12(Kpeq93o@*`^RL!}bW z+fO}+Hg0zp3tt<9iOLU*h}d$5y>r0PvW0Cz?5E0Rko`MKh=0!mZQ*depJjXf9l- zzx_SOLyU<|M4(RZw_lQh&G(!HUh$#|0F_F<;@}o)@bysLw7Kxuz$c{nf@Q3%8=a00 zMoO4DyA86HUn;|DMHwU2;g?Jjv>x^7_n!T%?{yB`CNK5I7A-+5Uy!v02TrG& zbU5+ntKX@x5wXW*`&!2bce((cPtqQ zgOuMNdn`F?V1xvTam8EV+)7YJ?XdAJD7yRuWVJU-KvH=vyn z7EBLyT04|+c84mA$gj8c<*K$lG!Qod$}pFxelHn>BVHKya@s)yQ@D|b;CTn6BqU%x z=K|(L7$(Oe5%MmTE=Wk;MTv(LtNAD{*d5JBRZCRil<19~a_T^Ew9BxgN<$GrhI%H} zRfre6{!@aWLZo7~=2fXaIqqd(b=3t_6cWZGO2 z8I7N~A(nV;BX(?8e46zDbmgrl3np0aJ%Rk|sKZ?dtuA50L5USK?1H{wq}&N18a!aO z-c0g<;V~WZNun@$rE@U*5~^q_Mj|RoEQpbyj6xYabRBF6(Wp=Eo|Daoo*DdX0+k9Z zLIa5zugJlOcKQsawCXkWpN0A+Opw<#r2#EofN`)U;}ttrEN{62rb8JFpVoj4!Y63~ zg${&|Mgw9!&~o}PEov#UV0}1U-Qw7>;muLB7;n?4{|q<=YyToYGl%Tl$9z}735U?I z%T>Cn^NoIr+3axK{1i13^ia0aF|LkYFs5bDOLrqIwq>xci1|oNI_3?a$nD4>4LKdI zPYWBw*SNm>V_mnLTm#?kV0y=6cQEuu{_;DRSEJYu z{YaYho|8*`NE)*rPRxKRpTCmv;y8GhUcD^uF7Bbir7rF(U+g2B=|jS?TRH9J5F!ScbvWi1LID*3AcbjqtUkxB}+k>$}7ad=h{$( zG}k^wg~>VVmu+G@INQE$k*Ap`_IuiP<*lTde15LVO!?!1``g*0oWYuB)?+C~n-O~J zW8V3OjV&)Jmadif@HrkgelA(P_@dU1QKqsrVY%b-e(X%TNr371XwK5ajhw94N#^{D z7c2BzU*5?hv|Qgc;MA^c+$R0AS7rTaVs6fyV%?SSl`t!z{PH5DV7CvVQGPjMj^X55wn zv*!=PtXA}b0!ho61703wSYHwO;VdX1_Xj8En+L@zj~91JK2iiLVkk};x~*22{IW%C zXlTELwHjcf|R$XU@sV79~s@AM;f|0i2vJu}+EUVAi`U`T2I=l~*_W)jY~W>?G-| zjb6ljy&UZ)`T6M0huJNTb8Jy(z>V-%OX=c-2CvJdz_viZptY>@6B?zQ05mU3teREF zgS|GT*}7Ve`g+u~h6cTqN&AeGhRBvXH-aT{>AzHcSq=5fFxOZOow7M2S1M3I|3#Z6LpM^y#!q%Wk?*v= z?0Jc`@n~b2^ixvq^696n-{HL8T^bN>ZvFEUFMWDiK+lOe4@i^rBZ(yQM`6Kq8fU>o zno?>2m?Voxw`(4vWw`(zr_ee*YcbZ#>GV%&oF^A7*i`ZWQNG-KJ|gv7VT&ESyX&p# z6;U_!n*C5M@VJ9Ge+5PWn-T_h4l&IQBUa7e>|^Zxk0td%s1)`fOYj~ZTL7;Oe#0!A z+Yg4sgNvJfAe%REle`>8O0tYtGpt9zRQL2%Z-Wtgxc@WVLIJ48l} z-Y7Y0&!Vbj#|Cg%0UMF%I(IF_1Ejn|N`Fd>mAU_c`-F->$l@C@N`Cn^m_=44b9cp?8?j=I59cu zK-pZuFkv9dfxJo6Q$Nljx$Nb7=J#Zp~O`4s`k2 zps@pVWns?z))&MJiETQJ_=Gz@l&{VN28*vR6QV`FuU$KXX@yzx#j9XPVjNLOjSPv2 zp7L!ddLC=Xf^j`<3-(}|$4ZdAu;(a@A0xQNXa@c_w$grV1QmXR#01T?bJD{46rzTA zO-+FWsme%E@%lDYr;zX%km~V6suMEk1&68RWCUcyh!oXDav%YPzQ{U<-V`D*1Vd%d z4W?(15kPa{U#>@1=spi$Xdnqtq&z(s3&F=FUYT^cR{w)hxB0YI*YEUB zsb188zePJ`jCAkQBg6+TYO(2h8{)mWdugJv^!a0Qy5qJ|b<(ZDjrLIWOe+0G%kSUwcdbu~lAwoR863vt`!sVb?dU^lJk}iL$zHi-5TI zRckYYCVsNzg<#DiId+ZB)-=AF_Q10mn^y7qP4qukdXpxDx6bJ|omX%@tg?NrQdxS{ zk)+Wmaq>iSPGD$QuqO4bA@d)(uQbb*xoGC$X!oo5$r+00lM19yCuhopYMdSpyJop1 zIaCgRTO}x(xeo4gFG?TmzHC`C*d5X?EI52?$8Pt=1Eakre=}2)Ut`fg+Emcd=S!)^64q3&A^Mtg@+YuD$^OcOh)$Mpt(%sfmq+FR{5 zo1ib;C{9Wzbh3-^s9Q4q1>Uj0ykJ|l(Y+IF1+dRWHxBux>SyGPT-%SE)cij8Cm+vb z3ZH6g8=m zfpZZMeJ%Fz6m|m8+w@->A;%Q2egqW&7!=jpxG0sS3xD$hpBeNYjGvLp%51d}^gwDQ z>u)f8{!y;jcX4sg_}HjRByY6t_jeN0AMJa6fr@UA+mgRV&$OlU`A8*u_*Mo!F^c*m zaLH_uNxh^3Kp2-Ys(zws%CZ60>Ts@x5`Qar$K$(!sCw3m@S8Xy0oc`-`qi_>DF86D zFp~fCCRQ31Al9Y6nO?sL10Spe`dI4#q3?Ap*1ftUKadvOSD~{2kj`d^M@6ZgwVeIj z^u}jzZ}4PSEO_1)A?>{Vqvt&jrbVVVfXGK0#XOUCt1~Z}IZ3_7?}jN^6tiV!u*4^WwrzI7 z`1(-KfxYzbxL56Y5W_~$dj7){agZB{#}{ndukvQkb67TNAm|A{9!_*ZwpK3=oINFp zHP_>B?pLf(GTFcX>s+}$2dOU&tOE(ux-Rne>pz?qmR)(<) z(?Y*v=L8bCHJx*WiD3FGy9(o_G5LYf@^y@q4*xin#Ugr39;_LqmK0!8IrB6W`J!$) zMYS7ZS{6mC0{*g#lXAWX;~h~2q&JRwV46#bx~I#J2?9{4N{l;xQRiWb_TOneOneK4 zhYRC%za2@i0+~iIo`B!SLriBu;0&mMvV5dihiI1zLYU){38zHFhHUAyWDG*y0XGl! z%voQ`_XG-?XBA9xE94{x#r>U^q%kI!AUE(s8|c`vC9?2?QkTqT-#J2iKwX^b;o8fh zL5$b(3@!4a4SA4$UsH&=(RIu3#&sdL+u#@MPO4{eDpZ>!NXWv+=%fw7)CVSt3%Rx~ zR8VRJtBVpP=8j)KF;q*{bBn0L(T?|T-qXX*$tc0cecM15#HIyYz!WFRAnTFVWnIt* zEeeDrjhNJ80^*55#3tB(KH&5qM7d+5Ndi6{+@t>j=xtJx1?Laxp4l)?Qqi-(-311kFvSZH^$j?I}Gcs(1e)GgnC9|P{85wiJal=V- z>IxQWD|hrAbq}o;N>u12(|hOw^$K}XEd79c1(BaVy}=qGuAaE(5u#L(6{9df3Qpd9 zwD=dqWm0n$9r0tNAHvoy`#k+K&!zc#+=!@OZ8(#Nm>!fON4i_iQInz?i)*w2=20TB zT)}eZ(5nGsuOU>kyd|-FjvEP~sO89{Gy|BcRzL$c^VqRPCf}&BQN>{P3&yS3cyJKJ z^E^-jPk5*@Jm7(WtP=VZ0WJl~J`JPZ4I-=+r(00mY3zc^^eid1wv-Us@Il-mfyPf% znE#`>>wzmhPd5iK3V9d{-_e&wDIGC#h!A1RjnvoDq8io%L~MbnL$H~uKe7&dttc~>fG zX_}ys#@=+2)@gqZzm?_BB4X4plgOiY(*N4gebcEsN@BJ>O2SrGXt-uc zu2SP>zE|0FR9K^thix$B(bbT**U!Glp{MX2&o!HR8>JdDGsh@h8Irc#@l5-ZOl7Wc z^hK5xJNY z*&A0ySPGi)=apA&{REfkf|GpTYMG8nsnnD{E=}|mFz5dX)WC3a{!TEs)($SYwqK`j zwQ6p+R;~YfLJwD1n&=5m?vy3|kL_49Mf?}{&bSxiPJ1rsKdl1x+F0XWtbbCu@FR$k z@2OvMzkD&H{+HM6ADw2O`khgolCbCZ*&2NloBbEK|90l{Km6+CAAJAw>F2FsQ|Iov zP<+1kSwURJPMY=YE^oie@16Ez?XQ~um)2j7oh-SjUO{1|W3F#4Xy)+4zwGsulO*q5 z-tJYV|E*@*p9zyB?IzCuv$=Ys`OJsyz#ihB;0b3w6nqCwFb16Dd07ga>Jv`^cE@z* zF{dbR-2az7U3uqYftwy5BvlQ79k2&eZ+g7rIPccvZ#Jd3<#_Tbwwp)Q#sLc|tG!Rx zG3fV2PB&$+v46Mz4?}V*vrYcyxGaW>Yj%&z ztJT_@_rnay+k(J3x$r{_a;A~`rVKrzd+v0gxs@&*T8PhO&MTA zm5Y6b^)+Y4W5pH+Zg)RB!EX=-WN=?gmF4&VT*vl}c~50mxsz3cdHN0ImkjsjTobyt zN1o}!uPa;Yl@GiYUSrXadX#a`yTdsm%oVCyiVW+kE-0U5m?p{&>-+FMNEKhU%!_f} zr^=bPZUSfLN)ocV71E=BE7<~gy!zCXDF8MgTZK2YE%VCpl)C96r+-j=S zV*9X#QRD8x$+&H?$(0k?jLUwq0?SUH$68x9=pG1JxGVC7uXRJ z1kIU6gr8z~_t@uI8?(=0{Vfl44$R){5^{<$ZgsKFfi(W}Vk=o^Xl{TR&NMx2iN`dL0B#eXY9DtHiiQi;-b< zF~@^SYtMOJlT2l|$*@CJn`OhLVu1s`FAX^uB3@c@Jg5@FITr_8x_Muy;d@oDNsUpQ^3CGBo7qdE zT7mO&zzrTz^<{C&rJv)Jb@NVSFS&6-5Y#z3zBc#CkN@h%Gpl^r-@j)70#8>zmvv4F FO#rP_R}=sM literal 0 HcmV?d00001 diff --git a/package.json b/package.json index 13400bc..75b6261 100644 --- a/package.json +++ b/package.json @@ -15,24 +15,30 @@ "name": "Mike Bostock", "url": "http://bost.ocks.org/mike" }, - "main": "build/d3-hexbin.js", - "module": "index", - "jsnext:main": "index", + "main": "dist/d3-hexbin.js", + "unpkg": "dist/d3-hexbin.min.js", + "module": "src/index.js", "repository": { "type": "git", "url": "https://github.com/d3/d3-hexbin.git" }, + "files": [ + "dist/**/*.js", + "src/**/*.js" + ], "scripts": { - "pretest": "rm -rf build && mkdir build && rollup --banner \"$(preamble)\" -f umd -n d3 -o build/d3-hexbin.js -- index.js", - "test": "tape 'test/**/*-test.js' && eslint index.js src", - "prepublish": "npm run test && uglifyjs --preamble \"$(preamble)\" build/d3-hexbin.js -c -m -o build/d3-hexbin.min.js", - "postpublish": "git push && git push --tags && cd ../d3.github.com && git pull && cp ../d3-hexbin/build/d3-hexbin.js d3-hexbin.v0.2.js && cp ../d3-hexbin/build/d3-hexbin.min.js d3-hexbin.v0.2.min.js && git add d3-hexbin.v0.2.js d3-hexbin.v0.2.min.js && git commit -m \"d3-hexbin ${npm_package_version}\" && git push && cd - && zip -j build/d3-hexbin.zip -- LICENSE README.md build/d3-hexbin.js build/d3-hexbin.min.js" + "test": "tape -r esm 'test/**/*-test.js' && eslint src", + "prepublishOnly": "rm -rf dist && yarn test && rollup -c && mkdir -p test/output && test/compare-images", + "postpublish": "git push && git push --tags && zip -j dist/${npm_package_name}.zip -- LICENSE README.md dist/${npm_package_name}.js dist/${npm_package_name}.min.js" }, "devDependencies": { - "eslint": "3", - "package-preamble": "0.0", - "rollup": "0.41", + "canvas": "1", + "eslint": "6", + "eslint-plugin-es5": "1", + "esm": "3", + "rollup": "1", + "rollup-plugin-terser": "5", "tape": "4", - "uglify-js": "2" + "tape-await": "0.1" } } diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000..804bba8 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,36 @@ +import {terser} from "rollup-plugin-terser"; +import * as meta from "./package.json"; + +const config = { + input: "src/index.js", + external: Object.keys(meta.dependencies || {}).filter(key => /^d3-/.test(key)), + output: { + file: `dist/${meta.name}.js`, + name: "d3", + format: "umd", + indent: false, + extend: true, + banner: `// ${meta.homepage} v${meta.version} Copyright ${(new Date).getFullYear()} ${meta.author.name}`, + globals: Object.assign({}, ...Object.keys(meta.dependencies || {}).filter(key => /^d3-/.test(key)).map(key => ({[key]: "d3"}))) + }, + plugins: [] +}; + +export default [ + config, + { + ...config, + output: { + ...config.output, + file: `dist/${meta.name}.min.js` + }, + plugins: [ + ...config.plugins, + terser({ + output: { + preamble: config.output.banner + } + }) + ] + } +]; diff --git a/src/hexbin.js b/src/hexbin.js index 45ae6f2..913ba95 100644 --- a/src/hexbin.js +++ b/src/hexbin.js @@ -144,15 +144,21 @@ export default function() { } } - hexbin.hexagon = function(radius) { + hexbin.hexagon = function(radius, translate) { + if (typeof radius == "object") { + var tmp = translate; + translate = radius; + radius = tmp; + } var points = hexagon(radius == null ? r : +radius); if (!context) { vectors(points); - return "m" + points.join("l") + "z"; + return (translate ? "M" + translate : "") + "m" + points.join("l") + "z"; } - context.moveTo(points[0][0], points[0][1]); + if (translate == null) translate = [0, 0]; + context.moveTo(translate[0] + points[0][0], translate[1] + points[0][1]); for (var i = 1; i < 6; i++) - context.lineTo(points[i][0], points[i][1]); + context.lineTo(translate[0] + points[i][0], translate[1] + points[i][1]); }; hexbin.centers = function() { diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..fc1ef36 --- /dev/null +++ b/src/index.js @@ -0,0 +1 @@ +export {default as hexbin} from "./hexbin.js"; diff --git a/test/compare-images b/test/compare-images new file mode 100755 index 0000000..fd7628a --- /dev/null +++ b/test/compare-images @@ -0,0 +1,16 @@ +#!/bin/bash + +for i in hexagons; do + test/render-canvas $i > test/output/$i.png \ + && [ "$(gm compare -metric rmse img/$i.png test/output/$i.png 2>&1)" = "Image Difference (RootMeanSquaredError): + Normalized Absolute + ============ ========== + Red: 0.0000000000 0.0 + Green: 0.0000000000 0.0 + Blue: 0.0000000000 0.0 + Total: 0.0000000000 0.0" ] \ + && echo -e "\x1B[1;32m✓ $2\x1B[0mtest/output/$i.png" \ + && rm -f -- test/output/$i-difference.png \ + || (gm compare -type TrueColor -highlight-style assign -highlight-color red -file test/output/$i-difference.png test/output/$i.png img/$i.png; \ + echo -e "\x1B[1;31m✗ $2\x1B[0mtest/output/$i.png\n test/output/$i-difference.png") +done diff --git a/test/render-canvas b/test/render-canvas new file mode 100755 index 0000000..68ef42b --- /dev/null +++ b/test/render-canvas @@ -0,0 +1,39 @@ +#!/usr/bin/env node + +var width = 960, + height = 500, + Canvas = require("canvas"), + d3 = require("../"); + +var canvas = new Canvas(width, height), + context = canvas.getContext("2d"); + +var hexbin = d3.hexbin() + .radius(15) + .context(context) + .size([width, height]); + +const data = Array.from({length: 1000}, (_,i) => [ + width * (i * 96.367866757 % 1), + Math.floor(i * 96.367866757) % height +]); + +const bins = hexbin(data); + + +context.fillStyle = "#fff"; +context.fillRect(0, 0, width, height); + +context.beginPath(); +hexbin.mesh(); +context.stroke(); + +context.fillStyle = "#ddd"; +context.beginPath(); +for (var i = 0; i < bins.length; i++) { + var bin = bins[i]; + hexbin.hexagon(6 * Math.sqrt(bin.length), [bin.x, bin.y]); +} +context.fill(); + +canvas.pngStream().pipe(process.stdout); diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..02723e3 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,1117 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.5.5.tgz#bc0782f6d69f7b7d49531219699b988f669a8f9d" + integrity sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw== + dependencies: + "@babel/highlight" "^7.0.0" + +"@babel/highlight@^7.0.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.5.0.tgz#56d11312bd9248fa619591d02472be6e8cb32540" + integrity sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ== + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + +"@types/estree@0.0.39": + version "0.0.39" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" + integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== + +"@types/node@^12.6.3": + version "12.6.9" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.6.9.tgz#ffeee23afdc19ab16e979338e7b536fdebbbaeaf" + integrity sha512-+YB9FtyxXGyD54p8rXwWaN1EWEyar5L58GlGWgtH2I9rGmLGBQcw63+0jw+ujqVavNuO47S1ByAjm9zdHMnskw== + +acorn-jsx@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" + integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== + +acorn@^6.0.7, acorn@^6.2.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.2.1.tgz#3ed8422d6dec09e6121cc7a843ca86a330a86b51" + integrity sha512-JD0xT5FCRDNyjDda3Lrg/IxFscp9q4tiYtxE1/nOzlKCk7hIRuYjhq1kCNkbPjMRMZuFq20HNQn1I9k8Oj0E+Q== + +ajv@^6.10.0, ajv@^6.10.2: + version "6.10.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52" + integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw== + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-escapes@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" + integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + integrity sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg== + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +canvas@1: + version "1.6.13" + resolved "https://registry.yarnpkg.com/canvas/-/canvas-1.6.13.tgz#8cb4e9abbea9e615a377890ffac50277a1167c73" + integrity sha512-XAfzfEOHZ3JIPjEV+WSI6PpISgUta3dgmndWbsajotz+0TQOX/jDpp2kawjRERatOGv9sMMzk5auB3GKEKA6hg== + dependencies: + nan "^2.10.0" + +chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + integrity sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU= + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +commander@^2.20.0: + version "2.20.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422" + integrity sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +debug@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" + integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== + dependencies: + ms "^2.1.1" + +deep-equal@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +define-properties@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== + dependencies: + object-keys "^1.0.12" + +defined@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" + integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + +es-abstract@^1.5.0: + version "1.13.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.13.0.tgz#ac86145fdd5099d8dd49558ccba2eaf9b88e24e9" + integrity sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg== + dependencies: + es-to-primitive "^1.2.0" + function-bind "^1.1.1" + has "^1.0.3" + is-callable "^1.1.4" + is-regex "^1.0.4" + object-keys "^1.0.12" + +es-to-primitive@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" + integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +eslint-plugin-es5@1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-es5/-/eslint-plugin-es5-1.4.1.tgz#258fe89bc5f72fbd9f5f7936c840151766821f1e" + integrity sha512-kktkmkF2O7pnSZYgrMiYMbt3wCKRIiXePwILv8USDG95YgP0PzhIxSIROLLKmiQQ/Z6LuhDGWTHK04gnbXBvkg== + +eslint-scope@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9" + integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint-utils@^1.3.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.0.tgz#e2c3c8dba768425f897cf0f9e51fe2e241485d4c" + integrity sha512-7ehnzPaP5IIEh1r1tkjuIrxqhNkzUJa9z3R92tLJdZIVdWaczEhr3EbhGtsMrVxi1KeR8qA7Off6SWc5WNQqyQ== + dependencies: + eslint-visitor-keys "^1.0.0" + +eslint-visitor-keys@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" + integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== + +eslint@6: + version "6.1.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-6.1.0.tgz#06438a4a278b1d84fb107d24eaaa35471986e646" + integrity sha512-QhrbdRD7ofuV09IuE2ySWBz0FyXCq0rriLTZXZqaWSI79CVtHVRdkFuFTViiqzZhkCgfOh9USpriuGN2gIpZDQ== + dependencies: + "@babel/code-frame" "^7.0.0" + ajv "^6.10.0" + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^4.0.1" + doctrine "^3.0.0" + eslint-scope "^5.0.0" + eslint-utils "^1.3.1" + eslint-visitor-keys "^1.0.0" + espree "^6.0.0" + esquery "^1.0.1" + esutils "^2.0.2" + file-entry-cache "^5.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.0.0" + globals "^11.7.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + inquirer "^6.4.1" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.14" + minimatch "^3.0.4" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + progress "^2.0.0" + regexpp "^2.0.1" + semver "^6.1.2" + strip-ansi "^5.2.0" + strip-json-comments "^3.0.1" + table "^5.2.3" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + +esm@3: + version "3.2.25" + resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" + integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== + +espree@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-6.0.0.tgz#716fc1f5a245ef5b9a7fdb1d7b0d3f02322e75f6" + integrity sha512-lJvCS6YbCn3ImT3yKkPe0+tJ+mH6ljhGNjHQH9mRtiO6gjhVAOhVXW1yjnwqGwTkK3bGbye+hb00nFNmu0l/1Q== + dependencies: + acorn "^6.0.7" + acorn-jsx "^5.0.0" + eslint-visitor-keys "^1.0.0" + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esquery@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.1.tgz#406c51658b1f5991a5f9b62b1dc25b00e3e5c708" + integrity sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA== + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + integrity sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ== + dependencies: + estraverse "^4.1.0" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + +estree-walker@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" + integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk= + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I= + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + integrity sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI= + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-5.0.1.tgz#ca0f6efa6dd3d561333fb14515065c2fafdf439c" + integrity sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g== + dependencies: + flat-cache "^2.0.1" + +flat-cache@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-2.0.1.tgz#5d296d6f04bda44a4630a301413bdbc2ec085ec0" + integrity sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA== + dependencies: + flatted "^2.0.0" + rimraf "2.6.3" + write "1.0.3" + +flatted@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-2.0.1.tgz#69e57caa8f0eacbc281d2e2cb458d46fdb449e08" + integrity sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg== + +for-each@~0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +function-bind@^1.0.2, function-bind@^1.1.1, function-bind@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= + +glob-parent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.0.0.tgz#1dc99f0f39b006d3e92c2c284068382f0c20e954" + integrity sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg== + dependencies: + is-glob "^4.0.1" + +glob@^7.1.3, glob@~7.1.4: + version "7.1.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" + integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.7.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" + integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= + +has@^1.0.1, has@^1.0.3, has@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +iconv-lite@^0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +import-fresh@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.1.0.tgz#6d33fa1dcef6df930fae003446f33415af905118" + integrity sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@~2.0.3, inherits@~2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +inquirer@^6.4.1: + version "6.5.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.0.tgz#2303317efc9a4ea7ec2e2df6f86569b734accf42" + integrity sha512-scfHejeG/lVZSpvCXpsB4j/wQNPM5JC8kiElOI0OUTwmc1RTpXr4H32/HOlQHcZiYl2z2VElwuCVDRG8vFmbnA== + dependencies: + ansi-escapes "^3.2.0" + chalk "^2.4.2" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^3.0.3" + figures "^2.0.0" + lodash "^4.17.12" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^6.4.0" + string-width "^2.1.0" + strip-ansi "^5.1.0" + through "^2.3.6" + +is-callable@^1.1.3, is-callable@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + integrity sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY= + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-glob@^4.0.0, is-glob@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" + integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== + dependencies: + is-extglob "^2.1.1" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= + dependencies: + has "^1.0.1" + +is-symbol@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.2.tgz#a055f6ae57192caee329e7a860118b497a950f38" + integrity sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw== + dependencies: + has-symbols "^1.0.0" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +jest-worker@^24.6.0: + version "24.6.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-24.6.0.tgz#7f81ceae34b7cde0c9827a6980c35b7cdc0161b3" + integrity sha512-jDwgW5W9qGNvpI1tNnvajh0a5IE/PuGLFmHk6aR/BZFz8tSgGw17GsDPXAJ6p91IvYDjOw8GpFbvvZGAK+DPQQ== + dependencies: + merge-stream "^1.0.1" + supports-color "^6.1.0" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^3.13.1: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE= + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4= + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lodash@^4.17.12, lodash@^4.17.14: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + +merge-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + integrity sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE= + dependencies: + readable-stream "^2.0.1" + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== + +minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +mkdirp@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +ms@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= + +nan@^2.10.0: + version "2.14.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" + integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= + +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + +object-inspect@~1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" + integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ== + +object-keys@^1.0.12: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + integrity sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ= + dependencies: + mimic-fn "^1.0.0" + +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + integrity sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q= + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= + +path-parse@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" + integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + +progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== + +readable-stream@^2.0.1: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +regexpp@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" + integrity sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw== + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve@~1.11.1: + version "1.11.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.1.tgz#ea10d8110376982fef578df8fc30b9ac30a07a3e" + integrity sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw== + dependencies: + path-parse "^1.0.6" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + integrity sha1-n37ih/gv0ybU/RYpI9YhKe7g368= + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +resumer@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/resumer/-/resumer-0.0.0.tgz#f1e8f461e4064ba39e82af3cdc2a8c893d076759" + integrity sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k= + dependencies: + through "~2.3.4" + +rimraf@2.6.3: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +rollup-plugin-terser@5: + version "5.1.1" + resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-5.1.1.tgz#e9d2545ec8d467f96ba99b9216d2285aad8d5b66" + integrity sha512-McIMCDEY8EU6Y839C09UopeRR56wXHGdvKKjlfiZG/GrP6wvZQ62u2ko/Xh1MNH2M9WDL+obAAHySljIZYCuPQ== + dependencies: + "@babel/code-frame" "^7.0.0" + jest-worker "^24.6.0" + rollup-pluginutils "^2.8.1" + serialize-javascript "^1.7.0" + terser "^4.1.0" + +rollup-pluginutils@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.1.tgz#8fa6dd0697344938ef26c2c09d2488ce9e33ce97" + integrity sha512-J5oAoysWar6GuZo0s+3bZ6sVZAC0pfqKz68De7ZgDi5z63jOVZn1uJL/+z1jeKHNbGII8kAyHF5q8LnxSX5lQg== + dependencies: + estree-walker "^0.6.1" + +rollup@1: + version "1.18.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.18.0.tgz#98ea36472523ed712e20c0e996fd051882f787e6" + integrity sha512-MBAWr6ectF948gW/bs/yfi0jW7DzwI8n0tEYG/ZMQutmK+blF/Oazyhg3oPqtScCGV8bzCtL9KzlzPtTriEOJA== + dependencies: + "@types/estree" "0.0.39" + "@types/node" "^12.6.3" + acorn "^6.2.0" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + integrity sha1-A3GrSuC91yDUFm19/aZP96RFpsA= + dependencies: + is-promise "^2.1.0" + +rxjs@^6.4.0: + version "6.5.2" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.2.tgz#2e35ce815cd46d84d02a209fb4e5921e051dbec7" + integrity sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg== + dependencies: + tslib "^1.9.0" + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +semver@^5.5.0: + version "5.7.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" + integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== + +semver@^6.1.2: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +serialize-javascript@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.7.0.tgz#d6e0dfb2a3832a8c94468e6eb1db97e55a192a65" + integrity sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA== + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha1-RKrGW2lbAzmJaMOfNj/uXer98eo= + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= + +signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +slice-ansi@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" + integrity sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ== + dependencies: + ansi-styles "^3.2.0" + astral-regex "^1.0.0" + is-fullwidth-code-point "^2.0.0" + +source-map-support@~0.5.12: + version "0.5.13" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" + integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +string-width@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string-width@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + +string.prototype.trim@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz#d04de2c89e137f4d7d206f086b5ed2fae6be8cea" + integrity sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo= + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.0" + function-bind "^1.0.2" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@^5.1.0, strip-ansi@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + +strip-json-comments@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" + integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + +table@^5.2.3: + version "5.4.5" + resolved "https://registry.yarnpkg.com/table/-/table-5.4.5.tgz#c8f4ea2d8fee08c0027fac27b0ec0a4fe01dfa42" + integrity sha512-oGa2Hl7CQjfoaogtrOHEJroOcYILTx7BZWLGsJIlzoWmB2zmguhNfPJZsWPKYek/MgCxfco54gEi31d1uN2hFA== + dependencies: + ajv "^6.10.2" + lodash "^4.17.14" + slice-ansi "^2.1.0" + string-width "^3.0.0" + +tape-await@0.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/tape-await/-/tape-await-0.1.2.tgz#41f99110a2bc4728732d8bc058278b2fbf3c0bec" + integrity sha512-Gt1bXilp9uRTVj+DecLDs37tP1XwGXfFzWVqQEfW7foO9TNacy+aN5TdT0Kv6LI5t/9l3iOE4nX2hr2SQ4+OSg== + +tape@4: + version "4.11.0" + resolved "https://registry.yarnpkg.com/tape/-/tape-4.11.0.tgz#63d41accd95e45a23a874473051c57fdbc58edc1" + integrity sha512-yixvDMX7q7JIs/omJSzSZrqulOV51EC9dK8dM0TzImTIkHWfe2/kFyL5v+d9C+SrCMaICk59ujsqFAVidDqDaA== + dependencies: + deep-equal "~1.0.1" + defined "~1.0.0" + for-each "~0.3.3" + function-bind "~1.1.1" + glob "~7.1.4" + has "~1.0.3" + inherits "~2.0.4" + minimist "~1.2.0" + object-inspect "~1.6.0" + resolve "~1.11.1" + resumer "~0.0.0" + string.prototype.trim "~1.1.2" + through "~2.3.8" + +terser@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.1.2.tgz#b2656c8a506f7ce805a3f300a2ff48db022fa391" + integrity sha512-jvNoEQSPXJdssFwqPSgWjsOrb+ELoE+ILpHPKXC83tIxOlh2U75F1KuB2luLD/3a6/7K3Vw5pDn+hvu0C4AzSw== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +through@^2.3.6, through@~2.3.4, through@~2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + +tslib@^1.9.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +uri-js@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + integrity sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ== + dependencies: + punycode "^2.1.0" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +v8-compile-cache@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" + integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== + +which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus= + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +write@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/write/-/write-1.0.3.tgz#0800e14523b923a387e415123c865616aae0f5c3" + integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== + dependencies: + mkdirp "^0.5.1" From 63d6c5a4bc9f6725b044089e23a1ecb0add288c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Tue, 3 Sep 2019 09:45:18 +0200 Subject: [PATCH 13/18] merge canvas test --- package.json | 3 ++- yarn.lock | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index abeff4b..20ee78c 100644 --- a/package.json +++ b/package.json @@ -30,10 +30,11 @@ "scripts": { "pretest": "rollup -c", "test": "tape 'test/**/*-test.js' && eslint src test", - "prepublishOnly": "rm -rf dist && yarn test", + "prepublishOnly": "rm -rf dist && yarn test && mkdir -p test/output && test/compare-images", "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 - && zip -j dist/${npm_package_name}.zip -- LICENSE README.md dist/${npm_package_name}.js dist/${npm_package_name}.min.js" }, "devDependencies": { + "canvas": "1", "eslint": "6", "rollup": "1", "rollup-plugin-terser": "5", diff --git a/yarn.lock b/yarn.lock index 3d787f2..34457ef 100644 --- a/yarn.lock +++ b/yarn.lock @@ -105,6 +105,13 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== +canvas@1: + version "1.6.13" + resolved "https://registry.yarnpkg.com/canvas/-/canvas-1.6.13.tgz#8cb4e9abbea9e615a377890ffac50277a1167c73" + integrity sha512-XAfzfEOHZ3JIPjEV+WSI6PpISgUta3dgmndWbsajotz+0TQOX/jDpp2kawjRERatOGv9sMMzk5auB3GKEKA6hg== + dependencies: + nan "^2.10.0" + chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -652,6 +659,11 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= +nan@^2.10.0: + version "2.14.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" + integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" From 0a670782e6805553b9b67ad10019f1a279ea3197 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Thu, 26 Sep 2019 15:03:47 +0200 Subject: [PATCH 14/18] ignore test/output --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 8abcf6a..5780f71 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ dist/ node_modules npm-debug.log +test/output From 760375bd07726e3410c332e30e168a66ceb220f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Thu, 26 Sep 2019 15:04:48 +0200 Subject: [PATCH 15/18] avoid the awkward unbinned/re-binning method of #17 (see https://github.com/d3/d3-hexbin/pull/17#issuecomment-527757594) --- src/hexbin.js | 40 ++++++++++++---------------------------- test/hexbin-test.js | 4 ++-- 2 files changed, 14 insertions(+), 30 deletions(-) diff --git a/src/hexbin.js b/src/hexbin.js index 913ba95..4da89fe 100644 --- a/src/hexbin.js +++ b/src/hexbin.js @@ -26,9 +26,7 @@ export default function() { sa = 0, context = null, binsById = {}, - bins = [], - unbinned = [], - dirty = false; + bins = []; // from pixels to grid function transform(x, y) { @@ -48,20 +46,8 @@ export default function() { if (points) { binsById = {}; bins.splice(0, bins.length); - unbinned.splice(0, unbinned.length); addAll(points); - } else if (dirty) { - bins.forEach(function(bin) { - bin.forEach(function(d) { - unbinned.push(d); - }); - }); - binsById = {}; - bins.splice(0, bins.length); } - addAll(unbinned); - unbinned.splice(0, unbinned.length); - dirty = false; return bins; } @@ -117,7 +103,6 @@ export default function() { if (isNaN(px = +x.call(null, point)) || isNaN(py = +y.call(null, point))) return; var b = getBin(px, py), id = b[0] + "-" + b[1], bin = binsById[id]; - removeFromBin(point, unbinned); if (bin) { removeFromBin(point, bin); if (bin.length == 0) { @@ -201,23 +186,23 @@ export default function() { }; hexbin.angle = function(_) { - return arguments.length ? (angle = _, ca = Math.cos(angle * Math.PI/180), sa = Math.sin(angle * Math.PI/180), dirty = true, hexbin) : angle; + return arguments.length ? (angle = _, ca = Math.cos(angle * Math.PI/180), sa = Math.sin(angle * Math.PI/180), hexbin) : angle; }; hexbin.translate = function(_) { - return arguments.length ? (tx = _[0], ty = _[1], dirty = true, hexbin) : [tx, ty]; + return arguments.length ? (tx = _[0], ty = _[1], hexbin) : [tx, ty]; }; hexbin.x = function(_) { - return arguments.length ? (x = _, dirty = true, hexbin) : x; + return arguments.length ? (x = _, hexbin) : x; }; hexbin.y = function(_) { - return arguments.length ? (y = _, dirty = true, hexbin) : y; + return arguments.length ? (y = _, hexbin) : y; }; hexbin.radius = function(_) { - return arguments.length ? (r = +_, dx = r * 2 * Math.sin(thirdPi), dy = r * 1.5, dirty = true, hexbin) : r; + return arguments.length ? (r = +_, dx = r * 2 * Math.sin(thirdPi), dy = r * 1.5, hexbin) : r; }; hexbin.size = function(_) { @@ -247,16 +232,15 @@ export default function() { } hexbin.add = function(point) { - unbinned.push(point); - dirty = true; + var px, py; + if (!isNaN(px = +x.call(null, point, 0, [point])) + && !isNaN(py = +y.call(null, point, 0, [point]))) + addOne(point, px, py); return hexbin; } hexbin.addAll = function(points) { - points.forEach(function(point) { - unbinned.push(point); - }); - dirty = true; + points.forEach(hexbin.add); return hexbin; } @@ -266,7 +250,7 @@ export default function() { } hexbin.removeAll = function(points) { - for (var i = 0, l = points.length; i < l; i++) remove(points[i]); + points.forEach(remove); return hexbin; } diff --git a/test/hexbin-test.js b/test/hexbin-test.js index 67c0581..d8d2a27 100644 --- a/test/hexbin-test.js +++ b/test/hexbin-test.js @@ -199,7 +199,7 @@ tape("hexbin.remove() doesn't remove a point that isn't there", function(test) { test.end(); }); -tape("hexbin.removeAll() removes several points", function(test) { +tape("hexbin.removeAll() removes several points (method 1)", function(test) { var points = [[0,0], [1,1], [2,2]]; var hexbin = d3.hexbin(), expected = [[[2,2]]]; @@ -209,7 +209,7 @@ tape("hexbin.removeAll() removes several points", function(test) { test.end(); }); -tape("hexbin.removeAll() removes unbinned points", function(test) { +tape("hexbin.removeAll() removes several points (method 2)", function(test) { var points = [[0,0], [1,1], [2,2]]; var hexbin = d3.hexbin().addAll(points).removeAll(points.slice(0,2)), expected = [[[2,2]]]; From 21db5c890c119a7786a806f002ad306c29ce2c9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Wed, 20 Nov 2019 22:24:46 +0100 Subject: [PATCH 16/18] *hexbin*() accepts iterables --- src/hexbin.js | 5 +++-- test/hexbin-test.js | 31 +++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/hexbin.js b/src/hexbin.js index 4da89fe..c007261 100644 --- a/src/hexbin.js +++ b/src/hexbin.js @@ -82,6 +82,7 @@ export default function() { } function addAll(points) { + points = Array.from(points); var i, point, px, py, n = points.length; for (i = 0; i < n; ++i) { @@ -240,7 +241,7 @@ export default function() { } hexbin.addAll = function(points) { - points.forEach(hexbin.add); + Array.from(points).forEach(hexbin.add); return hexbin; } @@ -250,7 +251,7 @@ export default function() { } hexbin.removeAll = function(points) { - points.forEach(remove); + Array.from(points).forEach(remove); return hexbin; } diff --git a/test/hexbin-test.js b/test/hexbin-test.js index d8d2a27..d3bd170 100644 --- a/test/hexbin-test.js +++ b/test/hexbin-test.js @@ -34,6 +34,37 @@ tape("hexbin(points) bins the specified points into hexagonal bins", function(te test.end(); }); +tape("hexbin(points) accepts iterators", function(test) { + var bin = d3.hexbin(), + a = [0, 0], b = [0, 1], + bins = bin(new Set([ + a, b, [0, 2], + [1, 0], [1, 1], [1, 2], + [2, 0], [2, 1], [2, 2] + ])); + test.deepEqual(noxy(bins), [ + [[0, 0]], + [[0, 1], [0, 2], [1, 1], [1, 2]], + [[1, 0], [2, 0]], + [[2, 1], [2, 2]] + ]); + bin.removeAll(new Set([a, b])); + test.deepEqual(noxy(bins), [ + [[0, 2], [1, 1], [1, 2]], + [[1, 0], [2, 0]], + [[2, 1], [2, 2]] + ]); + bin.addAll(new Set([a, b])); + test.deepEqual(noxy(bins), [ + [[0, 2], [1, 1], [1, 2], [0, 1]], + [[1, 0], [2, 0]], + [[2, 1], [2, 2]], + [[0, 0]], + ]); + + test.end(); +}); + tape("hexbin(points) observes the current x- and y-accessors", function(test) { var x = function(d) { return d.x; }, y = function(d) { return d.y; }, From 3cf735eac7a698a58af9e34f2669c56ec9c3572a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Wed, 1 Jul 2020 23:33:48 +0200 Subject: [PATCH 17/18] compatibility with canvas 1-2 as in https://github.com/d3/d3-geo-polygon/pull/41 --- package.json | 2 +- test/render-canvas | 3 + yarn.lock | 503 ++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 456 insertions(+), 52 deletions(-) diff --git a/package.json b/package.json index 20ee78c..48dcc5f 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,7 @@ "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 - && zip -j dist/${npm_package_name}.zip -- LICENSE README.md dist/${npm_package_name}.js dist/${npm_package_name}.min.js" }, "devDependencies": { - "canvas": "1", + "canvas": "1 - 2", "eslint": "6", "rollup": "1", "rollup-plugin-terser": "5", diff --git a/test/render-canvas b/test/render-canvas index 68ef42b..b8e2d7c 100755 --- a/test/render-canvas +++ b/test/render-canvas @@ -5,6 +5,9 @@ var width = 960, Canvas = require("canvas"), d3 = require("../"); +// canvas@2 compatibility check +if (Canvas.Canvas) Canvas = Canvas.Canvas; + var canvas = new Canvas(width, height), context = canvas.getContext("2d"); diff --git a/yarn.lock b/yarn.lock index 34457ef..7aceab4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -28,6 +28,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-12.7.3.tgz#27b3f40addaf2f580459fdb405222685542f907a" integrity sha512-3SiLAIBkDWDg6vFo0+5YJyHPWU9uwu40Qe+v+0MH8wRKYBimHvvAOyk3EzMrD/TrIlLYfXrqDqrg913PynrMJQ== +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + acorn-jsx@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.2.tgz#84b68ea44b373c4f8686023a551f61a21b7c4a4f" @@ -53,6 +58,11 @@ ansi-escapes@^3.2.0: resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.2.0.tgz#8780b98ff9dbf5638152d1f1fe5c1d7b4442976b" integrity sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ== +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + ansi-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" @@ -70,6 +80,19 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + argparse@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -105,12 +128,14 @@ callsites@^3.0.0: resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -canvas@1: - version "1.6.13" - resolved "https://registry.yarnpkg.com/canvas/-/canvas-1.6.13.tgz#8cb4e9abbea9e615a377890ffac50277a1167c73" - integrity sha512-XAfzfEOHZ3JIPjEV+WSI6PpISgUta3dgmndWbsajotz+0TQOX/jDpp2kawjRERatOGv9sMMzk5auB3GKEKA6hg== +"canvas@1 - 2": + version "2.6.1" + resolved "https://registry.yarnpkg.com/canvas/-/canvas-2.6.1.tgz#0d087dd4d60f5a5a9efa202757270abea8bef89e" + integrity sha512-S98rKsPcuhfTcYbtF53UIJhcbgIAK533d1kJKMwsMwAIFgfd58MOyxRud3kktlzWiEkFliaJtvyZCBtud/XVEA== dependencies: - nan "^2.10.0" + nan "^2.14.0" + node-pre-gyp "^0.11.0" + simple-get "^3.0.3" chalk@^2.0.0, chalk@^2.1.0, chalk@^2.4.2: version "2.4.2" @@ -126,6 +151,11 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + cli-cursor@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" @@ -138,6 +168,11 @@ cli-width@^2.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" integrity sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk= +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + color-convert@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -160,6 +195,16 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -171,6 +216,13 @@ cross-spawn@^6.0.5: shebang-command "^1.2.0" which "^1.2.9" +debug@^3.2.6: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + debug@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" @@ -178,17 +230,29 @@ debug@^4.0.1: dependencies: ms "^2.1.1" +decompress-response@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-4.2.1.tgz#414023cc7a302da25ce2ec82d0d5238ccafd8986" + integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== + dependencies: + mimic-response "^2.0.0" + deep-equal@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + deep-is@~0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= -define-properties@^1.1.2: +define-properties@^1.1.2, define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" integrity sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ== @@ -200,6 +264,16 @@ defined@~1.0.0: resolved "https://registry.yarnpkg.com/defined/-/defined-1.0.0.tgz#c98d9bcef75674188e110969151199e39b1fa693" integrity sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM= +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + doctrine@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" @@ -212,26 +286,27 @@ emoji-regex@^7.0.1: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== -es-abstract@^1.5.0: - version "1.14.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.14.0.tgz#f59d9d44278ea8f90c8ff3de1552537c2fd739b4" - integrity sha512-lri42nNq1tIohUuwFBYEM3wKwcrcJa78jukGDdWsuaNxTtxBFGFkKUQ15nc9J+ipje4mhbQR6JwABb4VvawR3A== +es-abstract@^1.17.5, es-abstract@^1.5.0: + version "1.17.6" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" + integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== dependencies: - es-to-primitive "^1.2.0" + es-to-primitive "^1.2.1" function-bind "^1.1.1" has "^1.0.3" - has-symbols "^1.0.0" - is-callable "^1.1.4" - is-regex "^1.0.4" - object-inspect "^1.6.0" + has-symbols "^1.0.1" + is-callable "^1.2.0" + is-regex "^1.1.0" + object-inspect "^1.7.0" object-keys "^1.1.1" - string.prototype.trimleft "^2.0.0" - string.prototype.trimright "^2.0.0" + object.assign "^4.1.0" + string.prototype.trimend "^1.0.1" + string.prototype.trimstart "^1.0.1" -es-to-primitive@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.0.tgz#edf72478033456e8dda8ef09e00ad9650707f377" - integrity sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg== +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== dependencies: is-callable "^1.1.4" is-date-object "^1.0.1" @@ -407,6 +482,13 @@ for-each@~0.3.3: dependencies: is-callable "^1.1.3" +fs-minipass@^1.2.5: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" + integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== + dependencies: + minipass "^2.6.0" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -422,6 +504,20 @@ functional-red-black-tree@^1.0.1: resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc= +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + glob-parent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.0.0.tgz#1dc99f0f39b006d3e92c2c284068382f0c20e954" @@ -456,20 +552,37 @@ has-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.0.tgz#ba1a8f1af2a0fc39650f5c850367704122063b44" integrity sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q= -has@^1.0.1, has@^1.0.3, has@~1.0.3: +has-symbols@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.1.tgz#9f5214758a44196c406d9bd76cebf81ec2dd31e8" + integrity sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg== + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has@^1.0.3, has@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: function-bind "^1.1.1" -iconv-lite@^0.4.24: +iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== dependencies: safer-buffer ">= 2.1.2 < 3" +ignore-walk@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37" + integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw== + dependencies: + minimatch "^3.0.4" + ignore@^4.0.6: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" @@ -496,11 +609,16 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@~2.0.4: +inherits@2, inherits@~2.0.3, inherits@~2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + inquirer@^6.4.1: version "6.5.2" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca" @@ -525,6 +643,11 @@ is-callable@^1.1.3, is-callable@^1.1.4: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" integrity sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA== +is-callable@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" + integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw== + is-date-object@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" @@ -535,6 +658,13 @@ is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" @@ -552,12 +682,12 @@ is-promise@^2.1.0: resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" integrity sha1-eaKp7OfwlugPNtKy87wWwf9L8/o= -is-regex@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" - integrity sha1-VRdIm1RwkbCTDglWVM7SXul+lJE= +is-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff" + integrity sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw== dependencies: - has "^1.0.1" + has-symbols "^1.0.1" is-symbol@^1.0.2: version "1.0.2" @@ -566,6 +696,11 @@ is-symbol@^1.0.2: dependencies: has-symbols "^1.0.0" +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -625,6 +760,11 @@ mimic-fn@^1.0.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== +mimic-response@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43" + integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== + minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" @@ -637,11 +777,38 @@ minimist@0.0.8: resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= +minimist@^1.2.0, minimist@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" + integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== + minimist@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= +minipass@^2.6.0, minipass@^2.8.6, minipass@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" + integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.2.1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" + integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== + dependencies: + minipass "^2.9.0" + +mkdirp@^0.5.0: + version "0.5.5" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" + integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== + dependencies: + minimist "^1.2.5" + mkdirp@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" @@ -659,32 +826,121 @@ mute-stream@0.0.7: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" integrity sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s= -nan@^2.10.0: - version "2.14.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.0.tgz#7818f722027b2459a86f0295d434d1fc2336c52c" - integrity sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg== +nan@^2.14.0: + version "2.14.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01" + integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw== natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +needle@^2.2.1: + version "2.5.0" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.5.0.tgz#e6fc4b3cc6c25caed7554bd613a5cf0bac8c31c0" + integrity sha512-o/qITSDR0JCyCKEQ1/1bnUXMmznxabbwi/Y4WwJElf+evwJNFNwIDMCCt5IigFVxgeGBJESLohGtIS9gEzo1fA== + dependencies: + debug "^3.2.6" + iconv-lite "^0.4.4" + sax "^1.2.4" + nice-try@^1.0.4: version "1.0.5" resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== -object-inspect@^1.6.0, object-inspect@~1.6.0: +node-pre-gyp@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.11.0.tgz#db1f33215272f692cd38f03238e3e9b47c5dd054" + integrity sha512-TwWAOZb0j7e9eGaf9esRx3ZcLaE5tQ2lvYy1pb5IAaG1a2e2Kv5Lms1Y4hpj+ciXJRofIxxlt5haeQ/2ANeE0Q== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +nopt@^4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" + integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg== + dependencies: + abbrev "1" + osenv "^0.1.4" + +npm-bundled@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b" + integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA== + dependencies: + npm-normalize-package-bin "^1.0.1" + +npm-normalize-package-bin@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" + integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== + +npm-packlist@^1.1.6: + version "1.4.8" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e" + integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + npm-normalize-package-bin "^1.0.1" + +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-inspect@^1.7.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" + integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== + +object-inspect@~1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.6.0.tgz#c70b6cbf72f274aab4c34c0c82f5167bf82cf15b" integrity sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ== -object-keys@^1.0.12, object-keys@^1.1.1: +object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -once@^1.3.0: +object.assign@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" + integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== + dependencies: + define-properties "^1.1.2" + function-bind "^1.1.1" + has-symbols "^1.0.0" + object-keys "^1.0.11" + +once@^1.3.0, once@^1.3.1: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -710,11 +966,24 @@ optionator@^0.8.2: type-check "~0.3.2" wordwrap "~1.0.0" -os-tmpdir@~1.0.2: +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-tmpdir@^1.0.0, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -742,6 +1011,11 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= +process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + progress@^2.0.0: version "2.0.3" resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" @@ -752,6 +1026,29 @@ punycode@^2.1.0: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +readable-stream@^2.0.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" + integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + regexpp@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-2.0.1.tgz#8d19d31cf632482b589049f8281f93dbcba4d07f" @@ -791,6 +1088,13 @@ rimraf@2.6.3: dependencies: glob "^7.1.3" +rimraf@^2.6.1: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + rollup-plugin-terser@5: version "5.1.1" resolved "https://registry.yarnpkg.com/rollup-plugin-terser/-/rollup-plugin-terser-5.1.1.tgz#e9d2545ec8d467f96ba99b9216d2285aad8d5b66" @@ -832,12 +1136,27 @@ rxjs@^6.4.0: dependencies: tslib "^1.9.0" +safe-buffer@^5.1.2: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + "safer-buffer@>= 2.1.2 < 3": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -semver@^5.5.0: +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +semver@^5.3.0, semver@^5.5.0: version "5.7.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== @@ -852,6 +1171,11 @@ serialize-javascript@^1.7.0: resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.9.0.tgz#5b77019d7c3b85fe91b33ae424c53dcbfb6618bd" integrity sha512-UkGlcYMtw4d9w7YfCtJFgdRTps8N4L0A48R+SmcGL57ki1+yHwJXnalk5bjgrw+ljv6SfzjzPjhohod2qllg/Q== +set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -864,11 +1188,30 @@ shebang-regex@^1.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= +signal-exit@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c" + integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA== + signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= +simple-concat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.0.tgz#7344cbb8b6e26fb27d66b2fc86f9f6d5997521c6" + integrity sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY= + +simple-get@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-3.1.0.tgz#b45be062435e50d159540b576202ceec40b9c6b3" + integrity sha512-bCR6cP+aTdScaQCnQKbPKtJOKDp/hj9EDLJo3Nw4y1QksqaovlW/bnptB6/c1e+qmNIDHRK+oXFDdEqBT8WzUA== + dependencies: + decompress-response "^4.2.0" + once "^1.3.1" + simple-concat "^1.0.0" + slice-ansi@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-2.1.0.tgz#cacd7693461a637a5788d92a7dd4fba068e81636" @@ -896,7 +1239,16 @@ sprintf-js@~1.0.2: resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= -string-width@^2.1.0: +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -922,21 +1274,35 @@ string.prototype.trim@~1.1.2: es-abstract "^1.5.0" function-bind "^1.0.2" -string.prototype.trimleft@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.0.0.tgz#68b6aa8e162c6a80e76e3a8a0c2e747186e271ff" - integrity sha1-aLaqjhYsaoDnbjqKDC50cYbicf8= +string.prototype.trimend@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" + integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== dependencies: - define-properties "^1.1.2" - function-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.17.5" -string.prototype.trimright@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.0.0.tgz#ab4a56d802a01fbe7293e11e84f24dc8164661dd" - integrity sha1-q0pW2AKgH75yk+EehPJNyBZGYd0= +string.prototype.trimstart@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" + integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== dependencies: - define-properties "^1.1.2" - function-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.17.5" + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" strip-ansi@^4.0.0: version "4.0.0" @@ -957,6 +1323,11 @@ strip-json-comments@^3.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" integrity sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw== +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -1000,6 +1371,19 @@ tape@4: string.prototype.trim "~1.1.2" through "~2.3.8" +tar@^4: + version "4.4.13" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525" + integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.8.6" + minizlib "^1.2.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.3" + terser@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/terser/-/terser-4.2.1.tgz#1052cfe17576c66e7bc70fcc7119f22b155bdac1" @@ -1045,6 +1429,11 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + v8-compile-cache@^2.0.3: version "2.1.0" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz#e14de37b31a6d194f5690d67efc4e7f6fc6ab30e" @@ -1057,6 +1446,13 @@ which@^1.2.9: dependencies: isexe "^2.0.0" +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" @@ -1073,3 +1469,8 @@ write@1.0.3: integrity sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig== dependencies: mkdirp "^0.5.1" + +yallist@^3.0.0, yallist@^3.0.3: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== From 7b7694242666a0ef39d3e56d9d3317c9b7d8b51c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Rivi=C3=A8re?= Date: Fri, 10 Jul 2020 19:22:26 +0200 Subject: [PATCH 18/18] link to v1 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index dd41fac..0a672f6 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Hexagonal binning is useful for aggregating data into a coarser representation f If you use NPM, `npm install d3-hexbin`. Otherwise, download the [latest release](https://github.com/d3/d3-hexbin/releases/latest). You can also load directly from [d3js.org](https://d3js.org), either as a [standalone library](https://d3js.org/d3-hexbin.v0.2.min.js). AMD, CommonJS, and vanilla environments are supported. In vanilla, a `d3_hexbin` global is exported: ```html - +