(function() {
  
// noprotect
;
  var SCALE, SIDE, cpr, height, i, j, map, merge, squares, succeeded, svg, width, zoom, zoomable_layer, _i, _j;

  console.debug('Generating squares...');

  SIDE = 128;

  cpr = new ClipperLib.Clipper();

  squares = new ClipperLib.Paths();

  merge = new ClipperLib.Paths();

  for (i = _i = 0; 0 <= SIDE ? _i < SIDE : _i > SIDE; i = 0 <= SIDE ? ++_i : --_i) {
    for (j = _j = 0; 0 <= SIDE ? _j < SIDE : _j > SIDE; j = 0 <= SIDE ? ++_j : --_j) {
      if (Math.random() < 0.1) {
        continue;
      }
      squares.push([
        {
          X: j,
          Y: i
        }, {
          X: j + 1,
          Y: i
        }, {
          X: j + 1,
          Y: i + 1
        }, {
          X: j,
          Y: i + 1
        }
      ]);
    }
  }

  console.debug('Merging...');

  cpr.AddPaths(squares, ClipperLib.PolyType.ptSubject, true);

  succeeded = cpr.Execute(ClipperLib.ClipType.ctUnion, merge);

  console.debug('Drawing...');

  SCALE = 400 / SIDE;

  svg = d3.select('svg');

  width = svg.node().getBoundingClientRect().width;

  height = svg.node().getBoundingClientRect().height;

  svg.attr({
    viewBox: "" + (-width / 2) + " " + (-height / 2) + " " + width + " " + height
  });

  zoomable_layer = svg.append('g');

  zoom = d3.behavior.zoom().scaleExtent([1, 16]).on('zoom', function() {
    return zoomable_layer.attr({
      transform: "translate(" + (zoom.translate()) + ")scale(" + (zoom.scale()) + ")"
    });
  });

  svg.call(zoom);

  map = zoomable_layer.append('g').attr({
    transform: "translate(" + (-SCALE * SIDE / 2) + ", " + (-SCALE * SIDE / 2) + ")"
  });

  map.append('path').datum(merge).attr({
    "class": 'land',
    d: function(merge) {
      var d_str, linestring, _k, _len;

      d_str = '';
      for (_k = 0, _len = merge.length; _k < _len; _k++) {
        linestring = merge[_k];
        d_str += 'M' + linestring.map(function(p) {
          return "" + (SCALE * p.X) + " " + (SCALE * p.Y);
        }).join('L') + 'z';
      }
      return d_str;
    }
  });

  map.append('rect').attr({
    "class": 'boundary',
    width: SCALE * SIDE,
    height: SCALE * SIDE
  });

}).call(this);