Skip to content

Instantly share code, notes, and snippets.

@emeeks
Last active October 27, 2019 19:51
Show Gist options
  • Save emeeks/912e24404b85a2af7dc7cb17927e816d to your computer and use it in GitHub Desktop.
Save emeeks/912e24404b85a2af7dc7cb17927e816d to your computer and use it in GitHub Desktop.
Wargames Aesthetic

Strange game. The only way to win is not to play.

function circlePath(radius) {
let arc = d3.arc().outerRadius(radius);
return arc({ startAngle: 0, endAngle: 8 })
}
function rectPath(width,height) {
return "M0,0L" + width + ",0L" + width + "," + height + "L0," + height + "Z"
}
function linePath(x1,x2,y1,y2) {
return "M" + x1 + "," + y1 + "L" + x2 + "," + y2 + "L"
}
function jitterLine (pathNode) {
let length = pathNode.getTotalLength();
let j = 2;
let x = j + Math.random() * j * 5;
let jitteredPoints = [];
let lineGen = d3.line()
.x(d => d.x)
.y(d => d.y)
.curve(d3.curveCatmullRom.alpha(0.5));
let newPoint = pathNode.getPointAtLength(0);
jitteredPoints.push(newPoint);
while (x < length) {
newPoint = pathNode.getPointAtLength(x);
let newX = newPoint.x + (Math.random() * j - j/2);
let newY = newPoint.y + (Math.random() * j - j/2)
jitteredPoints.push({ x: newX, y: newY })
x += j + Math.random() * j * 5;
}
newPoint = pathNode.getPointAtLength(length);
jitteredPoints.push(newPoint);
return lineGen(jitteredPoints);
}
function cheapSketchy(path) {
let length = path.getTotalLength();
let drawCode = "";
let x = 0;
let step = 8;
while (x < length / 2) {
let start = path.getPointAtLength(x);
let end = path.getPointAtLength(length - x);
drawCode += " M" +
(start.x + (Math.random() * step - step/2)) + " " +
(start.y + (Math.random() * step - step/2)) + "L" +
(end.x + (Math.random() * step - step/2)) + " " +
(end.y + (Math.random() * step - step/2));
x += step + Math.random() * step;
}
return drawCode;
}
function cheapPopArtsy (path) {
let length = path.getTotalLength();
let circles = []
let x = 0;
let step = 8;
while (x < length / 2) {
let start = path.getPointAtLength(x);
let end = path.getPointAtLength(length - x);
let begin = 0.75
while (begin < step) {
const percent = begin / step
const circleXa = percent * start.x
const circleXb = (1 - percent) * end.x
const circleYa = percent * start.y
const circleYb = (1 - percent) * end.y
circles.push([circleXa + circleXb, circleYa + circleYb])
begin = begin + (1 + Math.random())
}
x = x + step
}
return circles;
}
randomColor = function (baseColor,range) {
var hslBase = d3.hsl(baseColor)
hslBase.h = hslBase.h + (Math.floor(Math.random() * (range * 255)) - Math.floor(range / 2));
hslBase.s = hslBase.s + (Math.floor(Math.random() * range) - Math.floor(range / 2));
hslBase.l = hslBase.l + (Math.floor(Math.random() * range) - Math.floor(range / 2));
return hslBase.toString();
}
/*global d3:false */
/*jshint unused:false*/
/**
* Initiate the sketchy library
* @constructor
*/
var d3sketchy = function(){
/**
* Default attributes for generating the shapes, doing this we don't need to check if all parameters are provided
* And if someone wants to build a lot of shapes with the same properties she just needs to use "setDefaults" to change them
* @type {object}
* @defaultvalue
*/
var defaults = {
x:0,
y:0,
width:20,
height:20,
sketch:1,
density:1,
radius:10,
angle:45,
count:2,
shape:"circle",
clip:"",
margin:2
};
/**
* Changing the default attributes
* @param {object} opts - object with default attributes see "var defaults"
* @return {object} defaults - the full default object
*/
function setDefaults(opts){
defaults = extend(defaults, opts);
return defaults;
}
/**
* merging two objects, source will replace duplicates in destination
* @param {object} destination
* @param {object} source
*/
function extend(destination, source) {
var returnObj = {}, attrname;
for (attrname in destination) { returnObj[attrname] = destination[attrname]; }
for (attrname in source) { returnObj[attrname] = source[attrname]; }
return returnObj;
}
/**
* Generate random number between min and max
* @param {float|int} min
* @param {float|int} max
* @return {float}
*/
function rand(min, max){
return Math.random()* (max-min) + min;
}
/**
* Create sketchy
* @constructor
*/
function sketchy(){
}
/**
* drawing a sketchy line
* this is kind of the heart of the whole tool.
* so if you want to make changes to the appearance of the lines, tweak the following lines
* @param {object} opts
* @param {d3.selection} opts.svg
* @param {float|int} opts.x1 - x point 1
* @param {float|int} opts.y1 - y point 1
* @param {float|int} opts.x2 - x point 2
* @param {float|int} opts.y2 - y point 2
* @param {object} opts.sketch
* @param {object} opts.sketch.x - sketchiness on the x-axis
* @param {object} opts.sketch.y - sketchiness on the y-axis
*/
sketchy.drawLine = function(opts){
//Each line is drawn twice the increase sketchiness
for(var i = 1; i<3; i++){
var or2 = rand(0.2, 0.8);
var cx2 = opts.x1+ (opts.x2-opts.x1)*or2+rand(-1,1);
var cy2 = opts.y1+ (opts.y2-opts.y1)*or2+rand(-1,1);
var or1 = or2 + rand(-0.3, -0.2);
var cx1 = opts.x1+ (opts.x2-opts.x1)*or1+rand(-1,1);
var cy1 = opts.y1+ (opts.y2-opts.y1)*or1+rand(-1,1);
opts.svg.append("path")
.attr("d", "M"+
(opts.x1 + rand(-1,0)*opts.sketch.x/i)+" "+
(opts.y1 + rand(-1,1)*opts.sketch.y/i)+" Q"+
cx1+" "+cy1+" "+
cx2+" "+cy2+" T"+
(opts.x2 + rand(0,1)*opts.sketch.x/i)+" "+
(opts.y2 + rand(-1,1)*opts.sketch.y/i));
}
};
sketchy.drawLineSinglePath = function(opts){
//Each line is drawn twice the increase sketchiness
var sketching = "";
for(var i = 1; i<3; i++){
var or2 = rand(0.2, 0.8);
var cx2 = opts.x1+ (opts.x2-opts.x1)*or2+rand(-1,1);
var cy2 = opts.y1+ (opts.y2-opts.y1)*or2+rand(-1,1);
var or1 = or2 + rand(-0.3, -0.2);
var cx1 = opts.x1+ (opts.x2-opts.x1)*or1+rand(-1,1);
var cy1 = opts.y1+ (opts.y2-opts.y1)*or1+rand(-1,1);
sketching += " M"+
(opts.x1 + rand(-1,0)*opts.sketch.x/i)+" "+
(opts.y1 + rand(-1,1)*opts.sketch.y/i)+" Q"+
cx1+" "+cy1+" "+
cx2+" "+cy2+" T"+
(opts.x2 + rand(0,1)*opts.sketch.x/i)+" "+
(opts.y2 + rand(-1,1)*opts.sketch.y/i);
}
return sketching;
};
/**
* drawing a circle shape
* no outline just the fill
* @param {object} opts - object containing the attributes
* @param {float|int} opts.x - x position
* @param {float|int} opts.y - y position
* @param {float|int} opts.r - radius
* @param {float|int} opts.angle - angle of the lines (0-360)
* @param {float|int} opts.density - distance between lines
* @param {float|int} opts.sketch - sketchiness factor
* @param {string} opts.shape - this is a development relic, default is "circle", alternatives "cut" and "star"
* @return {object} svg - d3.selection of a group object, containing the circle
*/
sketchy.circleFill = function(opts){
//merging default attributes with user attributes
var merged_opts = extend(defaults, opts);
//create a container, this is used to translate and rotate the circle, this container will be returned at the end of this function
var svg = merged_opts.svg.append("g").attr("transform", "translate("+merged_opts.x+" "+merged_opts.y+") rotate("+merged_opts.angle+")");
var fillLines = "";
//Looping through the lines
var y_dist = 0;
while(y_dist > -2*opts.r){
var x;
//During the development i accidentaly generated those shapes and kept them :)
if(merged_opts.shape==="cut"){
x = Math.sqrt( ( Math.pow(merged_opts.r, 2) - Math.pow((merged_opts.r-Math.abs(y_dist)), 2) ) );
}else if(merged_opts.shape==="star"){
x = merged_opts.r - Math.sqrt( ( Math.pow(merged_opts.r, 2) - Math.pow((merged_opts.r-Math.abs(y_dist)), 2) ) );
}else{
x = Math.sqrt( ( Math.pow(merged_opts.r, 2) - Math.pow((merged_opts.r-Math.abs(y_dist)), 2) ) );
}
//Draw the sketchy lines
fillLines += sketchy.drawLineSinglePath({
svg:svg,
x1:-x,
y1:y_dist+merged_opts.r,
x2:x,
y2:y_dist+merged_opts.r,
sketch:{
x:merged_opts.density*merged_opts.sketch,
y:merged_opts.density*merged_opts.sketch
}
});
y_dist -= merged_opts.density;
}
svg.append("path").attr("d", fillLines);
return svg;
};
/**
* draws a rectangle
* no outline just the fill
* @param {object} opts - object containing the attributes
* @param {float|int} opts.x - x position
* @param {float|int} opts.y - y position
* @param {float|int} opts.width - width
* @param {float|int} opts.height - height
* @param {float|int} opts.angle - angle of the lines (0-360)
* @param {float|int} opts.density - distance between lines
* @param {float|int} opts.sketch - sketchiness factor
* @return {object} svg - d3.selection of a group object, containing the rectangle
*/
sketchy.rectFill = function(opts){
var svg = opts.svg.append("g").attr("transform", "translate("+opts.x+" "+opts.y+")");
opts.svg = svg;
return sketchy.drawPattern(opts);
};
/**
* draws a background pattern in the shape of a square according to x,y,with,height
* @param {object} opts - object containing the attributes
* @param {float|int} opts.x - x position
* @param {float|int} opts.y - y position
* @param {float|int} opts.width - width
* @param {float|int} opts.height - height
* @param {float|int} opts.angle - angle of the lines (0-360)
* @param {float|int} opts.density - distance between lines
* @param {float|int} opts.sketch - sketchiness factor
* @return {object} svg - d3.selection of a group object, containing the background
*/
sketchy.drawPattern = function(opts){
var svg = opts.svg;
var drawCode = "";
//angle for strokes
var angle = opts.angle;
while(angle > 360){angle -= 360;}
if(angle > 180){angle -= 180;}
var radian = (Math.PI/180)*(90-angle);
var vector = {
y:1,
x:-1/Math.tan(radian)
};
//distance between strokes
var dist = opts.density;
var vy, tx, ty, vx, y1, x1, y_dist, x_dist;
opts.x = 0;
opts.y = 0;
var x = opts.x, y = opts.y;
if(Math.abs(angle) === 90){
while(y < opts.y+opts.height){
drawCode += sketchy.drawLineSinglePath({
svg:svg,
x1:x,
y1:y,
x2:x+opts.width,
y2:y,
sketch:{
x:dist*opts.sketch,
y:dist*opts.sketch
}
});
y += dist;
}
}else if((Math.abs(angle) === 180)||(angle === 0)){
while(x < opts.x+opts.width){
drawCode += sketchy.drawLineSinglePath({
svg:svg,
x1:x,
y1:y,
x2:x,
y2:y+opts.height,
sketch:{
x:dist*opts.sketch,
y:dist*opts.sketch
}
});
x += dist;
}
}else if(angle < 90){
y_dist = Math.abs(dist / Math.sin(Math.PI/180*angle));
x_dist = Math.abs(dist / Math.sin(Math.PI/180*(90-angle)));
y += y_dist;
y1 = opts.y;
x1 = opts.x;
while(y1 < opts.y+opts.height){
vx = opts.width / vector.x;
x1 = opts.width + x;
y1 = y + vector.y * vx;
ty = y;
tx = x;
if(y1<opts.y){
vy = (y-opts.y)/vector.y;
x1 = x + Math.abs(vector.x) * vy;
y1 = opts.y;
}else if(y > (opts.y+opts.height)){
ty = opts.y+opts.height;
vy = (ty-y1)/vector.y;
tx = x + opts.width - vy*Math.abs(vector.x);
}
drawCode += sketchy.drawLineSinglePath({
svg:svg,
x1:tx,
y1:ty,
x2:x1,
y2:y1,
sketch:{
x:x_dist*opts.sketch,
y:y_dist*opts.sketch
}
});
y += y_dist;
}
}else{
y_dist = Math.abs(dist / Math.sin(Math.PI/180*angle));
x_dist = Math.abs(dist / Math.sin(Math.PI/180*(180-angle)));
y = opts.y+opts.height;
y -= y_dist;
y1 = opts.y+opts.height;
x1 = opts.x;
while(y1 > opts.y){
vx = opts.width / vector.x;
x1 = opts.width + x;
y1 = y + vector.y * vx;
ty = y;
tx = x;
if(y1>(opts.y+opts.height)){
vy = (y-(opts.y+opts.height))/vector.y;
x1 = x + Math.abs(vector.x * vy);
y1 = opts.y+opts.height;
}else if(y < opts.y){
ty = opts.y;
vy = (ty-y1)/vector.y;
tx = x + opts.width - Math.abs(vy*vector.x);
}
drawCode += sketchy.drawLineSinglePath({
svg:svg,
x1:tx,
y1:ty,
x2:x1,
y2:y1,
sketch:{
x:x_dist*opts.sketch,
y:y_dist*opts.sketch
}
});
y -= y_dist;
}
}
svg.append("path")
.attr("d", drawCode);
return svg;
};
/**
* draws a background pattern in the shape of a square according to the position and size of the clip-path object
* @param {object} opts - object containing the attributes
* @param {string} opts.clip - id of the clip path
* @param {float|int} opts.angle - angle of the lines (0-360)
* @param {float|int} opts.density - distance between lines
* @param {float|int} opts.sketch - sketchiness factor
* @param {float|int} opts.margin - extra margin for the background
* @return {object} svg - d3.selection of a group object, containing the background
*/
sketchy.fill = function(opts){
var merged_opts = extend(defaults, opts);
var svg = merged_opts.svg.append("g")
.attr("clip-path", "url(#"+merged_opts.clip+")");
//Get the bounding box of the object that wants a background
var bb = d3.select("#"+merged_opts.clip).node().getBBox();
//To make sure that the background covers the whole are we increase the background by a few pixels
merged_opts.x = bb.x-merged_opts.margin;
merged_opts.y = bb.y-merged_opts.margin;
merged_opts.width = bb.width + 2*merged_opts.margin;
merged_opts.height = bb.height + 2*merged_opts.margin;
merged_opts.svg = svg;
return sketchy.drawPattern(merged_opts);
};
/**
* draws a background pattern in the shape of a square according to the position and size of the clip-path object
* @param {object} opts - object containing the attributes
* @param {array} opts.path - array of points {x:float|integer, y:float|integer}
* @param {int} opts.count - how many altered paths should be generated
* @param {float|int} opts.sketch - sketchiness factor
* @return {array} paths - altered paths
*/
sketchy.alterPath = function(opts){
var merged_opts = extend(defaults, opts);
var paths = [];
for(var i = 0; i<merged_opts.count; i++){
var t_path = [];
for(var j = 0; j<merged_opts.path.length; j++){
t_path.push({
x:merged_opts.path[j].x + rand(-1,1)*merged_opts.sketch/(i+1),
y:merged_opts.path[j].y + rand(-1,1)*merged_opts.sketch/(i+1)
});
}
paths.push(t_path);
}
return paths;
};
/**
* Draws alterPath() paths
* only straight lines, use alterPath and your own drawing function to draw curves etc.
* @param {object} opts - object containing the attributes
* @param {array} opts.svg - d3.selection of an svg
* @param {array} opts.path - array of points {x:float|integer, y:float|integer}
* @param {int} opts.count - how many altered paths should be generated
* @param {float|int} opts.sketch - sketchiness factor
* @return {object} svg - svg with the strokes
*/
sketchy.pathStroke = function(opts){
var paths = sketchy.alterPath(opts);
var svg = opts.svg;
var drawCode = "";
for(var i = 0; i<paths.length; i++){
for(var j = 0; j<paths[i].length; j++){
var x1 = paths[i][j].x;
var y1 = paths[i][j].y, x2, y2;
if(j<(paths[i].length-1)){
x2 = paths[i][j+1].x;
y2 = paths[i][j+1].y;
}else{
x2 = paths[i][0].x;
y2 = paths[i][0].y;
}
drawCode += sketchy.drawLineSinglePath({
svg:svg,
x1:x1,
y1:y1,
x2:x2,
y2:y2,
sketch:{
x:opts.sketch,
y:opts.sketch
}
});
}
}
svg.append("path")
.style("stroke", opts.stroke)
.style("stroke-width", opts.strokeWidth)
.attr("d", drawCode);
return svg;
};
/**
* Helper function for circleStroke
* Adapted from http://codepen.io/spencerthayer/pen/nhjwu
* Generates an altered circle path
* @param {float|int} radius - radius of the circle
* @param {float|int} radius_min - alternating radius min
* @param {float|int} radius_max - alternating radius max
* @param {float|int} s_angle_min - alternating angle min
* @param {float|int} s_angle_max - alternating angle max
* @param {float|int} rotation_min - alternating rotation min
* @param {float|int} rotation_max - alternating rotation max
* @return {string} path - altered circle svg path
*/
function circlePath(radius, radius_min,radius_max, s_angle_min, s_angle_max, rotation_min,rotation_max) {
var c = 0.551915024494,
b = Math.atan(c),
d = Math.sqrt(c*c+1*1),
r = radius,
o = rand(s_angle_min, s_angle_max)*Math.PI/180,
path = 'M';
path += [r * Math.sin(o), r * Math.cos(o)];
path += ' C' + [d * r * Math.sin(o + b), d * r * Math.cos(o + b)];
for (var i=0; i<4; i++) {
o += Math.PI/2 * (1 + rand(rotation_min, rotation_max));
r *= (1 + rand(radius_min, radius_max));
path += ' ' + (i?'S':'') + [d * r * Math.sin(o - b), d * r * Math.cos(o - b)];
path += ' ' + [r * Math.sin(o), r * Math.cos(o)];
}
return path;
}
/**
* Helper function for circleStroke
* Adapted from http://codepen.io/spencerthayer/pen/nhjwu
* Generates the transform value for squashing and rotating
* @param {float|int} squash_min - squashing min
* @param {float|int} squash_max - squashing max
* @param {float|int} squash_rotation_min - squashing rotation min
* @param {float|int} squash_rotation_max - squashing rotation max
* @return {string} path - transform string
*/
function circleTransform(squash_min, squash_max, squash_rotation_min, squash_rotation_max) {
var o = rand(squash_rotation_min, squash_rotation_max);
return 'rotate('+o+')'+'scale(1,'+rand(squash_min, squash_max) + ')';
}
/**
* Draw a sketch circle stroke
* Adapted from http://codepen.io/spencerthayer/pen/nhjwu
* @param {object} opts - object containing the attributes
* @param {object} opts.svg - svg container
* @param {float|int} opts.x - center x of circle
* @param {float|int} opts.y - center y of circle
* @param {float|int} opts.r - radius of circle
* @param {int} count - number of strokes
* @param {float|int} sketch - sketchiness factor
* @return {object} svg - d3.selection of the svg containing the circles
*/
sketchy.circleStroke = function(opts){
var merged_opts = extend(defaults, opts);
var svg = merged_opts.svg.append("g").attr('transform', function() { return "translate("+merged_opts.x+" "+merged_opts.y+") "+circleTransform(1,1, 0,360); });
var drawCode = "";
for(var i = 0; i<merged_opts.count; i++){
drawCode += " " + circlePath(merged_opts.r, merged_opts.sketch/-50/(i+1),merged_opts.sketch/10/(i+1), 200,240, 0,merged_opts.sketch/5/(i+1));
}
svg.append('path')
.attr("class", "sketchy-stroke")
.attr('d', drawCode);
return svg;
};
/**
* Draw a sketch rectangle stroke
* @param {object} opts - object containing the attributes
* @param {object} opts.svg - svg container
* @param {float|int} opts.x - x coordinate
* @param {float|int} opts.y - y coordinate
* @param {float|int} opts.width - width
* @param {float|int} opts.height - height
* @param {int} count - number of strokes
* @param {float|int} sketch - sketchiness factor
* @return {object} svg - d3.selection of the svg containing the rectangles
*/
sketchy.rectStroke = function(opts){
var merged_opts = extend(defaults, opts);
var svg = merged_opts.svg.append("g");
var path = [
{x:merged_opts.x, y:merged_opts.y},
{x:merged_opts.x+merged_opts.width, y:merged_opts.y},
{x:merged_opts.x+merged_opts.width, y:merged_opts.y+merged_opts.height},
{x:merged_opts.x, y:merged_opts.y+merged_opts.height}
];
return sketchy.pathStroke({svg:svg, path:path, count:merged_opts.count, sketch:merged_opts.sketch});
};
return sketchy;
};
<html>
<head>
<title>Strange Game</title>
<meta charset="utf-8" />
<script src="//d3js.org/d3.v4.min.js"></script>
<script src="//d3js.org/d3-geo-projection.v1.min.js"></script>
<script src="//d3js.org/topojson.v1.min.js"></script>
<script src="d3.sketchy.js"></script>
<script src="cheapMarky.js"></script>
</head>
<style>
body {
background: black;
}
svg {
height: 1000px;
width: 1280px;
border: none;
}
.countries {
fill: $443636;
stroke: none;
}
</style>
<body>
<div id="viz">
<svg>
</svg>
</div>
<div id="controls" />
</body>
<footer>
<script>
var colorScale = d3.scaleOrdinal().range(["#f8a313", "#a5c4c5", "#bab218", "#f0d976", "#e8381b", "#ee791e"]);
var filter = d3.select("svg").append("defs").append("filter").attr("id", "gooeyCodeFilter");
filter.append("feGaussianBlur").attr("id", "gaussblurrer").attr("in", "SourceGraphic").attr("stdDeviation", 4).attr("color-interpolation-filters", "sRGB").attr("result", "blur");
filter.append("feColorMatrix").attr("in", "blur").attr("mode", "matrix").attr("values", "1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 34 -7").attr("result", "gooey");
var svg = d3.select("svg");
d3.select("svg").append("g").attr("class", "bg")
d3.select("svg").append("g").attr("class", "fill")
.style("filter", "url(#gooeyCodeFilter)")
d3.select("svg").append("g").attr("class", "border")
d3.select("svg").append("g").attr("class", "explosions")
.style("filter", "url(#gooeyCodeFilter)")
var sketchy = d3sketchy();
var projection = d3.geoArmadillo()
.scale(300)
.translate([600, 360])
.parallel(20)
.rotate([-12, 0])
.precision(.1);
var geoPath = d3.geoPath().projection(projection);
var line = d3.line()
.x(function(d) { return d.x; })
.y(function(d) { return d.y; });
var numSides = 6
var sources
var countries
var sideHash
d3.json("simpleworld.json", createMap);
var powers = ["USA", "RUS", "CHN", "ISR", "IND", "PAK", "GBR", "FRA"]
function createMap(world) {
countries = topojson.feature(world, world.objects.world);
renderMap(countries, projection)
}
function renderMap(countries, projection) {
sideHash = {}
countries.features = countries.features.filter(function (d) {return d.id !== "ATA"})
countries.features.forEach(function (d) {
sideHash[d.id] = parseInt(Math.random() * numSides)
})
sources = countries.features.filter(function (p) {return powers.indexOf(p.id) !== -1})
d3.select("g.bg")
.selectAll("path")
.data(countries.features)
.enter()
.append("path")
.attr("d", geoPath)
.attr("class", "countries")
.each(function (d, i) {
d.centroid = geoPath.centroid(d)
var originalNode = this;
d.geometry.coordinates.forEach(function (p) {
if (p.length < 2) {
p = p[0];
}
var projectedArea = [];
p.forEach(function (coordinate) {
var proj = projection(coordinate);
projectedArea.push({x: proj[0], y: proj[1]});
})
sketchy.pathStroke({svg: d3.select("g.border"), path:projectedArea, density:3, sketch:2, stroke: colorScale(sideHash[d.id]), strokeWidth: "2px"});
})
})
d3.select("g.fill").selectAll("path")
.attr("stroke-dasharray", function () {return "0," + this.getTotalLength()})
.transition()
.delay(function (d,i) {return i * 10})
.transition()
.duration(500)
.attrTween("stroke-dasharray", tweenDash);
d3.select("g.border").selectAll("path")
.style("fill", "none")
.attr("stroke-dasharray", function () {return "0," + this.getTotalLength()})
.transition()
.delay(function (d,i) {return i * 10})
.transition()
.duration(500)
.attrTween("stroke-dasharray", tweenDash);
nuke()
}
function nuke() {
d3.select("svg")
.selectAll("path.nukelines")
.data(d3.range(100))
.enter()
.append("path")
.attr("class", "nukelines")
.each(function (d,i) {
var p1 = parseInt(Math.random() * sources.length)
var targets = countries.features.filter(function (p) {return sideHash[p.id] !== sideHash[sources[p1].id]})
var p2 = parseInt(Math.random() * targets.length)
var x1 = sources[p1].centroid[0] + (Math.random() * 30) - 15
var y1 = sources[p1].centroid[1]
var x2 = targets[p2].centroid[0] + (Math.random() * 50) - 25
var y2 = targets[p2].centroid[1] + (Math.random() * 50) - 25
var delay = i < 10 ? 2000 + i * 150 : 3500 + i * 10
d3.select(this)
.attr("d", "M" + x1 + "," + y1 + " S" + ((x1 + x2)/2) + "," + ((y1 + y2)/2 - 200) + " " + x2 + "," + y2)
.style("fill", "none")
.style("stroke", d3.rgb(colorScale(sideHash[sources[p1].id])).brighter(.25))
.style("stroke-width", 1)
.style("stroke-dasharray", "0 " + this.getTotalLength())
.transition()
.delay(delay)
.transition()
.duration(1000)
.style("stroke-dasharray", this.getTotalLength() + " 0")
createExplosion(x2, y2, delay + 500, d3.rgb(colorScale(sideHash[sources[p1].id])).brighter(.5))
})
setTimeout(function(){ d3.selectAll("g.blast").remove(); d3.selectAll("path.nukelines").remove(); nuke() }, 8000);
}
function tweenDash() {
var l = this.getTotalLength(),
i = d3.interpolateString("0," + l, l + "," + l);
return function(t) { return i(t); };
}
function cheapSketchy(path) {
var length = path.getTotalLength();
var drawCode = "";
var x = 0;
var step = 2.5;
while (x < length / 2) {
var start = path.getPointAtLength(x);
var end = path.getPointAtLength(length - x);
drawCode += " M" + (start.x + (Math.random() * step - step/2)) + " " + (start.y + (Math.random() * step - step/2)) + "L" + (end.x + (Math.random() * step - step/2)) + " " + (end.y + (Math.random() * step - step/2));
x += step + (Math.random() * step);
}
return drawCode;
}
function createExplosion(x, y, delay, color) {
var explosionG = d3.select("g.explosions")
.append("g")
.attr("class", "blast")
.attr("transform", "translate(" + x + "," + y + ")" )
.style("filter", "url(#gooeyCodeFilter)")
explosionG
.append("path")
.style("fill", "none")
.style("stroke", "none")
.attr("d", circlePath(20))
explosionG
.each(function (d,i) {
var artCircles = cheapPopArtsy(d3.select(this).select("path").node())
d3.select(this)
.selectAll("circle")
.data(artCircles)
.enter()
.append("circle")
.attr("r", 0)
.style("fill", color)
})
var artBarTransition = explosionG
.transition()
.delay(delay)
artBarTransition
.selectAll("circle")
.transition()
.delay(function (d) {return Math.abs(d[0] + d[1])})
.transition()
.duration(100)
.attr("r", function () {return Math.random() * 5})
.attr("cx", function (d) {return d[0]})
.attr("cy", function (d) {return d[1]})
}
</script>
</footer>
</html>
Display the source blob
Display the rendered blob
Raw
{"type":"Topology","objects":{"world":{"type":"GeometryCollection","geometries":[{"type":"Polygon","id":"AFG","arcs":[[0,1,2,3,4,5]]},{"type":"MultiPolygon","id":"AGO","arcs":[[[6,7,8,9]],[[10,11,12]]]},{"type":"Polygon","id":"ALB","arcs":[[13,14,15,16,17]]},{"type":"Polygon","id":"ARE","arcs":[[18,19,20,21,22]]},{"type":"MultiPolygon","id":"ARG","arcs":[[[23,24]],[[25,26,27,28,29,30]]]},{"type":"Polygon","id":"ARM","arcs":[[31,32,33,34,35]]},{"type":"MultiPolygon","id":"ATA","arcs":[[[36]]]},{"type":"MultiPolygon","id":"AUS","arcs":[[[37]]]},{"type":"Polygon","id":"AUT","arcs":[[38,39,40,41,42,43,44]]},{"type":"MultiPolygon","id":"AZE","arcs":[[[45,-35]],[[46,47,-33,48,49]]]},{"type":"Polygon","id":"BDI","arcs":[[50,51,52,53]]},{"type":"Polygon","id":"BEL","arcs":[[54,55,56,57,58]]},{"type":"Polygon","id":"BEN","arcs":[[59,60,61,62,63]]},{"type":"Polygon","id":"BFA","arcs":[[64,65,66,-62,67,68]]},{"type":"Polygon","id":"BGD","arcs":[[69,70,71]]},{"type":"Polygon","id":"BGR","arcs":[[72,73,74,75,76,77]]},{"type":"Polygon","id":"BIH","arcs":[[78,79,80]]},{"type":"Polygon","id":"BLR","arcs":[[81,82,83,84,85]]},{"type":"Polygon","id":"BLZ","arcs":[[86,87,88]]},{"type":"Polygon","id":"BOL","arcs":[[89,90,91,92,-31]]},{"type":"Polygon","id":"BRA","arcs":[[-27,93,-92,94,95,96,97,98,99,100,101]]},{"type":"Polygon","id":"BRN","arcs":[[102,103]]},{"type":"Polygon","id":"BTN","arcs":[[104,105]]},{"type":"Polygon","id":"BWA","arcs":[[106,107,108,109]]},{"type":"Polygon","id":"CAF","arcs":[[110,111,112,113,114,115,116]]},{"type":"MultiPolygon","id":"CAN","arcs":[[[117,118,119,120,121,122]],[[123]]]},{"type":"Polygon","id":"CHE","arcs":[[-42,124,125,126]]},{"type":"MultiPolygon","id":"CHL","arcs":[[[-24,127]],[[-30,128,129,-90]]]},{"type":"MultiPolygon","id":"CHN","arcs":[[[130,131,132,133,134,135,136,137,-106,138,139,140,141,-4,142,143,144,145,146,147,148,149]]]},{"type":"Polygon","id":"CIV","arcs":[[150,151,152,153,-65,154]]},{"type":"Polygon","id":"CMR","arcs":[[155,156,157,158,159,160,-117,161]]},{"type":"Polygon","id":"COD","arcs":[[162,163,-51,164,165,166,-10,167,-13,168,-115,169]]},{"type":"Polygon","id":"COG","arcs":[[-12,170,171,-162,-116,-169]]},{"type":"Polygon","id":"COL","arcs":[[172,173,174,175,176,-96,177]]},{"type":"Polygon","id":"CRI","arcs":[[178,179,180,181]]},{"type":"Polygon","id":"-99","arcs":[[182,183]]},{"type":"Polygon","id":"CYP","arcs":[[184,-184]]},{"type":"Polygon","id":"CZE","arcs":[[-44,185,186,187]]},{"type":"Polygon","id":"DEU","arcs":[[188,189,-186,-43,-127,190,191,-56,192,193,194]]},{"type":"Polygon","id":"DJI","arcs":[[195,196,197,198]]},{"type":"MultiPolygon","id":"DNK","arcs":[[[-195,199]]]},{"type":"Polygon","id":"DOM","arcs":[[200,201]]},{"type":"Polygon","id":"DZA","arcs":[[202,203,204,205,206,207,208,209]]},{"type":"Polygon","id":"ECU","arcs":[[210,-173,211]]},{"type":"Polygon","id":"EGY","arcs":[[212,213,214,215,216]]},{"type":"Polygon","id":"ERI","arcs":[[217,218,219,220,221,-199]]},{"type":"Polygon","id":"ESP","arcs":[[222,223,224,225]]},{"type":"Polygon","id":"EST","arcs":[[226,227,228,229,230]]},{"type":"Polygon","id":"ETH","arcs":[[231,-218,-198,232,233,234,235,236,237,-220]]},{"type":"Polygon","id":"FIN","arcs":[[238,239,240,241]]},{"type":"MultiPolygon","id":"FRA","arcs":[[[242,-191,-126,243,244,-224,245,-58]]]},{"type":"Polygon","id":"GAB","arcs":[[246,247,-156,-172]]},{"type":"MultiPolygon","id":"GBR","arcs":[[[248,249]],[[250]]]},{"type":"Polygon","id":"GEO","arcs":[[251,252,-49,-32,253]]},{"type":"Polygon","id":"GHA","arcs":[[254,-155,-69,255]]},{"type":"Polygon","id":"GIN","arcs":[[256,257,258,259,260,261,-153]]},{"type":"Polygon","id":"GMB","arcs":[[262,263]]},{"type":"Polygon","id":"GNB","arcs":[[264,265,-260]]},{"type":"Polygon","id":"GNQ","arcs":[[266,-157,-248]]},{"type":"MultiPolygon","id":"GRC","arcs":[[[267,-15,268,-76,269]]]},{"type":"Polygon","id":"GRL","arcs":[[270]]},{"type":"Polygon","id":"GTM","arcs":[[271,272,-89,273,274,275]]},{"type":"Polygon","id":"GUF","arcs":[[276,277,278,-100]]},{"type":"Polygon","id":"GUY","arcs":[[279,280,-98,281]]},{"type":"Polygon","id":"HND","arcs":[[282,283,-275,284,285]]},{"type":"Polygon","id":"HRV","arcs":[[286,-81,287,288,289,290]]},{"type":"Polygon","id":"HTI","arcs":[[-202,291]]},{"type":"Polygon","id":"HUN","arcs":[[-39,292,293,294,295,-291,296]]},{"type":"MultiPolygon","id":"IDN","arcs":[[[297,298]],[[299,300]],[[301,302]],[[303]]]},{"type":"Polygon","id":"IND","arcs":[[-141,304,-139,-105,-138,305,-72,306,307]]},{"type":"Polygon","id":"IRL","arcs":[[308,-249]]},{"type":"Polygon","id":"IRN","arcs":[[309,-6,310,311,312,313,-46,-34,-48,314]]},{"type":"Polygon","id":"IRQ","arcs":[[315,316,317,318,319,320,-313]]},{"type":"Polygon","id":"ISR","arcs":[[321,322,323,-217,324,325,326]]},{"type":"MultiPolygon","id":"ITA","arcs":[[[327,328,-244,-125,-41]]]},{"type":"Polygon","id":"JOR","arcs":[[-322,329,-319,330,331,-324,332]]},{"type":"Polygon","id":"KAZ","arcs":[[333,334,335,336,-145,337]]},{"type":"Polygon","id":"KEN","arcs":[[338,339,340,341,-235,342]]},{"type":"Polygon","id":"KGZ","arcs":[[-338,-144,343,344]]},{"type":"Polygon","id":"KHM","arcs":[[345,346,347,348]]},{"type":"Polygon","id":"KOR","arcs":[[349,350]]},{"type":"Polygon","id":"CS-KM","arcs":[[-18,351,352,353]]},{"type":"Polygon","id":"KWT","arcs":[[354,355,-317]]},{"type":"Polygon","id":"LAO","arcs":[[356,357,-136,358,-347]]},{"type":"Polygon","id":"LBN","arcs":[[-326,359,360]]},{"type":"Polygon","id":"LBR","arcs":[[361,362,-257,-152]]},{"type":"Polygon","id":"LBY","arcs":[[363,-210,364,365,-215,366,367]]},{"type":"Polygon","id":"LSO","arcs":[[368]]},{"type":"Polygon","id":"LTU","arcs":[[369,370,371,-82,372]]},{"type":"Polygon","id":"LUX","arcs":[[-192,-243,-57]]},{"type":"Polygon","id":"LVA","arcs":[[373,-231,374,-83,-372]]},{"type":"Polygon","id":"MAR","arcs":[[-207,375,376,377]]},{"type":"Polygon","id":"MDA","arcs":[[378,379]]},{"type":"Polygon","id":"MDG","arcs":[[380]]},{"type":"Polygon","id":"MEX","arcs":[[381,-87,-273,382,383]]},{"type":"Polygon","id":"MKD","arcs":[[-354,384,-77,-269,-14]]},{"type":"Polygon","id":"MLI","arcs":[[385,-204,386,-66,-154,-262,387]]},{"type":"Polygon","id":"MMR","arcs":[[388,-70,-306,-137,-358,389]]},{"type":"Polygon","id":"MNE","arcs":[[390,-288,-80,391,-352,-17]]},{"type":"Polygon","id":"MNG","arcs":[[392,-147]]},{"type":"Polygon","id":"MOZ","arcs":[[393,394,395,396,397,398,399,400,401,402]]},{"type":"Polygon","id":"MRT","arcs":[[403,404,405,-205,-386]]},{"type":"Polygon","id":"MWI","arcs":[[-403,406,407]]},{"type":"MultiPolygon","id":"MYS","arcs":[[[408,409]],[[-302,410,-104,411]]]},{"type":"Polygon","id":"NAM","arcs":[[412,-8,413,-108,414]]},{"type":"Polygon","id":"NER","arcs":[[-67,-387,-203,-364,415,-160,416,-63]]},{"type":"Polygon","id":"NGA","arcs":[[417,-64,-417,-159]]},{"type":"Polygon","id":"NIC","arcs":[[418,-286,419,-180]]},{"type":"Polygon","id":"NLD","arcs":[[-193,-55,420]]},{"type":"MultiPolygon","id":"NOR","arcs":[[[421,-242,422,423]]]},{"type":"Polygon","id":"NPL","arcs":[[-305,-140]]},{"type":"MultiPolygon","id":"OMN","arcs":[[[424,425,-22,426]],[[-20,427]]]},{"type":"Polygon","id":"PAK","arcs":[[-142,-308,428,-311,-5]]},{"type":"Polygon","id":"PAN","arcs":[[429,-182,430,-175]]},{"type":"Polygon","id":"PER","arcs":[[-130,431,-212,-178,-95,-91]]},{"type":"MultiPolygon","id":"PNG","arcs":[[[-300,432]]]},{"type":"Polygon","id":"POL","arcs":[[-190,433,434,-373,-86,435,436,-187]]},{"type":"Polygon","id":"PRK","arcs":[[437,438,-351,439,-133]]},{"type":"Polygon","id":"PRT","arcs":[[-226,440]]},{"type":"Polygon","id":"PRY","arcs":[[-93,-94,-26]]},{"type":"Polygon","id":"QAT","arcs":[[441,442]]},{"type":"Polygon","id":"ROU","arcs":[[443,-380,444,445,-73,446,-295]]},{"type":"MultiPolygon","id":"RUS","arcs":[[[-435,447,-370]],[[-438,-132,448,-150,449,-148,-393,-146,-337,450,-50,-253,451,452,453,454,455,-84,-375,-230,456,-228,457,-239,-422,458]]]},{"type":"Polygon","id":"RWA","arcs":[[459,-52,-164,460]]},{"type":"Polygon","id":"ESH","arcs":[[461,-206,-406,462,-377]]},{"type":"Polygon","id":"SAU","arcs":[[463,-331,-318,-356,464,-443,465,-23,-426,466]]},{"type":"Polygon","id":"SDN","arcs":[[467,468,-112,469,-367,-214,470,-221,-238,471]]},{"type":"Polygon","id":"SDS","arcs":[[472,-236,-342,473,-170,-114,474,-468]]},{"type":"Polygon","id":"SEN","arcs":[[475,-404,-388,-261,-266,476,-264]]},{"type":"Polygon","id":"SLE","arcs":[[477,-258,-363]]},{"type":"Polygon","id":"SLV","arcs":[[478,-276,-284]]},{"type":"Polygon","id":"-99","arcs":[[-233,-197,479,480]]},{"type":"Polygon","id":"SOM","arcs":[[-343,-234,-481,481]]},{"type":"Polygon","id":"SRB","arcs":[[-78,-385,-353,-392,-79,-287,-296,-447]]},{"type":"Polygon","id":"SUR","arcs":[[482,-278,483,-99,-281]]},{"type":"Polygon","id":"SVK","arcs":[[-437,484,-293,-45,-188]]},{"type":"Polygon","id":"SVN","arcs":[[-40,-297,-290,485,-328]]},{"type":"Polygon","id":"SWE","arcs":[[-423,-241,486]]},{"type":"Polygon","id":"SWZ","arcs":[[487,-399]]},{"type":"Polygon","id":"SYR","arcs":[[-330,-327,-361,488,489,-320]]},{"type":"Polygon","id":"TCD","arcs":[[-416,-368,-470,-111,-161]]},{"type":"Polygon","id":"TGO","arcs":[[490,-256,-68,-61]]},{"type":"Polygon","id":"THA","arcs":[[491,-410,492,-390,-357,-346]]},{"type":"Polygon","id":"TJK","arcs":[[-344,-143,-3,493]]},{"type":"Polygon","id":"TKM","arcs":[[-310,494,-335,495,-1]]},{"type":"Polygon","id":"TLS","arcs":[[496,-298]]},{"type":"Polygon","id":"TUN","arcs":[[-209,497,-365]]},{"type":"MultiPolygon","id":"TUR","arcs":[[[-254,-36,-314,-321,-490,498]],[[-270,-75,499]]]},{"type":"Polygon","id":"TZA","arcs":[[-340,500,-396,501,-394,-408,502,503,-165,-54,504,-460,505]]},{"type":"Polygon","id":"UGA","arcs":[[-461,-163,-474,-341,-506]]},{"type":"Polygon","id":"UKR","arcs":[[506,-455,507,-453,508,-445,-379,-444,-294,-485,-436,-85]]},{"type":"Polygon","id":"URY","arcs":[[-102,509,-28]]},{"type":"MultiPolygon","id":"USA","arcs":[[[510,-384,511,-118]],[[-122,512,-120,513]]]},{"type":"Polygon","id":"UZB","arcs":[[-496,-334,-345,-494,-2]]},{"type":"Polygon","id":"VEN","arcs":[[514,-282,-97,-177]]},{"type":"Polygon","id":"VNM","arcs":[[515,-348,-359,-135]]},{"type":"Polygon","id":"PSE","arcs":[[-333,-323]]},{"type":"Polygon","id":"YEM","arcs":[[516,-467,-425]]},{"type":"Polygon","id":"ZAF","arcs":[[-415,-107,517,-400,-488,-398,518],[-369]]},{"type":"Polygon","id":"ZMB","arcs":[[-407,-402,519,-109,-414,-7,-167,-503]]},{"type":"Polygon","id":"ZWE","arcs":[[-518,-110,-520,-401]]}]}},"arcs":[[[6700,7164],[147,101]],[[6847,7265],[36,-13]],[[6883,7252],[199,16]],[[7082,7268],[5,-17]],[[7087,7251],[-245,-428],[-152,-3]],[[6690,6820],[10,344]],[[5664,4412],[-20,-390]],[[5644,4022],[-319,12]],[[5325,4034],[17,663]],[[5342,4697],[322,-285]],[[5338,4715],[-8,45]],[[5330,4760],[30,15]],[[5360,4775],[-22,-60]],[[5571,7530],[12,-60]],[[5583,7470],[-24,-72]],[[5559,7398],[-21,134]],[[5538,7532],[19,42]],[[5557,7574],[14,-44]],[[6432,6490],[125,107]],[[6557,6597],[5,-20]],[[6562,6577],[4,-47]],[[6566,6530],[-33,-131]],[[6533,6399],[-101,91]],[[3140,1814],[-47,134]],[[3093,1948],[47,-134]],[[3258,3743],[224,-206]],[[3482,3537],[-83,-265]],[[3399,3272],[-22,-218]],[[3377,3054],[-255,-732],[-27,-354]],[[3095,1968],[-132,113],[173,1633]],[[3136,3714],[122,29]],[[6210,7485],[39,9]],[[6249,7494],[42,-146]],[[6291,7348],[-10,-2]],[[6281,7346],[-37,58]],[[6244,7404],[-34,81]],[[3371,1268],[11,-1128],[1332,706],[550,74],[1301,240],[322,-347],[412,273],[855,79],[887,-62],[714,-281],[-317,-547],[-8565,-275],[-189,387],[560,281],[876,100],[965,-24],[286,524]],[[8987,4244],[258,-679],[-182,-814],[-416,446],[-369,-211],[-129,631],[341,600],[186,183],[236,-369],[75,213]],[[5471,7900],[-21,-76]],[[5450,7824],[-67,-19]],[[5383,7805],[-93,22]],[[5290,7827],[-24,38]],[[5266,7865],[111,80]],[[5377,7945],[94,-18]],[[5471,7927],[0,-27]],[[6281,7346],[-37,58]],[[6349,7527],[8,-206]],[[6357,7321],[-66,27]],[[6249,7494],[39,37]],[[6288,7531],[61,-4]],[[5814,4792],[-8,98]],[[5806,4890],[40,25]],[[5846,4915],[7,-37]],[[5853,4878],[-39,-86]],[[5092,8091],[79,-32]],[[5171,8059],[-4,-40]],[[5167,8019],[-10,-35]],[[5157,7984],[-88,95]],[[5069,8079],[23,12]],[[5074,5427],[-23,-7]],[[5051,5420],[-27,287]],[[5024,5707],[35,56]],[[5059,5763],[41,-17]],[[5100,5746],[-26,-319]],[[4921,5627],[-72,43]],[[4849,5670],[161,269]],[[5010,5939],[49,-176]],[[5024,5707],[-24,1]],[[5000,5708],[-79,-81]],[[7573,6360],[-8,-81]],[[7565,6279],[-94,81]],[[7471,6360],[102,0]],[[5629,7671],[164,-31]],[[5793,7640],[-16,-101]],[[5777,7539],[-52,-10]],[[5725,7529],[-88,-29]],[[5637,7500],[-16,58]],[[5621,7558],[8,113]],[[5527,7708],[6,-79]],[[5533,7629],[-18,-52]],[[5515,7577],[12,131]],[[5652,8242],[83,101]],[[5735,8343],[47,33]],[[5782,8376],[100,-240]],[[5882,8136],[-229,-31]],[[5653,8105],[-1,137]],[[2524,6110],[23,40]],[[2547,6150],[-18,-154]],[[2529,5996],[-5,114]],[[3136,3714],[-69,305]],[[3067,4019],[1,392]],[[3068,4411],[251,-167],[65,-378]],[[3384,3866],[-126,-123]],[[3482,3537],[-98,329]],[[3068,4411],[-10,393]],[[3058,4804],[84,328]],[[3142,5132],[171,233]],[[3313,5365],[116,-195]],[[3429,5170],[56,24]],[[3485,5194],[80,109]],[[3565,5303],[26,-232],[430,-336],[-189,-1034],[-124,-67],[-191,-571]],[[3517,3063],[-118,209]],[[8172,5325],[34,54]],[[8206,5379],[-34,-54]],[[7546,6698],[-80,-28]],[[7466,6670],[80,28]],[[5817,3752],[-265,-158]],[[5552,3594],[144,420]],[[5696,4014],[5,-4]],[[5701,4010],[116,-258]],[[5424,5496],[211,220]],[[5635,5716],[26,-147]],[[5661,5569],[21,-25]],[[5682,5544],[78,-177]],[[5760,5367],[-248,-102]],[[5512,5265],[-68,-74]],[[5444,5191],[-20,305]],[[3135,7724],[-425,-204],[-165,390],[-957,42]],[[1588,7952],[-200,372]],[[1388,8324],[-250,278]],[[1138,8602],[-55,18]],[[1083,8620],[1,556]],[[1084,9176],[752,-78],[903,-76],[-369,-482],[504,-143],[-44,342],[376,-117],[247,-484],[-318,-414]],[[2595,9379],[687,-371],[-120,-292],[-626,501],[59,162]],[[5290,7827],[-100,-52]],[[5190,7775],[17,96]],[[5207,7871],[59,-6]],[[3140,1814],[-47,134]],[[3095,1968],[-197,334],[147,1672]],[[3045,3974],[22,45]],[[8663,7734],[-17,-71]],[[8646,7663],[-18,-102]],[[8628,7561],[-177,-145]],[[8451,7416],[-187,-70],[127,-526],[-173,-417],[-217,-72]],[[8001,6331],[-164,54]],[[7837,6385],[-27,-61]],[[7810,6324],[-107,403]],[[7703,6727],[-157,-29]],[[7466,6670],[-19,34]],[[7447,6704],[-195,137]],[[7252,6841],[-92,313]],[[7160,7154],[-73,97]],[[7082,7268],[-36,119]],[[7046,7387],[182,172]],[[7228,7559],[198,406]],[[7426,7965],[11,4]],[[7437,7969],[239,-387],[239,-67],[325,490]],[[8240,8005],[73,15]],[[8313,8020],[25,87]],[[8338,8107],[325,-373]],[[4920,5353],[-135,-38]],[[4785,5315],[-20,197]],[[4765,5512],[11,148]],[[4776,5660],[73,10]],[[4921,5627],[-1,-274]],[[5363,5191],[-50,0]],[[5313,5191],[-45,1]],[[5268,5192],[-32,147]],[[5236,5339],[157,456]],[[5393,5795],[9,22]],[[5402,5817],[22,-321]],[[5444,5191],[-81,0]],[[5856,5265],[-35,-287]],[[5821,4978],[-15,-88]],[[5814,4792],[8,-120]],[[5822,4672],[31,-107]],[[5853,4565],[-189,-153]],[[5342,4697],[-4,18]],[[5360,4775],[152,490]],[[5760,5367],[96,-102]],[[5330,4760],[-22,62]],[[5308,4822],[55,369]],[[2906,5049],[-97,90]],[[2809,5139],[27,345]],[[2836,5484],[15,86]],[[2851,5570],[167,183]],[[3018,5753],[124,-621]],[[3058,4804],[-152,245]],[[2695,5543],[-76,170]],[[2619,5713],[57,-9]],[[2676,5704],[31,-81]],[[2707,5623],[-12,-80]],[[5909,7133],[34,-4]],[[5943,7129],[-34,4]],[[5943,7129],[-34,4]],[[5377,7945],[40,131]],[[5417,8076],[106,-94]],[[5523,7982],[-52,-55]],[[5275,8306],[117,-73]],[[5392,8233],[25,-157]],[[5207,7871],[-36,108]],[[5171,7979],[-4,40]],[[5171,8059],[20,158]],[[5191,8217],[45,88]],[[5236,8305],[39,1]],[[6196,5808],[2,-73]],[[6198,5735],[-10,-32]],[[6188,5703],[-12,95]],[[6176,5798],[20,10]],[[5236,8305],[39,1]],[[3008,6222],[0,-98]],[[3008,6124],[0,98]],[[5333,6444],[-215,-255]],[[5118,6189],[-255,344]],[[4863,6533],[-105,143]],[[4758,6676],[1,15]],[[4759,6691],[180,444]],[[4939,7135],[294,105]],[[5233,7240],[30,-392]],[[5263,6848],[70,-404]],[[2769,4856],[40,283]],[[2906,5049],[-137,-193]],[[5969,6800],[54,-443]],[[6023,6357],[-329,0]],[[5694,6357],[4,566]],[[5698,6923],[253,-21]],[[5951,6902],[18,-102]],[[6176,5798],[-21,54]],[[6155,5852],[-20,40]],[[6135,5892],[-124,18]],[[6011,5910],[55,211]],[[6066,6121],[130,-313]],[[4749,7532],[198,91]],[[4947,7623],[135,-56]],[[5082,7567],[-290,-318]],[[4792,7249],[-43,283]],[[5675,8472],[102,99]],[[5777,8571],[4,-10]],[[5781,8561],[-12,-89]],[[5769,8472],[-12,-19]],[[5757,8453],[-82,19]],[[6135,5892],[20,-40]],[[6188,5703],[139,-173]],[[6327,5530],[-165,-241]],[[6162,5289],[-182,94]],[[5980,5383],[-37,188]],[[5943,5571],[0,53]],[[5943,5624],[68,286]],[[5794,9138],[-15,-506]],[[5779,8632],[-116,325]],[[5663,8957],[-90,183]],[[5573,9140],[221,-2]],[[5157,7984],[14,-5]],[[5190,7775],[16,-136]],[[5206,7639],[-124,-72]],[[4947,7623],[122,456]],[[5308,4822],[-45,295]],[[5263,5117],[50,74]],[[4827,8240],[-38,75]],[[4789,8315],[38,-75]],[[4916,8521],[99,-464],[-176,-36],[77,500]],[[6154,7511],[-45,113]],[[6109,7624],[179,-93]],[[6210,7485],[-56,26]],[[5029,5408],[-109,-55]],[[5000,5708],[29,-300]],[[4765,5512],[-50,42]],[[4715,5554],[-83,29]],[[4632,5583],[-53,127]],[[4579,5710],[40,91]],[[4619,5801],[61,-8]],[[4680,5793],[96,-133]],[[4532,5834],[3,27]],[[4535,5861],[-3,-27]],[[4579,5710],[-43,79]],[[4536,5789],[83,12]],[[5263,5117],[5,75]],[[5723,7469],[-164,-71]],[[5583,7470],[54,30]],[[5725,7529],[-2,-60]],[[3701,9939],[959,-79],[-281,-659],[-720,-548],[-691,1038],[733,248]],[[2497,5869],[-59,47]],[[2438,5916],[86,194]],[[2529,5996],[20,-9]],[[2549,5987],[-31,-77]],[[2518,5910],[-21,-41]],[[3485,5194],[4,112]],[[3489,5306],[12,92]],[[3501,5398],[64,-95]],[[3340,5552],[72,-142]],[[3412,5410],[17,-240]],[[3313,5365],[27,187]],[[2574,5825],[-13,23]],[[2561,5848],[-43,62]],[[2549,5987],[141,-44]],[[2690,5943],[-116,-118]],[[5523,7770],[4,-62]],[[5515,7577],[-3,-10]],[[5512,7567],[-132,179]],[[5380,7746],[80,59]],[[5460,7805],[63,-35]],[[3008,6124],[0,98]],[[5471,7900],[142,17]],[[5613,7917],[17,-31]],[[5630,7886],[-69,-104]],[[5561,7782],[-38,-12]],[[5460,7805],[-10,19]],[[8471,4532],[3,-29]],[[8474,4503],[-3,29]],[[8916,4904],[1,-385]],[[8917,4519],[-184,375],[183,10]],[[8045,5176],[229,126]],[[8274,5302],[-48,-482],[-181,356]],[[7939,4712],[-290,639],[235,-287],[55,-352]],[[7252,6841],[195,-137]],[[7703,6727],[-130,-367]],[[7471,6360],[-241,-363],[-77,-469],[-136,791],[-124,138]],[[6893,6457],[267,697]],[[4827,8240],[-38,75]],[[6497,7255],[203,-91]],[[6690,6820],[18,-281]],[[6708,6539],[-360,286]],[[6348,6825],[-105,428]],[[6243,7253],[1,151]],[[6357,7321],[140,-66]],[[6348,6825],[-16,3]],[[6332,6828],[-39,-51]],[[6293,6777],[-205,180]],[[6088,6957],[-11,72]],[[6077,7029],[99,228]],[[6176,7257],[67,-4]],[[5992,6990],[-5,-19]],[[5987,6971],[-4,-53]],[[5983,6918],[-14,-118]],[[5951,6902],[24,110]],[[5975,7012],[19,11]],[[5994,7023],[-2,-33]],[[5383,7805],[4,-54]],[[5387,7751],[-181,-112]],[[5992,6990],[85,39]],[[6088,6957],[-118,-165]],[[5970,6792],[-1,8]],[[5983,6918],[4,53]],[[6970,7554],[-417,162],[1,-218]],[[6554,7498],[-96,28]],[[6458,7526],[-95,273]],[[6363,7799],[-43,239],[804,220],[302,-293]],[[7228,7559],[-258,-5]],[[6155,4958],[-67,-177]],[[6088,4781],[-147,220]],[[5941,5001],[3,308]],[[5944,5309],[36,74]],[[6162,5289],[-7,-331]],[[7046,7387],[-74,48]],[[6972,7435],[-2,119]],[[7849,5777],[73,124]],[[7922,5901],[60,-4]],[[7982,5897],[-85,-220]],[[7897,5677],[-48,100]],[[8564,7339],[-60,-51]],[[8504,7288],[60,51]],[[5557,7574],[5,13]],[[5562,7587],[37,-34]],[[5599,7553],[-28,-23]],[[6332,6828],[12,-84]],[[6344,6744],[-51,33]],[[7922,5901],[-142,363]],[[7780,6264],[30,60]],[[7837,6385],[145,-488]],[[5975,7012],[24,92]],[[5999,7104],[-5,-81]],[[4785,5315],[-103,143]],[[4682,5458],[33,96]],[[5412,6408],[-79,36]],[[5263,6848],[56,167]],[[5319,7015],[379,-92]],[[5694,6357],[-32,-143]],[[5662,6214],[-250,194]],[[5804,3347],[0,0]],[[5631,8267],[-41,51]],[[5590,8318],[-6,50]],[[5584,8368],[151,-25]],[[5652,8242],[-21,25]],[[5584,8368],[91,104]],[[5757,8453],[25,-77]],[[4759,6691],[-4,0]],[[4755,6691],[-228,-368]],[[4527,6323],[308,847],[104,-35]],[[5739,7906],[45,-162]],[[5784,7744],[-45,162]],[[6376,4321],[-68,-737],[-74,516],[142,221]],[[2301,6586],[76,-457],[170,21]],[[2438,5916],[-313,222],[-379,842]],[[1746,6980],[294,-47],[261,-347]],[[5599,7553],[22,5]],[[4661,5921],[185,52],[17,560]],[[5118,6189],[-108,-250]],[[4680,5793],[-19,128]],[[7737,5644],[-172,635]],[[7780,6264],[-43,-620]],[[5538,7532],[-26,35]],[[5533,7629],[29,-42]],[[7437,7969],[803,36]],[[5959,4377],[62,-4]],[[6021,4373],[29,19]],[[6050,4392],[69,56]],[[6119,4448],[-208,-970]],[[5911,3478],[-21,0]],[[5890,3478],[-6,53]],[[5884,3531],[-18,212]],[[5866,3743],[-26,398]],[[5840,4141],[82,91]],[[5922,4232],[37,145]],[[4661,5921],[-119,90]],[[4542,6011],[-16,287]],[[4526,6298],[232,378]],[[5922,4232],[-13,280]],[[5909,4512],[50,-135]],[[7836,5425],[-57,14]],[[7779,5439],[57,-14]],[[8045,5176],[127,149]],[[8206,5379],[68,-77]],[[5453,3369],[-128,665]],[[5644,4022],[52,-8]],[[5552,3594],[-99,-225]],[[5412,6408],[-10,-591]],[[5393,5795],[-293,-49]],[[5236,5339],[-162,88]],[[2619,5713],[-45,112]],[[2690,5943],[-14,-239]],[[5092,8091],[99,126]],[[5863,9167],[-69,-29]],[[5573,9140],[-267,-605]],[[5306,8535],[-168,184],[725,448]],[[6475,6041],[-31,139]],[[6444,6180],[89,219]],[[6566,6530],[95,-154],[-186,-335]],[[6557,6597],[5,-20]],[[6893,6457],[-185,82]],[[2836,5484],[-141,59]],[[2707,5623],[144,-53]],[[3045,3974],[-157,218],[-119,664]],[[8916,4904],[229,-409],[-228,24]],[[5392,8233],[154,40]],[[5546,8273],[85,-6]],[[5653,8105],[-27,-148]],[[5626,7957],[-103,25]],[[8628,7561],[4,-9]],[[8632,7552],[-68,-213]],[[8504,7288],[-53,128]],[[4792,7249],[-43,283]],[[6411,6520],[16,-8]],[[6427,6512],[-16,8]],[[5630,7886],[109,20]],[[5784,7744],[38,-11]],[[5822,7733],[-29,-93]],[[5629,7671],[-68,111]],[[5546,8273],[44,45]],[[8646,7663],[17,71]],[[8338,8107],[-25,-87]],[[6363,7799],[-14,-272]],[[6109,7624],[-48,216]],[[6061,7840],[-79,205]],[[5982,8045],[-10,38]],[[5972,8083],[-72,64]],[[5900,8147],[-18,-11]],[[5769,8472],[12,89]],[[5777,8571],[2,61]],[[5863,9167],[424,-171],[925,334],[872,259],[487,-217],[899,-212],[-9189,-205],[9449,-360],[-781,-50],[-196,-254],[137,-371],[-258,-368]],[[5844,4990],[2,-75]],[[5821,4978],[23,12]],[[4755,6691],[4,0]],[[4526,6298],[1,25]],[[6188,6023],[-218,769]],[[6344,6744],[67,-224]],[[6427,6512],[5,-22]],[[6444,6180],[-256,-157]],[[5943,5617],[-280,-50]],[[5663,5567],[-2,2]],[[5635,5716],[27,498]],[[6023,6357],[43,-236]],[[5943,5624],[0,-7]],[[5943,5617],[0,-46]],[[5944,5309],[-88,-44]],[[5682,5544],[-19,23]],[[4535,5861],[7,150]],[[4536,5789],[-4,45]],[[4682,5458],[-50,125]],[[2561,5848],[-64,21]],[[6198,5735],[161,-3]],[[6359,5732],[-32,-202]],[[6359,5732],[45,-131],[-249,-643]],[[3412,5410],[89,-12]],[[3489,5306],[-4,-112]],[[5626,7957],[-13,-40]],[[5380,7746],[7,5]],[[5663,8957],[-357,-422]],[[5890,3478],[-6,53]],[[5999,7104],[5,70]],[[6004,7174],[172,83]],[[5051,5420],[-22,-12]],[[7849,5777],[-13,-352]],[[7779,5439],[-42,205]],[[6883,7252],[89,183]],[[6497,7255],[-39,271]],[[6554,7498],[293,-233]],[[8471,4532],[3,-29]],[[5233,7240],[86,-225]],[[6004,7174],[-192,319],[342,18]],[[5777,7539],[-54,-70]],[[6088,4781],[31,-333]],[[6050,4392],[-29,-19]],[[5909,4512],[-56,53]],[[5853,4565],[-31,107]],[[5853,4878],[-7,37]],[[5844,4990],[97,11]],[[5882,8136],[18,11]],[[5972,8083],[10,-38]],[[6061,7840],[-239,-107]],[[3517,3063],[-140,-9]],[[3135,7724],[-395,-809],[-371,-116],[-68,-213]],[[1746,6980],[-183,379],[25,593]],[[1083,8620],[55,-18]],[[1388,8324],[-475,330],[-315,-289],[-231,731],[717,80]],[[3018,5753],[322,-201]],[[8001,6331],[32,-584],[-136,-70]],[[6475,6041],[-268,-237],[-19,219]],[[5817,3752],[49,-9]],[[5911,3478],[-367,-477],[-91,368]],[[5840,4141],[-139,-131]]],"transform":{"scale":[0.036003600360036005,0.016927109510951093],"translate":[-180,-85.609038]}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment