function redraw() {
    var t = (0 | Math.log(projection.scale()) / Math.LN2) - 5
        , e = d3.quadTiles(projection, t)
        , n = projection.clipExtent();
    tiles_ = d3.quadTiles(projection.clipExtent([[1, 1], [width - 1, height - 1]]), t);
    var a = svg.selectAll(".tile").data(tiles_, key);
    a.enter().append("path").attr("class", "tile"),
        a.exit().remove(),
        a.attr("class", "tile").attr("d", path),
        svg.selectAll(".tile").data(e, key).classed("highlight", !0).exit().classed("highlight", !1);
    var r = svg.selectAll("text").data(e, key);
    r.enter().append("text").attr("text-anchor", "middle").text(key),
        r.exit().remove(),
        r.attr("transform", function (t) {
            return "translate(" + projection(t.centroid) + ")"
        }),
        projection.clipExtent(n)
}
function key(t) {
    return t.key.join(", ")
}
!function () {
    function t() { }
    function e(t) {
        return 360 * Math.atan(Math.exp(-t * Math.PI / 180)) / Math.PI - 90
    }
    d3.quadTiles = function (n, a) {
        function r(t, n, p, d) {
            var h = p - t
                , g = e(n)
                , u = e(d)
                , v = l * h;
            i = !0,
                s.polygonStart(),
                s.lineStart();
            for (var f = t; p + v / 2 > f && i; f += v)
                s.point(f, g);
            for (var m = g; (m += v) < u && i;)
                s.point(p, m);
            for (var f = p; f > t - v / 2 && i; f -= v)
                s.point(f, u);
            for (var m = u; (m -= v) > g && i;)
                s.point(t, m);
            if (i && s.point(t, g),
                s.lineEnd(),
                s.polygonEnd(),
                360 / c >= h)
                i || o.push({
                    type: "Polygon",
                    coordinates: [d3.range(t, p + v / 2, v).map(function (t) {
                        return [t, n]
                    }).concat([[p, .5 * (n + d)]]).concat(d3.range(p, t - v / 2, -v).map(function (t) {
                        return [t, d]
                    })).concat([[t, .5 * (n + d)]]).concat([[t, n]]).map(function (t) {
                        return [t[0], e(t[1])]
                    })],
                    key: [0 | (180 + t) / 360 * c, 0 | (180 + n) / 360 * c, a],
                    centroid: [.5 * (t + p), .5 * (g + u)]
                });
            else if (!i) {
                var f = .5 * (t + p)
                    , m = .5 * (n + d);
                r(t, n, f, m),
                    r(f, n, p, m),
                    r(t, m, f, d),
                    r(f, m, p, d)
            }
        }
        var i, o = [], c = 1 << (a = Math.max(0, a)), l = Math.max(.2, Math.min(1, .01 * a)), p = n.precision(), s = n.precision(960).stream({
            point: function () {
                i = !1
            },
            lineStart: t,
            lineEnd: t,
            polygonStart: t,
            polygonEnd: t
        });
        return r(-180, -180, 180, 180),
            n.precision(p),
            o
    }
}();
var width = 960
    , height = 600
    , p = 100
    , projection = d3.geo.albers().rotate([0, 0]).center([0, 38.7]).scale(1280).translate([width / 2, height / 2]).precision(.1).clipExtent([[p, p], [width - p, height - p]])
    , path = d3.geo.path().projection(projection)
    , svg = d3.select("#map").append("svg").attr("width", width).attr("height", height).style("pointer-events", "all").call(d3.behavior.zoom().translate(projection.translate()).scale(projection.scale()).scaleExtent([50, 1e7]).on("zoom", function () {
        projection.scale(d3.event.scale).translate(d3.event.translate),
            redraw()
    }));
svg.append("path").datum({
    type: "Sphere"
}).attr("class", "outline").attr("d", path),
    redraw();
