text: // wrapped by build app
  define("d3/src/geo/bounds", ["dojo","dijit","dojox"], function(dojo,dijit,dojox){
  import "../math/abs";
  import "geo";
  import "stream";
  import "area";
  import "cartesian";
  import "spherical";
  
  d3.geo.bounds = (function() {
    var λ0, φ0, λ1, φ1, // bounds
        λ_, // previous λ-coordinate
        λ__, φ__, // first point
        p0, // previous 3D point
        dλSum,
        ranges,
        range;
  
    var bound = {
      point: point,
      lineStart: lineStart,
      lineEnd: lineEnd,
  
      polygonStart: function() {
        bound.point = ringPoint;
        bound.lineStart = ringStart;
        bound.lineEnd = ringEnd;
        dλSum = 0;
        d3_geo_area.polygonStart();
      },
      polygonEnd: function() {
        d3_geo_area.polygonEnd();
        bound.point = point;
        bound.lineStart = lineStart;
        bound.lineEnd = lineEnd;
        if (d3_geo_areaRingSum < 0) λ0 = -(λ1 = 180), φ0 = -(φ1 = 90);
        else if (dλSum > ε) φ1 = 90;
        else if (dλSum < -ε) φ0 = -90;
        range[0] = λ0, range[1] = λ1;
      }
    };
  
    function point(λ, φ) {
      ranges.push(range = [λ0 = λ, λ1 = λ]);
      if (φ < φ0) φ0 = φ;
      if (φ > φ1) φ1 = φ;
    }
  
    function linePoint(λ, φ) {
      var p = d3_geo_cartesian([λ * d3_radians, φ * d3_radians]);
      if (p0) {
        var normal = d3_geo_cartesianCross(p0, p),
            equatorial = [normal[1], -normal[0], 0],
            inflection = d3_geo_cartesianCross(equatorial, normal);
        d3_geo_cartesianNormalize(inflection);
        inflection = d3_geo_spherical(inflection);
        var dλ = λ - λ_,
            s = dλ > 0 ? 1 : -1,
            λi = inflection[0] * d3_degrees * s,
            antimeridian = abs(dλ) > 180;
        if (antimeridian ^ (s * λ_ < λi && λi < s * λ)) {
          var φi = inflection[1] * d3_degrees;
          if (φi > φ1) φ1 = φi;
        } else if (λi = (λi + 360) % 360 - 180, antimeridian ^ (s * λ_ < λi && λi < s * λ)) {
          var φi = -inflection[1] * d3_degrees;
          if (φi < φ0) φ0 = φi;
        } else {
          if (φ < φ0) φ0 = φ;
          if (φ > φ1) φ1 = φ;
        }
        if (antimeridian) {
          if (λ < λ_) {
            if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ;
          } else {
            if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ;
          }
        } else {
          if (λ1 >= λ0) {
            if (λ < λ0) λ0 = λ;
            if (λ > λ1) λ1 = λ;
          } else {
            if (λ > λ_) {
              if (angle(λ0, λ) > angle(λ0, λ1)) λ1 = λ;
            } else {
              if (angle(λ, λ1) > angle(λ0, λ1)) λ0 = λ;
            }
          }
        }
      } else {
        point(λ, φ);
      }
      p0 = p, λ_ = λ;
    }
  
    function lineStart() { bound.point = linePoint; }
    function lineEnd() {
      range[0] = λ0, range[1] = λ1;
      bound.point = point;
      p0 = null;
    }
  
    function ringPoint(λ, φ) {
      if (p0) {
        var dλ = λ - λ_;
        dλSum += abs(dλ) > 180 ? dλ + (dλ > 0 ? 360 : -360) : dλ;
      } else λ__ = λ, φ__ = φ;
      d3_geo_area.point(λ, φ);
      linePoint(λ, φ);
    }
  
    function ringStart() {
      d3_geo_area.lineStart();
    }
  
    function ringEnd() {
      ringPoint(λ__, φ__);
      d3_geo_area.lineEnd();
      if (abs(dλSum) > ε) λ0 = -(λ1 = 180);
      range[0] = λ0, range[1] = λ1;
      p0 = null;
    }
  
    // Finds the left-right distance between two longitudes.
    // This is almost the same as (λ1 - λ0 + 360°) % 360°, except that we want
    // the distance between ±180° to be 360°.
    function angle(λ0, λ1) { return (λ1 -= λ0) < 0 ? λ1 + 360 : λ1; }
  
    function compareRanges(a, b) { return a[0] - b[0]; }
  
    function withinRange(x, range) {
      return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;
    }
  
    return function(feature) {
      φ1 = λ1 = -(λ0 = φ0 = Infinity);
      ranges = [];
  
      d3.geo.stream(feature, bound);
  
      var n = ranges.length;
      if (n) {
        // First, sort ranges by their minimum longitudes.
        ranges.sort(compareRanges);
  
        // Then, merge any ranges that overlap.
        for (var i = 1, a = ranges[0], b, merged = [a]; i < n; ++i) {
          b = ranges[i];
          if (withinRange(b[0], a) || withinRange(b[1], a)) {
            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.
        var best = -Infinity, dλ;
        for (var n = merged.length - 1, i = 0, a = merged[n], b; i <= n; a = b, ++i) {
          b = merged[i];
          if ((dλ = angle(a[1], b[0])) > best) best = dλ, λ0 = b[0], λ1 = a[1];
        }
      }
      ranges = range = null;
  
      return λ0 === Infinity || φ0 === Infinity
          ? [[NaN, NaN], [NaN, NaN]]
          : [[λ0, φ0], [λ1, φ1]];
    };
  })();
  
  });
  