Index: node_modules/d3-geo/LICENSE
===================================================================
--- node_modules/d3-geo/LICENSE	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/LICENSE	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,34 @@
+Copyright 2010-2024 Mike Bostock
+
+Permission to use, copy, modify, and/or distribute this software for any purpose
+with or without fee is hereby granted, provided that the above copyright notice
+and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
+OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
+THIS SOFTWARE.
+
+This license applies to GeographicLib, versions 1.12 and later.
+
+Copyright 2008-2012 Charles Karney
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Index: node_modules/d3-geo/README.md
===================================================================
--- node_modules/d3-geo/README.md	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/README.md	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,12 @@
+# d3-geo
+
+<a href="https://d3js.org"><img src="https://github.com/d3/d3/raw/main/docs/public/logo.svg" width="256" height="256"></a>
+
+This module uses spherical [GeoJSON](http://geojson.org/geojson-spec.html) to represent geographic features in JavaScript. D3 supports a wide variety of common and [unusual](https://github.com/d3/d3-geo-projection) map projections. And because D3 uses spherical geometry to represent data, you can apply any aspect to any projection by rotating geometry.
+
+## Resources
+
+- [Documentation](https://d3js.org/d3-geo)
+- [Examples](https://observablehq.com/collection/@d3/d3-geo)
+- [Releases](https://github.com/d3/d3-geo/releases)
+- [Getting help](https://d3js.org/community)
Index: node_modules/d3-geo/dist/d3-geo.js
===================================================================
--- node_modules/d3-geo/dist/d3-geo.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/dist/d3-geo.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,3167 @@
+// https://d3js.org/d3-geo/ v3.1.1 Copyright 2010-2024 Mike Bostock, 2008-2012 Charles Karney
+(function (global, factory) {
+typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-array')) :
+typeof define === 'function' && define.amd ? define(['exports', 'd3-array'], factory) :
+(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.d3 = global.d3 || {}, global.d3));
+})(this, (function (exports, d3Array) { 'use strict';
+
+var epsilon = 1e-6;
+var epsilon2 = 1e-12;
+var pi = Math.PI;
+var halfPi = pi / 2;
+var quarterPi = pi / 4;
+var tau = pi * 2;
+
+var degrees = 180 / pi;
+var radians = pi / 180;
+
+var abs = Math.abs;
+var atan = Math.atan;
+var atan2 = Math.atan2;
+var cos = Math.cos;
+var ceil = Math.ceil;
+var exp = Math.exp;
+var hypot = Math.hypot;
+var log = Math.log;
+var pow = Math.pow;
+var sin = Math.sin;
+var sign = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; };
+var sqrt = Math.sqrt;
+var tan = Math.tan;
+
+function acos(x) {
+  return x > 1 ? 0 : x < -1 ? pi : Math.acos(x);
+}
+
+function asin(x) {
+  return x > 1 ? halfPi : x < -1 ? -halfPi : Math.asin(x);
+}
+
+function haversin(x) {
+  return (x = sin(x / 2)) * x;
+}
+
+function noop() {}
+
+function streamGeometry(geometry, stream) {
+  if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) {
+    streamGeometryType[geometry.type](geometry, stream);
+  }
+}
+
+var streamObjectType = {
+  Feature: function(object, stream) {
+    streamGeometry(object.geometry, stream);
+  },
+  FeatureCollection: function(object, stream) {
+    var features = object.features, i = -1, n = features.length;
+    while (++i < n) streamGeometry(features[i].geometry, stream);
+  }
+};
+
+var streamGeometryType = {
+  Sphere: function(object, stream) {
+    stream.sphere();
+  },
+  Point: function(object, stream) {
+    object = object.coordinates;
+    stream.point(object[0], object[1], object[2]);
+  },
+  MultiPoint: function(object, stream) {
+    var coordinates = object.coordinates, i = -1, n = coordinates.length;
+    while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]);
+  },
+  LineString: function(object, stream) {
+    streamLine(object.coordinates, stream, 0);
+  },
+  MultiLineString: function(object, stream) {
+    var coordinates = object.coordinates, i = -1, n = coordinates.length;
+    while (++i < n) streamLine(coordinates[i], stream, 0);
+  },
+  Polygon: function(object, stream) {
+    streamPolygon(object.coordinates, stream);
+  },
+  MultiPolygon: function(object, stream) {
+    var coordinates = object.coordinates, i = -1, n = coordinates.length;
+    while (++i < n) streamPolygon(coordinates[i], stream);
+  },
+  GeometryCollection: function(object, stream) {
+    var geometries = object.geometries, i = -1, n = geometries.length;
+    while (++i < n) streamGeometry(geometries[i], stream);
+  }
+};
+
+function streamLine(coordinates, stream, closed) {
+  var i = -1, n = coordinates.length - closed, coordinate;
+  stream.lineStart();
+  while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]);
+  stream.lineEnd();
+}
+
+function streamPolygon(coordinates, stream) {
+  var i = -1, n = coordinates.length;
+  stream.polygonStart();
+  while (++i < n) streamLine(coordinates[i], stream, 1);
+  stream.polygonEnd();
+}
+
+function geoStream(object, stream) {
+  if (object && streamObjectType.hasOwnProperty(object.type)) {
+    streamObjectType[object.type](object, stream);
+  } else {
+    streamGeometry(object, stream);
+  }
+}
+
+var areaRingSum$1 = new d3Array.Adder();
+
+// hello?
+
+var areaSum$1 = new d3Array.Adder(),
+    lambda00$2,
+    phi00$2,
+    lambda0$2,
+    cosPhi0$1,
+    sinPhi0$1;
+
+var areaStream$1 = {
+  point: noop,
+  lineStart: noop,
+  lineEnd: noop,
+  polygonStart: function() {
+    areaRingSum$1 = new d3Array.Adder();
+    areaStream$1.lineStart = areaRingStart$1;
+    areaStream$1.lineEnd = areaRingEnd$1;
+  },
+  polygonEnd: function() {
+    var areaRing = +areaRingSum$1;
+    areaSum$1.add(areaRing < 0 ? tau + areaRing : areaRing);
+    this.lineStart = this.lineEnd = this.point = noop;
+  },
+  sphere: function() {
+    areaSum$1.add(tau);
+  }
+};
+
+function areaRingStart$1() {
+  areaStream$1.point = areaPointFirst$1;
+}
+
+function areaRingEnd$1() {
+  areaPoint$1(lambda00$2, phi00$2);
+}
+
+function areaPointFirst$1(lambda, phi) {
+  areaStream$1.point = areaPoint$1;
+  lambda00$2 = lambda, phi00$2 = phi;
+  lambda *= radians, phi *= radians;
+  lambda0$2 = lambda, cosPhi0$1 = cos(phi = phi / 2 + quarterPi), sinPhi0$1 = sin(phi);
+}
+
+function areaPoint$1(lambda, phi) {
+  lambda *= radians, phi *= radians;
+  phi = phi / 2 + quarterPi; // half the angular distance from south pole
+
+  // Spherical excess E for a spherical triangle with vertices: south pole,
+  // previous point, current point.  Uses a formula derived from Cagnoli’s
+  // theorem.  See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2).
+  var dLambda = lambda - lambda0$2,
+      sdLambda = dLambda >= 0 ? 1 : -1,
+      adLambda = sdLambda * dLambda,
+      cosPhi = cos(phi),
+      sinPhi = sin(phi),
+      k = sinPhi0$1 * sinPhi,
+      u = cosPhi0$1 * cosPhi + k * cos(adLambda),
+      v = k * sdLambda * sin(adLambda);
+  areaRingSum$1.add(atan2(v, u));
+
+  // Advance the previous points.
+  lambda0$2 = lambda, cosPhi0$1 = cosPhi, sinPhi0$1 = sinPhi;
+}
+
+function area(object) {
+  areaSum$1 = new d3Array.Adder();
+  geoStream(object, areaStream$1);
+  return areaSum$1 * 2;
+}
+
+function spherical(cartesian) {
+  return [atan2(cartesian[1], cartesian[0]), asin(cartesian[2])];
+}
+
+function cartesian(spherical) {
+  var lambda = spherical[0], phi = spherical[1], cosPhi = cos(phi);
+  return [cosPhi * cos(lambda), cosPhi * sin(lambda), sin(phi)];
+}
+
+function cartesianDot(a, b) {
+  return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
+}
+
+function cartesianCross(a, b) {
+  return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
+}
+
+// TODO return a
+function cartesianAddInPlace(a, b) {
+  a[0] += b[0], a[1] += b[1], a[2] += b[2];
+}
+
+function cartesianScale(vector, k) {
+  return [vector[0] * k, vector[1] * k, vector[2] * k];
+}
+
+// TODO return d
+function cartesianNormalizeInPlace(d) {
+  var l = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
+  d[0] /= l, d[1] /= l, d[2] /= l;
+}
+
+var lambda0$1, phi0, lambda1, phi1, // bounds
+    lambda2, // previous lambda-coordinate
+    lambda00$1, phi00$1, // first point
+    p0, // previous 3D point
+    deltaSum,
+    ranges,
+    range;
+
+var boundsStream$1 = {
+  point: boundsPoint$1,
+  lineStart: boundsLineStart,
+  lineEnd: boundsLineEnd,
+  polygonStart: function() {
+    boundsStream$1.point = boundsRingPoint;
+    boundsStream$1.lineStart = boundsRingStart;
+    boundsStream$1.lineEnd = boundsRingEnd;
+    deltaSum = new d3Array.Adder();
+    areaStream$1.polygonStart();
+  },
+  polygonEnd: function() {
+    areaStream$1.polygonEnd();
+    boundsStream$1.point = boundsPoint$1;
+    boundsStream$1.lineStart = boundsLineStart;
+    boundsStream$1.lineEnd = boundsLineEnd;
+    if (areaRingSum$1 < 0) lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90);
+    else if (deltaSum > epsilon) phi1 = 90;
+    else if (deltaSum < -epsilon) phi0 = -90;
+    range[0] = lambda0$1, range[1] = lambda1;
+  },
+  sphere: function() {
+    lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90);
+  }
+};
+
+function boundsPoint$1(lambda, phi) {
+  ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);
+  if (phi < phi0) phi0 = phi;
+  if (phi > phi1) phi1 = phi;
+}
+
+function linePoint(lambda, phi) {
+  var p = cartesian([lambda * radians, phi * radians]);
+  if (p0) {
+    var normal = cartesianCross(p0, p),
+        equatorial = [normal[1], -normal[0], 0],
+        inflection = cartesianCross(equatorial, normal);
+    cartesianNormalizeInPlace(inflection);
+    inflection = spherical(inflection);
+    var delta = lambda - lambda2,
+        sign = delta > 0 ? 1 : -1,
+        lambdai = inflection[0] * degrees * sign,
+        phii,
+        antimeridian = abs(delta) > 180;
+    if (antimeridian ^ (sign * lambda2 < lambdai && lambdai < sign * lambda)) {
+      phii = inflection[1] * degrees;
+      if (phii > phi1) phi1 = phii;
+    } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign * lambda2 < lambdai && lambdai < sign * lambda)) {
+      phii = -inflection[1] * degrees;
+      if (phii < phi0) phi0 = phii;
+    } else {
+      if (phi < phi0) phi0 = phi;
+      if (phi > phi1) phi1 = phi;
+    }
+    if (antimeridian) {
+      if (lambda < lambda2) {
+        if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
+      } else {
+        if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
+      }
+    } else {
+      if (lambda1 >= lambda0$1) {
+        if (lambda < lambda0$1) lambda0$1 = lambda;
+        if (lambda > lambda1) lambda1 = lambda;
+      } else {
+        if (lambda > lambda2) {
+          if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda;
+        } else {
+          if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda;
+        }
+      }
+    }
+  } else {
+    ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]);
+  }
+  if (phi < phi0) phi0 = phi;
+  if (phi > phi1) phi1 = phi;
+  p0 = p, lambda2 = lambda;
+}
+
+function boundsLineStart() {
+  boundsStream$1.point = linePoint;
+}
+
+function boundsLineEnd() {
+  range[0] = lambda0$1, range[1] = lambda1;
+  boundsStream$1.point = boundsPoint$1;
+  p0 = null;
+}
+
+function boundsRingPoint(lambda, phi) {
+  if (p0) {
+    var delta = lambda - lambda2;
+    deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta);
+  } else {
+    lambda00$1 = lambda, phi00$1 = phi;
+  }
+  areaStream$1.point(lambda, phi);
+  linePoint(lambda, phi);
+}
+
+function boundsRingStart() {
+  areaStream$1.lineStart();
+}
+
+function boundsRingEnd() {
+  boundsRingPoint(lambda00$1, phi00$1);
+  areaStream$1.lineEnd();
+  if (abs(deltaSum) > epsilon) lambda0$1 = -(lambda1 = 180);
+  range[0] = lambda0$1, range[1] = lambda1;
+  p0 = null;
+}
+
+// Finds the left-right distance between two longitudes.
+// This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want
+// the distance between ±180° to be 360°.
+function angle(lambda0, lambda1) {
+  return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1;
+}
+
+function rangeCompare(a, b) {
+  return a[0] - b[0];
+}
+
+function rangeContains(range, x) {
+  return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;
+}
+
+function bounds(feature) {
+  var i, n, a, b, merged, deltaMax, delta;
+
+  phi1 = lambda1 = -(lambda0$1 = phi0 = Infinity);
+  ranges = [];
+  geoStream(feature, boundsStream$1);
+
+  // First, sort ranges by their minimum longitudes.
+  if (n = ranges.length) {
+    ranges.sort(rangeCompare);
+
+    // Then, merge any ranges that overlap.
+    for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) {
+      b = ranges[i];
+      if (rangeContains(a, b[0]) || rangeContains(a, b[1])) {
+        if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1];
+        if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0];
+      } else {
+        merged.push(a = b);
+      }
+    }
+
+    // Finally, find the largest gap between the merged ranges.
+    // The final bounding box will be the inverse of this gap.
+    for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) {
+      b = merged[i];
+      if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0$1 = b[0], lambda1 = a[1];
+    }
+  }
+
+  ranges = range = null;
+
+  return lambda0$1 === Infinity || phi0 === Infinity
+      ? [[NaN, NaN], [NaN, NaN]]
+      : [[lambda0$1, phi0], [lambda1, phi1]];
+}
+
+var W0, W1,
+    X0$1, Y0$1, Z0$1,
+    X1$1, Y1$1, Z1$1,
+    X2$1, Y2$1, Z2$1,
+    lambda00, phi00, // first point
+    x0$4, y0$4, z0; // previous point
+
+var centroidStream$1 = {
+  sphere: noop,
+  point: centroidPoint$1,
+  lineStart: centroidLineStart$1,
+  lineEnd: centroidLineEnd$1,
+  polygonStart: function() {
+    centroidStream$1.lineStart = centroidRingStart$1;
+    centroidStream$1.lineEnd = centroidRingEnd$1;
+  },
+  polygonEnd: function() {
+    centroidStream$1.lineStart = centroidLineStart$1;
+    centroidStream$1.lineEnd = centroidLineEnd$1;
+  }
+};
+
+// Arithmetic mean of Cartesian vectors.
+function centroidPoint$1(lambda, phi) {
+  lambda *= radians, phi *= radians;
+  var cosPhi = cos(phi);
+  centroidPointCartesian(cosPhi * cos(lambda), cosPhi * sin(lambda), sin(phi));
+}
+
+function centroidPointCartesian(x, y, z) {
+  ++W0;
+  X0$1 += (x - X0$1) / W0;
+  Y0$1 += (y - Y0$1) / W0;
+  Z0$1 += (z - Z0$1) / W0;
+}
+
+function centroidLineStart$1() {
+  centroidStream$1.point = centroidLinePointFirst;
+}
+
+function centroidLinePointFirst(lambda, phi) {
+  lambda *= radians, phi *= radians;
+  var cosPhi = cos(phi);
+  x0$4 = cosPhi * cos(lambda);
+  y0$4 = cosPhi * sin(lambda);
+  z0 = sin(phi);
+  centroidStream$1.point = centroidLinePoint;
+  centroidPointCartesian(x0$4, y0$4, z0);
+}
+
+function centroidLinePoint(lambda, phi) {
+  lambda *= radians, phi *= radians;
+  var cosPhi = cos(phi),
+      x = cosPhi * cos(lambda),
+      y = cosPhi * sin(lambda),
+      z = sin(phi),
+      w = atan2(sqrt((w = y0$4 * z - z0 * y) * w + (w = z0 * x - x0$4 * z) * w + (w = x0$4 * y - y0$4 * x) * w), x0$4 * x + y0$4 * y + z0 * z);
+  W1 += w;
+  X1$1 += w * (x0$4 + (x0$4 = x));
+  Y1$1 += w * (y0$4 + (y0$4 = y));
+  Z1$1 += w * (z0 + (z0 = z));
+  centroidPointCartesian(x0$4, y0$4, z0);
+}
+
+function centroidLineEnd$1() {
+  centroidStream$1.point = centroidPoint$1;
+}
+
+// See J. E. Brock, The Inertia Tensor for a Spherical Triangle,
+// J. Applied Mechanics 42, 239 (1975).
+function centroidRingStart$1() {
+  centroidStream$1.point = centroidRingPointFirst;
+}
+
+function centroidRingEnd$1() {
+  centroidRingPoint(lambda00, phi00);
+  centroidStream$1.point = centroidPoint$1;
+}
+
+function centroidRingPointFirst(lambda, phi) {
+  lambda00 = lambda, phi00 = phi;
+  lambda *= radians, phi *= radians;
+  centroidStream$1.point = centroidRingPoint;
+  var cosPhi = cos(phi);
+  x0$4 = cosPhi * cos(lambda);
+  y0$4 = cosPhi * sin(lambda);
+  z0 = sin(phi);
+  centroidPointCartesian(x0$4, y0$4, z0);
+}
+
+function centroidRingPoint(lambda, phi) {
+  lambda *= radians, phi *= radians;
+  var cosPhi = cos(phi),
+      x = cosPhi * cos(lambda),
+      y = cosPhi * sin(lambda),
+      z = sin(phi),
+      cx = y0$4 * z - z0 * y,
+      cy = z0 * x - x0$4 * z,
+      cz = x0$4 * y - y0$4 * x,
+      m = hypot(cx, cy, cz),
+      w = asin(m), // line weight = angle
+      v = m && -w / m; // area weight multiplier
+  X2$1.add(v * cx);
+  Y2$1.add(v * cy);
+  Z2$1.add(v * cz);
+  W1 += w;
+  X1$1 += w * (x0$4 + (x0$4 = x));
+  Y1$1 += w * (y0$4 + (y0$4 = y));
+  Z1$1 += w * (z0 + (z0 = z));
+  centroidPointCartesian(x0$4, y0$4, z0);
+}
+
+function centroid(object) {
+  W0 = W1 =
+  X0$1 = Y0$1 = Z0$1 =
+  X1$1 = Y1$1 = Z1$1 = 0;
+  X2$1 = new d3Array.Adder();
+  Y2$1 = new d3Array.Adder();
+  Z2$1 = new d3Array.Adder();
+  geoStream(object, centroidStream$1);
+
+  var x = +X2$1,
+      y = +Y2$1,
+      z = +Z2$1,
+      m = hypot(x, y, z);
+
+  // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid.
+  if (m < epsilon2) {
+    x = X1$1, y = Y1$1, z = Z1$1;
+    // If the feature has zero length, fall back to arithmetic mean of point vectors.
+    if (W1 < epsilon) x = X0$1, y = Y0$1, z = Z0$1;
+    m = hypot(x, y, z);
+    // If the feature still has an undefined ccentroid, then return.
+    if (m < epsilon2) return [NaN, NaN];
+  }
+
+  return [atan2(y, x) * degrees, asin(z / m) * degrees];
+}
+
+function constant(x) {
+  return function() {
+    return x;
+  };
+}
+
+function compose(a, b) {
+
+  function compose(x, y) {
+    return x = a(x, y), b(x[0], x[1]);
+  }
+
+  if (a.invert && b.invert) compose.invert = function(x, y) {
+    return x = b.invert(x, y), x && a.invert(x[0], x[1]);
+  };
+
+  return compose;
+}
+
+function rotationIdentity(lambda, phi) {
+  if (abs(lambda) > pi) lambda -= Math.round(lambda / tau) * tau;
+  return [lambda, phi];
+}
+
+rotationIdentity.invert = rotationIdentity;
+
+function rotateRadians(deltaLambda, deltaPhi, deltaGamma) {
+  return (deltaLambda %= tau) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma))
+    : rotationLambda(deltaLambda))
+    : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma)
+    : rotationIdentity);
+}
+
+function forwardRotationLambda(deltaLambda) {
+  return function(lambda, phi) {
+    lambda += deltaLambda;
+    if (abs(lambda) > pi) lambda -= Math.round(lambda / tau) * tau;
+    return [lambda, phi];
+  };
+}
+
+function rotationLambda(deltaLambda) {
+  var rotation = forwardRotationLambda(deltaLambda);
+  rotation.invert = forwardRotationLambda(-deltaLambda);
+  return rotation;
+}
+
+function rotationPhiGamma(deltaPhi, deltaGamma) {
+  var cosDeltaPhi = cos(deltaPhi),
+      sinDeltaPhi = sin(deltaPhi),
+      cosDeltaGamma = cos(deltaGamma),
+      sinDeltaGamma = sin(deltaGamma);
+
+  function rotation(lambda, phi) {
+    var cosPhi = cos(phi),
+        x = cos(lambda) * cosPhi,
+        y = sin(lambda) * cosPhi,
+        z = sin(phi),
+        k = z * cosDeltaPhi + x * sinDeltaPhi;
+    return [
+      atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi),
+      asin(k * cosDeltaGamma + y * sinDeltaGamma)
+    ];
+  }
+
+  rotation.invert = function(lambda, phi) {
+    var cosPhi = cos(phi),
+        x = cos(lambda) * cosPhi,
+        y = sin(lambda) * cosPhi,
+        z = sin(phi),
+        k = z * cosDeltaGamma - y * sinDeltaGamma;
+    return [
+      atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi),
+      asin(k * cosDeltaPhi - x * sinDeltaPhi)
+    ];
+  };
+
+  return rotation;
+}
+
+function rotation(rotate) {
+  rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0);
+
+  function forward(coordinates) {
+    coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians);
+    return coordinates[0] *= degrees, coordinates[1] *= degrees, coordinates;
+  }
+
+  forward.invert = function(coordinates) {
+    coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians);
+    return coordinates[0] *= degrees, coordinates[1] *= degrees, coordinates;
+  };
+
+  return forward;
+}
+
+// Generates a circle centered at [0°, 0°], with a given radius and precision.
+function circleStream(stream, radius, delta, direction, t0, t1) {
+  if (!delta) return;
+  var cosRadius = cos(radius),
+      sinRadius = sin(radius),
+      step = direction * delta;
+  if (t0 == null) {
+    t0 = radius + direction * tau;
+    t1 = radius - step / 2;
+  } else {
+    t0 = circleRadius(cosRadius, t0);
+    t1 = circleRadius(cosRadius, t1);
+    if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau;
+  }
+  for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) {
+    point = spherical([cosRadius, -sinRadius * cos(t), -sinRadius * sin(t)]);
+    stream.point(point[0], point[1]);
+  }
+}
+
+// Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0].
+function circleRadius(cosRadius, point) {
+  point = cartesian(point), point[0] -= cosRadius;
+  cartesianNormalizeInPlace(point);
+  var radius = acos(-point[1]);
+  return ((-point[2] < 0 ? -radius : radius) + tau - epsilon) % tau;
+}
+
+function circle() {
+  var center = constant([0, 0]),
+      radius = constant(90),
+      precision = constant(2),
+      ring,
+      rotate,
+      stream = {point: point};
+
+  function point(x, y) {
+    ring.push(x = rotate(x, y));
+    x[0] *= degrees, x[1] *= degrees;
+  }
+
+  function circle() {
+    var c = center.apply(this, arguments),
+        r = radius.apply(this, arguments) * radians,
+        p = precision.apply(this, arguments) * radians;
+    ring = [];
+    rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert;
+    circleStream(stream, r, p, 1);
+    c = {type: "Polygon", coordinates: [ring]};
+    ring = rotate = null;
+    return c;
+  }
+
+  circle.center = function(_) {
+    return arguments.length ? (center = typeof _ === "function" ? _ : constant([+_[0], +_[1]]), circle) : center;
+  };
+
+  circle.radius = function(_) {
+    return arguments.length ? (radius = typeof _ === "function" ? _ : constant(+_), circle) : radius;
+  };
+
+  circle.precision = function(_) {
+    return arguments.length ? (precision = typeof _ === "function" ? _ : constant(+_), circle) : precision;
+  };
+
+  return circle;
+}
+
+function clipBuffer() {
+  var lines = [],
+      line;
+  return {
+    point: function(x, y, m) {
+      line.push([x, y, m]);
+    },
+    lineStart: function() {
+      lines.push(line = []);
+    },
+    lineEnd: noop,
+    rejoin: function() {
+      if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));
+    },
+    result: function() {
+      var result = lines;
+      lines = [];
+      line = null;
+      return result;
+    }
+  };
+}
+
+function pointEqual(a, b) {
+  return abs(a[0] - b[0]) < epsilon && abs(a[1] - b[1]) < epsilon;
+}
+
+function Intersection(point, points, other, entry) {
+  this.x = point;
+  this.z = points;
+  this.o = other; // another intersection
+  this.e = entry; // is an entry?
+  this.v = false; // visited
+  this.n = this.p = null; // next & previous
+}
+
+// A generalized polygon clipping algorithm: given a polygon that has been cut
+// into its visible line segments, and rejoins the segments by interpolating
+// along the clip edge.
+function clipRejoin(segments, compareIntersection, startInside, interpolate, stream) {
+  var subject = [],
+      clip = [],
+      i,
+      n;
+
+  segments.forEach(function(segment) {
+    if ((n = segment.length - 1) <= 0) return;
+    var n, p0 = segment[0], p1 = segment[n], x;
+
+    if (pointEqual(p0, p1)) {
+      if (!p0[2] && !p1[2]) {
+        stream.lineStart();
+        for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]);
+        stream.lineEnd();
+        return;
+      }
+      // handle degenerate cases by moving the point
+      p1[0] += 2 * epsilon;
+    }
+
+    subject.push(x = new Intersection(p0, segment, null, true));
+    clip.push(x.o = new Intersection(p0, null, x, false));
+    subject.push(x = new Intersection(p1, segment, null, false));
+    clip.push(x.o = new Intersection(p1, null, x, true));
+  });
+
+  if (!subject.length) return;
+
+  clip.sort(compareIntersection);
+  link(subject);
+  link(clip);
+
+  for (i = 0, n = clip.length; i < n; ++i) {
+    clip[i].e = startInside = !startInside;
+  }
+
+  var start = subject[0],
+      points,
+      point;
+
+  while (1) {
+    // Find first unvisited intersection.
+    var current = start,
+        isSubject = true;
+    while (current.v) if ((current = current.n) === start) return;
+    points = current.z;
+    stream.lineStart();
+    do {
+      current.v = current.o.v = true;
+      if (current.e) {
+        if (isSubject) {
+          for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]);
+        } else {
+          interpolate(current.x, current.n.x, 1, stream);
+        }
+        current = current.n;
+      } else {
+        if (isSubject) {
+          points = current.p.z;
+          for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]);
+        } else {
+          interpolate(current.x, current.p.x, -1, stream);
+        }
+        current = current.p;
+      }
+      current = current.o;
+      points = current.z;
+      isSubject = !isSubject;
+    } while (!current.v);
+    stream.lineEnd();
+  }
+}
+
+function link(array) {
+  if (!(n = array.length)) return;
+  var n,
+      i = 0,
+      a = array[0],
+      b;
+  while (++i < n) {
+    a.n = b = array[i];
+    b.p = a;
+    a = b;
+  }
+  a.n = b = array[0];
+  b.p = a;
+}
+
+function longitude(point) {
+  return abs(point[0]) <= pi ? point[0] : sign(point[0]) * ((abs(point[0]) + pi) % tau - pi);
+}
+
+function polygonContains(polygon, point) {
+  var lambda = longitude(point),
+      phi = point[1],
+      sinPhi = sin(phi),
+      normal = [sin(lambda), -cos(lambda), 0],
+      angle = 0,
+      winding = 0;
+
+  var sum = new d3Array.Adder();
+
+  if (sinPhi === 1) phi = halfPi + epsilon;
+  else if (sinPhi === -1) phi = -halfPi - epsilon;
+
+  for (var i = 0, n = polygon.length; i < n; ++i) {
+    if (!(m = (ring = polygon[i]).length)) continue;
+    var ring,
+        m,
+        point0 = ring[m - 1],
+        lambda0 = longitude(point0),
+        phi0 = point0[1] / 2 + quarterPi,
+        sinPhi0 = sin(phi0),
+        cosPhi0 = cos(phi0);
+
+    for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) {
+      var point1 = ring[j],
+          lambda1 = longitude(point1),
+          phi1 = point1[1] / 2 + quarterPi,
+          sinPhi1 = sin(phi1),
+          cosPhi1 = cos(phi1),
+          delta = lambda1 - lambda0,
+          sign = delta >= 0 ? 1 : -1,
+          absDelta = sign * delta,
+          antimeridian = absDelta > pi,
+          k = sinPhi0 * sinPhi1;
+
+      sum.add(atan2(k * sign * sin(absDelta), cosPhi0 * cosPhi1 + k * cos(absDelta)));
+      angle += antimeridian ? delta + sign * tau : delta;
+
+      // Are the longitudes either side of the point’s meridian (lambda),
+      // and are the latitudes smaller than the parallel (phi)?
+      if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) {
+        var arc = cartesianCross(cartesian(point0), cartesian(point1));
+        cartesianNormalizeInPlace(arc);
+        var intersection = cartesianCross(normal, arc);
+        cartesianNormalizeInPlace(intersection);
+        var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin(intersection[2]);
+        if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) {
+          winding += antimeridian ^ delta >= 0 ? 1 : -1;
+        }
+      }
+    }
+  }
+
+  // First, determine whether the South pole is inside or outside:
+  //
+  // It is inside if:
+  // * the polygon winds around it in a clockwise direction.
+  // * the polygon does not (cumulatively) wind around it, but has a negative
+  //   (counter-clockwise) area.
+  //
+  // Second, count the (signed) number of times a segment crosses a lambda
+  // from the point to the South pole.  If it is zero, then the point is the
+  // same side as the South pole.
+
+  return (angle < -epsilon || angle < epsilon && sum < -epsilon2) ^ (winding & 1);
+}
+
+function clip(pointVisible, clipLine, interpolate, start) {
+  return function(sink) {
+    var line = clipLine(sink),
+        ringBuffer = clipBuffer(),
+        ringSink = clipLine(ringBuffer),
+        polygonStarted = false,
+        polygon,
+        segments,
+        ring;
+
+    var clip = {
+      point: point,
+      lineStart: lineStart,
+      lineEnd: lineEnd,
+      polygonStart: function() {
+        clip.point = pointRing;
+        clip.lineStart = ringStart;
+        clip.lineEnd = ringEnd;
+        segments = [];
+        polygon = [];
+      },
+      polygonEnd: function() {
+        clip.point = point;
+        clip.lineStart = lineStart;
+        clip.lineEnd = lineEnd;
+        segments = d3Array.merge(segments);
+        var startInside = polygonContains(polygon, start);
+        if (segments.length) {
+          if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
+          clipRejoin(segments, compareIntersection, startInside, interpolate, sink);
+        } else if (startInside) {
+          if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
+          sink.lineStart();
+          interpolate(null, null, 1, sink);
+          sink.lineEnd();
+        }
+        if (polygonStarted) sink.polygonEnd(), polygonStarted = false;
+        segments = polygon = null;
+      },
+      sphere: function() {
+        sink.polygonStart();
+        sink.lineStart();
+        interpolate(null, null, 1, sink);
+        sink.lineEnd();
+        sink.polygonEnd();
+      }
+    };
+
+    function point(lambda, phi) {
+      if (pointVisible(lambda, phi)) sink.point(lambda, phi);
+    }
+
+    function pointLine(lambda, phi) {
+      line.point(lambda, phi);
+    }
+
+    function lineStart() {
+      clip.point = pointLine;
+      line.lineStart();
+    }
+
+    function lineEnd() {
+      clip.point = point;
+      line.lineEnd();
+    }
+
+    function pointRing(lambda, phi) {
+      ring.push([lambda, phi]);
+      ringSink.point(lambda, phi);
+    }
+
+    function ringStart() {
+      ringSink.lineStart();
+      ring = [];
+    }
+
+    function ringEnd() {
+      pointRing(ring[0][0], ring[0][1]);
+      ringSink.lineEnd();
+
+      var clean = ringSink.clean(),
+          ringSegments = ringBuffer.result(),
+          i, n = ringSegments.length, m,
+          segment,
+          point;
+
+      ring.pop();
+      polygon.push(ring);
+      ring = null;
+
+      if (!n) return;
+
+      // No intersections.
+      if (clean & 1) {
+        segment = ringSegments[0];
+        if ((m = segment.length - 1) > 0) {
+          if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
+          sink.lineStart();
+          for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]);
+          sink.lineEnd();
+        }
+        return;
+      }
+
+      // Rejoin connected segments.
+      // TODO reuse ringBuffer.rejoin()?
+      if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
+
+      segments.push(ringSegments.filter(validSegment));
+    }
+
+    return clip;
+  };
+}
+
+function validSegment(segment) {
+  return segment.length > 1;
+}
+
+// Intersections are sorted along the clip edge. For both antimeridian cutting
+// and circle clipping, the same comparison is used.
+function compareIntersection(a, b) {
+  return ((a = a.x)[0] < 0 ? a[1] - halfPi - epsilon : halfPi - a[1])
+       - ((b = b.x)[0] < 0 ? b[1] - halfPi - epsilon : halfPi - b[1]);
+}
+
+var clipAntimeridian = clip(
+  function() { return true; },
+  clipAntimeridianLine,
+  clipAntimeridianInterpolate,
+  [-pi, -halfPi]
+);
+
+// Takes a line and cuts into visible segments. Return values: 0 - there were
+// intersections or the line was empty; 1 - no intersections; 2 - there were
+// intersections, and the first and last segments should be rejoined.
+function clipAntimeridianLine(stream) {
+  var lambda0 = NaN,
+      phi0 = NaN,
+      sign0 = NaN,
+      clean; // no intersections
+
+  return {
+    lineStart: function() {
+      stream.lineStart();
+      clean = 1;
+    },
+    point: function(lambda1, phi1) {
+      var sign1 = lambda1 > 0 ? pi : -pi,
+          delta = abs(lambda1 - lambda0);
+      if (abs(delta - pi) < epsilon) { // line crosses a pole
+        stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi : -halfPi);
+        stream.point(sign0, phi0);
+        stream.lineEnd();
+        stream.lineStart();
+        stream.point(sign1, phi0);
+        stream.point(lambda1, phi0);
+        clean = 0;
+      } else if (sign0 !== sign1 && delta >= pi) { // line crosses antimeridian
+        if (abs(lambda0 - sign0) < epsilon) lambda0 -= sign0 * epsilon; // handle degeneracies
+        if (abs(lambda1 - sign1) < epsilon) lambda1 -= sign1 * epsilon;
+        phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1);
+        stream.point(sign0, phi0);
+        stream.lineEnd();
+        stream.lineStart();
+        stream.point(sign1, phi0);
+        clean = 0;
+      }
+      stream.point(lambda0 = lambda1, phi0 = phi1);
+      sign0 = sign1;
+    },
+    lineEnd: function() {
+      stream.lineEnd();
+      lambda0 = phi0 = NaN;
+    },
+    clean: function() {
+      return 2 - clean; // if intersections, rejoin first and last segments
+    }
+  };
+}
+
+function clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) {
+  var cosPhi0,
+      cosPhi1,
+      sinLambda0Lambda1 = sin(lambda0 - lambda1);
+  return abs(sinLambda0Lambda1) > epsilon
+      ? atan((sin(phi0) * (cosPhi1 = cos(phi1)) * sin(lambda1)
+          - sin(phi1) * (cosPhi0 = cos(phi0)) * sin(lambda0))
+          / (cosPhi0 * cosPhi1 * sinLambda0Lambda1))
+      : (phi0 + phi1) / 2;
+}
+
+function clipAntimeridianInterpolate(from, to, direction, stream) {
+  var phi;
+  if (from == null) {
+    phi = direction * halfPi;
+    stream.point(-pi, phi);
+    stream.point(0, phi);
+    stream.point(pi, phi);
+    stream.point(pi, 0);
+    stream.point(pi, -phi);
+    stream.point(0, -phi);
+    stream.point(-pi, -phi);
+    stream.point(-pi, 0);
+    stream.point(-pi, phi);
+  } else if (abs(from[0] - to[0]) > epsilon) {
+    var lambda = from[0] < to[0] ? pi : -pi;
+    phi = direction * lambda / 2;
+    stream.point(-lambda, phi);
+    stream.point(0, phi);
+    stream.point(lambda, phi);
+  } else {
+    stream.point(to[0], to[1]);
+  }
+}
+
+function clipCircle(radius) {
+  var cr = cos(radius),
+      delta = 2 * radians,
+      smallRadius = cr > 0,
+      notHemisphere = abs(cr) > epsilon; // TODO optimise for this common case
+
+  function interpolate(from, to, direction, stream) {
+    circleStream(stream, radius, delta, direction, from, to);
+  }
+
+  function visible(lambda, phi) {
+    return cos(lambda) * cos(phi) > cr;
+  }
+
+  // Takes a line and cuts into visible segments. Return values used for polygon
+  // clipping: 0 - there were intersections or the line was empty; 1 - no
+  // intersections 2 - there were intersections, and the first and last segments
+  // should be rejoined.
+  function clipLine(stream) {
+    var point0, // previous point
+        c0, // code for previous point
+        v0, // visibility of previous point
+        v00, // visibility of first point
+        clean; // no intersections
+    return {
+      lineStart: function() {
+        v00 = v0 = false;
+        clean = 1;
+      },
+      point: function(lambda, phi) {
+        var point1 = [lambda, phi],
+            point2,
+            v = visible(lambda, phi),
+            c = smallRadius
+              ? v ? 0 : code(lambda, phi)
+              : v ? code(lambda + (lambda < 0 ? pi : -pi), phi) : 0;
+        if (!point0 && (v00 = v0 = v)) stream.lineStart();
+        if (v !== v0) {
+          point2 = intersect(point0, point1);
+          if (!point2 || pointEqual(point0, point2) || pointEqual(point1, point2))
+            point1[2] = 1;
+        }
+        if (v !== v0) {
+          clean = 0;
+          if (v) {
+            // outside going in
+            stream.lineStart();
+            point2 = intersect(point1, point0);
+            stream.point(point2[0], point2[1]);
+          } else {
+            // inside going out
+            point2 = intersect(point0, point1);
+            stream.point(point2[0], point2[1], 2);
+            stream.lineEnd();
+          }
+          point0 = point2;
+        } else if (notHemisphere && point0 && smallRadius ^ v) {
+          var t;
+          // If the codes for two points are different, or are both zero,
+          // and there this segment intersects with the small circle.
+          if (!(c & c0) && (t = intersect(point1, point0, true))) {
+            clean = 0;
+            if (smallRadius) {
+              stream.lineStart();
+              stream.point(t[0][0], t[0][1]);
+              stream.point(t[1][0], t[1][1]);
+              stream.lineEnd();
+            } else {
+              stream.point(t[1][0], t[1][1]);
+              stream.lineEnd();
+              stream.lineStart();
+              stream.point(t[0][0], t[0][1], 3);
+            }
+          }
+        }
+        if (v && (!point0 || !pointEqual(point0, point1))) {
+          stream.point(point1[0], point1[1]);
+        }
+        point0 = point1, v0 = v, c0 = c;
+      },
+      lineEnd: function() {
+        if (v0) stream.lineEnd();
+        point0 = null;
+      },
+      // Rejoin first and last segments if there were intersections and the first
+      // and last points were visible.
+      clean: function() {
+        return clean | ((v00 && v0) << 1);
+      }
+    };
+  }
+
+  // Intersects the great circle between a and b with the clip circle.
+  function intersect(a, b, two) {
+    var pa = cartesian(a),
+        pb = cartesian(b);
+
+    // We have two planes, n1.p = d1 and n2.p = d2.
+    // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2).
+    var n1 = [1, 0, 0], // normal
+        n2 = cartesianCross(pa, pb),
+        n2n2 = cartesianDot(n2, n2),
+        n1n2 = n2[0], // cartesianDot(n1, n2),
+        determinant = n2n2 - n1n2 * n1n2;
+
+    // Two polar points.
+    if (!determinant) return !two && a;
+
+    var c1 =  cr * n2n2 / determinant,
+        c2 = -cr * n1n2 / determinant,
+        n1xn2 = cartesianCross(n1, n2),
+        A = cartesianScale(n1, c1),
+        B = cartesianScale(n2, c2);
+    cartesianAddInPlace(A, B);
+
+    // Solve |p(t)|^2 = 1.
+    var u = n1xn2,
+        w = cartesianDot(A, u),
+        uu = cartesianDot(u, u),
+        t2 = w * w - uu * (cartesianDot(A, A) - 1);
+
+    if (t2 < 0) return;
+
+    var t = sqrt(t2),
+        q = cartesianScale(u, (-w - t) / uu);
+    cartesianAddInPlace(q, A);
+    q = spherical(q);
+
+    if (!two) return q;
+
+    // Two intersection points.
+    var lambda0 = a[0],
+        lambda1 = b[0],
+        phi0 = a[1],
+        phi1 = b[1],
+        z;
+
+    if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z;
+
+    var delta = lambda1 - lambda0,
+        polar = abs(delta - pi) < epsilon,
+        meridian = polar || delta < epsilon;
+
+    if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z;
+
+    // Check that the first point is between a and b.
+    if (meridian
+        ? polar
+          ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon ? phi0 : phi1)
+          : phi0 <= q[1] && q[1] <= phi1
+        : delta > pi ^ (lambda0 <= q[0] && q[0] <= lambda1)) {
+      var q1 = cartesianScale(u, (-w + t) / uu);
+      cartesianAddInPlace(q1, A);
+      return [q, spherical(q1)];
+    }
+  }
+
+  // Generates a 4-bit vector representing the location of a point relative to
+  // the small circle's bounding box.
+  function code(lambda, phi) {
+    var r = smallRadius ? radius : pi - radius,
+        code = 0;
+    if (lambda < -r) code |= 1; // left
+    else if (lambda > r) code |= 2; // right
+    if (phi < -r) code |= 4; // below
+    else if (phi > r) code |= 8; // above
+    return code;
+  }
+
+  return clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi, radius - pi]);
+}
+
+function clipLine(a, b, x0, y0, x1, y1) {
+  var ax = a[0],
+      ay = a[1],
+      bx = b[0],
+      by = b[1],
+      t0 = 0,
+      t1 = 1,
+      dx = bx - ax,
+      dy = by - ay,
+      r;
+
+  r = x0 - ax;
+  if (!dx && r > 0) return;
+  r /= dx;
+  if (dx < 0) {
+    if (r < t0) return;
+    if (r < t1) t1 = r;
+  } else if (dx > 0) {
+    if (r > t1) return;
+    if (r > t0) t0 = r;
+  }
+
+  r = x1 - ax;
+  if (!dx && r < 0) return;
+  r /= dx;
+  if (dx < 0) {
+    if (r > t1) return;
+    if (r > t0) t0 = r;
+  } else if (dx > 0) {
+    if (r < t0) return;
+    if (r < t1) t1 = r;
+  }
+
+  r = y0 - ay;
+  if (!dy && r > 0) return;
+  r /= dy;
+  if (dy < 0) {
+    if (r < t0) return;
+    if (r < t1) t1 = r;
+  } else if (dy > 0) {
+    if (r > t1) return;
+    if (r > t0) t0 = r;
+  }
+
+  r = y1 - ay;
+  if (!dy && r < 0) return;
+  r /= dy;
+  if (dy < 0) {
+    if (r > t1) return;
+    if (r > t0) t0 = r;
+  } else if (dy > 0) {
+    if (r < t0) return;
+    if (r < t1) t1 = r;
+  }
+
+  if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy;
+  if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy;
+  return true;
+}
+
+var clipMax = 1e9, clipMin = -clipMax;
+
+// TODO Use d3-polygon’s polygonContains here for the ring check?
+// TODO Eliminate duplicate buffering in clipBuffer and polygon.push?
+
+function clipRectangle(x0, y0, x1, y1) {
+
+  function visible(x, y) {
+    return x0 <= x && x <= x1 && y0 <= y && y <= y1;
+  }
+
+  function interpolate(from, to, direction, stream) {
+    var a = 0, a1 = 0;
+    if (from == null
+        || (a = corner(from, direction)) !== (a1 = corner(to, direction))
+        || comparePoint(from, to) < 0 ^ direction > 0) {
+      do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);
+      while ((a = (a + direction + 4) % 4) !== a1);
+    } else {
+      stream.point(to[0], to[1]);
+    }
+  }
+
+  function corner(p, direction) {
+    return abs(p[0] - x0) < epsilon ? direction > 0 ? 0 : 3
+        : abs(p[0] - x1) < epsilon ? direction > 0 ? 2 : 1
+        : abs(p[1] - y0) < epsilon ? direction > 0 ? 1 : 0
+        : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon
+  }
+
+  function compareIntersection(a, b) {
+    return comparePoint(a.x, b.x);
+  }
+
+  function comparePoint(a, b) {
+    var ca = corner(a, 1),
+        cb = corner(b, 1);
+    return ca !== cb ? ca - cb
+        : ca === 0 ? b[1] - a[1]
+        : ca === 1 ? a[0] - b[0]
+        : ca === 2 ? a[1] - b[1]
+        : b[0] - a[0];
+  }
+
+  return function(stream) {
+    var activeStream = stream,
+        bufferStream = clipBuffer(),
+        segments,
+        polygon,
+        ring,
+        x__, y__, v__, // first point
+        x_, y_, v_, // previous point
+        first,
+        clean;
+
+    var clipStream = {
+      point: point,
+      lineStart: lineStart,
+      lineEnd: lineEnd,
+      polygonStart: polygonStart,
+      polygonEnd: polygonEnd
+    };
+
+    function point(x, y) {
+      if (visible(x, y)) activeStream.point(x, y);
+    }
+
+    function polygonInside() {
+      var winding = 0;
+
+      for (var i = 0, n = polygon.length; i < n; ++i) {
+        for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) {
+          a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1];
+          if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; }
+          else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; }
+        }
+      }
+
+      return winding;
+    }
+
+    // Buffer geometry within a polygon and then clip it en masse.
+    function polygonStart() {
+      activeStream = bufferStream, segments = [], polygon = [], clean = true;
+    }
+
+    function polygonEnd() {
+      var startInside = polygonInside(),
+          cleanInside = clean && startInside,
+          visible = (segments = d3Array.merge(segments)).length;
+      if (cleanInside || visible) {
+        stream.polygonStart();
+        if (cleanInside) {
+          stream.lineStart();
+          interpolate(null, null, 1, stream);
+          stream.lineEnd();
+        }
+        if (visible) {
+          clipRejoin(segments, compareIntersection, startInside, interpolate, stream);
+        }
+        stream.polygonEnd();
+      }
+      activeStream = stream, segments = polygon = ring = null;
+    }
+
+    function lineStart() {
+      clipStream.point = linePoint;
+      if (polygon) polygon.push(ring = []);
+      first = true;
+      v_ = false;
+      x_ = y_ = NaN;
+    }
+
+    // TODO rather than special-case polygons, simply handle them separately.
+    // Ideally, coincident intersection points should be jittered to avoid
+    // clipping issues.
+    function lineEnd() {
+      if (segments) {
+        linePoint(x__, y__);
+        if (v__ && v_) bufferStream.rejoin();
+        segments.push(bufferStream.result());
+      }
+      clipStream.point = point;
+      if (v_) activeStream.lineEnd();
+    }
+
+    function linePoint(x, y) {
+      var v = visible(x, y);
+      if (polygon) ring.push([x, y]);
+      if (first) {
+        x__ = x, y__ = y, v__ = v;
+        first = false;
+        if (v) {
+          activeStream.lineStart();
+          activeStream.point(x, y);
+        }
+      } else {
+        if (v && v_) activeStream.point(x, y);
+        else {
+          var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))],
+              b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))];
+          if (clipLine(a, b, x0, y0, x1, y1)) {
+            if (!v_) {
+              activeStream.lineStart();
+              activeStream.point(a[0], a[1]);
+            }
+            activeStream.point(b[0], b[1]);
+            if (!v) activeStream.lineEnd();
+            clean = false;
+          } else if (v) {
+            activeStream.lineStart();
+            activeStream.point(x, y);
+            clean = false;
+          }
+        }
+      }
+      x_ = x, y_ = y, v_ = v;
+    }
+
+    return clipStream;
+  };
+}
+
+function extent() {
+  var x0 = 0,
+      y0 = 0,
+      x1 = 960,
+      y1 = 500,
+      cache,
+      cacheStream,
+      clip;
+
+  return clip = {
+    stream: function(stream) {
+      return cache && cacheStream === stream ? cache : cache = clipRectangle(x0, y0, x1, y1)(cacheStream = stream);
+    },
+    extent: function(_) {
+      return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]];
+    }
+  };
+}
+
+var lengthSum$1,
+    lambda0,
+    sinPhi0,
+    cosPhi0;
+
+var lengthStream$1 = {
+  sphere: noop,
+  point: noop,
+  lineStart: lengthLineStart,
+  lineEnd: noop,
+  polygonStart: noop,
+  polygonEnd: noop
+};
+
+function lengthLineStart() {
+  lengthStream$1.point = lengthPointFirst$1;
+  lengthStream$1.lineEnd = lengthLineEnd;
+}
+
+function lengthLineEnd() {
+  lengthStream$1.point = lengthStream$1.lineEnd = noop;
+}
+
+function lengthPointFirst$1(lambda, phi) {
+  lambda *= radians, phi *= radians;
+  lambda0 = lambda, sinPhi0 = sin(phi), cosPhi0 = cos(phi);
+  lengthStream$1.point = lengthPoint$1;
+}
+
+function lengthPoint$1(lambda, phi) {
+  lambda *= radians, phi *= radians;
+  var sinPhi = sin(phi),
+      cosPhi = cos(phi),
+      delta = abs(lambda - lambda0),
+      cosDelta = cos(delta),
+      sinDelta = sin(delta),
+      x = cosPhi * sinDelta,
+      y = cosPhi0 * sinPhi - sinPhi0 * cosPhi * cosDelta,
+      z = sinPhi0 * sinPhi + cosPhi0 * cosPhi * cosDelta;
+  lengthSum$1.add(atan2(sqrt(x * x + y * y), z));
+  lambda0 = lambda, sinPhi0 = sinPhi, cosPhi0 = cosPhi;
+}
+
+function length(object) {
+  lengthSum$1 = new d3Array.Adder();
+  geoStream(object, lengthStream$1);
+  return +lengthSum$1;
+}
+
+var coordinates = [null, null],
+    object = {type: "LineString", coordinates: coordinates};
+
+function distance(a, b) {
+  coordinates[0] = a;
+  coordinates[1] = b;
+  return length(object);
+}
+
+var containsObjectType = {
+  Feature: function(object, point) {
+    return containsGeometry(object.geometry, point);
+  },
+  FeatureCollection: function(object, point) {
+    var features = object.features, i = -1, n = features.length;
+    while (++i < n) if (containsGeometry(features[i].geometry, point)) return true;
+    return false;
+  }
+};
+
+var containsGeometryType = {
+  Sphere: function() {
+    return true;
+  },
+  Point: function(object, point) {
+    return containsPoint(object.coordinates, point);
+  },
+  MultiPoint: function(object, point) {
+    var coordinates = object.coordinates, i = -1, n = coordinates.length;
+    while (++i < n) if (containsPoint(coordinates[i], point)) return true;
+    return false;
+  },
+  LineString: function(object, point) {
+    return containsLine(object.coordinates, point);
+  },
+  MultiLineString: function(object, point) {
+    var coordinates = object.coordinates, i = -1, n = coordinates.length;
+    while (++i < n) if (containsLine(coordinates[i], point)) return true;
+    return false;
+  },
+  Polygon: function(object, point) {
+    return containsPolygon(object.coordinates, point);
+  },
+  MultiPolygon: function(object, point) {
+    var coordinates = object.coordinates, i = -1, n = coordinates.length;
+    while (++i < n) if (containsPolygon(coordinates[i], point)) return true;
+    return false;
+  },
+  GeometryCollection: function(object, point) {
+    var geometries = object.geometries, i = -1, n = geometries.length;
+    while (++i < n) if (containsGeometry(geometries[i], point)) return true;
+    return false;
+  }
+};
+
+function containsGeometry(geometry, point) {
+  return geometry && containsGeometryType.hasOwnProperty(geometry.type)
+      ? containsGeometryType[geometry.type](geometry, point)
+      : false;
+}
+
+function containsPoint(coordinates, point) {
+  return distance(coordinates, point) === 0;
+}
+
+function containsLine(coordinates, point) {
+  var ao, bo, ab;
+  for (var i = 0, n = coordinates.length; i < n; i++) {
+    bo = distance(coordinates[i], point);
+    if (bo === 0) return true;
+    if (i > 0) {
+      ab = distance(coordinates[i], coordinates[i - 1]);
+      if (
+        ab > 0 &&
+        ao <= ab &&
+        bo <= ab &&
+        (ao + bo - ab) * (1 - Math.pow((ao - bo) / ab, 2)) < epsilon2 * ab
+      )
+        return true;
+    }
+    ao = bo;
+  }
+  return false;
+}
+
+function containsPolygon(coordinates, point) {
+  return !!polygonContains(coordinates.map(ringRadians), pointRadians(point));
+}
+
+function ringRadians(ring) {
+  return ring = ring.map(pointRadians), ring.pop(), ring;
+}
+
+function pointRadians(point) {
+  return [point[0] * radians, point[1] * radians];
+}
+
+function contains(object, point) {
+  return (object && containsObjectType.hasOwnProperty(object.type)
+      ? containsObjectType[object.type]
+      : containsGeometry)(object, point);
+}
+
+function graticuleX(y0, y1, dy) {
+  var y = d3Array.range(y0, y1 - epsilon, dy).concat(y1);
+  return function(x) { return y.map(function(y) { return [x, y]; }); };
+}
+
+function graticuleY(x0, x1, dx) {
+  var x = d3Array.range(x0, x1 - epsilon, dx).concat(x1);
+  return function(y) { return x.map(function(x) { return [x, y]; }); };
+}
+
+function graticule() {
+  var x1, x0, X1, X0,
+      y1, y0, Y1, Y0,
+      dx = 10, dy = dx, DX = 90, DY = 360,
+      x, y, X, Y,
+      precision = 2.5;
+
+  function graticule() {
+    return {type: "MultiLineString", coordinates: lines()};
+  }
+
+  function lines() {
+    return d3Array.range(ceil(X0 / DX) * DX, X1, DX).map(X)
+        .concat(d3Array.range(ceil(Y0 / DY) * DY, Y1, DY).map(Y))
+        .concat(d3Array.range(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon; }).map(x))
+        .concat(d3Array.range(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon; }).map(y));
+  }
+
+  graticule.lines = function() {
+    return lines().map(function(coordinates) { return {type: "LineString", coordinates: coordinates}; });
+  };
+
+  graticule.outline = function() {
+    return {
+      type: "Polygon",
+      coordinates: [
+        X(X0).concat(
+        Y(Y1).slice(1),
+        X(X1).reverse().slice(1),
+        Y(Y0).reverse().slice(1))
+      ]
+    };
+  };
+
+  graticule.extent = function(_) {
+    if (!arguments.length) return graticule.extentMinor();
+    return graticule.extentMajor(_).extentMinor(_);
+  };
+
+  graticule.extentMajor = function(_) {
+    if (!arguments.length) return [[X0, Y0], [X1, Y1]];
+    X0 = +_[0][0], X1 = +_[1][0];
+    Y0 = +_[0][1], Y1 = +_[1][1];
+    if (X0 > X1) _ = X0, X0 = X1, X1 = _;
+    if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _;
+    return graticule.precision(precision);
+  };
+
+  graticule.extentMinor = function(_) {
+    if (!arguments.length) return [[x0, y0], [x1, y1]];
+    x0 = +_[0][0], x1 = +_[1][0];
+    y0 = +_[0][1], y1 = +_[1][1];
+    if (x0 > x1) _ = x0, x0 = x1, x1 = _;
+    if (y0 > y1) _ = y0, y0 = y1, y1 = _;
+    return graticule.precision(precision);
+  };
+
+  graticule.step = function(_) {
+    if (!arguments.length) return graticule.stepMinor();
+    return graticule.stepMajor(_).stepMinor(_);
+  };
+
+  graticule.stepMajor = function(_) {
+    if (!arguments.length) return [DX, DY];
+    DX = +_[0], DY = +_[1];
+    return graticule;
+  };
+
+  graticule.stepMinor = function(_) {
+    if (!arguments.length) return [dx, dy];
+    dx = +_[0], dy = +_[1];
+    return graticule;
+  };
+
+  graticule.precision = function(_) {
+    if (!arguments.length) return precision;
+    precision = +_;
+    x = graticuleX(y0, y1, 90);
+    y = graticuleY(x0, x1, precision);
+    X = graticuleX(Y0, Y1, 90);
+    Y = graticuleY(X0, X1, precision);
+    return graticule;
+  };
+
+  return graticule
+      .extentMajor([[-180, -90 + epsilon], [180, 90 - epsilon]])
+      .extentMinor([[-180, -80 - epsilon], [180, 80 + epsilon]]);
+}
+
+function graticule10() {
+  return graticule()();
+}
+
+function interpolate(a, b) {
+  var x0 = a[0] * radians,
+      y0 = a[1] * radians,
+      x1 = b[0] * radians,
+      y1 = b[1] * radians,
+      cy0 = cos(y0),
+      sy0 = sin(y0),
+      cy1 = cos(y1),
+      sy1 = sin(y1),
+      kx0 = cy0 * cos(x0),
+      ky0 = cy0 * sin(x0),
+      kx1 = cy1 * cos(x1),
+      ky1 = cy1 * sin(x1),
+      d = 2 * asin(sqrt(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))),
+      k = sin(d);
+
+  var interpolate = d ? function(t) {
+    var B = sin(t *= d) / k,
+        A = sin(d - t) / k,
+        x = A * kx0 + B * kx1,
+        y = A * ky0 + B * ky1,
+        z = A * sy0 + B * sy1;
+    return [
+      atan2(y, x) * degrees,
+      atan2(z, sqrt(x * x + y * y)) * degrees
+    ];
+  } : function() {
+    return [x0 * degrees, y0 * degrees];
+  };
+
+  interpolate.distance = d;
+
+  return interpolate;
+}
+
+var identity$1 = x => x;
+
+var areaSum = new d3Array.Adder(),
+    areaRingSum = new d3Array.Adder(),
+    x00$2,
+    y00$2,
+    x0$3,
+    y0$3;
+
+var areaStream = {
+  point: noop,
+  lineStart: noop,
+  lineEnd: noop,
+  polygonStart: function() {
+    areaStream.lineStart = areaRingStart;
+    areaStream.lineEnd = areaRingEnd;
+  },
+  polygonEnd: function() {
+    areaStream.lineStart = areaStream.lineEnd = areaStream.point = noop;
+    areaSum.add(abs(areaRingSum));
+    areaRingSum = new d3Array.Adder();
+  },
+  result: function() {
+    var area = areaSum / 2;
+    areaSum = new d3Array.Adder();
+    return area;
+  }
+};
+
+function areaRingStart() {
+  areaStream.point = areaPointFirst;
+}
+
+function areaPointFirst(x, y) {
+  areaStream.point = areaPoint;
+  x00$2 = x0$3 = x, y00$2 = y0$3 = y;
+}
+
+function areaPoint(x, y) {
+  areaRingSum.add(y0$3 * x - x0$3 * y);
+  x0$3 = x, y0$3 = y;
+}
+
+function areaRingEnd() {
+  areaPoint(x00$2, y00$2);
+}
+
+var x0$2 = Infinity,
+    y0$2 = x0$2,
+    x1 = -x0$2,
+    y1 = x1;
+
+var boundsStream = {
+  point: boundsPoint,
+  lineStart: noop,
+  lineEnd: noop,
+  polygonStart: noop,
+  polygonEnd: noop,
+  result: function() {
+    var bounds = [[x0$2, y0$2], [x1, y1]];
+    x1 = y1 = -(y0$2 = x0$2 = Infinity);
+    return bounds;
+  }
+};
+
+function boundsPoint(x, y) {
+  if (x < x0$2) x0$2 = x;
+  if (x > x1) x1 = x;
+  if (y < y0$2) y0$2 = y;
+  if (y > y1) y1 = y;
+}
+
+// TODO Enforce positive area for exterior, negative area for interior?
+
+var X0 = 0,
+    Y0 = 0,
+    Z0 = 0,
+    X1 = 0,
+    Y1 = 0,
+    Z1 = 0,
+    X2 = 0,
+    Y2 = 0,
+    Z2 = 0,
+    x00$1,
+    y00$1,
+    x0$1,
+    y0$1;
+
+var centroidStream = {
+  point: centroidPoint,
+  lineStart: centroidLineStart,
+  lineEnd: centroidLineEnd,
+  polygonStart: function() {
+    centroidStream.lineStart = centroidRingStart;
+    centroidStream.lineEnd = centroidRingEnd;
+  },
+  polygonEnd: function() {
+    centroidStream.point = centroidPoint;
+    centroidStream.lineStart = centroidLineStart;
+    centroidStream.lineEnd = centroidLineEnd;
+  },
+  result: function() {
+    var centroid = Z2 ? [X2 / Z2, Y2 / Z2]
+        : Z1 ? [X1 / Z1, Y1 / Z1]
+        : Z0 ? [X0 / Z0, Y0 / Z0]
+        : [NaN, NaN];
+    X0 = Y0 = Z0 =
+    X1 = Y1 = Z1 =
+    X2 = Y2 = Z2 = 0;
+    return centroid;
+  }
+};
+
+function centroidPoint(x, y) {
+  X0 += x;
+  Y0 += y;
+  ++Z0;
+}
+
+function centroidLineStart() {
+  centroidStream.point = centroidPointFirstLine;
+}
+
+function centroidPointFirstLine(x, y) {
+  centroidStream.point = centroidPointLine;
+  centroidPoint(x0$1 = x, y0$1 = y);
+}
+
+function centroidPointLine(x, y) {
+  var dx = x - x0$1, dy = y - y0$1, z = sqrt(dx * dx + dy * dy);
+  X1 += z * (x0$1 + x) / 2;
+  Y1 += z * (y0$1 + y) / 2;
+  Z1 += z;
+  centroidPoint(x0$1 = x, y0$1 = y);
+}
+
+function centroidLineEnd() {
+  centroidStream.point = centroidPoint;
+}
+
+function centroidRingStart() {
+  centroidStream.point = centroidPointFirstRing;
+}
+
+function centroidRingEnd() {
+  centroidPointRing(x00$1, y00$1);
+}
+
+function centroidPointFirstRing(x, y) {
+  centroidStream.point = centroidPointRing;
+  centroidPoint(x00$1 = x0$1 = x, y00$1 = y0$1 = y);
+}
+
+function centroidPointRing(x, y) {
+  var dx = x - x0$1,
+      dy = y - y0$1,
+      z = sqrt(dx * dx + dy * dy);
+
+  X1 += z * (x0$1 + x) / 2;
+  Y1 += z * (y0$1 + y) / 2;
+  Z1 += z;
+
+  z = y0$1 * x - x0$1 * y;
+  X2 += z * (x0$1 + x);
+  Y2 += z * (y0$1 + y);
+  Z2 += z * 3;
+  centroidPoint(x0$1 = x, y0$1 = y);
+}
+
+function PathContext(context) {
+  this._context = context;
+}
+
+PathContext.prototype = {
+  _radius: 4.5,
+  pointRadius: function(_) {
+    return this._radius = _, this;
+  },
+  polygonStart: function() {
+    this._line = 0;
+  },
+  polygonEnd: function() {
+    this._line = NaN;
+  },
+  lineStart: function() {
+    this._point = 0;
+  },
+  lineEnd: function() {
+    if (this._line === 0) this._context.closePath();
+    this._point = NaN;
+  },
+  point: function(x, y) {
+    switch (this._point) {
+      case 0: {
+        this._context.moveTo(x, y);
+        this._point = 1;
+        break;
+      }
+      case 1: {
+        this._context.lineTo(x, y);
+        break;
+      }
+      default: {
+        this._context.moveTo(x + this._radius, y);
+        this._context.arc(x, y, this._radius, 0, tau);
+        break;
+      }
+    }
+  },
+  result: noop
+};
+
+var lengthSum = new d3Array.Adder(),
+    lengthRing,
+    x00,
+    y00,
+    x0,
+    y0;
+
+var lengthStream = {
+  point: noop,
+  lineStart: function() {
+    lengthStream.point = lengthPointFirst;
+  },
+  lineEnd: function() {
+    if (lengthRing) lengthPoint(x00, y00);
+    lengthStream.point = noop;
+  },
+  polygonStart: function() {
+    lengthRing = true;
+  },
+  polygonEnd: function() {
+    lengthRing = null;
+  },
+  result: function() {
+    var length = +lengthSum;
+    lengthSum = new d3Array.Adder();
+    return length;
+  }
+};
+
+function lengthPointFirst(x, y) {
+  lengthStream.point = lengthPoint;
+  x00 = x0 = x, y00 = y0 = y;
+}
+
+function lengthPoint(x, y) {
+  x0 -= x, y0 -= y;
+  lengthSum.add(sqrt(x0 * x0 + y0 * y0));
+  x0 = x, y0 = y;
+}
+
+// Simple caching for constant-radius points.
+let cacheDigits, cacheAppend, cacheRadius, cacheCircle;
+
+class PathString {
+  constructor(digits) {
+    this._append = digits == null ? append : appendRound(digits);
+    this._radius = 4.5;
+    this._ = "";
+  }
+  pointRadius(_) {
+    this._radius = +_;
+    return this;
+  }
+  polygonStart() {
+    this._line = 0;
+  }
+  polygonEnd() {
+    this._line = NaN;
+  }
+  lineStart() {
+    this._point = 0;
+  }
+  lineEnd() {
+    if (this._line === 0) this._ += "Z";
+    this._point = NaN;
+  }
+  point(x, y) {
+    switch (this._point) {
+      case 0: {
+        this._append`M${x},${y}`;
+        this._point = 1;
+        break;
+      }
+      case 1: {
+        this._append`L${x},${y}`;
+        break;
+      }
+      default: {
+        this._append`M${x},${y}`;
+        if (this._radius !== cacheRadius || this._append !== cacheAppend) {
+          const r = this._radius;
+          const s = this._;
+          this._ = ""; // stash the old string so we can cache the circle path fragment
+          this._append`m0,${r}a${r},${r} 0 1,1 0,${-2 * r}a${r},${r} 0 1,1 0,${2 * r}z`;
+          cacheRadius = r;
+          cacheAppend = this._append;
+          cacheCircle = this._;
+          this._ = s;
+        }
+        this._ += cacheCircle;
+        break;
+      }
+    }
+  }
+  result() {
+    const result = this._;
+    this._ = "";
+    return result.length ? result : null;
+  }
+}
+
+function append(strings) {
+  let i = 1;
+  this._ += strings[0];
+  for (const j = strings.length; i < j; ++i) {
+    this._ += arguments[i] + strings[i];
+  }
+}
+
+function appendRound(digits) {
+  const d = Math.floor(digits);
+  if (!(d >= 0)) throw new RangeError(`invalid digits: ${digits}`);
+  if (d > 15) return append;
+  if (d !== cacheDigits) {
+    const k = 10 ** d;
+    cacheDigits = d;
+    cacheAppend = function append(strings) {
+      let i = 1;
+      this._ += strings[0];
+      for (const j = strings.length; i < j; ++i) {
+        this._ += Math.round(arguments[i] * k) / k + strings[i];
+      }
+    };
+  }
+  return cacheAppend;
+}
+
+function index(projection, context) {
+  let digits = 3,
+      pointRadius = 4.5,
+      projectionStream,
+      contextStream;
+
+  function path(object) {
+    if (object) {
+      if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments));
+      geoStream(object, projectionStream(contextStream));
+    }
+    return contextStream.result();
+  }
+
+  path.area = function(object) {
+    geoStream(object, projectionStream(areaStream));
+    return areaStream.result();
+  };
+
+  path.measure = function(object) {
+    geoStream(object, projectionStream(lengthStream));
+    return lengthStream.result();
+  };
+
+  path.bounds = function(object) {
+    geoStream(object, projectionStream(boundsStream));
+    return boundsStream.result();
+  };
+
+  path.centroid = function(object) {
+    geoStream(object, projectionStream(centroidStream));
+    return centroidStream.result();
+  };
+
+  path.projection = function(_) {
+    if (!arguments.length) return projection;
+    projectionStream = _ == null ? (projection = null, identity$1) : (projection = _).stream;
+    return path;
+  };
+
+  path.context = function(_) {
+    if (!arguments.length) return context;
+    contextStream = _ == null ? (context = null, new PathString(digits)) : new PathContext(context = _);
+    if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius);
+    return path;
+  };
+
+  path.pointRadius = function(_) {
+    if (!arguments.length) return pointRadius;
+    pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_);
+    return path;
+  };
+
+  path.digits = function(_) {
+    if (!arguments.length) return digits;
+    if (_ == null) digits = null;
+    else {
+      const d = Math.floor(_);
+      if (!(d >= 0)) throw new RangeError(`invalid digits: ${_}`);
+      digits = d;
+    }
+    if (context === null) contextStream = new PathString(digits);
+    return path;
+  };
+
+  return path.projection(projection).digits(digits).context(context);
+}
+
+function transform(methods) {
+  return {
+    stream: transformer(methods)
+  };
+}
+
+function transformer(methods) {
+  return function(stream) {
+    var s = new TransformStream;
+    for (var key in methods) s[key] = methods[key];
+    s.stream = stream;
+    return s;
+  };
+}
+
+function TransformStream() {}
+
+TransformStream.prototype = {
+  constructor: TransformStream,
+  point: function(x, y) { this.stream.point(x, y); },
+  sphere: function() { this.stream.sphere(); },
+  lineStart: function() { this.stream.lineStart(); },
+  lineEnd: function() { this.stream.lineEnd(); },
+  polygonStart: function() { this.stream.polygonStart(); },
+  polygonEnd: function() { this.stream.polygonEnd(); }
+};
+
+function fit(projection, fitBounds, object) {
+  var clip = projection.clipExtent && projection.clipExtent();
+  projection.scale(150).translate([0, 0]);
+  if (clip != null) projection.clipExtent(null);
+  geoStream(object, projection.stream(boundsStream));
+  fitBounds(boundsStream.result());
+  if (clip != null) projection.clipExtent(clip);
+  return projection;
+}
+
+function fitExtent(projection, extent, object) {
+  return fit(projection, function(b) {
+    var w = extent[1][0] - extent[0][0],
+        h = extent[1][1] - extent[0][1],
+        k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])),
+        x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2,
+        y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2;
+    projection.scale(150 * k).translate([x, y]);
+  }, object);
+}
+
+function fitSize(projection, size, object) {
+  return fitExtent(projection, [[0, 0], size], object);
+}
+
+function fitWidth(projection, width, object) {
+  return fit(projection, function(b) {
+    var w = +width,
+        k = w / (b[1][0] - b[0][0]),
+        x = (w - k * (b[1][0] + b[0][0])) / 2,
+        y = -k * b[0][1];
+    projection.scale(150 * k).translate([x, y]);
+  }, object);
+}
+
+function fitHeight(projection, height, object) {
+  return fit(projection, function(b) {
+    var h = +height,
+        k = h / (b[1][1] - b[0][1]),
+        x = -k * b[0][0],
+        y = (h - k * (b[1][1] + b[0][1])) / 2;
+    projection.scale(150 * k).translate([x, y]);
+  }, object);
+}
+
+var maxDepth = 16, // maximum depth of subdivision
+    cosMinDistance = cos(30 * radians); // cos(minimum angular distance)
+
+function resample(project, delta2) {
+  return +delta2 ? resample$1(project, delta2) : resampleNone(project);
+}
+
+function resampleNone(project) {
+  return transformer({
+    point: function(x, y) {
+      x = project(x, y);
+      this.stream.point(x[0], x[1]);
+    }
+  });
+}
+
+function resample$1(project, delta2) {
+
+  function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) {
+    var dx = x1 - x0,
+        dy = y1 - y0,
+        d2 = dx * dx + dy * dy;
+    if (d2 > 4 * delta2 && depth--) {
+      var a = a0 + a1,
+          b = b0 + b1,
+          c = c0 + c1,
+          m = sqrt(a * a + b * b + c * c),
+          phi2 = asin(c /= m),
+          lambda2 = abs(abs(c) - 1) < epsilon || abs(lambda0 - lambda1) < epsilon ? (lambda0 + lambda1) / 2 : atan2(b, a),
+          p = project(lambda2, phi2),
+          x2 = p[0],
+          y2 = p[1],
+          dx2 = x2 - x0,
+          dy2 = y2 - y0,
+          dz = dy * dx2 - dx * dy2;
+      if (dz * dz / d2 > delta2 // perpendicular projected distance
+          || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end
+          || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance
+        resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream);
+        stream.point(x2, y2);
+        resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream);
+      }
+    }
+  }
+  return function(stream) {
+    var lambda00, x00, y00, a00, b00, c00, // first point
+        lambda0, x0, y0, a0, b0, c0; // previous point
+
+    var resampleStream = {
+      point: point,
+      lineStart: lineStart,
+      lineEnd: lineEnd,
+      polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; },
+      polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; }
+    };
+
+    function point(x, y) {
+      x = project(x, y);
+      stream.point(x[0], x[1]);
+    }
+
+    function lineStart() {
+      x0 = NaN;
+      resampleStream.point = linePoint;
+      stream.lineStart();
+    }
+
+    function linePoint(lambda, phi) {
+      var c = cartesian([lambda, phi]), p = project(lambda, phi);
+      resampleLineTo(x0, y0, lambda0, a0, b0, c0, x0 = p[0], y0 = p[1], lambda0 = lambda, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);
+      stream.point(x0, y0);
+    }
+
+    function lineEnd() {
+      resampleStream.point = point;
+      stream.lineEnd();
+    }
+
+    function ringStart() {
+      lineStart();
+      resampleStream.point = ringPoint;
+      resampleStream.lineEnd = ringEnd;
+    }
+
+    function ringPoint(lambda, phi) {
+      linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;
+      resampleStream.point = linePoint;
+    }
+
+    function ringEnd() {
+      resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream);
+      resampleStream.lineEnd = lineEnd;
+      lineEnd();
+    }
+
+    return resampleStream;
+  };
+}
+
+var transformRadians = transformer({
+  point: function(x, y) {
+    this.stream.point(x * radians, y * radians);
+  }
+});
+
+function transformRotate(rotate) {
+  return transformer({
+    point: function(x, y) {
+      var r = rotate(x, y);
+      return this.stream.point(r[0], r[1]);
+    }
+  });
+}
+
+function scaleTranslate(k, dx, dy, sx, sy) {
+  function transform(x, y) {
+    x *= sx; y *= sy;
+    return [dx + k * x, dy - k * y];
+  }
+  transform.invert = function(x, y) {
+    return [(x - dx) / k * sx, (dy - y) / k * sy];
+  };
+  return transform;
+}
+
+function scaleTranslateRotate(k, dx, dy, sx, sy, alpha) {
+  if (!alpha) return scaleTranslate(k, dx, dy, sx, sy);
+  var cosAlpha = cos(alpha),
+      sinAlpha = sin(alpha),
+      a = cosAlpha * k,
+      b = sinAlpha * k,
+      ai = cosAlpha / k,
+      bi = sinAlpha / k,
+      ci = (sinAlpha * dy - cosAlpha * dx) / k,
+      fi = (sinAlpha * dx + cosAlpha * dy) / k;
+  function transform(x, y) {
+    x *= sx; y *= sy;
+    return [a * x - b * y + dx, dy - b * x - a * y];
+  }
+  transform.invert = function(x, y) {
+    return [sx * (ai * x - bi * y + ci), sy * (fi - bi * x - ai * y)];
+  };
+  return transform;
+}
+
+function projection(project) {
+  return projectionMutator(function() { return project; })();
+}
+
+function projectionMutator(projectAt) {
+  var project,
+      k = 150, // scale
+      x = 480, y = 250, // translate
+      lambda = 0, phi = 0, // center
+      deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, // pre-rotate
+      alpha = 0, // post-rotate angle
+      sx = 1, // reflectX
+      sy = 1, // reflectX
+      theta = null, preclip = clipAntimeridian, // pre-clip angle
+      x0 = null, y0, x1, y1, postclip = identity$1, // post-clip extent
+      delta2 = 0.5, // precision
+      projectResample,
+      projectTransform,
+      projectRotateTransform,
+      cache,
+      cacheStream;
+
+  function projection(point) {
+    return projectRotateTransform(point[0] * radians, point[1] * radians);
+  }
+
+  function invert(point) {
+    point = projectRotateTransform.invert(point[0], point[1]);
+    return point && [point[0] * degrees, point[1] * degrees];
+  }
+
+  projection.stream = function(stream) {
+    return cache && cacheStream === stream ? cache : cache = transformRadians(transformRotate(rotate)(preclip(projectResample(postclip(cacheStream = stream)))));
+  };
+
+  projection.preclip = function(_) {
+    return arguments.length ? (preclip = _, theta = undefined, reset()) : preclip;
+  };
+
+  projection.postclip = function(_) {
+    return arguments.length ? (postclip = _, x0 = y0 = x1 = y1 = null, reset()) : postclip;
+  };
+
+  projection.clipAngle = function(_) {
+    return arguments.length ? (preclip = +_ ? clipCircle(theta = _ * radians) : (theta = null, clipAntimeridian), reset()) : theta * degrees;
+  };
+
+  projection.clipExtent = function(_) {
+    return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$1) : clipRectangle(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
+  };
+
+  projection.scale = function(_) {
+    return arguments.length ? (k = +_, recenter()) : k;
+  };
+
+  projection.translate = function(_) {
+    return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y];
+  };
+
+  projection.center = function(_) {
+    return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees, phi * degrees];
+  };
+
+  projection.rotate = function(_) {
+    return arguments.length ? (deltaLambda = _[0] % 360 * radians, deltaPhi = _[1] % 360 * radians, deltaGamma = _.length > 2 ? _[2] % 360 * radians : 0, recenter()) : [deltaLambda * degrees, deltaPhi * degrees, deltaGamma * degrees];
+  };
+
+  projection.angle = function(_) {
+    return arguments.length ? (alpha = _ % 360 * radians, recenter()) : alpha * degrees;
+  };
+
+  projection.reflectX = function(_) {
+    return arguments.length ? (sx = _ ? -1 : 1, recenter()) : sx < 0;
+  };
+
+  projection.reflectY = function(_) {
+    return arguments.length ? (sy = _ ? -1 : 1, recenter()) : sy < 0;
+  };
+
+  projection.precision = function(_) {
+    return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt(delta2);
+  };
+
+  projection.fitExtent = function(extent, object) {
+    return fitExtent(projection, extent, object);
+  };
+
+  projection.fitSize = function(size, object) {
+    return fitSize(projection, size, object);
+  };
+
+  projection.fitWidth = function(width, object) {
+    return fitWidth(projection, width, object);
+  };
+
+  projection.fitHeight = function(height, object) {
+    return fitHeight(projection, height, object);
+  };
+
+  function recenter() {
+    var center = scaleTranslateRotate(k, 0, 0, sx, sy, alpha).apply(null, project(lambda, phi)),
+        transform = scaleTranslateRotate(k, x - center[0], y - center[1], sx, sy, alpha);
+    rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma);
+    projectTransform = compose(project, transform);
+    projectRotateTransform = compose(rotate, projectTransform);
+    projectResample = resample(projectTransform, delta2);
+    return reset();
+  }
+
+  function reset() {
+    cache = cacheStream = null;
+    return projection;
+  }
+
+  return function() {
+    project = projectAt.apply(this, arguments);
+    projection.invert = project.invert && invert;
+    return recenter();
+  };
+}
+
+function conicProjection(projectAt) {
+  var phi0 = 0,
+      phi1 = pi / 3,
+      m = projectionMutator(projectAt),
+      p = m(phi0, phi1);
+
+  p.parallels = function(_) {
+    return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees, phi1 * degrees];
+  };
+
+  return p;
+}
+
+function cylindricalEqualAreaRaw(phi0) {
+  var cosPhi0 = cos(phi0);
+
+  function forward(lambda, phi) {
+    return [lambda * cosPhi0, sin(phi) / cosPhi0];
+  }
+
+  forward.invert = function(x, y) {
+    return [x / cosPhi0, asin(y * cosPhi0)];
+  };
+
+  return forward;
+}
+
+function conicEqualAreaRaw(y0, y1) {
+  var sy0 = sin(y0), n = (sy0 + sin(y1)) / 2;
+
+  // Are the parallels symmetrical around the Equator?
+  if (abs(n) < epsilon) return cylindricalEqualAreaRaw(y0);
+
+  var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt(c) / n;
+
+  function project(x, y) {
+    var r = sqrt(c - 2 * n * sin(y)) / n;
+    return [r * sin(x *= n), r0 - r * cos(x)];
+  }
+
+  project.invert = function(x, y) {
+    var r0y = r0 - y,
+        l = atan2(x, abs(r0y)) * sign(r0y);
+    if (r0y * n < 0)
+      l -= pi * sign(x) * sign(r0y);
+    return [l / n, asin((c - (x * x + r0y * r0y) * n * n) / (2 * n))];
+  };
+
+  return project;
+}
+
+function conicEqualArea() {
+  return conicProjection(conicEqualAreaRaw)
+      .scale(155.424)
+      .center([0, 33.6442]);
+}
+
+function albers() {
+  return conicEqualArea()
+      .parallels([29.5, 45.5])
+      .scale(1070)
+      .translate([480, 250])
+      .rotate([96, 0])
+      .center([-0.6, 38.7]);
+}
+
+// The projections must have mutually exclusive clip regions on the sphere,
+// as this will avoid emitting interleaving lines and polygons.
+function multiplex(streams) {
+  var n = streams.length;
+  return {
+    point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); },
+    sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); },
+    lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); },
+    lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); },
+    polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); },
+    polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); }
+  };
+}
+
+// A composite projection for the United States, configured by default for
+// 960×500. The projection also works quite well at 960×600 if you change the
+// scale to 1285 and adjust the translate accordingly. The set of standard
+// parallels for each region comes from USGS, which is published here:
+// http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers
+function albersUsa() {
+  var cache,
+      cacheStream,
+      lower48 = albers(), lower48Point,
+      alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338
+      hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007
+      point, pointStream = {point: function(x, y) { point = [x, y]; }};
+
+  function albersUsa(coordinates) {
+    var x = coordinates[0], y = coordinates[1];
+    return point = null,
+        (lower48Point.point(x, y), point)
+        || (alaskaPoint.point(x, y), point)
+        || (hawaiiPoint.point(x, y), point);
+  }
+
+  albersUsa.invert = function(coordinates) {
+    var k = lower48.scale(),
+        t = lower48.translate(),
+        x = (coordinates[0] - t[0]) / k,
+        y = (coordinates[1] - t[1]) / k;
+    return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska
+        : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii
+        : lower48).invert(coordinates);
+  };
+
+  albersUsa.stream = function(stream) {
+    return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]);
+  };
+
+  albersUsa.precision = function(_) {
+    if (!arguments.length) return lower48.precision();
+    lower48.precision(_), alaska.precision(_), hawaii.precision(_);
+    return reset();
+  };
+
+  albersUsa.scale = function(_) {
+    if (!arguments.length) return lower48.scale();
+    lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_);
+    return albersUsa.translate(lower48.translate());
+  };
+
+  albersUsa.translate = function(_) {
+    if (!arguments.length) return lower48.translate();
+    var k = lower48.scale(), x = +_[0], y = +_[1];
+
+    lower48Point = lower48
+        .translate(_)
+        .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]])
+        .stream(pointStream);
+
+    alaskaPoint = alaska
+        .translate([x - 0.307 * k, y + 0.201 * k])
+        .clipExtent([[x - 0.425 * k + epsilon, y + 0.120 * k + epsilon], [x - 0.214 * k - epsilon, y + 0.234 * k - epsilon]])
+        .stream(pointStream);
+
+    hawaiiPoint = hawaii
+        .translate([x - 0.205 * k, y + 0.212 * k])
+        .clipExtent([[x - 0.214 * k + epsilon, y + 0.166 * k + epsilon], [x - 0.115 * k - epsilon, y + 0.234 * k - epsilon]])
+        .stream(pointStream);
+
+    return reset();
+  };
+
+  albersUsa.fitExtent = function(extent, object) {
+    return fitExtent(albersUsa, extent, object);
+  };
+
+  albersUsa.fitSize = function(size, object) {
+    return fitSize(albersUsa, size, object);
+  };
+
+  albersUsa.fitWidth = function(width, object) {
+    return fitWidth(albersUsa, width, object);
+  };
+
+  albersUsa.fitHeight = function(height, object) {
+    return fitHeight(albersUsa, height, object);
+  };
+
+  function reset() {
+    cache = cacheStream = null;
+    return albersUsa;
+  }
+
+  return albersUsa.scale(1070);
+}
+
+function azimuthalRaw(scale) {
+  return function(x, y) {
+    var cx = cos(x),
+        cy = cos(y),
+        k = scale(cx * cy);
+        if (k === Infinity) return [2, 0];
+    return [
+      k * cy * sin(x),
+      k * sin(y)
+    ];
+  }
+}
+
+function azimuthalInvert(angle) {
+  return function(x, y) {
+    var z = sqrt(x * x + y * y),
+        c = angle(z),
+        sc = sin(c),
+        cc = cos(c);
+    return [
+      atan2(x * sc, z * cc),
+      asin(z && y * sc / z)
+    ];
+  }
+}
+
+var azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) {
+  return sqrt(2 / (1 + cxcy));
+});
+
+azimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) {
+  return 2 * asin(z / 2);
+});
+
+function azimuthalEqualArea() {
+  return projection(azimuthalEqualAreaRaw)
+      .scale(124.75)
+      .clipAngle(180 - 1e-3);
+}
+
+var azimuthalEquidistantRaw = azimuthalRaw(function(c) {
+  return (c = acos(c)) && c / sin(c);
+});
+
+azimuthalEquidistantRaw.invert = azimuthalInvert(function(z) {
+  return z;
+});
+
+function azimuthalEquidistant() {
+  return projection(azimuthalEquidistantRaw)
+      .scale(79.4188)
+      .clipAngle(180 - 1e-3);
+}
+
+function mercatorRaw(lambda, phi) {
+  return [lambda, log(tan((halfPi + phi) / 2))];
+}
+
+mercatorRaw.invert = function(x, y) {
+  return [x, 2 * atan(exp(y)) - halfPi];
+};
+
+function mercator() {
+  return mercatorProjection(mercatorRaw)
+      .scale(961 / tau);
+}
+
+function mercatorProjection(project) {
+  var m = projection(project),
+      center = m.center,
+      scale = m.scale,
+      translate = m.translate,
+      clipExtent = m.clipExtent,
+      x0 = null, y0, x1, y1; // clip extent
+
+  m.scale = function(_) {
+    return arguments.length ? (scale(_), reclip()) : scale();
+  };
+
+  m.translate = function(_) {
+    return arguments.length ? (translate(_), reclip()) : translate();
+  };
+
+  m.center = function(_) {
+    return arguments.length ? (center(_), reclip()) : center();
+  };
+
+  m.clipExtent = function(_) {
+    return arguments.length ? ((_ == null ? x0 = y0 = x1 = y1 = null : (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1])), reclip()) : x0 == null ? null : [[x0, y0], [x1, y1]];
+  };
+
+  function reclip() {
+    var k = pi * scale(),
+        t = m(rotation(m.rotate()).invert([0, 0]));
+    return clipExtent(x0 == null
+        ? [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]] : project === mercatorRaw
+        ? [[Math.max(t[0] - k, x0), y0], [Math.min(t[0] + k, x1), y1]]
+        : [[x0, Math.max(t[1] - k, y0)], [x1, Math.min(t[1] + k, y1)]]);
+  }
+
+  return reclip();
+}
+
+function tany(y) {
+  return tan((halfPi + y) / 2);
+}
+
+function conicConformalRaw(y0, y1) {
+  var cy0 = cos(y0),
+      n = y0 === y1 ? sin(y0) : log(cy0 / cos(y1)) / log(tany(y1) / tany(y0)),
+      f = cy0 * pow(tany(y0), n) / n;
+
+  if (!n) return mercatorRaw;
+
+  function project(x, y) {
+    if (f > 0) { if (y < -halfPi + epsilon) y = -halfPi + epsilon; }
+    else { if (y > halfPi - epsilon) y = halfPi - epsilon; }
+    var r = f / pow(tany(y), n);
+    return [r * sin(n * x), f - r * cos(n * x)];
+  }
+
+  project.invert = function(x, y) {
+    var fy = f - y, r = sign(n) * sqrt(x * x + fy * fy),
+      l = atan2(x, abs(fy)) * sign(fy);
+    if (fy * n < 0)
+      l -= pi * sign(x) * sign(fy);
+    return [l / n, 2 * atan(pow(f / r, 1 / n)) - halfPi];
+  };
+
+  return project;
+}
+
+function conicConformal() {
+  return conicProjection(conicConformalRaw)
+      .scale(109.5)
+      .parallels([30, 30]);
+}
+
+function equirectangularRaw(lambda, phi) {
+  return [lambda, phi];
+}
+
+equirectangularRaw.invert = equirectangularRaw;
+
+function equirectangular() {
+  return projection(equirectangularRaw)
+      .scale(152.63);
+}
+
+function conicEquidistantRaw(y0, y1) {
+  var cy0 = cos(y0),
+      n = y0 === y1 ? sin(y0) : (cy0 - cos(y1)) / (y1 - y0),
+      g = cy0 / n + y0;
+
+  if (abs(n) < epsilon) return equirectangularRaw;
+
+  function project(x, y) {
+    var gy = g - y, nx = n * x;
+    return [gy * sin(nx), g - gy * cos(nx)];
+  }
+
+  project.invert = function(x, y) {
+    var gy = g - y,
+        l = atan2(x, abs(gy)) * sign(gy);
+    if (gy * n < 0)
+      l -= pi * sign(x) * sign(gy);
+    return [l / n, g - sign(n) * sqrt(x * x + gy * gy)];
+  };
+
+  return project;
+}
+
+function conicEquidistant() {
+  return conicProjection(conicEquidistantRaw)
+      .scale(131.154)
+      .center([0, 13.9389]);
+}
+
+var A1 = 1.340264,
+    A2 = -0.081106,
+    A3 = 0.000893,
+    A4 = 0.003796,
+    M = sqrt(3) / 2,
+    iterations = 12;
+
+function equalEarthRaw(lambda, phi) {
+  var l = asin(M * sin(phi)), l2 = l * l, l6 = l2 * l2 * l2;
+  return [
+    lambda * cos(l) / (M * (A1 + 3 * A2 * l2 + l6 * (7 * A3 + 9 * A4 * l2))),
+    l * (A1 + A2 * l2 + l6 * (A3 + A4 * l2))
+  ];
+}
+
+equalEarthRaw.invert = function(x, y) {
+  var l = y, l2 = l * l, l6 = l2 * l2 * l2;
+  for (var i = 0, delta, fy, fpy; i < iterations; ++i) {
+    fy = l * (A1 + A2 * l2 + l6 * (A3 + A4 * l2)) - y;
+    fpy = A1 + 3 * A2 * l2 + l6 * (7 * A3 + 9 * A4 * l2);
+    l -= delta = fy / fpy, l2 = l * l, l6 = l2 * l2 * l2;
+    if (abs(delta) < epsilon2) break;
+  }
+  return [
+    M * x * (A1 + 3 * A2 * l2 + l6 * (7 * A3 + 9 * A4 * l2)) / cos(l),
+    asin(sin(l) / M)
+  ];
+};
+
+function equalEarth() {
+  return projection(equalEarthRaw)
+      .scale(177.158);
+}
+
+function gnomonicRaw(x, y) {
+  var cy = cos(y), k = cos(x) * cy;
+  return [cy * sin(x) / k, sin(y) / k];
+}
+
+gnomonicRaw.invert = azimuthalInvert(atan);
+
+function gnomonic() {
+  return projection(gnomonicRaw)
+      .scale(144.049)
+      .clipAngle(60);
+}
+
+function identity() {
+  var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, // scale, translate and reflect
+      alpha = 0, ca, sa, // angle
+      x0 = null, y0, x1, y1, // clip extent
+      kx = 1, ky = 1,
+      transform = transformer({
+        point: function(x, y) {
+          var p = projection([x, y]);
+          this.stream.point(p[0], p[1]);
+        }
+      }),
+      postclip = identity$1,
+      cache,
+      cacheStream;
+
+  function reset() {
+    kx = k * sx;
+    ky = k * sy;
+    cache = cacheStream = null;
+    return projection;
+  }
+
+  function projection (p) {
+    var x = p[0] * kx, y = p[1] * ky;
+    if (alpha) {
+      var t = y * ca - x * sa;
+      x = x * ca + y * sa;
+      y = t;
+    }    
+    return [x + tx, y + ty];
+  }
+  projection.invert = function(p) {
+    var x = p[0] - tx, y = p[1] - ty;
+    if (alpha) {
+      var t = y * ca + x * sa;
+      x = x * ca - y * sa;
+      y = t;
+    }
+    return [x / kx, y / ky];
+  };
+  projection.stream = function(stream) {
+    return cache && cacheStream === stream ? cache : cache = transform(postclip(cacheStream = stream));
+  };
+  projection.postclip = function(_) {
+    return arguments.length ? (postclip = _, x0 = y0 = x1 = y1 = null, reset()) : postclip;
+  };
+  projection.clipExtent = function(_) {
+    return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$1) : clipRectangle(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
+  };
+  projection.scale = function(_) {
+    return arguments.length ? (k = +_, reset()) : k;
+  };
+  projection.translate = function(_) {
+    return arguments.length ? (tx = +_[0], ty = +_[1], reset()) : [tx, ty];
+  };
+  projection.angle = function(_) {
+    return arguments.length ? (alpha = _ % 360 * radians, sa = sin(alpha), ca = cos(alpha), reset()) : alpha * degrees;
+  };
+  projection.reflectX = function(_) {
+    return arguments.length ? (sx = _ ? -1 : 1, reset()) : sx < 0;
+  };
+  projection.reflectY = function(_) {
+    return arguments.length ? (sy = _ ? -1 : 1, reset()) : sy < 0;
+  };
+  projection.fitExtent = function(extent, object) {
+    return fitExtent(projection, extent, object);
+  };
+  projection.fitSize = function(size, object) {
+    return fitSize(projection, size, object);
+  };
+  projection.fitWidth = function(width, object) {
+    return fitWidth(projection, width, object);
+  };
+  projection.fitHeight = function(height, object) {
+    return fitHeight(projection, height, object);
+  };
+
+  return projection;
+}
+
+function naturalEarth1Raw(lambda, phi) {
+  var phi2 = phi * phi, phi4 = phi2 * phi2;
+  return [
+    lambda * (0.8707 - 0.131979 * phi2 + phi4 * (-0.013791 + phi4 * (0.003971 * phi2 - 0.001529 * phi4))),
+    phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4)))
+  ];
+}
+
+naturalEarth1Raw.invert = function(x, y) {
+  var phi = y, i = 25, delta;
+  do {
+    var phi2 = phi * phi, phi4 = phi2 * phi2;
+    phi -= delta = (phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4))) - y) /
+        (1.007226 + phi2 * (0.015085 * 3 + phi4 * (-0.044475 * 7 + 0.028874 * 9 * phi2 - 0.005916 * 11 * phi4)));
+  } while (abs(delta) > epsilon && --i > 0);
+  return [
+    x / (0.8707 + (phi2 = phi * phi) * (-0.131979 + phi2 * (-0.013791 + phi2 * phi2 * phi2 * (0.003971 - 0.001529 * phi2)))),
+    phi
+  ];
+};
+
+function naturalEarth1() {
+  return projection(naturalEarth1Raw)
+      .scale(175.295);
+}
+
+function orthographicRaw(x, y) {
+  return [cos(y) * sin(x), sin(y)];
+}
+
+orthographicRaw.invert = azimuthalInvert(asin);
+
+function orthographic() {
+  return projection(orthographicRaw)
+      .scale(249.5)
+      .clipAngle(90 + epsilon);
+}
+
+function stereographicRaw(x, y) {
+  var cy = cos(y), k = 1 + cos(x) * cy;
+  return [cy * sin(x) / k, sin(y) / k];
+}
+
+stereographicRaw.invert = azimuthalInvert(function(z) {
+  return 2 * atan(z);
+});
+
+function stereographic() {
+  return projection(stereographicRaw)
+      .scale(250)
+      .clipAngle(142);
+}
+
+function transverseMercatorRaw(lambda, phi) {
+  return [log(tan((halfPi + phi) / 2)), -lambda];
+}
+
+transverseMercatorRaw.invert = function(x, y) {
+  return [-y, 2 * atan(exp(x)) - halfPi];
+};
+
+function transverseMercator() {
+  var m = mercatorProjection(transverseMercatorRaw),
+      center = m.center,
+      rotate = m.rotate;
+
+  m.center = function(_) {
+    return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]);
+  };
+
+  m.rotate = function(_) {
+    return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]);
+  };
+
+  return rotate([0, 0, 90])
+      .scale(159.155);
+}
+
+exports.geoAlbers = albers;
+exports.geoAlbersUsa = albersUsa;
+exports.geoArea = area;
+exports.geoAzimuthalEqualArea = azimuthalEqualArea;
+exports.geoAzimuthalEqualAreaRaw = azimuthalEqualAreaRaw;
+exports.geoAzimuthalEquidistant = azimuthalEquidistant;
+exports.geoAzimuthalEquidistantRaw = azimuthalEquidistantRaw;
+exports.geoBounds = bounds;
+exports.geoCentroid = centroid;
+exports.geoCircle = circle;
+exports.geoClipAntimeridian = clipAntimeridian;
+exports.geoClipCircle = clipCircle;
+exports.geoClipExtent = extent;
+exports.geoClipRectangle = clipRectangle;
+exports.geoConicConformal = conicConformal;
+exports.geoConicConformalRaw = conicConformalRaw;
+exports.geoConicEqualArea = conicEqualArea;
+exports.geoConicEqualAreaRaw = conicEqualAreaRaw;
+exports.geoConicEquidistant = conicEquidistant;
+exports.geoConicEquidistantRaw = conicEquidistantRaw;
+exports.geoContains = contains;
+exports.geoDistance = distance;
+exports.geoEqualEarth = equalEarth;
+exports.geoEqualEarthRaw = equalEarthRaw;
+exports.geoEquirectangular = equirectangular;
+exports.geoEquirectangularRaw = equirectangularRaw;
+exports.geoGnomonic = gnomonic;
+exports.geoGnomonicRaw = gnomonicRaw;
+exports.geoGraticule = graticule;
+exports.geoGraticule10 = graticule10;
+exports.geoIdentity = identity;
+exports.geoInterpolate = interpolate;
+exports.geoLength = length;
+exports.geoMercator = mercator;
+exports.geoMercatorRaw = mercatorRaw;
+exports.geoNaturalEarth1 = naturalEarth1;
+exports.geoNaturalEarth1Raw = naturalEarth1Raw;
+exports.geoOrthographic = orthographic;
+exports.geoOrthographicRaw = orthographicRaw;
+exports.geoPath = index;
+exports.geoProjection = projection;
+exports.geoProjectionMutator = projectionMutator;
+exports.geoRotation = rotation;
+exports.geoStereographic = stereographic;
+exports.geoStereographicRaw = stereographicRaw;
+exports.geoStream = geoStream;
+exports.geoTransform = transform;
+exports.geoTransverseMercator = transverseMercator;
+exports.geoTransverseMercatorRaw = transverseMercatorRaw;
+
+}));
Index: node_modules/d3-geo/dist/d3-geo.min.js
===================================================================
--- node_modules/d3-geo/dist/d3-geo.min.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/dist/d3-geo.min.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,2 @@
+// https://d3js.org/d3-geo/ v3.1.1 Copyright 2010-2024 Mike Bostock, 2008-2012 Charles Karney
+!function(n,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("d3-array")):"function"==typeof define&&define.amd?define(["exports","d3-array"],t):t((n="undefined"!=typeof globalThis?globalThis:n||self).d3=n.d3||{},n.d3)}(this,(function(n,t){"use strict";var r=1e-6,e=1e-12,i=Math.PI,o=i/2,u=i/4,a=2*i,c=180/i,l=i/180,f=Math.abs,p=Math.atan,s=Math.atan2,h=Math.cos,g=Math.ceil,d=Math.exp,v=Math.hypot,E=Math.log,y=Math.pow,S=Math.sin,m=Math.sign||function(n){return n>0?1:n<0?-1:0},M=Math.sqrt,w=Math.tan;function x(n){return n>1?0:n<-1?i:Math.acos(n)}function _(n){return n>1?o:n<-1?-o:Math.asin(n)}function N(n){return(n=S(n/2))*n}function A(){}function R(n,t){n&&P.hasOwnProperty(n.type)&&P[n.type](n,t)}var C={Feature:function(n,t){R(n.geometry,t)},FeatureCollection:function(n,t){for(var r=n.features,e=-1,i=r.length;++e<i;)R(r[e].geometry,t)}},P={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var r=n.coordinates,e=-1,i=r.length;++e<i;)n=r[e],t.point(n[0],n[1],n[2])},LineString:function(n,t){$(n.coordinates,t,0)},MultiLineString:function(n,t){for(var r=n.coordinates,e=-1,i=r.length;++e<i;)$(r[e],t,0)},Polygon:function(n,t){q(n.coordinates,t)},MultiPolygon:function(n,t){for(var r=n.coordinates,e=-1,i=r.length;++e<i;)q(r[e],t)},GeometryCollection:function(n,t){for(var r=n.geometries,e=-1,i=r.length;++e<i;)R(r[e],t)}};function $(n,t,r){var e,i=-1,o=n.length-r;for(t.lineStart();++i<o;)e=n[i],t.point(e[0],e[1],e[2]);t.lineEnd()}function q(n,t){var r=-1,e=n.length;for(t.polygonStart();++r<e;)$(n[r],t,1);t.polygonEnd()}function j(n,t){n&&C.hasOwnProperty(n.type)?C[n.type](n,t):R(n,t)}var z,b,L,T,G,O,k,F,H,I,W,X,Y,B,D,U,Z=new t.Adder,J=new t.Adder,K={point:A,lineStart:A,lineEnd:A,polygonStart:function(){Z=new t.Adder,K.lineStart=Q,K.lineEnd=V},polygonEnd:function(){var n=+Z;J.add(n<0?a+n:n),this.lineStart=this.lineEnd=this.point=A},sphere:function(){J.add(a)}};function Q(){K.point=nn}function V(){tn(z,b)}function nn(n,t){K.point=tn,z=n,b=t,L=n*=l,T=h(t=(t*=l)/2+u),G=S(t)}function tn(n,t){var r=(n*=l)-L,e=r>=0?1:-1,i=e*r,o=h(t=(t*=l)/2+u),a=S(t),c=G*a,f=T*o+c*h(i),p=c*e*S(i);Z.add(s(p,f)),L=n,T=o,G=a}function rn(n){return[s(n[1],n[0]),_(n[2])]}function en(n){var t=n[0],r=n[1],e=h(r);return[e*h(t),e*S(t),S(r)]}function on(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function un(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function an(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function cn(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function ln(n){var t=M(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}var fn,pn,sn,hn,gn,dn,vn,En,yn,Sn,mn,Mn,wn,xn,_n,Nn,An={point:Rn,lineStart:Pn,lineEnd:$n,polygonStart:function(){An.point=qn,An.lineStart=jn,An.lineEnd=zn,B=new t.Adder,K.polygonStart()},polygonEnd:function(){K.polygonEnd(),An.point=Rn,An.lineStart=Pn,An.lineEnd=$n,Z<0?(O=-(F=180),k=-(H=90)):B>r?H=90:B<-r&&(k=-90),U[0]=O,U[1]=F},sphere:function(){O=-(F=180),k=-(H=90)}};function Rn(n,t){D.push(U=[O=n,F=n]),t<k&&(k=t),t>H&&(H=t)}function Cn(n,t){var r=en([n*l,t*l]);if(Y){var e=un(Y,r),i=un([e[1],-e[0],0],e);ln(i),i=rn(i);var o,u=n-I,a=u>0?1:-1,p=i[0]*c*a,s=f(u)>180;s^(a*I<p&&p<a*n)?(o=i[1]*c)>H&&(H=o):s^(a*I<(p=(p+360)%360-180)&&p<a*n)?(o=-i[1]*c)<k&&(k=o):(t<k&&(k=t),t>H&&(H=t)),s?n<I?bn(O,n)>bn(O,F)&&(F=n):bn(n,F)>bn(O,F)&&(O=n):F>=O?(n<O&&(O=n),n>F&&(F=n)):n>I?bn(O,n)>bn(O,F)&&(F=n):bn(n,F)>bn(O,F)&&(O=n)}else D.push(U=[O=n,F=n]);t<k&&(k=t),t>H&&(H=t),Y=r,I=n}function Pn(){An.point=Cn}function $n(){U[0]=O,U[1]=F,An.point=Rn,Y=null}function qn(n,t){if(Y){var r=n-I;B.add(f(r)>180?r+(r>0?360:-360):r)}else W=n,X=t;K.point(n,t),Cn(n,t)}function jn(){K.lineStart()}function zn(){qn(W,X),K.lineEnd(),f(B)>r&&(O=-(F=180)),U[0]=O,U[1]=F,Y=null}function bn(n,t){return(t-=n)<0?t+360:t}function Ln(n,t){return n[0]-t[0]}function Tn(n,t){return n[0]<=n[1]?n[0]<=t&&t<=n[1]:t<n[0]||n[1]<t}var Gn={sphere:A,point:On,lineStart:Fn,lineEnd:Wn,polygonStart:function(){Gn.lineStart=Xn,Gn.lineEnd=Yn},polygonEnd:function(){Gn.lineStart=Fn,Gn.lineEnd=Wn}};function On(n,t){n*=l;var r=h(t*=l);kn(r*h(n),r*S(n),S(t))}function kn(n,t,r){++fn,sn+=(n-sn)/fn,hn+=(t-hn)/fn,gn+=(r-gn)/fn}function Fn(){Gn.point=Hn}function Hn(n,t){n*=l;var r=h(t*=l);xn=r*h(n),_n=r*S(n),Nn=S(t),Gn.point=In,kn(xn,_n,Nn)}function In(n,t){n*=l;var r=h(t*=l),e=r*h(n),i=r*S(n),o=S(t),u=s(M((u=_n*o-Nn*i)*u+(u=Nn*e-xn*o)*u+(u=xn*i-_n*e)*u),xn*e+_n*i+Nn*o);pn+=u,dn+=u*(xn+(xn=e)),vn+=u*(_n+(_n=i)),En+=u*(Nn+(Nn=o)),kn(xn,_n,Nn)}function Wn(){Gn.point=On}function Xn(){Gn.point=Bn}function Yn(){Dn(Mn,wn),Gn.point=On}function Bn(n,t){Mn=n,wn=t,n*=l,t*=l,Gn.point=Dn;var r=h(t);xn=r*h(n),_n=r*S(n),Nn=S(t),kn(xn,_n,Nn)}function Dn(n,t){n*=l;var r=h(t*=l),e=r*h(n),i=r*S(n),o=S(t),u=_n*o-Nn*i,a=Nn*e-xn*o,c=xn*i-_n*e,f=v(u,a,c),p=_(f),s=f&&-p/f;yn.add(s*u),Sn.add(s*a),mn.add(s*c),pn+=p,dn+=p*(xn+(xn=e)),vn+=p*(_n+(_n=i)),En+=p*(Nn+(Nn=o)),kn(xn,_n,Nn)}function Un(n){return function(){return n}}function Zn(n,t){function r(r,e){return r=n(r,e),t(r[0],r[1])}return n.invert&&t.invert&&(r.invert=function(r,e){return(r=t.invert(r,e))&&n.invert(r[0],r[1])}),r}function Jn(n,t){return f(n)>i&&(n-=Math.round(n/a)*a),[n,t]}function Kn(n,t,r){return(n%=a)?t||r?Zn(Vn(n),nt(t,r)):Vn(n):t||r?nt(t,r):Jn}function Qn(n){return function(t,r){return f(t+=n)>i&&(t-=Math.round(t/a)*a),[t,r]}}function Vn(n){var t=Qn(n);return t.invert=Qn(-n),t}function nt(n,t){var r=h(n),e=S(n),i=h(t),o=S(t);function u(n,t){var u=h(t),a=h(n)*u,c=S(n)*u,l=S(t),f=l*r+a*e;return[s(c*i-f*o,a*r-l*e),_(f*i+c*o)]}return u.invert=function(n,t){var u=h(t),a=h(n)*u,c=S(n)*u,l=S(t),f=l*i-c*o;return[s(c*i+l*o,a*r+f*e),_(f*r-a*e)]},u}function tt(n){function t(t){return(t=n(t[0]*l,t[1]*l))[0]*=c,t[1]*=c,t}return n=Kn(n[0]*l,n[1]*l,n.length>2?n[2]*l:0),t.invert=function(t){return(t=n.invert(t[0]*l,t[1]*l))[0]*=c,t[1]*=c,t},t}function rt(n,t,r,e,i,o){if(r){var u=h(t),c=S(t),l=e*r;null==i?(i=t+e*a,o=t-l/2):(i=et(u,i),o=et(u,o),(e>0?i<o:i>o)&&(i+=e*a));for(var f,p=i;e>0?p>o:p<o;p-=l)f=rn([u,-c*h(p),-c*S(p)]),n.point(f[0],f[1])}}function et(n,t){(t=en(t))[0]-=n,ln(t);var e=x(-t[1]);return((-t[2]<0?-e:e)+a-r)%a}function it(){var n,t=[];return{point:function(t,r,e){n.push([t,r,e])},lineStart:function(){t.push(n=[])},lineEnd:A,rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))},result:function(){var r=t;return t=[],n=null,r}}}function ot(n,t){return f(n[0]-t[0])<r&&f(n[1]-t[1])<r}function ut(n,t,r,e){this.x=n,this.z=t,this.o=r,this.e=e,this.v=!1,this.n=this.p=null}function at(n,t,e,i,o){var u,a,c=[],l=[];if(n.forEach((function(n){if(!((t=n.length-1)<=0)){var t,e,i=n[0],a=n[t];if(ot(i,a)){if(!i[2]&&!a[2]){for(o.lineStart(),u=0;u<t;++u)o.point((i=n[u])[0],i[1]);return void o.lineEnd()}a[0]+=2*r}c.push(e=new ut(i,n,null,!0)),l.push(e.o=new ut(i,null,e,!1)),c.push(e=new ut(a,n,null,!1)),l.push(e.o=new ut(a,null,e,!0))}})),c.length){for(l.sort(t),ct(c),ct(l),u=0,a=l.length;u<a;++u)l[u].e=e=!e;for(var f,p,s=c[0];;){for(var h=s,g=!0;h.v;)if((h=h.n)===s)return;f=h.z,o.lineStart();do{if(h.v=h.o.v=!0,h.e){if(g)for(u=0,a=f.length;u<a;++u)o.point((p=f[u])[0],p[1]);else i(h.x,h.n.x,1,o);h=h.n}else{if(g)for(f=h.p.z,u=f.length-1;u>=0;--u)o.point((p=f[u])[0],p[1]);else i(h.x,h.p.x,-1,o);h=h.p}f=(h=h.o).z,g=!g}while(!h.v);o.lineEnd()}}}function ct(n){if(t=n.length){for(var t,r,e=0,i=n[0];++e<t;)i.n=r=n[e],r.p=i,i=r;i.n=r=n[0],r.p=i}}function lt(n){return f(n[0])<=i?n[0]:m(n[0])*((f(n[0])+i)%a-i)}function ft(n,c){var l=lt(c),f=c[1],p=S(f),g=[S(l),-h(l),0],d=0,v=0,E=new t.Adder;1===p?f=o+r:-1===p&&(f=-o-r);for(var y=0,m=n.length;y<m;++y)if(w=(M=n[y]).length)for(var M,w,x=M[w-1],N=lt(x),A=x[1]/2+u,R=S(A),C=h(A),P=0;P<w;++P,N=q,R=z,C=b,x=$){var $=M[P],q=lt($),j=$[1]/2+u,z=S(j),b=h(j),L=q-N,T=L>=0?1:-1,G=T*L,O=G>i,k=R*z;if(E.add(s(k*T*S(G),C*b+k*h(G))),d+=O?L+T*a:L,O^N>=l^q>=l){var F=un(en(x),en($));ln(F);var H=un(g,F);ln(H);var I=(O^L>=0?-1:1)*_(H[2]);(f>I||f===I&&(F[0]||F[1]))&&(v+=O^L>=0?1:-1)}}return(d<-r||d<r&&E<-e)^1&v}function pt(n,r,e,i){return function(o){var u,a,c,l=r(o),f=it(),p=r(f),s=!1,h={point:g,lineStart:v,lineEnd:E,polygonStart:function(){h.point=y,h.lineStart=S,h.lineEnd=m,a=[],u=[]},polygonEnd:function(){h.point=g,h.lineStart=v,h.lineEnd=E,a=t.merge(a);var n=ft(u,i);a.length?(s||(o.polygonStart(),s=!0),at(a,ht,n,e,o)):n&&(s||(o.polygonStart(),s=!0),o.lineStart(),e(null,null,1,o),o.lineEnd()),s&&(o.polygonEnd(),s=!1),a=u=null},sphere:function(){o.polygonStart(),o.lineStart(),e(null,null,1,o),o.lineEnd(),o.polygonEnd()}};function g(t,r){n(t,r)&&o.point(t,r)}function d(n,t){l.point(n,t)}function v(){h.point=d,l.lineStart()}function E(){h.point=g,l.lineEnd()}function y(n,t){c.push([n,t]),p.point(n,t)}function S(){p.lineStart(),c=[]}function m(){y(c[0][0],c[0][1]),p.lineEnd();var n,t,r,e,i=p.clean(),l=f.result(),h=l.length;if(c.pop(),u.push(c),c=null,h)if(1&i){if((t=(r=l[0]).length-1)>0){for(s||(o.polygonStart(),s=!0),o.lineStart(),n=0;n<t;++n)o.point((e=r[n])[0],e[1]);o.lineEnd()}}else h>1&&2&i&&l.push(l.pop().concat(l.shift())),a.push(l.filter(st))}return h}}function st(n){return n.length>1}function ht(n,t){return((n=n.x)[0]<0?n[1]-o-r:o-n[1])-((t=t.x)[0]<0?t[1]-o-r:o-t[1])}Jn.invert=Jn;var gt=pt((function(){return!0}),(function(n){var t,e=NaN,u=NaN,a=NaN;return{lineStart:function(){n.lineStart(),t=1},point:function(c,l){var s=c>0?i:-i,g=f(c-e);f(g-i)<r?(n.point(e,u=(u+l)/2>0?o:-o),n.point(a,u),n.lineEnd(),n.lineStart(),n.point(s,u),n.point(c,u),t=0):a!==s&&g>=i&&(f(e-a)<r&&(e-=a*r),f(c-s)<r&&(c-=s*r),u=function(n,t,e,i){var o,u,a=S(n-e);return f(a)>r?p((S(t)*(u=h(i))*S(e)-S(i)*(o=h(t))*S(n))/(o*u*a)):(t+i)/2}(e,u,c,l),n.point(a,u),n.lineEnd(),n.lineStart(),n.point(s,u),t=0),n.point(e=c,u=l),a=s},lineEnd:function(){n.lineEnd(),e=u=NaN},clean:function(){return 2-t}}}),(function(n,t,e,u){var a;if(null==n)a=e*o,u.point(-i,a),u.point(0,a),u.point(i,a),u.point(i,0),u.point(i,-a),u.point(0,-a),u.point(-i,-a),u.point(-i,0),u.point(-i,a);else if(f(n[0]-t[0])>r){var c=n[0]<t[0]?i:-i;a=e*c/2,u.point(-c,a),u.point(0,a),u.point(c,a)}else u.point(t[0],t[1])}),[-i,-o]);function dt(n){var t=h(n),e=2*l,o=t>0,u=f(t)>r;function a(n,r){return h(n)*h(r)>t}function c(n,e,o){var u=[1,0,0],a=un(en(n),en(e)),c=on(a,a),l=a[0],p=c-l*l;if(!p)return!o&&n;var s=t*c/p,h=-t*l/p,g=un(u,a),d=cn(u,s);an(d,cn(a,h));var v=g,E=on(d,v),y=on(v,v),S=E*E-y*(on(d,d)-1);if(!(S<0)){var m=M(S),w=cn(v,(-E-m)/y);if(an(w,d),w=rn(w),!o)return w;var x,_=n[0],N=e[0],A=n[1],R=e[1];N<_&&(x=_,_=N,N=x);var C=N-_,P=f(C-i)<r;if(!P&&R<A&&(x=A,A=R,R=x),P||C<r?P?A+R>0^w[1]<(f(w[0]-_)<r?A:R):A<=w[1]&&w[1]<=R:C>i^(_<=w[0]&&w[0]<=N)){var $=cn(v,(-E+m)/y);return an($,d),[w,rn($)]}}}function p(t,r){var e=o?n:i-n,u=0;return t<-e?u|=1:t>e&&(u|=2),r<-e?u|=4:r>e&&(u|=8),u}return pt(a,(function(n){var t,r,e,l,f;return{lineStart:function(){l=e=!1,f=1},point:function(s,h){var g,d=[s,h],v=a(s,h),E=o?v?0:p(s,h):v?p(s+(s<0?i:-i),h):0;if(!t&&(l=e=v)&&n.lineStart(),v!==e&&(!(g=c(t,d))||ot(t,g)||ot(d,g))&&(d[2]=1),v!==e)f=0,v?(n.lineStart(),g=c(d,t),n.point(g[0],g[1])):(g=c(t,d),n.point(g[0],g[1],2),n.lineEnd()),t=g;else if(u&&t&&o^v){var y;E&r||!(y=c(d,t,!0))||(f=0,o?(n.lineStart(),n.point(y[0][0],y[0][1]),n.point(y[1][0],y[1][1]),n.lineEnd()):(n.point(y[1][0],y[1][1]),n.lineEnd(),n.lineStart(),n.point(y[0][0],y[0][1],3)))}!v||t&&ot(t,d)||n.point(d[0],d[1]),t=d,e=v,r=E},lineEnd:function(){e&&n.lineEnd(),t=null},clean:function(){return f|(l&&e)<<1}}}),(function(t,r,i,o){rt(o,n,e,i,t,r)}),o?[0,-n]:[-i,n-i])}var vt,Et,yt,St,mt=1e9,Mt=-mt;function wt(n,e,i,o){function u(t,r){return n<=t&&t<=i&&e<=r&&r<=o}function a(t,r,u,a){var l=0,f=0;if(null==t||(l=c(t,u))!==(f=c(r,u))||p(t,r)<0^u>0)do{a.point(0===l||3===l?n:i,l>1?o:e)}while((l=(l+u+4)%4)!==f);else a.point(r[0],r[1])}function c(t,o){return f(t[0]-n)<r?o>0?0:3:f(t[0]-i)<r?o>0?2:1:f(t[1]-e)<r?o>0?1:0:o>0?3:2}function l(n,t){return p(n.x,t.x)}function p(n,t){var r=c(n,1),e=c(t,1);return r!==e?r-e:0===r?t[1]-n[1]:1===r?n[0]-t[0]:2===r?n[1]-t[1]:t[0]-n[0]}return function(r){var c,f,p,s,h,g,d,v,E,y,S,m=r,M=it(),w={point:x,lineStart:function(){w.point=_,f&&f.push(p=[]);y=!0,E=!1,d=v=NaN},lineEnd:function(){c&&(_(s,h),g&&E&&M.rejoin(),c.push(M.result()));w.point=x,E&&m.lineEnd()},polygonStart:function(){m=M,c=[],f=[],S=!0},polygonEnd:function(){var e=function(){for(var t=0,r=0,e=f.length;r<e;++r)for(var i,u,a=f[r],c=1,l=a.length,p=a[0],s=p[0],h=p[1];c<l;++c)i=s,u=h,s=(p=a[c])[0],h=p[1],u<=o?h>o&&(s-i)*(o-u)>(h-u)*(n-i)&&++t:h<=o&&(s-i)*(o-u)<(h-u)*(n-i)&&--t;return t}(),i=S&&e,u=(c=t.merge(c)).length;(i||u)&&(r.polygonStart(),i&&(r.lineStart(),a(null,null,1,r),r.lineEnd()),u&&at(c,l,e,a,r),r.polygonEnd());m=r,c=f=p=null}};function x(n,t){u(n,t)&&m.point(n,t)}function _(t,r){var a=u(t,r);if(f&&p.push([t,r]),y)s=t,h=r,g=a,y=!1,a&&(m.lineStart(),m.point(t,r));else if(a&&E)m.point(t,r);else{var c=[d=Math.max(Mt,Math.min(mt,d)),v=Math.max(Mt,Math.min(mt,v))],l=[t=Math.max(Mt,Math.min(mt,t)),r=Math.max(Mt,Math.min(mt,r))];!function(n,t,r,e,i,o){var u,a=n[0],c=n[1],l=0,f=1,p=t[0]-a,s=t[1]-c;if(u=r-a,p||!(u>0)){if(u/=p,p<0){if(u<l)return;u<f&&(f=u)}else if(p>0){if(u>f)return;u>l&&(l=u)}if(u=i-a,p||!(u<0)){if(u/=p,p<0){if(u>f)return;u>l&&(l=u)}else if(p>0){if(u<l)return;u<f&&(f=u)}if(u=e-c,s||!(u>0)){if(u/=s,s<0){if(u<l)return;u<f&&(f=u)}else if(s>0){if(u>f)return;u>l&&(l=u)}if(u=o-c,s||!(u<0)){if(u/=s,s<0){if(u>f)return;u>l&&(l=u)}else if(s>0){if(u<l)return;u<f&&(f=u)}return l>0&&(n[0]=a+l*p,n[1]=c+l*s),f<1&&(t[0]=a+f*p,t[1]=c+f*s),!0}}}}}(c,l,n,e,i,o)?a&&(m.lineStart(),m.point(t,r),S=!1):(E||(m.lineStart(),m.point(c[0],c[1])),m.point(l[0],l[1]),a||m.lineEnd(),S=!1)}d=t,v=r,E=a}return w}}var xt={sphere:A,point:A,lineStart:function(){xt.point=Nt,xt.lineEnd=_t},lineEnd:A,polygonStart:A,polygonEnd:A};function _t(){xt.point=xt.lineEnd=A}function Nt(n,t){Et=n*=l,yt=S(t*=l),St=h(t),xt.point=At}function At(n,t){n*=l;var r=S(t*=l),e=h(t),i=f(n-Et),o=h(i),u=e*S(i),a=St*r-yt*e*o,c=yt*r+St*e*o;vt.add(s(M(u*u+a*a),c)),Et=n,yt=r,St=e}function Rt(n){return vt=new t.Adder,j(n,xt),+vt}var Ct=[null,null],Pt={type:"LineString",coordinates:Ct};function $t(n,t){return Ct[0]=n,Ct[1]=t,Rt(Pt)}var qt={Feature:function(n,t){return zt(n.geometry,t)},FeatureCollection:function(n,t){for(var r=n.features,e=-1,i=r.length;++e<i;)if(zt(r[e].geometry,t))return!0;return!1}},jt={Sphere:function(){return!0},Point:function(n,t){return bt(n.coordinates,t)},MultiPoint:function(n,t){for(var r=n.coordinates,e=-1,i=r.length;++e<i;)if(bt(r[e],t))return!0;return!1},LineString:function(n,t){return Lt(n.coordinates,t)},MultiLineString:function(n,t){for(var r=n.coordinates,e=-1,i=r.length;++e<i;)if(Lt(r[e],t))return!0;return!1},Polygon:function(n,t){return Tt(n.coordinates,t)},MultiPolygon:function(n,t){for(var r=n.coordinates,e=-1,i=r.length;++e<i;)if(Tt(r[e],t))return!0;return!1},GeometryCollection:function(n,t){for(var r=n.geometries,e=-1,i=r.length;++e<i;)if(zt(r[e],t))return!0;return!1}};function zt(n,t){return!(!n||!jt.hasOwnProperty(n.type))&&jt[n.type](n,t)}function bt(n,t){return 0===$t(n,t)}function Lt(n,t){for(var r,i,o,u=0,a=n.length;u<a;u++){if(0===(i=$t(n[u],t)))return!0;if(u>0&&(o=$t(n[u],n[u-1]))>0&&r<=o&&i<=o&&(r+i-o)*(1-Math.pow((r-i)/o,2))<e*o)return!0;r=i}return!1}function Tt(n,t){return!!ft(n.map(Gt),Ot(t))}function Gt(n){return(n=n.map(Ot)).pop(),n}function Ot(n){return[n[0]*l,n[1]*l]}function kt(n,e,i){var o=t.range(n,e-r,i).concat(e);return function(n){return o.map((function(t){return[n,t]}))}}function Ft(n,e,i){var o=t.range(n,e-r,i).concat(e);return function(n){return o.map((function(t){return[t,n]}))}}function Ht(){var n,e,i,o,u,a,c,l,p,s,h,d,v=10,E=v,y=90,S=360,m=2.5;function M(){return{type:"MultiLineString",coordinates:w()}}function w(){return t.range(g(o/y)*y,i,y).map(h).concat(t.range(g(l/S)*S,c,S).map(d)).concat(t.range(g(e/v)*v,n,v).filter((function(n){return f(n%y)>r})).map(p)).concat(t.range(g(a/E)*E,u,E).filter((function(n){return f(n%S)>r})).map(s))}return M.lines=function(){return w().map((function(n){return{type:"LineString",coordinates:n}}))},M.outline=function(){return{type:"Polygon",coordinates:[h(o).concat(d(c).slice(1),h(i).reverse().slice(1),d(l).reverse().slice(1))]}},M.extent=function(n){return arguments.length?M.extentMajor(n).extentMinor(n):M.extentMinor()},M.extentMajor=function(n){return arguments.length?(o=+n[0][0],i=+n[1][0],l=+n[0][1],c=+n[1][1],o>i&&(n=o,o=i,i=n),l>c&&(n=l,l=c,c=n),M.precision(m)):[[o,l],[i,c]]},M.extentMinor=function(t){return arguments.length?(e=+t[0][0],n=+t[1][0],a=+t[0][1],u=+t[1][1],e>n&&(t=e,e=n,n=t),a>u&&(t=a,a=u,u=t),M.precision(m)):[[e,a],[n,u]]},M.step=function(n){return arguments.length?M.stepMajor(n).stepMinor(n):M.stepMinor()},M.stepMajor=function(n){return arguments.length?(y=+n[0],S=+n[1],M):[y,S]},M.stepMinor=function(n){return arguments.length?(v=+n[0],E=+n[1],M):[v,E]},M.precision=function(t){return arguments.length?(m=+t,p=kt(a,u,90),s=Ft(e,n,m),h=kt(l,c,90),d=Ft(o,i,m),M):m},M.extentMajor([[-180,-90+r],[180,90-r]]).extentMinor([[-180,-80-r],[180,80+r]])}var It,Wt,Xt,Yt,Bt=n=>n,Dt=new t.Adder,Ut=new t.Adder,Zt={point:A,lineStart:A,lineEnd:A,polygonStart:function(){Zt.lineStart=Jt,Zt.lineEnd=Vt},polygonEnd:function(){Zt.lineStart=Zt.lineEnd=Zt.point=A,Dt.add(f(Ut)),Ut=new t.Adder},result:function(){var n=Dt/2;return Dt=new t.Adder,n}};function Jt(){Zt.point=Kt}function Kt(n,t){Zt.point=Qt,It=Xt=n,Wt=Yt=t}function Qt(n,t){Ut.add(Yt*n-Xt*t),Xt=n,Yt=t}function Vt(){Qt(It,Wt)}var nr=1/0,tr=nr,rr=-nr,er=rr,ir={point:function(n,t){n<nr&&(nr=n);n>rr&&(rr=n);t<tr&&(tr=t);t>er&&(er=t)},lineStart:A,lineEnd:A,polygonStart:A,polygonEnd:A,result:function(){var n=[[nr,tr],[rr,er]];return rr=er=-(tr=nr=1/0),n}};var or,ur,ar,cr,lr=0,fr=0,pr=0,sr=0,hr=0,gr=0,dr=0,vr=0,Er=0,yr={point:Sr,lineStart:mr,lineEnd:xr,polygonStart:function(){yr.lineStart=_r,yr.lineEnd=Nr},polygonEnd:function(){yr.point=Sr,yr.lineStart=mr,yr.lineEnd=xr},result:function(){var n=Er?[dr/Er,vr/Er]:gr?[sr/gr,hr/gr]:pr?[lr/pr,fr/pr]:[NaN,NaN];return lr=fr=pr=sr=hr=gr=dr=vr=Er=0,n}};function Sr(n,t){lr+=n,fr+=t,++pr}function mr(){yr.point=Mr}function Mr(n,t){yr.point=wr,Sr(ar=n,cr=t)}function wr(n,t){var r=n-ar,e=t-cr,i=M(r*r+e*e);sr+=i*(ar+n)/2,hr+=i*(cr+t)/2,gr+=i,Sr(ar=n,cr=t)}function xr(){yr.point=Sr}function _r(){yr.point=Ar}function Nr(){Rr(or,ur)}function Ar(n,t){yr.point=Rr,Sr(or=ar=n,ur=cr=t)}function Rr(n,t){var r=n-ar,e=t-cr,i=M(r*r+e*e);sr+=i*(ar+n)/2,hr+=i*(cr+t)/2,gr+=i,dr+=(i=cr*n-ar*t)*(ar+n),vr+=i*(cr+t),Er+=3*i,Sr(ar=n,cr=t)}function Cr(n){this._context=n}Cr.prototype={_radius:4.5,pointRadius:function(n){return this._radius=n,this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._context.closePath(),this._point=NaN},point:function(n,t){switch(this._point){case 0:this._context.moveTo(n,t),this._point=1;break;case 1:this._context.lineTo(n,t);break;default:this._context.moveTo(n+this._radius,t),this._context.arc(n,t,this._radius,0,a)}},result:A};var Pr,$r,qr,jr,zr,br=new t.Adder,Lr={point:A,lineStart:function(){Lr.point=Tr},lineEnd:function(){Pr&&Gr($r,qr),Lr.point=A},polygonStart:function(){Pr=!0},polygonEnd:function(){Pr=null},result:function(){var n=+br;return br=new t.Adder,n}};function Tr(n,t){Lr.point=Gr,$r=jr=n,qr=zr=t}function Gr(n,t){jr-=n,zr-=t,br.add(M(jr*jr+zr*zr)),jr=n,zr=t}let Or,kr,Fr,Hr;class Ir{constructor(n){this._append=null==n?Wr:function(n){const t=Math.floor(n);if(!(t>=0))throw new RangeError(`invalid digits: ${n}`);if(t>15)return Wr;if(t!==Or){const n=10**t;Or=t,kr=function(t){let r=1;this._+=t[0];for(const e=t.length;r<e;++r)this._+=Math.round(arguments[r]*n)/n+t[r]}}return kr}(n),this._radius=4.5,this._=""}pointRadius(n){return this._radius=+n,this}polygonStart(){this._line=0}polygonEnd(){this._line=NaN}lineStart(){this._point=0}lineEnd(){0===this._line&&(this._+="Z"),this._point=NaN}point(n,t){switch(this._point){case 0:this._append`M${n},${t}`,this._point=1;break;case 1:this._append`L${n},${t}`;break;default:if(this._append`M${n},${t}`,this._radius!==Fr||this._append!==kr){const n=this._radius,t=this._;this._="",this._append`m0,${n}a${n},${n} 0 1,1 0,${-2*n}a${n},${n} 0 1,1 0,${2*n}z`,Fr=n,kr=this._append,Hr=this._,this._=t}this._+=Hr}}result(){const n=this._;return this._="",n.length?n:null}}function Wr(n){let t=1;this._+=n[0];for(const r=n.length;t<r;++t)this._+=arguments[t]+n[t]}function Xr(n){return function(t){var r=new Yr;for(var e in n)r[e]=n[e];return r.stream=t,r}}function Yr(){}function Br(n,t,r){var e=n.clipExtent&&n.clipExtent();return n.scale(150).translate([0,0]),null!=e&&n.clipExtent(null),j(r,n.stream(ir)),t(ir.result()),null!=e&&n.clipExtent(e),n}function Dr(n,t,r){return Br(n,(function(r){var e=t[1][0]-t[0][0],i=t[1][1]-t[0][1],o=Math.min(e/(r[1][0]-r[0][0]),i/(r[1][1]-r[0][1])),u=+t[0][0]+(e-o*(r[1][0]+r[0][0]))/2,a=+t[0][1]+(i-o*(r[1][1]+r[0][1]))/2;n.scale(150*o).translate([u,a])}),r)}function Ur(n,t,r){return Dr(n,[[0,0],t],r)}function Zr(n,t,r){return Br(n,(function(r){var e=+t,i=e/(r[1][0]-r[0][0]),o=(e-i*(r[1][0]+r[0][0]))/2,u=-i*r[0][1];n.scale(150*i).translate([o,u])}),r)}function Jr(n,t,r){return Br(n,(function(r){var e=+t,i=e/(r[1][1]-r[0][1]),o=-i*r[0][0],u=(e-i*(r[1][1]+r[0][1]))/2;n.scale(150*i).translate([o,u])}),r)}Yr.prototype={constructor:Yr,point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};var Kr=16,Qr=h(30*l);function Vr(n,t){return+t?function(n,t){function e(i,o,u,a,c,l,p,h,g,d,v,E,y,S){var m=p-i,w=h-o,x=m*m+w*w;if(x>4*t&&y--){var N=a+d,A=c+v,R=l+E,C=M(N*N+A*A+R*R),P=_(R/=C),$=f(f(R)-1)<r||f(u-g)<r?(u+g)/2:s(A,N),q=n($,P),j=q[0],z=q[1],b=j-i,L=z-o,T=w*b-m*L;(T*T/x>t||f((m*b+w*L)/x-.5)>.3||a*d+c*v+l*E<Qr)&&(e(i,o,u,a,c,l,j,z,$,N/=C,A/=C,R,y,S),S.point(j,z),e(j,z,$,N,A,R,p,h,g,d,v,E,y,S))}}return function(t){var r,i,o,u,a,c,l,f,p,s,h,g,d={point:v,lineStart:E,lineEnd:S,polygonStart:function(){t.polygonStart(),d.lineStart=m},polygonEnd:function(){t.polygonEnd(),d.lineStart=E}};function v(r,e){r=n(r,e),t.point(r[0],r[1])}function E(){f=NaN,d.point=y,t.lineStart()}function y(r,i){var o=en([r,i]),u=n(r,i);e(f,p,l,s,h,g,f=u[0],p=u[1],l=r,s=o[0],h=o[1],g=o[2],Kr,t),t.point(f,p)}function S(){d.point=v,t.lineEnd()}function m(){E(),d.point=M,d.lineEnd=w}function M(n,t){y(r=n,t),i=f,o=p,u=s,a=h,c=g,d.point=y}function w(){e(f,p,l,s,h,g,i,o,r,u,a,c,Kr,t),d.lineEnd=S,S()}return d}}(n,t):function(n){return Xr({point:function(t,r){t=n(t,r),this.stream.point(t[0],t[1])}})}(n)}var ne=Xr({point:function(n,t){this.stream.point(n*l,t*l)}});function te(n,t,r,e,i,o){if(!o)return function(n,t,r,e,i){function o(o,u){return[t+n*(o*=e),r-n*(u*=i)]}return o.invert=function(o,u){return[(o-t)/n*e,(r-u)/n*i]},o}(n,t,r,e,i);var u=h(o),a=S(o),c=u*n,l=a*n,f=u/n,p=a/n,s=(a*r-u*t)/n,g=(a*t+u*r)/n;function d(n,o){return[c*(n*=e)-l*(o*=i)+t,r-l*n-c*o]}return d.invert=function(n,t){return[e*(f*n-p*t+s),i*(g-p*n-f*t)]},d}function re(n){return ee((function(){return n}))()}function ee(n){var t,r,e,i,o,u,a,f,p,s,h=150,g=480,d=250,v=0,E=0,y=0,S=0,m=0,w=0,x=1,_=1,N=null,A=gt,R=null,C=Bt,P=.5;function $(n){return f(n[0]*l,n[1]*l)}function q(n){return(n=f.invert(n[0],n[1]))&&[n[0]*c,n[1]*c]}function j(){var n=te(h,0,0,x,_,w).apply(null,t(v,E)),e=te(h,g-n[0],d-n[1],x,_,w);return r=Kn(y,S,m),a=Zn(t,e),f=Zn(r,a),u=Vr(a,P),z()}function z(){return p=s=null,$}return $.stream=function(n){return p&&s===n?p:p=ne(function(n){return Xr({point:function(t,r){var e=n(t,r);return this.stream.point(e[0],e[1])}})}(r)(A(u(C(s=n)))))},$.preclip=function(n){return arguments.length?(A=n,N=void 0,z()):A},$.postclip=function(n){return arguments.length?(C=n,R=e=i=o=null,z()):C},$.clipAngle=function(n){return arguments.length?(A=+n?dt(N=n*l):(N=null,gt),z()):N*c},$.clipExtent=function(n){return arguments.length?(C=null==n?(R=e=i=o=null,Bt):wt(R=+n[0][0],e=+n[0][1],i=+n[1][0],o=+n[1][1]),z()):null==R?null:[[R,e],[i,o]]},$.scale=function(n){return arguments.length?(h=+n,j()):h},$.translate=function(n){return arguments.length?(g=+n[0],d=+n[1],j()):[g,d]},$.center=function(n){return arguments.length?(v=n[0]%360*l,E=n[1]%360*l,j()):[v*c,E*c]},$.rotate=function(n){return arguments.length?(y=n[0]%360*l,S=n[1]%360*l,m=n.length>2?n[2]%360*l:0,j()):[y*c,S*c,m*c]},$.angle=function(n){return arguments.length?(w=n%360*l,j()):w*c},$.reflectX=function(n){return arguments.length?(x=n?-1:1,j()):x<0},$.reflectY=function(n){return arguments.length?(_=n?-1:1,j()):_<0},$.precision=function(n){return arguments.length?(u=Vr(a,P=n*n),z()):M(P)},$.fitExtent=function(n,t){return Dr($,n,t)},$.fitSize=function(n,t){return Ur($,n,t)},$.fitWidth=function(n,t){return Zr($,n,t)},$.fitHeight=function(n,t){return Jr($,n,t)},function(){return t=n.apply(this,arguments),$.invert=t.invert&&q,j()}}function ie(n){var t=0,r=i/3,e=ee(n),o=e(t,r);return o.parallels=function(n){return arguments.length?e(t=n[0]*l,r=n[1]*l):[t*c,r*c]},o}function oe(n,t){var e=S(n),o=(e+S(t))/2;if(f(o)<r)return function(n){var t=h(n);function r(n,r){return[n*t,S(r)/t]}return r.invert=function(n,r){return[n/t,_(r*t)]},r}(n);var u=1+e*(2*o-e),a=M(u)/o;function c(n,t){var r=M(u-2*o*S(t))/o;return[r*S(n*=o),a-r*h(n)]}return c.invert=function(n,t){var r=a-t,e=s(n,f(r))*m(r);return r*o<0&&(e-=i*m(n)*m(r)),[e/o,_((u-(n*n+r*r)*o*o)/(2*o))]},c}function ue(){return ie(oe).scale(155.424).center([0,33.6442])}function ae(){return ue().parallels([29.5,45.5]).scale(1070).translate([480,250]).rotate([96,0]).center([-.6,38.7])}function ce(n){return function(t,r){var e=h(t),i=h(r),o=n(e*i);return o===1/0?[2,0]:[o*i*S(t),o*S(r)]}}function le(n){return function(t,r){var e=M(t*t+r*r),i=n(e),o=S(i),u=h(i);return[s(t*o,e*u),_(e&&r*o/e)]}}var fe=ce((function(n){return M(2/(1+n))}));fe.invert=le((function(n){return 2*_(n/2)}));var pe=ce((function(n){return(n=x(n))&&n/S(n)}));function se(n,t){return[n,E(w((o+t)/2))]}function he(n){var t,r,e,o=re(n),u=o.center,a=o.scale,c=o.translate,l=o.clipExtent,f=null;function p(){var u=i*a(),c=o(tt(o.rotate()).invert([0,0]));return l(null==f?[[c[0]-u,c[1]-u],[c[0]+u,c[1]+u]]:n===se?[[Math.max(c[0]-u,f),t],[Math.min(c[0]+u,r),e]]:[[f,Math.max(c[1]-u,t)],[r,Math.min(c[1]+u,e)]])}return o.scale=function(n){return arguments.length?(a(n),p()):a()},o.translate=function(n){return arguments.length?(c(n),p()):c()},o.center=function(n){return arguments.length?(u(n),p()):u()},o.clipExtent=function(n){return arguments.length?(null==n?f=t=r=e=null:(f=+n[0][0],t=+n[0][1],r=+n[1][0],e=+n[1][1]),p()):null==f?null:[[f,t],[r,e]]},p()}function ge(n){return w((o+n)/2)}function de(n,t){var e=h(n),u=n===t?S(n):E(e/h(t))/E(ge(t)/ge(n)),a=e*y(ge(n),u)/u;if(!u)return se;function c(n,t){a>0?t<-o+r&&(t=-o+r):t>o-r&&(t=o-r);var e=a/y(ge(t),u);return[e*S(u*n),a-e*h(u*n)]}return c.invert=function(n,t){var r=a-t,e=m(u)*M(n*n+r*r),c=s(n,f(r))*m(r);return r*u<0&&(c-=i*m(n)*m(r)),[c/u,2*p(y(a/e,1/u))-o]},c}function ve(n,t){return[n,t]}function Ee(n,t){var e=h(n),o=n===t?S(n):(e-h(t))/(t-n),u=e/o+n;if(f(o)<r)return ve;function a(n,t){var r=u-t,e=o*n;return[r*S(e),u-r*h(e)]}return a.invert=function(n,t){var r=u-t,e=s(n,f(r))*m(r);return r*o<0&&(e-=i*m(n)*m(r)),[e/o,u-m(o)*M(n*n+r*r)]},a}pe.invert=le((function(n){return n})),se.invert=function(n,t){return[n,2*p(d(t))-o]},ve.invert=ve;var ye=1.340264,Se=-.081106,me=893e-6,Me=.003796,we=M(3)/2;function xe(n,t){var r=_(we*S(t)),e=r*r,i=e*e*e;return[n*h(r)/(we*(ye+3*Se*e+i*(7*me+9*Me*e))),r*(ye+Se*e+i*(me+Me*e))]}function _e(n,t){var r=h(t),e=h(n)*r;return[r*S(n)/e,S(t)/e]}function Ne(n,t){var r=t*t,e=r*r;return[n*(.8707-.131979*r+e*(e*(.003971*r-.001529*e)-.013791)),t*(1.007226+r*(.015085+e*(.028874*r-.044475-.005916*e)))]}function Ae(n,t){return[h(t)*S(n),S(t)]}function Re(n,t){var r=h(t),e=1+h(n)*r;return[r*S(n)/e,S(t)/e]}function Ce(n,t){return[E(w((o+t)/2)),-n]}xe.invert=function(n,t){for(var r,i=t,o=i*i,u=o*o*o,a=0;a<12&&(u=(o=(i-=r=(i*(ye+Se*o+u*(me+Me*o))-t)/(ye+3*Se*o+u*(7*me+9*Me*o)))*i)*o*o,!(f(r)<e));++a);return[we*n*(ye+3*Se*o+u*(7*me+9*Me*o))/h(i),_(S(i)/we)]},_e.invert=le(p),Ne.invert=function(n,t){var e,i=t,o=25;do{var u=i*i,a=u*u;i-=e=(i*(1.007226+u*(.015085+a*(.028874*u-.044475-.005916*a)))-t)/(1.007226+u*(.045255+a*(.259866*u-.311325-.005916*11*a)))}while(f(e)>r&&--o>0);return[n/(.8707+(u=i*i)*(u*(u*u*u*(.003971-.001529*u)-.013791)-.131979)),i]},Ae.invert=le(_),Re.invert=le((function(n){return 2*p(n)})),Ce.invert=function(n,t){return[-t,2*p(d(n))-o]},n.geoAlbers=ae,n.geoAlbersUsa=function(){var n,t,e,i,o,u,a=ae(),c=ue().rotate([154,0]).center([-2,58.5]).parallels([55,65]),l=ue().rotate([157,0]).center([-3,19.9]).parallels([8,18]),f={point:function(n,t){u=[n,t]}};function p(n){var t=n[0],r=n[1];return u=null,e.point(t,r),u||(i.point(t,r),u)||(o.point(t,r),u)}function s(){return n=t=null,p}return p.invert=function(n){var t=a.scale(),r=a.translate(),e=(n[0]-r[0])/t,i=(n[1]-r[1])/t;return(i>=.12&&i<.234&&e>=-.425&&e<-.214?c:i>=.166&&i<.234&&e>=-.214&&e<-.115?l:a).invert(n)},p.stream=function(r){return n&&t===r?n:(e=[a.stream(t=r),c.stream(r),l.stream(r)],i=e.length,n={point:function(n,t){for(var r=-1;++r<i;)e[r].point(n,t)},sphere:function(){for(var n=-1;++n<i;)e[n].sphere()},lineStart:function(){for(var n=-1;++n<i;)e[n].lineStart()},lineEnd:function(){for(var n=-1;++n<i;)e[n].lineEnd()},polygonStart:function(){for(var n=-1;++n<i;)e[n].polygonStart()},polygonEnd:function(){for(var n=-1;++n<i;)e[n].polygonEnd()}});var e,i},p.precision=function(n){return arguments.length?(a.precision(n),c.precision(n),l.precision(n),s()):a.precision()},p.scale=function(n){return arguments.length?(a.scale(n),c.scale(.35*n),l.scale(n),p.translate(a.translate())):a.scale()},p.translate=function(n){if(!arguments.length)return a.translate();var t=a.scale(),u=+n[0],p=+n[1];return e=a.translate(n).clipExtent([[u-.455*t,p-.238*t],[u+.455*t,p+.238*t]]).stream(f),i=c.translate([u-.307*t,p+.201*t]).clipExtent([[u-.425*t+r,p+.12*t+r],[u-.214*t-r,p+.234*t-r]]).stream(f),o=l.translate([u-.205*t,p+.212*t]).clipExtent([[u-.214*t+r,p+.166*t+r],[u-.115*t-r,p+.234*t-r]]).stream(f),s()},p.fitExtent=function(n,t){return Dr(p,n,t)},p.fitSize=function(n,t){return Ur(p,n,t)},p.fitWidth=function(n,t){return Zr(p,n,t)},p.fitHeight=function(n,t){return Jr(p,n,t)},p.scale(1070)},n.geoArea=function(n){return J=new t.Adder,j(n,K),2*J},n.geoAzimuthalEqualArea=function(){return re(fe).scale(124.75).clipAngle(179.999)},n.geoAzimuthalEqualAreaRaw=fe,n.geoAzimuthalEquidistant=function(){return re(pe).scale(79.4188).clipAngle(179.999)},n.geoAzimuthalEquidistantRaw=pe,n.geoBounds=function(n){var t,r,e,i,o,u,a;if(H=F=-(O=k=1/0),D=[],j(n,An),r=D.length){for(D.sort(Ln),t=1,o=[e=D[0]];t<r;++t)Tn(e,(i=D[t])[0])||Tn(e,i[1])?(bn(e[0],i[1])>bn(e[0],e[1])&&(e[1]=i[1]),bn(i[0],e[1])>bn(e[0],e[1])&&(e[0]=i[0])):o.push(e=i);for(u=-1/0,t=0,e=o[r=o.length-1];t<=r;e=i,++t)i=o[t],(a=bn(e[1],i[0]))>u&&(u=a,O=i[0],F=e[1])}return D=U=null,O===1/0||k===1/0?[[NaN,NaN],[NaN,NaN]]:[[O,k],[F,H]]},n.geoCentroid=function(n){fn=pn=sn=hn=gn=dn=vn=En=0,yn=new t.Adder,Sn=new t.Adder,mn=new t.Adder,j(n,Gn);var i=+yn,o=+Sn,u=+mn,a=v(i,o,u);return a<e&&(i=dn,o=vn,u=En,pn<r&&(i=sn,o=hn,u=gn),(a=v(i,o,u))<e)?[NaN,NaN]:[s(o,i)*c,_(u/a)*c]},n.geoCircle=function(){var n,t,r=Un([0,0]),e=Un(90),i=Un(2),o={point:function(r,e){n.push(r=t(r,e)),r[0]*=c,r[1]*=c}};function u(){var u=r.apply(this,arguments),a=e.apply(this,arguments)*l,c=i.apply(this,arguments)*l;return n=[],t=Kn(-u[0]*l,-u[1]*l,0).invert,rt(o,a,c,1),u={type:"Polygon",coordinates:[n]},n=t=null,u}return u.center=function(n){return arguments.length?(r="function"==typeof n?n:Un([+n[0],+n[1]]),u):r},u.radius=function(n){return arguments.length?(e="function"==typeof n?n:Un(+n),u):e},u.precision=function(n){return arguments.length?(i="function"==typeof n?n:Un(+n),u):i},u},n.geoClipAntimeridian=gt,n.geoClipCircle=dt,n.geoClipExtent=function(){var n,t,r,e=0,i=0,o=960,u=500;return r={stream:function(r){return n&&t===r?n:n=wt(e,i,o,u)(t=r)},extent:function(a){return arguments.length?(e=+a[0][0],i=+a[0][1],o=+a[1][0],u=+a[1][1],n=t=null,r):[[e,i],[o,u]]}}},n.geoClipRectangle=wt,n.geoConicConformal=function(){return ie(de).scale(109.5).parallels([30,30])},n.geoConicConformalRaw=de,n.geoConicEqualArea=ue,n.geoConicEqualAreaRaw=oe,n.geoConicEquidistant=function(){return ie(Ee).scale(131.154).center([0,13.9389])},n.geoConicEquidistantRaw=Ee,n.geoContains=function(n,t){return(n&&qt.hasOwnProperty(n.type)?qt[n.type]:zt)(n,t)},n.geoDistance=$t,n.geoEqualEarth=function(){return re(xe).scale(177.158)},n.geoEqualEarthRaw=xe,n.geoEquirectangular=function(){return re(ve).scale(152.63)},n.geoEquirectangularRaw=ve,n.geoGnomonic=function(){return re(_e).scale(144.049).clipAngle(60)},n.geoGnomonicRaw=_e,n.geoGraticule=Ht,n.geoGraticule10=function(){return Ht()()},n.geoIdentity=function(){var n,t,r,e,i,o,u,a=1,f=0,p=0,s=1,g=1,d=0,v=null,E=1,y=1,m=Xr({point:function(n,t){var r=x([n,t]);this.stream.point(r[0],r[1])}}),M=Bt;function w(){return E=a*s,y=a*g,o=u=null,x}function x(r){var e=r[0]*E,i=r[1]*y;if(d){var o=i*n-e*t;e=e*n+i*t,i=o}return[e+f,i+p]}return x.invert=function(r){var e=r[0]-f,i=r[1]-p;if(d){var o=i*n+e*t;e=e*n-i*t,i=o}return[e/E,i/y]},x.stream=function(n){return o&&u===n?o:o=m(M(u=n))},x.postclip=function(n){return arguments.length?(M=n,v=r=e=i=null,w()):M},x.clipExtent=function(n){return arguments.length?(M=null==n?(v=r=e=i=null,Bt):wt(v=+n[0][0],r=+n[0][1],e=+n[1][0],i=+n[1][1]),w()):null==v?null:[[v,r],[e,i]]},x.scale=function(n){return arguments.length?(a=+n,w()):a},x.translate=function(n){return arguments.length?(f=+n[0],p=+n[1],w()):[f,p]},x.angle=function(r){return arguments.length?(t=S(d=r%360*l),n=h(d),w()):d*c},x.reflectX=function(n){return arguments.length?(s=n?-1:1,w()):s<0},x.reflectY=function(n){return arguments.length?(g=n?-1:1,w()):g<0},x.fitExtent=function(n,t){return Dr(x,n,t)},x.fitSize=function(n,t){return Ur(x,n,t)},x.fitWidth=function(n,t){return Zr(x,n,t)},x.fitHeight=function(n,t){return Jr(x,n,t)},x},n.geoInterpolate=function(n,t){var r=n[0]*l,e=n[1]*l,i=t[0]*l,o=t[1]*l,u=h(e),a=S(e),f=h(o),p=S(o),g=u*h(r),d=u*S(r),v=f*h(i),E=f*S(i),y=2*_(M(N(o-e)+u*f*N(i-r))),m=S(y),w=y?function(n){var t=S(n*=y)/m,r=S(y-n)/m,e=r*g+t*v,i=r*d+t*E,o=r*a+t*p;return[s(i,e)*c,s(o,M(e*e+i*i))*c]}:function(){return[r*c,e*c]};return w.distance=y,w},n.geoLength=Rt,n.geoMercator=function(){return he(se).scale(961/a)},n.geoMercatorRaw=se,n.geoNaturalEarth1=function(){return re(Ne).scale(175.295)},n.geoNaturalEarth1Raw=Ne,n.geoOrthographic=function(){return re(Ae).scale(249.5).clipAngle(90+r)},n.geoOrthographicRaw=Ae,n.geoPath=function(n,t){let r,e,i=3,o=4.5;function u(n){return n&&("function"==typeof o&&e.pointRadius(+o.apply(this,arguments)),j(n,r(e))),e.result()}return u.area=function(n){return j(n,r(Zt)),Zt.result()},u.measure=function(n){return j(n,r(Lr)),Lr.result()},u.bounds=function(n){return j(n,r(ir)),ir.result()},u.centroid=function(n){return j(n,r(yr)),yr.result()},u.projection=function(t){return arguments.length?(r=null==t?(n=null,Bt):(n=t).stream,u):n},u.context=function(n){return arguments.length?(e=null==n?(t=null,new Ir(i)):new Cr(t=n),"function"!=typeof o&&e.pointRadius(o),u):t},u.pointRadius=function(n){return arguments.length?(o="function"==typeof n?n:(e.pointRadius(+n),+n),u):o},u.digits=function(n){if(!arguments.length)return i;if(null==n)i=null;else{const t=Math.floor(n);if(!(t>=0))throw new RangeError(`invalid digits: ${n}`);i=t}return null===t&&(e=new Ir(i)),u},u.projection(n).digits(i).context(t)},n.geoProjection=re,n.geoProjectionMutator=ee,n.geoRotation=tt,n.geoStereographic=function(){return re(Re).scale(250).clipAngle(142)},n.geoStereographicRaw=Re,n.geoStream=j,n.geoTransform=function(n){return{stream:Xr(n)}},n.geoTransverseMercator=function(){var n=he(Ce),t=n.center,r=n.rotate;return n.center=function(n){return arguments.length?t([-n[1],n[0]]):[(n=t())[1],-n[0]]},n.rotate=function(n){return arguments.length?r([n[0],n[1],n.length>2?n[2]+90:90]):[(n=r())[0],n[1],n[2]-90]},r([0,0,90]).scale(159.155)},n.geoTransverseMercatorRaw=Ce}));
Index: node_modules/d3-geo/package.json
===================================================================
--- node_modules/d3-geo/package.json	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/package.json	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,59 @@
+{
+  "name": "d3-geo",
+  "version": "3.1.1",
+  "description": "Shapes and calculators for spherical coordinates.",
+  "homepage": "https://d3js.org/d3-geo/",
+  "repository": {
+    "type": "git",
+    "url": "https://github.com/d3/d3-geo.git"
+  },
+  "keywords": [
+    "d3",
+    "d3-module",
+    "geo",
+    "maps",
+    "cartography"
+  ],
+  "license": "ISC",
+  "author": {
+    "name": "Mike Bostock",
+    "url": "https://bost.ocks.org/mike"
+  },
+  "type": "module",
+  "files": [
+    "dist/**/*.js",
+    "src/**/*.js"
+  ],
+  "module": "src/index.js",
+  "main": "src/index.js",
+  "jsdelivr": "dist/d3-geo.min.js",
+  "unpkg": "dist/d3-geo.min.js",
+  "exports": {
+    "umd": "./dist/d3-geo.min.js",
+    "default": "./src/index.js"
+  },
+  "sideEffects": false,
+  "dependencies": {
+    "d3-array": "2.5.0 - 3"
+  },
+  "devDependencies": {
+    "@rollup/plugin-terser": "0.4",
+    "canvas": "2",
+    "d3-format": "1 - 3",
+    "eslint": "8",
+    "mocha": "10",
+    "pixelmatch": "5",
+    "pngjs": "6",
+    "rollup": "3",
+    "topojson-client": "3",
+    "world-atlas": "1"
+  },
+  "scripts": {
+    "test": "mocha 'test/**/*-test.js' && eslint src test",
+    "prepublishOnly": "rm -rf dist && rollup -c",
+    "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 -"
+  },
+  "engines": {
+    "node": ">=12"
+  }
+}
Index: node_modules/d3-geo/src/area.js
===================================================================
--- node_modules/d3-geo/src/area.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/area.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,76 @@
+import {Adder} from "d3-array";
+import {atan2, cos, quarterPi, radians, sin, tau} from "./math.js";
+import noop from "./noop.js";
+import stream from "./stream.js";
+
+export var areaRingSum = new Adder();
+
+// hello?
+
+var areaSum = new Adder(),
+    lambda00,
+    phi00,
+    lambda0,
+    cosPhi0,
+    sinPhi0;
+
+export var areaStream = {
+  point: noop,
+  lineStart: noop,
+  lineEnd: noop,
+  polygonStart: function() {
+    areaRingSum = new Adder();
+    areaStream.lineStart = areaRingStart;
+    areaStream.lineEnd = areaRingEnd;
+  },
+  polygonEnd: function() {
+    var areaRing = +areaRingSum;
+    areaSum.add(areaRing < 0 ? tau + areaRing : areaRing);
+    this.lineStart = this.lineEnd = this.point = noop;
+  },
+  sphere: function() {
+    areaSum.add(tau);
+  }
+};
+
+function areaRingStart() {
+  areaStream.point = areaPointFirst;
+}
+
+function areaRingEnd() {
+  areaPoint(lambda00, phi00);
+}
+
+function areaPointFirst(lambda, phi) {
+  areaStream.point = areaPoint;
+  lambda00 = lambda, phi00 = phi;
+  lambda *= radians, phi *= radians;
+  lambda0 = lambda, cosPhi0 = cos(phi = phi / 2 + quarterPi), sinPhi0 = sin(phi);
+}
+
+function areaPoint(lambda, phi) {
+  lambda *= radians, phi *= radians;
+  phi = phi / 2 + quarterPi; // half the angular distance from south pole
+
+  // Spherical excess E for a spherical triangle with vertices: south pole,
+  // previous point, current point.  Uses a formula derived from Cagnoli’s
+  // theorem.  See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2).
+  var dLambda = lambda - lambda0,
+      sdLambda = dLambda >= 0 ? 1 : -1,
+      adLambda = sdLambda * dLambda,
+      cosPhi = cos(phi),
+      sinPhi = sin(phi),
+      k = sinPhi0 * sinPhi,
+      u = cosPhi0 * cosPhi + k * cos(adLambda),
+      v = k * sdLambda * sin(adLambda);
+  areaRingSum.add(atan2(v, u));
+
+  // Advance the previous points.
+  lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi;
+}
+
+export default function(object) {
+  areaSum = new Adder();
+  stream(object, areaStream);
+  return areaSum * 2;
+}
Index: node_modules/d3-geo/src/bounds.js
===================================================================
--- node_modules/d3-geo/src/bounds.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/bounds.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,179 @@
+import {Adder} from "d3-array";
+import {areaStream, areaRingSum} from "./area.js";
+import {cartesian, cartesianCross, cartesianNormalizeInPlace, spherical} from "./cartesian.js";
+import {abs, degrees, epsilon, radians} from "./math.js";
+import stream from "./stream.js";
+
+var lambda0, phi0, lambda1, phi1, // bounds
+    lambda2, // previous lambda-coordinate
+    lambda00, phi00, // first point
+    p0, // previous 3D point
+    deltaSum,
+    ranges,
+    range;
+
+var boundsStream = {
+  point: boundsPoint,
+  lineStart: boundsLineStart,
+  lineEnd: boundsLineEnd,
+  polygonStart: function() {
+    boundsStream.point = boundsRingPoint;
+    boundsStream.lineStart = boundsRingStart;
+    boundsStream.lineEnd = boundsRingEnd;
+    deltaSum = new Adder();
+    areaStream.polygonStart();
+  },
+  polygonEnd: function() {
+    areaStream.polygonEnd();
+    boundsStream.point = boundsPoint;
+    boundsStream.lineStart = boundsLineStart;
+    boundsStream.lineEnd = boundsLineEnd;
+    if (areaRingSum < 0) lambda0 = -(lambda1 = 180), phi0 = -(phi1 = 90);
+    else if (deltaSum > epsilon) phi1 = 90;
+    else if (deltaSum < -epsilon) phi0 = -90;
+    range[0] = lambda0, range[1] = lambda1;
+  },
+  sphere: function() {
+    lambda0 = -(lambda1 = 180), phi0 = -(phi1 = 90);
+  }
+};
+
+function boundsPoint(lambda, phi) {
+  ranges.push(range = [lambda0 = lambda, lambda1 = lambda]);
+  if (phi < phi0) phi0 = phi;
+  if (phi > phi1) phi1 = phi;
+}
+
+function linePoint(lambda, phi) {
+  var p = cartesian([lambda * radians, phi * radians]);
+  if (p0) {
+    var normal = cartesianCross(p0, p),
+        equatorial = [normal[1], -normal[0], 0],
+        inflection = cartesianCross(equatorial, normal);
+    cartesianNormalizeInPlace(inflection);
+    inflection = spherical(inflection);
+    var delta = lambda - lambda2,
+        sign = delta > 0 ? 1 : -1,
+        lambdai = inflection[0] * degrees * sign,
+        phii,
+        antimeridian = abs(delta) > 180;
+    if (antimeridian ^ (sign * lambda2 < lambdai && lambdai < sign * lambda)) {
+      phii = inflection[1] * degrees;
+      if (phii > phi1) phi1 = phii;
+    } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign * lambda2 < lambdai && lambdai < sign * lambda)) {
+      phii = -inflection[1] * degrees;
+      if (phii < phi0) phi0 = phii;
+    } else {
+      if (phi < phi0) phi0 = phi;
+      if (phi > phi1) phi1 = phi;
+    }
+    if (antimeridian) {
+      if (lambda < lambda2) {
+        if (angle(lambda0, lambda) > angle(lambda0, lambda1)) lambda1 = lambda;
+      } else {
+        if (angle(lambda, lambda1) > angle(lambda0, lambda1)) lambda0 = lambda;
+      }
+    } else {
+      if (lambda1 >= lambda0) {
+        if (lambda < lambda0) lambda0 = lambda;
+        if (lambda > lambda1) lambda1 = lambda;
+      } else {
+        if (lambda > lambda2) {
+          if (angle(lambda0, lambda) > angle(lambda0, lambda1)) lambda1 = lambda;
+        } else {
+          if (angle(lambda, lambda1) > angle(lambda0, lambda1)) lambda0 = lambda;
+        }
+      }
+    }
+  } else {
+    ranges.push(range = [lambda0 = lambda, lambda1 = lambda]);
+  }
+  if (phi < phi0) phi0 = phi;
+  if (phi > phi1) phi1 = phi;
+  p0 = p, lambda2 = lambda;
+}
+
+function boundsLineStart() {
+  boundsStream.point = linePoint;
+}
+
+function boundsLineEnd() {
+  range[0] = lambda0, range[1] = lambda1;
+  boundsStream.point = boundsPoint;
+  p0 = null;
+}
+
+function boundsRingPoint(lambda, phi) {
+  if (p0) {
+    var delta = lambda - lambda2;
+    deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta);
+  } else {
+    lambda00 = lambda, phi00 = phi;
+  }
+  areaStream.point(lambda, phi);
+  linePoint(lambda, phi);
+}
+
+function boundsRingStart() {
+  areaStream.lineStart();
+}
+
+function boundsRingEnd() {
+  boundsRingPoint(lambda00, phi00);
+  areaStream.lineEnd();
+  if (abs(deltaSum) > epsilon) lambda0 = -(lambda1 = 180);
+  range[0] = lambda0, range[1] = lambda1;
+  p0 = null;
+}
+
+// Finds the left-right distance between two longitudes.
+// This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want
+// the distance between ±180° to be 360°.
+function angle(lambda0, lambda1) {
+  return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1;
+}
+
+function rangeCompare(a, b) {
+  return a[0] - b[0];
+}
+
+function rangeContains(range, x) {
+  return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;
+}
+
+export default function(feature) {
+  var i, n, a, b, merged, deltaMax, delta;
+
+  phi1 = lambda1 = -(lambda0 = phi0 = Infinity);
+  ranges = [];
+  stream(feature, boundsStream);
+
+  // First, sort ranges by their minimum longitudes.
+  if (n = ranges.length) {
+    ranges.sort(rangeCompare);
+
+    // Then, merge any ranges that overlap.
+    for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) {
+      b = ranges[i];
+      if (rangeContains(a, b[0]) || rangeContains(a, b[1])) {
+        if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1];
+        if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0];
+      } else {
+        merged.push(a = b);
+      }
+    }
+
+    // Finally, find the largest gap between the merged ranges.
+    // The final bounding box will be the inverse of this gap.
+    for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) {
+      b = merged[i];
+      if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0 = b[0], lambda1 = a[1];
+    }
+  }
+
+  ranges = range = null;
+
+  return lambda0 === Infinity || phi0 === Infinity
+      ? [[NaN, NaN], [NaN, NaN]]
+      : [[lambda0, phi0], [lambda1, phi1]];
+}
Index: node_modules/d3-geo/src/cartesian.js
===================================================================
--- node_modules/d3-geo/src/cartesian.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/cartesian.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,33 @@
+import {asin, atan2, cos, sin, sqrt} from "./math.js";
+
+export function spherical(cartesian) {
+  return [atan2(cartesian[1], cartesian[0]), asin(cartesian[2])];
+}
+
+export function cartesian(spherical) {
+  var lambda = spherical[0], phi = spherical[1], cosPhi = cos(phi);
+  return [cosPhi * cos(lambda), cosPhi * sin(lambda), sin(phi)];
+}
+
+export function cartesianDot(a, b) {
+  return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
+}
+
+export function cartesianCross(a, b) {
+  return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
+}
+
+// TODO return a
+export function cartesianAddInPlace(a, b) {
+  a[0] += b[0], a[1] += b[1], a[2] += b[2];
+}
+
+export function cartesianScale(vector, k) {
+  return [vector[0] * k, vector[1] * k, vector[2] * k];
+}
+
+// TODO return d
+export function cartesianNormalizeInPlace(d) {
+  var l = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
+  d[0] /= l, d[1] /= l, d[2] /= l;
+}
Index: node_modules/d3-geo/src/centroid.js
===================================================================
--- node_modules/d3-geo/src/centroid.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/centroid.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,143 @@
+import {Adder} from "d3-array";
+import {asin, atan2, cos, degrees, epsilon, epsilon2, hypot, radians, sin, sqrt} from "./math.js";
+import noop from "./noop.js";
+import stream from "./stream.js";
+
+var W0, W1,
+    X0, Y0, Z0,
+    X1, Y1, Z1,
+    X2, Y2, Z2,
+    lambda00, phi00, // first point
+    x0, y0, z0; // previous point
+
+var centroidStream = {
+  sphere: noop,
+  point: centroidPoint,
+  lineStart: centroidLineStart,
+  lineEnd: centroidLineEnd,
+  polygonStart: function() {
+    centroidStream.lineStart = centroidRingStart;
+    centroidStream.lineEnd = centroidRingEnd;
+  },
+  polygonEnd: function() {
+    centroidStream.lineStart = centroidLineStart;
+    centroidStream.lineEnd = centroidLineEnd;
+  }
+};
+
+// Arithmetic mean of Cartesian vectors.
+function centroidPoint(lambda, phi) {
+  lambda *= radians, phi *= radians;
+  var cosPhi = cos(phi);
+  centroidPointCartesian(cosPhi * cos(lambda), cosPhi * sin(lambda), sin(phi));
+}
+
+function centroidPointCartesian(x, y, z) {
+  ++W0;
+  X0 += (x - X0) / W0;
+  Y0 += (y - Y0) / W0;
+  Z0 += (z - Z0) / W0;
+}
+
+function centroidLineStart() {
+  centroidStream.point = centroidLinePointFirst;
+}
+
+function centroidLinePointFirst(lambda, phi) {
+  lambda *= radians, phi *= radians;
+  var cosPhi = cos(phi);
+  x0 = cosPhi * cos(lambda);
+  y0 = cosPhi * sin(lambda);
+  z0 = sin(phi);
+  centroidStream.point = centroidLinePoint;
+  centroidPointCartesian(x0, y0, z0);
+}
+
+function centroidLinePoint(lambda, phi) {
+  lambda *= radians, phi *= radians;
+  var cosPhi = cos(phi),
+      x = cosPhi * cos(lambda),
+      y = cosPhi * sin(lambda),
+      z = sin(phi),
+      w = atan2(sqrt((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z);
+  W1 += w;
+  X1 += w * (x0 + (x0 = x));
+  Y1 += w * (y0 + (y0 = y));
+  Z1 += w * (z0 + (z0 = z));
+  centroidPointCartesian(x0, y0, z0);
+}
+
+function centroidLineEnd() {
+  centroidStream.point = centroidPoint;
+}
+
+// See J. E. Brock, The Inertia Tensor for a Spherical Triangle,
+// J. Applied Mechanics 42, 239 (1975).
+function centroidRingStart() {
+  centroidStream.point = centroidRingPointFirst;
+}
+
+function centroidRingEnd() {
+  centroidRingPoint(lambda00, phi00);
+  centroidStream.point = centroidPoint;
+}
+
+function centroidRingPointFirst(lambda, phi) {
+  lambda00 = lambda, phi00 = phi;
+  lambda *= radians, phi *= radians;
+  centroidStream.point = centroidRingPoint;
+  var cosPhi = cos(phi);
+  x0 = cosPhi * cos(lambda);
+  y0 = cosPhi * sin(lambda);
+  z0 = sin(phi);
+  centroidPointCartesian(x0, y0, z0);
+}
+
+function centroidRingPoint(lambda, phi) {
+  lambda *= radians, phi *= radians;
+  var cosPhi = cos(phi),
+      x = cosPhi * cos(lambda),
+      y = cosPhi * sin(lambda),
+      z = sin(phi),
+      cx = y0 * z - z0 * y,
+      cy = z0 * x - x0 * z,
+      cz = x0 * y - y0 * x,
+      m = hypot(cx, cy, cz),
+      w = asin(m), // line weight = angle
+      v = m && -w / m; // area weight multiplier
+  X2.add(v * cx);
+  Y2.add(v * cy);
+  Z2.add(v * cz);
+  W1 += w;
+  X1 += w * (x0 + (x0 = x));
+  Y1 += w * (y0 + (y0 = y));
+  Z1 += w * (z0 + (z0 = z));
+  centroidPointCartesian(x0, y0, z0);
+}
+
+export default function(object) {
+  W0 = W1 =
+  X0 = Y0 = Z0 =
+  X1 = Y1 = Z1 = 0;
+  X2 = new Adder();
+  Y2 = new Adder();
+  Z2 = new Adder();
+  stream(object, centroidStream);
+
+  var x = +X2,
+      y = +Y2,
+      z = +Z2,
+      m = hypot(x, y, z);
+
+  // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid.
+  if (m < epsilon2) {
+    x = X1, y = Y1, z = Z1;
+    // If the feature has zero length, fall back to arithmetic mean of point vectors.
+    if (W1 < epsilon) x = X0, y = Y0, z = Z0;
+    m = hypot(x, y, z);
+    // If the feature still has an undefined ccentroid, then return.
+    if (m < epsilon2) return [NaN, NaN];
+  }
+
+  return [atan2(y, x) * degrees, asin(z / m) * degrees];
+}
Index: node_modules/d3-geo/src/circle.js
===================================================================
--- node_modules/d3-geo/src/circle.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/circle.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,72 @@
+import {cartesian, cartesianNormalizeInPlace, spherical} from "./cartesian.js";
+import constant from "./constant.js";
+import {acos, cos, degrees, epsilon, radians, sin, tau} from "./math.js";
+import {rotateRadians} from "./rotation.js";
+
+// Generates a circle centered at [0°, 0°], with a given radius and precision.
+export function circleStream(stream, radius, delta, direction, t0, t1) {
+  if (!delta) return;
+  var cosRadius = cos(radius),
+      sinRadius = sin(radius),
+      step = direction * delta;
+  if (t0 == null) {
+    t0 = radius + direction * tau;
+    t1 = radius - step / 2;
+  } else {
+    t0 = circleRadius(cosRadius, t0);
+    t1 = circleRadius(cosRadius, t1);
+    if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau;
+  }
+  for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) {
+    point = spherical([cosRadius, -sinRadius * cos(t), -sinRadius * sin(t)]);
+    stream.point(point[0], point[1]);
+  }
+}
+
+// Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0].
+function circleRadius(cosRadius, point) {
+  point = cartesian(point), point[0] -= cosRadius;
+  cartesianNormalizeInPlace(point);
+  var radius = acos(-point[1]);
+  return ((-point[2] < 0 ? -radius : radius) + tau - epsilon) % tau;
+}
+
+export default function() {
+  var center = constant([0, 0]),
+      radius = constant(90),
+      precision = constant(2),
+      ring,
+      rotate,
+      stream = {point: point};
+
+  function point(x, y) {
+    ring.push(x = rotate(x, y));
+    x[0] *= degrees, x[1] *= degrees;
+  }
+
+  function circle() {
+    var c = center.apply(this, arguments),
+        r = radius.apply(this, arguments) * radians,
+        p = precision.apply(this, arguments) * radians;
+    ring = [];
+    rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert;
+    circleStream(stream, r, p, 1);
+    c = {type: "Polygon", coordinates: [ring]};
+    ring = rotate = null;
+    return c;
+  }
+
+  circle.center = function(_) {
+    return arguments.length ? (center = typeof _ === "function" ? _ : constant([+_[0], +_[1]]), circle) : center;
+  };
+
+  circle.radius = function(_) {
+    return arguments.length ? (radius = typeof _ === "function" ? _ : constant(+_), circle) : radius;
+  };
+
+  circle.precision = function(_) {
+    return arguments.length ? (precision = typeof _ === "function" ? _ : constant(+_), circle) : precision;
+  };
+
+  return circle;
+}
Index: node_modules/d3-geo/src/clip/antimeridian.js
===================================================================
--- node_modules/d3-geo/src/clip/antimeridian.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/clip/antimeridian.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,92 @@
+import clip from "./index.js";
+import {abs, atan, cos, epsilon, halfPi, pi, sin} from "../math.js";
+
+export default clip(
+  function() { return true; },
+  clipAntimeridianLine,
+  clipAntimeridianInterpolate,
+  [-pi, -halfPi]
+);
+
+// Takes a line and cuts into visible segments. Return values: 0 - there were
+// intersections or the line was empty; 1 - no intersections; 2 - there were
+// intersections, and the first and last segments should be rejoined.
+function clipAntimeridianLine(stream) {
+  var lambda0 = NaN,
+      phi0 = NaN,
+      sign0 = NaN,
+      clean; // no intersections
+
+  return {
+    lineStart: function() {
+      stream.lineStart();
+      clean = 1;
+    },
+    point: function(lambda1, phi1) {
+      var sign1 = lambda1 > 0 ? pi : -pi,
+          delta = abs(lambda1 - lambda0);
+      if (abs(delta - pi) < epsilon) { // line crosses a pole
+        stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi : -halfPi);
+        stream.point(sign0, phi0);
+        stream.lineEnd();
+        stream.lineStart();
+        stream.point(sign1, phi0);
+        stream.point(lambda1, phi0);
+        clean = 0;
+      } else if (sign0 !== sign1 && delta >= pi) { // line crosses antimeridian
+        if (abs(lambda0 - sign0) < epsilon) lambda0 -= sign0 * epsilon; // handle degeneracies
+        if (abs(lambda1 - sign1) < epsilon) lambda1 -= sign1 * epsilon;
+        phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1);
+        stream.point(sign0, phi0);
+        stream.lineEnd();
+        stream.lineStart();
+        stream.point(sign1, phi0);
+        clean = 0;
+      }
+      stream.point(lambda0 = lambda1, phi0 = phi1);
+      sign0 = sign1;
+    },
+    lineEnd: function() {
+      stream.lineEnd();
+      lambda0 = phi0 = NaN;
+    },
+    clean: function() {
+      return 2 - clean; // if intersections, rejoin first and last segments
+    }
+  };
+}
+
+function clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) {
+  var cosPhi0,
+      cosPhi1,
+      sinLambda0Lambda1 = sin(lambda0 - lambda1);
+  return abs(sinLambda0Lambda1) > epsilon
+      ? atan((sin(phi0) * (cosPhi1 = cos(phi1)) * sin(lambda1)
+          - sin(phi1) * (cosPhi0 = cos(phi0)) * sin(lambda0))
+          / (cosPhi0 * cosPhi1 * sinLambda0Lambda1))
+      : (phi0 + phi1) / 2;
+}
+
+function clipAntimeridianInterpolate(from, to, direction, stream) {
+  var phi;
+  if (from == null) {
+    phi = direction * halfPi;
+    stream.point(-pi, phi);
+    stream.point(0, phi);
+    stream.point(pi, phi);
+    stream.point(pi, 0);
+    stream.point(pi, -phi);
+    stream.point(0, -phi);
+    stream.point(-pi, -phi);
+    stream.point(-pi, 0);
+    stream.point(-pi, phi);
+  } else if (abs(from[0] - to[0]) > epsilon) {
+    var lambda = from[0] < to[0] ? pi : -pi;
+    phi = direction * lambda / 2;
+    stream.point(-lambda, phi);
+    stream.point(0, phi);
+    stream.point(lambda, phi);
+  } else {
+    stream.point(to[0], to[1]);
+  }
+}
Index: node_modules/d3-geo/src/clip/buffer.js
===================================================================
--- node_modules/d3-geo/src/clip/buffer.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/clip/buffer.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,24 @@
+import noop from "../noop.js";
+
+export default function() {
+  var lines = [],
+      line;
+  return {
+    point: function(x, y, m) {
+      line.push([x, y, m]);
+    },
+    lineStart: function() {
+      lines.push(line = []);
+    },
+    lineEnd: noop,
+    rejoin: function() {
+      if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));
+    },
+    result: function() {
+      var result = lines;
+      lines = [];
+      line = null;
+      return result;
+    }
+  };
+}
Index: node_modules/d3-geo/src/clip/circle.js
===================================================================
--- node_modules/d3-geo/src/clip/circle.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/clip/circle.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,177 @@
+import {cartesian, cartesianAddInPlace, cartesianCross, cartesianDot, cartesianScale, spherical} from "../cartesian.js";
+import {circleStream} from "../circle.js";
+import {abs, cos, epsilon, pi, radians, sqrt} from "../math.js";
+import pointEqual from "../pointEqual.js";
+import clip from "./index.js";
+
+export default function(radius) {
+  var cr = cos(radius),
+      delta = 2 * radians,
+      smallRadius = cr > 0,
+      notHemisphere = abs(cr) > epsilon; // TODO optimise for this common case
+
+  function interpolate(from, to, direction, stream) {
+    circleStream(stream, radius, delta, direction, from, to);
+  }
+
+  function visible(lambda, phi) {
+    return cos(lambda) * cos(phi) > cr;
+  }
+
+  // Takes a line and cuts into visible segments. Return values used for polygon
+  // clipping: 0 - there were intersections or the line was empty; 1 - no
+  // intersections 2 - there were intersections, and the first and last segments
+  // should be rejoined.
+  function clipLine(stream) {
+    var point0, // previous point
+        c0, // code for previous point
+        v0, // visibility of previous point
+        v00, // visibility of first point
+        clean; // no intersections
+    return {
+      lineStart: function() {
+        v00 = v0 = false;
+        clean = 1;
+      },
+      point: function(lambda, phi) {
+        var point1 = [lambda, phi],
+            point2,
+            v = visible(lambda, phi),
+            c = smallRadius
+              ? v ? 0 : code(lambda, phi)
+              : v ? code(lambda + (lambda < 0 ? pi : -pi), phi) : 0;
+        if (!point0 && (v00 = v0 = v)) stream.lineStart();
+        if (v !== v0) {
+          point2 = intersect(point0, point1);
+          if (!point2 || pointEqual(point0, point2) || pointEqual(point1, point2))
+            point1[2] = 1;
+        }
+        if (v !== v0) {
+          clean = 0;
+          if (v) {
+            // outside going in
+            stream.lineStart();
+            point2 = intersect(point1, point0);
+            stream.point(point2[0], point2[1]);
+          } else {
+            // inside going out
+            point2 = intersect(point0, point1);
+            stream.point(point2[0], point2[1], 2);
+            stream.lineEnd();
+          }
+          point0 = point2;
+        } else if (notHemisphere && point0 && smallRadius ^ v) {
+          var t;
+          // If the codes for two points are different, or are both zero,
+          // and there this segment intersects with the small circle.
+          if (!(c & c0) && (t = intersect(point1, point0, true))) {
+            clean = 0;
+            if (smallRadius) {
+              stream.lineStart();
+              stream.point(t[0][0], t[0][1]);
+              stream.point(t[1][0], t[1][1]);
+              stream.lineEnd();
+            } else {
+              stream.point(t[1][0], t[1][1]);
+              stream.lineEnd();
+              stream.lineStart();
+              stream.point(t[0][0], t[0][1], 3);
+            }
+          }
+        }
+        if (v && (!point0 || !pointEqual(point0, point1))) {
+          stream.point(point1[0], point1[1]);
+        }
+        point0 = point1, v0 = v, c0 = c;
+      },
+      lineEnd: function() {
+        if (v0) stream.lineEnd();
+        point0 = null;
+      },
+      // Rejoin first and last segments if there were intersections and the first
+      // and last points were visible.
+      clean: function() {
+        return clean | ((v00 && v0) << 1);
+      }
+    };
+  }
+
+  // Intersects the great circle between a and b with the clip circle.
+  function intersect(a, b, two) {
+    var pa = cartesian(a),
+        pb = cartesian(b);
+
+    // We have two planes, n1.p = d1 and n2.p = d2.
+    // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2).
+    var n1 = [1, 0, 0], // normal
+        n2 = cartesianCross(pa, pb),
+        n2n2 = cartesianDot(n2, n2),
+        n1n2 = n2[0], // cartesianDot(n1, n2),
+        determinant = n2n2 - n1n2 * n1n2;
+
+    // Two polar points.
+    if (!determinant) return !two && a;
+
+    var c1 =  cr * n2n2 / determinant,
+        c2 = -cr * n1n2 / determinant,
+        n1xn2 = cartesianCross(n1, n2),
+        A = cartesianScale(n1, c1),
+        B = cartesianScale(n2, c2);
+    cartesianAddInPlace(A, B);
+
+    // Solve |p(t)|^2 = 1.
+    var u = n1xn2,
+        w = cartesianDot(A, u),
+        uu = cartesianDot(u, u),
+        t2 = w * w - uu * (cartesianDot(A, A) - 1);
+
+    if (t2 < 0) return;
+
+    var t = sqrt(t2),
+        q = cartesianScale(u, (-w - t) / uu);
+    cartesianAddInPlace(q, A);
+    q = spherical(q);
+
+    if (!two) return q;
+
+    // Two intersection points.
+    var lambda0 = a[0],
+        lambda1 = b[0],
+        phi0 = a[1],
+        phi1 = b[1],
+        z;
+
+    if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z;
+
+    var delta = lambda1 - lambda0,
+        polar = abs(delta - pi) < epsilon,
+        meridian = polar || delta < epsilon;
+
+    if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z;
+
+    // Check that the first point is between a and b.
+    if (meridian
+        ? polar
+          ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon ? phi0 : phi1)
+          : phi0 <= q[1] && q[1] <= phi1
+        : delta > pi ^ (lambda0 <= q[0] && q[0] <= lambda1)) {
+      var q1 = cartesianScale(u, (-w + t) / uu);
+      cartesianAddInPlace(q1, A);
+      return [q, spherical(q1)];
+    }
+  }
+
+  // Generates a 4-bit vector representing the location of a point relative to
+  // the small circle's bounding box.
+  function code(lambda, phi) {
+    var r = smallRadius ? radius : pi - radius,
+        code = 0;
+    if (lambda < -r) code |= 1; // left
+    else if (lambda > r) code |= 2; // right
+    if (phi < -r) code |= 4; // below
+    else if (phi > r) code |= 8; // above
+    return code;
+  }
+
+  return clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi, radius - pi]);
+}
Index: node_modules/d3-geo/src/clip/extent.js
===================================================================
--- node_modules/d3-geo/src/clip/extent.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/clip/extent.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,20 @@
+import clipRectangle from "./rectangle.js";
+
+export default function() {
+  var x0 = 0,
+      y0 = 0,
+      x1 = 960,
+      y1 = 500,
+      cache,
+      cacheStream,
+      clip;
+
+  return clip = {
+    stream: function(stream) {
+      return cache && cacheStream === stream ? cache : cache = clipRectangle(x0, y0, x1, y1)(cacheStream = stream);
+    },
+    extent: function(_) {
+      return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]];
+    }
+  };
+}
Index: node_modules/d3-geo/src/clip/index.js
===================================================================
--- node_modules/d3-geo/src/clip/index.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/clip/index.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,131 @@
+import clipBuffer from "./buffer.js";
+import clipRejoin from "./rejoin.js";
+import {epsilon, halfPi} from "../math.js";
+import polygonContains from "../polygonContains.js";
+import {merge} from "d3-array";
+
+export default function(pointVisible, clipLine, interpolate, start) {
+  return function(sink) {
+    var line = clipLine(sink),
+        ringBuffer = clipBuffer(),
+        ringSink = clipLine(ringBuffer),
+        polygonStarted = false,
+        polygon,
+        segments,
+        ring;
+
+    var clip = {
+      point: point,
+      lineStart: lineStart,
+      lineEnd: lineEnd,
+      polygonStart: function() {
+        clip.point = pointRing;
+        clip.lineStart = ringStart;
+        clip.lineEnd = ringEnd;
+        segments = [];
+        polygon = [];
+      },
+      polygonEnd: function() {
+        clip.point = point;
+        clip.lineStart = lineStart;
+        clip.lineEnd = lineEnd;
+        segments = merge(segments);
+        var startInside = polygonContains(polygon, start);
+        if (segments.length) {
+          if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
+          clipRejoin(segments, compareIntersection, startInside, interpolate, sink);
+        } else if (startInside) {
+          if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
+          sink.lineStart();
+          interpolate(null, null, 1, sink);
+          sink.lineEnd();
+        }
+        if (polygonStarted) sink.polygonEnd(), polygonStarted = false;
+        segments = polygon = null;
+      },
+      sphere: function() {
+        sink.polygonStart();
+        sink.lineStart();
+        interpolate(null, null, 1, sink);
+        sink.lineEnd();
+        sink.polygonEnd();
+      }
+    };
+
+    function point(lambda, phi) {
+      if (pointVisible(lambda, phi)) sink.point(lambda, phi);
+    }
+
+    function pointLine(lambda, phi) {
+      line.point(lambda, phi);
+    }
+
+    function lineStart() {
+      clip.point = pointLine;
+      line.lineStart();
+    }
+
+    function lineEnd() {
+      clip.point = point;
+      line.lineEnd();
+    }
+
+    function pointRing(lambda, phi) {
+      ring.push([lambda, phi]);
+      ringSink.point(lambda, phi);
+    }
+
+    function ringStart() {
+      ringSink.lineStart();
+      ring = [];
+    }
+
+    function ringEnd() {
+      pointRing(ring[0][0], ring[0][1]);
+      ringSink.lineEnd();
+
+      var clean = ringSink.clean(),
+          ringSegments = ringBuffer.result(),
+          i, n = ringSegments.length, m,
+          segment,
+          point;
+
+      ring.pop();
+      polygon.push(ring);
+      ring = null;
+
+      if (!n) return;
+
+      // No intersections.
+      if (clean & 1) {
+        segment = ringSegments[0];
+        if ((m = segment.length - 1) > 0) {
+          if (!polygonStarted) sink.polygonStart(), polygonStarted = true;
+          sink.lineStart();
+          for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]);
+          sink.lineEnd();
+        }
+        return;
+      }
+
+      // Rejoin connected segments.
+      // TODO reuse ringBuffer.rejoin()?
+      if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));
+
+      segments.push(ringSegments.filter(validSegment));
+    }
+
+    return clip;
+  };
+}
+
+function validSegment(segment) {
+  return segment.length > 1;
+}
+
+// Intersections are sorted along the clip edge. For both antimeridian cutting
+// and circle clipping, the same comparison is used.
+function compareIntersection(a, b) {
+  return ((a = a.x)[0] < 0 ? a[1] - halfPi - epsilon : halfPi - a[1])
+       - ((b = b.x)[0] < 0 ? b[1] - halfPi - epsilon : halfPi - b[1]);
+}
Index: node_modules/d3-geo/src/clip/line.js
===================================================================
--- node_modules/d3-geo/src/clip/line.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/clip/line.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,59 @@
+export default function(a, b, x0, y0, x1, y1) {
+  var ax = a[0],
+      ay = a[1],
+      bx = b[0],
+      by = b[1],
+      t0 = 0,
+      t1 = 1,
+      dx = bx - ax,
+      dy = by - ay,
+      r;
+
+  r = x0 - ax;
+  if (!dx && r > 0) return;
+  r /= dx;
+  if (dx < 0) {
+    if (r < t0) return;
+    if (r < t1) t1 = r;
+  } else if (dx > 0) {
+    if (r > t1) return;
+    if (r > t0) t0 = r;
+  }
+
+  r = x1 - ax;
+  if (!dx && r < 0) return;
+  r /= dx;
+  if (dx < 0) {
+    if (r > t1) return;
+    if (r > t0) t0 = r;
+  } else if (dx > 0) {
+    if (r < t0) return;
+    if (r < t1) t1 = r;
+  }
+
+  r = y0 - ay;
+  if (!dy && r > 0) return;
+  r /= dy;
+  if (dy < 0) {
+    if (r < t0) return;
+    if (r < t1) t1 = r;
+  } else if (dy > 0) {
+    if (r > t1) return;
+    if (r > t0) t0 = r;
+  }
+
+  r = y1 - ay;
+  if (!dy && r < 0) return;
+  r /= dy;
+  if (dy < 0) {
+    if (r > t1) return;
+    if (r > t0) t0 = r;
+  } else if (dy > 0) {
+    if (r < t0) return;
+    if (r < t1) t1 = r;
+  }
+
+  if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy;
+  if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy;
+  return true;
+}
Index: node_modules/d3-geo/src/clip/rectangle.js
===================================================================
--- node_modules/d3-geo/src/clip/rectangle.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/clip/rectangle.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,168 @@
+import {abs, epsilon} from "../math.js";
+import clipBuffer from "./buffer.js";
+import clipLine from "./line.js";
+import clipRejoin from "./rejoin.js";
+import {merge} from "d3-array";
+
+var clipMax = 1e9, clipMin = -clipMax;
+
+// TODO Use d3-polygon’s polygonContains here for the ring check?
+// TODO Eliminate duplicate buffering in clipBuffer and polygon.push?
+
+export default function clipRectangle(x0, y0, x1, y1) {
+
+  function visible(x, y) {
+    return x0 <= x && x <= x1 && y0 <= y && y <= y1;
+  }
+
+  function interpolate(from, to, direction, stream) {
+    var a = 0, a1 = 0;
+    if (from == null
+        || (a = corner(from, direction)) !== (a1 = corner(to, direction))
+        || comparePoint(from, to) < 0 ^ direction > 0) {
+      do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);
+      while ((a = (a + direction + 4) % 4) !== a1);
+    } else {
+      stream.point(to[0], to[1]);
+    }
+  }
+
+  function corner(p, direction) {
+    return abs(p[0] - x0) < epsilon ? direction > 0 ? 0 : 3
+        : abs(p[0] - x1) < epsilon ? direction > 0 ? 2 : 1
+        : abs(p[1] - y0) < epsilon ? direction > 0 ? 1 : 0
+        : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon
+  }
+
+  function compareIntersection(a, b) {
+    return comparePoint(a.x, b.x);
+  }
+
+  function comparePoint(a, b) {
+    var ca = corner(a, 1),
+        cb = corner(b, 1);
+    return ca !== cb ? ca - cb
+        : ca === 0 ? b[1] - a[1]
+        : ca === 1 ? a[0] - b[0]
+        : ca === 2 ? a[1] - b[1]
+        : b[0] - a[0];
+  }
+
+  return function(stream) {
+    var activeStream = stream,
+        bufferStream = clipBuffer(),
+        segments,
+        polygon,
+        ring,
+        x__, y__, v__, // first point
+        x_, y_, v_, // previous point
+        first,
+        clean;
+
+    var clipStream = {
+      point: point,
+      lineStart: lineStart,
+      lineEnd: lineEnd,
+      polygonStart: polygonStart,
+      polygonEnd: polygonEnd
+    };
+
+    function point(x, y) {
+      if (visible(x, y)) activeStream.point(x, y);
+    }
+
+    function polygonInside() {
+      var winding = 0;
+
+      for (var i = 0, n = polygon.length; i < n; ++i) {
+        for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) {
+          a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1];
+          if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; }
+          else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; }
+        }
+      }
+
+      return winding;
+    }
+
+    // Buffer geometry within a polygon and then clip it en masse.
+    function polygonStart() {
+      activeStream = bufferStream, segments = [], polygon = [], clean = true;
+    }
+
+    function polygonEnd() {
+      var startInside = polygonInside(),
+          cleanInside = clean && startInside,
+          visible = (segments = merge(segments)).length;
+      if (cleanInside || visible) {
+        stream.polygonStart();
+        if (cleanInside) {
+          stream.lineStart();
+          interpolate(null, null, 1, stream);
+          stream.lineEnd();
+        }
+        if (visible) {
+          clipRejoin(segments, compareIntersection, startInside, interpolate, stream);
+        }
+        stream.polygonEnd();
+      }
+      activeStream = stream, segments = polygon = ring = null;
+    }
+
+    function lineStart() {
+      clipStream.point = linePoint;
+      if (polygon) polygon.push(ring = []);
+      first = true;
+      v_ = false;
+      x_ = y_ = NaN;
+    }
+
+    // TODO rather than special-case polygons, simply handle them separately.
+    // Ideally, coincident intersection points should be jittered to avoid
+    // clipping issues.
+    function lineEnd() {
+      if (segments) {
+        linePoint(x__, y__);
+        if (v__ && v_) bufferStream.rejoin();
+        segments.push(bufferStream.result());
+      }
+      clipStream.point = point;
+      if (v_) activeStream.lineEnd();
+    }
+
+    function linePoint(x, y) {
+      var v = visible(x, y);
+      if (polygon) ring.push([x, y]);
+      if (first) {
+        x__ = x, y__ = y, v__ = v;
+        first = false;
+        if (v) {
+          activeStream.lineStart();
+          activeStream.point(x, y);
+        }
+      } else {
+        if (v && v_) activeStream.point(x, y);
+        else {
+          var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))],
+              b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))];
+          if (clipLine(a, b, x0, y0, x1, y1)) {
+            if (!v_) {
+              activeStream.lineStart();
+              activeStream.point(a[0], a[1]);
+            }
+            activeStream.point(b[0], b[1]);
+            if (!v) activeStream.lineEnd();
+            clean = false;
+          } else if (v) {
+            activeStream.lineStart();
+            activeStream.point(x, y);
+            clean = false;
+          }
+        }
+      }
+      x_ = x, y_ = y, v_ = v;
+    }
+
+    return clipStream;
+  };
+}
Index: node_modules/d3-geo/src/clip/rejoin.js
===================================================================
--- node_modules/d3-geo/src/clip/rejoin.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/clip/rejoin.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,103 @@
+import pointEqual from "../pointEqual.js";
+import {epsilon} from "../math.js";
+
+function Intersection(point, points, other, entry) {
+  this.x = point;
+  this.z = points;
+  this.o = other; // another intersection
+  this.e = entry; // is an entry?
+  this.v = false; // visited
+  this.n = this.p = null; // next & previous
+}
+
+// A generalized polygon clipping algorithm: given a polygon that has been cut
+// into its visible line segments, and rejoins the segments by interpolating
+// along the clip edge.
+export default function(segments, compareIntersection, startInside, interpolate, stream) {
+  var subject = [],
+      clip = [],
+      i,
+      n;
+
+  segments.forEach(function(segment) {
+    if ((n = segment.length - 1) <= 0) return;
+    var n, p0 = segment[0], p1 = segment[n], x;
+
+    if (pointEqual(p0, p1)) {
+      if (!p0[2] && !p1[2]) {
+        stream.lineStart();
+        for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]);
+        stream.lineEnd();
+        return;
+      }
+      // handle degenerate cases by moving the point
+      p1[0] += 2 * epsilon;
+    }
+
+    subject.push(x = new Intersection(p0, segment, null, true));
+    clip.push(x.o = new Intersection(p0, null, x, false));
+    subject.push(x = new Intersection(p1, segment, null, false));
+    clip.push(x.o = new Intersection(p1, null, x, true));
+  });
+
+  if (!subject.length) return;
+
+  clip.sort(compareIntersection);
+  link(subject);
+  link(clip);
+
+  for (i = 0, n = clip.length; i < n; ++i) {
+    clip[i].e = startInside = !startInside;
+  }
+
+  var start = subject[0],
+      points,
+      point;
+
+  while (1) {
+    // Find first unvisited intersection.
+    var current = start,
+        isSubject = true;
+    while (current.v) if ((current = current.n) === start) return;
+    points = current.z;
+    stream.lineStart();
+    do {
+      current.v = current.o.v = true;
+      if (current.e) {
+        if (isSubject) {
+          for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]);
+        } else {
+          interpolate(current.x, current.n.x, 1, stream);
+        }
+        current = current.n;
+      } else {
+        if (isSubject) {
+          points = current.p.z;
+          for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]);
+        } else {
+          interpolate(current.x, current.p.x, -1, stream);
+        }
+        current = current.p;
+      }
+      current = current.o;
+      points = current.z;
+      isSubject = !isSubject;
+    } while (!current.v);
+    stream.lineEnd();
+  }
+}
+
+function link(array) {
+  if (!(n = array.length)) return;
+  var n,
+      i = 0,
+      a = array[0],
+      b;
+  while (++i < n) {
+    a.n = b = array[i];
+    b.p = a;
+    a = b;
+  }
+  a.n = b = array[0];
+  b.p = a;
+}
Index: node_modules/d3-geo/src/compose.js
===================================================================
--- node_modules/d3-geo/src/compose.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/compose.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,12 @@
+export default function(a, b) {
+
+  function compose(x, y) {
+    return x = a(x, y), b(x[0], x[1]);
+  }
+
+  if (a.invert && b.invert) compose.invert = function(x, y) {
+    return x = b.invert(x, y), x && a.invert(x[0], x[1]);
+  };
+
+  return compose;
+}
Index: node_modules/d3-geo/src/constant.js
===================================================================
--- node_modules/d3-geo/src/constant.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/constant.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,5 @@
+export default function(x) {
+  return function() {
+    return x;
+  };
+}
Index: node_modules/d3-geo/src/contains.js
===================================================================
--- node_modules/d3-geo/src/contains.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/contains.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,97 @@
+import {default as polygonContains} from "./polygonContains.js";
+import {default as distance} from "./distance.js";
+import {epsilon2, radians} from "./math.js";
+
+var containsObjectType = {
+  Feature: function(object, point) {
+    return containsGeometry(object.geometry, point);
+  },
+  FeatureCollection: function(object, point) {
+    var features = object.features, i = -1, n = features.length;
+    while (++i < n) if (containsGeometry(features[i].geometry, point)) return true;
+    return false;
+  }
+};
+
+var containsGeometryType = {
+  Sphere: function() {
+    return true;
+  },
+  Point: function(object, point) {
+    return containsPoint(object.coordinates, point);
+  },
+  MultiPoint: function(object, point) {
+    var coordinates = object.coordinates, i = -1, n = coordinates.length;
+    while (++i < n) if (containsPoint(coordinates[i], point)) return true;
+    return false;
+  },
+  LineString: function(object, point) {
+    return containsLine(object.coordinates, point);
+  },
+  MultiLineString: function(object, point) {
+    var coordinates = object.coordinates, i = -1, n = coordinates.length;
+    while (++i < n) if (containsLine(coordinates[i], point)) return true;
+    return false;
+  },
+  Polygon: function(object, point) {
+    return containsPolygon(object.coordinates, point);
+  },
+  MultiPolygon: function(object, point) {
+    var coordinates = object.coordinates, i = -1, n = coordinates.length;
+    while (++i < n) if (containsPolygon(coordinates[i], point)) return true;
+    return false;
+  },
+  GeometryCollection: function(object, point) {
+    var geometries = object.geometries, i = -1, n = geometries.length;
+    while (++i < n) if (containsGeometry(geometries[i], point)) return true;
+    return false;
+  }
+};
+
+function containsGeometry(geometry, point) {
+  return geometry && containsGeometryType.hasOwnProperty(geometry.type)
+      ? containsGeometryType[geometry.type](geometry, point)
+      : false;
+}
+
+function containsPoint(coordinates, point) {
+  return distance(coordinates, point) === 0;
+}
+
+function containsLine(coordinates, point) {
+  var ao, bo, ab;
+  for (var i = 0, n = coordinates.length; i < n; i++) {
+    bo = distance(coordinates[i], point);
+    if (bo === 0) return true;
+    if (i > 0) {
+      ab = distance(coordinates[i], coordinates[i - 1]);
+      if (
+        ab > 0 &&
+        ao <= ab &&
+        bo <= ab &&
+        (ao + bo - ab) * (1 - Math.pow((ao - bo) / ab, 2)) < epsilon2 * ab
+      )
+        return true;
+    }
+    ao = bo;
+  }
+  return false;
+}
+
+function containsPolygon(coordinates, point) {
+  return !!polygonContains(coordinates.map(ringRadians), pointRadians(point));
+}
+
+function ringRadians(ring) {
+  return ring = ring.map(pointRadians), ring.pop(), ring;
+}
+
+function pointRadians(point) {
+  return [point[0] * radians, point[1] * radians];
+}
+
+export default function(object, point) {
+  return (object && containsObjectType.hasOwnProperty(object.type)
+      ? containsObjectType[object.type]
+      : containsGeometry)(object, point);
+}
Index: node_modules/d3-geo/src/distance.js
===================================================================
--- node_modules/d3-geo/src/distance.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/distance.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,10 @@
+import length from "./length.js";
+
+var coordinates = [null, null],
+    object = {type: "LineString", coordinates: coordinates};
+
+export default function(a, b) {
+  coordinates[0] = a;
+  coordinates[1] = b;
+  return length(object);
+}
Index: node_modules/d3-geo/src/graticule.js
===================================================================
--- node_modules/d3-geo/src/graticule.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/graticule.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,105 @@
+import {range} from "d3-array";
+import {abs, ceil, epsilon} from "./math.js";
+
+function graticuleX(y0, y1, dy) {
+  var y = range(y0, y1 - epsilon, dy).concat(y1);
+  return function(x) { return y.map(function(y) { return [x, y]; }); };
+}
+
+function graticuleY(x0, x1, dx) {
+  var x = range(x0, x1 - epsilon, dx).concat(x1);
+  return function(y) { return x.map(function(x) { return [x, y]; }); };
+}
+
+export default function graticule() {
+  var x1, x0, X1, X0,
+      y1, y0, Y1, Y0,
+      dx = 10, dy = dx, DX = 90, DY = 360,
+      x, y, X, Y,
+      precision = 2.5;
+
+  function graticule() {
+    return {type: "MultiLineString", coordinates: lines()};
+  }
+
+  function lines() {
+    return range(ceil(X0 / DX) * DX, X1, DX).map(X)
+        .concat(range(ceil(Y0 / DY) * DY, Y1, DY).map(Y))
+        .concat(range(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon; }).map(x))
+        .concat(range(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon; }).map(y));
+  }
+
+  graticule.lines = function() {
+    return lines().map(function(coordinates) { return {type: "LineString", coordinates: coordinates}; });
+  };
+
+  graticule.outline = function() {
+    return {
+      type: "Polygon",
+      coordinates: [
+        X(X0).concat(
+        Y(Y1).slice(1),
+        X(X1).reverse().slice(1),
+        Y(Y0).reverse().slice(1))
+      ]
+    };
+  };
+
+  graticule.extent = function(_) {
+    if (!arguments.length) return graticule.extentMinor();
+    return graticule.extentMajor(_).extentMinor(_);
+  };
+
+  graticule.extentMajor = function(_) {
+    if (!arguments.length) return [[X0, Y0], [X1, Y1]];
+    X0 = +_[0][0], X1 = +_[1][0];
+    Y0 = +_[0][1], Y1 = +_[1][1];
+    if (X0 > X1) _ = X0, X0 = X1, X1 = _;
+    if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _;
+    return graticule.precision(precision);
+  };
+
+  graticule.extentMinor = function(_) {
+    if (!arguments.length) return [[x0, y0], [x1, y1]];
+    x0 = +_[0][0], x1 = +_[1][0];
+    y0 = +_[0][1], y1 = +_[1][1];
+    if (x0 > x1) _ = x0, x0 = x1, x1 = _;
+    if (y0 > y1) _ = y0, y0 = y1, y1 = _;
+    return graticule.precision(precision);
+  };
+
+  graticule.step = function(_) {
+    if (!arguments.length) return graticule.stepMinor();
+    return graticule.stepMajor(_).stepMinor(_);
+  };
+
+  graticule.stepMajor = function(_) {
+    if (!arguments.length) return [DX, DY];
+    DX = +_[0], DY = +_[1];
+    return graticule;
+  };
+
+  graticule.stepMinor = function(_) {
+    if (!arguments.length) return [dx, dy];
+    dx = +_[0], dy = +_[1];
+    return graticule;
+  };
+
+  graticule.precision = function(_) {
+    if (!arguments.length) return precision;
+    precision = +_;
+    x = graticuleX(y0, y1, 90);
+    y = graticuleY(x0, x1, precision);
+    X = graticuleX(Y0, Y1, 90);
+    Y = graticuleY(X0, X1, precision);
+    return graticule;
+  };
+
+  return graticule
+      .extentMajor([[-180, -90 + epsilon], [180, 90 - epsilon]])
+      .extentMinor([[-180, -80 - epsilon], [180, 80 + epsilon]]);
+}
+
+export function graticule10() {
+  return graticule()();
+}
Index: node_modules/d3-geo/src/identity.js
===================================================================
--- node_modules/d3-geo/src/identity.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/identity.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,1 @@
+export default x => x;
Index: node_modules/d3-geo/src/index.js
===================================================================
--- node_modules/d3-geo/src/index.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/index.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,34 @@
+export {default as geoArea} from "./area.js";
+export {default as geoBounds} from "./bounds.js";
+export {default as geoCentroid} from "./centroid.js";
+export {default as geoCircle} from "./circle.js";
+export {default as geoClipAntimeridian} from "./clip/antimeridian.js";
+export {default as geoClipCircle} from "./clip/circle.js";
+export {default as geoClipExtent} from "./clip/extent.js"; // DEPRECATED! Use d3.geoIdentity().clipExtent(…).
+export {default as geoClipRectangle} from "./clip/rectangle.js";
+export {default as geoContains} from "./contains.js";
+export {default as geoDistance} from "./distance.js";
+export {default as geoGraticule, graticule10 as geoGraticule10} from "./graticule.js";
+export {default as geoInterpolate} from "./interpolate.js";
+export {default as geoLength} from "./length.js";
+export {default as geoPath} from "./path/index.js";
+export {default as geoAlbers} from "./projection/albers.js";
+export {default as geoAlbersUsa} from "./projection/albersUsa.js";
+export {default as geoAzimuthalEqualArea, azimuthalEqualAreaRaw as geoAzimuthalEqualAreaRaw} from "./projection/azimuthalEqualArea.js";
+export {default as geoAzimuthalEquidistant, azimuthalEquidistantRaw as geoAzimuthalEquidistantRaw} from "./projection/azimuthalEquidistant.js";
+export {default as geoConicConformal, conicConformalRaw as geoConicConformalRaw} from "./projection/conicConformal.js";
+export {default as geoConicEqualArea, conicEqualAreaRaw as geoConicEqualAreaRaw} from "./projection/conicEqualArea.js";
+export {default as geoConicEquidistant, conicEquidistantRaw as geoConicEquidistantRaw} from "./projection/conicEquidistant.js";
+export {default as geoEqualEarth, equalEarthRaw as geoEqualEarthRaw} from "./projection/equalEarth.js";
+export {default as geoEquirectangular, equirectangularRaw as geoEquirectangularRaw} from "./projection/equirectangular.js";
+export {default as geoGnomonic, gnomonicRaw as geoGnomonicRaw} from "./projection/gnomonic.js";
+export {default as geoIdentity} from "./projection/identity.js";
+export {default as geoProjection, projectionMutator as geoProjectionMutator} from "./projection/index.js";
+export {default as geoMercator, mercatorRaw as geoMercatorRaw} from "./projection/mercator.js";
+export {default as geoNaturalEarth1, naturalEarth1Raw as geoNaturalEarth1Raw} from "./projection/naturalEarth1.js";
+export {default as geoOrthographic, orthographicRaw as geoOrthographicRaw} from "./projection/orthographic.js";
+export {default as geoStereographic, stereographicRaw as geoStereographicRaw} from "./projection/stereographic.js";
+export {default as geoTransverseMercator, transverseMercatorRaw as geoTransverseMercatorRaw} from "./projection/transverseMercator.js";
+export {default as geoRotation} from "./rotation.js";
+export {default as geoStream} from "./stream.js";
+export {default as geoTransform} from "./transform.js";
Index: node_modules/d3-geo/src/interpolate.js
===================================================================
--- node_modules/d3-geo/src/interpolate.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/interpolate.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,36 @@
+import {asin, atan2, cos, degrees, haversin, radians, sin, sqrt} from "./math.js";
+
+export default function(a, b) {
+  var x0 = a[0] * radians,
+      y0 = a[1] * radians,
+      x1 = b[0] * radians,
+      y1 = b[1] * radians,
+      cy0 = cos(y0),
+      sy0 = sin(y0),
+      cy1 = cos(y1),
+      sy1 = sin(y1),
+      kx0 = cy0 * cos(x0),
+      ky0 = cy0 * sin(x0),
+      kx1 = cy1 * cos(x1),
+      ky1 = cy1 * sin(x1),
+      d = 2 * asin(sqrt(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))),
+      k = sin(d);
+
+  var interpolate = d ? function(t) {
+    var B = sin(t *= d) / k,
+        A = sin(d - t) / k,
+        x = A * kx0 + B * kx1,
+        y = A * ky0 + B * ky1,
+        z = A * sy0 + B * sy1;
+    return [
+      atan2(y, x) * degrees,
+      atan2(z, sqrt(x * x + y * y)) * degrees
+    ];
+  } : function() {
+    return [x0 * degrees, y0 * degrees];
+  };
+
+  interpolate.distance = d;
+
+  return interpolate;
+}
Index: node_modules/d3-geo/src/length.js
===================================================================
--- node_modules/d3-geo/src/length.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/length.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,53 @@
+import {Adder} from "d3-array";
+import {abs, atan2, cos, radians, sin, sqrt} from "./math.js";
+import noop from "./noop.js";
+import stream from "./stream.js";
+
+var lengthSum,
+    lambda0,
+    sinPhi0,
+    cosPhi0;
+
+var lengthStream = {
+  sphere: noop,
+  point: noop,
+  lineStart: lengthLineStart,
+  lineEnd: noop,
+  polygonStart: noop,
+  polygonEnd: noop
+};
+
+function lengthLineStart() {
+  lengthStream.point = lengthPointFirst;
+  lengthStream.lineEnd = lengthLineEnd;
+}
+
+function lengthLineEnd() {
+  lengthStream.point = lengthStream.lineEnd = noop;
+}
+
+function lengthPointFirst(lambda, phi) {
+  lambda *= radians, phi *= radians;
+  lambda0 = lambda, sinPhi0 = sin(phi), cosPhi0 = cos(phi);
+  lengthStream.point = lengthPoint;
+}
+
+function lengthPoint(lambda, phi) {
+  lambda *= radians, phi *= radians;
+  var sinPhi = sin(phi),
+      cosPhi = cos(phi),
+      delta = abs(lambda - lambda0),
+      cosDelta = cos(delta),
+      sinDelta = sin(delta),
+      x = cosPhi * sinDelta,
+      y = cosPhi0 * sinPhi - sinPhi0 * cosPhi * cosDelta,
+      z = sinPhi0 * sinPhi + cosPhi0 * cosPhi * cosDelta;
+  lengthSum.add(atan2(sqrt(x * x + y * y), z));
+  lambda0 = lambda, sinPhi0 = sinPhi, cosPhi0 = cosPhi;
+}
+
+export default function(object) {
+  lengthSum = new Adder();
+  stream(object, lengthStream);
+  return +lengthSum;
+}
Index: node_modules/d3-geo/src/math.js
===================================================================
--- node_modules/d3-geo/src/math.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/math.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,36 @@
+export var epsilon = 1e-6;
+export var epsilon2 = 1e-12;
+export var pi = Math.PI;
+export var halfPi = pi / 2;
+export var quarterPi = pi / 4;
+export var tau = pi * 2;
+
+export var degrees = 180 / pi;
+export var radians = pi / 180;
+
+export var abs = Math.abs;
+export var atan = Math.atan;
+export var atan2 = Math.atan2;
+export var cos = Math.cos;
+export var ceil = Math.ceil;
+export var exp = Math.exp;
+export var floor = Math.floor;
+export var hypot = Math.hypot;
+export var log = Math.log;
+export var pow = Math.pow;
+export var sin = Math.sin;
+export var sign = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; };
+export var sqrt = Math.sqrt;
+export var tan = Math.tan;
+
+export function acos(x) {
+  return x > 1 ? 0 : x < -1 ? pi : Math.acos(x);
+}
+
+export function asin(x) {
+  return x > 1 ? halfPi : x < -1 ? -halfPi : Math.asin(x);
+}
+
+export function haversin(x) {
+  return (x = sin(x / 2)) * x;
+}
Index: node_modules/d3-geo/src/noop.js
===================================================================
--- node_modules/d3-geo/src/noop.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/noop.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,1 @@
+export default function noop() {}
Index: node_modules/d3-geo/src/path/area.js
===================================================================
--- node_modules/d3-geo/src/path/area.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/path/area.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,50 @@
+import {Adder} from "d3-array";
+import {abs} from "../math.js";
+import noop from "../noop.js";
+
+var areaSum = new Adder(),
+    areaRingSum = new Adder(),
+    x00,
+    y00,
+    x0,
+    y0;
+
+var areaStream = {
+  point: noop,
+  lineStart: noop,
+  lineEnd: noop,
+  polygonStart: function() {
+    areaStream.lineStart = areaRingStart;
+    areaStream.lineEnd = areaRingEnd;
+  },
+  polygonEnd: function() {
+    areaStream.lineStart = areaStream.lineEnd = areaStream.point = noop;
+    areaSum.add(abs(areaRingSum));
+    areaRingSum = new Adder();
+  },
+  result: function() {
+    var area = areaSum / 2;
+    areaSum = new Adder();
+    return area;
+  }
+};
+
+function areaRingStart() {
+  areaStream.point = areaPointFirst;
+}
+
+function areaPointFirst(x, y) {
+  areaStream.point = areaPoint;
+  x00 = x0 = x, y00 = y0 = y;
+}
+
+function areaPoint(x, y) {
+  areaRingSum.add(y0 * x - x0 * y);
+  x0 = x, y0 = y;
+}
+
+function areaRingEnd() {
+  areaPoint(x00, y00);
+}
+
+export default areaStream;
Index: node_modules/d3-geo/src/path/bounds.js
===================================================================
--- node_modules/d3-geo/src/path/bounds.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/path/bounds.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,28 @@
+import noop from "../noop.js";
+
+var x0 = Infinity,
+    y0 = x0,
+    x1 = -x0,
+    y1 = x1;
+
+var boundsStream = {
+  point: boundsPoint,
+  lineStart: noop,
+  lineEnd: noop,
+  polygonStart: noop,
+  polygonEnd: noop,
+  result: function() {
+    var bounds = [[x0, y0], [x1, y1]];
+    x1 = y1 = -(y0 = x0 = Infinity);
+    return bounds;
+  }
+};
+
+function boundsPoint(x, y) {
+  if (x < x0) x0 = x;
+  if (x > x1) x1 = x;
+  if (y < y0) y0 = y;
+  if (y > y1) y1 = y;
+}
+
+export default boundsStream;
Index: node_modules/d3-geo/src/path/centroid.js
===================================================================
--- node_modules/d3-geo/src/path/centroid.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/path/centroid.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,100 @@
+import {sqrt} from "../math.js";
+
+// TODO Enforce positive area for exterior, negative area for interior?
+
+var X0 = 0,
+    Y0 = 0,
+    Z0 = 0,
+    X1 = 0,
+    Y1 = 0,
+    Z1 = 0,
+    X2 = 0,
+    Y2 = 0,
+    Z2 = 0,
+    x00,
+    y00,
+    x0,
+    y0;
+
+var centroidStream = {
+  point: centroidPoint,
+  lineStart: centroidLineStart,
+  lineEnd: centroidLineEnd,
+  polygonStart: function() {
+    centroidStream.lineStart = centroidRingStart;
+    centroidStream.lineEnd = centroidRingEnd;
+  },
+  polygonEnd: function() {
+    centroidStream.point = centroidPoint;
+    centroidStream.lineStart = centroidLineStart;
+    centroidStream.lineEnd = centroidLineEnd;
+  },
+  result: function() {
+    var centroid = Z2 ? [X2 / Z2, Y2 / Z2]
+        : Z1 ? [X1 / Z1, Y1 / Z1]
+        : Z0 ? [X0 / Z0, Y0 / Z0]
+        : [NaN, NaN];
+    X0 = Y0 = Z0 =
+    X1 = Y1 = Z1 =
+    X2 = Y2 = Z2 = 0;
+    return centroid;
+  }
+};
+
+function centroidPoint(x, y) {
+  X0 += x;
+  Y0 += y;
+  ++Z0;
+}
+
+function centroidLineStart() {
+  centroidStream.point = centroidPointFirstLine;
+}
+
+function centroidPointFirstLine(x, y) {
+  centroidStream.point = centroidPointLine;
+  centroidPoint(x0 = x, y0 = y);
+}
+
+function centroidPointLine(x, y) {
+  var dx = x - x0, dy = y - y0, z = sqrt(dx * dx + dy * dy);
+  X1 += z * (x0 + x) / 2;
+  Y1 += z * (y0 + y) / 2;
+  Z1 += z;
+  centroidPoint(x0 = x, y0 = y);
+}
+
+function centroidLineEnd() {
+  centroidStream.point = centroidPoint;
+}
+
+function centroidRingStart() {
+  centroidStream.point = centroidPointFirstRing;
+}
+
+function centroidRingEnd() {
+  centroidPointRing(x00, y00);
+}
+
+function centroidPointFirstRing(x, y) {
+  centroidStream.point = centroidPointRing;
+  centroidPoint(x00 = x0 = x, y00 = y0 = y);
+}
+
+function centroidPointRing(x, y) {
+  var dx = x - x0,
+      dy = y - y0,
+      z = sqrt(dx * dx + dy * dy);
+
+  X1 += z * (x0 + x) / 2;
+  Y1 += z * (y0 + y) / 2;
+  Z1 += z;
+
+  z = y0 * x - x0 * y;
+  X2 += z * (x0 + x);
+  Y2 += z * (y0 + y);
+  Z2 += z * 3;
+  centroidPoint(x0 = x, y0 = y);
+}
+
+export default centroidStream;
Index: node_modules/d3-geo/src/path/context.js
===================================================================
--- node_modules/d3-geo/src/path/context.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/path/context.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,45 @@
+import {tau} from "../math.js";
+import noop from "../noop.js";
+
+export default function PathContext(context) {
+  this._context = context;
+}
+
+PathContext.prototype = {
+  _radius: 4.5,
+  pointRadius: function(_) {
+    return this._radius = _, this;
+  },
+  polygonStart: function() {
+    this._line = 0;
+  },
+  polygonEnd: function() {
+    this._line = NaN;
+  },
+  lineStart: function() {
+    this._point = 0;
+  },
+  lineEnd: function() {
+    if (this._line === 0) this._context.closePath();
+    this._point = NaN;
+  },
+  point: function(x, y) {
+    switch (this._point) {
+      case 0: {
+        this._context.moveTo(x, y);
+        this._point = 1;
+        break;
+      }
+      case 1: {
+        this._context.lineTo(x, y);
+        break;
+      }
+      default: {
+        this._context.moveTo(x + this._radius, y);
+        this._context.arc(x, y, this._radius, 0, tau);
+        break;
+      }
+    }
+  },
+  result: noop
+};
Index: node_modules/d3-geo/src/path/index.js
===================================================================
--- node_modules/d3-geo/src/path/index.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/path/index.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,76 @@
+import identity from "../identity.js";
+import stream from "../stream.js";
+import pathArea from "./area.js";
+import pathBounds from "./bounds.js";
+import pathCentroid from "./centroid.js";
+import PathContext from "./context.js";
+import pathMeasure from "./measure.js";
+import PathString from "./string.js";
+
+export default function(projection, context) {
+  let digits = 3,
+      pointRadius = 4.5,
+      projectionStream,
+      contextStream;
+
+  function path(object) {
+    if (object) {
+      if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments));
+      stream(object, projectionStream(contextStream));
+    }
+    return contextStream.result();
+  }
+
+  path.area = function(object) {
+    stream(object, projectionStream(pathArea));
+    return pathArea.result();
+  };
+
+  path.measure = function(object) {
+    stream(object, projectionStream(pathMeasure));
+    return pathMeasure.result();
+  };
+
+  path.bounds = function(object) {
+    stream(object, projectionStream(pathBounds));
+    return pathBounds.result();
+  };
+
+  path.centroid = function(object) {
+    stream(object, projectionStream(pathCentroid));
+    return pathCentroid.result();
+  };
+
+  path.projection = function(_) {
+    if (!arguments.length) return projection;
+    projectionStream = _ == null ? (projection = null, identity) : (projection = _).stream;
+    return path;
+  };
+
+  path.context = function(_) {
+    if (!arguments.length) return context;
+    contextStream = _ == null ? (context = null, new PathString(digits)) : new PathContext(context = _);
+    if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius);
+    return path;
+  };
+
+  path.pointRadius = function(_) {
+    if (!arguments.length) return pointRadius;
+    pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_);
+    return path;
+  };
+
+  path.digits = function(_) {
+    if (!arguments.length) return digits;
+    if (_ == null) digits = null;
+    else {
+      const d = Math.floor(_);
+      if (!(d >= 0)) throw new RangeError(`invalid digits: ${_}`);
+      digits = d;
+    }
+    if (context === null) contextStream = new PathString(digits);
+    return path;
+  };
+
+  return path.projection(projection).digits(digits).context(context);
+}
Index: node_modules/d3-geo/src/path/measure.js
===================================================================
--- node_modules/d3-geo/src/path/measure.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/path/measure.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,45 @@
+import {Adder} from "d3-array";
+import {sqrt} from "../math.js";
+import noop from "../noop.js";
+
+var lengthSum = new Adder(),
+    lengthRing,
+    x00,
+    y00,
+    x0,
+    y0;
+
+var lengthStream = {
+  point: noop,
+  lineStart: function() {
+    lengthStream.point = lengthPointFirst;
+  },
+  lineEnd: function() {
+    if (lengthRing) lengthPoint(x00, y00);
+    lengthStream.point = noop;
+  },
+  polygonStart: function() {
+    lengthRing = true;
+  },
+  polygonEnd: function() {
+    lengthRing = null;
+  },
+  result: function() {
+    var length = +lengthSum;
+    lengthSum = new Adder();
+    return length;
+  }
+};
+
+function lengthPointFirst(x, y) {
+  lengthStream.point = lengthPoint;
+  x00 = x0 = x, y00 = y0 = y;
+}
+
+function lengthPoint(x, y) {
+  x0 -= x, y0 -= y;
+  lengthSum.add(sqrt(x0 * x0 + y0 * y0));
+  x0 = x, y0 = y;
+}
+
+export default lengthStream;
Index: node_modules/d3-geo/src/path/string.js
===================================================================
--- node_modules/d3-geo/src/path/string.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/path/string.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,86 @@
+// Simple caching for constant-radius points.
+let cacheDigits, cacheAppend, cacheRadius, cacheCircle;
+
+export default class PathString {
+  constructor(digits) {
+    this._append = digits == null ? append : appendRound(digits);
+    this._radius = 4.5;
+    this._ = "";
+  }
+  pointRadius(_) {
+    this._radius = +_;
+    return this;
+  }
+  polygonStart() {
+    this._line = 0;
+  }
+  polygonEnd() {
+    this._line = NaN;
+  }
+  lineStart() {
+    this._point = 0;
+  }
+  lineEnd() {
+    if (this._line === 0) this._ += "Z";
+    this._point = NaN;
+  }
+  point(x, y) {
+    switch (this._point) {
+      case 0: {
+        this._append`M${x},${y}`;
+        this._point = 1;
+        break;
+      }
+      case 1: {
+        this._append`L${x},${y}`;
+        break;
+      }
+      default: {
+        this._append`M${x},${y}`;
+        if (this._radius !== cacheRadius || this._append !== cacheAppend) {
+          const r = this._radius;
+          const s = this._;
+          this._ = ""; // stash the old string so we can cache the circle path fragment
+          this._append`m0,${r}a${r},${r} 0 1,1 0,${-2 * r}a${r},${r} 0 1,1 0,${2 * r}z`;
+          cacheRadius = r;
+          cacheAppend = this._append;
+          cacheCircle = this._;
+          this._ = s;
+        }
+        this._ += cacheCircle;
+        break;
+      }
+    }
+  }
+  result() {
+    const result = this._;
+    this._ = "";
+    return result.length ? result : null;
+  }
+}
+
+function append(strings) {
+  let i = 1;
+  this._ += strings[0];
+  for (const j = strings.length; i < j; ++i) {
+    this._ += arguments[i] + strings[i];
+  }
+}
+
+function appendRound(digits) {
+  const d = Math.floor(digits);
+  if (!(d >= 0)) throw new RangeError(`invalid digits: ${digits}`);
+  if (d > 15) return append;
+  if (d !== cacheDigits) {
+    const k = 10 ** d;
+    cacheDigits = d;
+    cacheAppend = function append(strings) {
+      let i = 1;
+      this._ += strings[0];
+      for (const j = strings.length; i < j; ++i) {
+        this._ += Math.round(arguments[i] * k) / k + strings[i];
+      }
+    };
+  }
+  return cacheAppend;
+}
Index: node_modules/d3-geo/src/pointEqual.js
===================================================================
--- node_modules/d3-geo/src/pointEqual.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/pointEqual.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,5 @@
+import {abs, epsilon} from "./math.js";
+
+export default function(a, b) {
+  return abs(a[0] - b[0]) < epsilon && abs(a[1] - b[1]) < epsilon;
+}
Index: node_modules/d3-geo/src/polygonContains.js
===================================================================
--- node_modules/d3-geo/src/polygonContains.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/polygonContains.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,74 @@
+import {Adder} from "d3-array";
+import {cartesian, cartesianCross, cartesianNormalizeInPlace} from "./cartesian.js";
+import {abs, asin, atan2, cos, epsilon, epsilon2, halfPi, pi, quarterPi, sign, sin, tau} from "./math.js";
+
+function longitude(point) {
+  return abs(point[0]) <= pi ? point[0] : sign(point[0]) * ((abs(point[0]) + pi) % tau - pi);
+}
+
+export default function(polygon, point) {
+  var lambda = longitude(point),
+      phi = point[1],
+      sinPhi = sin(phi),
+      normal = [sin(lambda), -cos(lambda), 0],
+      angle = 0,
+      winding = 0;
+
+  var sum = new Adder();
+
+  if (sinPhi === 1) phi = halfPi + epsilon;
+  else if (sinPhi === -1) phi = -halfPi - epsilon;
+
+  for (var i = 0, n = polygon.length; i < n; ++i) {
+    if (!(m = (ring = polygon[i]).length)) continue;
+    var ring,
+        m,
+        point0 = ring[m - 1],
+        lambda0 = longitude(point0),
+        phi0 = point0[1] / 2 + quarterPi,
+        sinPhi0 = sin(phi0),
+        cosPhi0 = cos(phi0);
+
+    for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) {
+      var point1 = ring[j],
+          lambda1 = longitude(point1),
+          phi1 = point1[1] / 2 + quarterPi,
+          sinPhi1 = sin(phi1),
+          cosPhi1 = cos(phi1),
+          delta = lambda1 - lambda0,
+          sign = delta >= 0 ? 1 : -1,
+          absDelta = sign * delta,
+          antimeridian = absDelta > pi,
+          k = sinPhi0 * sinPhi1;
+
+      sum.add(atan2(k * sign * sin(absDelta), cosPhi0 * cosPhi1 + k * cos(absDelta)));
+      angle += antimeridian ? delta + sign * tau : delta;
+
+      // Are the longitudes either side of the point’s meridian (lambda),
+      // and are the latitudes smaller than the parallel (phi)?
+      if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) {
+        var arc = cartesianCross(cartesian(point0), cartesian(point1));
+        cartesianNormalizeInPlace(arc);
+        var intersection = cartesianCross(normal, arc);
+        cartesianNormalizeInPlace(intersection);
+        var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin(intersection[2]);
+        if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) {
+          winding += antimeridian ^ delta >= 0 ? 1 : -1;
+        }
+      }
+    }
+  }
+
+  // First, determine whether the South pole is inside or outside:
+  //
+  // It is inside if:
+  // * the polygon winds around it in a clockwise direction.
+  // * the polygon does not (cumulatively) wind around it, but has a negative
+  //   (counter-clockwise) area.
+  //
+  // Second, count the (signed) number of times a segment crosses a lambda
+  // from the point to the South pole.  If it is zero, then the point is the
+  // same side as the South pole.
+
+  return (angle < -epsilon || angle < epsilon && sum < -epsilon2) ^ (winding & 1);
+}
Index: node_modules/d3-geo/src/projection/albers.js
===================================================================
--- node_modules/d3-geo/src/projection/albers.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/albers.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,10 @@
+import conicEqualArea from "./conicEqualArea.js";
+
+export default function() {
+  return conicEqualArea()
+      .parallels([29.5, 45.5])
+      .scale(1070)
+      .translate([480, 250])
+      .rotate([96, 0])
+      .center([-0.6, 38.7]);
+}
Index: node_modules/d3-geo/src/projection/albersUsa.js
===================================================================
--- node_modules/d3-geo/src/projection/albersUsa.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/albersUsa.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,111 @@
+import {epsilon} from "../math.js";
+import albers from "./albers.js";
+import conicEqualArea from "./conicEqualArea.js";
+import {fitExtent, fitSize, fitWidth, fitHeight} from "./fit.js";
+
+// The projections must have mutually exclusive clip regions on the sphere,
+// as this will avoid emitting interleaving lines and polygons.
+function multiplex(streams) {
+  var n = streams.length;
+  return {
+    point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); },
+    sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); },
+    lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); },
+    lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); },
+    polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); },
+    polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); }
+  };
+}
+
+// A composite projection for the United States, configured by default for
+// 960×500. The projection also works quite well at 960×600 if you change the
+// scale to 1285 and adjust the translate accordingly. The set of standard
+// parallels for each region comes from USGS, which is published here:
+// http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers
+export default function() {
+  var cache,
+      cacheStream,
+      lower48 = albers(), lower48Point,
+      alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338
+      hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007
+      point, pointStream = {point: function(x, y) { point = [x, y]; }};
+
+  function albersUsa(coordinates) {
+    var x = coordinates[0], y = coordinates[1];
+    return point = null,
+        (lower48Point.point(x, y), point)
+        || (alaskaPoint.point(x, y), point)
+        || (hawaiiPoint.point(x, y), point);
+  }
+
+  albersUsa.invert = function(coordinates) {
+    var k = lower48.scale(),
+        t = lower48.translate(),
+        x = (coordinates[0] - t[0]) / k,
+        y = (coordinates[1] - t[1]) / k;
+    return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska
+        : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii
+        : lower48).invert(coordinates);
+  };
+
+  albersUsa.stream = function(stream) {
+    return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]);
+  };
+
+  albersUsa.precision = function(_) {
+    if (!arguments.length) return lower48.precision();
+    lower48.precision(_), alaska.precision(_), hawaii.precision(_);
+    return reset();
+  };
+
+  albersUsa.scale = function(_) {
+    if (!arguments.length) return lower48.scale();
+    lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_);
+    return albersUsa.translate(lower48.translate());
+  };
+
+  albersUsa.translate = function(_) {
+    if (!arguments.length) return lower48.translate();
+    var k = lower48.scale(), x = +_[0], y = +_[1];
+
+    lower48Point = lower48
+        .translate(_)
+        .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]])
+        .stream(pointStream);
+
+    alaskaPoint = alaska
+        .translate([x - 0.307 * k, y + 0.201 * k])
+        .clipExtent([[x - 0.425 * k + epsilon, y + 0.120 * k + epsilon], [x - 0.214 * k - epsilon, y + 0.234 * k - epsilon]])
+        .stream(pointStream);
+
+    hawaiiPoint = hawaii
+        .translate([x - 0.205 * k, y + 0.212 * k])
+        .clipExtent([[x - 0.214 * k + epsilon, y + 0.166 * k + epsilon], [x - 0.115 * k - epsilon, y + 0.234 * k - epsilon]])
+        .stream(pointStream);
+
+    return reset();
+  };
+
+  albersUsa.fitExtent = function(extent, object) {
+    return fitExtent(albersUsa, extent, object);
+  };
+
+  albersUsa.fitSize = function(size, object) {
+    return fitSize(albersUsa, size, object);
+  };
+
+  albersUsa.fitWidth = function(width, object) {
+    return fitWidth(albersUsa, width, object);
+  };
+
+  albersUsa.fitHeight = function(height, object) {
+    return fitHeight(albersUsa, height, object);
+  };
+
+  function reset() {
+    cache = cacheStream = null;
+    return albersUsa;
+  }
+
+  return albersUsa.scale(1070);
+}
Index: node_modules/d3-geo/src/projection/azimuthal.js
===================================================================
--- node_modules/d3-geo/src/projection/azimuthal.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/azimuthal.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,27 @@
+import {asin, atan2, cos, sin, sqrt} from "../math.js";
+
+export function azimuthalRaw(scale) {
+  return function(x, y) {
+    var cx = cos(x),
+        cy = cos(y),
+        k = scale(cx * cy);
+        if (k === Infinity) return [2, 0];
+    return [
+      k * cy * sin(x),
+      k * sin(y)
+    ];
+  }
+}
+
+export function azimuthalInvert(angle) {
+  return function(x, y) {
+    var z = sqrt(x * x + y * y),
+        c = angle(z),
+        sc = sin(c),
+        cc = cos(c);
+    return [
+      atan2(x * sc, z * cc),
+      asin(z && y * sc / z)
+    ];
+  }
+}
Index: node_modules/d3-geo/src/projection/azimuthalEqualArea.js
===================================================================
--- node_modules/d3-geo/src/projection/azimuthalEqualArea.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/azimuthalEqualArea.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,17 @@
+import {asin, sqrt} from "../math.js";
+import {azimuthalRaw, azimuthalInvert} from "./azimuthal.js";
+import projection from "./index.js";
+
+export var azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) {
+  return sqrt(2 / (1 + cxcy));
+});
+
+azimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) {
+  return 2 * asin(z / 2);
+});
+
+export default function() {
+  return projection(azimuthalEqualAreaRaw)
+      .scale(124.75)
+      .clipAngle(180 - 1e-3);
+}
Index: node_modules/d3-geo/src/projection/azimuthalEquidistant.js
===================================================================
--- node_modules/d3-geo/src/projection/azimuthalEquidistant.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/azimuthalEquidistant.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,17 @@
+import {acos, sin} from "../math.js";
+import {azimuthalRaw, azimuthalInvert} from "./azimuthal.js";
+import projection from "./index.js";
+
+export var azimuthalEquidistantRaw = azimuthalRaw(function(c) {
+  return (c = acos(c)) && c / sin(c);
+});
+
+azimuthalEquidistantRaw.invert = azimuthalInvert(function(z) {
+  return z;
+});
+
+export default function() {
+  return projection(azimuthalEquidistantRaw)
+      .scale(79.4188)
+      .clipAngle(180 - 1e-3);
+}
Index: node_modules/d3-geo/src/projection/conic.js
===================================================================
--- node_modules/d3-geo/src/projection/conic.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/conic.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,15 @@
+import {degrees, pi, radians} from "../math.js";
+import {projectionMutator} from "./index.js";
+
+export function conicProjection(projectAt) {
+  var phi0 = 0,
+      phi1 = pi / 3,
+      m = projectionMutator(projectAt),
+      p = m(phi0, phi1);
+
+  p.parallels = function(_) {
+    return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees, phi1 * degrees];
+  };
+
+  return p;
+}
Index: node_modules/d3-geo/src/projection/conicConformal.js
===================================================================
--- node_modules/d3-geo/src/projection/conicConformal.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/conicConformal.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,38 @@
+import {abs, atan, atan2, cos, epsilon, halfPi, log, pi, pow, sign, sin, sqrt, tan} from "../math.js";
+import {conicProjection} from "./conic.js";
+import {mercatorRaw} from "./mercator.js";
+
+function tany(y) {
+  return tan((halfPi + y) / 2);
+}
+
+export function conicConformalRaw(y0, y1) {
+  var cy0 = cos(y0),
+      n = y0 === y1 ? sin(y0) : log(cy0 / cos(y1)) / log(tany(y1) / tany(y0)),
+      f = cy0 * pow(tany(y0), n) / n;
+
+  if (!n) return mercatorRaw;
+
+  function project(x, y) {
+    if (f > 0) { if (y < -halfPi + epsilon) y = -halfPi + epsilon; }
+    else { if (y > halfPi - epsilon) y = halfPi - epsilon; }
+    var r = f / pow(tany(y), n);
+    return [r * sin(n * x), f - r * cos(n * x)];
+  }
+
+  project.invert = function(x, y) {
+    var fy = f - y, r = sign(n) * sqrt(x * x + fy * fy),
+      l = atan2(x, abs(fy)) * sign(fy);
+    if (fy * n < 0)
+      l -= pi * sign(x) * sign(fy);
+    return [l / n, 2 * atan(pow(f / r, 1 / n)) - halfPi];
+  };
+
+  return project;
+}
+
+export default function() {
+  return conicProjection(conicConformalRaw)
+      .scale(109.5)
+      .parallels([30, 30]);
+}
Index: node_modules/d3-geo/src/projection/conicEqualArea.js
===================================================================
--- node_modules/d3-geo/src/projection/conicEqualArea.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/conicEqualArea.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,33 @@
+import {abs, asin, atan2, cos, epsilon, pi, sign, sin, sqrt} from "../math.js";
+import {conicProjection} from "./conic.js";
+import {cylindricalEqualAreaRaw} from "./cylindricalEqualArea.js";
+
+export function conicEqualAreaRaw(y0, y1) {
+  var sy0 = sin(y0), n = (sy0 + sin(y1)) / 2;
+
+  // Are the parallels symmetrical around the Equator?
+  if (abs(n) < epsilon) return cylindricalEqualAreaRaw(y0);
+
+  var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt(c) / n;
+
+  function project(x, y) {
+    var r = sqrt(c - 2 * n * sin(y)) / n;
+    return [r * sin(x *= n), r0 - r * cos(x)];
+  }
+
+  project.invert = function(x, y) {
+    var r0y = r0 - y,
+        l = atan2(x, abs(r0y)) * sign(r0y);
+    if (r0y * n < 0)
+      l -= pi * sign(x) * sign(r0y);
+    return [l / n, asin((c - (x * x + r0y * r0y) * n * n) / (2 * n))];
+  };
+
+  return project;
+}
+
+export default function() {
+  return conicProjection(conicEqualAreaRaw)
+      .scale(155.424)
+      .center([0, 33.6442]);
+}
Index: node_modules/d3-geo/src/projection/conicEquidistant.js
===================================================================
--- node_modules/d3-geo/src/projection/conicEquidistant.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/conicEquidistant.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,32 @@
+import {abs, atan2, cos, epsilon, pi, sign, sin, sqrt} from "../math.js";
+import {conicProjection} from "./conic.js";
+import {equirectangularRaw} from "./equirectangular.js";
+
+export function conicEquidistantRaw(y0, y1) {
+  var cy0 = cos(y0),
+      n = y0 === y1 ? sin(y0) : (cy0 - cos(y1)) / (y1 - y0),
+      g = cy0 / n + y0;
+
+  if (abs(n) < epsilon) return equirectangularRaw;
+
+  function project(x, y) {
+    var gy = g - y, nx = n * x;
+    return [gy * sin(nx), g - gy * cos(nx)];
+  }
+
+  project.invert = function(x, y) {
+    var gy = g - y,
+        l = atan2(x, abs(gy)) * sign(gy);
+    if (gy * n < 0)
+      l -= pi * sign(x) * sign(gy);
+    return [l / n, g - sign(n) * sqrt(x * x + gy * gy)];
+  };
+
+  return project;
+}
+
+export default function() {
+  return conicProjection(conicEquidistantRaw)
+      .scale(131.154)
+      .center([0, 13.9389]);
+}
Index: node_modules/d3-geo/src/projection/cylindricalEqualArea.js
===================================================================
--- node_modules/d3-geo/src/projection/cylindricalEqualArea.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/cylindricalEqualArea.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,15 @@
+import {asin, cos, sin} from "../math.js";
+
+export function cylindricalEqualAreaRaw(phi0) {
+  var cosPhi0 = cos(phi0);
+
+  function forward(lambda, phi) {
+    return [lambda * cosPhi0, sin(phi) / cosPhi0];
+  }
+
+  forward.invert = function(x, y) {
+    return [x / cosPhi0, asin(y * cosPhi0)];
+  };
+
+  return forward;
+}
Index: node_modules/d3-geo/src/projection/equalEarth.js
===================================================================
--- node_modules/d3-geo/src/projection/equalEarth.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/equalEarth.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,36 @@
+import projection from "./index.js";
+import {abs, asin, cos, epsilon2, sin, sqrt} from "../math.js";
+
+var A1 = 1.340264,
+    A2 = -0.081106,
+    A3 = 0.000893,
+    A4 = 0.003796,
+    M = sqrt(3) / 2,
+    iterations = 12;
+
+export function equalEarthRaw(lambda, phi) {
+  var l = asin(M * sin(phi)), l2 = l * l, l6 = l2 * l2 * l2;
+  return [
+    lambda * cos(l) / (M * (A1 + 3 * A2 * l2 + l6 * (7 * A3 + 9 * A4 * l2))),
+    l * (A1 + A2 * l2 + l6 * (A3 + A4 * l2))
+  ];
+}
+
+equalEarthRaw.invert = function(x, y) {
+  var l = y, l2 = l * l, l6 = l2 * l2 * l2;
+  for (var i = 0, delta, fy, fpy; i < iterations; ++i) {
+    fy = l * (A1 + A2 * l2 + l6 * (A3 + A4 * l2)) - y;
+    fpy = A1 + 3 * A2 * l2 + l6 * (7 * A3 + 9 * A4 * l2);
+    l -= delta = fy / fpy, l2 = l * l, l6 = l2 * l2 * l2;
+    if (abs(delta) < epsilon2) break;
+  }
+  return [
+    M * x * (A1 + 3 * A2 * l2 + l6 * (7 * A3 + 9 * A4 * l2)) / cos(l),
+    asin(sin(l) / M)
+  ];
+};
+
+export default function() {
+  return projection(equalEarthRaw)
+      .scale(177.158);
+}
Index: node_modules/d3-geo/src/projection/equirectangular.js
===================================================================
--- node_modules/d3-geo/src/projection/equirectangular.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/equirectangular.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,12 @@
+import projection from "./index.js";
+
+export function equirectangularRaw(lambda, phi) {
+  return [lambda, phi];
+}
+
+equirectangularRaw.invert = equirectangularRaw;
+
+export default function() {
+  return projection(equirectangularRaw)
+      .scale(152.63);
+}
Index: node_modules/d3-geo/src/projection/fit.js
===================================================================
--- node_modules/d3-geo/src/projection/fit.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/fit.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,47 @@
+import {default as geoStream} from "../stream.js";
+import boundsStream from "../path/bounds.js";
+
+function fit(projection, fitBounds, object) {
+  var clip = projection.clipExtent && projection.clipExtent();
+  projection.scale(150).translate([0, 0]);
+  if (clip != null) projection.clipExtent(null);
+  geoStream(object, projection.stream(boundsStream));
+  fitBounds(boundsStream.result());
+  if (clip != null) projection.clipExtent(clip);
+  return projection;
+}
+
+export function fitExtent(projection, extent, object) {
+  return fit(projection, function(b) {
+    var w = extent[1][0] - extent[0][0],
+        h = extent[1][1] - extent[0][1],
+        k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])),
+        x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2,
+        y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2;
+    projection.scale(150 * k).translate([x, y]);
+  }, object);
+}
+
+export function fitSize(projection, size, object) {
+  return fitExtent(projection, [[0, 0], size], object);
+}
+
+export function fitWidth(projection, width, object) {
+  return fit(projection, function(b) {
+    var w = +width,
+        k = w / (b[1][0] - b[0][0]),
+        x = (w - k * (b[1][0] + b[0][0])) / 2,
+        y = -k * b[0][1];
+    projection.scale(150 * k).translate([x, y]);
+  }, object);
+}
+
+export function fitHeight(projection, height, object) {
+  return fit(projection, function(b) {
+    var h = +height,
+        k = h / (b[1][1] - b[0][1]),
+        x = -k * b[0][0],
+        y = (h - k * (b[1][1] + b[0][1])) / 2;
+    projection.scale(150 * k).translate([x, y]);
+  }, object);
+}
Index: node_modules/d3-geo/src/projection/gnomonic.js
===================================================================
--- node_modules/d3-geo/src/projection/gnomonic.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/gnomonic.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,16 @@
+import {atan, cos, sin} from "../math.js";
+import {azimuthalInvert} from "./azimuthal.js";
+import projection from "./index.js";
+
+export function gnomonicRaw(x, y) {
+  var cy = cos(y), k = cos(x) * cy;
+  return [cy * sin(x) / k, sin(y) / k];
+}
+
+gnomonicRaw.invert = azimuthalInvert(atan);
+
+export default function() {
+  return projection(gnomonicRaw)
+      .scale(144.049)
+      .clipAngle(60);
+}
Index: node_modules/d3-geo/src/projection/identity.js
===================================================================
--- node_modules/d3-geo/src/projection/identity.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/identity.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,85 @@
+import clipRectangle from "../clip/rectangle.js";
+import identity from "../identity.js";
+import {transformer} from "../transform.js";
+import {fitExtent, fitSize, fitWidth, fitHeight} from "./fit.js";
+import {cos, degrees, radians, sin} from "../math.js";
+
+export default function() {
+  var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, // scale, translate and reflect
+      alpha = 0, ca, sa, // angle
+      x0 = null, y0, x1, y1, // clip extent
+      kx = 1, ky = 1,
+      transform = transformer({
+        point: function(x, y) {
+          var p = projection([x, y])
+          this.stream.point(p[0], p[1]);
+        }
+      }),
+      postclip = identity,
+      cache,
+      cacheStream;
+
+  function reset() {
+    kx = k * sx;
+    ky = k * sy;
+    cache = cacheStream = null;
+    return projection;
+  }
+
+  function projection (p) {
+    var x = p[0] * kx, y = p[1] * ky;
+    if (alpha) {
+      var t = y * ca - x * sa;
+      x = x * ca + y * sa;
+      y = t;
+    }    
+    return [x + tx, y + ty];
+  }
+  projection.invert = function(p) {
+    var x = p[0] - tx, y = p[1] - ty;
+    if (alpha) {
+      var t = y * ca + x * sa;
+      x = x * ca - y * sa;
+      y = t;
+    }
+    return [x / kx, y / ky];
+  };
+  projection.stream = function(stream) {
+    return cache && cacheStream === stream ? cache : cache = transform(postclip(cacheStream = stream));
+  };
+  projection.postclip = function(_) {
+    return arguments.length ? (postclip = _, x0 = y0 = x1 = y1 = null, reset()) : postclip;
+  };
+  projection.clipExtent = function(_) {
+    return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity) : clipRectangle(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
+  };
+  projection.scale = function(_) {
+    return arguments.length ? (k = +_, reset()) : k;
+  };
+  projection.translate = function(_) {
+    return arguments.length ? (tx = +_[0], ty = +_[1], reset()) : [tx, ty];
+  }
+  projection.angle = function(_) {
+    return arguments.length ? (alpha = _ % 360 * radians, sa = sin(alpha), ca = cos(alpha), reset()) : alpha * degrees;
+  };
+  projection.reflectX = function(_) {
+    return arguments.length ? (sx = _ ? -1 : 1, reset()) : sx < 0;
+  };
+  projection.reflectY = function(_) {
+    return arguments.length ? (sy = _ ? -1 : 1, reset()) : sy < 0;
+  };
+  projection.fitExtent = function(extent, object) {
+    return fitExtent(projection, extent, object);
+  };
+  projection.fitSize = function(size, object) {
+    return fitSize(projection, size, object);
+  };
+  projection.fitWidth = function(width, object) {
+    return fitWidth(projection, width, object);
+  };
+  projection.fitHeight = function(height, object) {
+    return fitHeight(projection, height, object);
+  };
+
+  return projection;
+}
Index: node_modules/d3-geo/src/projection/index.js
===================================================================
--- node_modules/d3-geo/src/projection/index.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/index.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,177 @@
+import clipAntimeridian from "../clip/antimeridian.js";
+import clipCircle from "../clip/circle.js";
+import clipRectangle from "../clip/rectangle.js";
+import compose from "../compose.js";
+import identity from "../identity.js";
+import {cos, degrees, radians, sin, sqrt} from "../math.js";
+import {rotateRadians} from "../rotation.js";
+import {transformer} from "../transform.js";
+import {fitExtent, fitSize, fitWidth, fitHeight} from "./fit.js";
+import resample from "./resample.js";
+
+var transformRadians = transformer({
+  point: function(x, y) {
+    this.stream.point(x * radians, y * radians);
+  }
+});
+
+function transformRotate(rotate) {
+  return transformer({
+    point: function(x, y) {
+      var r = rotate(x, y);
+      return this.stream.point(r[0], r[1]);
+    }
+  });
+}
+
+function scaleTranslate(k, dx, dy, sx, sy) {
+  function transform(x, y) {
+    x *= sx; y *= sy;
+    return [dx + k * x, dy - k * y];
+  }
+  transform.invert = function(x, y) {
+    return [(x - dx) / k * sx, (dy - y) / k * sy];
+  };
+  return transform;
+}
+
+function scaleTranslateRotate(k, dx, dy, sx, sy, alpha) {
+  if (!alpha) return scaleTranslate(k, dx, dy, sx, sy);
+  var cosAlpha = cos(alpha),
+      sinAlpha = sin(alpha),
+      a = cosAlpha * k,
+      b = sinAlpha * k,
+      ai = cosAlpha / k,
+      bi = sinAlpha / k,
+      ci = (sinAlpha * dy - cosAlpha * dx) / k,
+      fi = (sinAlpha * dx + cosAlpha * dy) / k;
+  function transform(x, y) {
+    x *= sx; y *= sy;
+    return [a * x - b * y + dx, dy - b * x - a * y];
+  }
+  transform.invert = function(x, y) {
+    return [sx * (ai * x - bi * y + ci), sy * (fi - bi * x - ai * y)];
+  };
+  return transform;
+}
+
+export default function projection(project) {
+  return projectionMutator(function() { return project; })();
+}
+
+export function projectionMutator(projectAt) {
+  var project,
+      k = 150, // scale
+      x = 480, y = 250, // translate
+      lambda = 0, phi = 0, // center
+      deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, // pre-rotate
+      alpha = 0, // post-rotate angle
+      sx = 1, // reflectX
+      sy = 1, // reflectX
+      theta = null, preclip = clipAntimeridian, // pre-clip angle
+      x0 = null, y0, x1, y1, postclip = identity, // post-clip extent
+      delta2 = 0.5, // precision
+      projectResample,
+      projectTransform,
+      projectRotateTransform,
+      cache,
+      cacheStream;
+
+  function projection(point) {
+    return projectRotateTransform(point[0] * radians, point[1] * radians);
+  }
+
+  function invert(point) {
+    point = projectRotateTransform.invert(point[0], point[1]);
+    return point && [point[0] * degrees, point[1] * degrees];
+  }
+
+  projection.stream = function(stream) {
+    return cache && cacheStream === stream ? cache : cache = transformRadians(transformRotate(rotate)(preclip(projectResample(postclip(cacheStream = stream)))));
+  };
+
+  projection.preclip = function(_) {
+    return arguments.length ? (preclip = _, theta = undefined, reset()) : preclip;
+  };
+
+  projection.postclip = function(_) {
+    return arguments.length ? (postclip = _, x0 = y0 = x1 = y1 = null, reset()) : postclip;
+  };
+
+  projection.clipAngle = function(_) {
+    return arguments.length ? (preclip = +_ ? clipCircle(theta = _ * radians) : (theta = null, clipAntimeridian), reset()) : theta * degrees;
+  };
+
+  projection.clipExtent = function(_) {
+    return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity) : clipRectangle(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];
+  };
+
+  projection.scale = function(_) {
+    return arguments.length ? (k = +_, recenter()) : k;
+  };
+
+  projection.translate = function(_) {
+    return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y];
+  };
+
+  projection.center = function(_) {
+    return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees, phi * degrees];
+  };
+
+  projection.rotate = function(_) {
+    return arguments.length ? (deltaLambda = _[0] % 360 * radians, deltaPhi = _[1] % 360 * radians, deltaGamma = _.length > 2 ? _[2] % 360 * radians : 0, recenter()) : [deltaLambda * degrees, deltaPhi * degrees, deltaGamma * degrees];
+  };
+
+  projection.angle = function(_) {
+    return arguments.length ? (alpha = _ % 360 * radians, recenter()) : alpha * degrees;
+  };
+
+  projection.reflectX = function(_) {
+    return arguments.length ? (sx = _ ? -1 : 1, recenter()) : sx < 0;
+  };
+
+  projection.reflectY = function(_) {
+    return arguments.length ? (sy = _ ? -1 : 1, recenter()) : sy < 0;
+  };
+
+  projection.precision = function(_) {
+    return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt(delta2);
+  };
+
+  projection.fitExtent = function(extent, object) {
+    return fitExtent(projection, extent, object);
+  };
+
+  projection.fitSize = function(size, object) {
+    return fitSize(projection, size, object);
+  };
+
+  projection.fitWidth = function(width, object) {
+    return fitWidth(projection, width, object);
+  };
+
+  projection.fitHeight = function(height, object) {
+    return fitHeight(projection, height, object);
+  };
+
+  function recenter() {
+    var center = scaleTranslateRotate(k, 0, 0, sx, sy, alpha).apply(null, project(lambda, phi)),
+        transform = scaleTranslateRotate(k, x - center[0], y - center[1], sx, sy, alpha);
+    rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma);
+    projectTransform = compose(project, transform);
+    projectRotateTransform = compose(rotate, projectTransform);
+    projectResample = resample(projectTransform, delta2);
+    return reset();
+  }
+
+  function reset() {
+    cache = cacheStream = null;
+    return projection;
+  }
+
+  return function() {
+    project = projectAt.apply(this, arguments);
+    projection.invert = project.invert && invert;
+    return recenter();
+  };
+}
Index: node_modules/d3-geo/src/projection/mercator.js
===================================================================
--- node_modules/d3-geo/src/projection/mercator.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/mercator.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,52 @@
+import {atan, exp, halfPi, log, pi, tan, tau} from "../math.js";
+import rotation from "../rotation.js";
+import projection from "./index.js";
+
+export function mercatorRaw(lambda, phi) {
+  return [lambda, log(tan((halfPi + phi) / 2))];
+}
+
+mercatorRaw.invert = function(x, y) {
+  return [x, 2 * atan(exp(y)) - halfPi];
+};
+
+export default function() {
+  return mercatorProjection(mercatorRaw)
+      .scale(961 / tau);
+}
+
+export function mercatorProjection(project) {
+  var m = projection(project),
+      center = m.center,
+      scale = m.scale,
+      translate = m.translate,
+      clipExtent = m.clipExtent,
+      x0 = null, y0, x1, y1; // clip extent
+
+  m.scale = function(_) {
+    return arguments.length ? (scale(_), reclip()) : scale();
+  };
+
+  m.translate = function(_) {
+    return arguments.length ? (translate(_), reclip()) : translate();
+  };
+
+  m.center = function(_) {
+    return arguments.length ? (center(_), reclip()) : center();
+  };
+
+  m.clipExtent = function(_) {
+    return arguments.length ? ((_ == null ? x0 = y0 = x1 = y1 = null : (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1])), reclip()) : x0 == null ? null : [[x0, y0], [x1, y1]];
+  };
+
+  function reclip() {
+    var k = pi * scale(),
+        t = m(rotation(m.rotate()).invert([0, 0]));
+    return clipExtent(x0 == null
+        ? [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]] : project === mercatorRaw
+        ? [[Math.max(t[0] - k, x0), y0], [Math.min(t[0] + k, x1), y1]]
+        : [[x0, Math.max(t[1] - k, y0)], [x1, Math.min(t[1] + k, y1)]]);
+  }
+
+  return reclip();
+}
Index: node_modules/d3-geo/src/projection/naturalEarth1.js
===================================================================
--- node_modules/d3-geo/src/projection/naturalEarth1.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/naturalEarth1.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,28 @@
+import projection from "./index.js";
+import {abs, epsilon} from "../math.js";
+
+export function naturalEarth1Raw(lambda, phi) {
+  var phi2 = phi * phi, phi4 = phi2 * phi2;
+  return [
+    lambda * (0.8707 - 0.131979 * phi2 + phi4 * (-0.013791 + phi4 * (0.003971 * phi2 - 0.001529 * phi4))),
+    phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4)))
+  ];
+}
+
+naturalEarth1Raw.invert = function(x, y) {
+  var phi = y, i = 25, delta;
+  do {
+    var phi2 = phi * phi, phi4 = phi2 * phi2;
+    phi -= delta = (phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4))) - y) /
+        (1.007226 + phi2 * (0.015085 * 3 + phi4 * (-0.044475 * 7 + 0.028874 * 9 * phi2 - 0.005916 * 11 * phi4)));
+  } while (abs(delta) > epsilon && --i > 0);
+  return [
+    x / (0.8707 + (phi2 = phi * phi) * (-0.131979 + phi2 * (-0.013791 + phi2 * phi2 * phi2 * (0.003971 - 0.001529 * phi2)))),
+    phi
+  ];
+};
+
+export default function() {
+  return projection(naturalEarth1Raw)
+      .scale(175.295);
+}
Index: node_modules/d3-geo/src/projection/orthographic.js
===================================================================
--- node_modules/d3-geo/src/projection/orthographic.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/orthographic.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,15 @@
+import {asin, cos, epsilon, sin} from "../math.js";
+import {azimuthalInvert} from "./azimuthal.js";
+import projection from "./index.js";
+
+export function orthographicRaw(x, y) {
+  return [cos(y) * sin(x), sin(y)];
+}
+
+orthographicRaw.invert = azimuthalInvert(asin);
+
+export default function() {
+  return projection(orthographicRaw)
+      .scale(249.5)
+      .clipAngle(90 + epsilon);
+}
Index: node_modules/d3-geo/src/projection/resample.js
===================================================================
--- node_modules/d3-geo/src/projection/resample.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/resample.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,102 @@
+import {cartesian} from "../cartesian.js";
+import {abs, asin, atan2, cos, epsilon, radians, sqrt} from "../math.js";
+import {transformer} from "../transform.js";
+
+var maxDepth = 16, // maximum depth of subdivision
+    cosMinDistance = cos(30 * radians); // cos(minimum angular distance)
+
+export default function(project, delta2) {
+  return +delta2 ? resample(project, delta2) : resampleNone(project);
+}
+
+function resampleNone(project) {
+  return transformer({
+    point: function(x, y) {
+      x = project(x, y);
+      this.stream.point(x[0], x[1]);
+    }
+  });
+}
+
+function resample(project, delta2) {
+
+  function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) {
+    var dx = x1 - x0,
+        dy = y1 - y0,
+        d2 = dx * dx + dy * dy;
+    if (d2 > 4 * delta2 && depth--) {
+      var a = a0 + a1,
+          b = b0 + b1,
+          c = c0 + c1,
+          m = sqrt(a * a + b * b + c * c),
+          phi2 = asin(c /= m),
+          lambda2 = abs(abs(c) - 1) < epsilon || abs(lambda0 - lambda1) < epsilon ? (lambda0 + lambda1) / 2 : atan2(b, a),
+          p = project(lambda2, phi2),
+          x2 = p[0],
+          y2 = p[1],
+          dx2 = x2 - x0,
+          dy2 = y2 - y0,
+          dz = dy * dx2 - dx * dy2;
+      if (dz * dz / d2 > delta2 // perpendicular projected distance
+          || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end
+          || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance
+        resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream);
+        stream.point(x2, y2);
+        resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream);
+      }
+    }
+  }
+  return function(stream) {
+    var lambda00, x00, y00, a00, b00, c00, // first point
+        lambda0, x0, y0, a0, b0, c0; // previous point
+
+    var resampleStream = {
+      point: point,
+      lineStart: lineStart,
+      lineEnd: lineEnd,
+      polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; },
+      polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; }
+    };
+
+    function point(x, y) {
+      x = project(x, y);
+      stream.point(x[0], x[1]);
+    }
+
+    function lineStart() {
+      x0 = NaN;
+      resampleStream.point = linePoint;
+      stream.lineStart();
+    }
+
+    function linePoint(lambda, phi) {
+      var c = cartesian([lambda, phi]), p = project(lambda, phi);
+      resampleLineTo(x0, y0, lambda0, a0, b0, c0, x0 = p[0], y0 = p[1], lambda0 = lambda, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);
+      stream.point(x0, y0);
+    }
+
+    function lineEnd() {
+      resampleStream.point = point;
+      stream.lineEnd();
+    }
+
+    function ringStart() {
+      lineStart();
+      resampleStream.point = ringPoint;
+      resampleStream.lineEnd = ringEnd;
+    }
+
+    function ringPoint(lambda, phi) {
+      linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;
+      resampleStream.point = linePoint;
+    }
+
+    function ringEnd() {
+      resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream);
+      resampleStream.lineEnd = lineEnd;
+      lineEnd();
+    }
+
+    return resampleStream;
+  };
+}
Index: node_modules/d3-geo/src/projection/stereographic.js
===================================================================
--- node_modules/d3-geo/src/projection/stereographic.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/stereographic.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,18 @@
+import {atan, cos, sin} from "../math.js";
+import {azimuthalInvert} from "./azimuthal.js";
+import projection from "./index.js";
+
+export function stereographicRaw(x, y) {
+  var cy = cos(y), k = 1 + cos(x) * cy;
+  return [cy * sin(x) / k, sin(y) / k];
+}
+
+stereographicRaw.invert = azimuthalInvert(function(z) {
+  return 2 * atan(z);
+});
+
+export default function() {
+  return projection(stereographicRaw)
+      .scale(250)
+      .clipAngle(142);
+}
Index: node_modules/d3-geo/src/projection/transverseMercator.js
===================================================================
--- node_modules/d3-geo/src/projection/transverseMercator.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/projection/transverseMercator.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,27 @@
+import {atan, exp, halfPi, log, tan} from "../math.js";
+import {mercatorProjection} from "./mercator.js";
+
+export function transverseMercatorRaw(lambda, phi) {
+  return [log(tan((halfPi + phi) / 2)), -lambda];
+}
+
+transverseMercatorRaw.invert = function(x, y) {
+  return [-y, 2 * atan(exp(x)) - halfPi];
+};
+
+export default function() {
+  var m = mercatorProjection(transverseMercatorRaw),
+      center = m.center,
+      rotate = m.rotate;
+
+  m.center = function(_) {
+    return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]);
+  };
+
+  m.rotate = function(_) {
+    return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]);
+  };
+
+  return rotate([0, 0, 90])
+      .scale(159.155);
+}
Index: node_modules/d3-geo/src/rotation.js
===================================================================
--- node_modules/d3-geo/src/rotation.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/rotation.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,79 @@
+import compose from "./compose.js";
+import {abs, asin, atan2, cos, degrees, pi, radians, sin, tau} from "./math.js";
+
+function rotationIdentity(lambda, phi) {
+  if (abs(lambda) > pi) lambda -= Math.round(lambda / tau) * tau;
+  return [lambda, phi];
+}
+
+rotationIdentity.invert = rotationIdentity;
+
+export function rotateRadians(deltaLambda, deltaPhi, deltaGamma) {
+  return (deltaLambda %= tau) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma))
+    : rotationLambda(deltaLambda))
+    : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma)
+    : rotationIdentity);
+}
+
+function forwardRotationLambda(deltaLambda) {
+  return function(lambda, phi) {
+    lambda += deltaLambda;
+    if (abs(lambda) > pi) lambda -= Math.round(lambda / tau) * tau;
+    return [lambda, phi];
+  };
+}
+
+function rotationLambda(deltaLambda) {
+  var rotation = forwardRotationLambda(deltaLambda);
+  rotation.invert = forwardRotationLambda(-deltaLambda);
+  return rotation;
+}
+
+function rotationPhiGamma(deltaPhi, deltaGamma) {
+  var cosDeltaPhi = cos(deltaPhi),
+      sinDeltaPhi = sin(deltaPhi),
+      cosDeltaGamma = cos(deltaGamma),
+      sinDeltaGamma = sin(deltaGamma);
+
+  function rotation(lambda, phi) {
+    var cosPhi = cos(phi),
+        x = cos(lambda) * cosPhi,
+        y = sin(lambda) * cosPhi,
+        z = sin(phi),
+        k = z * cosDeltaPhi + x * sinDeltaPhi;
+    return [
+      atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi),
+      asin(k * cosDeltaGamma + y * sinDeltaGamma)
+    ];
+  }
+
+  rotation.invert = function(lambda, phi) {
+    var cosPhi = cos(phi),
+        x = cos(lambda) * cosPhi,
+        y = sin(lambda) * cosPhi,
+        z = sin(phi),
+        k = z * cosDeltaGamma - y * sinDeltaGamma;
+    return [
+      atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi),
+      asin(k * cosDeltaPhi - x * sinDeltaPhi)
+    ];
+  };
+
+  return rotation;
+}
+
+export default function(rotate) {
+  rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0);
+
+  function forward(coordinates) {
+    coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians);
+    return coordinates[0] *= degrees, coordinates[1] *= degrees, coordinates;
+  }
+
+  forward.invert = function(coordinates) {
+    coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians);
+    return coordinates[0] *= degrees, coordinates[1] *= degrees, coordinates;
+  };
+
+  return forward;
+}
Index: node_modules/d3-geo/src/stream.js
===================================================================
--- node_modules/d3-geo/src/stream.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/stream.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,69 @@
+function streamGeometry(geometry, stream) {
+  if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) {
+    streamGeometryType[geometry.type](geometry, stream);
+  }
+}
+
+var streamObjectType = {
+  Feature: function(object, stream) {
+    streamGeometry(object.geometry, stream);
+  },
+  FeatureCollection: function(object, stream) {
+    var features = object.features, i = -1, n = features.length;
+    while (++i < n) streamGeometry(features[i].geometry, stream);
+  }
+};
+
+var streamGeometryType = {
+  Sphere: function(object, stream) {
+    stream.sphere();
+  },
+  Point: function(object, stream) {
+    object = object.coordinates;
+    stream.point(object[0], object[1], object[2]);
+  },
+  MultiPoint: function(object, stream) {
+    var coordinates = object.coordinates, i = -1, n = coordinates.length;
+    while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]);
+  },
+  LineString: function(object, stream) {
+    streamLine(object.coordinates, stream, 0);
+  },
+  MultiLineString: function(object, stream) {
+    var coordinates = object.coordinates, i = -1, n = coordinates.length;
+    while (++i < n) streamLine(coordinates[i], stream, 0);
+  },
+  Polygon: function(object, stream) {
+    streamPolygon(object.coordinates, stream);
+  },
+  MultiPolygon: function(object, stream) {
+    var coordinates = object.coordinates, i = -1, n = coordinates.length;
+    while (++i < n) streamPolygon(coordinates[i], stream);
+  },
+  GeometryCollection: function(object, stream) {
+    var geometries = object.geometries, i = -1, n = geometries.length;
+    while (++i < n) streamGeometry(geometries[i], stream);
+  }
+};
+
+function streamLine(coordinates, stream, closed) {
+  var i = -1, n = coordinates.length - closed, coordinate;
+  stream.lineStart();
+  while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]);
+  stream.lineEnd();
+}
+
+function streamPolygon(coordinates, stream) {
+  var i = -1, n = coordinates.length;
+  stream.polygonStart();
+  while (++i < n) streamLine(coordinates[i], stream, 1);
+  stream.polygonEnd();
+}
+
+export default function(object, stream) {
+  if (object && streamObjectType.hasOwnProperty(object.type)) {
+    streamObjectType[object.type](object, stream);
+  } else {
+    streamGeometry(object, stream);
+  }
+}
Index: node_modules/d3-geo/src/transform.js
===================================================================
--- node_modules/d3-geo/src/transform.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
+++ node_modules/d3-geo/src/transform.js	(revision e4c61dd6cd86e06265bc2bd91adba84a0f04044a)
@@ -0,0 +1,26 @@
+export default function(methods) {
+  return {
+    stream: transformer(methods)
+  };
+}
+
+export function transformer(methods) {
+  return function(stream) {
+    var s = new TransformStream;
+    for (var key in methods) s[key] = methods[key];
+    s.stream = stream;
+    return s;
+  };
+}
+
+function TransformStream() {}
+
+TransformStream.prototype = {
+  constructor: TransformStream,
+  point: function(x, y) { this.stream.point(x, y); },
+  sphere: function() { this.stream.sphere(); },
+  lineStart: function() { this.stream.lineStart(); },
+  lineEnd: function() { this.stream.lineEnd(); },
+  polygonStart: function() { this.stream.polygonStart(); },
+  polygonEnd: function() { this.stream.polygonEnd(); }
+};
