Skip to content

Instantly share code, notes, and snippets.

@sifbuilder
Last active December 24, 2017 17:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sifbuilder/b97f86898fdc5753a1811c2eca559a99 to your computer and use it in GitHub Desktop.
Save sifbuilder/b97f86898fdc5753a1811c2eca559a99 to your computer and use it in GitHub Desktop.
anicube

#d3animas stt anicube

d3animas

  • space-time manifolds

Author

  • sifbuilder

based upon

with references including

License

  • MIT
/***********
* @bosonClone
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.bosonClone = global.bosonClone || {})))
}(this, function (exports) { "use strict"
let bosonClone = function bosonClone(__mapper = {}) {
let f = __mapper("props")()
/***********
* @clone : anigram
*/
let clone = function (v) {
if (v === null) return null //00 _____ o
else if (typeof(v) === "number") return v //02 _____ num
else if (typeof(v) === "string") return v //03 _____ str
else if (f.isArray(v) && v.length === 0) return v //04 _____ []
else if (typeof(v) === "function"
) return v // v(t) //01 _____ fn
else if (f.isObject(v) //06 ___ v :: {}
) {
let r = {}
for (let y of Reflect.ownKeys(v)) {
r[y] = clone(v[y]) // reenter
}
return r
}
else if (f.isArray(v) //09 ____ [[[ ], {}]] // last chance for the array
) {
let ws = v.map(d => clone(d))
return ws
}
else {
return v
}
}
/***********
* @enty
*/
let enty = v => clone(v)
return enty
}
exports.bosonClone = bosonClone
}));
/****************************
* @bosonGist
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.bosonGist = global.bosonGist || {})));
}(this, function (exports) { 'use strict';
let bosonGist = function bosonGist(__mapper = {}) {
let f = __mapper("props")()
let mwen = __mapper("xs").m("wen")
let cwen = __mapper("xs").c("wen")() //let wen = __mapper("controlWen") //
let bversor = __mapper("xs").b("versor")()
let cversor = __mapper("xs").c("versor")
/****************************
* @getproj
* get projection from proform
* apply projection properties
* if control:wen wen rotation
* if control:wen and 2d: wen z rotation
* if control:versor versor rotation
*/
let getproj = function (p = {}, prj) {
if (f.isString(p.projection)) { // if _projection singular name
prj = __mapper("xs").g(p.projection)(p) // props passed to projection
} else if (f.isFunction(p.projection)) { // if is projection
prj = p.projection // props passed to projection
} else if (f.isArray(p.projections)) { // if plural select one
prj = p.projections[ Math.round(p.projectidx || 0) ]
if (f.isString(prj)) { // if name in array
prj = __mapper("xs").g(prj)(p) // get projection from name
}
}
if (prj === undefined || prj === null) {
prj = d3.geoIdentity() // console.error("prj not defined") //
}
if (prj.rotate !== undefined) {
let rot = p.rotate || [0,0,0]
if (p.control === "wen") { // wen control
let wenRotation = cwen.rotation()
if (p.dims === 2) {
if (wenRotation[0] * wenRotation[1] !== 0) {
wenRotation = mwen.cross( [wenRotation[0], 0, 0], [0, wenRotation[1], 0])
}
}
rot = bversor.add(rot, wenRotation)
} else if (p.control === "versor") { // versor control
let verser = cversor.projection(prj)
let verRotation = verser.rotation() // rotation from versor
rot = bversor.add(rot, verRotation) // add ani rotation
}
prj.rotate(rot) // rotate
}
for (let [key, value] of Object.entries(p)) {
if (key !== "rotate" && prj[key] !== undefined && f.isFunction(prj[key])) prj[key](value)
}
return prj
}
/****************************
* @enty
*/
let enty = p => getproj(p)
return enty
}
exports.bosonGist = bosonGist
}));
/***********
* @bosonImage
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.bosonImage = global.bosonImage || {})))
}(this, function (exports) { "use strict"
let bosonImage = function (__mapper) {
let enty = function (src) {
let name = src || "space.jpg"
if (__mapper("renderSVG")) {
let imgs = __mapper("renderSVG").svg()
.select("svg").selectAll("image").data([0])
imgs.enter()
.insert("svg:image")
.attr("xlink:href", "./" + name)
.attr("x", "0")
.attr("y", "0")
.attr("width", "600")
.attr("height", "400")
.style("position", "absolute; top:0px; left:0px; z-index:1")
.attr("overflow", "visible") // _e_
} else {
// "no renderSVG"
}
}
return enty
}
exports.bosonImage = bosonImage
}));
/*******************************************
* @bosonInit
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.bosonInit = global.bosonInit || {})))
}(this, function (exports) { "use strict"
/*******************************************
* @bosonInit
*/
let bosonInit = function bosonInit(__mapper = {}) {
/*******************************************
* @enty
*/
let enty = function ( p={} ) {
if (p.canvas) __mapper({"renderCanvas": renderCanvas.renderCanvas(__mapper)})
if (p.svg) __mapper({"renderSVG": renderSVG.renderSVG(__mapper)}) // SVG
if (p.pos) __mapper("xs").c("pos")(__mapper("renderSVG").svg()) // SVG POSITION
if (p.img) __mapper("xs").b("image")("zimg-black.jpg") // BCK IMAGE
if (p.svg && p.wen) __mapper("xs").c("wen").control(__mapper("renderSVG").svg()) // SVG WEN
if (p.svg && p.versor) __mapper("xs").c("versor").control(__mapper("renderSVG").svg()) // SVG VERSOR
if (p.webgl) __mapper({"renderWebgl": renderWebgl.renderWebgl(__mapper)}) // WEBGL
__mapper({"muonAnimation": muonAnimation.muonAnimation(__mapper)}) // ANIMATION
__mapper({"muonStore": muonStore.muonStore(__mapper)}) // STORE
if (p.gui) {gui = new dat.GUI(); gui.add(window, "restart")} // GUI https://github.com/dataarts/dat.gui
if (p.key) {
__mapper("xs").c("key").start() // KEYBRD CONTROLS
let controltimerRightArrowAlt = () => { // ARROW
if (__mapper("muonAnimation").animationStop !== undefined)
{
console.log("started",__mapper("controlTimer").started())
if (__mapper("controlTimer").started()) {
__mapper("controlTimer").stop()
} else {
console.log("controlTimer resume")
__mapper("controlTimer").resume()
}
}
}
__mapper("controlKey").subscribe(controltimerRightArrowAlt, "rightArrowAlt")
}
let mouseDownListener = function mouseDownListener(event) {
__mapper("xs").m("mouse").mouseDown(1)
__mapper("xs").m("mouse").mouseDownShared(1)
__mapper("xs").m("mouse").event(event)
}
let mouseUpListener = function mouseUpListener(event) {
__mapper("xs").m("mouse").mouseDown(0)
__mapper("xs").m("mouse").mouseDownShared(0)
}
if (__mapper("renderSVG")) __mapper("xs").c("mouseDown").control(__mapper("renderSVG").svg()).subscribe(mouseDownListener, __mapper("renderSVG").svg())
if (__mapper("renderSVG")) __mapper("xs").c("mouseUp").control(__mapper("renderSVG").svg()).subscribe(mouseUpListener, __mapper("renderSVG").svg())
if (p.fps) { // FPS
const fpsdiv = d3.select("body").append("div").attr("id","fps")
__mapper("xs").m("fps").init()
}
if (p.stats) { // STATS
let stats = __mapper("xs").m("stats")() // new Stats();
stats.showPanel( -1 ) // 0: fps, 1: ms, 2: mb, 3+: custom
document.body.appendChild( stats.dom )
function animate() {
stats.begin() /* monitored code goes here */; stats.end()
requestAnimationFrame( animate )
}
requestAnimationFrame( animate )
}
}
return enty
}
exports.bosonInit = bosonInit
}));
/*******************************************
* @bosonMapper
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.bosonMapper = global.bosonMapper || {})))
}(this, function (exports) { "use strict"
let bosonMapper = function bosonMapper() {
let state = {}
let enty = function (_) {
if (arguments.length < 1) return state
if (typeof _ === "object") return state = Object.assign({}, state, _)
if ((typeof _ === "string") && (state[_] !== undefined)) return state[_]
}
return enty
}
exports.bosonMapper = bosonMapper
}));
/***************************
* @bosonPolyhedral
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.bosonPolyhedral = global.bosonPolyhedral || {})));
}(this, function (exports) { 'use strict';
var bosonPolyhedral = function bosonPolyhedral(__mapper = {}) {
let f = __mapper({'props': bosonProps.bosonProps()}).props() // props
let renderer = __mapper("renderRenderer"),
width = renderer.width(),
height = renderer.height()
let d3Geo = d3
let pi = Math.PI, degrees = 180 / pi, radians = pi / 180
/***************************
* @enty
*/
var enty = function ( proform={} ) {
let {faciaRotation, geoRotation, prjRaw, faces, tree} = proform
let faceProjection = function(face) {
let prj = d3Geo.geoProjection(prjRaw)
let c = d3Geo.geoCentroid({type: "MultiPoint", coordinates: face})
let rotate = geoRotation(c)
let translate = [0, 0, 0]
let scale = 1 // convention
return prj.scale(scale).translate(translate).rotate(rotate)
}
faces = faces.map(function(face) {
let polygon = face.slice()
face = face.slice(0,-1);
return {
face: face,
contains: function(lambda, phi) {
return d3Geo.geoContains({ type: "Polygon", coordinates: [ polygon ] },
[lambda * degrees, phi * degrees]);
},
project: faceProjection(face)
}
})
tree.forEach(function(d, i) { // tree
let node = faces[d]
node && (node.children || (node.children = [])).push(faces[i])
})
let facefn = function(lambda, phi) {
for (let i = 0; i < faces.length; i++) {
if (faces[i].contains(lambda, phi)) return faces[i];
}
}
let m = d3Geo.geoPolyhedral(
faces[0],
facefn,
faciaRotation, // rotation of the root face in the projected (pixel) space
true // clipPolygon http://blockbuilder.org/Fil/cb7930254c9e7062114678d62d9be5ac
)
return m
}
return enty
}
exports.bosonPolyhedral = bosonPolyhedral
}));
/***************************
* @bosonProj3ct
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.bosonProj3ct = global.bosonProj3ct || {})));
}(this, function (exports) { 'use strict';
// https://d3js.org/d3-geo-projection/ V
// Copyright 2017 Mike Bostock.
var bosonProj3ct = function (__mapper = {}) {
let f = __mapper("props")()
let noop = function() {}
let d3Geo = d3
var clockwise = function(ring) {
if ((n = ring.length) < 4) return false;
var i = 0,
n,
area = ring[n - 1][1] * ring[0][0] - ring[n - 1][0] * ring[0][1];
while (++i < n) area += ring[i - 1][1] * ring[i][0] - ring[i - 1][0] * ring[i][1];
return area <= 0;
};
var contains = function(ring, point) {
var x = point[0],
y = point[1],
contains = false;
for (var i = 0, n = ring.length, j = n - 1; i < n; j = i++) {
var pi = ring[i], xi = pi[0], yi = pi[1],
pj = ring[j], xj = pj[0], yj = pj[1];
if (((yi > y) ^ (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi)) contains = !contains;
}
return contains;
};
var project = function(object, projection) { // index
var stream = projection.stream, project;
if (!stream) throw new Error("invalid projection");
switch (object && object.type) {
case "Feature": project = projectFeature; break;
case "FeatureCollection": project = projectFeatureCollection; break;
default: project = projectGeometry; break;
}
return project(object, stream);
};
function projectFeatureCollection(o, stream) {
return {
type: "FeatureCollection",
features: o.features.map(function(f) {
return projectFeature(f, stream);
})
};
}
function projectFeature(o, stream) {
return {
type: "Feature",
id: o.id,
properties: o.properties,
geometry: projectGeometry(o.geometry, stream)
};
}
function projectGeometryCollection(o, stream) {
return {
type: "GeometryCollection",
geometries: o.geometries.map(function(o) {
return projectGeometry(o, stream);
})
};
}
function projectGeometry(o, stream) {
if (!o) return null;
if (o.type === "GeometryCollection") return projectGeometryCollection(o, stream);
var sink;
switch (o.type) {
case "Point": sink = sinkPoint; break;
case "MultiPoint": sink = sinkPoint; break;
case "LineString": sink = sinkLine; break;
case "MultiLineString": sink = sinkLine; break;
case "Polygon": sink = sinkPolygon; break;
case "MultiPolygon": sink = sinkPolygon; break;
case "Sphere": sink = sinkPolygon; break;
default: return null;
}
d3Geo.geoStream(o, stream(sink));
return sink.result();
}
var points = [];
var lines = [];
var sinkPoint = {
point: function(x, y, z) {
points.push([x, y, z]); // z
},
result: function() {
var result = !points.length ? null
: points.length < 2 ? {type: "Point", coordinates: points[0]}
: {type: "MultiPoint", coordinates: points};
points = [];
return result;
}
};
var sinkLine = {
lineStart: noop,
point: function(x, y, z) {
points.push([x, y, z]); // z
},
lineEnd: function() {
if (points.length) lines.push(points), points = [];
},
result: function() {
var result = !lines.length ? null
: lines.length < 2 ? {type: "LineString", coordinates: lines[0]}
: {type: "MultiLineString", coordinates: lines};
lines = [];
return result;
}
};
var sinkPolygon = {
polygonStart: noop,
lineStart: noop,
point: function(x, y, z) {
points.push([x, y, z]); // z
},
lineEnd: function() {
var n = points.length;
if (n) {
do points.push(points[0].slice()); while (++n < 4);
lines.push(points), points = [];
}
},
polygonEnd: noop,
result: function() {
if (!lines.length) return null;
var polygons = [],
holes = [];
// https://github.com/d3/d3/issues/1558
lines.forEach(function(ring) {
if (clockwise(ring)) polygons.push([ring]);
else holes.push(ring);
});
holes.forEach(function(hole) {
var point = hole[0];
polygons.some(function(polygon) {
if (contains(polygon[0], point)) {
polygon.push(hole);
return true;
}
}) || polygons.push([hole]);
});
lines = [];
return !polygons.length ? null
: polygons.length > 1 ? {type: "MultiPolygon", coordinates: polygons}
: {type: "Polygon", coordinates: polygons[0]};
}
}
/***************************
* @enty
*/
let enty = (object, projection) => project(object, projection)
return enty
}
exports.bosonProj3ct = bosonProj3ct
}));
/***************************
* @bosonProps
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.bosonProps = global.bosonProps || {})))
}(this, function (exports) { "use strict"
let bosonProps = function bosonProps() {
let props = {}
props.a = d => (Array.isArray(d)) ? [...d] : [d]
props.v = (d,...p) => (typeof(d) === "function") ? d(...p) : d
props.f = d => (typeof(d) === "function") ? d : () => d
// https://stackoverflow.com/questions/728360/how-do-i-correctly-clone-a-javascript-object
props.o = obj => {
if (null == obj || "object" != typeof obj) return obj
let copy = obj.constructor()
for (let attr in obj) {
if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr]
}
return copy
}
// http://heyjavascript.com/4-creative-ways-to-cloneObj-objects/
props.cloneObj = function cloneObj(obj) {
if (obj === null || typeof obj !== "object") {
return obj
}
let temp = obj.constructor() // give temp the original obj's constructor
for (let key in obj) {
temp[key] = cloneObj(obj[key])
}
return temp
}
props.cloneArray = function cloneArray(obj) {
if (Array.isArray(obj) ) {
let r = [ ...obj ]
} else {
r = obj
}
return r
}
props.debug = () => [].join.call(arguments, "\n")
props.diagonalp = function(d, v) { // error: d is undefined
// v < 0: linear link
// 0 < v < 1: curved link
// > 1: curvy link
let s = d.source
let t = d.target
let x0 = s.x // s.stace.stateA // s.x
let y0 = s.y // s.stace.stateB //s.y
let x1 = t.x // t.stace.stateA //t.x
let y1 = t.y // t.stace.stateB //t.y
if ((x0 === undefined) ||
(y0 === undefined) ||
(x1 === undefined) ||
(y1 === undefined)) {
console.log("error in diagonal")
return null
}
let polygon = []
if (v < 0) { // linar
polygon = [ [x0,y0],
[x1,y1]
]
} else if (v > 1) { // (1, ) curvy
let rd = 1 + d3.randomNormal(0, v-1)() // v
polygon = [ [x0,y0] ,
[x0 + rd * (x1 - x0), y0],
[x0 + rd * (x1 - x0), y1],
[x1,y1]
]
} else { // (0,1) curve
let rd = 1 + d3.randomNormal(0, v)() // v
let r = -1 // let r = Math.sign((0.5 - Math.random()))
let x0a = x0 + r * rd * (x1 - x0)
let y0a = y0 - r * rd * (y1 - y0)
polygon = [
[x0,y0] ,
[x0a, y0a],
[x1,y1]
]
}
return polygon
}
props.closerange = (a,b) => [...d3.range(a,b), a]
props.geoscale = extent => d3.scaleLinear().domain(extent[0]).range(extent[1])
// force array
props.fa = d => {
let ret
if (Array.isArray(d)) ret = d
else if (typeof d === "object") ret = Object.values(d)
else if (d === null) ret = []
else if (d === undefined) ret = []
else ret = d
return props.a(ret)
}
props.norma = function norma(pts = []) {
let m = Math.max(...pts)
let c = 1 / m
let r = pts.map(p => p * c)
return r
}
props.ta = d => (Array.isArray(d)) ? d.map( di => [[ di ]]) : [[ d ]]
props.unslide = function unslide (stream = []) {
let lengths = stream.map(d => d.length)
let mx = Math.max(...lengths)
let unslide = d3.range(mx).map(i => [])
for (let i=0; i<stream.length; i++) {
for (let j=0; j<mx; j++) {
unslide[j][i] = stream[i][j]
}
}
return unslide
}
props.parray = d => (Array.isArray(d)) ? d.slice() : [d]
props.geoscale = extent => d3.scaleLinear().domain(extent[0]).range(extent[1])
props.rarray = d => (Array.isArray(d)) ? [ ...d ].reverse() : [d] // reverse array
props.closerange = (a,b) => [...d3.range(a,b), a]
props.isNumericArray = d => Array.isArray(d) && d.reduce((prev, curr) => prev && typeof curr === "number", true)
// pure array: no object/funcion elements
props.isPureArray = d => Array.isArray(d) && d.reduce((prev, curr) => prev && typeof curr !== "object" && typeof curr !== "function", true)
// quasipure array: arrrays, string or number elements
props.isQuasiPureArray = d => Array.isArray(d) && d.reduce((prev, curr) => prev &&
Array.isArray(curr) ||
typeof(curr) === "string" ||
typeof(curr) === "number"
, true)
props.isDoubleSingleArray = d => (Array.isArray(d) // [[_]]
&& Array.isArray(d[0])
&& d.length === 1
&& d[0].length === 1
)
props.isDoubleArray = d => (Array.isArray(d) // [[_]]
&& Array.isArray(d[0])
&& d.length === 1
)
// tripleArray" animas animation, single polygon geojson MultiPolygon
props.isTripleArray = d => (Array.isArray(d) && Array.isArray(d[0]) && Array.isArray(d[0][0])
&& d.length === 1 && d[0].length === 1 && d[0][0].length === 1 ) // [[[_]]]
props.isPureObject = d => (!Array.isArray(d) &&
typeof d === "object" &&
Object.keys(d).reduce ((p,c) => p && (typeof d[c] !== "object"), true)
)
props.isObject = d => (typeof d === "object" && Array.isArray(d) === false)
props.isArray = d => Array.isArray(d)
props.isString = d => typeof(d) === "string"
props.isNumber = d => typeof(d) === "number"
props.isFunction = d => typeof(d) === "function"
props.functor = d => (typeof(d) === "function") ? d : d => d
props.constant = v => (typeof v === "function") ? v() : v
props.value = v => (typeof v === "function") ? v() : v
props.noop = () => {}
/* **************************
* @colors
*/
props.colors = {} // colors
props.colors.scales = {
bos: d3.scaleLinear().domain([0, 0.5, 1]).range(["black", "#FF2400", "Wheat"]), // 0
wheat: d3.scaleLinear().domain([0, 0.5, 1]).range(["black", "Wheat", "#FF2400"]), // 1
red: d3.scaleLinear().domain([0, 0.5, 1]).range(["#FF2400", "Yellow"]), // 2
ry: d3.scaleLinear().domain([0, 1]).range(["red", "yellow"]), // 3
bar: d3.scaleLinear().domain([0, 0.5, 1]).range(["black", "#FF2400", "Yellow"]), // 4
lab: d3.interpolateLab("#FF2400", "yellow"), // 5
hsl: d3.interpolateLab("brown", "steelblue"), // 6
rbl: d3.interpolateLab("red", "blue"), // 7
plasma: d3.interpolatePlasma, // 8
cool: d3.interpolateCool, // 9
warm: d3.interpolateWarm, // 10
magma: d3.interpolateMagma, // 11
inferno: d3.interpolateInferno, // 12
viridis: d3.interpolateViridis, // 13
cubehelex: d3.interpolateCubehelexDefault, // 14
rainbow: d3.interpolateRainbow, // 15
bluered: d3.scaleLinear().domain([0, 0.5, 1]).range(["blue", "Wheat", "red",]),
blueblack: d3.scaleLinear().domain([0, 0.5, 1]).range(["blue", "Wheat", "black",]) // "red",]) // 0
}
props.colors.color = props.colors.scales.bos
props.colors.array = Object.keys(props.colors.scales).map(key => props.colors.scales[key])
props.color = (d=0) => {
return props.colors.array[Math.round(d)]
}
props.kolor = (v, d=0) => {
return props.color(d)(v/1000)
}
props.polarize = function(point) { // cart to 2d planar
let x = point[0]
let y = point[1]
let ang = Math.atan2(y, x)
let rad = Math.sqrt(x * x + y * y)
return [ang,0,rad]
}
/* **************************
* @slide
*
* [ [a1,a2,a3], [b1,b2] ] [ [a1,b1], [a2,b2x], [a3,b2] ]
* [ {a1,a2,a3}, [b1,b2] ] [ [a1v,b1], [a2v,b2x], [a3v,b2] ]
* [ {a1,a2,a3}, {b1,b2} ] [ [a1v,b1], [a2v,b2x], [a3v,b2] ]
*/
props.slide = function slide (streams=[], compl="max") {
let nbr = streams.length
let inpattern = streams.reduce( (p,q) => p && props.isNumericArray(q), true)
/* if ( !inpattern ) console.log (" streams not in pattern", streams) */
let lengths = streams.map(d => d.length),
mx = Math.max(...lengths),
mn = Math.min(...lengths)
let streamXYZ = []
if (compl === "min") {
let pointsHowmany = mn // min length
for (let i=0; i<pointsHowmany; i++) {
streamXYZ[i] = streams.map(d => d[i])
}
let scales = streams.map(d => d3.scaleLinear().domain([0,pointsHowmany - 1]).range([0,d.length -1 ]))
} else {
let pointsHowmany = mx // max length
let scales = streams.map(d => d3.scaleLinear().domain([0,pointsHowmany - 1]).range([0,d.length -1 ]))
for (let j=0; j<pointsHowmany; j++) {
let w = streams.map((s,k) => streams[k][Math.round(scales[k](j))])
streamXYZ.push(w)
}
}
return streamXYZ
}
/***************************
* @streamRange
*/
props.streamRange = function streamRange(pts, pa=0, pb=-1, step=1, fas=0) {
// for (let k in params) params[k] = value(params[k])
// + clockwise, - counter-clockwise
// [-0,-1] := [359,0] // [0,360] _e_
// [-300,120] := -[300, 0], -[0,120]
let neg = x => x < 0 || (x === 0 && (1/x < 0))
let pos = x => x > 0 || (x === 0 && (1/x > 0))
let ptsLength = pts.length // group order assume positive
let intA = Math.round(pa)
let intB = Math.round(pb)
let posA = Math.abs(intA)
let posB = Math.abs(intB)
let posmodA = Math.floor(posA % ptsLength)
let posmodB = Math.floor(posB % ptsLength)
let modStep = Math.floor(step)
let ret = []
if (intA === intB) {
let p = intA % ptsLength // pt in group
ret.push(pts[p])
} else if (intB < 0) { // neg B is nb. of cycles
for(let i = 1; i<= posB; i++) ret = ret.concat(pts.slice(posA, ptsLength))
ret = ret.concat(pts.slice(posA, Math.floor(ptsLength * (posB % 1) ))) // fraction
if (neg(intA)) ret = props.immutableReverse(ret)
} else if (posA < posB) {
if (posmodA < posmodB) {
ret = ret.concat(pts.slice(posmodA, posmodB + 1)) // +1 position
.filter((d,i)=> (i % modStep === 0)) // step
} else {
ret = ret.concat(
pts.slice(posmodA, ptsLength),
pts.slice(0, posmodB))
}
if (neg(intA)) ret = props.immutableReverse(ret)
} else if (posA > posB) { // _e_
if (neg(intA)) {
ret = ret.concat(pts.slice(posA, ptsLength))
ret = ret.concat(pts.slice(0, posB))
ret = props.immutableReverse(ret)
} else {
let rpts = props.immutableReverse(pts)
ret = props.streamRange(rpts, pts.length - posA, pts.length - posB)
}
}
return ret
}
/***************************
* @fibonacciSphere
*/
props.cartesian = function (spherical) {
let radians = Math.PI / 180
let lambda = spherical[0] * radians,
phi = spherical[1] * radians,
cosphi = Math.cos(phi)
return [
Math.cos(lambda) * cosphi ,
Math.sin(lambda) * cosphi ,
Math.sin(phi)
]
}
props.spherical = function (cartesian) {
let radians = Math.PI / 180
let r = Math.sqrt(cartesian[0] * cartesian[0] + cartesian[1] * cartesian[1]),
lat = Math.atan2(cartesian[2], r),
lng = Math.atan2(cartesian[1], cartesian[0])
return [lng / radians, lat / radians]
}
props.mapline = function (Positions, Verts) {
return Verts
.map(function (v) {
return props.spherical(Positions[v])
})
}
props.fibonacciSphere = function fibonacciSphere(samples = 1, randomize = true) {
let rnd = 1.0
if (randomize) {
rnd = Math.random() * samples
}
const offset = 2.0 / samples
const increment = Math.PI * (3.0 - Math.sqrt(5.0))
let r = d3.range(samples)
.map((i) => {
const y = ((i * offset) - 1) + (offset / 2)
const r = Math.sqrt(1 - Math.pow(y, 2))
const phi = ((i + rnd) % samples) * increment
const x = Math.cos(phi) * r
const z = Math.sin(phi) * r
return ([x, y, z])
})
return r
}
/***************************
* @ent
*/
props.entx = function( ent, ents, entidx = 0) {
let ret
if (ent !== undefined) { // if ent singular
ret = ent // .map(d => Math.round(d))
} else if (ents !== undefined) { // if plural
if (typeof entidx === "number") ret = ents[Math.round(entidx)] // get one
else if (Array.isArray(entidx)) ret = entidx.map(d => ents[Math.round(d)]) // get some
}
return ret
}
props.entxx = function( ent, ents, entidx = 0, arr) {
let _ent = arr[ent]
let _ents = arr[ents]
let _entidx = arr[entidx]
return props.entx(_ent, _ents, _entidx )
}
/***************************
* @enty
*/
let enty = function enty() {
return props
}
return enty
}
exports.bosonProps = bosonProps
}));
/***********
* @bosonSnap
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.bosonSnap = global.bosonSnap || {})));
}(this, function (exports) { 'use strict';
var bosonSnap = function bosonSnap(__mapper = {}) {
let f = __mapper("props")()
/***********
* @interlace
*/
let interlace = function interlace (streams, t) {
let ww = []
let ses = [] // scale per position
let res = [] // scale per position
let nStreams = streams.length // number of streams
let nDots = streams.reduce((p,q) => Math.max(q.length,p),0) // max dots
for (let i=0; i<nStreams; i++) { // scales
let sid = [0,nDots-1]
let sir = [0,streams[i].length -1]
let si = d3.scaleLinear() // argument scale
.domain( sid ) // from result position
.range ( sir ) // to strem i position
ses[i] = si // ses scale for i stream
let rid = d3.range(streams[i].length).map((d,i) => i)
let rir = streams[i]
let ri = d3.scaleLinear() // argument scale
.domain( rid ) // from result position
.range ( rir ) // to strem i position
res[i] = ri // ses scale for i stream
}
for (let j=0;j<nDots;j++) { // each position j
let rr = []
let ss = []
for (let k=0;k<streams.length;k++) { // each stream
let vk = ses[k](j) // postion on stram
let sk = res[k](vk) // time stream
rr.push(vk) //[0, 0, 0], [0.5, 0.25, 1], [1, 0.5, 2] positions per stream
ss.push(sk) // [2, 33, 5], [2.5, 33.25, 6], [3, 33.5, 7] values j
}
let d = ss.map( (item, idx) => idx / (ss.length - 1))
let r = ss
let ws = d3.scaleLinear()
.domain(d)
.range(r)
ww[j] = ws(t)
}
return ww
}
/***********
* @snap : anigram, t, flag
*/
let snap = function snap (v, t=0, g=0) {
// ____________________________________________________ un-tagged
if (v === null) return null //00 _____ o
else if (typeof(v) === "number") return v //02 _____ num
else if (typeof(v) === "string") return v //03 _____ str
else if (f.isArray(v) && v.length === 0) return v //04 _____ []
else if (typeof(v) === "function"
&& g !== 1) return v //01 _____ fn v(t)
else if (f.isArray(v) //05 ____ [[ [ pure ] ]] intra array interpolation
&& f.isDoubleSingleArray(v) // double array with single elem
&& f.isPureArray(v[0][0]) // single elem in double array is pure
&& g !== 1
) {
let ws = snap(v[0][0],t,1)
return ws
}
else if (f.isObject(v) //06 ___ v :: {}
&& g !== 1) {
let r = {}
for (let y of Reflect.ownKeys(v)) {
r[y] = snap(v[y], t) // reenter
}
return r
}
else if (f.isDoubleArray(v) //07 [[ [ [], [] ] ]] inter arrays interpolation
&& f.isQuasiPureArray(v[0][0]) // double array with array of arrays elem
&& v[0][0].length === 1
&& g !== 1
) {
let na = []
for (let i=0; i<v[0][0].length; i++) {
let comp = v[0][0][i]
let intra = snap(comp, t, 1)
na.push(intra)
}
let ws = snap(na,t,1) // scales of internal array
return ws
}
else if (f.isArray(v) //08a ____ [[[ fn() ]]]
&& f.isTripleArray(v)
&& typeof v[0][0][0] === "function"
&& g !== 1
) {
let ws = snap( f.v(v[0][0][0]) ,t,0) // snap function value
return ws
}
else if (f.isArray(v) //08 ____ [ [[ [ ], {} ]] ]
&& f.isTripleArray(v)
&& g !== 1
) {
let ws = snap( v[0][0][0], t, 1) // scales of internal array
return ws
}
else if (f.isArray(v) //09 ____ [[[ ], {}]] // last chance for the array
&& g !== 1
) {
let ws = v.map(d => snap(d,t,0))
return ws
}
// ____________________________________________________ tagged
else if (typeof(v) === "function"
&& g === 1) {
let ret = v(t)
return ret //01 _____ fn
}
else if (f.isObject(v) //10 ___ v :: {b, c, d ...}*
&& g === 1) {
let tau = 2 * Math.PI
let radians = Math.PI / 180
if ( v.x === undefined && v.y === undefined && v.z === undefined ) {
let w = {} // nat on dims
w.x = Object.assign({}, v)
w.y = Object.assign({}, w.x, {fas8: v.fas8 - 90}) // set transversal fas8
w.z = Object.assign({}, v)
v = w
}
// console.log(" --------------- v", v)
let ws = {} // dim nat
for (let y of Reflect.ownKeys(v)) {
let d = v[y]
d = snap(d, t) // reenter
let s = __mapper("xs").m("nat").rador(d)
s = f.streamRange(s,d.pa6,d.pb7)
s = s.map( (p,i) => {
let refAng = (d.w4 + d.fas8) * radians
let angUnit = tau / s.length
let ang = ((i * angUnit * d.v1) - refAng + tau) % tau
return p * Math.cos(ang) * d.ra2
})
if (s.length === 1) {
let r = [s[0], s[0]],
d = [0, 1]
ws[y] = d3.scaleLinear().domain(d).range(r)(t)
} else {
let r = s,
d = d3.range(r.length).map((item, idx) => idx / (r.length - 1))
ws[y] = d3.scaleLinear().domain(d).range(r)(t)
}
}
// console.log(" --------------- ws", ws)
return ws
}
else if (f.isArray(v) //11_____ [v]*
&& f.isPureArray(v)
&& v.length === 1
&& g === 1) {
let d = [0, 1], r = [v[0], v[0]]
let w = d3.scaleLinear().domain(d).range(r)
return w(t)
}
else if (f.isArray(v) //12 _____ [v1,v2,v3]*
&& f.isPureArray(v)
&& v.length > 1
&& g === 1) {
let d = v.map( (item, idx) => idx / (v.length - 1))
let r = v
let w = d3.scaleLinear()
.domain(d)
.range(r)
return w(t)
}
else if (f.isArray(v) //13 _____ [[a1,a2,a3],[b1,b2]]*
&& f.isQuasiPureArray(v) // => [[a1,b1],[a2,b1'],[a3,b2]]
&& g === 1) {
let streams = v.filter(d => d.length > 0)
let ww = interlace(streams, t)
return ww
}
else if (f.isArray(v) //14 _____ v :: [a, {b}]*
&& !f.isPureArray(v) // has objects or array elements
&& !f.isDoubleSingleArray(v) // not double array with single value
&& g === 1) {
let doSnap = v.filter(d => Array.isArray(d) && d.length === 0).length
let wss = []
let was = []
if (doSnap === 0) { // 0[] - time snap and summa
for (let i = 0; i < v.length; i++) {
let wsi = snap(v[i], t, 0)
if (f.isObject(wsi)) { // {}
let d = wsi
d = snap(d, t) // reenter
let s = __mapper("xs").m("nat").rador(d)
s = f.streamRange(s,d.pa6,d.pb7)
s = s.map( (p,i) => {
let refAng = (d.w4 + d.fas8) * radians
let angUnit = tau / s.length
let ang = ((i * angUnit * d.v1) - refAng + tau) % tau
return p * Math.cos(ang) * d.ra2
})
if (s.length === 1) {
let r = [s[0], s[0]],
d = [0, 1]
wsi = d3.scaleLinear().domain(d).range(r)(t)
} else {
let r = s,
d = d3.range(r.length).map((item, idx) => idx / (r.length - 1))
wsi = d3.scaleLinear().domain(d).range(r)(t)
}
}
wss.push(wsi)
}
} else if (doSnap === 1) { // 1[] - leave expanded array
let w = v.map(d => snap(d, t))
for (let i = 0; i < w.length; i++) {
if (f.isObject(w[i])) { // {}
let d = snap(d, t) // reenter
was = __mapper("xs").m("nat").rador(d)
was = f.streamRange(s,d.pa6,d.pb7)
was = s.map( (p,i) => {
let refAng = (d.w4 + d.fas8) * radians
let angUnit = tau / s.length
let ang = ((i * angUnit * d.v1) - refAng + tau) % tau
return p * Math.cos(ang) * d.ra2
})
} else if (Array.isArray(w[i]) && w[i].length > 0) {
let wsi = w[i] // snap(w[i], t) // was.push(wsi) //
was = wsi // was.push(wsi) //
}
}
} else if (doSnap === 2) { // 2[] - do not snap --- summa
for (let i = 0; i < v.length; i++) {
let wsi = snap(v[i], t)
if (f.isObject(wsi)) { // {}
let d = wsi
d = snap(d, t) // reenter
let s = __mapper("xs").m("nat").rador(d)
s = f.streamRange(s,d.pa6,d.pb7)
s = s.map( (p,i) => {
let refAng = (d.w4 + d.fas8) * radians
let angUnit = tau / s.length
let ang = ((i * angUnit * d.v1) - refAng + tau) % tau
return p * Math.cos(ang) * d.ra2
})
if (s.length === 1) {
let r = [s[0], s[0]],
d = [0, 1]
ws[y] = d3.scaleLinear().domain(d).range(r)(t)
} else {
let r = s,
d = d3.range(r.length).map((item, idx) => idx / (r.length - 1))
wsi = d3.scaleLinear().domain(d).range(r)(t)
}
} else if (Array.isArray(wsi) && wsi.length > 0) {
was.push(wsi) //
} else if (typeof wsi === "number") {
was.push([wsi,wsi]) // constant path
}
}
}
let vr = null
if (doSnap === 0) {
vr = f.add(wss.map(d => {
let r = (typeof(d) === "function") ? d(t) : d // d cte: stateA:[[[300, {}]]]
return r
})) // summa snaps
} else if (doSnap === 1) {
vr = was // if out of time return array of values
}else if (doSnap === 2) {
vr = f.interadd(was) // summa arrays
}
return vr
}
else {
return v
}
}
/***********
* @enty
*/
let enty = function (v, t=0, g=0) {
return snap (v, t, g)
}
return enty
}
exports.bosonSnap = bosonSnap
}));
/**********************
* @bosonTim
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.bosonTim = global.bosonTim || {})));
}(this, function (exports) { 'use strict';
let bosonTim = function bosonTim(__mapper = {}) {
let props = __mapper("props")()
let epsilon = 1e-5
/**********************
* @timing
*/
let timing = function timing (pTim, pElapsed) {
let tim = Object.assign({},pTim)
let _tim = Object.assign({},pTim)
if (pElapsed < 0 ) tim.msStart = undefined // reset
let timeunits = tim.tu || 1000 // tim.tu: time unit
let duration = tim.td // tim.td: time duration
let t0 = tim.t0 // tim.t0: time init/wait
let t1 = tim.t1 // tim.t1: time limit
let step = Math.abs(tim.t2) || 1 // tim.t2: time step
let period = Math.abs(tim.t3) || 1 // tim.t3: time period
let window = (tim.tw) ? true : false // tim.tw: time window
let timeinverse = tim.inverse || false // tim.inverse: time direction
let common = tim.common // tim.common: shared time
let msDelta = (tim.msDelta !== undefined) ? tim.msDelta : 0 // time (ms) between ticks
let elapsed = tim.elapsed = pElapsed // abs msPassed time (ms)
let msElapsed = tim.elapsed // abs msPassed time - life (ms)
let msStart = tim.msStart // abs start time (ms)
let msPassed = tim.msPassed // rel time msPassed - life (ms)
let stopped = tim.stopped // is time stopped
let unitElapsed = tim.unitElapsed // common time elapsed (units)
let unitPassed = tim.unitPassed // rel time msPassed - life (units)
let unitStart = tim.unitStart // ref time start (common or relative) (units)
let unitTime = tim.unitTime // ref time msPassed (common or relative) (units)
let unitDelta = (tim.unitDelta !== undefined) ? tim.unitDelta : 0 // time (units) between ticks
let tick = tim.tick // time msPassed (ticks)
let timefactor = duration / timeunits // time factor
let wait = tim.wait = Math.abs(timefactor * t0) // t0 wait
let limit = tim.limit = Math.abs(timefactor * t1) // t1 limit
let slots = tim.slots = [] // slots
let d = (window === false) ? [tim.wait, tim.limit] : [0, duration] // time window
if ((Math.sign(t0) === -1) || (Math.sign(t1) === -1)) timeinverse = true // inverse
let r = (timeinverse === false) ? [0, 1] : [1, 0] // time inversion
let timescale = d3.scaleLinear().domain(d).range(r) // timescale: scale of life
tim.msStart = tim.msStart || elapsed // -- start time (abs, ms)
tim.msElapsed = tim.elapsed // -- abs time elapsed (abs, ms)
tim.msPassed = tim.elapsed - tim.msStart // -- relative time msPassed (abs, ms)
tim.msDelta = tim.elapsed - _tim.elapsed // -- time msPassed (abs, ms) between ticks
tim.stopped = 1 // -- time is stopped
let elapsedInPeriod = (period > epsilon) ? ((tim.elapsed % ( duration / period)) * period) : elapsed
let unitTimeElapsedInPeriod = timescale(elapsedInPeriod) // abs elapsed time in period (units)
let elapsedstep = Math.round(elapsed / step) // elapsedstep
if ((wait <= elapsed) && (elapsed <= limit) && (slots.indexOf(elapsedstep) !== null) ) {
slots.push(elapsedstep)
tim.unitElapsed = unitTimeElapsedInPeriod // TimeElapsedInPeriod (units)
}
let passedInPeriod = (period > epsilon) ? ((tim.msPassed % ( duration / period)) * period) : tim.msPassed
let unitTimePassedInPeriod = timescale(passedInPeriod) // rel msPassed time in period (units)
let passedstep = Math.round(tim.msPassed / step) // passedstep
if ((wait <= tim.msPassed) && (tim.msPassed <= limit) && (slots.indexOf(passedstep) !== null)) {
slots.push(passedstep)
tim.unitPassed = unitTimePassedInPeriod // TimePassedInPeriod (units)
}
tim.unitDelta = tim.unitPassed - _tim.unitPassed // -- time units between ticks
tim.unitTime = (common !== undefined) ? tim.unitElapsed : tim.unitPassed // time (units)
tim.msTime = (common !== undefined) ? tim.msElapsed : tim.msPassed // time (ms)
if (tim.unitTime !== null) { // do not start yet if no unitTime
tim.stopped = 0 // -- time unstopped
tim.unitStart = tim.unitStart || tim.unitTime // -- time started (units)
tim.tick = (tim.tick === undefined) ? 0 : tim.tick + 1 // -- time tick
}
return tim
}
/**********************
* @enty
*/
let enty = (pTim, pElapsed) => timing(pTim, pElapsed)
return enty
}
exports.bosonTim = bosonTim
}));
/*******************************************
* @bosonVersor
*
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.bosonVersor = global.bosonVersor || {})));
}(this, function (exports) { 'use strict';
// Version 0.0.0. Copyright 2017 Mike Bostock.
// ref: http://codepen.io/jorin/pen/YNajXZ
var bosonVersor = function bosonVersor(__mapper = {}) {
let props = __mapper("props")()
var stace = Object.assign({})
var acos = Math.acos,
asin = Math.asin,
atan2 = Math.atan2,
cos = Math.cos,
max = Math.max,
min = Math.min,
PI = Math.PI,
sin = Math.sin,
sqrt = Math.sqrt,
radians = PI / 180,
degrees = 180 / PI;
// Returns the unit quaternion for the given Euler rotation angles [λ, φ, γ].
var versor = function versor(e) {
var l = e[0] / 2 * radians, sl = sin(l), cl = cos(l), // λ / 2
p = e[1] / 2 * radians, sp = sin(p), cp = cos(p), // φ / 2
g = e[2] / 2 * radians, sg = sin(g), cg = cos(g); // γ / 2
return [
cl * cp * cg + sl * sp * sg,
sl * cp * cg - cl * sp * sg,
cl * sp * cg + sl * cp * sg,
cl * cp * sg - sl * sp * cg
];
}
// Returns Cartesian coordinates [x, y, z] given spherical coordinates [λ, φ].
versor.cartesian = function(e) {
var l = e[0] * radians, p = e[1] * radians, cp = cos(p);
return [cp * cos(l), cp * sin(l), sin(p)];
};
// Returns the Euler rotation angles [?, f, ?] for the given quaternion.
versor.rotation = function(q) {
return [
atan2(2 * (q[0] * q[1] + q[2] * q[3]), 1 - 2 * (q[1] * q[1] + q[2] * q[2])) * degrees,
asin(max(-1, min(1, 2 * (q[0] * q[2] - q[3] * q[1])))) * degrees,
atan2(2 * (q[0] * q[3] + q[1] * q[2]), 1 - 2 * (q[2] * q[2] + q[3] * q[3])) * degrees
];
};
// Returns the quaternion to rotate between two cartesian points on the sphere.
versor.delta = function(v0, v1) {
var w = versor.cross(v0, v1), l = sqrt(versor.dot(w, w));
if (!l) return [1, 0, 0, 0];
var t = acos(max(-1, min(1, versor.dot(v0, v1)))) / 2, s = sin(t); // t = θ / 2
return [cos(t), w[2] / l * s, -w[1] / l * s, w[0] / l * s];
};
// Returns the quaternion that represents q0 * q1.
versor.multiply = function(q0, q1) {
return [
q0[0] * q1[0] - q0[1] * q1[1] - q0[2] * q1[2] - q0[3] * q1[3],
q0[0] * q1[1] + q0[1] * q1[0] + q0[2] * q1[3] - q0[3] * q1[2],
q0[0] * q1[2] - q0[1] * q1[3] + q0[2] * q1[0] + q0[3] * q1[1],
q0[0] * q1[3] + q0[1] * q1[2] - q0[2] * q1[1] + q0[3] * q1[0]
];
};
versor.cross = function(v0, v1) {
return [
v0[1] * v1[2] - v0[2] * v1[1],
v0[2] * v1[0] - v0[0] * v1[2],
v0[0] * v1[1] - v0[1] * v1[0]
];
}
versor.dot = function(v0, v1) {
return v0[0] * v1[0] + v0[1] * v1[1] + v0[2] * v1[2];
}
versor.add = function(v0, v1) {
return [v0[0] + v1[0],
v0[1] + v1[1],
v0[2] + v1[2]]
}
/*******************************************
* @enty
*
*/
var enty = () => versor
return enty
}
exports.bosonVersor = bosonVersor
}));
/**********************
* @controlMouseDown
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.controlMouseDown = global.controlMouseDown || {})))
}(this, function (exports) { "use strict"
function controlMouseDown(payload) {
let state = {}
state.domNode = null
let currentListeners = []
let nextListeners = currentListeners
function ensureCanMutateNextListeners() {
if (nextListeners === currentListeners) {
nextListeners = currentListeners.slice()
}
}
function pauseEvent(e){
if(e.stopPropagation) e.stopPropagation()
if(e.preventDefault) e.preventDefault()
e.cancelBubble=true
e.returnValue=false
return false
}
function controlAction(_) {
let e = d3.event
pauseEvent(e)
let listeners = currentListeners = nextListeners
for (let i = 0; i < listeners.length; i++) {
listeners[i](e)
}
}
/*******************************************
* @enty
*
**/
function enty() {}
enty.domNode = function domNode(domNode) {
if (domNode === undefined ) return state.domNode
state.domNode = domNode
return enty
}
enty.control = function control(svg) {
return enty
}
enty.subscribe = function subscribe (listener, domNode) {
if (typeof listener !== "function") {
throw new Error("Expected listener to be a function.")
}
enty.domNode(domNode.node())
state.domNode.addEventListener("mousedown", listener) // event listener
}
return enty
}
exports.controlMouseDown = controlMouseDown
}));
/**********************
* @controlMouseUp
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.controlMouseUp = global.controlMouseUp || {})))
}(this, function (exports) { "use strict"
function controlMouseUp(payload) {
let state = {}
state.domNode = null
let currentListeners = []
let nextListeners = currentListeners
function ensureCanMutateNextListeners() {
if (nextListeners === currentListeners) {
nextListeners = currentListeners.slice()
}
}
function pauseEvent(e){
if(e.stopPropagation) e.stopPropagation()
if(e.preventDefault) e.preventDefault()
e.cancelBubble=true
e.returnValue=false
return false
}
function controlAction(_) {
let e = d3.event
pauseEvent(e)
let listeners = currentListeners = nextListeners
for (let i = 0; i < listeners.length; i++) {
listeners[i](e)
}
}
/*******************************************
* @enty
*
**/
function enty() {}
enty.domNode = function domNode(domNode) {
if (domNode === undefined ) return state.domNode
state.domNode = domNode
return enty
}
enty.control = function control(svg) {
return enty
}
enty.subscribe = function subscribe (listener, domNode) {
if (typeof listener !== "function") {
throw new Error("Expected listener to be a function.")
}
enty.domNode(domNode.node())
state.domNode.addEventListener("mouseup", listener) // event listener
}
return enty
}
exports.controlMouseUp = controlMouseUp
}))
/*******************************************
* @controlRaycaster
*
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.controlRaycaster = global.controlRaycaster || {})))
}(this, function (exports) { "use strict"
let controlRaycaster = function controlRaycaster(__mapper = {}) {
let f = __mapper("props")()
let raycaster = new THREE.Raycaster()
let state = {}
state. mouse = new THREE.Vector2()
state.mouse.x = -2 // Initialize off canvas
state.mouse.y = -2
state.domNode = null
/*******************************************
* @enty
*
*/
let enty = function enty() {}
enty.domNode = function domNode(domNode) {
if (domNode === undefined ) return state.domNode
state.domNode = domNode
return enty
}
/*******************************************
* @listerner
*
*/
let listerner = function listerner(event) {
let domElem = enty.domNode()
let width = domElem.getBoundingClientRect().width
let height = domElem.getBoundingClientRect().height
const offset = getOffset(domElem),
relPos = {
x: event.pageX - offset.left,
y: event.pageY - offset.top
}
state.mouse.x = (relPos.x / width) * 2 - 1
state.mouse.y = -(relPos.y / height) * 2 + 1
function getOffset(el) {
const rect = el.getBoundingClientRect(),
scrollLeft = window.pageXOffset || document.documentElement.scrollLeft,
scrollTop = window.pageYOffset || document.documentElement.scrollTop
return { top: rect.top + scrollTop, left: rect.left + scrollLeft }
}
}
/*******************************************
* @control
*
*/
enty.control = function control(domNode) {
enty.domNode(domNode)
domNode.addEventListener("mousemove",listerner) // event listener
}
enty.mouse = function() {
return state.mouse
}
return enty
}
exports.controlRaycaster = controlRaycaster
}));
/**********************
* @controlTimer
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.controlTimer = global.controlTimer || {})))
}(this, function (exports) { "use strict"
function controlTimer(__mapper) {
let state = {}
state.now = performance.now()
state.restartTime = performance.now()
state.stopTime = performance.now()
let currentListeners = []
let nextListeners = currentListeners
let d3timers = []
let started = false
// ......................... ensureCanMutateNextListeners
function ensureCanMutateNextListeners() {
if (nextListeners === currentListeners) {
nextListeners = currentListeners.slice()
}
}
// ......................... start
let start = function start() {
started = false
let main = function(timestamp) {
window.requestAnimationFrame(main)
let listeners = currentListeners = nextListeners
for (let i = 0; i < listeners.length; i++) {
listeners[i]() // run each listener
}
}
if (!started) {
started = true
main()
}
state.restartTime = performance.now() - (state.stopTime - state.restartTime)
return enty
}
// ......................... restart
let restart = function restart() {
started = true
let listeners = currentListeners = nextListeners
for (let i = 0; i < listeners.length; i++) {
state.restartTime = performance.now() - (state.stopTime - state.restartTime)
console.log("restart **", state.restartTime )
d3timers[i].restart(listeners[i],0,0)
}
return enty
}
// ......................... resume
let resume = function resume() {
started = true
let listeners = currentListeners = nextListeners
for (let i = 0; i < listeners.length; i++) {
state.restartTime = performance.now() - (state.stopTime - state.restartTime)
console.log("resume **", state.restartTime )
d3timers[i].stop(listeners[i])
d3timers[i].resume(listeners[i],0,state.restartTime)
}
return enty
}
// ......................... stop
let stop = function stop() {
started = false
let listeners = currentListeners = nextListeners
state.stopTime = performance.now()
for (let i = 0; i < listeners.length; i++) {
d3timers[i].stop()
}
return enty
}
// ......................... subscribe
let subscribe = function subscribe (listener, wait =0) {
started = true
if (typeof listener !== "function") {
throw new Error("Expected listener to be a function.")
}
let isSubscribed = true
ensureCanMutateNextListeners()
nextListeners.push(listener)
d3timers[nextListeners.length - 1] =
__mapper("xs").m("timer").timer(listener, wait, 0)
return function unsubscribe() {
if (!isSubscribed) {
return
}
let started = false //
isSubscribed = false
ensureCanMutateNextListeners()
let index = nextListeners.indexOf(listener)
d3timers[index].stop()
}
}
// ......................... enty
function enty() {}
enty.started = () => started
enty.start = start
enty.restart = restart
enty.resume = resume
enty.stop = stop
enty.subscribe = subscribe
return enty
}
exports.controlTimer = controlTimer
}))
/*******************************************
* @controlVersor
*
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.controlVersor = global.controlVersor || {})))
}(this, function (exports) { "use strict"
let controlVersor = function controlVersor(__mapper = {}) {
let f = __mapper("props")()
let bversor = __mapper("xs").b("versor")()
let drag = d3.drag()
let state = Object.assign({})
state.projection = d3.geoOrthographic()
state.rotation = [0,0,0]
state.v0 // Mouse position in Cartesian coordinates at start of drag gesture
state.r0 // Projection rotation as Euler angles at start
state.q0 // Projection rotation as versor at start
state.p0 // Polar coordintes
state.dtc // Distance initial dot to center untransformed
// inside
function inside(p) {
let pt0 = p
let k = state.projection.scale()
let dx = state.projection.translate()[0]
let dy = state.projection.translate()[1]
let radians = Math.PI / 180
let pt1 = [(pt0[0] - dx) / k, (dy - pt0[1]) / k]
let x = pt1[0]
let y = pt1[1]
let dtc = Math.sqrt(x * x + y * y) // abs < 1
return Math.abs(dtc) < 1
}
let getPos = e => (e.touches && e.touches.length) ? (e = e.touches[0], [e.x,e.y]) : [e.x,e.y]
let control = elem => elem.call(drag.on("start", dragstarted).on("drag", dragged))
// dragstarted
let dragstarted = function() {
let e = d3.event
let projection = state.projection
if (projection.invert !== undefined && projection.rotate !== undefined) {
state.p0 = getPos(e) // d3.mouse(this)
let inve0 = projection.invert(state.p0)
if (inve0 !== undefined) {
state.v0 = bversor.cartesian(inve0)
state.r0 = projection.rotate()
state.q0 = bversor(state.r0)
}
}
}
// dragged
let dragged = function() {
let e = d3.event
let projection = state.projection
if (projection.invert !== undefined && projection.rotate !== undefined) {
if (state.v0 !== undefined && state.r0 !== undefined) {
let inve0 = projection.rotate(state.r0).invert(getPos(e))
if (inve0 !== undefined) {
let v1 = bversor.cartesian(inve0)
let q1 = bversor.multiply(state.q0, bversor.delta(state.v0, v1))
let r1 = bversor.rotation(q1)
state.rotation = r1 // set global rotate
}
}
}
}
/*******************************************
* @API
*
*/
let enty = function enty() {}
enty.dragstarted = dragstarted
enty.dragged = dragged
enty.control = control
enty.projection = _ => _ !== undefined ? (state.projection = _ , enty) : state.projection
enty.rotation = _ => _ !== undefined ? (state.rotation = _ , enty) : state.rotation
return enty
}
exports.controlVersor = controlVersor
}))
/*******************************************
* @controlWen
*
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.controlWen = global.controlWen || {})))
}(this, function (exports) { "use strict"
// http://codepen.io/bali_balo/pen/XbyrME?editors=1100)
// https://github.com/wenliang-developer
// https://codepen.io/wenliang-developer/pen/gMwvXR
// https://github.com/wenliang-developer/web-developer-site
let controlWen = function controlWen(__mapper = {}) {
let f = __mapper("props")()
let w = __mapper("xs").m("wen")
let g = __mapper("xs").m("geom")
let drag = d3.drag()
let grabbed = false,
moved = false,
cPos,
pPos
function setBase() {
rotBase = rotMatrix
rotInDrag = [0,0,0] // reset rotInDrag
}
function tick() {
if(autorotimer) autorotimer = requestAnimationFrame(tick)
}
let defaults = {},
decay = 0.95,
mult = 2e-3, // rotInDrag factor
rotInit = [0,0,0] // [60,60,60],
let state = {},
rotVel = [0,0,0], // [-6e-3,7.6e-3,2.13e-3], // [0,0,0],
rotInDrag = [0,0,0], // rotInDrag in radians
rotPreDrag = [0,0,0],
rotAccum = [0,0,0],
autoRot = false,
lastMoveTime,
vel = [0,0,0],
timer,
autorotimer,
moveSpan = 16,
rotBase = [1,0,0,0,1,0,0,0,1], // identity matrix
rotMatrix
let getPos = e => (e.touches && e.touches.length) ? (e = e.touches[0], [e.x,e.y]) : [e.x,e.y]
let control = elem => elem.call(drag.on("start", dragstarted).on("drag", dragged).on("end", dragended))
function stopMomentum() { cancelAnimationFrame(timer); timer = null }
let dragstarted = function() {
let e = d3.event
if(grabbed) return // drag ongoing
if(!e.touches) e.sourceEvent.preventDefault()
stopMomentum()
cPos = pPos = grabbed = getPos(e) // position from event
moved = false // not moved yet
rotAccum = g.add(rotAccum, rotInDrag)
rotInDrag = [0,0,0]
}
let dragged = function() {
let e = d3.event
if(!grabbed) return
let pos = getPos(e) // d3.mouse(this)
let dx = grabbed[1] - pos[1],
dy = pos[0] - grabbed[0]
if(!moved) {
if(dx * dx + dy * dy < moveSpan) return
moved = true // moved
autoRot = false
rotInDrag = [0,0,0]
setBase()
}
lastMoveTime = Date.now()
pPos = cPos
cPos = pos
rotInDrag = [
rotVel[0] + dx * mult,
rotVel[1] + dy * mult,
rotVel[2] + 0
]
}
let dragended = function() {
let e = d3.event
if(!grabbed) return
grabbed = false
if(!moved) return
let f = Math.max(0, 1 - (Date.now() - lastMoveTime) / 200)
vel = [(pPos[1] - cPos[1]) * mult * f, (cPos[0] - pPos[0]) * mult * f]
timer = requestAnimationFrame(momentum)
}
function momentum() {
if(Math.abs(vel[0]) < 0.001 && Math.abs(vel[1]) < 0.001) return
vel[0] *= decay; vel[1] *= decay
rotInDrag[0] += vel[0]; rotInDrag[1] += vel[1]
if(timer) timer = requestAnimationFrame(momentum)
}
/*******************************************
* @ENTY
*/
let enty = function ( p={} ) {
rotInit = g.to_radians(p.rotInit) || [0,0,0]
autorotimer = requestAnimationFrame(tick)
return enty
}
enty.dragstarted = dragstarted
enty.dragged = dragged
enty.dragended = dragended
enty.control = control
enty.mult = _ => _ !== undefined ? (mult = _ , enty) : mult // effect multiplier
enty.rotInDrag = _ => _ !== undefined ? (rotInDrag = g.to_radians(_) , enty) : rotInDrag.map(g.to_degrees)
enty.rotAccum = _ => _ !== undefined ? (rotAccum = g.to_radians(_) , enty) : rotAccum.map(g.to_degrees)
enty.rotation = _ => _ !== undefined ? (rotation = g.to_radians(_) , enty) : g.add(rotAccum,rotInDrag).map(g.to_degrees)
enty.rotVel = _ => _ !== undefined ? (rotVel = g.to_radians(_) , enty) : rotVel.map(g.to_degrees)
enty.rotInit = _ => _ !== undefined ? (rotInit = g.to_radians(_) , enty) : rotInit.map(g.to_degrees)
return enty
}
exports.controlWen = controlWen
}))
// https://github.com/d3/d3-geo-polygon Version 1.0.1. Copyright 2017 Mike Bostock.
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-array')) :
typeof define === 'function' && define.amd ? define(['exports', 'd3-array'], factory) :
(factory((global.d3 = global.d3 || {}),global.d3));
}(this, (function (exports,d3Array) { 'use strict';
function noop() {}
var clipBuffer = function() {
var lines = [],
line;
return {
point: function(x, y, i, t) {
var point = [x, y];
// when called by clipPolygon, store index and t
if (arguments.length > 2) { point.index = i; point.t = t; }
line.push(point);
},
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;
}
};
};
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 radians = pi / 180;
var abs = Math.abs;
var atan2 = Math.atan2;
var cos = Math.cos;
var sin = Math.sin;
var sign = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; };
var sqrt = Math.sqrt;
function asin(x) {
return x > 1 ? halfPi : x < -1 ? -halfPi : Math.asin(x);
}
var pointEqual = function(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.
var clipRejoin = 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 the first and last points of a segment are coincident, then treat as a
// closed ring. TODO if all rings are closed, then the winding order of the
// exterior ring should be checked.
if (pointEqual(p0, p1)) {
stream.lineStart();
for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]);
stream.lineEnd();
return;
}
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;
}
// Adds floating point numbers with twice the normal precision.
// Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and
// Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3)
// 305–363 (1997).
// Code adapted from GeographicLib by Charles F. F. Karney,
// http://geographiclib.sourceforge.net/
var adder = function() {
return new Adder;
};
function Adder() {
this.reset();
}
Adder.prototype = {
constructor: Adder,
reset: function() {
this.s = // rounded value
this.t = 0; // exact error
},
add: function(y) {
add(temp, y, this.t);
add(this, temp.s, this.s);
if (this.s) this.t += temp.t;
else this.s = temp.t;
},
valueOf: function() {
return this.s;
}
};
var temp = new Adder;
function add(adder, a, b) {
var x = adder.s = a + b,
bv = x - a,
av = x - bv;
adder.t = (a - av) + (b - bv);
}
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
// 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;
}
function cartesianEqual(a, b) {
var dx = b[0] - a[0],
dy = b[1] - a[1],
dz = b[2] - a[2];
return dx * dx + dy * dy + dz * dz < epsilon2 * epsilon2;
}
var sum = adder();
var polygonContains = function(polygon, point) {
var lambda = point[0],
phi = point[1],
normal = [sin(lambda), -cos(lambda), 0],
angle = 0,
winding = 0;
sum.reset();
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 = point0[0],
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 = point1[0],
phi1 = point1[1] / 2 + quarterPi,
sinPhi1 = sin(phi1),
cosPhi1 = cos(phi1),
delta = lambda1 - lambda0,
sign$$1 = delta >= 0 ? 1 : -1,
absDelta = sign$$1 * delta,
antimeridian = absDelta > pi,
k = sinPhi0 * sinPhi1;
sum.add(atan2(k * sign$$1 * sin(absDelta), cosPhi0 * cosPhi1 + k * cos(absDelta)));
angle += antimeridian ? delta + sign$$1 * 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 < -epsilon) ^ (winding & 1);
};
var clip = function(pointVisible, clipLine, interpolate, start, sort) {
if (typeof sort === "undefined") sort = compareIntersection;
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, sort, 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, close) {
ring.push([lambda, phi]);
ringSink.point(lambda, phi, close);
}
function ringStart() {
ringSink.lineStart();
ring = [];
}
function ringEnd() {
pointRing(ring[0][0], ring[0][1], true);
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]);
}
function intersectSegment(from, to) {
this.from = from, this.to = to;
this.normal = cartesianCross(from, to);
this.fromNormal = cartesianCross(this.normal, from);
this.toNormal = cartesianCross(this.normal, to);
}
var epsilon3 = 1e-18;
// >> here a and b are segments processed by intersectSegment
function intersect(a, b) {
var axb = cartesianCross(a.normal, b.normal);
cartesianNormalizeInPlace(axb);
var a0 = cartesianDot(axb, a.fromNormal),
a1 = cartesianDot(axb, a.toNormal),
b0 = cartesianDot(axb, b.fromNormal),
b1 = cartesianDot(axb, b.toNormal);
if (a0 > -epsilon3 && a1 < epsilon3 && b0 > -epsilon3 && b1 < epsilon3) {
return axb;
}
if (a0 < epsilon3 && a1 > -epsilon3 && b0 < epsilon3 && b1 > -epsilon3) {
axb[0] = -axb[0], axb[1] = -axb[1], axb[2] = -axb[2];
return axb;
}
}
function intersectPointOnLine(p, a) {
var a0 = cartesianDot(p, a.fromNormal),
a1 = cartesianDot(p, a.toNormal);
p = cartesianDot(p, a.normal);
return abs(p) < epsilon2 && (a0 > -epsilon2 && a1 < epsilon2 || a0 < epsilon2 && a1 > -epsilon2);
}
var intersectCoincident = {};
// todo: publicly expose d3.geoIntersect(segment0, segment1) ??
// cf. https://github.com/d3/d3/commit/3dbdf87974dc2588c29db0533a8500ccddb25daa#diff-65daf69cea7d039d72c1eca7c13326b0
var clipNone = function(stream) { return stream; };
// clipPolygon
var polygon = function (p) {
var segments = [];
if (p.type != "Polygon") return clipNone; // todo: MultiPolygon?
var polygon = p.coordinates.map(function(ring) {
var c, c0;
ring = ring.map(function(point, i) {
c = cartesian(point = [point[0] * radians, point[1] * radians]);
if (i) segments.push(new intersectSegment(c0, c));
c0 = c;
return point;
});
ring.pop();
return ring;
});
function visible(lambda, phi) {
return polygonContains(polygon, [lambda, phi]);
}
function clipLine(stream) {
var point0,
lambda00,
phi00,
v00,
v0,
clean;
return {
lineStart: function() {
point0 = null;
clean = 1;
},
point: function(lambda, phi, close) {
if (cos(lambda) == -1) lambda -= sign(sin(lambda)) * 1e-5; // move away from -180/180 https://github.com/d3/d3-geo/pull/108#issuecomment-323798937
if (close) lambda = lambda00, phi = phi00;
var point = cartesian([lambda, phi]),
v = v0,
intersection,
i, j, s, t;
if (point0) {
var segment = new intersectSegment(point0, point),
intersections = [];
for (i = 0, j = 100; i < segments.length && j > 0; ++i) {
s = segments[i];
intersection = intersect(segment, s);
if (intersection) {
if (intersection === intersectCoincident ||
cartesianEqual(intersection, point0) || cartesianEqual(intersection, point) ||
cartesianEqual(intersection, s.from) || cartesianEqual(intersection, s.to)) {
t = 1e-4;
lambda = (lambda + 3 * pi + (Math.random() < .5 ? t : -t)) % (2 * pi) - pi;
phi = Math.min(pi / 2 - 1e-4, Math.max(1e-4 - pi / 2, phi + (Math.random() < .5 ? t : -t)));
segment = new intersectSegment(point0, point = cartesian([lambda, phi]));
i = -1, --j;
intersections.length = 0;
continue;
}
var sph = spherical(intersection);
intersection.distance = clipPolygonDistance(point0, intersection);
intersection.index = i;
intersection.t = clipPolygonDistance(s.from, intersection);
intersection[0] = sph[0], intersection[1] = sph[1], intersection.pop();
intersections.push(intersection);
}
}
if (intersections.length) {
clean = 0;
intersections.sort(function(a, b) { return a.distance - b.distance; });
for (i = 0; i < intersections.length; ++i) {
intersection = intersections[i];
v = !v;
if (v) {
stream.lineStart();
stream.point(intersection[0], intersection[1], intersection.index, intersection.t);
} else {
stream.point(intersection[0], intersection[1], intersection.index, intersection.t);
stream.lineEnd();
}
}
}
if (v) stream.point(lambda, phi);
} else {
for (i = 0, j = 100; i < segments.length && j > 0; ++i) {
s = segments[i];
if (intersectPointOnLine(point, s)) {
t = 1e-4;
lambda = (lambda + 3 * pi + (Math.random() < .5 ? t : -t)) % (2 * pi) - pi;
phi = Math.min(pi / 2 - 1e-4, Math.max(1e-4 - pi / 2, phi + (Math.random() < .5 ? t : -t)));
point = cartesian([lambda, phi]);
i = -1, --j;
}
}
v00 = v = visible(lambda00 = lambda, phi00 = phi);
if (v) stream.lineStart(), stream.point(lambda, phi);
}
point0 = point, v0 = v;
},
lineEnd: function() {
if (v0) stream.lineEnd();
},
// Rejoin first and last segments if there were intersections and the first
// and last points were visible.
clean: function() {
return clean | ((v00 && v0) << 1);
}
};
}
function interpolate(from, to, direction, stream) {
if (from == null) {
var n = polygon.length;
polygon.forEach(function(ring, i) {
ring.forEach(function(point) { stream.point(point[0], point[1]); });
if (i < n - 1) stream.lineEnd(), stream.lineStart();
});
} else if (from.index !== to.index && from.index != null && to.index != null) {
for (var i = from.index; i !== to.index; i = (i + direction + segments.length) % segments.length) {
var segment = segments[i],
point = spherical(direction > 0 ? segment.to : segment.from);
stream.point(point[0], point[1]);
}
}
}
return clip(visible, clipLine, interpolate, polygon[0][0], clipPolygonSort);
};
function clipPolygonSort(a, b) {
a = a.x, b = b.x;
return a.index - b.index || a.t - b.t;
}
// Geodesic coordinates for two 3D points.
function clipPolygonDistance(a, b) {
var axb = cartesianCross(a, b);
return atan2(sqrt(cartesianDot(axb, axb)), cartesianDot(a, b));
}
exports.geoClipPolygon = polygon;
Object.defineProperty(exports, '__esModule', { value: true });
})));
// https://d3js.org/d3-geo-projection/ Version 2.3.1. Copyright 2017 Mike Bostock.
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-geo'), require('d3-array'), require('d3-geo-polygon')) :
typeof define === 'function' && define.amd ? define(['exports', 'd3-geo', 'd3-array', 'd3-geo-polygon'], factory) :
(factory((global.d3 = global.d3 || {}),global.d3,global.d3,global.d3));
}(this, (function (exports,d3Geo,d3Array,d3GeoPolygon) { 'use strict';
var abs = Math.abs;
var atan = Math.atan;
var atan2 = Math.atan2;
var cos = Math.cos;
var exp = Math.exp;
var floor = Math.floor;
var log = Math.log;
var max = Math.max;
var min = Math.min;
var pow = Math.pow;
var round = Math.round;
var sign = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; };
var sin = Math.sin;
var tan = Math.tan;
var epsilon = 1e-6;
var epsilon2 = 1e-12;
var pi = Math.PI;
var halfPi = pi / 2;
var quarterPi = pi / 4;
var sqrt1_2 = Math.SQRT1_2;
var sqrt2 = sqrt(2);
var sqrtPi = sqrt(pi);
var tau = pi * 2;
var degrees = 180 / pi;
var radians = pi / 180;
function sinci(x) {
return x ? x / Math.sin(x) : 1;
}
function asin(x) {
return x > 1 ? halfPi : x < -1 ? -halfPi : Math.asin(x);
}
function acos(x) {
return x > 1 ? 0 : x < -1 ? pi : Math.acos(x);
}
function sqrt(x) {
return x > 0 ? Math.sqrt(x) : 0;
}
function tanh(x) {
x = exp(2 * x);
return (x - 1) / (x + 1);
}
function sinh(x) {
return (exp(x) - exp(-x)) / 2;
}
function cosh(x) {
return (exp(x) + exp(-x)) / 2;
}
function arsinh(x) {
return log(x + sqrt(x * x + 1));
}
function arcosh(x) {
return log(x + sqrt(x * x - 1));
}
function airyRaw(beta) {
var tanBeta_2 = tan(beta / 2),
b = 2 * log(cos(beta / 2)) / (tanBeta_2 * tanBeta_2);
function forward(x, y) {
var cosx = cos(x),
cosy = cos(y),
siny = sin(y),
cosz = cosy * cosx,
k = -((1 - cosz ? log((1 + cosz) / 2) / (1 - cosz) : -0.5) + b / (1 + cosz));
return [k * cosy * sin(x), k * siny];
}
forward.invert = function(x, y) {
var r = sqrt(x * x + y * y),
z = -beta / 2,
i = 50, delta;
if (!r) return [0, 0];
do {
var z_2 = z / 2,
cosz_2 = cos(z_2),
sinz_2 = sin(z_2),
tanz_2 = tan(z_2),
lnsecz_2 = log(1 / cosz_2);
z -= delta = (2 / tanz_2 * lnsecz_2 - b * tanz_2 - r) / (-lnsecz_2 / (sinz_2 * sinz_2) + 1 - b / (2 * cosz_2 * cosz_2));
} while (abs(delta) > epsilon && --i > 0);
var sinz = sin(z);
return [atan2(x * sinz, r * cos(z)), asin(y * sinz / r)];
};
return forward;
}
var airy = function() {
var beta = halfPi,
m = d3Geo.geoProjectionMutator(airyRaw),
p = m(beta);
p.radius = function(_) {
return arguments.length ? m(beta = _ * radians) : beta * degrees;
};
return p
.scale(179.976)
.clipAngle(147);
};
function aitoffRaw(x, y) {
var cosy = cos(y), sincia = sinci(acos(cosy * cos(x /= 2)));
return [2 * cosy * sin(x) * sincia, sin(y) * sincia];
}
// Abort if [x, y] is not within an ellipse centered at [0, 0] with
// semi-major axis pi and semi-minor axis pi/2.
aitoffRaw.invert = function(x, y) {
if (x * x + 4 * y * y > pi * pi + epsilon) return;
var x1 = x, y1 = y, i = 25;
do {
var sinx = sin(x1),
sinx_2 = sin(x1 / 2),
cosx_2 = cos(x1 / 2),
siny = sin(y1),
cosy = cos(y1),
sin_2y = sin(2 * y1),
sin2y = siny * siny,
cos2y = cosy * cosy,
sin2x_2 = sinx_2 * sinx_2,
c = 1 - cos2y * cosx_2 * cosx_2,
e = c ? acos(cosy * cosx_2) * sqrt(f = 1 / c) : f = 0,
f,
fx = 2 * e * cosy * sinx_2 - x,
fy = e * siny - y,
dxdx = f * (cos2y * sin2x_2 + e * cosy * cosx_2 * sin2y),
dxdy = f * (0.5 * sinx * sin_2y - e * 2 * siny * sinx_2),
dydx = f * 0.25 * (sin_2y * sinx_2 - e * siny * cos2y * sinx),
dydy = f * (sin2y * cosx_2 + e * sin2x_2 * cosy),
z = dxdy * dydx - dydy * dxdx;
if (!z) break;
var dx = (fy * dxdy - fx * dydy) / z,
dy = (fx * dydx - fy * dxdx) / z;
x1 -= dx, y1 -= dy;
} while ((abs(dx) > epsilon || abs(dy) > epsilon) && --i > 0);
return [x1, y1];
};
var aitoff = function() {
return d3Geo.geoProjection(aitoffRaw)
.scale(152.63);
};
function armadilloRaw(phi0) {
var sinPhi0 = sin(phi0),
cosPhi0 = cos(phi0),
sPhi0 = phi0 >= 0 ? 1 : -1,
tanPhi0 = tan(sPhi0 * phi0),
k = (1 + sinPhi0 - cosPhi0) / 2;
function forward(lambda, phi) {
var cosPhi = cos(phi),
cosLambda = cos(lambda /= 2);
return [
(1 + cosPhi) * sin(lambda),
(sPhi0 * phi > -atan2(cosLambda, tanPhi0) - 1e-3 ? 0 : -sPhi0 * 10) + k + sin(phi) * cosPhi0 - (1 + cosPhi) * sinPhi0 * cosLambda // TODO D3 core should allow null or [NaN, NaN] to be returned.
];
}
forward.invert = function(x, y) {
var lambda = 0,
phi = 0,
i = 50;
do {
var cosLambda = cos(lambda),
sinLambda = sin(lambda),
cosPhi = cos(phi),
sinPhi = sin(phi),
A = 1 + cosPhi,
fx = A * sinLambda - x,
fy = k + sinPhi * cosPhi0 - A * sinPhi0 * cosLambda - y,
dxdLambda = A * cosLambda / 2,
dxdPhi = -sinLambda * sinPhi,
dydLambda = sinPhi0 * A * sinLambda / 2,
dydPhi = cosPhi0 * cosPhi + sinPhi0 * cosLambda * sinPhi,
denominator = dxdPhi * dydLambda - dydPhi * dxdLambda,
dLambda = (fy * dxdPhi - fx * dydPhi) / denominator / 2,
dPhi = (fx * dydLambda - fy * dxdLambda) / denominator;
lambda -= dLambda, phi -= dPhi;
} while ((abs(dLambda) > epsilon || abs(dPhi) > epsilon) && --i > 0);
return sPhi0 * phi > -atan2(cos(lambda), tanPhi0) - 1e-3 ? [lambda * 2, phi] : null;
};
return forward;
}
var armadillo = function() {
var phi0 = 20 * radians,
sPhi0 = phi0 >= 0 ? 1 : -1,
tanPhi0 = tan(sPhi0 * phi0),
m = d3Geo.geoProjectionMutator(armadilloRaw),
p = m(phi0),
stream_ = p.stream;
p.parallel = function(_) {
if (!arguments.length) return phi0 * degrees;
tanPhi0 = tan((sPhi0 = (phi0 = _ * radians) >= 0 ? 1 : -1) * phi0);
return m(phi0);
};
p.stream = function(stream) {
var rotate = p.rotate(),
rotateStream = stream_(stream),
sphereStream = (p.rotate([0, 0]), stream_(stream));
p.rotate(rotate);
rotateStream.sphere = function() {
sphereStream.polygonStart(), sphereStream.lineStart();
for (var lambda = sPhi0 * -180; sPhi0 * lambda < 180; lambda += sPhi0 * 90) sphereStream.point(lambda, sPhi0 * 90);
while (sPhi0 * (lambda -= phi0) >= -180) { // TODO precision?
sphereStream.point(lambda, sPhi0 * -atan2(cos(lambda * radians / 2), tanPhi0) * degrees);
}
sphereStream.lineEnd(), sphereStream.polygonEnd();
};
return rotateStream;
};
return p
.scale(218.695)
.center([0, 28.0974]);
};
function augustRaw(lambda, phi) {
var tanPhi = tan(phi / 2),
k = sqrt(1 - tanPhi * tanPhi),
c = 1 + k * cos(lambda /= 2),
x = sin(lambda) * k / c,
y = tanPhi / c,
x2 = x * x,
y2 = y * y;
return [
4 / 3 * x * (3 + x2 - 3 * y2),
4 / 3 * y * (3 + 3 * x2 - y2)
];
}
augustRaw.invert = function(x, y) {
x *= 3 / 8, y *= 3 / 8;
if (!x && abs(y) > 1) return null;
var x2 = x * x,
y2 = y * y,
s = 1 + x2 + y2,
sin3Eta = sqrt((s - sqrt(s * s - 4 * y * y)) / 2),
eta = asin(sin3Eta) / 3,
xi = sin3Eta ? arcosh(abs(y / sin3Eta)) / 3 : arsinh(abs(x)) / 3,
cosEta = cos(eta),
coshXi = cosh(xi),
d = coshXi * coshXi - cosEta * cosEta;
return [
sign(x) * 2 * atan2(sinh(xi) * cosEta, 0.25 - d),
sign(y) * 2 * atan2(coshXi * sin(eta), 0.25 + d)
];
};
var august = function() {
return d3Geo.geoProjection(augustRaw)
.scale(66.1603);
};
var sqrt8 = sqrt(8);
var phi0 = log(1 + sqrt2);
function bakerRaw(lambda, phi) {
var phi0 = abs(phi);
return phi0 < quarterPi
? [lambda, log(tan(quarterPi + phi / 2))]
: [lambda * cos(phi0) * (2 * sqrt2 - 1 / sin(phi0)), sign(phi) * (2 * sqrt2 * (phi0 - quarterPi) - log(tan(phi0 / 2)))];
}
bakerRaw.invert = function(x, y) {
if ((y0 = abs(y)) < phi0) return [x, 2 * atan(exp(y)) - halfPi];
var phi = quarterPi, i = 25, delta, y0;
do {
var cosPhi_2 = cos(phi / 2), tanPhi_2 = tan(phi / 2);
phi -= delta = (sqrt8 * (phi - quarterPi) - log(tanPhi_2) - y0) / (sqrt8 - cosPhi_2 * cosPhi_2 / (2 * tanPhi_2));
} while (abs(delta) > epsilon2 && --i > 0);
return [x / (cos(phi) * (sqrt8 - 1 / sin(phi))), sign(y) * phi];
};
var baker = function() {
return d3Geo.geoProjection(bakerRaw)
.scale(112.314);
};
function berghausRaw(lobes) {
var k = 2 * pi / lobes;
function forward(lambda, phi) {
var p = d3Geo.geoAzimuthalEquidistantRaw(lambda, phi);
if (abs(lambda) > halfPi) { // back hemisphere
var theta = atan2(p[1], p[0]),
r = sqrt(p[0] * p[0] + p[1] * p[1]),
theta0 = k * round((theta - halfPi) / k) + halfPi,
alpha = atan2(sin(theta -= theta0), 2 - cos(theta)); // angle relative to lobe end
theta = theta0 + asin(pi / r * sin(alpha)) - alpha;
p[0] = r * cos(theta);
p[1] = r * sin(theta);
}
return p;
}
forward.invert = function(x, y) {
var r = sqrt(x * x + y * y);
if (r > halfPi) {
var theta = atan2(y, x),
theta0 = k * round((theta - halfPi) / k) + halfPi,
s = theta > theta0 ? -1 : 1,
A = r * cos(theta0 - theta),
cotAlpha = 1 / tan(s * acos((A - pi) / sqrt(pi * (pi - 2 * A) + r * r)));
theta = theta0 + 2 * atan((cotAlpha + s * sqrt(cotAlpha * cotAlpha - 3)) / 3);
x = r * cos(theta), y = r * sin(theta);
}
return d3Geo.geoAzimuthalEquidistantRaw.invert(x, y);
};
return forward;
}
var berghaus = function() {
var lobes = 5,
m = d3Geo.geoProjectionMutator(berghausRaw),
p = m(lobes),
projectionStream = p.stream,
epsilon$$1 = 1e-2,
cr = -cos(epsilon$$1 * radians),
sr = sin(epsilon$$1 * radians);
p.lobes = function(_) {
return arguments.length ? m(lobes = +_) : lobes;
};
p.stream = function(stream) {
var rotate = p.rotate(),
rotateStream = projectionStream(stream),
sphereStream = (p.rotate([0, 0]), projectionStream(stream));
p.rotate(rotate);
rotateStream.sphere = function() {
sphereStream.polygonStart(), sphereStream.lineStart();
for (var i = 0, delta = 360 / lobes, delta0 = 2 * pi / lobes, phi = 90 - 180 / lobes, phi0 = halfPi; i < lobes; ++i, phi -= delta, phi0 -= delta0) {
sphereStream.point(atan2(sr * cos(phi0), cr) * degrees, asin(sr * sin(phi0)) * degrees);
if (phi < -90) {
sphereStream.point(-90, -180 - phi - epsilon$$1);
sphereStream.point(-90, -180 - phi + epsilon$$1);
} else {
sphereStream.point(90, phi + epsilon$$1);
sphereStream.point(90, phi - epsilon$$1);
}
}
sphereStream.lineEnd(), sphereStream.polygonEnd();
};
return rotateStream;
};
return p
.scale(87.8076)
.center([0, 17.1875])
.clipAngle(180 - 1e-3);
};
function hammerRaw(A, B) {
if (arguments.length < 2) B = A;
if (B === 1) return d3Geo.geoAzimuthalEqualAreaRaw;
if (B === Infinity) return hammerQuarticAuthalicRaw;
function forward(lambda, phi) {
var coordinates = d3Geo.geoAzimuthalEqualAreaRaw(lambda / B, phi);
coordinates[0] *= A;
return coordinates;
}
forward.invert = function(x, y) {
var coordinates = d3Geo.geoAzimuthalEqualAreaRaw.invert(x / A, y);
coordinates[0] *= B;
return coordinates;
};
return forward;
}
function hammerQuarticAuthalicRaw(lambda, phi) {
return [
lambda * cos(phi) / cos(phi /= 2),
2 * sin(phi)
];
}
hammerQuarticAuthalicRaw.invert = function(x, y) {
var phi = 2 * asin(y / 2);
return [
x * cos(phi / 2) / cos(phi),
phi
];
};
var hammer = function() {
var B = 2,
m = d3Geo.geoProjectionMutator(hammerRaw),
p = m(B);
p.coefficient = function(_) {
if (!arguments.length) return B;
return m(B = +_);
};
return p
.scale(169.529);
};
// Bertin 1953 as a modified Briesemeister
// https://bl.ocks.org/Fil/5b9ee9636dfb6ffa53443c9006beb642
function bertin1953Raw() {
var hammer$$1 = hammerRaw(1.68, 2),
fu = 1.4, k = 12;
return function(lambda, phi) {
if (lambda + phi < -fu) {
var u = (lambda - phi + 1.6) * (lambda + phi + fu) / 8;
lambda += u;
phi -= 0.8 * u * sin(phi + pi / 2);
}
var r = hammer$$1(lambda, phi);
var d = (1 - cos(lambda * phi)) / k;
if (r[1] < 0) {
r[0] *= 1 + d;
}
if (r[1] > 0) {
r[1] *= 1 + d / 1.5 * r[0] * r[0];
}
return r;
};
}
var bertin = function() {
var p = d3Geo.geoProjection(bertin1953Raw());
p.rotate([-16.5, -42]);
delete p.rotate;
return p
.scale(176.57)
.center([7.93, 0.09]);
};
function mollweideBromleyTheta(cp, phi) {
var cpsinPhi = cp * sin(phi), i = 30, delta;
do phi -= delta = (phi + sin(phi) - cpsinPhi) / (1 + cos(phi));
while (abs(delta) > epsilon && --i > 0);
return phi / 2;
}
function mollweideBromleyRaw(cx, cy, cp) {
function forward(lambda, phi) {
return [cx * lambda * cos(phi = mollweideBromleyTheta(cp, phi)), cy * sin(phi)];
}
forward.invert = function(x, y) {
return y = asin(y / cy), [x / (cx * cos(y)), asin((2 * y + sin(2 * y)) / cp)];
};
return forward;
}
var mollweideRaw = mollweideBromleyRaw(sqrt2 / halfPi, sqrt2, pi);
var mollweide = function() {
return d3Geo.geoProjection(mollweideRaw)
.scale(169.529);
};
var k = 2.00276;
var w = 1.11072;
function boggsRaw(lambda, phi) {
var theta = mollweideBromleyTheta(pi, phi);
return [k * lambda / (1 / cos(phi) + w / cos(theta)), (phi + sqrt2 * sin(theta)) / k];
}
boggsRaw.invert = function(x, y) {
var ky = k * y, theta = y < 0 ? -quarterPi : quarterPi, i = 25, delta, phi;
do {
phi = ky - sqrt2 * sin(theta);
theta -= delta = (sin(2 * theta) + 2 * theta - pi * sin(phi)) / (2 * cos(2 * theta) + 2 + pi * cos(phi) * sqrt2 * cos(theta));
} while (abs(delta) > epsilon && --i > 0);
phi = ky - sqrt2 * sin(theta);
return [x * (1 / cos(phi) + w / cos(theta)) / k, phi];
};
var boggs = function() {
return d3Geo.geoProjection(boggsRaw)
.scale(160.857);
};
var parallel1 = function(projectAt) {
var phi0 = 0,
m = d3Geo.geoProjectionMutator(projectAt),
p = m(phi0);
p.parallel = function(_) {
return arguments.length ? m(phi0 = _ * radians) : phi0 * degrees;
};
return p;
};
function sinusoidalRaw(lambda, phi) {
return [lambda * cos(phi), phi];
}
sinusoidalRaw.invert = function(x, y) {
return [x / cos(y), y];
};
var sinusoidal = function() {
return d3Geo.geoProjection(sinusoidalRaw)
.scale(152.63);
};
function bonneRaw(phi0) {
if (!phi0) return sinusoidalRaw;
var cotPhi0 = 1 / tan(phi0);
function forward(lambda, phi) {
var rho = cotPhi0 + phi0 - phi,
e = rho ? lambda * cos(phi) / rho : rho;
return [rho * sin(e), cotPhi0 - rho * cos(e)];
}
forward.invert = function(x, y) {
var rho = sqrt(x * x + (y = cotPhi0 - y) * y),
phi = cotPhi0 + phi0 - rho;
return [rho / cos(phi) * atan2(x, y), phi];
};
return forward;
}
var bonne = function() {
return parallel1(bonneRaw)
.scale(123.082)
.center([0, 26.1441])
.parallel(45);
};
function bottomleyRaw(sinPsi) {
function forward(lambda, phi) {
var rho = halfPi - phi,
eta = rho ? lambda * sinPsi * sin(rho) / rho : rho;
return [rho * sin(eta) / sinPsi, halfPi - rho * cos(eta)];
}
forward.invert = function(x, y) {
var x1 = x * sinPsi,
y1 = halfPi - y,
rho = sqrt(x1 * x1 + y1 * y1),
eta = atan2(x1, y1);
return [(rho ? rho / sin(rho) : 1) * eta / sinPsi, halfPi - rho];
};
return forward;
}
var bottomley = function() {
var sinPsi = 0.5,
m = d3Geo.geoProjectionMutator(bottomleyRaw),
p = m(sinPsi);
p.fraction = function(_) {
return arguments.length ? m(sinPsi = +_) : sinPsi;
};
return p
.scale(158.837);
};
var bromleyRaw = mollweideBromleyRaw(1, 4 / pi, pi);
var bromley = function() {
return d3Geo.geoProjection(bromleyRaw)
.scale(152.63);
};
// Azimuthal distance.
function distance(dPhi, c1, s1, c2, s2, dLambda) {
var cosdLambda = cos(dLambda), r;
if (abs(dPhi) > 1 || abs(dLambda) > 1) {
r = acos(s1 * s2 + c1 * c2 * cosdLambda);
} else {
var sindPhi = sin(dPhi / 2), sindLambda = sin(dLambda / 2);
r = 2 * asin(sqrt(sindPhi * sindPhi + c1 * c2 * sindLambda * sindLambda));
}
return abs(r) > epsilon ? [r, atan2(c2 * sin(dLambda), c1 * s2 - s1 * c2 * cosdLambda)] : [0, 0];
}
// Angle opposite a, and contained between sides of lengths b and c.
function angle(b, c, a) {
return acos((b * b + c * c - a * a) / (2 * b * c));
}
// Normalize longitude.
function longitude(lambda) {
return lambda - 2 * pi * floor((lambda + pi) / (2 * pi));
}
function chamberlinRaw(p0, p1, p2) {
var points = [
[p0[0], p0[1], sin(p0[1]), cos(p0[1])],
[p1[0], p1[1], sin(p1[1]), cos(p1[1])],
[p2[0], p2[1], sin(p2[1]), cos(p2[1])]
];
for (var a = points[2], b, i = 0; i < 3; ++i, a = b) {
b = points[i];
a.v = distance(b[1] - a[1], a[3], a[2], b[3], b[2], b[0] - a[0]);
a.point = [0, 0];
}
var beta0 = angle(points[0].v[0], points[2].v[0], points[1].v[0]),
beta1 = angle(points[0].v[0], points[1].v[0], points[2].v[0]),
beta2 = pi - beta0;
points[2].point[1] = 0;
points[0].point[0] = -(points[1].point[0] = points[0].v[0] / 2);
var mean = [
points[2].point[0] = points[0].point[0] + points[2].v[0] * cos(beta0),
2 * (points[0].point[1] = points[1].point[1] = points[2].v[0] * sin(beta0))
];
function forward(lambda, phi) {
var sinPhi = sin(phi),
cosPhi = cos(phi),
v = new Array(3), i;
// Compute distance and azimuth from control points.
for (i = 0; i < 3; ++i) {
var p = points[i];
v[i] = distance(phi - p[1], p[3], p[2], cosPhi, sinPhi, lambda - p[0]);
if (!v[i][0]) return p.point;
v[i][1] = longitude(v[i][1] - p.v[1]);
}
// Arithmetic mean of interception points.
var point = mean.slice();
for (i = 0; i < 3; ++i) {
var j = i == 2 ? 0 : i + 1;
var a = angle(points[i].v[0], v[i][0], v[j][0]);
if (v[i][1] < 0) a = -a;
if (!i) {
point[0] += v[i][0] * cos(a);
point[1] -= v[i][0] * sin(a);
} else if (i == 1) {
a = beta1 - a;
point[0] -= v[i][0] * cos(a);
point[1] -= v[i][0] * sin(a);
} else {
a = beta2 - a;
point[0] += v[i][0] * cos(a);
point[1] += v[i][0] * sin(a);
}
}
point[0] /= 3, point[1] /= 3;
return point;
}
return forward;
}
function pointRadians(p) {
return p[0] *= radians, p[1] *= radians, p;
}
function chamberlinAfrica() {
return chamberlin([0, 22], [45, 22], [22.5, -22])
.scale(380)
.center([22.5, 2]);
}
function chamberlin(p0, p1, p2) { // TODO order matters!
var c = d3Geo.geoCentroid({type: "MultiPoint", coordinates: [p0, p1, p2]}),
R = [-c[0], -c[1]],
r = d3Geo.geoRotation(R),
p = d3Geo.geoProjection(chamberlinRaw(pointRadians(r(p0)), pointRadians(r(p1)), pointRadians(r(p2)))).rotate(R),
center = p.center;
delete p.rotate;
p.center = function(_) {
return arguments.length ? center(r(_)) : r.invert(center());
};
return p
.clipAngle(90);
}
function collignonRaw(lambda, phi) {
var alpha = sqrt(1 - sin(phi));
return [(2 / sqrtPi) * lambda * alpha, sqrtPi * (1 - alpha)];
}
collignonRaw.invert = function(x, y) {
var lambda = (lambda = y / sqrtPi - 1) * lambda;
return [lambda > 0 ? x * sqrt(pi / lambda) / 2 : 0, asin(1 - lambda)];
};
var collignon = function() {
return d3Geo.geoProjection(collignonRaw)
.scale(95.6464)
.center([0, 30]);
};
function craigRaw(phi0) {
var tanPhi0 = tan(phi0);
function forward(lambda, phi) {
return [lambda, (lambda ? lambda / sin(lambda) : 1) * (sin(phi) * cos(lambda) - tanPhi0 * cos(phi))];
}
forward.invert = tanPhi0 ? function(x, y) {
if (x) y *= sin(x) / x;
var cosLambda = cos(x);
return [x, 2 * atan2(sqrt(cosLambda * cosLambda + tanPhi0 * tanPhi0 - y * y) - cosLambda, tanPhi0 - y)];
} : function(x, y) {
return [x, asin(x ? y * tan(x) / x : y)];
};
return forward;
}
var craig = function() {
return parallel1(craigRaw)
.scale(249.828)
.clipAngle(90);
};
var sqrt3 = sqrt(3);
function crasterRaw(lambda, phi) {
return [sqrt3 * lambda * (2 * cos(2 * phi / 3) - 1) / sqrtPi, sqrt3 * sqrtPi * sin(phi / 3)];
}
crasterRaw.invert = function(x, y) {
var phi = 3 * asin(y / (sqrt3 * sqrtPi));
return [sqrtPi * x / (sqrt3 * (2 * cos(2 * phi / 3) - 1)), phi];
};
var craster = function() {
return d3Geo.geoProjection(crasterRaw)
.scale(156.19);
};
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;
}
var cylindricalEqualArea = function() {
return parallel1(cylindricalEqualAreaRaw)
.parallel(38.58) // acos(sqrt(width / height / pi)) * radians
.scale(195.044); // width / (sqrt(width / height / pi) * 2 * pi)
};
function cylindricalStereographicRaw(phi0) {
var cosPhi0 = cos(phi0);
function forward(lambda, phi) {
return [lambda * cosPhi0, (1 + cosPhi0) * tan(phi / 2)];
}
forward.invert = function(x, y) {
return [x / cosPhi0, atan(y / (1 + cosPhi0)) * 2];
};
return forward;
}
var cylindricalStereographic = function() {
return parallel1(cylindricalStereographicRaw)
.scale(124.75);
};
function eckert1Raw(lambda, phi) {
var alpha = sqrt(8 / (3 * pi));
return [
alpha * lambda * (1 - abs(phi) / pi),
alpha * phi
];
}
eckert1Raw.invert = function(x, y) {
var alpha = sqrt(8 / (3 * pi)),
phi = y / alpha;
return [
x / (alpha * (1 - abs(phi) / pi)),
phi
];
};
var eckert1 = function() {
return d3Geo.geoProjection(eckert1Raw)
.scale(165.664);
};
function eckert2Raw(lambda, phi) {
var alpha = sqrt(4 - 3 * sin(abs(phi)));
return [
2 / sqrt(6 * pi) * lambda * alpha,
sign(phi) * sqrt(2 * pi / 3) * (2 - alpha)
];
}
eckert2Raw.invert = function(x, y) {
var alpha = 2 - abs(y) / sqrt(2 * pi / 3);
return [
x * sqrt(6 * pi) / (2 * alpha),
sign(y) * asin((4 - alpha * alpha) / 3)
];
};
var eckert2 = function() {
return d3Geo.geoProjection(eckert2Raw)
.scale(165.664);
};
function eckert3Raw(lambda, phi) {
var k = sqrt(pi * (4 + pi));
return [
2 / k * lambda * (1 + sqrt(1 - 4 * phi * phi / (pi * pi))),
4 / k * phi
];
}
eckert3Raw.invert = function(x, y) {
var k = sqrt(pi * (4 + pi)) / 2;
return [
x * k / (1 + sqrt(1 - y * y * (4 + pi) / (4 * pi))),
y * k / 2
];
};
var eckert3 = function() {
return d3Geo.geoProjection(eckert3Raw)
.scale(180.739);
};
function eckert4Raw(lambda, phi) {
var k = (2 + halfPi) * sin(phi);
phi /= 2;
for (var i = 0, delta = Infinity; i < 10 && abs(delta) > epsilon; i++) {
var cosPhi = cos(phi);
phi -= delta = (phi + sin(phi) * (cosPhi + 2) - k) / (2 * cosPhi * (1 + cosPhi));
}
return [
2 / sqrt(pi * (4 + pi)) * lambda * (1 + cos(phi)),
2 * sqrt(pi / (4 + pi)) * sin(phi)
];
}
eckert4Raw.invert = function(x, y) {
var A = y * sqrt((4 + pi) / pi) / 2,
k = asin(A),
c = cos(k);
return [
x / (2 / sqrt(pi * (4 + pi)) * (1 + c)),
asin((k + A * (c + 2)) / (2 + halfPi))
];
};
var eckert4 = function() {
return d3Geo.geoProjection(eckert4Raw)
.scale(180.739);
};
function eckert5Raw(lambda, phi) {
return [
lambda * (1 + cos(phi)) / sqrt(2 + pi),
2 * phi / sqrt(2 + pi)
];
}
eckert5Raw.invert = function(x, y) {
var k = sqrt(2 + pi),
phi = y * k / 2;
return [
k * x / (1 + cos(phi)),
phi
];
};
var eckert5 = function() {
return d3Geo.geoProjection(eckert5Raw)
.scale(173.044);
};
function eckert6Raw(lambda, phi) {
var k = (1 + halfPi) * sin(phi);
for (var i = 0, delta = Infinity; i < 10 && abs(delta) > epsilon; i++) {
phi -= delta = (phi + sin(phi) - k) / (1 + cos(phi));
}
k = sqrt(2 + pi);
return [
lambda * (1 + cos(phi)) / k,
2 * phi / k
];
}
eckert6Raw.invert = function(x, y) {
var j = 1 + halfPi,
k = sqrt(j / 2);
return [
x * 2 * k / (1 + cos(y *= k)),
asin((y + sin(y)) / j)
];
};
var eckert6 = function() {
return d3Geo.geoProjection(eckert6Raw)
.scale(173.044);
};
var eisenlohrK = 3 + 2 * sqrt2;
function eisenlohrRaw(lambda, phi) {
var s0 = sin(lambda /= 2),
c0 = cos(lambda),
k = sqrt(cos(phi)),
c1 = cos(phi /= 2),
t = sin(phi) / (c1 + sqrt2 * c0 * k),
c = sqrt(2 / (1 + t * t)),
v = sqrt((sqrt2 * c1 + (c0 + s0) * k) / (sqrt2 * c1 + (c0 - s0) * k));
return [
eisenlohrK * (c * (v - 1 / v) - 2 * log(v)),
eisenlohrK * (c * t * (v + 1 / v) - 2 * atan(t))
];
}
eisenlohrRaw.invert = function(x, y) {
if (!(p = augustRaw.invert(x / 1.2, y * 1.065))) return null;
var lambda = p[0], phi = p[1], i = 20, p;
x /= eisenlohrK, y /= eisenlohrK;
do {
var _0 = lambda / 2,
_1 = phi / 2,
s0 = sin(_0),
c0 = cos(_0),
s1 = sin(_1),
c1 = cos(_1),
cos1 = cos(phi),
k = sqrt(cos1),
t = s1 / (c1 + sqrt2 * c0 * k),
t2 = t * t,
c = sqrt(2 / (1 + t2)),
v0 = (sqrt2 * c1 + (c0 + s0) * k),
v1 = (sqrt2 * c1 + (c0 - s0) * k),
v2 = v0 / v1,
v = sqrt(v2),
vm1v = v - 1 / v,
vp1v = v + 1 / v,
fx = c * vm1v - 2 * log(v) - x,
fy = c * t * vp1v - 2 * atan(t) - y,
deltatDeltaLambda = s1 && sqrt1_2 * k * s0 * t2 / s1,
deltatDeltaPhi = (sqrt2 * c0 * c1 + k) / (2 * (c1 + sqrt2 * c0 * k) * (c1 + sqrt2 * c0 * k) * k),
deltacDeltat = -0.5 * t * c * c * c,
deltacDeltaLambda = deltacDeltat * deltatDeltaLambda,
deltacDeltaPhi = deltacDeltat * deltatDeltaPhi,
A = (A = 2 * c1 + sqrt2 * k * (c0 - s0)) * A * v,
deltavDeltaLambda = (sqrt2 * c0 * c1 * k + cos1) / A,
deltavDeltaPhi = -(sqrt2 * s0 * s1) / (k * A),
deltaxDeltaLambda = vm1v * deltacDeltaLambda - 2 * deltavDeltaLambda / v + c * (deltavDeltaLambda + deltavDeltaLambda / v2),
deltaxDeltaPhi = vm1v * deltacDeltaPhi - 2 * deltavDeltaPhi / v + c * (deltavDeltaPhi + deltavDeltaPhi / v2),
deltayDeltaLambda = t * vp1v * deltacDeltaLambda - 2 * deltatDeltaLambda / (1 + t2) + c * vp1v * deltatDeltaLambda + c * t * (deltavDeltaLambda - deltavDeltaLambda / v2),
deltayDeltaPhi = t * vp1v * deltacDeltaPhi - 2 * deltatDeltaPhi / (1 + t2) + c * vp1v * deltatDeltaPhi + c * t * (deltavDeltaPhi - deltavDeltaPhi / v2),
denominator = deltaxDeltaPhi * deltayDeltaLambda - deltayDeltaPhi * deltaxDeltaLambda;
if (!denominator) break;
var deltaLambda = (fy * deltaxDeltaPhi - fx * deltayDeltaPhi) / denominator,
deltaPhi = (fx * deltayDeltaLambda - fy * deltaxDeltaLambda) / denominator;
lambda -= deltaLambda;
phi = max(-halfPi, min(halfPi, phi - deltaPhi));
} while ((abs(deltaLambda) > epsilon || abs(deltaPhi) > epsilon) && --i > 0);
return abs(abs(phi) - halfPi) < epsilon ? [0, phi] : i && [lambda, phi];
};
var eisenlohr = function() {
return d3Geo.geoProjection(eisenlohrRaw)
.scale(62.5271);
};
var faheyK = cos(35 * radians);
function faheyRaw(lambda, phi) {
var t = tan(phi / 2);
return [lambda * faheyK * sqrt(1 - t * t), (1 + faheyK) * t];
}
faheyRaw.invert = function(x, y) {
var t = y / (1 + faheyK);
return [x && x / (faheyK * sqrt(1 - t * t)), 2 * atan(t)];
};
var fahey = function() {
return d3Geo.geoProjection(faheyRaw)
.scale(137.152);
};
function foucautRaw(lambda, phi) {
var k = phi / 2, cosk = cos(k);
return [ 2 * lambda / sqrtPi * cos(phi) * cosk * cosk, sqrtPi * tan(k)];
}
foucautRaw.invert = function(x, y) {
var k = atan(y / sqrtPi), cosk = cos(k), phi = 2 * k;
return [x * sqrtPi / 2 / (cos(phi) * cosk * cosk), phi];
};
var foucaut = function() {
return d3Geo.geoProjection(foucautRaw)
.scale(135.264);
};
function gilbertForward(point) {
return [point[0] / 2, asin(tan(point[1] / 2 * radians)) * degrees];
}
function gilbertInvert(point) {
return [point[0] * 2, 2 * atan(sin(point[1] * radians)) * degrees];
}
var gilbert = function(projectionType) {
if (projectionType == null) projectionType = d3Geo.geoOrthographic;
var projection = projectionType(),
equirectangular = d3Geo.geoEquirectangular().scale(degrees).precision(0).clipAngle(null).translate([0, 0]); // antimeridian cutting
function gilbert(point) {
return projection(gilbertForward(point));
}
if (projection.invert) gilbert.invert = function(point) {
return gilbertInvert(projection.invert(point));
};
gilbert.stream = function(stream) {
var s1 = projection.stream(stream), s0 = equirectangular.stream({
point: function(lambda, phi) { s1.point(lambda / 2, asin(tan(-phi / 2 * radians)) * degrees); },
lineStart: function() { s1.lineStart(); },
lineEnd: function() { s1.lineEnd(); },
polygonStart: function() { s1.polygonStart(); },
polygonEnd: function() { s1.polygonEnd(); }
});
s0.sphere = s1.sphere;
return s0;
};
function property(name) {
gilbert[name] = function(_) {
return arguments.length ? (projection[name](_), gilbert) : projection[name]();
};
}
gilbert.rotate = function(_) {
return arguments.length ? (equirectangular.rotate(_), gilbert) : equirectangular.rotate();
};
gilbert.center = function(_) {
return arguments.length ? (projection.center(gilbertForward(_)), gilbert) : gilbertInvert(projection.center());
};
property("clipAngle");
property("clipExtent");
property("scale");
property("translate");
property("precision");
return gilbert
.scale(249.5);
};
function gingeryRaw(rho, n) {
var k = 2 * pi / n,
rho2 = rho * rho;
function forward(lambda, phi) {
var p = d3Geo.geoAzimuthalEquidistantRaw(lambda, phi),
x = p[0],
y = p[1],
r2 = x * x + y * y;
if (r2 > rho2) {
var r = sqrt(r2),
theta = atan2(y, x),
theta0 = k * round(theta / k),
alpha = theta - theta0,
rhoCosAlpha = rho * cos(alpha),
k_ = (rho * sin(alpha) - alpha * sin(rhoCosAlpha)) / (halfPi - rhoCosAlpha),
s_ = gingeryLength(alpha, k_),
e = (pi - rho) / gingeryIntegrate(s_, rhoCosAlpha, pi);
x = r;
var i = 50, delta;
do {
x -= delta = (rho + gingeryIntegrate(s_, rhoCosAlpha, x) * e - r) / (s_(x) * e);
} while (abs(delta) > epsilon && --i > 0);
y = alpha * sin(x);
if (x < halfPi) y -= k_ * (x - halfPi);
var s = sin(theta0),
c = cos(theta0);
p[0] = x * c - y * s;
p[1] = x * s + y * c;
}
return p;
}
forward.invert = function(x, y) {
var r2 = x * x + y * y;
if (r2 > rho2) {
var r = sqrt(r2),
theta = atan2(y, x),
theta0 = k * round(theta / k),
dTheta = theta - theta0;
x = r * cos(dTheta);
y = r * sin(dTheta);
var x_halfPi = x - halfPi,
sinx = sin(x),
alpha = y / sinx,
delta = x < halfPi ? Infinity : 0,
i = 10;
while (true) {
var rhosinAlpha = rho * sin(alpha),
rhoCosAlpha = rho * cos(alpha),
sinRhoCosAlpha = sin(rhoCosAlpha),
halfPi_RhoCosAlpha = halfPi - rhoCosAlpha,
k_ = (rhosinAlpha - alpha * sinRhoCosAlpha) / halfPi_RhoCosAlpha,
s_ = gingeryLength(alpha, k_);
if (abs(delta) < epsilon2 || !--i) break;
alpha -= delta = (alpha * sinx - k_ * x_halfPi - y) / (
sinx - x_halfPi * 2 * (
halfPi_RhoCosAlpha * (rhoCosAlpha + alpha * rhosinAlpha * cos(rhoCosAlpha) - sinRhoCosAlpha) -
rhosinAlpha * (rhosinAlpha - alpha * sinRhoCosAlpha)
) / (halfPi_RhoCosAlpha * halfPi_RhoCosAlpha));
}
r = rho + gingeryIntegrate(s_, rhoCosAlpha, x) * (pi - rho) / gingeryIntegrate(s_, rhoCosAlpha, pi);
theta = theta0 + alpha;
x = r * cos(theta);
y = r * sin(theta);
}
return d3Geo.geoAzimuthalEquidistantRaw.invert(x, y);
};
return forward;
}
function gingeryLength(alpha, k) {
return function(x) {
var y_ = alpha * cos(x);
if (x < halfPi) y_ -= k;
return sqrt(1 + y_ * y_);
};
}
// Numerical integration: trapezoidal rule.
function gingeryIntegrate(f, a, b) {
var n = 50,
h = (b - a) / n,
s = f(a) + f(b);
for (var i = 1, x = a; i < n; ++i) s += 2 * f(x += h);
return s * 0.5 * h;
}
var gingery = function() {
var n = 6,
rho = 30 * radians,
cRho = cos(rho),
sRho = sin(rho),
m = d3Geo.geoProjectionMutator(gingeryRaw),
p = m(rho, n),
stream_ = p.stream,
epsilon$$1 = 1e-2,
cr = -cos(epsilon$$1 * radians),
sr = sin(epsilon$$1 * radians);
p.radius = function(_) {
if (!arguments.length) return rho * degrees;
cRho = cos(rho = _ * radians);
sRho = sin(rho);
return m(rho, n);
};
p.lobes = function(_) {
if (!arguments.length) return n;
return m(rho, n = +_);
};
p.stream = function(stream) {
var rotate = p.rotate(),
rotateStream = stream_(stream),
sphereStream = (p.rotate([0, 0]), stream_(stream));
p.rotate(rotate);
rotateStream.sphere = function() {
sphereStream.polygonStart(), sphereStream.lineStart();
for (var i = 0, delta = 2 * pi / n, phi = 0; i < n; ++i, phi -= delta) {
sphereStream.point(atan2(sr * cos(phi), cr) * degrees, asin(sr * sin(phi)) * degrees);
sphereStream.point(atan2(sRho * cos(phi - delta / 2), cRho) * degrees, asin(sRho * sin(phi - delta / 2)) * degrees);
}
sphereStream.lineEnd(), sphereStream.polygonEnd();
};
return rotateStream;
};
return p
.rotate([90, -40])
.scale(91.7095)
.clipAngle(180 - 1e-3);
};
var ginzburgPolyconicRaw = function(a, b, c, d, e, f, g, h) {
if (arguments.length < 8) h = 0;
function forward(lambda, phi) {
if (!phi) return [a * lambda / pi, 0];
var phi2 = phi * phi,
xB = a + phi2 * (b + phi2 * (c + phi2 * d)),
yB = phi * (e - 1 + phi2 * (f - h + phi2 * g)),
m = (xB * xB + yB * yB) / (2 * yB),
alpha = lambda * asin(xB / m) / pi;
return [m * sin(alpha), phi * (1 + phi2 * h) + m * (1 - cos(alpha))];
}
forward.invert = function(x, y) {
var lambda = pi * x / a,
phi = y,
deltaLambda, deltaPhi, i = 50;
do {
var phi2 = phi * phi,
xB = a + phi2 * (b + phi2 * (c + phi2 * d)),
yB = phi * (e - 1 + phi2 * (f - h + phi2 * g)),
p = xB * xB + yB * yB,
q = 2 * yB,
m = p / q,
m2 = m * m,
dAlphadLambda = asin(xB / m) / pi,
alpha = lambda * dAlphadLambda,
xB2 = xB * xB,
dxBdPhi = (2 * b + phi2 * (4 * c + phi2 * 6 * d)) * phi,
dyBdPhi = e + phi2 * (3 * f + phi2 * 5 * g),
dpdPhi = 2 * (xB * dxBdPhi + yB * (dyBdPhi - 1)),
dqdPhi = 2 * (dyBdPhi - 1),
dmdPhi = (dpdPhi * q - p * dqdPhi) / (q * q),
cosAlpha = cos(alpha),
sinAlpha = sin(alpha),
mcosAlpha = m * cosAlpha,
msinAlpha = m * sinAlpha,
dAlphadPhi = ((lambda / pi) * (1 / sqrt(1 - xB2 / m2)) * (dxBdPhi * m - xB * dmdPhi)) / m2,
fx = msinAlpha - x,
fy = phi * (1 + phi2 * h) + m - mcosAlpha - y,
deltaxDeltaPhi = dmdPhi * sinAlpha + mcosAlpha * dAlphadPhi,
deltaxDeltaLambda = mcosAlpha * dAlphadLambda,
deltayDeltaPhi = 1 + dmdPhi - (dmdPhi * cosAlpha - msinAlpha * dAlphadPhi),
deltayDeltaLambda = msinAlpha * dAlphadLambda,
denominator = deltaxDeltaPhi * deltayDeltaLambda - deltayDeltaPhi * deltaxDeltaLambda;
if (!denominator) break;
lambda -= deltaLambda = (fy * deltaxDeltaPhi - fx * deltayDeltaPhi) / denominator;
phi -= deltaPhi = (fx * deltayDeltaLambda - fy * deltaxDeltaLambda) / denominator;
} while ((abs(deltaLambda) > epsilon || abs(deltaPhi) > epsilon) && --i > 0);
return [lambda, phi];
};
return forward;
};
var ginzburg4Raw = ginzburgPolyconicRaw(2.8284, -1.6988, 0.75432, -0.18071, 1.76003, -0.38914, 0.042555);
var ginzburg4 = function() {
return d3Geo.geoProjection(ginzburg4Raw)
.scale(149.995);
};
var ginzburg5Raw = ginzburgPolyconicRaw(2.583819, -0.835827, 0.170354, -0.038094, 1.543313, -0.411435,0.082742);
var ginzburg5 = function() {
return d3Geo.geoProjection(ginzburg5Raw)
.scale(153.93);
};
var ginzburg6Raw = ginzburgPolyconicRaw(5 / 6 * pi, -0.62636, -0.0344, 0, 1.3493, -0.05524, 0, 0.045);
var ginzburg6 = function() {
return d3Geo.geoProjection(ginzburg6Raw)
.scale(130.945);
};
function ginzburg8Raw(lambda, phi) {
var lambda2 = lambda * lambda,
phi2 = phi * phi;
return [
lambda * (1 - 0.162388 * phi2) * (0.87 - 0.000952426 * lambda2 * lambda2),
phi * (1 + phi2 / 12)
];
}
ginzburg8Raw.invert = function(x, y) {
var lambda = x,
phi = y,
i = 50, delta;
do {
var phi2 = phi * phi;
phi -= delta = (phi * (1 + phi2 / 12) - y) / (1 + phi2 / 4);
} while (abs(delta) > epsilon && --i > 0);
i = 50;
x /= 1 -0.162388 * phi2;
do {
var lambda4 = (lambda4 = lambda * lambda) * lambda4;
lambda -= delta = (lambda * (0.87 - 0.000952426 * lambda4) - x) / (0.87 - 0.00476213 * lambda4);
} while (abs(delta) > epsilon && --i > 0);
return [lambda, phi];
};
var ginzburg8 = function() {
return d3Geo.geoProjection(ginzburg8Raw)
.scale(131.747);
};
var ginzburg9Raw = ginzburgPolyconicRaw(2.6516, -0.76534, 0.19123, -0.047094, 1.36289, -0.13965,0.031762);
var ginzburg9 = function() {
return d3Geo.geoProjection(ginzburg9Raw)
.scale(131.087);
};
var squareRaw = function(project) {
var dx = project(halfPi, 0)[0] - project(-halfPi, 0)[0];
function projectSquare(lambda, phi) {
var s = lambda > 0 ? -0.5 : 0.5,
point = project(lambda + s * pi, phi);
point[0] -= s * dx;
return point;
}
if (project.invert) projectSquare.invert = function(x, y) {
var s = x > 0 ? -0.5 : 0.5,
location = project.invert(x + s * dx, y),
lambda = location[0] - s * pi;
if (lambda < -pi) lambda += 2 * pi;
else if (lambda > pi) lambda -= 2 * pi;
location[0] = lambda;
return location;
};
return projectSquare;
};
function gringortenRaw(lambda, phi) {
var sLambda = sign(lambda),
sPhi = sign(phi),
cosPhi = cos(phi),
x = cos(lambda) * cosPhi,
y = sin(lambda) * cosPhi,
z = sin(sPhi * phi);
lambda = abs(atan2(y, z));
phi = asin(x);
if (abs(lambda - halfPi) > epsilon) lambda %= halfPi;
var point = gringortenHexadecant(lambda > pi / 4 ? halfPi - lambda : lambda, phi);
if (lambda > pi / 4) z = point[0], point[0] = -point[1], point[1] = -z;
return (point[0] *= sLambda, point[1] *= -sPhi, point);
}
gringortenRaw.invert = function(x, y) {
if (abs(x) > 1) x = sign(x) * 2 - x;
if (abs(y) > 1) y = sign(y) * 2 - y;
var sx = sign(x),
sy = sign(y),
x0 = -sx * x,
y0 = -sy * y,
t = y0 / x0 < 1,
p = gringortenHexadecantInvert(t ? y0 : x0, t ? x0 : y0),
lambda = p[0],
phi = p[1],
cosPhi = cos(phi);
if (t) lambda = -halfPi - lambda;
return [sx * (atan2(sin(lambda) * cosPhi, -sin(phi)) + pi), sy * asin(cos(lambda) * cosPhi)];
};
function gringortenHexadecant(lambda, phi) {
if (phi === halfPi) return [0, 0];
var sinPhi = sin(phi),
r = sinPhi * sinPhi,
r2 = r * r,
j = 1 + r2,
k = 1 + 3 * r2,
q = 1 - r2,
z = asin(1 / sqrt(j)),
v = q + r * j * z,
p2 = (1 - sinPhi) / v,
p = sqrt(p2),
a2 = p2 * j,
a = sqrt(a2),
h = p * q,
x,
i;
if (lambda === 0) return [0, -(h + r * a)];
var cosPhi = cos(phi),
secPhi = 1 / cosPhi,
drdPhi = 2 * sinPhi * cosPhi,
dvdPhi = (-3 * r + z * k) * drdPhi,
dp2dPhi = (-v * cosPhi - (1 - sinPhi) * dvdPhi) / (v * v),
dpdPhi = (0.5 * dp2dPhi) / p,
dhdPhi = q * dpdPhi - 2 * r * p * drdPhi,
dra2dPhi = r * j * dp2dPhi + p2 * k * drdPhi,
mu = -secPhi * drdPhi,
nu = -secPhi * dra2dPhi,
zeta = -2 * secPhi * dhdPhi,
lambda1 = 4 * lambda / pi,
delta;
// Slower but accurate bisection method.
if (lambda > 0.222 * pi || phi < pi / 4 && lambda > 0.175 * pi) {
x = (h + r * sqrt(a2 * (1 + r2) - h * h)) / (1 + r2);
if (lambda > pi / 4) return [x, x];
var x1 = x, x0 = 0.5 * x;
x = 0.5 * (x0 + x1), i = 50;
do {
var g = sqrt(a2 - x * x),
f = (x * (zeta + mu * g) + nu * asin(x / a)) - lambda1;
if (!f) break;
if (f < 0) x0 = x;
else x1 = x;
x = 0.5 * (x0 + x1);
} while (abs(x1 - x0) > epsilon && --i > 0);
}
// Newton-Raphson.
else {
x = epsilon, i = 25;
do {
var x2 = x * x,
g2 = sqrt(a2 - x2),
zetaMug = zeta + mu * g2,
f2 = x * zetaMug + nu * asin(x / a) - lambda1,
df = zetaMug + (nu - mu * x2) / g2;
x -= delta = g2 ? f2 / df : 0;
} while (abs(delta) > epsilon && --i > 0);
}
return [x, -h - r * sqrt(a2 - x * x)];
}
function gringortenHexadecantInvert(x, y) {
var x0 = 0,
x1 = 1,
r = 0.5,
i = 50;
while (true) {
var r2 = r * r,
sinPhi = sqrt(r),
z = asin(1 / sqrt(1 + r2)),
v = (1 - r2) + r * (1 + r2) * z,
p2 = (1 - sinPhi) / v,
p = sqrt(p2),
a2 = p2 * (1 + r2),
h = p * (1 - r2),
g2 = a2 - x * x,
g = sqrt(g2),
y0 = y + h + r * g;
if (abs(x1 - x0) < epsilon2 || --i === 0 || y0 === 0) break;
if (y0 > 0) x0 = r;
else x1 = r;
r = 0.5 * (x0 + x1);
}
if (!i) return null;
var phi = asin(sinPhi),
cosPhi = cos(phi),
secPhi = 1 / cosPhi,
drdPhi = 2 * sinPhi * cosPhi,
dvdPhi = (-3 * r + z * (1 + 3 * r2)) * drdPhi,
dp2dPhi = (-v * cosPhi - (1 - sinPhi) * dvdPhi) / (v * v),
dpdPhi = 0.5 * dp2dPhi / p,
dhdPhi = (1 - r2) * dpdPhi - 2 * r * p * drdPhi,
zeta = -2 * secPhi * dhdPhi,
mu = -secPhi * drdPhi,
nu = -secPhi * (r * (1 + r2) * dp2dPhi + p2 * (1 + 3 * r2) * drdPhi);
return [pi / 4 * (x * (zeta + mu * g) + nu * asin(x / sqrt(a2))), phi];
}
var gringorten = function() {
return d3Geo.geoProjection(squareRaw(gringortenRaw))
.scale(239.75);
};
// Returns [sn, cn, dn](u + iv|m).
function ellipticJi(u, v, m) {
var a, b, c;
if (!u) {
b = ellipticJ(v, 1 - m);
return [
[0, b[0] / b[1]],
[1 / b[1], 0],
[b[2] / b[1], 0]
];
}
a = ellipticJ(u, m);
if (!v) return [[a[0], 0], [a[1], 0], [a[2], 0]];
b = ellipticJ(v, 1 - m);
c = b[1] * b[1] + m * a[0] * a[0] * b[0] * b[0];
return [
[a[0] * b[2] / c, a[1] * a[2] * b[0] * b[1] / c],
[a[1] * b[1] / c, -a[0] * a[2] * b[0] * b[2] / c],
[a[2] * b[1] * b[2] / c, -m * a[0] * a[1] * b[0] / c]
];
}
// Returns [sn, cn, dn, ph](u|m).
function ellipticJ(u, m) {
var ai, b, phi, t, twon;
if (m < epsilon) {
t = sin(u);
b = cos(u);
ai = m * (u - t * b) / 4;
return [
t - ai * b,
b + ai * t,
1 - m * t * t / 2,
u - ai
];
}
if (m >= 1 - epsilon) {
ai = (1 - m) / 4;
b = cosh(u);
t = tanh(u);
phi = 1 / b;
twon = b * sinh(u);
return [
t + ai * (twon - u) / (b * b),
phi - ai * t * phi * (twon - u),
phi + ai * t * phi * (twon + u),
2 * atan(exp(u)) - halfPi + ai * (twon - u) / b
];
}
var a = [1, 0, 0, 0, 0, 0, 0, 0, 0],
c = [sqrt(m), 0, 0, 0, 0, 0, 0, 0, 0],
i = 0;
b = sqrt(1 - m);
twon = 1;
while (abs(c[i] / a[i]) > epsilon && i < 8) {
ai = a[i++];
c[i] = (ai - b) / 2;
a[i] = (ai + b) / 2;
b = sqrt(ai * b);
twon *= 2;
}
phi = twon * a[i] * u;
do {
t = c[i] * sin(b = phi) / a[i];
phi = (asin(t) + phi) / 2;
} while (--i);
return [sin(phi), t = cos(phi), t / cos(phi - b), phi];
}
// Calculate F(phi+iPsi|m).
// See Abramowitz and Stegun, 17.4.11.
function ellipticFi(phi, psi, m) {
var r = abs(phi),
i = abs(psi),
sinhPsi = sinh(i);
if (r) {
var cscPhi = 1 / sin(r),
cotPhi2 = 1 / (tan(r) * tan(r)),
b = -(cotPhi2 + m * (sinhPsi * sinhPsi * cscPhi * cscPhi) - 1 + m),
c = (m - 1) * cotPhi2,
cotLambda2 = (-b + sqrt(b * b - 4 * c)) / 2;
return [
ellipticF(atan(1 / sqrt(cotLambda2)), m) * sign(phi),
ellipticF(atan(sqrt((cotLambda2 / cotPhi2 - 1) / m)), 1 - m) * sign(psi)
];
}
return [
0,
ellipticF(atan(sinhPsi), 1 - m) * sign(psi)
];
}
// Calculate F(phi|m) where m = k² = sin²α.
// See Abramowitz and Stegun, 17.6.7.
function ellipticF(phi, m) {
if (!m) return phi;
if (m === 1) return log(tan(phi / 2 + quarterPi));
var a = 1,
b = sqrt(1 - m),
c = sqrt(m);
for (var i = 0; abs(c) > epsilon; i++) {
if (phi % pi) {
var dPhi = atan(b * tan(phi) / a);
if (dPhi < 0) dPhi += pi;
phi += dPhi + ~~(phi / pi) * pi;
} else phi += phi;
c = (a + b) / 2;
b = sqrt(a * b);
c = ((a = c) - b) / 2;
}
return phi / (pow(2, i) * a);
}
function guyouRaw(lambda, phi) {
var k_ = (sqrt2 - 1) / (sqrt2 + 1),
k = sqrt(1 - k_ * k_),
K = ellipticF(halfPi, k * k),
f = -1,
psi = log(tan(pi / 4 + abs(phi) / 2)),
r = exp(f * psi) / sqrt(k_),
at = guyouComplexAtan(r * cos(f * lambda), r * sin(f * lambda)),
t = ellipticFi(at[0], at[1], k * k);
return [-t[1], (phi >= 0 ? 1 : -1) * (0.5 * K - t[0])];
}
function guyouComplexAtan(x, y) {
var x2 = x * x,
y_1 = y + 1,
t = 1 - x2 - y * y;
return [
0.5 * ((x >= 0 ? halfPi : -halfPi) - atan2(t, 2 * x)),
-0.25 * log(t * t + 4 * x2) +0.5 * log(y_1 * y_1 + x2)
];
}
function guyouComplexDivide(a, b) {
var denominator = b[0] * b[0] + b[1] * b[1];
return [
(a[0] * b[0] + a[1] * b[1]) / denominator,
(a[1] * b[0] - a[0] * b[1]) / denominator
];
}
guyouRaw.invert = function(x, y) {
var k_ = (sqrt2 - 1) / (sqrt2 + 1),
k = sqrt(1 - k_ * k_),
K = ellipticF(halfPi, k * k),
f = -1,
j = ellipticJi(0.5 * K - y, -x, k * k),
tn = guyouComplexDivide(j[0], j[1]),
lambda = atan2(tn[1], tn[0]) / f;
return [
lambda,
2 * atan(exp(0.5 / f * log(k_ * tn[0] * tn[0] + k_ * tn[1] * tn[1]))) - halfPi
];
};
var guyou = function() {
return d3Geo.geoProjection(squareRaw(guyouRaw))
.scale(151.496);
};
function hammerRetroazimuthalRaw(phi0) {
var sinPhi0 = sin(phi0),
cosPhi0 = cos(phi0),
rotate = hammerRetroazimuthalRotation(phi0);
rotate.invert = hammerRetroazimuthalRotation(-phi0);
function forward(lambda, phi) {
var p = rotate(lambda, phi);
lambda = p[0], phi = p[1];
var sinPhi = sin(phi),
cosPhi = cos(phi),
cosLambda = cos(lambda),
z = acos(sinPhi0 * sinPhi + cosPhi0 * cosPhi * cosLambda),
sinz = sin(z),
K = abs(sinz) > epsilon ? z / sinz : 1;
return [
K * cosPhi0 * sin(lambda),
(abs(lambda) > halfPi ? K : -K) // rotate for back hemisphere
* (sinPhi0 * cosPhi - cosPhi0 * sinPhi * cosLambda)
];
}
forward.invert = function(x, y) {
var rho = sqrt(x * x + y * y),
sinz = -sin(rho),
cosz = cos(rho),
a = rho * cosz,
b = -y * sinz,
c = rho * sinPhi0,
d = sqrt(a * a + b * b - c * c),
phi = atan2(a * c + b * d, b * c - a * d),
lambda = (rho > halfPi ? -1 : 1) * atan2(x * sinz, rho * cos(phi) * cosz + y * sin(phi) * sinz);
return rotate.invert(lambda, phi);
};
return forward;
}
// Latitudinal rotation by phi0.
// Temporary hack until D3 supports arbitrary small-circle clipping origins.
function hammerRetroazimuthalRotation(phi0) {
var sinPhi0 = sin(phi0),
cosPhi0 = cos(phi0);
return function(lambda, phi) {
var cosPhi = cos(phi),
x = cos(lambda) * cosPhi,
y = sin(lambda) * cosPhi,
z = sin(phi);
return [
atan2(y, x * cosPhi0 - z * sinPhi0),
asin(z * cosPhi0 + x * sinPhi0)
];
};
}
var hammerRetroazimuthal = function() {
var phi0 = 0,
m = d3Geo.geoProjectionMutator(hammerRetroazimuthalRaw),
p = m(phi0),
rotate_ = p.rotate,
stream_ = p.stream,
circle = d3Geo.geoCircle();
p.parallel = function(_) {
if (!arguments.length) return phi0 * degrees;
var r = p.rotate();
return m(phi0 = _ * radians).rotate(r);
};
// Temporary hack; see hammerRetroazimuthalRotation.
p.rotate = function(_) {
if (!arguments.length) return (_ = rotate_.call(p), _[1] += phi0 * degrees, _);
rotate_.call(p, [_[0], _[1] - phi0 * degrees]);
circle.center([-_[0], -_[1]]);
return p;
};
p.stream = function(stream) {
stream = stream_(stream);
stream.sphere = function() {
stream.polygonStart();
var epsilon$$1 = 1e-2,
ring = circle.radius(90 - epsilon$$1)().coordinates[0],
n = ring.length - 1,
i = -1,
p;
stream.lineStart();
while (++i < n) stream.point((p = ring[i])[0], p[1]);
stream.lineEnd();
ring = circle.radius(90 + epsilon$$1)().coordinates[0];
n = ring.length - 1;
stream.lineStart();
while (--i >= 0) stream.point((p = ring[i])[0], p[1]);
stream.lineEnd();
stream.polygonEnd();
};
return stream;
};
return p
.scale(79.4187)
.parallel(45)
.clipAngle(180 - 1e-3);
};
var healpixParallel = 41 + 48 / 36 + 37 / 3600;
var healpixLambert = cylindricalEqualAreaRaw(0);
function healpixRaw(H) {
var phi0 = healpixParallel * radians,
dx = collignonRaw(pi, phi0)[0] - collignonRaw(-pi, phi0)[0],
y0 = healpixLambert(0, phi0)[1],
y1 = collignonRaw(0, phi0)[1],
dy1 = sqrtPi - y1,
k = tau / H,
w = 4 / tau,
h = y0 + (dy1 * dy1 * 4) / tau;
function forward(lambda, phi) {
var point,
phi2 = abs(phi);
if (phi2 > phi0) {
var i = min(H - 1, max(0, floor((lambda + pi) / k)));
lambda += pi * (H - 1) / H - i * k;
point = collignonRaw(lambda, phi2);
point[0] = point[0] * tau / dx - tau * (H - 1) / (2 * H) + i * tau / H;
point[1] = y0 + (point[1] - y1) * 4 * dy1 / tau;
if (phi < 0) point[1] = -point[1];
} else {
point = healpixLambert(lambda, phi);
}
point[0] *= w, point[1] /= h;
return point;
}
forward.invert = function(x, y) {
x /= w, y *= h;
var y2 = abs(y);
if (y2 > y0) {
var i = min(H - 1, max(0, floor((x + pi) / k)));
x = (x + pi * (H - 1) / H - i * k) * dx / tau;
var point = collignonRaw.invert(x, 0.25 * (y2 - y0) * tau / dy1 + y1);
point[0] -= pi * (H - 1) / H - i * k;
if (y < 0) point[1] = -point[1];
return point;
}
return healpixLambert.invert(x, y);
};
return forward;
}
function sphere(step) {
return {
type: "Polygon",
coordinates: [
d3Array.range(-180, 180 + step / 2, step).map(function(x, i) { return [x, i & 1 ? 90 - 1e-6 : healpixParallel]; })
.concat(d3Array.range(180, -180 - step / 2, -step).map(function(x, i) { return [x, i & 1 ? -90 + 1e-6 : -healpixParallel]; }))
]
};
}
var healpix = function() {
var H = 4,
m = d3Geo.geoProjectionMutator(healpixRaw),
p = m(H),
stream_ = p.stream;
p.lobes = function(_) {
return arguments.length ? m(H = +_) : H;
};
p.stream = function(stream) {
var rotate = p.rotate(),
rotateStream = stream_(stream),
sphereStream = (p.rotate([0, 0]), stream_(stream));
p.rotate(rotate);
rotateStream.sphere = function() { d3Geo.geoStream(sphere(180 / H), sphereStream); };
return rotateStream;
};
return p
.scale(239.75);
};
function hillRaw(K) {
var L = 1 + K,
sinBt = sin(1 / L),
Bt = asin(sinBt),
A = 2 * sqrt(pi / (B = pi + 4 * Bt * L)),
B,
rho0 = 0.5 * A * (L + sqrt(K * (2 + K))),
K2 = K * K,
L2 = L * L;
function forward(lambda, phi) {
var t = 1 - sin(phi),
rho,
omega;
if (t && t < 2) {
var theta = halfPi - phi, i = 25, delta;
do {
var sinTheta = sin(theta),
cosTheta = cos(theta),
Bt_Bt1 = Bt + atan2(sinTheta, L - cosTheta),
C = 1 + L2 - 2 * L * cosTheta;
theta -= delta = (theta - K2 * Bt - L * sinTheta + C * Bt_Bt1 -0.5 * t * B) / (2 * L * sinTheta * Bt_Bt1);
} while (abs(delta) > epsilon2 && --i > 0);
rho = A * sqrt(C);
omega = lambda * Bt_Bt1 / pi;
} else {
rho = A * (K + t);
omega = lambda * Bt / pi;
}
return [
rho * sin(omega),
rho0 - rho * cos(omega)
];
}
forward.invert = function(x, y) {
var rho2 = x * x + (y -= rho0) * y,
cosTheta = (1 + L2 - rho2 / (A * A)) / (2 * L),
theta = acos(cosTheta),
sinTheta = sin(theta),
Bt_Bt1 = Bt + atan2(sinTheta, L - cosTheta);
return [
asin(x / sqrt(rho2)) * pi / Bt_Bt1,
asin(1 - 2 * (theta - K2 * Bt - L * sinTheta + (1 + L2 - 2 * L * cosTheta) * Bt_Bt1) / B)
];
};
return forward;
}
var hill = function() {
var K = 1,
m = d3Geo.geoProjectionMutator(hillRaw),
p = m(K);
p.ratio = function(_) {
return arguments.length ? m(K = +_) : K;
};
return p
.scale(167.774)
.center([0, 18.67]);
};
var sinuMollweidePhi = 0.7109889596207567;
var sinuMollweideY = 0.0528035274542;
function sinuMollweideRaw(lambda, phi) {
return phi > -sinuMollweidePhi
? (lambda = mollweideRaw(lambda, phi), lambda[1] += sinuMollweideY, lambda)
: sinusoidalRaw(lambda, phi);
}
sinuMollweideRaw.invert = function(x, y) {
return y > -sinuMollweidePhi
? mollweideRaw.invert(x, y - sinuMollweideY)
: sinusoidalRaw.invert(x, y);
};
var sinuMollweide = function() {
return d3Geo.geoProjection(sinuMollweideRaw)
.rotate([-20, -55])
.scale(164.263)
.center([0, -5.4036]);
};
function homolosineRaw(lambda, phi) {
return abs(phi) > sinuMollweidePhi
? (lambda = mollweideRaw(lambda, phi), lambda[1] -= phi > 0 ? sinuMollweideY : -sinuMollweideY, lambda)
: sinusoidalRaw(lambda, phi);
}
homolosineRaw.invert = function(x, y) {
return abs(y) > sinuMollweidePhi
? mollweideRaw.invert(x, y + (y > 0 ? sinuMollweideY : -sinuMollweideY))
: sinusoidalRaw.invert(x, y);
};
var homolosine = function() {
return d3Geo.geoProjection(homolosineRaw)
.scale(152.63);
};
function pointEqual(a, b) {
return abs(a[0] - b[0]) < epsilon && abs(a[1] - b[1]) < epsilon;
}
function interpolateLine(coordinates, m) {
var i = -1,
n = coordinates.length,
p0 = coordinates[0],
p1,
dx,
dy,
resampled = [];
while (++i < n) {
p1 = coordinates[i];
dx = (p1[0] - p0[0]) / m;
dy = (p1[1] - p0[1]) / m;
for (var j = 0; j < m; ++j) resampled.push([p0[0] + j * dx, p0[1] + j * dy]);
p0 = p1;
}
resampled.push(p1);
return resampled;
}
function interpolateSphere(lobes) {
var coordinates = [],
lobe,
lambda0, phi0, phi1,
lambda2, phi2,
i, n = lobes[0].length;
// Northern Hemisphere
for (i = 0; i < n; ++i) {
lobe = lobes[0][i];
lambda0 = lobe[0][0], phi0 = lobe[0][1], phi1 = lobe[1][1];
lambda2 = lobe[2][0], phi2 = lobe[2][1];
coordinates.push(interpolateLine([
[lambda0 + epsilon, phi0 + epsilon],
[lambda0 + epsilon, phi1 - epsilon],
[lambda2 - epsilon, phi1 - epsilon],
[lambda2 - epsilon, phi2 + epsilon]
], 30));
}
// Southern Hemisphere
for (i = lobes[1].length - 1; i >= 0; --i) {
lobe = lobes[1][i];
lambda0 = lobe[0][0], phi0 = lobe[0][1], phi1 = lobe[1][1];
lambda2 = lobe[2][0], phi2 = lobe[2][1];
coordinates.push(interpolateLine([
[lambda2 - epsilon, phi2 - epsilon],
[lambda2 - epsilon, phi1 + epsilon],
[lambda0 + epsilon, phi1 + epsilon],
[lambda0 + epsilon, phi0 - epsilon]
], 30));
}
return {
type: "Polygon",
coordinates: [d3Array.merge(coordinates)]
};
}
var interrupt = function(project, lobes) {
var sphere, bounds;
function forward(lambda, phi) {
var sign$$1 = phi < 0 ? -1 : +1, lobe = lobes[+(phi < 0)];
for (var i = 0, n = lobe.length - 1; i < n && lambda > lobe[i][2][0]; ++i);
var p = project(lambda - lobe[i][1][0], phi);
p[0] += project(lobe[i][1][0], sign$$1 * phi > sign$$1 * lobe[i][0][1] ? lobe[i][0][1] : phi)[0];
return p;
}
// Assumes mutually exclusive bounding boxes for lobes.
if (project.invert) forward.invert = function(x, y) {
var bound = bounds[+(y < 0)], lobe = lobes[+(y < 0)];
for (var i = 0, n = bound.length; i < n; ++i) {
var b = bound[i];
if (b[0][0] <= x && x < b[1][0] && b[0][1] <= y && y < b[1][1]) {
var p = project.invert(x - project(lobe[i][1][0], 0)[0], y);
p[0] += lobe[i][1][0];
return pointEqual(forward(p[0], p[1]), [x, y]) ? p : null;
}
}
};
var p = d3Geo.geoProjection(forward),
stream_ = p.stream;
p.stream = function(stream) {
var rotate = p.rotate(),
rotateStream = stream_(stream),
sphereStream = (p.rotate([0, 0]), stream_(stream));
p.rotate(rotate);
rotateStream.sphere = function() { d3Geo.geoStream(sphere, sphereStream); };
return rotateStream;
};
p.lobes = function(_) {
if (!arguments.length) return lobes.map(function(lobe) {
return lobe.map(function(l) {
return [
[l[0][0] * degrees, l[0][1] * degrees],
[l[1][0] * degrees, l[1][1] * degrees],
[l[2][0] * degrees, l[2][1] * degrees]
];
});
});
sphere = interpolateSphere(_);
lobes = _.map(function(lobe) {
return lobe.map(function(l) {
return [
[l[0][0] * radians, l[0][1] * radians],
[l[1][0] * radians, l[1][1] * radians],
[l[2][0] * radians, l[2][1] * radians]
];
});
});
bounds = lobes.map(function(lobe) {
return lobe.map(function(l) {
var x0 = project(l[0][0], l[0][1])[0],
x1 = project(l[2][0], l[2][1])[0],
y0 = project(l[1][0], l[0][1])[1],
y1 = project(l[1][0], l[1][1])[1],
t;
if (y0 > y1) t = y0, y0 = y1, y1 = t;
return [[x0, y0], [x1, y1]];
});
});
return p;
};
if (lobes != null) p.lobes(lobes);
return p;
};
var lobes = [[ // northern hemisphere
[[-180, 0], [-100, 90], [ -40, 0]],
[[ -40, 0], [ 30, 90], [ 180, 0]]
], [ // southern hemisphere
[[-180, 0], [-160, -90], [-100, 0]],
[[-100, 0], [ -60, -90], [ -20, 0]],
[[ -20, 0], [ 20, -90], [ 80, 0]],
[[ 80, 0], [ 140, -90], [ 180, 0]]
]];
var boggs$1 = function() {
return interrupt(boggsRaw, lobes)
.scale(160.857);
};
var lobes$1 = [[ // northern hemisphere
[[-180, 0], [-100, 90], [ -40, 0]],
[[ -40, 0], [ 30, 90], [ 180, 0]]
], [ // southern hemisphere
[[-180, 0], [-160, -90], [-100, 0]],
[[-100, 0], [ -60, -90], [ -20, 0]],
[[ -20, 0], [ 20, -90], [ 80, 0]],
[[ 80, 0], [ 140, -90], [ 180, 0]]
]];
var homolosine$1 = function() {
return interrupt(homolosineRaw, lobes$1)
.scale(152.63);
};
var lobes$2 = [[ // northern hemisphere
[[-180, 0], [-100, 90], [ -40, 0]],
[[ -40, 0], [ 30, 90], [ 180, 0]]
], [ // southern hemisphere
[[-180, 0], [-160, -90], [-100, 0]],
[[-100, 0], [ -60, -90], [ -20, 0]],
[[ -20, 0], [ 20, -90], [ 80, 0]],
[[ 80, 0], [ 140, -90], [ 180, 0]]
]];
var mollweide$1 = function() {
return interrupt(mollweideRaw, lobes$2)
.scale(169.529);
};
var lobes$3 = [[ // northern hemisphere
[[-180, 0], [ -90, 90], [ 0, 0]],
[[ 0, 0], [ 90, 90], [ 180, 0]]
], [ // southern hemisphere
[[-180, 0], [ -90, -90], [ 0, 0]],
[[ 0, 0], [ 90, -90], [ 180, 0]]
]];
var mollweideHemispheres = function() {
return interrupt(mollweideRaw, lobes$3)
.scale(169.529)
.rotate([20, 0]);
};
var lobes$4 = [[ // northern hemisphere
[[-180, 35], [ -30, 90], [ 0, 35]],
[[ 0, 35], [ 30, 90], [ 180, 35]]
], [ // southern hemisphere
[[-180, -10], [-102, -90], [ -65, -10]],
[[ -65, -10], [ 5, -90], [ 77, -10]],
[[ 77, -10], [ 103, -90], [ 180, -10]]
]];
var sinuMollweide$1 = function() {
return interrupt(sinuMollweideRaw, lobes$4)
.rotate([-20, -55])
.scale(164.263)
.center([0, -5.4036]);
};
var lobes$5 = [[ // northern hemisphere
[[-180, 0], [-110, 90], [ -40, 0]],
[[ -40, 0], [ 0, 90], [ 40, 0]],
[[ 40, 0], [ 110, 90], [ 180, 0]]
], [ // southern hemisphere
[[-180, 0], [-110, -90], [ -40, 0]],
[[ -40, 0], [ 0, -90], [ 40, 0]],
[[ 40, 0], [ 110, -90], [ 180, 0]]
]];
var sinusoidal$1 = function() {
return interrupt(sinusoidalRaw, lobes$5)
.scale(152.63)
.rotate([-20, 0]);
};
function kavrayskiy7Raw(lambda, phi) {
return [3 / tau * lambda * sqrt(pi * pi / 3 - phi * phi), phi];
}
kavrayskiy7Raw.invert = function(x, y) {
return [tau / 3 * x / sqrt(pi * pi / 3 - y * y), y];
};
var kavrayskiy7 = function() {
return d3Geo.geoProjection(kavrayskiy7Raw)
.scale(158.837);
};
function lagrangeRaw(n) {
function forward(lambda, phi) {
if (abs(abs(phi) - halfPi) < epsilon) return [0, phi < 0 ? -2 : 2];
var sinPhi = sin(phi),
v = pow((1 + sinPhi) / (1 - sinPhi), n / 2),
c = 0.5 * (v + 1 / v) + cos(lambda *= n);
return [
2 * sin(lambda) / c,
(v - 1 / v) / c
];
}
forward.invert = function(x, y) {
var y0 = abs(y);
if (abs(y0 - 2) < epsilon) return x ? null : [0, sign(y) * halfPi];
if (y0 > 2) return null;
x /= 2, y /= 2;
var x2 = x * x,
y2 = y * y,
t = 2 * y / (1 + x2 + y2); // tanh(nPhi)
t = pow((1 + t) / (1 - t), 1 / n);
return [
atan2(2 * x, 1 - x2 - y2) / n,
asin((t - 1) / (t + 1))
];
};
return forward;
}
var lagrange = function() {
var n = 0.5,
m = d3Geo.geoProjectionMutator(lagrangeRaw),
p = m(n);
p.spacing = function(_) {
return arguments.length ? m(n = +_) : n;
};
return p
.scale(124.75);
};
var pi_sqrt2 = pi / sqrt2;
function larriveeRaw(lambda, phi) {
return [
lambda * (1 + sqrt(cos(phi))) / 2,
phi / (cos(phi / 2) * cos(lambda / 6))
];
}
larriveeRaw.invert = function(x, y) {
var x0 = abs(x),
y0 = abs(y),
lambda = epsilon,
phi = halfPi;
if (y0 < pi_sqrt2) phi *= y0 / pi_sqrt2;
else lambda += 6 * acos(pi_sqrt2 / y0);
for (var i = 0; i < 25; i++) {
var sinPhi = sin(phi),
sqrtcosPhi = sqrt(cos(phi)),
sinPhi_2 = sin(phi / 2),
cosPhi_2 = cos(phi / 2),
sinLambda_6 = sin(lambda / 6),
cosLambda_6 = cos(lambda / 6),
f0 = 0.5 * lambda * (1 + sqrtcosPhi) - x0,
f1 = phi / (cosPhi_2 * cosLambda_6) - y0,
df0dPhi = sqrtcosPhi ? -0.25 * lambda * sinPhi / sqrtcosPhi : 0,
df0dLambda = 0.5 * (1 + sqrtcosPhi),
df1dPhi = (1 +0.5 * phi * sinPhi_2 / cosPhi_2) / (cosPhi_2 * cosLambda_6),
df1dLambda = (phi / cosPhi_2) * (sinLambda_6 / 6) / (cosLambda_6 * cosLambda_6),
denom = df0dPhi * df1dLambda - df1dPhi * df0dLambda,
dPhi = (f0 * df1dLambda - f1 * df0dLambda) / denom,
dLambda = (f1 * df0dPhi - f0 * df1dPhi) / denom;
phi -= dPhi;
lambda -= dLambda;
if (abs(dPhi) < epsilon && abs(dLambda) < epsilon) break;
}
return [x < 0 ? -lambda : lambda, y < 0 ? -phi : phi];
};
var larrivee = function() {
return d3Geo.geoProjection(larriveeRaw)
.scale(97.2672);
};
function laskowskiRaw(lambda, phi) {
var lambda2 = lambda * lambda, phi2 = phi * phi;
return [
lambda * (0.975534 + phi2 * (-0.119161 + lambda2 * -0.0143059 + phi2 * -0.0547009)),
phi * (1.00384 + lambda2 * (0.0802894 + phi2 * -0.02855 + lambda2 * 0.000199025) + phi2 * (0.0998909 + phi2 * -0.0491032))
];
}
laskowskiRaw.invert = function(x, y) {
var lambda = sign(x) * pi,
phi = y / 2,
i = 50;
do {
var lambda2 = lambda * lambda,
phi2 = phi * phi,
lambdaPhi = lambda * phi,
fx = lambda * (0.975534 + phi2 * (-0.119161 + lambda2 * -0.0143059 + phi2 * -0.0547009)) - x,
fy = phi * (1.00384 + lambda2 * (0.0802894 + phi2 * -0.02855 + lambda2 * 0.000199025) + phi2 * (0.0998909 + phi2 * -0.0491032)) - y,
deltaxDeltaLambda = 0.975534 - phi2 * (0.119161 + 3 * lambda2 * 0.0143059 + phi2 * 0.0547009),
deltaxDeltaPhi = -lambdaPhi * (2 * 0.119161 + 4 * 0.0547009 * phi2 + 2 * 0.0143059 * lambda2),
deltayDeltaLambda = lambdaPhi * (2 * 0.0802894 + 4 * 0.000199025 * lambda2 + 2 * -0.02855 * phi2),
deltayDeltaPhi = 1.00384 + lambda2 * (0.0802894 + 0.000199025 * lambda2) + phi2 * (3 * (0.0998909 - 0.02855 * lambda2) - 5 * 0.0491032 * phi2),
denominator = deltaxDeltaPhi * deltayDeltaLambda - deltayDeltaPhi * deltaxDeltaLambda,
deltaLambda = (fy * deltaxDeltaPhi - fx * deltayDeltaPhi) / denominator,
deltaPhi = (fx * deltayDeltaLambda - fy * deltaxDeltaLambda) / denominator;
lambda -= deltaLambda, phi -= deltaPhi;
} while ((abs(deltaLambda) > epsilon || abs(deltaPhi) > epsilon) && --i > 0);
return i && [lambda, phi];
};
var laskowski = function() {
return d3Geo.geoProjection(laskowskiRaw)
.scale(139.98);
};
function littrowRaw(lambda, phi) {
return [
sin(lambda) / cos(phi),
tan(phi) * cos(lambda)
];
}
littrowRaw.invert = function(x, y) {
var x2 = x * x,
y2 = y * y,
y2_1 = y2 + 1,
x2_y2_1 = x2 + y2_1,
cosPhi = x
? sqrt1_2 * sqrt((x2_y2_1 - sqrt(x2_y2_1 * x2_y2_1 - 4 * x2)) / x2)
: 1 / sqrt(y2_1);
return [
asin(x * cosPhi),
sign(y) * acos(cosPhi)
];
};
var littrow = function() {
return d3Geo.geoProjection(littrowRaw)
.scale(144.049)
.clipAngle(90 - 1e-3);
};
function loximuthalRaw(phi0) {
var cosPhi0 = cos(phi0),
tanPhi0 = tan(quarterPi + phi0 / 2);
function forward(lambda, phi) {
var y = phi - phi0,
x = abs(y) < epsilon ? lambda * cosPhi0
: abs(x = quarterPi + phi / 2) < epsilon || abs(abs(x) - halfPi) < epsilon
? 0 : lambda * y / log(tan(x) / tanPhi0);
return [x, y];
}
forward.invert = function(x, y) {
var lambda,
phi = y + phi0;
return [
abs(y) < epsilon ? x / cosPhi0
: (abs(lambda = quarterPi + phi / 2) < epsilon || abs(abs(lambda) - halfPi) < epsilon) ? 0
: x * log(tan(lambda) / tanPhi0) / y,
phi
];
};
return forward;
}
var loximuthal = function() {
return parallel1(loximuthalRaw)
.parallel(40)
.scale(158.837);
};
function millerRaw(lambda, phi) {
return [lambda, 1.25 * log(tan(quarterPi + 0.4 * phi))];
}
millerRaw.invert = function(x, y) {
return [x, 2.5 * atan(exp(0.8 * y)) - 0.625 * pi];
};
var miller = function() {
return d3Geo.geoProjection(millerRaw)
.scale(108.318);
};
function modifiedStereographicRaw(C) {
var m = C.length - 1;
function forward(lambda, phi) {
var cosPhi = cos(phi),
k = 2 / (1 + cosPhi * cos(lambda)),
zr = k * cosPhi * sin(lambda),
zi = k * sin(phi),
i = m,
w = C[i],
ar = w[0],
ai = w[1],
t;
while (--i >= 0) {
w = C[i];
ar = w[0] + zr * (t = ar) - zi * ai;
ai = w[1] + zr * ai + zi * t;
}
ar = zr * (t = ar) - zi * ai;
ai = zr * ai + zi * t;
return [ar, ai];
}
forward.invert = function(x, y) {
var i = 20,
zr = x,
zi = y;
do {
var j = m,
w = C[j],
ar = w[0],
ai = w[1],
br = 0,
bi = 0,
t;
while (--j >= 0) {
w = C[j];
br = ar + zr * (t = br) - zi * bi;
bi = ai + zr * bi + zi * t;
ar = w[0] + zr * (t = ar) - zi * ai;
ai = w[1] + zr * ai + zi * t;
}
br = ar + zr * (t = br) - zi * bi;
bi = ai + zr * bi + zi * t;
ar = zr * (t = ar) - zi * ai - x;
ai = zr * ai + zi * t - y;
var denominator = br * br + bi * bi, deltar, deltai;
zr -= deltar = (ar * br + ai * bi) / denominator;
zi -= deltai = (ai * br - ar * bi) / denominator;
} while (abs(deltar) + abs(deltai) > epsilon * epsilon && --i > 0);
if (i) {
var rho = sqrt(zr * zr + zi * zi),
c = 2 * atan(rho * 0.5),
sinc = sin(c);
return [atan2(zr * sinc, rho * cos(c)), rho ? asin(zi * sinc / rho) : 0];
}
};
return forward;
}
var alaska = [[0.9972523, 0], [0.0052513, -0.0041175], [0.0074606, 0.0048125], [-0.0153783, -0.1968253], [0.0636871, -0.1408027], [0.3660976, -0.2937382]];
var gs48 = [[0.98879, 0], [0, 0], [-0.050909, 0], [0, 0], [0.075528, 0]];
var gs50 = [[0.9842990, 0], [0.0211642, 0.0037608], [-0.1036018, -0.0575102], [-0.0329095, -0.0320119], [0.0499471, 0.1223335], [0.0260460, 0.0899805], [0.0007388, -0.1435792], [0.0075848, -0.1334108], [-0.0216473, 0.0776645], [-0.0225161, 0.0853673]];
var miller$1 = [[0.9245, 0], [0, 0], [0.01943, 0]];
var lee = [[0.721316, 0], [0, 0], [-0.00881625, -0.00617325]];
function modifiedStereographicAlaska() {
return modifiedStereographic(alaska, [152, -64])
.scale(1500)
.center([-160.908, 62.4864])
.clipAngle(25);
}
function modifiedStereographicGs48() {
return modifiedStereographic(gs48, [95, -38])
.scale(1000)
.clipAngle(55)
.center([-96.5563, 38.8675]);
}
function modifiedStereographicGs50() {
return modifiedStereographic(gs50, [120, -45])
.scale(359.513)
.clipAngle(55)
.center([-117.474, 53.0628]);
}
function modifiedStereographicMiller() {
return modifiedStereographic(miller$1, [-20, -18])
.scale(209.091)
.center([20, 16.7214])
.clipAngle(82);
}
function modifiedStereographicLee() {
return modifiedStereographic(lee, [165, 10])
.scale(250)
.clipAngle(130)
.center([-165, -10]);
}
function modifiedStereographic(coefficients, rotate) {
var p = d3Geo.geoProjection(modifiedStereographicRaw(coefficients)).rotate(rotate).clipAngle(90),
r = d3Geo.geoRotation(rotate),
center = p.center;
delete p.rotate;
p.center = function(_) {
return arguments.length ? center(r(_)) : r.invert(center());
};
return p;
}
var sqrt6 = sqrt(6);
var sqrt7 = sqrt(7);
function mtFlatPolarParabolicRaw(lambda, phi) {
var theta = asin(7 * sin(phi) / (3 * sqrt6));
return [
sqrt6 * lambda * (2 * cos(2 * theta / 3) - 1) / sqrt7,
9 * sin(theta / 3) / sqrt7
];
}
mtFlatPolarParabolicRaw.invert = function(x, y) {
var theta = 3 * asin(y * sqrt7 / 9);
return [
x * sqrt7 / (sqrt6 * (2 * cos(2 * theta / 3) - 1)),
asin(sin(theta) * 3 * sqrt6 / 7)
];
};
var mtFlatPolarParabolic = function() {
return d3Geo.geoProjection(mtFlatPolarParabolicRaw)
.scale(164.859);
};
function mtFlatPolarQuarticRaw(lambda, phi) {
var k = (1 + sqrt1_2) * sin(phi),
theta = phi;
for (var i = 0, delta; i < 25; i++) {
theta -= delta = (sin(theta / 2) + sin(theta) - k) / (0.5 * cos(theta / 2) + cos(theta));
if (abs(delta) < epsilon) break;
}
return [
lambda * (1 + 2 * cos(theta) / cos(theta / 2)) / (3 * sqrt2),
2 * sqrt(3) * sin(theta / 2) / sqrt(2 + sqrt2)
];
}
mtFlatPolarQuarticRaw.invert = function(x, y) {
var sinTheta_2 = y * sqrt(2 + sqrt2) / (2 * sqrt(3)),
theta = 2 * asin(sinTheta_2);
return [
3 * sqrt2 * x / (1 + 2 * cos(theta) / cos(theta / 2)),
asin((sinTheta_2 + sin(theta)) / (1 + sqrt1_2))
];
};
var mtFlatPolarQuartic = function() {
return d3Geo.geoProjection(mtFlatPolarQuarticRaw)
.scale(188.209);
};
function mtFlatPolarSinusoidalRaw(lambda, phi) {
var A = sqrt(6 / (4 + pi)),
k = (1 + pi / 4) * sin(phi),
theta = phi / 2;
for (var i = 0, delta; i < 25; i++) {
theta -= delta = (theta / 2 + sin(theta) - k) / (0.5 + cos(theta));
if (abs(delta) < epsilon) break;
}
return [
A * (0.5 + cos(theta)) * lambda / 1.5,
A * theta
];
}
mtFlatPolarSinusoidalRaw.invert = function(x, y) {
var A = sqrt(6 / (4 + pi)),
theta = y / A;
if (abs(abs(theta) - halfPi) < epsilon) theta = theta < 0 ? -halfPi : halfPi;
return [
1.5 * x / (A * (0.5 + cos(theta))),
asin((theta / 2 + sin(theta)) / (1 + pi / 4))
];
};
var mtFlatPolarSinusoidal = function() {
return d3Geo.geoProjection(mtFlatPolarSinusoidalRaw)
.scale(166.518);
};
function naturalEarth2Raw(lambda, phi) {
var phi2 = phi * phi, phi4 = phi2 * phi2, phi6 = phi2 * phi4;
return [
lambda * (0.84719 - 0.13063 * phi2 + phi6 * phi6 * (-0.04515 + 0.05494 * phi2 - 0.02326 * phi4 + 0.00331 * phi6)),
phi * (1.01183 + phi4 * phi4 * (-0.02625 + 0.01926 * phi2 - 0.00396 * phi4))
];
}
naturalEarth2Raw.invert = function(x, y) {
var phi = y, i = 25, delta, phi2, phi4, phi6;
do {
phi2 = phi * phi; phi4 = phi2 * phi2;
phi -= delta = ((phi * (1.01183 + phi4 * phi4 * (-0.02625 + 0.01926 * phi2 - 0.00396 * phi4))) - y) /
(1.01183 + phi4 * phi4 * ((9 * -0.02625) + (11 * 0.01926) * phi2 + (13 * -0.00396) * phi4));
} while (abs(delta) > epsilon2 && --i > 0);
phi2 = phi * phi; phi4 = phi2 * phi2; phi6 = phi2 * phi4;
return [
x / (0.84719 - 0.13063 * phi2 + phi6 * phi6 * (-0.04515 + 0.05494 * phi2 - 0.02326 * phi4 + 0.00331 * phi6)),
phi
];
};
var naturalEarth2 = function() {
return d3Geo.geoProjection(naturalEarth2Raw)
.scale(175.295);
};
function nellHammerRaw(lambda, phi) {
return [
lambda * (1 + cos(phi)) / 2,
2 * (phi - tan(phi / 2))
];
}
nellHammerRaw.invert = function(x, y) {
var p = y / 2;
for (var i = 0, delta = Infinity; i < 10 && abs(delta) > epsilon; ++i) {
var c = cos(y / 2);
y -= delta = (y - tan(y / 2) - p) / (1 - 0.5 / (c * c));
}
return [
2 * x / (1 + cos(y)),
y
];
};
var nellHammer = function() {
return d3Geo.geoProjection(nellHammerRaw)
.scale(152.63);
};
// Based on Java implementation by Bojan Savric.
// https://github.com/OSUCartography/JMapProjLib/blob/master/src/com/jhlabs/map/proj/PattersonProjection.java
var pattersonK1 = 1.0148;
var pattersonK2 = 0.23185;
var pattersonK3 = -0.14499;
var pattersonK4 = 0.02406;
var pattersonC1 = pattersonK1;
var pattersonC2 = 5 * pattersonK2;
var pattersonC3 = 7 * pattersonK3;
var pattersonC4 = 9 * pattersonK4;
var pattersonYmax = 1.790857183;
function pattersonRaw(lambda, phi) {
var phi2 = phi * phi;
return [
lambda,
phi * (pattersonK1 + phi2 * phi2 * (pattersonK2 + phi2 * (pattersonK3 + pattersonK4 * phi2)))
];
}
pattersonRaw.invert = function(x, y) {
if (y > pattersonYmax) y = pattersonYmax;
else if (y < -pattersonYmax) y = -pattersonYmax;
var yc = y, delta;
do { // Newton-Raphson
var y2 = yc * yc;
yc -= delta = ((yc * (pattersonK1 + y2 * y2 * (pattersonK2 + y2 * (pattersonK3 + pattersonK4 * y2)))) - y) / (pattersonC1 + y2 * y2 * (pattersonC2 + y2 * (pattersonC3 + pattersonC4 * y2)));
} while (abs(delta) > epsilon);
return [x, yc];
};
var patterson = function() {
return d3Geo.geoProjection(pattersonRaw)
.scale(139.319);
};
function polyconicRaw(lambda, phi) {
if (abs(phi) < epsilon) return [lambda, 0];
var tanPhi = tan(phi),
k = lambda * sin(phi);
return [
sin(k) / tanPhi,
phi + (1 - cos(k)) / tanPhi
];
}
polyconicRaw.invert = function(x, y) {
if (abs(y) < epsilon) return [x, 0];
var k = x * x + y * y,
phi = y * 0.5,
i = 10, delta;
do {
var tanPhi = tan(phi),
secPhi = 1 / cos(phi),
j = k - 2 * y * phi + phi * phi;
phi -= delta = (tanPhi * j + 2 * (phi - y)) / (2 + j * secPhi * secPhi + 2 * (phi - y) * tanPhi);
} while (abs(delta) > epsilon && --i > 0);
tanPhi = tan(phi);
return [
(abs(y) < abs(phi + 1 / tanPhi) ? asin(x * tanPhi) : sign(x) * (acos(abs(x * tanPhi)) + halfPi)) / sin(phi),
phi
];
};
var polyconic = function() {
return d3Geo.geoProjection(polyconicRaw)
.scale(103.74);
};
// Note: 6-element arrays are used to denote the 3x3 affine transform matrix:
// [a, b, c,
// d, e, f,
// 0, 0, 1] - this redundant row is left out.
// Transform matrix for [a0, a1] -> [b0, b1].
var matrix = function(a, b) {
var u = subtract(a[1], a[0]),
v = subtract(b[1], b[0]),
phi = angle$1(u, v),
s = length(u) / length(v);
return multiply([
1, 0, a[0][0],
0, 1, a[0][1]
], multiply([
s, 0, 0,
0, s, 0
], multiply([
cos(phi), sin(phi), 0,
-sin(phi), cos(phi), 0
], [
1, 0, -b[0][0],
0, 1, -b[0][1]
])));
};
// Inverts a transform matrix.
function inverse(m) {
var k = 1 / (m[0] * m[4] - m[1] * m[3]);
return [
k * m[4], -k * m[1], k * (m[1] * m[5] - m[2] * m[4]),
-k * m[3], k * m[0], k * (m[2] * m[3] - m[0] * m[5])
];
}
// Multiplies two 3x2 matrices.
function multiply(a, b) {
return [
a[0] * b[0] + a[1] * b[3],
a[0] * b[1] + a[1] * b[4],
a[0] * b[2] + a[1] * b[5] + a[2],
a[3] * b[0] + a[4] * b[3],
a[3] * b[1] + a[4] * b[4],
a[3] * b[2] + a[4] * b[5] + a[5]
];
}
// Subtracts 2D vectors.
function subtract(a, b) {
return [a[0] - b[0], a[1] - b[1]];
}
// Magnitude of a 2D vector.
function length(v) {
return sqrt(v[0] * v[0] + v[1] * v[1]);
}
// Angle between two 2D vectors.
function angle$1(a, b) {
return atan2(a[0] * b[1] - a[1] * b[0], a[0] * b[0] + a[1] * b[1]);
}
// Creates a polyhedral projection.
// * root: a spanning tree of polygon faces. Nodes are automatically
// augmented with a transform matrix.
// * face: a function that returns the appropriate node for a given {lambda, phi}
// point (radians).
// * r: rotation angle for final polyhedral net. Defaults to -pi / 6 (for
// butterflies).
var polyhedral = function(root, face, r) {
r = r == null ? -pi / 6 : r; // TODO automate
recurse(root, {transform: [
cos(r), sin(r), 0,
-sin(r), cos(r), 0
]});
function recurse(node, parent) {
node.edges = faceEdges(node.face);
// Find shared edge.
if (parent.face) {
var shared = node.shared = sharedEdge(node.face, parent.face),
m = matrix(shared.map(parent.project), shared.map(node.project));
node.transform = parent.transform ? multiply(parent.transform, m) : m;
// Replace shared edge in parent edges array.
var edges = parent.edges;
for (var i = 0, n = edges.length; i < n; ++i) {
if (pointEqual$1(shared[0], edges[i][1]) && pointEqual$1(shared[1], edges[i][0])) edges[i] = node;
if (pointEqual$1(shared[0], edges[i][0]) && pointEqual$1(shared[1], edges[i][1])) edges[i] = node;
}
edges = node.edges;
for (i = 0, n = edges.length; i < n; ++i) {
if (pointEqual$1(shared[0], edges[i][0]) && pointEqual$1(shared[1], edges[i][1])) edges[i] = parent;
if (pointEqual$1(shared[0], edges[i][1]) && pointEqual$1(shared[1], edges[i][0])) edges[i] = parent;
}
} else {
node.transform = parent.transform;
}
if (node.children) {
node.children.forEach(function(child) {
recurse(child, node);
});
}
return node;
}
function forward(lambda, phi) {
var node = face(lambda, phi),
point = node.project([lambda * degrees, phi * degrees]),
t;
if (t = node.transform) {
return [
t[0] * point[0] + t[1] * point[1] + t[2],
-(t[3] * point[0] + t[4] * point[1] + t[5])
];
}
point[1] = -point[1];
return point;
}
// Naive inverse! A faster solution would use bounding boxes, or even a
// polygonal quadtree.
if (hasInverse(root)) forward.invert = function(x, y) {
var coordinates = faceInvert(root, [x, -y]);
return coordinates && (coordinates[0] *= radians, coordinates[1] *= radians, coordinates);
};
function faceInvert(node, coordinates) {
var invert = node.project.invert,
t = node.transform,
point = coordinates;
if (t) {
t = inverse(t);
point = [
t[0] * point[0] + t[1] * point[1] + t[2],
(t[3] * point[0] + t[4] * point[1] + t[5])
];
}
if (invert && node === faceDegrees(p = invert(point))) return p;
var p,
children = node.children;
for (var i = 0, n = children && children.length; i < n; ++i) {
if (p = faceInvert(children[i], coordinates)) return p;
}
}
function faceDegrees(coordinates) {
return face(coordinates[0] * radians, coordinates[1] * radians);
}
var proj = d3Geo.geoProjection(forward),
stream_ = proj.stream;
// if d3-geo-polygon and proj.preclip are available:
// run around the mesh of faces and stream all vertices to create the clipping polygon
if (d3GeoPolygon.geoClipPolygon && proj.preclip) {
var polygon = [];
outline({point: function(lambda, phi) { polygon.push([lambda, phi]); }}, 1e-4, root);
proj.preclip(d3GeoPolygon.geoClipPolygon({ type: "Polygon", coordinates: [ polygon ] }));
}
function noClip(s) { return s; }
proj.stream = function(stream) {
var rotate = proj.rotate(),
preclip = proj.preclip ? proj.preclip() : null,
rotateStream = stream_(stream),
sphereStream = ((preclip ? proj.preclip(noClip) : proj).rotate([0, 0]), stream_(stream));
proj.rotate(rotate);
if (preclip) proj.preclip(preclip);
rotateStream.sphere = function() {
sphereStream.polygonStart();
sphereStream.lineStart();
outline(sphereStream, epsilon, root);
sphereStream.lineEnd();
sphereStream.polygonEnd();
};
return rotateStream;
};
return proj;
};
function outline(stream, epsilon$$1, node, parent) {
var point,
edges = node.edges,
n = edges.length,
edge,
multiPoint = {type: "MultiPoint", coordinates: node.face},
notPoles = node.face.filter(function(d) { return abs(d[1]) !== 90; }),
b = d3Geo.geoBounds({type: "MultiPoint", coordinates: notPoles}),
inside = false,
j = -1,
dx = b[1][0] - b[0][0];
// TODO
var c = dx === 180 || dx === 360
? [(b[0][0] + b[1][0]) / 2, (b[0][1] + b[1][1]) / 2]
: d3Geo.geoCentroid(multiPoint);
// First find the shared edge…
if (parent) while (++j < n) {
if (edges[j] === parent) break;
}
++j;
for (var i = 0; i < n; ++i) {
edge = edges[(i + j) % n];
if (Array.isArray(edge)) {
if (!inside) {
stream.point((point = d3Geo.geoInterpolate(edge[0], c)(epsilon$$1))[0], point[1]);
inside = true;
}
stream.point((point = d3Geo.geoInterpolate(edge[1], c)(epsilon$$1))[0], point[1]);
} else {
inside = false;
if (edge !== parent) outline(stream, epsilon$$1, edge, node);
}
}
}
// Tests equality of two spherical points.
function pointEqual$1(a, b) {
return a && b && a[0] === b[0] && a[1] === b[1];
}
// Finds a shared edge given two clockwise polygons.
function sharedEdge(a, b) {
var x, y, n = a.length, found = null;
for (var i = 0; i < n; ++i) {
x = a[i];
for (var j = b.length; --j >= 0;) {
y = b[j];
if (x[0] === y[0] && x[1] === y[1]) {
if (found) return [found, x];
found = x;
}
}
}
}
// Converts an array of n face vertices to an array of n + 1 edges.
function faceEdges(face) {
var n = face.length,
edges = [];
for (var a = face[n - 1], i = 0; i < n; ++i) edges.push([a, a = face[i]]);
return edges;
}
function hasInverse(node) {
return node.project.invert || node.children && node.children.some(hasInverse);
}
// TODO generate on-the-fly to avoid external modification.
var octahedron = [
[0, 90],
[-90, 0], [0, 0], [90, 0], [180, 0],
[0, -90]
];
var octahedron$1 = [
[0, 2, 1],
[0, 3, 2],
[5, 1, 2],
[5, 2, 3],
[0, 1, 4],
[0, 4, 3],
[5, 4, 1],
[5, 3, 4]
].map(function(face) {
return face.map(function(i) {
return octahedron[i];
});
});
var butterfly = function(faceProjection) {
faceProjection = faceProjection || function(face) {
var c = d3Geo.geoCentroid({type: "MultiPoint", coordinates: face});
return d3Geo.geoGnomonic().scale(1).translate([0, 0]).rotate([-c[0], -c[1]]);
};
var faces = octahedron$1.map(function(face) {
return {face: face, project: faceProjection(face)};
});
[-1, 0, 0, 1, 0, 1, 4, 5].forEach(function(d, i) {
var node = faces[d];
node && (node.children || (node.children = [])).push(faces[i]);
});
return polyhedral(faces[0], function(lambda, phi) {
return faces[lambda < -pi / 2 ? phi < 0 ? 6 : 4
: lambda < 0 ? phi < 0 ? 2 : 0
: lambda < pi / 2 ? phi < 0 ? 3 : 1
: phi < 0 ? 7 : 5];
})
.scale(101.858)
.center([0, 45]);
};
var kx = 2 / sqrt(3);
function collignonK(a, b) {
var p = collignonRaw(a, b);
return [p[0] * kx, p[1]];
}
collignonK.invert = function(x,y) {
return collignonRaw.invert(x / kx, y);
};
var collignon$1 = function(faceProjection) {
faceProjection = faceProjection || function(face) {
var c = d3Geo.geoCentroid({type: "MultiPoint", coordinates: face});
return d3Geo.geoProjection(collignonK).translate([0, 0]).scale(1).rotate(c[1] > 0 ? [-c[0], 0] : [180 - c[0], 180]);
};
var faces = octahedron$1.map(function(face) {
return {face: face, project: faceProjection(face)};
});
[-1, 0, 0, 1, 0, 1, 4, 5].forEach(function(d, i) {
var node = faces[d];
node && (node.children || (node.children = [])).push(faces[i]);
});
return polyhedral(faces[0], function(lambda, phi) {
return faces[lambda < -pi / 2 ? phi < 0 ? 6 : 4
: lambda < 0 ? phi < 0 ? 2 : 0
: lambda < pi / 2 ? phi < 0 ? 3 : 1
: phi < 0 ? 7 : 5];
})
.scale(121.906)
.center([0, 48.5904]);
};
var waterman = function(faceProjection) {
faceProjection = faceProjection || function(face) {
var c = face.length === 6 ? d3Geo.geoCentroid({type: "MultiPoint", coordinates: face}) : face[0];
return d3Geo.geoGnomonic().scale(1).translate([0, 0]).rotate([-c[0], -c[1]]);
};
var w5 = octahedron$1.map(function(face) {
var xyz = face.map(cartesian),
n = xyz.length,
a = xyz[n - 1],
b,
hexagon = [];
for (var i = 0; i < n; ++i) {
b = xyz[i];
hexagon.push(spherical([
a[0] * 0.9486832980505138 + b[0] * 0.31622776601683794,
a[1] * 0.9486832980505138 + b[1] * 0.31622776601683794,
a[2] * 0.9486832980505138 + b[2] * 0.31622776601683794
]), spherical([
b[0] * 0.9486832980505138 + a[0] * 0.31622776601683794,
b[1] * 0.9486832980505138 + a[1] * 0.31622776601683794,
b[2] * 0.9486832980505138 + a[2] * 0.31622776601683794
]));
a = b;
}
return hexagon;
});
var cornerNormals = [];
var parents = [-1, 0, 0, 1, 0, 1, 4, 5];
w5.forEach(function(hexagon, j) {
var face = octahedron$1[j],
n = face.length,
normals = cornerNormals[j] = [];
for (var i = 0; i < n; ++i) {
w5.push([
face[i],
hexagon[(i * 2 + 2) % (2 * n)],
hexagon[(i * 2 + 1) % (2 * n)]
]);
parents.push(j);
normals.push(cross(
cartesian(hexagon[(i * 2 + 2) % (2 * n)]),
cartesian(hexagon[(i * 2 + 1) % (2 * n)])
));
}
});
var faces = w5.map(function(face) {
return {
project: faceProjection(face),
face: face
};
});
parents.forEach(function(d, i) {
var parent = faces[d];
parent && (parent.children || (parent.children = [])).push(faces[i]);
});
function face(lambda, phi) {
var cosphi = cos(phi),
p = [cosphi * cos(lambda), cosphi * sin(lambda), sin(phi)];
var hexagon = lambda < -pi / 2 ? phi < 0 ? 6 : 4
: lambda < 0 ? phi < 0 ? 2 : 0
: lambda < pi / 2 ? phi < 0 ? 3 : 1
: phi < 0 ? 7 : 5;
var n = cornerNormals[hexagon];
return faces[dot(n[0], p) < 0 ? 8 + 3 * hexagon
: dot(n[1], p) < 0 ? 8 + 3 * hexagon + 1
: dot(n[2], p) < 0 ? 8 + 3 * hexagon + 2
: hexagon];
}
return polyhedral(faces[0], face)
.scale(110.625)
.center([0,45]);
};
function dot(a, b) {
for (var i = 0, n = a.length, s = 0; i < n; ++i) s += a[i] * b[i];
return s;
}
function cross(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]
];
}
// Converts 3D Cartesian to spherical coordinates (degrees).
function spherical(cartesian) {
return [
atan2(cartesian[1], cartesian[0]) * degrees,
asin(max(-1, min(1, cartesian[2]))) * degrees
];
}
// Converts spherical coordinates (degrees) to 3D Cartesian.
function cartesian(coordinates) {
var lambda = coordinates[0] * radians,
phi = coordinates[1] * radians,
cosphi = cos(phi);
return [
cosphi * cos(lambda),
cosphi * sin(lambda),
sin(phi)
];
}
var noop = function() {};
var clockwise = function(ring) {
if ((n = ring.length) < 4) return false;
var i = 0,
n,
area = ring[n - 1][1] * ring[0][0] - ring[n - 1][0] * ring[0][1];
while (++i < n) area += ring[i - 1][1] * ring[i][0] - ring[i - 1][0] * ring[i][1];
return area <= 0;
};
var contains = function(ring, point) {
var x = point[0],
y = point[1],
contains = false;
for (var i = 0, n = ring.length, j = n - 1; i < n; j = i++) {
var pi = ring[i], xi = pi[0], yi = pi[1],
pj = ring[j], xj = pj[0], yj = pj[1];
if (((yi > y) ^ (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi)) contains = !contains;
}
return contains;
};
var index = function(object, projection) {
var stream = projection.stream, project;
if (!stream) throw new Error("invalid projection");
switch (object && object.type) {
case "Feature": project = projectFeature; break;
case "FeatureCollection": project = projectFeatureCollection; break;
default: project = projectGeometry; break;
}
return project(object, stream);
};
function projectFeatureCollection(o, stream) {
return {
type: "FeatureCollection",
features: o.features.map(function(f) {
return projectFeature(f, stream);
})
};
}
function projectFeature(o, stream) {
return {
type: "Feature",
id: o.id,
properties: o.properties,
geometry: projectGeometry(o.geometry, stream)
};
}
function projectGeometryCollection(o, stream) {
return {
type: "GeometryCollection",
geometries: o.geometries.map(function(o) {
return projectGeometry(o, stream);
})
};
}
function projectGeometry(o, stream) {
if (!o) return null;
if (o.type === "GeometryCollection") return projectGeometryCollection(o, stream);
var sink;
switch (o.type) {
case "Point": sink = sinkPoint; break;
case "MultiPoint": sink = sinkPoint; break;
case "LineString": sink = sinkLine; break;
case "MultiLineString": sink = sinkLine; break;
case "Polygon": sink = sinkPolygon; break;
case "MultiPolygon": sink = sinkPolygon; break;
case "Sphere": sink = sinkPolygon; break;
default: return null;
}
d3Geo.geoStream(o, stream(sink));
return sink.result();
}
var points = [];
var lines = [];
var sinkPoint = {
point: function(x, y) {
points.push([x, y]);
},
result: function() {
var result = !points.length ? null
: points.length < 2 ? {type: "Point", coordinates: points[0]}
: {type: "MultiPoint", coordinates: points};
points = [];
return result;
}
};
var sinkLine = {
lineStart: noop,
point: function(x, y) {
points.push([x, y]);
},
lineEnd: function() {
if (points.length) lines.push(points), points = [];
},
result: function() {
var result = !lines.length ? null
: lines.length < 2 ? {type: "LineString", coordinates: lines[0]}
: {type: "MultiLineString", coordinates: lines};
lines = [];
return result;
}
};
var sinkPolygon = {
polygonStart: noop,
lineStart: noop,
point: function(x, y) {
points.push([x, y]);
},
lineEnd: function() {
var n = points.length;
if (n) {
do points.push(points[0].slice()); while (++n < 4);
lines.push(points), points = [];
}
},
polygonEnd: noop,
result: function() {
if (!lines.length) return null;
var polygons = [],
holes = [];
// https://github.com/d3/d3/issues/1558
lines.forEach(function(ring) {
if (clockwise(ring)) polygons.push([ring]);
else holes.push(ring);
});
holes.forEach(function(hole) {
var point = hole[0];
polygons.some(function(polygon) {
if (contains(polygon[0], point)) {
polygon.push(hole);
return true;
}
}) || polygons.push([hole]);
});
lines = [];
return !polygons.length ? null
: polygons.length > 1 ? {type: "MultiPolygon", coordinates: polygons}
: {type: "Polygon", coordinates: polygons[0]};
}
};
var quincuncial = function(project) {
var dx = project(halfPi, 0)[0] - project(-halfPi, 0)[0];
function projectQuincuncial(lambda, phi) {
var t = abs(lambda) < halfPi,
p = project(t ? lambda : lambda > 0 ? lambda - pi : lambda + pi, phi),
x = (p[0] - p[1]) * sqrt1_2,
y = (p[0] + p[1]) * sqrt1_2;
if (t) return [x, y];
var d = dx * sqrt1_2,
s = x > 0 ^ y > 0 ? -1 : 1;
return [s * x - sign(y) * d, s * y - sign(x) * d];
}
if (project.invert) projectQuincuncial.invert = function(x0, y0) {
var x = (x0 + y0) * sqrt1_2,
y = (y0 - x0) * sqrt1_2,
t = abs(x) < 0.5 * dx && abs(y) < 0.5 * dx;
if (!t) {
var d = dx * sqrt1_2,
s = x > 0 ^ y > 0 ? -1 : 1,
x1 = -s * x0 + (y > 0 ? 1 : -1) * d,
y1 = -s * y0 + (x > 0 ? 1 : -1) * d;
x = (-x1 - y1) * sqrt1_2;
y = (x1 - y1) * sqrt1_2;
}
var p = project.invert(x, y);
if (!t) p[0] += x > 0 ? pi : -pi;
return p;
};
return d3Geo.geoProjection(projectQuincuncial)
.rotate([-90, -90, 45])
.clipAngle(180 - 1e-3);
};
var gringorten$1 = function() {
return quincuncial(gringortenRaw)
.scale(176.423);
};
var peirce = function() {
return quincuncial(guyouRaw)
.scale(111.48);
};
var quantize = function(input, digits) {
if (!(0 <= (digits = +digits) && digits <= 20)) throw new Error("invalid digits");
function quantizePoint(input) {
var n = input.length, i = 2, output = new Array(n);
output[0] = +input[0].toFixed(digits);
output[1] = +input[1].toFixed(digits);
while (i < n) output[i] = input[i], ++i;
return output;
}
function quantizePoints(input) {
return input.map(quantizePoint);
}
function quantizePolygon(input) {
return input.map(quantizePoints);
}
function quantizeGeometry(input) {
if (input == null) return input;
var output;
switch (input.type) {
case "GeometryCollection": output = {type: "GeometryCollection", geometries: input.geometries.map(quantizeGeometry)}; break;
case "Point": output = {type: "Point", coordinates: quantizePoint(input.coordinates)}; break;
case "MultiPoint": case "LineString": output = {type: input.type, coordinates: quantizePoints(input.coordinates)}; break;
case "MultiLineString": case "Polygon": output = {type: input.type, coordinates: quantizePolygon(input.coordinates)}; break;
case "MultiPolygon": output = {type: "MultiPolygon", coordinates: input.coordinates.map(quantizePolygon)}; break;
default: return input;
}
if (input.bbox != null) output.bbox = input.bbox;
return output;
}
function quantizeFeature(input) {
var output = {type: "Feature", properties: input.properties, geometry: quantizeGeometry(input.geometry)};
if (input.id != null) output.id = input.id;
if (input.bbox != null) output.bbox = input.bbox;
return output;
}
if (input != null) switch (input.type) {
case "Feature": return quantizeFeature(input);
case "FeatureCollection": {
var output = {type: "FeatureCollection", features: input.features.map(quantizeFeature)};
if (input.bbox != null) output.bbox = input.bbox;
return output;
}
default: return quantizeGeometry(input);
}
return input;
};
function rectangularPolyconicRaw(phi0) {
var sinPhi0 = sin(phi0);
function forward(lambda, phi) {
var A = sinPhi0 ? tan(lambda * sinPhi0 / 2) / sinPhi0 : lambda / 2;
if (!phi) return [2 * A, -phi0];
var E = 2 * atan(A * sin(phi)),
cotPhi = 1 / tan(phi);
return [
sin(E) * cotPhi,
phi + (1 - cos(E)) * cotPhi - phi0
];
}
// TODO return null for points outside outline.
forward.invert = function(x, y) {
if (abs(y += phi0) < epsilon) return [sinPhi0 ? 2 * atan(sinPhi0 * x / 2) / sinPhi0 : x, 0];
var k = x * x + y * y,
phi = 0,
i = 10, delta;
do {
var tanPhi = tan(phi),
secPhi = 1 / cos(phi),
j = k - 2 * y * phi + phi * phi;
phi -= delta = (tanPhi * j + 2 * (phi - y)) / (2 + j * secPhi * secPhi + 2 * (phi - y) * tanPhi);
} while (abs(delta) > epsilon && --i > 0);
var E = x * (tanPhi = tan(phi)),
A = tan(abs(y) < abs(phi + 1 / tanPhi) ? asin(E) * 0.5 : acos(E) * 0.5 + pi / 4) / sin(phi);
return [
sinPhi0 ? 2 * atan(sinPhi0 * A) / sinPhi0 : 2 * A,
phi
];
};
return forward;
}
var rectangularPolyconic = function() {
return parallel1(rectangularPolyconicRaw)
.scale(131.215);
};
var K = [
[0.9986, -0.062],
[1.0000, 0.0000],
[0.9986, 0.0620],
[0.9954, 0.1240],
[0.9900, 0.1860],
[0.9822, 0.2480],
[0.9730, 0.3100],
[0.9600, 0.3720],
[0.9427, 0.4340],
[0.9216, 0.4958],
[0.8962, 0.5571],
[0.8679, 0.6176],
[0.8350, 0.6769],
[0.7986, 0.7346],
[0.7597, 0.7903],
[0.7186, 0.8435],
[0.6732, 0.8936],
[0.6213, 0.9394],
[0.5722, 0.9761],
[0.5322, 1.0000]
];
K.forEach(function(d) {
d[1] *= 1.0144;
});
function robinsonRaw(lambda, phi) {
var i = min(18, abs(phi) * 36 / pi),
i0 = floor(i),
di = i - i0,
ax = (k = K[i0])[0],
ay = k[1],
bx = (k = K[++i0])[0],
by = k[1],
cx = (k = K[min(19, ++i0)])[0],
cy = k[1],
k;
return [
lambda * (bx + di * (cx - ax) / 2 + di * di * (cx - 2 * bx + ax) / 2),
(phi > 0 ? halfPi : -halfPi) * (by + di * (cy - ay) / 2 + di * di * (cy - 2 * by + ay) / 2)
];
}
robinsonRaw.invert = function(x, y) {
var yy = y / halfPi,
phi = yy * 90,
i = min(18, abs(phi / 5)),
i0 = max(0, floor(i));
do {
var ay = K[i0][1],
by = K[i0 + 1][1],
cy = K[min(19, i0 + 2)][1],
u = cy - ay,
v = cy - 2 * by + ay,
t = 2 * (abs(yy) - by) / u,
c = v / u,
di = t * (1 - c * t * (1 - 2 * c * t));
if (di >= 0 || i0 === 1) {
phi = (y >= 0 ? 5 : -5) * (di + i);
var j = 50, delta;
do {
i = min(18, abs(phi) / 5);
i0 = floor(i);
di = i - i0;
ay = K[i0][1];
by = K[i0 + 1][1];
cy = K[min(19, i0 + 2)][1];
phi -= (delta = (y >= 0 ? halfPi : -halfPi) * (by + di * (cy - ay) / 2 + di * di * (cy - 2 * by + ay) / 2) - y) * degrees;
} while (abs(delta) > epsilon2 && --j > 0);
break;
}
} while (--i0 >= 0);
var ax = K[i0][0],
bx = K[i0 + 1][0],
cx = K[min(19, i0 + 2)][0];
return [
x / (bx + di * (cx - ax) / 2 + di * di * (cx - 2 * bx + ax) / 2),
phi * radians
];
};
var robinson = function() {
return d3Geo.geoProjection(robinsonRaw)
.scale(152.63);
};
function satelliteVerticalRaw(P) {
function forward(lambda, phi) {
var cosPhi = cos(phi),
k = (P - 1) / (P - cosPhi * cos(lambda));
return [
k * cosPhi * sin(lambda),
k * sin(phi)
];
}
forward.invert = function(x, y) {
var rho2 = x * x + y * y,
rho = sqrt(rho2),
sinc = (P - sqrt(1 - rho2 * (P + 1) / (P - 1))) / ((P - 1) / rho + rho / (P - 1));
return [
atan2(x * sinc, rho * sqrt(1 - sinc * sinc)),
rho ? asin(y * sinc / rho) : 0
];
};
return forward;
}
function satelliteRaw(P, omega) {
var vertical = satelliteVerticalRaw(P);
if (!omega) return vertical;
var cosOmega = cos(omega),
sinOmega = sin(omega);
function forward(lambda, phi) {
var coordinates = vertical(lambda, phi),
y = coordinates[1],
A = y * sinOmega / (P - 1) + cosOmega;
return [
coordinates[0] * cosOmega / A,
y / A
];
}
forward.invert = function(x, y) {
var k = (P - 1) / (P - 1 - y * sinOmega);
return vertical.invert(k * x, k * y * cosOmega);
};
return forward;
}
var satellite = function() {
var distance = 2,
omega = 0,
m = d3Geo.geoProjectionMutator(satelliteRaw),
p = m(distance, omega);
// As a multiple of radius.
p.distance = function(_) {
if (!arguments.length) return distance;
return m(distance = +_, omega);
};
p.tilt = function(_) {
if (!arguments.length) return omega * degrees;
return m(distance, omega = _ * radians);
};
return p
.scale(432.147)
.clipAngle(acos(1 / distance) * degrees - 1e-6);
};
var epsilon$1 = 1e-4;
var epsilonInverse = 1e4;
var x0 = -180;
var x0e = x0 + epsilon$1;
var x1 = 180;
var x1e = x1 - epsilon$1;
var y0 = -90;
var y0e = y0 + epsilon$1;
var y1 = 90;
var y1e = y1 - epsilon$1;
function nonempty(coordinates) {
return coordinates.length > 0;
}
function quantize$1(x) {
return Math.floor(x * epsilonInverse) / epsilonInverse;
}
function normalizePoint(y) {
return y === y0 || y === y1 ? [0, y] : [x0, quantize$1(y)]; // pole or antimeridian?
}
function clampPoint(p) {
var x = p[0], y = p[1], clamped = false;
if (x <= x0e) x = x0, clamped = true;
else if (x >= x1e) x = x1, clamped = true;
if (y <= y0e) y = y0, clamped = true;
else if (y >= y1e) y = y1, clamped = true;
return clamped ? [x, y] : p;
}
function clampPoints(points) {
return points.map(clampPoint);
}
// For each ring, detect where it crosses the antimeridian or pole.
function extractFragments(rings, polygon, fragments) {
for (var j = 0, m = rings.length; j < m; ++j) {
var ring = rings[j].slice();
// By default, assume that this ring doesn’t need any stitching.
fragments.push({index: -1, polygon: polygon, ring: ring});
for (var i = 0, n = ring.length; i < n; ++i) {
var point = ring[i],
x = point[0],
y = point[1];
// If this is an antimeridian or polar point…
if (x <= x0e || x >= x1e || y <= y0e || y >= y1e) {
ring[i] = clampPoint(point);
// Advance through any antimeridian or polar points…
for (var k = i + 1; k < n; ++k) {
var pointk = ring[k],
xk = pointk[0],
yk = pointk[1];
if (xk > x0e && xk < x1e && yk > y0e && yk < y1e) break;
}
// If this was just a single antimeridian or polar point,
// we don’t need to cut this ring into a fragment;
// we can just leave it as-is.
if (k === i + 1) continue;
// Otherwise, if this is not the first point in the ring,
// cut the current fragment so that it ends at the current point.
// The current point is also normalized for later joining.
if (i) {
var fragmentBefore = {index: -1, polygon: polygon, ring: ring.slice(0, i + 1)};
fragmentBefore.ring[fragmentBefore.ring.length - 1] = normalizePoint(y);
fragments[fragments.length - 1] = fragmentBefore;
}
// If the ring started with an antimeridian fragment,
// we can ignore that fragment entirely.
else fragments.pop();
// If the remainder of the ring is an antimeridian fragment,
// move on to the next ring.
if (k >= n) break;
// Otherwise, add the remaining ring fragment and continue.
fragments.push({index: -1, polygon: polygon, ring: ring = ring.slice(k - 1)});
ring[0] = normalizePoint(ring[0][1]);
i = -1;
n = ring.length;
}
}
}
}
// Now stitch the fragments back together into rings.
function stitchFragments(fragments) {
var i, n = fragments.length;
// To connect the fragments start-to-end, create a simple index by end.
var fragmentByStart = {},
fragmentByEnd = {},
fragment,
start,
startFragment,
end,
endFragment;
// For each fragment…
for (i = 0; i < n; ++i) {
fragment = fragments[i];
start = fragment.ring[0];
end = fragment.ring[fragment.ring.length - 1];
// If this fragment is closed, add it as a standalone ring.
if (start[0] === end[0] && start[1] === end[1]) {
fragment.polygon.push(fragment.ring);
fragments[i] = null;
continue;
}
fragment.index = i;
fragmentByStart[start] = fragmentByEnd[end] = fragment;
}
// For each open fragment…
for (i = 0; i < n; ++i) {
fragment = fragments[i];
if (fragment) {
start = fragment.ring[0];
end = fragment.ring[fragment.ring.length - 1];
startFragment = fragmentByEnd[start];
endFragment = fragmentByStart[end];
delete fragmentByStart[start];
delete fragmentByEnd[end];
// If this fragment is closed, add it as a standalone ring.
if (start[0] === end[0] && start[1] === end[1]) {
fragment.polygon.push(fragment.ring);
continue;
}
if (startFragment) {
delete fragmentByEnd[start];
delete fragmentByStart[startFragment.ring[0]];
startFragment.ring.pop(); // drop the shared coordinate
fragments[startFragment.index] = null;
fragment = {index: -1, polygon: startFragment.polygon, ring: startFragment.ring.concat(fragment.ring)};
if (startFragment === endFragment) {
// Connect both ends to this single fragment to create a ring.
fragment.polygon.push(fragment.ring);
} else {
fragment.index = n++;
fragments.push(fragmentByStart[fragment.ring[0]] = fragmentByEnd[fragment.ring[fragment.ring.length - 1]] = fragment);
}
} else if (endFragment) {
delete fragmentByStart[end];
delete fragmentByEnd[endFragment.ring[endFragment.ring.length - 1]];
fragment.ring.pop(); // drop the shared coordinate
fragment = {index: n++, polygon: endFragment.polygon, ring: fragment.ring.concat(endFragment.ring)};
fragments[endFragment.index] = null;
fragments.push(fragmentByStart[fragment.ring[0]] = fragmentByEnd[fragment.ring[fragment.ring.length - 1]] = fragment);
} else {
fragment.ring.push(fragment.ring[0]); // close ring
fragment.polygon.push(fragment.ring);
}
}
}
}
function stitchFeature(input) {
var output = {type: "Feature", geometry: stitchGeometry(input.geometry)};
if (input.id != null) output.id = input.id;
if (input.bbox != null) output.bbox = input.bbox;
if (input.properties != null) output.properties = input.properties;
return output;
}
function stitchGeometry(input) {
if (input == null) return input;
var output, fragments, i, n;
switch (input.type) {
case "GeometryCollection": output = {type: "GeometryCollection", geometries: input.geometries.map(stitchGeometry)}; break;
case "Point": output = {type: "Point", coordinates: clampPoint(input.coordinates)}; break;
case "MultiPoint": case "LineString": output = {type: input.type, coordinates: clampPoints(input.coordinates)}; break;
case "MultiLineString": output = {type: "MultiLineString", coordinates: input.coordinates.map(clampPoints)}; break;
case "Polygon": {
var polygon = [];
extractFragments(input.coordinates, polygon, fragments = []);
stitchFragments(fragments);
output = {type: "Polygon", coordinates: polygon};
break;
}
case "MultiPolygon": {
fragments = [], i = -1, n = input.coordinates.length;
var polygons = new Array(n);
while (++i < n) extractFragments(input.coordinates[i], polygons[i] = [], fragments);
stitchFragments(fragments);
output = {type: "MultiPolygon", coordinates: polygons.filter(nonempty)};
break;
}
default: return input;
}
if (input.bbox != null) output.bbox = input.bbox;
return output;
}
var stitch = function(input) {
if (input == null) return input;
switch (input.type) {
case "Feature": return stitchFeature(input);
case "FeatureCollection": {
var output = {type: "FeatureCollection", features: input.features.map(stitchFeature)};
if (input.bbox != null) output.bbox = input.bbox;
return output;
}
default: return stitchGeometry(input);
}
};
function timesRaw(lambda, phi) {
var t = tan(phi / 2),
s = sin(quarterPi * t);
return [
lambda * (0.74482 - 0.34588 * s * s),
1.70711 * t
];
}
timesRaw.invert = function(x, y) {
var t = y / 1.70711,
s = sin(quarterPi * t);
return [
x / (0.74482 - 0.34588 * s * s),
2 * atan(t)
];
};
var times = function() {
return d3Geo.geoProjection(timesRaw)
.scale(146.153);
};
// Compute the origin as the midpoint of the two reference points.
// Rotate one of the reference points by the origin.
// Apply the spherical law of sines to compute gamma rotation.
var twoPoint = function(raw, p0, p1) {
var i = d3Geo.geoInterpolate(p0, p1),
o = i(0.5),
a = d3Geo.geoRotation([-o[0], -o[1]])(p0),
b = i.distance / 2,
y = -asin(sin(a[1] * radians) / sin(b)),
R = [-o[0], -o[1], -(a[0] > 0 ? pi - y : y) * degrees],
p = d3Geo.geoProjection(raw(b)).rotate(R),
r = d3Geo.geoRotation(R),
center = p.center;
delete p.rotate;
p.center = function(_) {
return arguments.length ? center(r(_)) : r.invert(center());
};
return p
.clipAngle(90);
};
function twoPointAzimuthalRaw(d) {
var cosd = cos(d);
function forward(lambda, phi) {
var coordinates = d3Geo.geoGnomonicRaw(lambda, phi);
coordinates[0] *= cosd;
return coordinates;
}
forward.invert = function(x, y) {
return d3Geo.geoGnomonicRaw.invert(x / cosd, y);
};
return forward;
}
function twoPointAzimuthalUsa() {
return twoPointAzimuthal([-158, 21.5], [-77, 39])
.clipAngle(60)
.scale(400);
}
function twoPointAzimuthal(p0, p1) {
return twoPoint(twoPointAzimuthalRaw, p0, p1);
}
// TODO clip to ellipse
function twoPointEquidistantRaw(z0) {
if (!(z0 *= 2)) return d3Geo.geoAzimuthalEquidistantRaw;
var lambdaa = -z0 / 2,
lambdab = -lambdaa,
z02 = z0 * z0,
tanLambda0 = tan(lambdab),
S = 0.5 / sin(lambdab);
function forward(lambda, phi) {
var za = acos(cos(phi) * cos(lambda - lambdaa)),
zb = acos(cos(phi) * cos(lambda - lambdab)),
ys = phi < 0 ? -1 : 1;
za *= za, zb *= zb;
return [
(za - zb) / (2 * z0),
ys * sqrt(4 * z02 * zb - (z02 - za + zb) * (z02 - za + zb)) / (2 * z0)
];
}
forward.invert = function(x, y) {
var y2 = y * y,
cosza = cos(sqrt(y2 + (t = x + lambdaa) * t)),
coszb = cos(sqrt(y2 + (t = x + lambdab) * t)),
t,
d;
return [
atan2(d = cosza - coszb, t = (cosza + coszb) * tanLambda0),
(y < 0 ? -1 : 1) * acos(sqrt(t * t + d * d) * S)
];
};
return forward;
}
function twoPointEquidistantUsa() {
return twoPointEquidistant([-158, 21.5], [-77, 39])
.clipAngle(130)
.scale(122.571);
}
function twoPointEquidistant(p0, p1) {
return twoPoint(twoPointEquidistantRaw, p0, p1);
}
function vanDerGrintenRaw(lambda, phi) {
if (abs(phi) < epsilon) return [lambda, 0];
var sinTheta = abs(phi / halfPi),
theta = asin(sinTheta);
if (abs(lambda) < epsilon || abs(abs(phi) - halfPi) < epsilon) return [0, sign(phi) * pi * tan(theta / 2)];
var cosTheta = cos(theta),
A = abs(pi / lambda - lambda / pi) / 2,
A2 = A * A,
G = cosTheta / (sinTheta + cosTheta - 1),
P = G * (2 / sinTheta - 1),
P2 = P * P,
P2_A2 = P2 + A2,
G_P2 = G - P2,
Q = A2 + G;
return [
sign(lambda) * pi * (A * G_P2 + sqrt(A2 * G_P2 * G_P2 - P2_A2 * (G * G - P2))) / P2_A2,
sign(phi) * pi * (P * Q - A * sqrt((A2 + 1) * P2_A2 - Q * Q)) / P2_A2
];
}
vanDerGrintenRaw.invert = function(x, y) {
if (abs(y) < epsilon) return [x, 0];
if (abs(x) < epsilon) return [0, halfPi * sin(2 * atan(y / pi))];
var x2 = (x /= pi) * x,
y2 = (y /= pi) * y,
x2_y2 = x2 + y2,
z = x2_y2 * x2_y2,
c1 = -abs(y) * (1 + x2_y2),
c2 = c1 - 2 * y2 + x2,
c3 = -2 * c1 + 1 + 2 * y2 + z,
d = y2 / c3 + (2 * c2 * c2 * c2 / (c3 * c3 * c3) - 9 * c1 * c2 / (c3 * c3)) / 27,
a1 = (c1 - c2 * c2 / (3 * c3)) / c3,
m1 = 2 * sqrt(-a1 / 3),
theta1 = acos(3 * d / (a1 * m1)) / 3;
return [
pi * (x2_y2 - 1 + sqrt(1 + 2 * (x2 - y2) + z)) / (2 * x),
sign(y) * pi * (-m1 * cos(theta1 + pi / 3) - c2 / (3 * c3))
];
};
var vanDerGrinten = function() {
return d3Geo.geoProjection(vanDerGrintenRaw)
.scale(79.4183);
};
function vanDerGrinten2Raw(lambda, phi) {
if (abs(phi) < epsilon) return [lambda, 0];
var sinTheta = abs(phi / halfPi),
theta = asin(sinTheta);
if (abs(lambda) < epsilon || abs(abs(phi) - halfPi) < epsilon) return [0, sign(phi) * pi * tan(theta / 2)];
var cosTheta = cos(theta),
A = abs(pi / lambda - lambda / pi) / 2,
A2 = A * A,
x1 = cosTheta * (sqrt(1 + A2) - A * cosTheta) / (1 + A2 * sinTheta * sinTheta);
return [
sign(lambda) * pi * x1,
sign(phi) * pi * sqrt(1 - x1 * (2 * A + x1))
];
}
vanDerGrinten2Raw.invert = function(x, y) {
if (!x) return [0, halfPi * sin(2 * atan(y / pi))];
var x1 = abs(x / pi),
A = (1 - x1 * x1 - (y /= pi) * y) / (2 * x1),
A2 = A * A,
B = sqrt(A2 + 1);
return [
sign(x) * pi * (B - A),
sign(y) * halfPi * sin(2 * atan2(sqrt((1 - 2 * A * x1) * (A + B) - x1), sqrt(B + A + x1)))
];
};
var vanDerGrinten2 = function() {
return d3Geo.geoProjection(vanDerGrinten2Raw)
.scale(79.4183);
};
function vanDerGrinten3Raw(lambda, phi) {
if (abs(phi) < epsilon) return [lambda, 0];
var sinTheta = phi / halfPi,
theta = asin(sinTheta);
if (abs(lambda) < epsilon || abs(abs(phi) - halfPi) < epsilon) return [0, pi * tan(theta / 2)];
var A = (pi / lambda - lambda / pi) / 2,
y1 = sinTheta / (1 + cos(theta));
return [
pi * (sign(lambda) * sqrt(A * A + 1 - y1 * y1) - A),
pi * y1
];
}
vanDerGrinten3Raw.invert = function(x, y) {
if (!y) return [x, 0];
var y1 = y / pi,
A = (pi * pi * (1 - y1 * y1) - x * x) / (2 * pi * x);
return [
x ? pi * (sign(x) * sqrt(A * A + 1) - A) : 0,
halfPi * sin(2 * atan(y1))
];
};
var vanDerGrinten3 = function() {
return d3Geo.geoProjection(vanDerGrinten3Raw)
.scale(79.4183);
};
function vanDerGrinten4Raw(lambda, phi) {
if (!phi) return [lambda, 0];
var phi0 = abs(phi);
if (!lambda || phi0 === halfPi) return [0, phi];
var B = phi0 / halfPi,
B2 = B * B,
C = (8 * B - B2 * (B2 + 2) - 5) / (2 * B2 * (B - 1)),
C2 = C * C,
BC = B * C,
B_C2 = B2 + C2 + 2 * BC,
B_3C = B + 3 * C,
lambda0 = lambda / halfPi,
lambda1 = lambda0 + 1 / lambda0,
D = sign(abs(lambda) - halfPi) * sqrt(lambda1 * lambda1 - 4),
D2 = D * D,
F = B_C2 * (B2 + C2 * D2 - 1) + (1 - B2) * (B2 * (B_3C * B_3C + 4 * C2) + 12 * BC * C2 + 4 * C2 * C2),
x1 = (D * (B_C2 + C2 - 1) + 2 * sqrt(F)) / (4 * B_C2 + D2);
return [
sign(lambda) * halfPi * x1,
sign(phi) * halfPi * sqrt(1 + D * abs(x1) - x1 * x1)
];
}
vanDerGrinten4Raw.invert = function(x, y) {
var delta;
if (!x || !y) return [x, y];
y /= pi;
var x1 = sign(x) * x / halfPi,
D = (x1 * x1 - 1 + 4 * y * y) / abs(x1),
D2 = D * D,
B = 2 * y,
i = 50;
do {
var B2 = B * B,
C = (8 * B - B2 * (B2 + 2) - 5) / (2 * B2 * (B - 1)),
C_ = (3 * B - B2 * B - 10) / (2 * B2 * B),
C2 = C * C,
BC = B * C,
B_C = B + C,
B_C2 = B_C * B_C,
B_3C = B + 3 * C,
F = B_C2 * (B2 + C2 * D2 - 1) + (1 - B2) * (B2 * (B_3C * B_3C + 4 * C2) + C2 * (12 * BC + 4 * C2)),
F_ = -2 * B_C * (4 * BC * C2 + (1 - 4 * B2 + 3 * B2 * B2) * (1 + C_) + C2 * (-6 + 14 * B2 - D2 + (-8 + 8 * B2 - 2 * D2) * C_) + BC * (-8 + 12 * B2 + (-10 + 10 * B2 - D2) * C_)),
sqrtF = sqrt(F),
f = D * (B_C2 + C2 - 1) + 2 * sqrtF - x1 * (4 * B_C2 + D2),
f_ = D * (2 * C * C_ + 2 * B_C * (1 + C_)) + F_ / sqrtF - 8 * B_C * (D * (-1 + C2 + B_C2) + 2 * sqrtF) * (1 + C_) / (D2 + 4 * B_C2);
B -= delta = f / f_;
} while (delta > epsilon && --i > 0);
return [
sign(x) * (sqrt(D * D + 4) + D) * pi / 4,
halfPi * B
];
};
var vanDerGrinten4 = function() {
return d3Geo.geoProjection(vanDerGrinten4Raw)
.scale(127.16);
};
var A = 4 * pi + 3 * sqrt(3);
var B = 2 * sqrt(2 * pi * sqrt(3) / A);
var wagner4Raw = mollweideBromleyRaw(B * sqrt(3) / pi, B, A / 6);
var wagner4 = function() {
return d3Geo.geoProjection(wagner4Raw)
.scale(176.84);
};
function wagner6Raw(lambda, phi) {
return [lambda * sqrt(1 - 3 * phi * phi / (pi * pi)), phi];
}
wagner6Raw.invert = function(x, y) {
return [x / sqrt(1 - 3 * y * y / (pi * pi)), y];
};
var wagner6 = function() {
return d3Geo.geoProjection(wagner6Raw)
.scale(152.63);
};
function wagner7Raw(lambda, phi) {
var s = 0.90631 * sin(phi),
c0 = sqrt(1 - s * s),
c1 = sqrt(2 / (1 + c0 * cos(lambda /= 3)));
return [
2.66723 * c0 * c1 * sin(lambda),
1.24104 * s * c1
];
}
wagner7Raw.invert = function(x, y) {
var t1 = x / 2.66723,
t2 = y / 1.24104,
p = sqrt(t1 * t1 + t2 * t2),
c = 2 * asin(p / 2);
return [
3 * atan2(x * tan(c), 2.66723 * p),
p && asin(y * sin(c) / (1.24104 * 0.90631 * p))
];
};
var wagner7 = function() {
return d3Geo.geoProjection(wagner7Raw)
.scale(172.632);
};
function wiechelRaw(lambda, phi) {
var cosPhi = cos(phi),
sinPhi = cos(lambda) * cosPhi,
sin1_Phi = 1 - sinPhi,
cosLambda = cos(lambda = atan2(sin(lambda) * cosPhi, -sin(phi))),
sinLambda = sin(lambda);
cosPhi = sqrt(1 - sinPhi * sinPhi);
return [
sinLambda * cosPhi - cosLambda * sin1_Phi,
-cosLambda * cosPhi - sinLambda * sin1_Phi
];
}
wiechelRaw.invert = function(x, y) {
var w = (x * x + y * y) / -2,
k = sqrt(-w * (2 + w)),
b = y * w + x * k,
a = x * w - y * k,
D = sqrt(a * a + b * b);
return [
atan2(k * b, D * (1 + w)),
D ? -asin(k * a / D) : 0
];
};
var wiechel = function() {
return d3Geo.geoProjection(wiechelRaw)
.rotate([0, -90, 45])
.scale(124.75)
.clipAngle(180 - 1e-3);
};
function winkel3Raw(lambda, phi) {
var coordinates = aitoffRaw(lambda, phi);
return [
(coordinates[0] + lambda / halfPi) / 2,
(coordinates[1] + phi) / 2
];
}
winkel3Raw.invert = function(x, y) {
var lambda = x, phi = y, i = 25;
do {
var cosphi = cos(phi),
sinphi = sin(phi),
sin_2phi = sin(2 * phi),
sin2phi = sinphi * sinphi,
cos2phi = cosphi * cosphi,
sinlambda = sin(lambda),
coslambda_2 = cos(lambda / 2),
sinlambda_2 = sin(lambda / 2),
sin2lambda_2 = sinlambda_2 * sinlambda_2,
C = 1 - cos2phi * coslambda_2 * coslambda_2,
E = C ? acos(cosphi * coslambda_2) * sqrt(F = 1 / C) : F = 0,
F,
fx = 0.5 * (2 * E * cosphi * sinlambda_2 + lambda / halfPi) - x,
fy = 0.5 * (E * sinphi + phi) - y,
dxdlambda = 0.5 * F * (cos2phi * sin2lambda_2 + E * cosphi * coslambda_2 * sin2phi) + 0.5 / halfPi,
dxdphi = F * (sinlambda * sin_2phi / 4 - E * sinphi * sinlambda_2),
dydlambda = 0.125 * F * (sin_2phi * sinlambda_2 - E * sinphi * cos2phi * sinlambda),
dydphi = 0.5 * F * (sin2phi * coslambda_2 + E * sin2lambda_2 * cosphi) + 0.5,
denominator = dxdphi * dydlambda - dydphi * dxdlambda,
dlambda = (fy * dxdphi - fx * dydphi) / denominator,
dphi = (fx * dydlambda - fy * dxdlambda) / denominator;
lambda -= dlambda, phi -= dphi;
} while ((abs(dlambda) > epsilon || abs(dphi) > epsilon) && --i > 0);
return [lambda, phi];
};
var winkel3 = function() {
return d3Geo.geoProjection(winkel3Raw)
.scale(158.837);
};
exports.geoAiry = airy;
exports.geoAiryRaw = airyRaw;
exports.geoAitoff = aitoff;
exports.geoAitoffRaw = aitoffRaw;
exports.geoArmadillo = armadillo;
exports.geoArmadilloRaw = armadilloRaw;
exports.geoAugust = august;
exports.geoAugustRaw = augustRaw;
exports.geoBaker = baker;
exports.geoBakerRaw = bakerRaw;
exports.geoBerghaus = berghaus;
exports.geoBerghausRaw = berghausRaw;
exports.geoBertin1953 = bertin;
exports.geoBertin1953Raw = bertin1953Raw;
exports.geoBoggs = boggs;
exports.geoBoggsRaw = boggsRaw;
exports.geoBonne = bonne;
exports.geoBonneRaw = bonneRaw;
exports.geoBottomley = bottomley;
exports.geoBottomleyRaw = bottomleyRaw;
exports.geoBromley = bromley;
exports.geoBromleyRaw = bromleyRaw;
exports.geoChamberlin = chamberlin;
exports.geoChamberlinRaw = chamberlinRaw;
exports.geoChamberlinAfrica = chamberlinAfrica;
exports.geoCollignon = collignon;
exports.geoCollignonRaw = collignonRaw;
exports.geoCraig = craig;
exports.geoCraigRaw = craigRaw;
exports.geoCraster = craster;
exports.geoCrasterRaw = crasterRaw;
exports.geoCylindricalEqualArea = cylindricalEqualArea;
exports.geoCylindricalEqualAreaRaw = cylindricalEqualAreaRaw;
exports.geoCylindricalStereographic = cylindricalStereographic;
exports.geoCylindricalStereographicRaw = cylindricalStereographicRaw;
exports.geoEckert1 = eckert1;
exports.geoEckert1Raw = eckert1Raw;
exports.geoEckert2 = eckert2;
exports.geoEckert2Raw = eckert2Raw;
exports.geoEckert3 = eckert3;
exports.geoEckert3Raw = eckert3Raw;
exports.geoEckert4 = eckert4;
exports.geoEckert4Raw = eckert4Raw;
exports.geoEckert5 = eckert5;
exports.geoEckert5Raw = eckert5Raw;
exports.geoEckert6 = eckert6;
exports.geoEckert6Raw = eckert6Raw;
exports.geoEisenlohr = eisenlohr;
exports.geoEisenlohrRaw = eisenlohrRaw;
exports.geoFahey = fahey;
exports.geoFaheyRaw = faheyRaw;
exports.geoFoucaut = foucaut;
exports.geoFoucautRaw = foucautRaw;
exports.geoGilbert = gilbert;
exports.geoGingery = gingery;
exports.geoGingeryRaw = gingeryRaw;
exports.geoGinzburg4 = ginzburg4;
exports.geoGinzburg4Raw = ginzburg4Raw;
exports.geoGinzburg5 = ginzburg5;
exports.geoGinzburg5Raw = ginzburg5Raw;
exports.geoGinzburg6 = ginzburg6;
exports.geoGinzburg6Raw = ginzburg6Raw;
exports.geoGinzburg8 = ginzburg8;
exports.geoGinzburg8Raw = ginzburg8Raw;
exports.geoGinzburg9 = ginzburg9;
exports.geoGinzburg9Raw = ginzburg9Raw;
exports.geoGringorten = gringorten;
exports.geoGringortenRaw = gringortenRaw;
exports.geoGuyou = guyou;
exports.geoGuyouRaw = guyouRaw;
exports.geoHammer = hammer;
exports.geoHammerRaw = hammerRaw;
exports.geoHammerRetroazimuthal = hammerRetroazimuthal;
exports.geoHammerRetroazimuthalRaw = hammerRetroazimuthalRaw;
exports.geoHealpix = healpix;
exports.geoHealpixRaw = healpixRaw;
exports.geoHill = hill;
exports.geoHillRaw = hillRaw;
exports.geoHomolosine = homolosine;
exports.geoHomolosineRaw = homolosineRaw;
exports.geoInterrupt = interrupt;
exports.geoInterruptedBoggs = boggs$1;
exports.geoInterruptedHomolosine = homolosine$1;
exports.geoInterruptedMollweide = mollweide$1;
exports.geoInterruptedMollweideHemispheres = mollweideHemispheres;
exports.geoInterruptedSinuMollweide = sinuMollweide$1;
exports.geoInterruptedSinusoidal = sinusoidal$1;
exports.geoKavrayskiy7 = kavrayskiy7;
exports.geoKavrayskiy7Raw = kavrayskiy7Raw;
exports.geoLagrange = lagrange;
exports.geoLagrangeRaw = lagrangeRaw;
exports.geoLarrivee = larrivee;
exports.geoLarriveeRaw = larriveeRaw;
exports.geoLaskowski = laskowski;
exports.geoLaskowskiRaw = laskowskiRaw;
exports.geoLittrow = littrow;
exports.geoLittrowRaw = littrowRaw;
exports.geoLoximuthal = loximuthal;
exports.geoLoximuthalRaw = loximuthalRaw;
exports.geoMiller = miller;
exports.geoMillerRaw = millerRaw;
exports.geoModifiedStereographic = modifiedStereographic;
exports.geoModifiedStereographicRaw = modifiedStereographicRaw;
exports.geoModifiedStereographicAlaska = modifiedStereographicAlaska;
exports.geoModifiedStereographicGs48 = modifiedStereographicGs48;
exports.geoModifiedStereographicGs50 = modifiedStereographicGs50;
exports.geoModifiedStereographicMiller = modifiedStereographicMiller;
exports.geoModifiedStereographicLee = modifiedStereographicLee;
exports.geoMollweide = mollweide;
exports.geoMollweideRaw = mollweideRaw;
exports.geoMtFlatPolarParabolic = mtFlatPolarParabolic;
exports.geoMtFlatPolarParabolicRaw = mtFlatPolarParabolicRaw;
exports.geoMtFlatPolarQuartic = mtFlatPolarQuartic;
exports.geoMtFlatPolarQuarticRaw = mtFlatPolarQuarticRaw;
exports.geoMtFlatPolarSinusoidal = mtFlatPolarSinusoidal;
exports.geoMtFlatPolarSinusoidalRaw = mtFlatPolarSinusoidalRaw;
exports.geoNaturalEarth = d3Geo.geoNaturalEarth1;
exports.geoNaturalEarthRaw = d3Geo.geoNaturalEarth1Raw;
exports.geoNaturalEarth2 = naturalEarth2;
exports.geoNaturalEarth2Raw = naturalEarth2Raw;
exports.geoNellHammer = nellHammer;
exports.geoNellHammerRaw = nellHammerRaw;
exports.geoPatterson = patterson;
exports.geoPattersonRaw = pattersonRaw;
exports.geoPolyconic = polyconic;
exports.geoPolyconicRaw = polyconicRaw;
exports.geoPolyhedral = polyhedral;
exports.geoPolyhedralButterfly = butterfly;
exports.geoPolyhedralCollignon = collignon$1;
exports.geoPolyhedralWaterman = waterman;
exports.geoProject = index;
exports.geoGringortenQuincuncial = gringorten$1;
exports.geoPeirceQuincuncial = peirce;
exports.geoPierceQuincuncial = peirce;
exports.geoQuantize = quantize;
exports.geoQuincuncial = quincuncial;
exports.geoRectangularPolyconic = rectangularPolyconic;
exports.geoRectangularPolyconicRaw = rectangularPolyconicRaw;
exports.geoRobinson = robinson;
exports.geoRobinsonRaw = robinsonRaw;
exports.geoSatellite = satellite;
exports.geoSatelliteRaw = satelliteRaw;
exports.geoSinuMollweide = sinuMollweide;
exports.geoSinuMollweideRaw = sinuMollweideRaw;
exports.geoSinusoidal = sinusoidal;
exports.geoSinusoidalRaw = sinusoidalRaw;
exports.geoStitch = stitch;
exports.geoTimes = times;
exports.geoTimesRaw = timesRaw;
exports.geoTwoPointAzimuthal = twoPointAzimuthal;
exports.geoTwoPointAzimuthalRaw = twoPointAzimuthalRaw;
exports.geoTwoPointAzimuthalUsa = twoPointAzimuthalUsa;
exports.geoTwoPointEquidistant = twoPointEquidistant;
exports.geoTwoPointEquidistantRaw = twoPointEquidistantRaw;
exports.geoTwoPointEquidistantUsa = twoPointEquidistantUsa;
exports.geoVanDerGrinten = vanDerGrinten;
exports.geoVanDerGrintenRaw = vanDerGrintenRaw;
exports.geoVanDerGrinten2 = vanDerGrinten2;
exports.geoVanDerGrinten2Raw = vanDerGrinten2Raw;
exports.geoVanDerGrinten3 = vanDerGrinten3;
exports.geoVanDerGrinten3Raw = vanDerGrinten3Raw;
exports.geoVanDerGrinten4 = vanDerGrinten4;
exports.geoVanDerGrinten4Raw = vanDerGrinten4Raw;
exports.geoWagner4 = wagner4;
exports.geoWagner4Raw = wagner4Raw;
exports.geoWagner6 = wagner6;
exports.geoWagner6Raw = wagner6Raw;
exports.geoWagner7 = wagner7;
exports.geoWagner7Raw = wagner7Raw;
exports.geoWiechel = wiechel;
exports.geoWiechelRaw = wiechelRaw;
exports.geoWinkel3 = winkel3;
exports.geoWinkel3Raw = winkel3Raw;
Object.defineProperty(exports, '__esModule', { value: true });
})));
/**********************
* @dataWorldTopo110m
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.dataWorldTopo110m = global.dataWorldTopo110m || {})));
}(this, function (exports) { 'use strict';
// dataWorldTopo110m ref. https://github.com/topojson/world-atlas
var dataWorldTopo110m = function dataWorldTopo110m(__mapper = {}) {
let props = __mapper("props")()
let f = props.lib
var state = Object.assign({},props.msg || {})
let data = {
"type": "Topology",
"objects": {
"countries": {
"type": "GeometryCollection",
"geometries": [{
"type": "Polygon",
"arcs": [[0,
1,
2,
3,
4,
5]],
"id": "004"
},
{
"type": "MultiPolygon",
"arcs": [[[6,
7,
8,
9]],
[[10,
11,
12]]],
"id": "024"
},
{
"type": "Polygon",
"arcs": [[13,
14,
15,
16,
17]],
"id": "008"
},
{
"type": "Polygon",
"arcs": [[18,
19,
20,
21,
22]],
"id": "784"
},
{
"type": "MultiPolygon",
"arcs": [[[23,
24]],
[[25,
26,
27,
28,
29,
30]]],
"id": "032"
},
{
"type": "Polygon",
"arcs": [[31,
32,
33,
34,
35]],
"id": "051"
},
{
"type": "MultiPolygon",
"arcs": [[[36]],
[[37]],
[[38]],
[[39]],
[[40]],
[[41]],
[[42]],
[[43]]],
"id": "010"
},
{
"type": "Polygon",
"arcs": [[44]],
"id": "260"
},
{
"type": "MultiPolygon",
"arcs": [[[45]],
[[46]]],
"id": "036"
},
{
"type": "Polygon",
"arcs": [[47,
48,
49,
50,
51,
52,
53]],
"id": "040"
},
{
"type": "MultiPolygon",
"arcs": [[[54,
-35]],
[[55,
56,
-33,
57,
58]]],
"id": "031"
},
{
"type": "Polygon",
"arcs": [[59,
60,
61]],
"id": "108"
},
{
"type": "Polygon",
"arcs": [[62,
63,
64,
65,
66]],
"id": "056"
},
{
"type": "Polygon",
"arcs": [[67,
68,
69,
70,
71]],
"id": "204"
},
{
"type": "Polygon",
"arcs": [[72,
73,
74,
-70,
75,
76]],
"id": "854"
},
{
"type": "Polygon",
"arcs": [[77,
78,
79]],
"id": "050"
},
{
"type": "Polygon",
"arcs": [[80,
81,
82,
83,
84,
85]],
"id": "100"
},
{
"type": "MultiPolygon",
"arcs": [[[86]],
[[87]],
[[88]]],
"id": "044"
},
{
"type": "Polygon",
"arcs": [[89,
90,
91]],
"id": "070"
},
{
"type": "Polygon",
"arcs": [[92,
93,
94,
95,
96]],
"id": "112"
},
{
"type": "Polygon",
"arcs": [[97,
98,
99]],
"id": "084"
},
{
"type": "Polygon",
"arcs": [[100,
101,
102,
103,
-31]],
"id": "068"
},
{
"type": "Polygon",
"arcs": [[-27,
104,
-103,
105,
106,
107,
108,
109,
110,
111,
112]],
"id": "076"
},
{
"type": "Polygon",
"arcs": [[113,
114]],
"id": "096"
},
{
"type": "Polygon",
"arcs": [[115,
116]],
"id": "064"
},
{
"type": "Polygon",
"arcs": [[117,
118,
119,
120]],
"id": "072"
},
{
"type": "Polygon",
"arcs": [[121,
122,
123,
124,
125,
126,
127]],
"id": "140"
},
{
"type": "MultiPolygon",
"arcs": [[[128]],
[[129]],
[[130]],
[[131]],
[[132]],
[[133]],
[[134]],
[[135]],
[[136]],
[[137]],
[[138,
139,
140,
141]],
[[142]],
[[143]],
[[144]],
[[145]],
[[146]],
[[147]],
[[148]],
[[149]],
[[150]],
[[151]],
[[152]],
[[153]],
[[154]],
[[155]],
[[156]],
[[157]],
[[158]],
[[159]],
[[160]]],
"id": "124"
},
{
"type": "Polygon",
"arcs": [[-51,
161,
162,
163]],
"id": "756"
},
{
"type": "MultiPolygon",
"arcs": [[[-24,
164]],
[[-30,
165,
166,
-101]]],
"id": "152"
},
{
"type": "MultiPolygon",
"arcs": [[[167]],
[[168,
169,
170,
171,
172,
173,
-117,
174,
175,
176,
177,
-4,
178,
179,
180,
181,
182,
183]]],
"id": "156"
},
{
"type": "Polygon",
"arcs": [[184,
185,
186,
187,
-73,
188]],
"id": "384"
},
{
"type": "Polygon",
"arcs": [[189,
190,
191,
192,
193,
194,
-128,
195]],
"id": "120"
},
{
"type": "Polygon",
"arcs": [[196,
197,
-60,
198,
199,
200,
201,
-10,
202,
-13,
203,
-126,
204]],
"id": "180"
},
{
"type": "Polygon",
"arcs": [[-12,
205,
206,
-196,
-127,
-204]],
"id": "178"
},
{
"type": "Polygon",
"arcs": [[207,
208,
209,
210,
211,
-107,
212]],
"id": "170"
},
{
"type": "Polygon",
"arcs": [[213,
214,
215,
216]],
"id": "188"
},
{
"type": "Polygon",
"arcs": [[217]],
"id": "192"
},
{
"type": "Polygon",
"arcs": [[218,
219]],
"id": "-99"
},
{
"type": "Polygon",
"arcs": [[220,
-220]],
"id": "196"
},
{
"type": "Polygon",
"arcs": [[-53,
221,
222,
223]],
"id": "203"
},
{
"type": "Polygon",
"arcs": [[224,
225,
-222,
-52,
-164,
226,
227,
-64,
228,
229,
230]],
"id": "276"
},
{
"type": "Polygon",
"arcs": [[231,
232,
233,
234]],
"id": "262"
},
{
"type": "MultiPolygon",
"arcs": [[[235]],
[[-231,
236]]],
"id": "208"
},
{
"type": "Polygon",
"arcs": [[237,
238]],
"id": "214"
},
{
"type": "Polygon",
"arcs": [[239,
240,
241,
242,
243,
244,
245,
246]],
"id": "012"
},
{
"type": "Polygon",
"arcs": [[247,
-208,
248]],
"id": "218"
},
{
"type": "Polygon",
"arcs": [[249,
250,
251,
252,
253]],
"id": "818"
},
{
"type": "Polygon",
"arcs": [[254,
255,
256,
-235]],
"id": "232"
},
{
"type": "Polygon",
"arcs": [[257,
258,
259,
260]],
"id": "724"
},
{
"type": "Polygon",
"arcs": [[261,
262,
263]],
"id": "233"
},
{
"type": "Polygon",
"arcs": [[-234,
264,
265,
266,
267,
268,
269,
-255]],
"id": "231"
},
{
"type": "Polygon",
"arcs": [[270,
271,
272,
273]],
"id": "246"
},
{
"type": "MultiPolygon",
"arcs": [[[274]],
[[275]]],
"id": "242"
},
{
"type": "Polygon",
"arcs": [[276]],
"id": "238"
},
{
"type": "MultiPolygon",
"arcs": [[[277,
278,
279,
-111]],
[[280]],
[[281,
-227,
-163,
282,
283,
-259,
284,
-66]]],
"id": "250"
},
{
"type": "Polygon",
"arcs": [[285,
286,
-190,
-207]],
"id": "266"
},
{
"type": "MultiPolygon",
"arcs": [[[287,
288]],
[[289]]],
"id": "826"
},
{
"type": "Polygon",
"arcs": [[290,
291,
-58,
-32,
292]],
"id": "268"
},
{
"type": "Polygon",
"arcs": [[293,
-189,
-77,
294]],
"id": "288"
},
{
"type": "Polygon",
"arcs": [[295,
296,
297,
298,
299,
300,
-187]],
"id": "324"
},
{
"type": "Polygon",
"arcs": [[301,
302]],
"id": "270"
},
{
"type": "Polygon",
"arcs": [[303,
304,
-299]],
"id": "624"
},
{
"type": "Polygon",
"arcs": [[305,
-191,
-287]],
"id": "226"
},
{
"type": "MultiPolygon",
"arcs": [[[306]],
[[307,
-15,
308,
-84,
309]]],
"id": "300"
},
{
"type": "Polygon",
"arcs": [[310]],
"id": "304"
},
{
"type": "Polygon",
"arcs": [[311,
312,
-100,
313,
314,
315]],
"id": "320"
},
{
"type": "Polygon",
"arcs": [[316,
317,
-109,
318]],
"id": "328"
},
{
"type": "Polygon",
"arcs": [[319,
320,
-315,
321,
322]],
"id": "340"
},
{
"type": "Polygon",
"arcs": [[323,
-92,
324,
325,
326,
327]],
"id": "191"
},
{
"type": "Polygon",
"arcs": [[-239,
328]],
"id": "332"
},
{
"type": "Polygon",
"arcs": [[-48,
329,
330,
331,
332,
-328,
333]],
"id": "348"
},
{
"type": "MultiPolygon",
"arcs": [[[334]],
[[335,
336]],
[[337]],
[[338]],
[[339]],
[[340]],
[[341]],
[[342]],
[[343,
344]],
[[345]],
[[346]],
[[347,
348]],
[[349]]],
"id": "360"
},
{
"type": "Polygon",
"arcs": [[-177,
350,
-175,
-116,
-174,
351,
-80,
352,
353]],
"id": "356"
},
{
"type": "Polygon",
"arcs": [[354,
-288]],
"id": "372"
},
{
"type": "Polygon",
"arcs": [[355,
-6,
356,
357,
358,
359,
-55,
-34,
-57,
360]],
"id": "364"
},
{
"type": "Polygon",
"arcs": [[361,
362,
363,
364,
365,
366,
-359]],
"id": "368"
},
{
"type": "Polygon",
"arcs": [[367]],
"id": "352"
},
{
"type": "Polygon",
"arcs": [[368,
369,
370,
-254,
371,
372,
373]],
"id": "376"
},
{
"type": "MultiPolygon",
"arcs": [[[374]],
[[375]],
[[376,
377,
-283,
-162,
-50]]],
"id": "380"
},
{
"type": "Polygon",
"arcs": [[378]],
"id": "388"
},
{
"type": "Polygon",
"arcs": [[-369,
379,
-365,
380,
381,
-371,
382]],
"id": "400"
},
{
"type": "MultiPolygon",
"arcs": [[[383]],
[[384]],
[[385]]],
"id": "392"
},
{
"type": "Polygon",
"arcs": [[386,
387,
388,
389,
-181,
390]],
"id": "398"
},
{
"type": "Polygon",
"arcs": [[391,
392,
393,
394,
-267,
395]],
"id": "404"
},
{
"type": "Polygon",
"arcs": [[-391,
-180,
396,
397]],
"id": "417"
},
{
"type": "Polygon",
"arcs": [[398,
399,
400,
401]],
"id": "116"
},
{
"type": "Polygon",
"arcs": [[402,
403]],
"id": "410"
},
{
"type": "Polygon",
"arcs": [[-18,
404,
405,
406]],
"id": "-99"
},
{
"type": "Polygon",
"arcs": [[407,
408,
-363]],
"id": "414"
},
{
"type": "Polygon",
"arcs": [[409,
410,
-172,
411,
-400]],
"id": "418"
},
{
"type": "Polygon",
"arcs": [[-373,
412,
413]],
"id": "422"
},
{
"type": "Polygon",
"arcs": [[414,
415,
-296,
-186]],
"id": "430"
},
{
"type": "Polygon",
"arcs": [[416,
-247,
417,
418,
-252,
419,
420]],
"id": "434"
},
{
"type": "Polygon",
"arcs": [[421]],
"id": "144"
},
{
"type": "Polygon",
"arcs": [[422]],
"id": "426"
},
{
"type": "Polygon",
"arcs": [[423,
424,
425,
-93,
426]],
"id": "440"
},
{
"type": "Polygon",
"arcs": [[-228,
-282,
-65]],
"id": "442"
},
{
"type": "Polygon",
"arcs": [[427,
-264,
428,
-94,
-426]],
"id": "428"
},
{
"type": "Polygon",
"arcs": [[-244,
429,
430]],
"id": "504"
},
{
"type": "Polygon",
"arcs": [[431,
432]],
"id": "498"
},
{
"type": "Polygon",
"arcs": [[433]],
"id": "450"
},
{
"type": "Polygon",
"arcs": [[434,
-98,
-313,
435,
436]],
"id": "484"
},
{
"type": "Polygon",
"arcs": [[-407,
437,
-85,
-309,
-14]],
"id": "807"
},
{
"type": "Polygon",
"arcs": [[438,
-241,
439,
-74,
-188,
-301,
440]],
"id": "466"
},
{
"type": "Polygon",
"arcs": [[441,
-78,
-352,
-173,
-411,
442]],
"id": "104"
},
{
"type": "Polygon",
"arcs": [[443,
-325,
-91,
444,
-405,
-17]],
"id": "499"
},
{
"type": "Polygon",
"arcs": [[445,
-183]],
"id": "496"
},
{
"type": "Polygon",
"arcs": [[446,
447,
448,
449,
450,
451,
452,
453]],
"id": "508"
},
{
"type": "Polygon",
"arcs": [[454,
455,
456,
-242,
-439]],
"id": "478"
},
{
"type": "Polygon",
"arcs": [[-454,
457,
458]],
"id": "454"
},
{
"type": "MultiPolygon",
"arcs": [[[459,
460]],
[[-348,
461,
-115,
462]]],
"id": "458"
},
{
"type": "Polygon",
"arcs": [[463,
-8,
464,
-119,
465]],
"id": "516"
},
{
"type": "Polygon",
"arcs": [[466]],
"id": "540"
},
{
"type": "Polygon",
"arcs": [[-75,
-440,
-240,
-417,
467,
-194,
468,
-71]],
"id": "562"
},
{
"type": "Polygon",
"arcs": [[469,
-72,
-469,
-193]],
"id": "566"
},
{
"type": "Polygon",
"arcs": [[470,
-323,
471,
-215]],
"id": "558"
},
{
"type": "Polygon",
"arcs": [[-229,
-63,
472]],
"id": "528"
},
{
"type": "MultiPolygon",
"arcs": [[[473,
-274,
474,
475]],
[[476]],
[[477]],
[[478]]],
"id": "578"
},
{
"type": "Polygon",
"arcs": [[-351,
-176]],
"id": "524"
},
{
"type": "MultiPolygon",
"arcs": [[[479]],
[[480]]],
"id": "554"
},
{
"type": "MultiPolygon",
"arcs": [[[481,
482,
-22,
483]],
[[-20,
484]]],
"id": "512"
},
{
"type": "Polygon",
"arcs": [[-178,
-354,
485,
-357,
-5]],
"id": "586"
},
{
"type": "Polygon",
"arcs": [[486,
-217,
487,
-210]],
"id": "591"
},
{
"type": "Polygon",
"arcs": [[-167,
488,
-249,
-213,
-106,
-102]],
"id": "604"
},
{
"type": "MultiPolygon",
"arcs": [[[489]],
[[490]],
[[491]],
[[492]],
[[493]],
[[494]],
[[495]]],
"id": "608"
},
{
"type": "MultiPolygon",
"arcs": [[[496]],
[[497]],
[[-344,
498]],
[[499]]],
"id": "598"
},
{
"type": "Polygon",
"arcs": [[-226,
500,
501,
-427,
-97,
502,
503,
-223]],
"id": "616"
},
{
"type": "Polygon",
"arcs": [[504]],
"id": "630"
},
{
"type": "Polygon",
"arcs": [[505,
506,
-404,
507,
-169]],
"id": "408"
},
{
"type": "Polygon",
"arcs": [[-261,
508]],
"id": "620"
},
{
"type": "Polygon",
"arcs": [[-104,
-105,
-26]],
"id": "600"
},
{
"type": "Polygon",
"arcs": [[-383,
-370]],
"id": "275"
},
{
"type": "Polygon",
"arcs": [[509,
510]],
"id": "634"
},
{
"type": "Polygon",
"arcs": [[511,
-433,
512,
513,
-81,
514,
-332]],
"id": "642"
},
{
"type": "MultiPolygon",
"arcs": [[[515]],
[[-502,
516,
-424]],
[[517]],
[[518]],
[[519]],
[[520]],
[[521]],
[[-506,
-184,
-446,
-182,
-390,
522,
-59,
-292,
523,
524,
-95,
-429,
-263,
525,
-271,
-474,
526]],
[[527]],
[[528]],
[[529]]],
"id": "643"
},
{
"type": "Polygon",
"arcs": [[530,
-61,
-198,
531]],
"id": "646"
},
{
"type": "Polygon",
"arcs": [[-243,
-457,
532,
-430]],
"id": "732"
},
{
"type": "Polygon",
"arcs": [[533,
-381,
-364,
-409,
534,
-511,
535,
-23,
-483,
536]],
"id": "682"
},
{
"type": "Polygon",
"arcs": [[537,
538,
-123,
539,
-420,
-251,
540,
-256,
-270,
541]],
"id": "729"
},
{
"type": "Polygon",
"arcs": [[542,
-268,
-395,
543,
-205,
-125,
544,
-538]],
"id": "728"
},
{
"type": "Polygon",
"arcs": [[545,
-455,
-441,
-300,
-305,
546,
-303]],
"id": "686"
},
{
"type": "MultiPolygon",
"arcs": [[[547]],
[[548]],
[[549]],
[[550]],
[[551]]],
"id": "090"
},
{
"type": "Polygon",
"arcs": [[552,
-297,
-416]],
"id": "694"
},
{
"type": "Polygon",
"arcs": [[553,
-316,
-321]],
"id": "222"
},
{
"type": "Polygon",
"arcs": [[-265,
-233,
554,
555]],
"id": "-99"
},
{
"type": "Polygon",
"arcs": [[-396,
-266,
-556,
556]],
"id": "706"
},
{
"type": "Polygon",
"arcs": [[-86,
-438,
-406,
-445,
-90,
-324,
-333,
-515]],
"id": "688"
},
{
"type": "Polygon",
"arcs": [[557,
-279,
558,
-110,
-318]],
"id": "740"
},
{
"type": "Polygon",
"arcs": [[-504,
559,
-330,
-54,
-224]],
"id": "703"
},
{
"type": "Polygon",
"arcs": [[-49,
-334,
-327,
560,
-377]],
"id": "705"
},
{
"type": "Polygon",
"arcs": [[-475,
-273,
561]],
"id": "752"
},
{
"type": "Polygon",
"arcs": [[562,
-450]],
"id": "748"
},
{
"type": "Polygon",
"arcs": [[-380,
-374,
-414,
563,
564,
-366]],
"id": "760"
},
{
"type": "Polygon",
"arcs": [[-468,
-421,
-540,
-122,
-195]],
"id": "148"
},
{
"type": "Polygon",
"arcs": [[565,
-295,
-76,
-69]],
"id": "768"
},
{
"type": "Polygon",
"arcs": [[566,
-461,
567,
-443,
-410,
-399]],
"id": "764"
},
{
"type": "Polygon",
"arcs": [[-397,
-179,
-3,
568]],
"id": "762"
},
{
"type": "Polygon",
"arcs": [[-356,
569,
-388,
570,
-1]],
"id": "795"
},
{
"type": "Polygon",
"arcs": [[571,
-336]],
"id": "626"
},
{
"type": "Polygon",
"arcs": [[572]],
"id": "780"
},
{
"type": "Polygon",
"arcs": [[-246,
573,
-418]],
"id": "788"
},
{
"type": "MultiPolygon",
"arcs": [[[-293,
-36,
-360,
-367,
-565,
574]],
[[-310,
-83,
575]]],
"id": "792"
},
{
"type": "Polygon",
"arcs": [[576]],
"id": "158"
},
{
"type": "Polygon",
"arcs": [[-393,
577,
-447,
-459,
578,
-201,
579,
-199,
-62,
-531,
580]],
"id": "834"
},
{
"type": "Polygon",
"arcs": [[-532,
-197,
-544,
-394,
-581]],
"id": "800"
},
{
"type": "Polygon",
"arcs": [[-525,
581,
-513,
-432,
-512,
-331,
-560,
-503,
-96]],
"id": "804"
},
{
"type": "Polygon",
"arcs": [[-113,
582,
-28]],
"id": "858"
},
{
"type": "MultiPolygon",
"arcs": [[[583]],
[[584]],
[[585]],
[[586]],
[[587]],
[[588,
-437,
589,
-139]],
[[590]],
[[591]],
[[592]],
[[-141,
593]]],
"id": "840"
},
{
"type": "Polygon",
"arcs": [[-571,
-387,
-398,
-569,
-2]],
"id": "860"
},
{
"type": "Polygon",
"arcs": [[594,
-319,
-108,
-212]],
"id": "862"
},
{
"type": "Polygon",
"arcs": [[595,
-401,
-412,
-171]],
"id": "704"
},
{
"type": "MultiPolygon",
"arcs": [[[596]],
[[597]]],
"id": "548"
},
{
"type": "Polygon",
"arcs": [[598,
-537,
-482]],
"id": "887"
},
{
"type": "Polygon",
"arcs": [[-466,
-118,
599,
-451,
-563,
-449,
600],
[-423]],
"id": "710"
},
{
"type": "Polygon",
"arcs": [[-458,
-453,
601,
-120,
-465,
-7,
-202,
-579]],
"id": "894"
},
{
"type": "Polygon",
"arcs": [[-600,
-121,
-602,
-452]],
"id": "716"
}]
},
"land": {
"type": "GeometryCollection",
"geometries": [{
"type": "MultiPolygon",
"arcs": [[[595,
401,
566,
459,
567,
441,
78,
352,
485,
357,
361,
407,
534,
509,
535,
18,
484,
20,
483,
598,
533,
381,
249,
540,
256,
231,
554,
556,
391,
577,
447,
600,
463,
8,
202,
10,
205,
285,
305,
191,
469,
67,
565,
293,
184,
414,
552,
297,
303,
546,
301,
545,
455,
532,
430,
244,
573,
418,
252,
371,
412,
563,
574,
290,
523,
581,
513,
81,
575,
307,
15,
443,
325,
560,
377,
283,
259,
508,
257,
284,
66,
472,
229,
236,
224,
500,
516,
424,
427,
261,
525,
271,
561,
475,
526,
506,
402,
507,
169],
[123,
544,
538],
[199,
579],
[542,
268,
541],
[388,
522,
55,
360,
569]],
[[24,
164]],
[[582,
28,
165,
488,
247,
208,
486,
213,
470,
319,
553,
311,
435,
589,
139,
593,
141,
588,
434,
98,
313,
321,
471,
215,
487,
210,
594,
316,
557,
279,
111],
[558,
277]],
[[36]],
[[37]],
[[38]],
[[39]],
[[40]],
[[41]],
[[42]],
[[43]],
[[44]],
[[45]],
[[46]],
[[86]],
[[87]],
[[88]],
[[461,
113,
462,
348]],
[[128]],
[[129]],
[[130]],
[[131]],
[[132]],
[[133]],
[[134]],
[[135]],
[[136]],
[[137]],
[[142]],
[[143]],
[[144]],
[[145]],
[[146]],
[[147]],
[[148]],
[[149]],
[[150]],
[[151]],
[[152]],
[[153]],
[[154]],
[[155]],
[[156]],
[[157]],
[[158]],
[[159]],
[[160]],
[[167]],
[[217]],
[[218,
220]],
[[235]],
[[237,
328]],
[[274]],
[[275]],
[[276]],
[[280]],
[[288,
354]],
[[289]],
[[306]],
[[310]],
[[334]],
[[336,
571]],
[[337]],
[[338]],
[[339]],
[[340]],
[[341]],
[[342]],
[[344,
498]],
[[345]],
[[346]],
[[349]],
[[367]],
[[374]],
[[375]],
[[378]],
[[383]],
[[384]],
[[385]],
[[421]],
[[433]],
[[466]],
[[476]],
[[477]],
[[478]],
[[479]],
[[480]],
[[489]],
[[490]],
[[491]],
[[492]],
[[493]],
[[494]],
[[495]],
[[496]],
[[497]],
[[499]],
[[504]],
[[515]],
[[517]],
[[518]],
[[519]],
[[520]],
[[521]],
[[527]],
[[528]],
[[529]],
[[547]],
[[548]],
[[549]],
[[550]],
[[551]],
[[572]],
[[576]],
[[583]],
[[584]],
[[585]],
[[586]],
[[587]],
[[590]],
[[591]],
[[592]],
[[596]],
[[597]]]
}]
}
},
"arcs": [[[67002,
71642],
[284,
-224],
[209,
79],
[58,
268],
[219,
89],
[157,
180],
[55,
472],
[234,
114],
[44,
211],
[131,
-158],
[84,
-19]],
[[68477,
72654],
[154,
-4],
[210,
-124]],
[[68841,
72526],
[85,
-72],
[201,
189],
[93,
-114],
[90,
271],
[166,
-12],
[43,
86],
[29,
239],
[120,
205],
[150,
-134],
[-30,
-181],
[84,
-28],
[-26,
-496],
[110,
-194],
[97,
125],
[123,
58],
[173,
265],
[192,
-44],
[286,
-1]],
[[70827,
72688],
[50,
-169]],
[[70877,
72519],
[-162,
-67],
[-141,
-109],
[-319,
-68],
[-298,
-124],
[-163,
-258],
[66,
-250],
[32,
-294],
[-139,
-248],
[12,
-227],
[-76,
-213],
[-265,
18],
[110,
-390],
[-177,
-150],
[-118,
-356],
[15,
-355],
[-108,
-166],
[-103,
55],
[-212,
-77],
[-31,
-166],
[-207,
1],
[-154,
-334],
[-10,
-503],
[-361,
-246],
[-194,
52],
[-56,
-129],
[-166,
75],
[-278,
-88],
[-465,
301]],
[[66909,
68203],
[252,
536],
[-23,
380],
[-210,
100],
[-22,
375],
[-91,
472],
[119,
323],
[-121,
87],
[76,
430],
[113,
736]],
[[56642,
44124],
[29,
-184],
[-32,
-286],
[49,
-277],
[-41,
-222],
[24,
-203],
[-579,
7],
[-13,
-1880],
[188,
-483],
[181,
-369]],
[[56448,
40227],
[-510,
-241],
[-673,
83],
[-192,
284],
[-1126,
-26],
[-42,
-41],
[-166,
267],
[-180,
17],
[-166,
-100],
[-134,
-113]],
[[53259,
40357],
[-26,
372],
[38,
519],
[96,
541],
[15,
254],
[90,
532],
[66,
243],
[159,
386],
[90,
263],
[29,
438],
[-15,
335],
[-83,
211],
[-74,
358],
[-68,
355],
[15,
122],
[85,
235],
[-84,
570],
[-57,
396],
[-139,
374],
[26,
115]],
[[53422,
46976],
[115,
79],
[80,
-11],
[98,
71],
[820,
-8],
[68,
-440],
[80,
-354],
[64,
-191],
[106,
-309],
[184,
47],
[91,
83],
[154,
-83],
[42,
148],
[69,
344],
[172,
23],
[15,
103],
[142,
2],
[-24,
-213],
[337,
5],
[5,
-372],
[56,
-228],
[-41,
-356],
[21,
-363],
[93,
-219],
[-15,
-703],
[68,
54],
[121,
-15],
[172,
89],
[127,
-35]],
[[53383,
47159],
[-74,
444]],
[[53309,
47603],
[112,
255],
[84,
100],
[104,
-203]],
[[53609,
47755],
[-101,
-124],
[-45,
-152],
[-9,
-258],
[-71,
-62]],
[[55719,
75309],
[-35,
-201],
[39,
-254],
[115,
-144]],
[[55838,
74710],
[-5,
-155],
[-91,
-85],
[-16,
-192],
[-129,
-287]],
[[55597,
73991],
[-48,
41],
[-5,
130],
[-154,
199],
[-24,
281],
[23,
403],
[38,
184],
[-47,
93]],
[[55380,
75322],
[-18,
188],
[120,
291],
[18,
-111],
[75,
52]],
[[55575,
75742],
[59,
-159],
[66,
-60],
[19,
-214]],
[[64327,
64904],
[49,
29],
[11,
-162],
[217,
93],
[230,
-15],
[168,
-18],
[190,
400],
[207,
379],
[176,
364]],
[[65575,
65974],
[52,
-202]],
[[65627,
65772],
[38,
-466]],
[[65665,
65306],
[-142,
-3],
[-23,
-384],
[50,
-82],
[-126,
-117],
[-1,
-241],
[-81,
-245],
[-7,
-238]],
[[65335,
63996],
[-56,
-125],
[-835,
298],
[-106,
599],
[-11,
136]],
[[31400,
18145],
[-168,
16],
[-297,
1],
[0,
1319]],
[[30935,
19481],
[106,
-274],
[139,
-443],
[361,
-355],
[389,
-147],
[-125,
-296],
[-264,
-29],
[-141,
208]],
[[32587,
37434],
[511,
-964],
[227,
-89],
[339,
-437],
[286,
-231],
[40,
-261],
[-273,
-898],
[280,
-160],
[312,
-91],
[220,
95],
[252,
453],
[45,
521]],
[[34826,
35372],
[138,
114],
[139,
-341],
[-6,
-472],
[-234,
-326],
[-186,
-241],
[-314,
-573],
[-370,
-806]],
[[33993,
32727],
[-70,
-473],
[-74,
-607],
[3,
-588],
[-61,
-132],
[-21,
-382]],
[[33770,
30545],
[-19,
-308],
[353,
-506],
[-38,
-408],
[173,
-257],
[-14,
-289],
[-267,
-757],
[-412,
-317],
[-557,
-123],
[-305,
59],
[59,
-352],
[-57,
-442],
[51,
-298],
[-167,
-208],
[-284,
-82],
[-267,
216],
[-108,
-155],
[39,
-587],
[188,
-178],
[152,
186],
[82,
-307],
[-255,
-183],
[-223,
-367],
[-41,
-595],
[-66,
-316],
[-262,
-2],
[-218,
-302],
[-80,
-443],
[273,
-433],
[266,
-119],
[-96,
-531],
[-328,
-333],
[-180,
-692],
[-254,
-234],
[-113,
-276],
[89,
-614],
[185,
-342],
[-117,
30]],
[[30952,
19680],
[-257,
93],
[-672,
79],
[-115,
344],
[6,
443],
[-185,
-38],
[-98,
214],
[-24,
626],
[213,
260],
[88,
375],
[-33,
299],
[148,
504],
[101,
782],
[-30,
347],
[122,
112],
[-30,
223],
[-129,
118],
[92,
248],
[-126,
224],
[-65,
682],
[112,
120],
[-47,
720],
[65,
605],
[75,
527],
[166,
215],
[-84,
576],
[-1,
543],
[210,
386],
[-7,
494],
[159,
576],
[1,
544],
[-72,
108],
[-128,
1020],
[171,
607],
[-27,
572],
[100,
537],
[182,
555],
[196,
367],
[-83,
232],
[58,
190],
[-9,
985],
[302,
291],
[96,
614],
[-34,
148]],
[[31359,
37147],
[231,
534],
[364,
-144],
[163,
-427],
[109,
475],
[316,
-24],
[45,
-127]],
[[62106,
74858],
[386,
92]],
[[62492,
74950],
[57,
-155],
[106,
-103],
[-56,
-148],
[148,
-202],
[-78,
-189],
[118,
-160],
[124,
-97],
[7,
-410]],
[[62918,
73486],
[-101,
-17]],
[[62817,
73469],
[-113,
342],
[1,
91],
[-123,
-2],
[-82,
159],
[-58,
-16]],
[[62442,
74043],
[-109,
172],
[-207,
147],
[27,
288],
[-47,
208]],
[[33452,
3290],
[-82,
-301],
[-81,
-266],
[-582,
81],
[-621,
-35],
[-348,
197],
[0,
23],
[-152,
174],
[625,
-23],
[599,
-58],
[207,
243],
[147,
208],
[288,
-243]],
[[5775,
3611],
[-533,
-81],
[-364,
208],
[-163,
209],
[-11,
35],
[-180,
162],
[169,
220],
[517,
-93],
[277,
-185],
[212,
-209],
[76,
-266]],
[[37457,
4468],
[342,
-255],
[120,
-359],
[33,
-254],
[11,
-301],
[-430,
-186],
[-452,
-150],
[-522,
-139],
[-582,
-116],
[-658,
35],
[-365,
197],
[49,
243],
[593,
162],
[239,
197],
[174,
254],
[126,
220],
[168,
209],
[180,
243],
[141,
0],
[414,
127],
[419,
-127]],
[[16330,
7154],
[359,
-93],
[332,
104],
[-158,
-208],
[-261,
-151],
[-386,
47],
[-278,
208],
[60,
197],
[332,
-104]],
[[15122,
7165],
[425,
-231],
[-164,
23],
[-359,
58],
[-381,
162],
[202,
127],
[277,
-139]],
[[22505,
8080],
[305,
-81],
[304,
69],
[163,
-335],
[-217,
46],
[-337,
-23],
[-343,
23],
[-376,
-35],
[-283,
116],
[-146,
243],
[174,
104],
[353,
-81],
[403,
-46]],
[[30985,
8657],
[33,
-266],
[-49,
-231],
[-76,
-220],
[-326,
-81],
[-311,
-116],
[-364,
11],
[136,
232],
[-327,
-81],
[-310,
-81],
[-212,
174],
[-16,
243],
[305,
231],
[190,
70],
[321,
-23],
[82,
301],
[16,
219],
[-6,
475],
[158,
278],
[256,
93],
[147,
-220],
[65,
-220],
[120,
-267],
[92,
-254],
[76,
-267]],
[[0,
529],
[16,
-5],
[245,
344],
[501,
-185],
[32,
21],
[294,
188],
[38,
-7],
[32,
-4],
[402,
-246],
[352,
246],
[63,
34],
[816,
104],
[265,
-138],
[130,
-71],
[419,
-196],
[789,
-151],
[625,
-185],
[1072,
-139],
[800,
162],
[1181,
-116],
[669,
-185],
[734,
174],
[773,
162],
[60,
278],
[-1094,
23],
[-898,
139],
[-234,
231],
[-745,
128],
[49,
266],
[103,
243],
[104,
220],
[-55,
243],
[-462,
162],
[-212,
209],
[-430,
185],
[675,
-35],
[642,
93],
[402,
-197],
[495,
173],
[457,
220],
[223,
197],
[-98,
243],
[-359,
162],
[-408,
174],
[-571,
35],
[-500,
81],
[-539,
58],
[-180,
220],
[-359,
185],
[-217,
208],
[-87,
672],
[136,
-58],
[250,
-185],
[457,
58],
[441,
81],
[228,
-255],
[441,
58],
[370,
127],
[348,
162],
[315,
197],
[419,
58],
[-11,
220],
[-97,
220],
[81,
208],
[359,
104],
[163,
-196],
[425,
115],
[321,
151],
[397,
12],
[375,
57],
[376,
139],
[299,
128],
[337,
127],
[218,
-35],
[190,
-46],
[414,
81],
[370,
-104],
[381,
11],
[364,
81],
[375,
-57],
[414,
-58],
[386,
23],
[403,
-12],
[413,
-11],
[381,
23],
[283,
174],
[337,
92],
[349,
-127],
[331,
104],
[300,
208],
[179,
-185],
[98,
-208],
[180,
-197],
[288,
174],
[332,
-220],
[375,
-70],
[321,
-162],
[392,
35],
[354,
104],
[418,
-23],
[376,
-81],
[381,
-104],
[147,
254],
[-180,
197],
[-136,
209],
[-359,
46],
[-158,
220],
[-60,
220],
[-98,
440],
[213,
-81],
[364,
-35],
[359,
35],
[327,
-93],
[283,
-174],
[119,
-208],
[376,
-35],
[359,
81],
[381,
116],
[342,
70],
[283,
-139],
[370,
46],
[239,
451],
[224,
-266],
[321,
-104],
[348,
58],
[228,
-232],
[365,
-23],
[337,
-69],
[332,
-128],
[218,
220],
[108,
209],
[278,
-232],
[381,
58],
[283,
-127],
[190,
-197],
[370,
58],
[288,
127],
[283,
151],
[337,
81],
[392,
69],
[354,
81],
[272,
127],
[163,
186],
[65,
254],
[-32,
244],
[-87,
231],
[-98,
232],
[-87,
231],
[-71,
209],
[-16,
231],
[27,
232],
[130,
220],
[109,
243],
[44,
231],
[-55,
255],
[-32,
232],
[136,
266],
[152,
173],
[180,
220],
[190,
186],
[223,
173],
[109,
255],
[152,
162],
[174,
151],
[267,
34],
[174,
186],
[196,
115],
[228,
70],
[202,
150],
[157,
186],
[218,
69],
[163,
-151],
[-103,
-196],
[-283,
-174],
[-120,
-127],
[-206,
92],
[-229,
-58],
[-190,
-139],
[-202,
-150],
[-136,
-174],
[-38,
-231],
[17,
-220],
[130,
-197],
[-190,
-139],
[-261,
-46],
[-153,
-197],
[-163,
-185],
[-174,
-255],
[-44,
-220],
[98,
-243],
[147,
-185],
[229,
-139],
[212,
-185],
[114,
-232],
[60,
-220],
[82,
-232],
[130,
-196],
[82,
-220],
[38,
-544],
[81,
-220],
[22,
-232],
[87,
-231],
[-38,
-313],
[-152,
-243],
[-163,
-197],
[-370,
-81],
[-125,
-208],
[-169,
-197],
[-419,
-220],
[-370,
-93],
[-348,
-127],
[-376,
-128],
[-223,
-243],
[-446,
-23],
[-489,
23],
[-441,
-46],
[-468,
0],
[87,
-232],
[424,
-104],
[311,
-162],
[174,
-208],
[-310,
-185],
[-479,
58],
[-397,
-151],
[-17,
-243],
[-11,
-232],
[327,
-196],
[60,
-220],
[353,
-220],
[588,
-93],
[500,
-162],
[398,
-185],
[506,
-186],
[690,
-92],
[681,
-162],
[473,
-174],
[517,
-197],
[272,
-278],
[136,
-220],
[337,
209],
[457,
173],
[484,
186],
[577,
150],
[495,
162],
[691,
12],
[680,
-81],
[560,
-139],
[180,
255],
[386,
173],
[702,
12],
[550,
127],
[522,
128],
[577,
81],
[614,
104],
[430,
150],
[-196,
209],
[-119,
208],
[0,
220],
[-539,
-23],
[-571,
-93],
[-544,
0],
[-77,
220],
[39,
440],
[125,
128],
[397,
138],
[468,
139],
[337,
174],
[337,
174],
[251,
231],
[380,
104],
[376,
81],
[190,
47],
[430,
23],
[408,
81],
[343,
116],
[337,
139],
[305,
139],
[386,
185],
[245,
197],
[261,
173],
[82,
232],
[-294,
139],
[98,
243],
[185,
185],
[288,
116],
[305,
139],
[283,
185],
[217,
232],
[136,
277],
[202,
163],
[331,
-35],
[136,
-197],
[332,
-23],
[11,
220],
[142,
231],
[299,
-58],
[71,
-220],
[331,
-34],
[360,
104],
[348,
69],
[315,
-34],
[120,
-243],
[305,
196],
[283,
105],
[315,
81],
[310,
81],
[283,
139],
[310,
92],
[240,
128],
[168,
208],
[207,
-151],
[288,
81],
[202,
-277],
[157,
-209],
[316,
116],
[125,
232],
[283,
162],
[365,
-35],
[108,
-220],
[229,
220],
[299,
69],
[326,
23],
[294,
-11],
[310,
-70],
[300,
-34],
[130,
-197],
[180,
-174],
[304,
104],
[327,
24],
[315,
0],
[310,
11],
[278,
81],
[294,
70],
[245,
162],
[261,
104],
[283,
58],
[212,
162],
[152,
324],
[158,
197],
[288,
-93],
[109,
-208],
[239,
-139],
[289,
46],
[196,
-208],
[206,
-151],
[283,
139],
[98,
255],
[250,
104],
[289,
197],
[272,
81],
[326,
116],
[218,
127],
[228,
139],
[218,
127],
[261,
-69],
[250,
208],
[180,
162],
[261,
-11],
[229,
139],
[54,
208],
[234,
162],
[228,
116],
[278,
93],
[256,
46],
[244,
-35],
[262,
-58],
[223,
-162],
[27,
-254],
[245,
-197],
[168,
-162],
[332,
-70],
[185,
-162],
[229,
-162],
[266,
-35],
[223,
116],
[240,
243],
[261,
-127],
[272,
-70],
[261,
-69],
[272,
-46],
[277,
0],
[229,
-614],
[-11,
-150],
[-33,
-267],
[-266,
-150],
[-218,
-220],
[38,
-232],
[310,
12],
[-38,
-232],
[-141,
-220],
[-131,
-243],
[212,
-185],
[321,
-58],
[321,
104],
[153,
232],
[92,
220],
[153,
185],
[174,
174],
[70,
208],
[147,
289],
[174,
58],
[316,
24],
[277,
69],
[283,
93],
[136,
231],
[82,
220],
[190,
220],
[272,
151],
[234,
115],
[153,
197],
[157,
104],
[202,
93],
[277,
-58],
[250,
58],
[272,
69],
[305,
-34],
[201,
162],
[142,
393],
[103,
-162],
[131,
-278],
[234,
-115],
[266,
-47],
[267,
70],
[283,
-46],
[261,
-12],
[174,
58],
[234,
-35],
[212,
-127],
[250,
81],
[300,
0],
[255,
81],
[289,
-81],
[185,
197],
[141,
196],
[191,
163],
[348,
439],
[179,
-81],
[212,
-162],
[185,
-208],
[354,
-359],
[272,
-12],
[256,
0],
[299,
70],
[299,
81],
[229,
162],
[190,
174],
[310,
23],
[207,
127],
[218,
-116],
[141,
-185],
[196,
-185],
[305,
23],
[190,
-150],
[332,
-151],
[348,
-58],
[288,
47],
[218,
185],
[185,
185],
[250,
46],
[251,
-81],
[288,
-58],
[261,
93],
[250,
0],
[245,
-58],
[256,
-58],
[250,
104],
[299,
93],
[283,
23],
[316,
0],
[255,
58],
[251,
46],
[76,
290],
[11,
243],
[174,
-162],
[49,
-266],
[92,
-244],
[115,
-196],
[234,
-105],
[315,
35],
[365,
12],
[250,
35],
[364,
0],
[262,
11],
[364,
-23],
[310,
-46],
[196,
-186],
[-54,
-220],
[179,
-173],
[299,
-139],
[310,
-151],
[360,
-104],
[375,
-92],
[283,
-93],
[315,
-12],
[180,
197],
[245,
-162],
[212,
-185],
[245,
-139],
[337,
-58],
[321,
-69],
[136,
-232],
[316,
-139],
[212,
-208],
[310,
-93],
[321,
12],
[299,
-35],
[332,
12],
[332,
-47],
[310,
-81],
[288,
-139],
[289,
-116],
[195,
-173],
[-32,
-232],
[-147,
-208],
[-125,
-266],
[-98,
-209],
[-131,
-243],
[-364,
-93],
[-163,
-208],
[-360,
-127],
[-125,
-232],
[-190,
-220],
[-201,
-185],
[-115,
-243],
[-70,
-220],
[-28,
-266],
[6,
-220],
[158,
-232],
[60,
-220],
[130,
-208],
[517,
-81],
[109,
-255],
[-501,
-93],
[-424,
-127],
[-528,
-23],
[-234,
-336],
[-49,
-278],
[-119,
-220],
[-147,
-220],
[370,
-196],
[141,
-244],
[239,
-219],
[338,
-197],
[386,
-186],
[419,
-185],
[636,
-185],
[142,
-289],
[800,
-128],
[53,
-45],
[208,
-175],
[767,
151],
[636,
-186],
[-99520,
-142]],
[[69148,
21851],
[179,
-186],
[263,
-74],
[9,
-112],
[-77,
-269],
[-427,
-38],
[-7,
314],
[41,
244],
[19,
121]],
[[90387,
26479],
[269,
-204],
[151,
81],
[217,
113],
[166,
-39],
[20,
-702],
[-95,
-203],
[-29,
-476],
[-97,
162],
[-193,
-412],
[-57,
32],
[-171,
19],
[-171,
505],
[-38,
390],
[-160,
515],
[7,
271],
[181,
-52]],
[[89877,
42448],
[100,
-464],
[179,
223],
[92,
-250],
[133,
-231],
[-29,
-262],
[60,
-506],
[42,
-295],
[70,
-72],
[75,
-505],
[-27,
-307],
[90,
-400],
[301,
-309],
[197,
-281],
[186,
-257],
[-37,
-143],
[159,
-371],
[108,
-639],
[111,
130],
[113,
-256],
[68,
91],
[48,
-626],
[197,
-363],
[129,
-226],
[217,
-478],
[78,
-475],
[7,
-337],
[-19,
-365],
[132,
-502],
[-16,
-523],
[-48,
-274],
[-75,
-527],
[6,
-339],
[-55,
-423],
[-123,
-538],
[-205,
-290],
[-102,
-458],
[-93,
-292],
[-82,
-510],
[-107,
-294],
[-70,
-442],
[-36,
-407],
[14,
-187],
[-159,
-205],
[-311,
-22],
[-257,
-242],
[-127,
-229],
[-168,
-254],
[-230,
262],
[-170,
104],
[43,
308],
[-152,
-112],
[-243,
-428],
[-240,
160],
[-158,
94],
[-159,
42],
[-269,
171],
[-179,
364],
[-52,
449],
[-64,
298],
[-137,
240],
[-267,
71],
[91,
287],
[-67,
438],
[-136,
-408],
[-247,
-109],
[146,
327],
[42,
341],
[107,
289],
[-22,
438],
[-226,
-504],
[-174,
-202],
[-106,
-470],
[-217,
243],
[9,
313],
[-174,
429],
[-147,
221],
[52,
137],
[-356,
358],
[-195,
17],
[-267,
287],
[-498,
-56],
[-359,
-211],
[-317,
-197],
[-265,
39],
[-294,
-303],
[-241,
-137],
[-53,
-309],
[-103,
-240],
[-236,
-15],
[-174,
-52],
[-246,
107],
[-199,
-64],
[-191,
-27],
[-165,
-315],
[-81,
26],
[-140,
-167],
[-133,
-187],
[-203,
23],
[-186,
0],
[-295,
377],
[-149,
113],
[6,
338],
[138,
81],
[47,
134],
[-10,
212],
[34,
411],
[-31,
350],
[-147,
598],
[-45,
337],
[12,
336],
[-111,
385],
[-7,
174],
[-123,
235],
[-35,
463],
[-158,
467],
[-39,
252],
[122,
-255],
[-93,
548],
[137,
-171],
[83,
-229],
[-5,
303],
[-138,
465],
[-26,
186],
[-65,
177],
[31,
341],
[56,
146],
[38,
295],
[-29,
346],
[114,
425],
[21,
-450],
[118,
406],
[225,
198],
[136,
252],
[212,
217],
[126,
46],
[77,
-73],
[219,
220],
[168,
66],
[42,
129],
[74,
54],
[153,
-14],
[292,
173],
[151,
262],
[71,
316],
[163,
300],
[13,
236],
[7,
321],
[194,
502],
[117,
-510],
[119,
118],
[-99,
279],
[87,
287],
[122,
-128],
[34,
449],
[152,
291],
[67,
233],
[140,
101],
[4,
165],
[122,
-69],
[5,
148],
[122,
85],
[134,
80],
[205,
-271],
[155,
-350],
[173,
-4],
[177,
-56],
[-59,
325],
[133,
473],
[126,
155],
[-44,
147],
[121,
338],
[168,
208],
[142,
-70],
[234,
111],
[-5,
302],
[-204,
195],
[148,
86],
[184,
-147],
[148,
-242],
[234,
-151],
[79,
60],
[172,
-182],
[162,
169],
[105,
-51],
[65,
113],
[127,
-292],
[-74,
-316],
[-105,
-239],
[-96,
-20],
[32,
-236],
[-81,
-295],
[-99,
-291],
[20,
-166],
[221,
-327],
[214,
-189],
[143,
-204],
[201,
-350],
[78,
1],
[145,
-151],
[43,
-183],
[265,
-200],
[183,
202],
[55,
317],
[56,
262],
[34,
324],
[85,
470],
[-39,
286],
[20,
171],
[-32,
339],
[37,
445],
[53,
120],
[-43,
197],
[67,
313],
[52,
325],
[7,
168],
[104,
222],
[78,
-289],
[19,
-371],
[70,
-71],
[11,
-249],
[101,
-300],
[21,
-335],
[-10,
-214]],
[[54716,
79012],
[-21,
-241],
[-156,
-2],
[53,
-128],
[-92,
-380]],
[[54500,
78261],
[-53,
-100],
[-243,
-14],
[-140,
-134],
[-229,
45]],
[[53835,
78058],
[-398,
153],
[-62,
205],
[-274,
-102],
[-32,
-113],
[-169,
84]],
[[52900,
78285],
[-142,
16],
[-125,
108],
[42,
145],
[-10,
104]],
[[52665,
78658],
[83,
33],
[141,
-164],
[39,
156],
[245,
-25],
[199,
106],
[133,
-18],
[87,
-121],
[26,
100],
[-40,
385],
[100,
75],
[98,
272]],
[[53776,
79457],
[206,
-190],
[157,
242],
[98,
44],
[215,
-180],
[131,
30],
[128,
-111]],
[[54711,
79292],
[-23,
-75],
[28,
-205]],
[[62817,
73469],
[-190,
78],
[-141,
273],
[-44,
223]],
[[63495,
75281],
[146,
-311],
[141,
-419],
[130,
-28],
[85,
-159],
[-228,
-47],
[-49,
-459],
[-48,
-207],
[-101,
-138],
[7,
-293]],
[[63578,
73220],
[-69,
-29],
[-173,
309],
[95,
292],
[-82,
174],
[-104,
-44],
[-327,
-436]],
[[62492,
74950],
[68,
96],
[207,
-169],
[149,
-36],
[38,
70],
[-136,
319],
[72,
82]],
[[62890,
75312],
[78,
-20],
[191,
-359],
[122,
-40],
[48,
150],
[166,
238]],
[[58149,
47921],
[-17,
713],
[-70,
268]],
[[58062,
48902],
[169,
-46],
[85,
336],
[147,
-38]],
[[58463,
49154],
[16,
-233],
[60,
-134],
[3,
-192],
[-69,
-124],
[-108,
-308],
[-101,
-214],
[-115,
-28]],
[[50920,
80916],
[204,
-47],
[257,
123],
[176,
-258],
[153,
-138]],
[[51710,
80596],
[-32,
-400]],
[[51678,
80196],
[-72,
-22],
[-30,
-331]],
[[51576,
79843],
[-243,
269],
[-143,
-46],
[-194,
279],
[-129,
237],
[-129,
10],
[-40,
207]],
[[50698,
80799],
[222,
117]],
[[50747,
54278],
[-229,
-69]],
[[50518,
54209],
[-69,
407],
[13,
1357],
[-56,
122],
[-11,
290],
[-96,
207],
[-85,
174],
[35,
311]],
[[50249,
57077],
[96,
67],
[56,
258],
[136,
56],
[61,
176]],
[[50598,
57634],
[93,
173],
[100,
2],
[212,
-340]],
[[51003,
57469],
[-11,
-197],
[62,
-350],
[-54,
-238],
[29,
-159],
[-135,
-366],
[-86,
-181],
[-52,
-372],
[7,
-376],
[-16,
-952]],
[[49214,
56277],
[-190,
152],
[-130,
-22],
[-97,
-149],
[-125,
125],
[-49,
195],
[-125,
129]],
[[48498,
56707],
[-18,
343],
[76,
250],
[-7,
200],
[221,
490],
[41,
405],
[76,
144],
[134,
-79],
[116,
120],
[38,
152],
[216,
265],
[53,
184],
[259,
246],
[153,
84],
[70,
-114],
[178,
3]],
[[50104,
59400],
[-22,
-286],
[37,
-269],
[156,
-386],
[9,
-286],
[320,
-134],
[-6,
-405]],
[[50249,
57077],
[-243,
13]],
[[50006,
57090],
[-128,
47],
[-90,
-96],
[-123,
43],
[-482,
-27],
[-7,
-336],
[38,
-444]],
[[75742,
63602],
[-6,
-424],
[-97,
90],
[18,
-476]],
[[75657,
62792],
[-79,
308],
[-16,
301],
[-53,
285],
[-116,
344],
[-256,
23],
[25,
-243],
[-87,
-329],
[-118,
120],
[-41,
-108],
[-78,
65],
[-108,
53]],
[[74730,
63611],
[-43,
486],
[-96,
444],
[47,
356],
[-171,
159],
[62,
215],
[173,
220],
[-200,
313],
[98,
401],
[220,
-255],
[133,
-30],
[24,
-410],
[265,
-81],
[257,
8],
[160,
-101],
[-128,
-500],
[-124,
-34],
[-86,
-336],
[152,
-306],
[46,
377],
[76,
2],
[147,
-937]],
[[56293,
76715],
[80,
-243],
[108,
43],
[213,
-92],
[408,
-31],
[138,
150],
[327,
138],
[202,
-215],
[163,
-62]],
[[57932,
76403],
[-144,
-245],
[-101,
-422],
[89,
-337]],
[[57776,
75399],
[-239,
79],
[-283,
-186]],
[[57254,
75292],
[-3,
-294],
[-252,
-56],
[-196,
206],
[-222,
-162],
[-206,
17]],
[[56375,
75003],
[-20,
391],
[-139,
189]],
[[56216,
75583],
[46,
84],
[-30,
70],
[47,
188],
[105,
185],
[-135,
255],
[-24,
216],
[68,
134]],
[[28462,
64617],
[-68,
-29],
[-70,
340],
[-104,
171],
[60,
375],
[84,
-23],
[97,
-491],
[1,
-343]],
[[28383,
66284],
[-303,
-95],
[-19,
219],
[130,
47],
[184,
-18],
[8,
-153]],
[[28611,
66290],
[-48,
-420],
[-51,
75],
[4,
309],
[-124,
234],
[-1,
67],
[220,
-265]],
[[55279,
77084],
[100,
2],
[-69,
-260],
[134,
-227],
[-41,
-278],
[-65,
-27]],
[[55338,
76294],
[-52,
-53],
[-90,
-138],
[-41,
-325]],
[[55155,
75778],
[-246,
224],
[-105,
247],
[-106,
130],
[-127,
221],
[-61,
183],
[-136,
277],
[59,
245],
[99,
-136],
[60,
123],
[130,
13],
[239,
-98],
[192,
8],
[126,
-131]],
[[56523,
82432],
[268,
-4],
[302,
223],
[64,
333],
[228,
190],
[-26,
264]],
[[57359,
83438],
[169,
100],
[298,
228]],
[[57826,
83766],
[293,
-149],
[39,
-146],
[146,
70],
[272,
-141],
[27,
-277],
[-60,
-159],
[174,
-387],
[113,
-108],
[-16,
-107],
[187,
-104],
[80,
-157],
[-108,
-129],
[-224,
20],
[-54,
-55],
[66,
-196],
[68,
-379]],
[[58829,
81362],
[-239,
-35],
[-85,
-129],
[-18,
-298],
[-111,
57],
[-250,
-28],
[-73,
138],
[-104,
-103],
[-105,
86],
[-218,
12],
[-310,
141],
[-281,
47],
[-215,
-14],
[-152,
-160],
[-133,
-23]],
[[56535,
81053],
[-6,
263],
[-85,
274],
[166,
121],
[2,
235],
[-77,
225],
[-12,
261]],
[[25238,
61101],
[-2,
87],
[33,
27],
[51,
-70],
[99,
357],
[53,
8]],
[[25472,
61510],
[1,
-87],
[53,
-3],
[-5,
-160],
[-45,
-256],
[24,
-91],
[-29,
-212],
[18,
-56],
[-32,
-299],
[-55,
-156],
[-50,
-19],
[-55,
-205]],
[[25297,
59966],
[-83,
0],
[22,
667],
[2,
468]],
[[31359,
37147],
[-200,
-81],
[-109,
814],
[-150,
663],
[88,
572],
[-146,
250],
[-37,
426],
[-136,
402]],
[[30669,
40193],
[175,
638],
[-119,
496],
[63,
199],
[-49,
219],
[108,
295],
[6,
503],
[13,
415],
[60,
200],
[-240,
951]],
[[30686,
44109],
[206,
-50],
[143,
13],
[62,
179],
[243,
239],
[147,
222],
[363,
100],
[-29,
-443],
[34,
-227],
[-23,
-396],
[302,
-529],
[311,
-98],
[109,
-220],
[188,
-117],
[115,
-172],
[175,
6],
[161,
-175],
[12,
-342],
[55,
-172],
[3,
-255],
[-81,
-10],
[107,
-688],
[533,
-24],
[-41,
-342],
[30,
-233],
[151,
-166],
[66,
-367],
[-49,
-465],
[-77,
-259],
[27,
-337],
[-87,
-122]],
[[33842,
38659],
[-4,
182],
[-259,
302],
[-258,
9],
[-484,
-172],
[-133,
-520],
[-7,
-318],
[-110,
-708]],
[[34826,
35372],
[54,
341],
[38,
350],
[0,
325],
[-100,
107],
[-104,
-96],
[-103,
26],
[-33,
228],
[-26,
541],
[-52,
177],
[-187,
160],
[-114,
-116],
[-293,
113],
[18,
802],
[-82,
329]],
[[30686,
44109],
[-157,
-102],
[-126,
68],
[18,
898],
[-228,
-348],
[-245,
15],
[-105,
315],
[-184,
34],
[59,
254],
[-155,
359],
[-115,
532],
[73,
108],
[0,
250],
[168,
171],
[-28,
319],
[71,
206],
[20,
275],
[318,
402],
[227,
114],
[37,
89],
[251,
-28]],
[[30585,
48040],
[125,
1620],
[6,
256],
[-43,
339],
[-123,
215],
[1,
430],
[156,
97],
[56,
-61],
[9,
226],
[-162,
61],
[-4,
370],
[541,
-13],
[92,
203],
[77,
-187],
[55,
-349],
[52,
73]],
[[31423,
51320],
[153,
-312],
[216,
38],
[54,
181],
[206,
138],
[115,
97],
[32,
250],
[198,
168],
[-15,
124],
[-235,
51],
[-39,
372],
[12,
396],
[-125,
153],
[52,
55],
[206,
-76],
[221,
-148],
[80,
140],
[200,
92],
[310,
221],
[102,
225],
[-37,
167]],
[[33129,
53652],
[145,
26],
[64,
-136],
[-36,
-259],
[96,
-90],
[63,
-274],
[-77,
-209],
[-44,
-502],
[71,
-299],
[20,
-274],
[171,
-277],
[137,
-29],
[30,
116],
[88,
25],
[126,
104],
[90,
157],
[154,
-50],
[67,
21]],
[[34294,
51702],
[151,
-48],
[25,
120],
[-46,
118],
[28,
171],
[112,
-53],
[131,
61],
[159,
-125]],
[[34854,
51946],
[121,
-122],
[86,
160],
[62,
-25],
[38,
-166],
[133,
42],
[107,
224],
[85,
436],
[164,
540]],
[[35650,
53035],
[95,
28],
[69,
-327],
[155,
-1033],
[149,
-97],
[7,
-408],
[-208,
-487],
[86,
-178],
[491,
-92],
[10,
-593],
[211,
388],
[349,
-212],
[462,
-361],
[135,
-346],
[-45,
-327],
[323,
182],
[540,
-313],
[415,
23],
[411,
-489],
[355,
-662],
[214,
-170],
[237,
-24],
[101,
-186],
[94,
-752],
[46,
-358],
[-110,
-977],
[-142,
-385],
[-391,
-822],
[-177,
-668],
[-206,
-513],
[-69,
-11],
[-78,
-435],
[20,
-1107],
[-77,
-910],
[-30,
-390],
[-88,
-233],
[-49,
-790],
[-282,
-771],
[-47,
-610],
[-225,
-256],
[-65,
-355],
[-302,
2],
[-437,
-227],
[-195,
-263],
[-311,
-173],
[-327,
-470],
[-235,
-586],
[-41,
-441],
[46,
-326],
[-51,
-597],
[-63,
-289],
[-195,
-325],
[-308,
-1040],
[-244,
-468],
[-189,
-277],
[-127,
-562],
[-183,
-337]],
[[35174,
30629],
[-77,
334],
[122,
280],
[-160,
402],
[-218,
327],
[-286,
379],
[-103,
-18],
[-279,
457],
[-180,
-63]],
[[81723,
53254],
[110,
221],
[236,
323]],
[[82069,
53798],
[-13,
-291],
[-16,
-377],
[-133,
19],
[-58,
-202],
[-126,
307]],
[[75471,
66988],
[113,
-189],
[-20,
-363],
[-227,
-17],
[-234,
39],
[-175,
-92],
[-252,
224],
[-6,
119]],
[[74670,
66709],
[184,
439],
[150,
150],
[198,
-137],
[147,
-14],
[122,
-159]],
[[58175,
37528],
[-393,
-435],
[-249,
-442],
[-93,
-393],
[-83,
-222],
[-152,
-47],
[-48,
-283],
[-28,
-184],
[-178,
-138],
[-226,
29],
[-133,
166],
[-117,
71],
[-135,
-137],
[-68,
-283],
[-132,
-177],
[-139,
-264],
[-199,
-60],
[-62,
207],
[26,
360],
[-165,
562],
[-75,
88]],
[[55526,
35946],
[0,
1725],
[274,
20],
[8,
2105],
[207,
19],
[428,
207],
[106,
-243],
[177,
231],
[85,
2],
[156,
133]],
[[56967,
40145],
[50,
-44]],
[[57017,
40101],
[107,
-473],
[56,
-105],
[87,
-342],
[315,
-649],
[119,
-64],
[0,
-208],
[82,
-375],
[215,
-90],
[177,
-267]],
[[54244,
54965],
[229,
44],
[52,
152],
[46,
-11],
[69,
-134],
[350,
226],
[118,
230],
[145,
207],
[-28,
208],
[78,
54],
[269,
-36],
[261,
273],
[201,
645],
[141,
239],
[176,
101]],
[[56351,
57163],
[31,
-253],
[160,
-369],
[1,
-241],
[-45,
-246],
[18,
-184],
[96,
-170]],
[[56612,
55700],
[212,
-258]],
[[56824,
55442],
[152,
-239],
[2,
-192],
[187,
-308],
[116,
-255],
[70,
-355],
[208,
-234],
[44,
-187]],
[[57603,
53672],
[-91,
-63],
[-178,
14],
[-209,
62],
[-104,
-51],
[-41,
-143],
[-90,
-18],
[-110,
125],
[-309,
-295],
[-127,
60],
[-38,
-46],
[-83,
-357],
[-207,
115],
[-203,
59],
[-177,
218],
[-229,
200],
[-149,
-190],
[-108,
-300],
[-25,
-412]],
[[55125,
52650],
[-178,
33],
[-188,
99],
[-166,
-313],
[-146,
-550]],
[[54447,
51919],
[-29,
172],
[-12,
269],
[-127,
190],
[-103,
305],
[-23,
212],
[-132,
309],
[23,
176],
[-28,
249],
[21,
458],
[67,
107],
[140,
599]],
[[32315,
78082],
[202,
-79],
[257,
16],
[-137,
-242],
[-102,
-38],
[-353,
250],
[-69,
198],
[105,
183],
[97,
-288]],
[[32831,
79592],
[-135,
-11],
[-360,
186],
[-258,
279],
[96,
49],
[365,
-148],
[284,
-247],
[8,
-108]],
[[15692,
79240],
[-140,
-82],
[-456,
269],
[-84,
209],
[-248,
207],
[-50,
168],
[-286,
107],
[-107,
321],
[24,
137],
[291,
-129],
[171,
-89],
[261,
-63],
[94,
-204],
[138,
-280],
[277,
-244],
[115,
-327]],
[[34407,
80527],
[-184,
-517],
[181,
199],
[187,
-126],
[-98,
-206],
[247,
-162],
[128,
144],
[277,
-182],
[-86,
-433],
[194,
101],
[36,
-313],
[86,
-367],
[-117,
-520],
[-125,
-22],
[-183,
111],
[60,
484],
[-77,
75],
[-322,
-513],
[-166,
21],
[196,
277],
[-267,
144],
[-298,
-35],
[-539,
18],
[-43,
175],
[173,
208],
[-121,
160],
[234,
356],
[287,
941],
[172,
336],
[241,
204],
[129,
-26],
[-54,
-160],
[-148,
-372]],
[[13005,
82584],
[131,
-76],
[267,
47],
[-84,
-671],
[242,
-475],
[-111,
1],
[-167,
270],
[-103,
272],
[-140,
184],
[-51,
260],
[16,
188]],
[[27981,
87304],
[-108,
-310],
[-123,
50],
[-73,
176],
[13,
41],
[107,
177],
[114,
-13],
[70,
-121]],
[[27250,
87631],
[-325,
-326],
[-196,
13],
[-61,
160],
[207,
273],
[381,
-6],
[-6,
-114]],
[[26344,
89371],
[51,
-259],
[143,
91],
[161,
-155],
[304,
-203],
[318,
-184],
[25,
-281],
[204,
46],
[199,
-196],
[-247,
-186],
[-432,
142],
[-156,
266],
[-275,
-314],
[-396,
-306],
[-95,
346],
[-377,
-57],
[242,
292],
[35,
465],
[95,
542],
[201,
-49]],
[[28926,
90253],
[-312,
-30],
[-69,
289],
[118,
331],
[255,
82],
[217,
-163],
[3,
-253],
[-32,
-82],
[-180,
-174]],
[[23431,
91410],
[-173,
-207],
[-374,
179],
[-226,
-65],
[-380,
266],
[245,
183],
[194,
256],
[295,
-168],
[166,
-106],
[84,
-112],
[169,
-226]],
[[31350,
77248],
[-181,
334],
[0,
805],
[-123,
171],
[-187,
-100],
[-92,
155],
[-212,
-446],
[-84,
-460],
[-99,
-269],
[-118,
-91],
[-89,
-30],
[-28,
-146],
[-512,
0],
[-422,
-4],
[-125,
-109],
[-294,
-425],
[-34,
-46],
[-89,
-231],
[-255,
1],
[-273,
-3],
[-125,
-93],
[44,
-116],
[25,
-181],
[-5,
-60],
[-363,
-293],
[-286,
-93],
[-323,
-316],
[-70,
0],
[-94,
93],
[-31,
85],
[6,
61],
[61,
207],
[131,
325],
[81,
349],
[-56,
514],
[-59,
536],
[-290,
277],
[35,
105],
[-41,
73],
[-76,
0],
[-56,
93],
[-14,
140],
[-54,
-61],
[-75,
18],
[17,
59],
[-65,
58],
[-27,
155],
[-216,
189],
[-224,
197],
[-272,
229],
[-261,
214],
[-248,
-167],
[-91,
-6],
[-342,
154],
[-225,
-77],
[-269,
183],
[-284,
94],
[-194,
36],
[-86,
100],
[-49,
325],
[-94,
-3],
[-1,
-227],
[-575,
0],
[-951,
0],
[-944,
0],
[-833,
0],
[-834,
0],
[-819,
0],
[-847,
0],
[-273,
0],
[-825,
0],
[-788,
0]],
[[15878,
79530],
[-38,
1],
[-537,
581],
[-199,
255],
[-503,
244],
[-155,
523],
[40,
363],
[-356,
252],
[-48,
476],
[-336,
429],
[-6,
304]],
[[13740,
82958],
[154,
285],
[-7,
373],
[-473,
376],
[-284,
674],
[-173,
424],
[-255,
266],
[-187,
242],
[-147,
306],
[-279,
-192],
[-270,
-330],
[-247,
388],
[-194,
259],
[-271,
164],
[-273,
17],
[1,
3364],
[2,
2193]],
[[10837,
91767],
[518,
-142],
[438,
-285],
[289,
-54],
[244,
247],
[336,
184],
[413,
-72],
[416,
259],
[455,
148],
[191,
-245],
[207,
138],
[62,
278],
[192,
-63],
[470,
-530],
[369,
401],
[38,
-449],
[341,
97],
[105,
173],
[337,
-34],
[424,
-248],
[650,
-217],
[383,
-100],
[272,
38],
[374,
-300],
[-390,
-293],
[502,
-127],
[750,
70],
[236,
103],
[296,
-354],
[302,
299],
[-283,
251],
[179,
202],
[338,
27],
[223,
59],
[224,
-141],
[279,
-321],
[310,
47],
[491,
-266],
[431,
94],
[405,
-14],
[-32,
367],
[247,
103],
[431,
-200],
[-2,
-559],
[177,
471],
[223,
-16],
[126,
594],
[-298,
364],
[-324,
239],
[22,
653],
[329,
429],
[366,
-95],
[281,
-261],
[378,
-666],
[-247,
-290],
[517,
-120],
[-1,
-604],
[371,
463],
[332,
-380],
[-83,
-438],
[269,
-399],
[290,
427],
[202,
510],
[16,
649],
[394,
-46],
[411,
-87],
[373,
-293],
[17,
-293],
[-207,
-315],
[196,
-316],
[-36,
-288],
[-544,
-413],
[-386,
-91],
[-287,
178],
[-83,
-297],
[-268,
-498],
[-81,
-259],
[-322,
-399],
[-397,
-39],
[-220,
-250],
[-18,
-384],
[-323,
-74],
[-340,
-479],
[-301,
-665],
[-108,
-466],
[-16,
-686],
[409,
-99],
[125,
-553],
[130,
-448],
[388,
117],
[517,
-256],
[277,
-225],
[199,
-279],
[348,
-163],
[294,
-248],
[459,
-34],
[302,
-58],
[-45,
-511],
[86,
-594],
[201,
-661],
[414,
-561],
[214,
192],
[150,
607],
[-145,
934],
[-196,
311],
[445,
276],
[314,
415],
[154,
411],
[-23,
395],
[-188,
502],
[-338,
445],
[328,
619],
[-121,
535],
[-93,
922],
[194,
137],
[476,
-161],
[286,
-57],
[230,
155],
[258,
-200],
[342,
-343],
[85,
-229],
[495,
-45],
[-8,
-496],
[92,
-747],
[254,
-92],
[201,
-348],
[402,
328],
[266,
652],
[184,
274],
[216,
-527],
[362,
-754],
[307,
-709],
[-112,
-371],
[370,
-333],
[250,
-338],
[442,
-152],
[179,
-189],
[110,
-500],
[216,
-78],
[112,
-223],
[20,
-664],
[-202,
-222],
[-199,
-207],
[-458,
-210],
[-349,
-486],
[-470,
-96],
[-594,
125],
[-417,
4],
[-287,
-41],
[-233,
-424],
[-354,
-262],
[-401,
-782],
[-320,
-545],
[236,
97],
[446,
776],
[583,
493],
[415,
58],
[246,
-289],
[-262,
-397],
[88,
-637],
[91,
-446],
[361,
-295],
[459,
86],
[278,
664],
[19,
-429],
[180,
-214],
[-344,
-387],
[-615,
-351],
[-276,
-239],
[-310,
-426],
[-211,
44],
[-11,
500],
[483,
488],
[-445,
-19],
[-309,
-72]],
[[18287,
93781],
[-139,
-277],
[618,
179],
[386,
-298],
[314,
302],
[254,
-194],
[227,
-580],
[140,
244],
[-197,
606],
[244,
86],
[276,
-94],
[311,
-239],
[175,
-575],
[86,
-417],
[466,
-293],
[502,
-279],
[-31,
-260],
[-456,
-48],
[178,
-227],
[-94,
-217],
[-503,
93],
[-478,
160],
[-322,
-36],
[-522,
-201],
[-704,
-88],
[-494,
-56],
[-151,
279],
[-379,
161],
[-246,
-66],
[-343,
468],
[185,
62],
[429,
101],
[392,
-26],
[362,
103],
[-537,
138],
[-594,
-47],
[-394,
12],
[-146,
217],
[644,
237],
[-428,
-9],
[-485,
156],
[233,
443],
[193,
235],
[744,
359],
[284,
-114]],
[[20972,
93958],
[-244,
-390],
[-434,
413],
[95,
83],
[372,
24],
[211,
-130]],
[[28794,
93770],
[25,
-163],
[-296,
17],
[-299,
13],
[-304,
-80],
[-80,
36],
[-306,
313],
[12,
213],
[133,
39],
[636,
-63],
[479,
-325]],
[[25955,
93803],
[219,
-369],
[256,
477],
[704,
242],
[477,
-611],
[-42,
-387],
[550,
172],
[263,
235],
[616,
-299],
[383,
-282],
[36,
-258],
[515,
134],
[290,
-376],
[670,
-234],
[242,
-238],
[263,
-553],
[-510,
-275],
[654,
-386],
[441,
-130],
[400,
-543],
[437,
-39],
[-87,
-414],
[-487,
-687],
[-342,
253],
[-437,
568],
[-359,
-74],
[-35,
-338],
[292,
-344],
[377,
-272],
[114,
-157],
[181,
-584],
[-96,
-425],
[-350,
160],
[-697,
473],
[393,
-509],
[289,
-357],
[45,
-206],
[-753,
236],
[-596,
343],
[-337,
287],
[97,
167],
[-414,
304],
[-405,
286],
[5,
-171],
[-803,
-94],
[-235,
203],
[183,
435],
[522,
10],
[571,
76],
[-92,
211],
[96,
294],
[360,
576],
[-77,
261],
[-107,
203],
[-425,
286],
[-563,
201],
[178,
150],
[-294,
367],
[-245,
34],
[-219,
201],
[-149,
-175],
[-503,
-76],
[-1011,
132],
[-588,
174],
[-450,
89],
[-231,
207],
[290,
270],
[-394,
2],
[-88,
599],
[213,
528],
[286,
241],
[717,
158],
[-204,
-382]],
[[22123,
94208],
[331,
-124],
[496,
75],
[72,
-172],
[-259,
-283],
[420,
-254],
[-50,
-532],
[-455,
-229],
[-268,
50],
[-192,
225],
[-690,
456],
[5,
189],
[567,
-73],
[-306,
386],
[329,
286]],
[[24112,
93575],
[-298,
-442],
[-317,
22],
[-173,
519],
[4,
294],
[145,
251],
[276,
161],
[579,
-20],
[530,
-144],
[-415,
-526],
[-331,
-115]],
[[16539,
92755],
[-731,
-285],
[-147,
259],
[-641,
312],
[119,
250],
[192,
432],
[241,
388],
[-272,
362],
[939,
93],
[397,
-123],
[709,
-33],
[270,
-171],
[298,
-249],
[-349,
-149],
[-681,
-415],
[-344,
-414],
[0,
-257]],
[[23996,
94879],
[-151,
-229],
[-403,
44],
[-337,
155],
[148,
266],
[399,
159],
[243,
-208],
[101,
-187]],
[[22639,
95907],
[212,
-273],
[9,
-303],
[-127,
-440],
[-458,
-60],
[-298,
94],
[5,
345],
[-455,
-46],
[-18,
457],
[299,
-18],
[419,
201],
[390,
-34],
[22,
77]],
[[19941,
95601],
[109,
-210],
[247,
99],
[291,
-26],
[49,
-289],
[-169,
-281],
[-940,
-91],
[-701,
-256],
[-423,
-14],
[-35,
193],
[577,
261],
[-1255,
-70],
[-389,
106],
[379,
577],
[262,
165],
[782,
-199],
[493,
-350],
[485,
-45],
[-397,
565],
[255,
215],
[286,
-68],
[94,
-282]],
[[23699,
96131],
[308,
-190],
[547,
1],
[240,
-194],
[-64,
-222],
[319,
-134],
[177,
-140],
[374,
-26],
[406,
-50],
[441,
128],
[566,
51],
[451,
-42],
[298,
-223],
[62,
-244],
[-174,
-157],
[-414,
-127],
[-355,
72],
[-797,
-91],
[-570,
-11],
[-449,
73],
[-738,
190],
[-96,
325],
[-34,
293],
[-279,
258],
[-574,
72],
[-322,
183],
[104,
242],
[573,
-37]],
[[17722,
96454],
[-38,
-454],
[-214,
-205],
[-259,
-29],
[-517,
-252],
[-444,
-91],
[-377,
128],
[472,
442],
[570,
383],
[426,
-9],
[381,
87]],
[[23933,
96380],
[-126,
-17],
[-521,
38],
[-74,
165],
[559,
-9],
[195,
-109],
[-33,
-68]],
[[19392,
96485],
[-518,
-170],
[-411,
191],
[224,
188],
[406,
60],
[392,
-92],
[-93,
-177]],
[[19538,
97019],
[-339,
-115],
[-461,
1],
[5,
84],
[285,
177],
[149,
-27],
[361,
-120]],
[[23380,
96697],
[-411,
-122],
[-226,
138],
[-119,
221],
[-22,
245],
[360,
-24],
[162,
-39],
[332,
-205],
[-76,
-214]],
[[22205,
96856],
[108,
-247],
[-453,
66],
[-457,
192],
[-619,
21],
[268,
176],
[-335,
142],
[-21,
227],
[546,
-81],
[751,
-215],
[212,
-281]],
[[25828,
97644],
[334,
-190],
[-381,
-176],
[-513,
-445],
[-492,
-42],
[-575,
76],
[-299,
240],
[4,
215],
[220,
157],
[-508,
-4],
[-306,
196],
[-176,
268],
[193,
262],
[192,
180],
[285,
42],
[-122,
135],
[646,
30],
[355,
-315],
[468,
-127],
[455,
-112],
[220,
-390]],
[[30972,
99681],
[742,
-47],
[597,
-75],
[508,
-161],
[-12,
-157],
[-678,
-257],
[-672,
-119],
[-251,
-133],
[605,
3],
[-656,
-358],
[-452,
-167],
[-476,
-483],
[-573,
-98],
[-177,
-120],
[-841,
-64],
[383,
-74],
[-192,
-105],
[230,
-292],
[-264,
-202],
[-429,
-167],
[-132,
-232],
[-388,
-176],
[39,
-134],
[475,
23],
[6,
-144],
[-742,
-355],
[-726,
163],
[-816,
-91],
[-414,
71],
[-525,
31],
[-35,
284],
[514,
133],
[-137,
427],
[170,
41],
[742,
-255],
[-379,
379],
[-450,
113],
[225,
229],
[492,
141],
[79,
206],
[-392,
231],
[-118,
304],
[759,
-26],
[220,
-64],
[433,
216],
[-625,
68],
[-972,
-38],
[-491,
201],
[-232,
239],
[-324,
173],
[-61,
202],
[413,
112],
[324,
19],
[545,
96],
[409,
220],
[344,
-30],
[300,
-166],
[211,
319],
[367,
95],
[498,
65],
[849,
24],
[148,
-63],
[802,
100],
[601,
-38],
[602,
-37]],
[[52900,
78285],
[-22,
-242],
[-122,
-100],
[-206,
75],
[-60,
-239],
[-132,
-19],
[-48,
94],
[-156,
-200],
[-134,
-28],
[-120,
126]],
[[51900,
77752],
[-95,
259],
[-133,
-92],
[5,
267],
[203,
332],
[-9,
150],
[126,
-54],
[77,
101]],
[[52074,
78715],
[236,
-4],
[57,
128],
[298,
-181]],
[[31400,
18145],
[-92,
-239],
[-238,
-183],
[-137,
19],
[-164,
48],
[-202,
177],
[-291,
86],
[-350,
330],
[-283,
317],
[-383,
662],
[229,
-124],
[390,
-395],
[369,
-212],
[143,
271],
[90,
405],
[256,
244],
[198,
-70]],
[[30952,
19680],
[-247,
4],
[-134,
-145],
[-250,
-213],
[-45,
-552],
[-118,
-14],
[-313,
192],
[-318,
412],
[-346,
338],
[-87,
374],
[79,
346],
[-140,
393],
[-36,
1007],
[119,
568],
[293,
457],
[-422,
172],
[265,
522],
[94,
982],
[309,
-208],
[145,
1224],
[-186,
157],
[-87,
-738],
[-175,
83],
[87,
845],
[95,
1095],
[127,
404],
[-80,
576],
[-22,
666],
[117,
19],
[170,
954],
[192,
945],
[118,
881],
[-64,
885],
[83,
487],
[-34,
730],
[163,
721],
[50,
1143],
[89,
1227],
[87,
1321],
[-20,
967],
[-58,
832]],
[[30452,
39739],
[143,
151],
[74,
303]],
[[80649,
61615],
[-240,
-284],
[-228,
183],
[-8,
509],
[137,
267],
[304,
166],
[159,
-14],
[62,
-226],
[-122,
-260],
[-64,
-341]],
[[86288,
75628],
[-179,
348],
[-111,
-331],
[-429,
-254],
[44,
-312],
[-241,
22],
[-131,
185],
[-191,
-419],
[-306,
-318],
[-227,
-379]],
[[84517,
74170],
[-388,
-171],
[-204,
-277],
[-300,
-161],
[148,
274],
[-58,
230],
[220,
397],
[-147,
310],
[-242,
-209],
[-314,
-411],
[-171,
-381],
[-272,
-29],
[-142,
-275],
[147,
-400],
[227,
-97],
[9,
-265],
[220,
-173],
[311,
422],
[247,
-230],
[179,
-15],
[45,
-310],
[-393,
-165],
[-130,
-319],
[-270,
-296],
[-142,
-414],
[299,
-325],
[109,
-581],
[169,
-541],
[189,
-454],
[-5,
-439],
[-174,
-161],
[66,
-315],
[164,
-184],
[-43,
-481],
[-71,
-468],
[-155,
-53],
[-203,
-640],
[-225,
-775],
[-258,
-705],
[-382,
-545],
[-386,
-498],
[-313,
-68],
[-170,
-262],
[-96,
192],
[-157,
-294],
[-388,
-296],
[-294,
-90],
[-95,
-624],
[-154,
-35],
[-73,
429],
[66,
228],
[-373,
189],
[-131,
-96]],
[[80013,
63313],
[-280,
154],
[-132,
240],
[44,
340],
[-254,
108],
[-134,
222],
[-236,
-315],
[-271,
-68],
[-221,
3],
[-149,
-145]],
[[78380,
63852],
[-144,
-86],
[42,
-676],
[-148,
16],
[-25,
139]],
[[78105,
63245],
[-9,
244],
[-203,
-172],
[-121,
109],
[-206,
222],
[81,
490],
[-176,
115],
[-66,
544],
[-293,
-98],
[33,
701],
[263,
493],
[11,
487],
[-8,
452],
[-121,
141],
[-93,
348],
[-162,
-44]],
[[77035,
67277],
[-300,
89],
[94,
248],
[-130,
367],
[-198,
-249],
[-233,
145],
[-321,
-376],
[-252,
-439],
[-224,
-74]],
[[74670,
66709],
[-23,
465],
[-170,
-124]],
[[74477,
67050],
[-324,
57],
[-314,
136],
[-225,
259],
[-216,
117],
[-93,
284],
[-157,
84],
[-280,
385],
[-223,
182],
[-115,
-141]],
[[72530,
68413],
[-386,
413],
[-273,
374],
[-78,
651],
[200,
-79],
[9,
301],
[-111,
303],
[28,
482],
[-298,
692]],
[[71621,
71550],
[-457,
239],
[-82,
454],
[-205,
276]],
[[70827,
72688],
[-42,
337],
[10,
230],
[-169,
134],
[-91,
-59],
[-70,
546]],
[[70465,
73876],
[79,
136],
[-39,
138],
[266,
279],
[192,
116],
[294,
-80],
[105,
378],
[356,
70],
[99,
234],
[438,
320],
[39,
134]],
[[72294,
75601],
[-22,
337],
[190,
154],
[-250,
1026],
[550,
236],
[143,
131],
[200,
1058],
[551,
-194],
[155,
267],
[13,
592],
[230,
56],
[212,
393]],
[[74266,
79657],
[109,
49]],
[[74375,
79706],
[73,
-413],
[233,
-313],
[396,
-222],
[192,
-476],
[-107,
-690],
[100,
-256],
[330,
-101],
[374,
-83],
[336,
-368],
[171,
-66],
[127,
-544],
[163,
-351],
[306,
14],
[574,
-133],
[369,
82],
[274,
-88],
[411,
-359],
[336,
1],
[123,
-184],
[324,
318],
[448,
205],
[417,
22],
[324,
208],
[200,
316],
[194,
199],
[-45,
195],
[-89,
227],
[146,
381],
[156,
-53],
[286,
-120],
[277,
313],
[423,
229],
[204,
391],
[195,
168],
[404,
78],
[219,
-66],
[30,
210],
[-251,
413],
[-223,
189],
[-214,
-219],
[-274,
92],
[-157,
-74],
[-72,
241],
[197,
590],
[135,
446]],
[[82410,
80055],
[333,
-223],
[392,
373],
[-3,
260],
[251,
627],
[155,
189],
[-4,
326],
[-152,
141],
[229,
294],
[345,
106],
[369,
16],
[415,
-176],
[244,
-217],
[172,
-596],
[104,
-254],
[97,
-363],
[103,
-579],
[483,
-189],
[329,
-420],
[112,
-555],
[423,
-1],
[240,
233],
[459,
175],
[-146,
-532],
[-107,
-216],
[-96,
-647],
[-186,
-575],
[-338,
104],
[-238,
-208],
[73,
-506],
[-40,
-698],
[-142,
-16],
[2,
-300]],
[[49206,
53531],
[-126,
-7],
[-194,
116],
[-178,
-7],
[-329,
-103],
[-193,
-170],
[-275,
-217],
[-54,
15]],
[[47857,
53158],
[22,
487],
[26,
74],
[-8,
233],
[-118,
247],
[-88,
40],
[-81,
162],
[60,
262],
[-28,
286],
[13,
172]],
[[47655,
55121],
[44,
0],
[17,
258],
[-22,
114],
[27,
82],
[103,
71],
[-69,
473],
[-64,
245],
[23,
200],
[55,
46]],
[[47769,
56610],
[36,
54],
[77,
-89],
[215,
-5],
[51,
172],
[48,
-11],
[80,
67],
[43,
-253],
[65,
74],
[114,
88]],
[[49214,
56277],
[74,
-841],
[-117,
-496],
[-73,
-667],
[121,
-509],
[-13,
-233]],
[[53632,
51919],
[-35,
32],
[-164,
-76],
[-169,
79],
[-132,
-38]],
[[53132,
51916],
[-452,
13]],
[[52680,
51929],
[40,
466],
[-108,
391],
[-127,
100],
[-56,
265],
[-72,
85],
[4,
163]],
[[52361,
53399],
[71,
418],
[132,
570],
[81,
6],
[165,
345],
[105,
10],
[156,
-243],
[191,
199],
[26,
246],
[63,
238],
[43,
299],
[148,
243],
[56,
414],
[59,
132],
[39,
307],
[74,
377],
[234,
457],
[14,
196],
[31,
107],
[-110,
235]],
[[53939,
57955],
[9,
188],
[78,
34]],
[[54026,
58177],
[111,
-378],
[18,
-392],
[-10,
-393],
[151,
-537],
[-155,
6],
[-78,
-42],
[-127,
60],
[-60,
-279],
[164,
-345],
[121,
-100],
[39,
-245],
[87,
-407],
[-43,
-160]],
[[54447,
51919],
[-20,
-319],
[-220,
140],
[-225,
156],
[-350,
23]],
[[58564,
52653],
[-16,
-691],
[111,
-80],
[-89,
-210],
[-107,
-157],
[-106,
-308],
[-59,
-274],
[-15,
-475],
[-65,
-225],
[-2,
-446]],
[[58216,
49787],
[-80,
-165],
[-10,
-351],
[-38,
-46],
[-26,
-323]],
[[58149,
47921],
[50,
-544],
[-27,
-307]],
[[58172,
47070],
[55,
-343],
[161,
-330]],
[[58388,
46397],
[150,
-745]],
[[58538,
45652],
[-109,
60],
[-373,
-99],
[-75,
-71],
[-79,
-377],
[62,
-261],
[-49,
-699],
[-34,
-593],
[75,
-105],
[194,
-230],
[76,
107],
[23,
-637],
[-212,
5],
[-114,
325],
[-103,
252],
[-213,
82],
[-62,
310],
[-170,
-187],
[-222,
83],
[-93,
268],
[-176,
55],
[-131,
-15],
[-15,
184],
[-96,
15]],
[[53422,
46976],
[-39,
183]],
[[53609,
47755],
[73,
-60],
[95,
226],
[152,
-6],
[17,
-167],
[104,
-105],
[164,
370],
[161,
289],
[71,
189],
[-10,
486],
[121,
574],
[127,
304],
[183,
285],
[32,
189],
[7,
216],
[45,
205],
[-14,
335],
[34,
524],
[55,
368],
[83,
316],
[16,
357]],
[[57603,
53672],
[169,
-488],
[124,
-71],
[75,
99],
[128,
-39],
[155,
125],
[66,
-252],
[244,
-393]],
[[53309,
47603],
[-228,
626]],
[[53081,
48229],
[212,
326],
[-105,
391],
[95,
148],
[187,
73],
[23,
261],
[148,
-283],
[245,
-25],
[85,
279],
[36,
393],
[-31,
461],
[-131,
350],
[120,
684],
[-69,
117],
[-207,
-48],
[-78,
305],
[21,
258]],
[[29063,
50490],
[-119,
140],
[-137,
195],
[-79,
-94],
[-235,
82],
[-68,
255],
[-52,
-10],
[-278,
338]],
[[28095,
51396],
[-37,
183],
[103,
44],
[-12,
296],
[65,
214],
[138,
40],
[117,
371],
[106,
310],
[-102,
141],
[52,
343],
[-62,
540],
[59,
155],
[-44,
500],
[-112,
315]],
[[28366,
54848],
[36,
287],
[89,
-43],
[52,
176],
[-64,
348],
[34,
86]],
[[28513,
55702],
[143,
-18],
[209,
412],
[114,
63],
[3,
195],
[51,
500],
[159,
274],
[175,
11],
[22,
123],
[218,
-49],
[218,
298],
[109,
132],
[134,
285],
[98,
-36],
[73,
-156],
[-54,
-199]],
[[30185,
57537],
[-178,
-99],
[-71,
-295],
[-107,
-169],
[-81,
-220],
[-34,
-422],
[-77,
-345],
[144,
-40],
[35,
-271],
[62,
-130],
[21,
-238],
[-33,
-219],
[10,
-123],
[69,
-49],
[66,
-207],
[357,
57],
[161,
-75],
[196,
-508],
[112,
63],
[200,
-32],
[158,
68],
[99,
-102],
[-50,
-318],
[-62,
-199],
[-22,
-423],
[56,
-393],
[79,
-175],
[9,
-133],
[-140,
-294],
[100,
-130],
[74,
-207],
[85,
-589]],
[[30585,
48040],
[-139,
314],
[-83,
14],
[179,
602],
[-213,
276],
[-166,
-51],
[-101,
103],
[-153,
-157],
[-207,
74],
[-163,
620],
[-129,
152],
[-89,
279],
[-184,
280],
[-74,
-56]],
[[26954,
55439],
[-151,
131],
[-56,
124],
[32,
103],
[-11,
130],
[-77,
142],
[-109,
116],
[-95,
76],
[-19,
173],
[-73,
105],
[18,
-172],
[-55,
-141],
[-64,
164],
[-89,
58],
[-38,
120],
[2,
179],
[36,
187],
[-78,
83],
[64,
114]],
[[26191,
57131],
[42,
76],
[183,
-156],
[63,
77],
[89,
-50],
[46,
-121],
[82,
-40],
[66,
126]],
[[26762,
57043],
[70,
-321],
[108,
-238],
[130,
-252]],
[[27070,
56232],
[-107,
-53],
[1,
-238],
[58,
-88],
[-41,
-70],
[10,
-107],
[-23,
-120],
[-14,
-117]],
[[27147,
64280],
[240,
-42],
[219,
-7],
[261,
-201],
[110,
-216],
[260,
66],
[98,
-138],
[235,
-366],
[173,
-267],
[92,
8],
[165,
-120],
[-20,
-167],
[205,
-24],
[210,
-242],
[-33,
-138],
[-185,
-75],
[-187,
-29],
[-191,
46],
[-398,
-57],
[186,
329],
[-113,
154],
[-179,
39],
[-96,
171],
[-66,
336],
[-157,
-23],
[-259,
159],
[-83,
124],
[-362,
91],
[-97,
115],
[104,
148],
[-273,
30],
[-199,
-307],
[-115,
-8],
[-40,
-144],
[-138,
-65],
[-118,
56],
[146,
183],
[60,
213],
[126,
131],
[142,
116],
[210,
56],
[67,
65]],
[[59092,
71341],
[19,
3],
[40,
143],
[200,
-8],
[253,
176],
[-188,
-251],
[21,
-111]],
[[59437,
71293],
[-30,
21],
[-53,
-45],
[-42,
12],
[-14,
-22],
[-5,
59],
[-20,
37],
[-54,
6],
[-75,
-51],
[-52,
31]],
[[59437,
71293],
[8,
-48],
[-285,
-240],
[-136,
77],
[-64,
237],
[132,
22]],
[[53776,
79457],
[-157,
254],
[-141,
142],
[-30,
249],
[-49,
176],
[202,
129],
[103,
147],
[200,
114],
[70,
113],
[73,
-68],
[124,
62]],
[[54171,
80775],
[132,
-191],
[207,
-51],
[-17,
-163],
[151,
-122],
[41,
153],
[191,
-66],
[26,
-185],
[207,
-36],
[127,
-291]],
[[55236,
79823],
[-82,
-1],
[-43,
-106],
[-64,
-26],
[-18,
-134],
[-54,
-28],
[-7,
-55],
[-95,
-61],
[-123,
10],
[-39,
-130]],
[[52756,
83065],
[4,
-228],
[281,
-138],
[-3,
-210],
[283,
111],
[156,
162],
[313,
-233],
[132,
-189]],
[[53922,
82340],
[64,
-300],
[-77,
-158],
[101,
-210],
[69,
-316],
[-22,
-204],
[114,
-377]],
[[52074,
78715],
[35,
421],
[140,
404],
[-400,
109],
[-131,
155]],
[[51718,
79804],
[16,
259],
[-56,
133]],
[[51710,
80596],
[-47,
619],
[167,
0],
[70,
222],
[69,
541],
[-51,
200]],
[[51918,
82178],
[54,
125],
[232,
32],
[52,
-130],
[188,
291],
[-63,
222],
[-13,
335]],
[[52368,
83053],
[210,
-78],
[178,
90]],
[[61966,
58083],
[66,
-183],
[-9,
-245],
[-158,
-142],
[119,
-161]],
[[61984,
57352],
[-102,
-317]],
[[61882,
57035],
[-62,
106],
[-67,
-42],
[-155,
10],
[-4,
180],
[-22,
163],
[94,
277],
[98,
261]],
[[61764,
57990],
[119,
-51],
[83,
144]],
[[53524,
83435],
[-166,
-478],
[-291,
333],
[-39,
246],
[408,
195],
[88,
-296]],
[[52368,
83053],
[-113,
328],
[-8,
604],
[46,
159],
[80,
177],
[244,
37],
[98,
163],
[223,
167],
[-9,
-304],
[-82,
-192],
[33,
-166],
[151,
-89],
[-68,
-223],
[-83,
64],
[-200,
-425],
[76,
-288]],
[[30080,
62227],
[34,
101],
[217,
-3],
[165,
-152],
[73,
15],
[50,
-209],
[152,
11],
[-9,
-176],
[124,
-21],
[136,
-217],
[-103,
-240],
[-132,
128],
[-127,
-25],
[-92,
28],
[-50,
-107],
[-106,
-37],
[-43,
144],
[-92,
-85],
[-111,
-405],
[-71,
94],
[-14,
170]],
[[30081,
61241],
[5,
161],
[-71,
177],
[68,
99],
[21,
228],
[-24,
321]],
[[53333,
64447],
[-952,
-1126],
[-804,
-1161],
[-392,
-263]],
[[51185,
61897],
[-308,
-58],
[-3,
376],
[-129,
96],
[-173,
169],
[-66,
277],
[-937,
1289],
[-937,
1289]],
[[48632,
65335],
[-1045,
1431]],
[[47587,
66766],
[6,
114],
[-1,
40]],
[[47592,
66920],
[-2,
700],
[449,
436],
[277,
90],
[227,
159],
[107,
295],
[324,
234],
[12,
438],
[161,
51],
[126,
219],
[363,
99],
[51,
230],
[-73,
125],
[-96,
624],
[-17,
359],
[-104,
379]],
[[49397,
71358],
[267,
323],
[300,
102],
[175,
244],
[268,
180],
[471,
105],
[459,
48],
[140,
-87],
[262,
232],
[297,
5],
[113,
-137],
[190,
35]],
[[52339,
72408],
[-57,
-303],
[44,
-563],
[-65,
-487],
[-171,
-330],
[24,
-445],
[227,
-352],
[3,
-143],
[171,
-238],
[118,
-1061]],
[[52633,
68486],
[90,
-522],
[15,
-274],
[-49,
-482],
[21,
-270],
[-36,
-323],
[24,
-371],
[-110,
-247],
[164,
-431],
[11,
-253],
[99,
-330],
[130,
109],
[219,
-275],
[122,
-370]],
[[27693,
48568],
[148,
442],
[-60,
258],
[-106,
-275],
[-166,
259],
[56,
167],
[-47,
536],
[97,
89],
[52,
368],
[105,
381],
[-20,
241],
[153,
126],
[190,
236]],
[[29063,
50490],
[38,
-449],
[-86,
-384],
[-303,
-619],
[-334,
-233],
[-170,
-514],
[-53,
-398],
[-157,
-243],
[-116,
298],
[-113,
64],
[-114,
-47],
[-8,
216],
[79,
141],
[-33,
246]],
[[59700,
68010],
[-78,
-238],
[-60,
-446],
[-75,
-308],
[-65,
-103],
[-93,
191],
[-125,
263],
[-198,
847],
[-29,
-53],
[115,
-624],
[171,
-594],
[210,
-920],
[102,
-321],
[90,
-334],
[249,
-654],
[-55,
-103],
[9,
-384],
[323,
-530],
[49,
-121]],
[[60240,
63578],
[-1102,
0],
[-1077,
0],
[-1117,
0]],
[[56944,
63578],
[0,
2175],
[0,
2101],
[-83,
476],
[71,
365],
[-43,
253],
[101,
283]],
[[56990,
69231],
[369,
10],
[268,
-156],
[275,
-175],
[129,
-92],
[214,
188],
[114,
169],
[245,
49],
[198,
-75],
[75,
-293],
[65,
193],
[222,
-140],
[217,
-33],
[137,
149]],
[[59518,
69025],
[182,
-1015]],
[[61764,
57990],
[-95,
191],
[-114,
346],
[-124,
190],
[-71,
204],
[-242,
237],
[-191,
7],
[-67,
124],
[-163,
-139],
[-168,
268],
[-87,
-441],
[-323,
124]],
[[60119,
59101],
[-30,
236],
[120,
868],
[27,
393],
[88,
181],
[204,
97],
[141,
337]],
[[60669,
61213],
[161,
-684],
[77,
-542],
[152,
-288],
[379,
-558],
[154,
-336],
[151,
-341],
[87,
-203],
[136,
-178]],
[[47490,
75324],
[14,
420],
[-114,
257],
[393,
426],
[340,
-106],
[373,
3],
[296,
-101],
[230,
31],
[449,
-19]],
[[49471,
76235],
[111,
-230],
[511,
-268],
[101,
127],
[313,
-267],
[322,
77]],
[[50829,
75674],
[15,
-344],
[-263,
-393],
[-356,
-125],
[-25,
-199],
[-171,
-327],
[-107,
-481],
[108,
-338],
[-160,
-263],
[-60,
-384],
[-210,
-118],
[-197,
-454],
[-352,
-9],
[-265,
11],
[-174,
-209],
[-106,
-223],
[-136,
49],
[-103,
199],
[-79,
340],
[-259,
92]],
[[47929,
72498],
[-23,
195],
[103,
222],
[38,
161],
[-96,
175],
[77,
388],
[-111,
355],
[120,
48],
[11,
280],
[45,
86],
[3,
461],
[129,
160],
[-78,
296],
[-162,
21],
[-47,
-75],
[-164,
0],
[-70,
289],
[-113,
-86],
[-101,
-150]],
[[56753,
84725],
[32,
349],
[-102,
-75],
[-176,
210],
[-24,
340],
[351,
164],
[350,
86],
[301,
-97],
[287,
17]],
[[57772,
85719],
[42,
-103],
[-198,
-341],
[83,
-551],
[-120,
-187]],
[[57579,
84537],
[-229,
1],
[-239,
219],
[-121,
73],
[-237,
-105]],
[[61882,
57035],
[-61,
-209],
[103,
-325],
[102,
-285],
[106,
-210],
[909,
-702],
[233,
4]],
[[63274,
55308],
[-785,
-1773],
[-362,
-26],
[-247,
-417],
[-178,
-11],
[-76,
-186]],
[[61626,
52895],
[-190,
0],
[-112,
200],
[-254,
-247],
[-82,
-247],
[-185,
47],
[-62,
68],
[-65,
-16],
[-87,
6],
[-352,
502],
[-193,
0],
[-95,
194],
[0,
332],
[-145,
99]],
[[59804,
53833],
[-164,
643],
[-127,
137],
[-48,
236],
[-141,
288],
[-171,
42],
[95,
337],
[147,
14],
[42,
181]],
[[59437,
55711],
[-4,
531]],
[[59433,
56242],
[82,
618],
[132,
166],
[28,
241],
[119,
451],
[168,
293],
[112,
582],
[45,
508]],
[[57942,
91385],
[-41,
-414],
[425,
-394],
[-256,
-445],
[323,
-673],
[-187,
-506],
[250,
-440],
[-113,
-385],
[411,
-405],
[-105,
-301],
[-258,
-341],
[-594,
-755]],
[[57797,
86326],
[-504,
-47],
[-489,
-216],
[-452,
-125],
[-161,
323],
[-269,
193],
[62,
582],
[-135,
533],
[133,
345],
[252,
371],
[635,
640],
[185,
124],
[-28,
250],
[-387,
279]],
[[56639,
89578],
[-93,
230],
[-8,
910],
[-433,
402],
[-371,
289]],
[[55734,
91409],
[167,
156],
[309,
-312],
[362,
29],
[298,
-143],
[265,
262],
[137,
433],
[431,
200],
[356,
-235],
[-117,
-414]],
[[99547,
40335],
[96,
-171],
[-46,
-308],
[-172,
-81],
[-153,
73],
[-27,
260],
[107,
203],
[126,
-74],
[69,
98]],
[[0,
41087],
[57,
27],
[-34,
-284],
[-23,
-32],
[99822,
-145],
[-177,
-124],
[-36,
220],
[139,
121],
[88,
33],
[-99836,
184]],
[[33000,
19946],
[333,
354],
[236,
-148],
[167,
237],
[222,
-266],
[-83,
-207],
[-375,
-177],
[-125,
207],
[-236,
-266],
[-139,
266]],
[[34854,
51946],
[70,
252],
[24,
269],
[48,
253],
[-107,
349]],
[[34889,
53069],
[-22,
404],
[144,
508]],
[[35011,
53981],
[95,
-65],
[204,
-140],
[294,
-499],
[46,
-242]],
[[52655,
75484],
[-92,
-456],
[-126,
120],
[-64,
398],
[56,
219],
[179,
226],
[47,
-507]],
[[51576,
79843],
[62,
-52],
[80,
13]],
[[51900,
77752],
[-11,
-167],
[82,
-222],
[-97,
-180],
[72,
-457],
[151,
-75],
[-32,
-256]],
[[52065,
76395],
[-252,
-334],
[-548,
160],
[-404,
-192],
[-32,
-355]],
[[49471,
76235],
[144,
354],
[53,
1177],
[-287,
620],
[-205,
299],
[-424,
227],
[-28,
431],
[360,
129],
[466,
-152],
[-88,
669],
[263,
-254],
[646,
461],
[84,
484],
[243,
119]],
[[53081,
48229],
[-285,
596],
[-184,
488],
[-169,
610],
[9,
196],
[61,
189],
[67,
430],
[56,
438]],
[[52636,
51176],
[94,
35],
[404,
-6],
[-2,
711]],
[[48278,
82406],
[-210,
122],
[-172,
-9],
[57,
317],
[-57,
317]],
[[47896,
83153],
[233,
24],
[298,
-365],
[-149,
-406]],
[[49165,
85222],
[-297,
-639],
[283,
81],
[304,
-3],
[-72,
-481],
[-250,
-530],
[287,
-38],
[22,
-62],
[248,
-697],
[190,
-95],
[171,
-673],
[79,
-233],
[337,
-113],
[-34,
-378],
[-142,
-173],
[111,
-305],
[-250,
-310],
[-371,
6],
[-473,
-163],
[-130,
116],
[-183,
-276],
[-257,
67],
[-195,
-226],
[-148,
118],
[407,
621],
[249,
127],
[-2,
1],
[-434,
98],
[-79,
235],
[291,
183],
[-152,
319],
[52,
387],
[413,
-54],
[1,
0],
[40,
343],
[-186,
364],
[-4,
8],
[-337,
104],
[-66,
160],
[101,
264],
[-92,
163],
[-149,
-279],
[-17,
569],
[-140,
301],
[101,
611],
[216,
480],
[222,
-47],
[335,
49]],
[[61542,
75120],
[42,
252],
[-70,
403],
[-160,
218],
[-154,
68],
[-102,
181]],
[[61098,
76242],
[34,
70],
[235,
-101],
[409,
-96],
[378,
-283],
[48,
-110],
[169,
93],
[259,
-124],
[85,
-242],
[175,
-137]],
[[62106,
74858],
[-268,
290],
[-296,
-28]],
[[50294,
54083],
[-436,
-346],
[-154,
-203],
[-250,
-171],
[-248,
168]],
[[50006,
57090],
[-20,
-184],
[116,
-305],
[-1,
-429],
[27,
-466],
[69,
-215],
[-61,
-532],
[22,
-294],
[74,
-375],
[62,
-207]],
[[47655,
55121],
[-78,
15],
[-57,
-238],
[-78,
3],
[-55,
126],
[19,
237],
[-116,
362],
[-73,
-67],
[-59,
-13]],
[[47158,
55546],
[-77,
-34],
[3,
217],
[-44,
155],
[9,
171],
[-60,
249],
[-78,
211],
[-222,
1],
[-65,
-112],
[-76,
-13],
[-48,
-128],
[-32,
-163],
[-148,
-260]],
[[46320,
55840],
[-122,
349],
[-108,
232],
[-71,
76],
[-69,
118],
[-32,
261],
[-41,
130],
[-80,
97]],
[[45797,
57103],
[123,
288],
[84,
-11],
[73,
99],
[61,
1],
[44,
78],
[-24,
196],
[31,
62],
[5,
200]],
[[46194,
58016],
[134,
-6],
[200,
-144],
[61,
13],
[21,
66],
[151,
-47],
[40,
33]],
[[46801,
57931],
[16,
-216],
[44,
1],
[73,
78],
[46,
-19],
[77,
-150],
[119,
-48],
[76,
128],
[90,
79],
[67,
83],
[55,
-15],
[62,
-130],
[33,
-163],
[114,
-248],
[-57,
-152],
[-11,
-192],
[59,
58],
[35,
-69],
[-15,
-176],
[85,
-170]],
[[45321,
58350],
[36,
262]],
[[45357,
58612],
[302,
17],
[63,
140],
[88,
9],
[110,
-145],
[86,
-3],
[92,
99],
[56,
-170],
[-120,
-133],
[-121,
11],
[-119,
124],
[-103,
-136],
[-50,
-5],
[-67,
-83],
[-253,
13]],
[[45797,
57103],
[-149,
247],
[-117,
39],
[-63,
166],
[1,
90],
[-84,
125],
[-18,
127]],
[[45367,
57897],
[147,
96],
[92,
-19],
[75,
67],
[513,
-25]],
[[52636,
51176],
[-52,
90],
[96,
663]],
[[56583,
71675],
[152,
-199],
[216,
34],
[207,
-42],
[-7,
-103],
[151,
71],
[-35,
-175],
[-400,
-50],
[3,
98],
[-339,
115],
[52,
251]],
[[57237,
74699],
[-169,
17],
[-145,
56],
[-336,
-154],
[192,
-332],
[-141,
-96],
[-154,
-1],
[-147,
305],
[-52,
-130],
[62,
-353],
[139,
-277],
[-105,
-129],
[155,
-273],
[137,
-171],
[4,
-334],
[-257,
157],
[82,
-302],
[-176,
-62],
[105,
-521],
[-184,
-8],
[-228,
257],
[-104,
473],
[-49,
393],
[-108,
272],
[-143,
337],
[-18,
168]],
[[55838,
74710],
[182,
53],
[106,
129],
[150,
-12],
[46,
103],
[53,
20]],
[[57254,
75292],
[135,
-157],
[-86,
-369],
[-66,
-67]],
[[37010,
99398],
[932,
353],
[975,
-27],
[354,
218],
[982,
57],
[2219,
-74],
[1737,
-469],
[-513,
-227],
[-1062,
-26],
[-1496,
-58],
[140,
-105],
[984,
65],
[836,
-204],
[540,
181],
[231,
-212],
[-305,
-344],
[707,
220],
[1348,
229],
[833,
-114],
[156,
-253],
[-1132,
-420],
[-157,
-136],
[-888,
-102],
[643,
-28],
[-324,
-431],
[-224,
-383],
[9,
-658],
[333,
-386],
[-434,
-24],
[-457,
-187],
[513,
-313],
[65,
-502],
[-297,
-55],
[360,
-508],
[-617,
-42],
[322,
-241],
[-91,
-208],
[-391,
-91],
[-388,
-2],
[348,
-400],
[4,
-263],
[-549,
244],
[-143,
-158],
[375,
-148],
[364,
-361],
[105,
-476],
[-495,
-114],
[-214,
228],
[-344,
340],
[95,
-401],
[-322,
-311],
[732,
-25],
[383,
-32],
[-745,
-515],
[-755,
-466],
[-813,
-204],
[-306,
-2],
[-288,
-228],
[-386,
-624],
[-597,
-414],
[-192,
-24],
[-370,
-145],
[-399,
-138],
[-238,
-365],
[-4,
-415],
[-141,
-388],
[-453,
-472],
[112,
-462],
[-125,
-488],
[-142,
-577],
[-391,
-36],
[-410,
482],
[-556,
3],
[-269,
324],
[-186,
577],
[-481,
735],
[-141,
385],
[-38,
530],
[-384,
546],
[100,
435],
[-186,
208],
[275,
691],
[418,
220],
[110,
247],
[58,
461],
[-318,
-209],
[-151,
-88],
[-249,
-84],
[-341,
193],
[-19,
401],
[109,
314],
[258,
9],
[567,
-157],
[-478,
375],
[-249,
202],
[-276,
-83],
[-232,
147],
[310,
550],
[-169,
220],
[-220,
409],
[-335,
626],
[-353,
230],
[3,
247],
[-745,
346],
[-590,
43],
[-743,
-24],
[-677,
-44],
[-323,
188],
[-482,
372],
[729,
186],
[559,
31],
[-1188,
154],
[-627,
241],
[39,
229],
[1051,
285],
[1018,
284],
[107,
214],
[-750,
213],
[243,
235],
[961,
413],
[404,
63],
[-115,
265],
[658,
156],
[854,
93],
[853,
5],
[303,
-184],
[737,
325],
[663,
-221],
[390,
-46],
[577,
-192],
[-660,
318],
[38,
253]],
[[24973,
58695],
[-142,
103],
[-174,
11],
[-127,
117],
[-149,
244]],
[[24381,
59170],
[7,
172],
[32,
138],
[-39,
111],
[133,
481],
[357,
2],
[7,
201],
[-45,
36],
[-31,
128],
[-103,
136],
[-103,
198],
[125,
1],
[1,
333],
[259,
1],
[257,
-7]],
[[25297,
59966],
[90,
-107],
[24,
88],
[82,
-75]],
[[25493,
59872],
[-127,
-225],
[-131,
-166],
[-20,
-113],
[22,
-116],
[-58,
-150]],
[[25179,
59102],
[-65,
-37],
[15,
-69],
[-52,
-66],
[-95,
-149],
[-9,
-86]],
[[33400,
55523],
[183,
-217],
[171,
-385],
[8,
-304],
[105,
-14],
[149,
-289],
[109,
-205]],
[[34125,
54109],
[-44,
-532],
[-169,
-154],
[15,
-139],
[-51,
-305],
[123,
-429],
[89,
-1],
[37,
-333],
[169,
-514]],
[[33129,
53652],
[-188,
448],
[75,
163],
[-5,
273],
[171,
95],
[69,
110],
[-95,
220],
[24,
215],
[220,
347]],
[[25745,
58251],
[-48,
185],
[-84,
51]],
[[25613,
58487],
[19,
237],
[-38,
64],
[-57,
42],
[-122,
-70],
[-10,
79],
[-84,
95],
[-60,
118],
[-82,
50]],
[[25493,
59872],
[29,
-23],
[61,
104],
[79,
8],
[26,
-48],
[43,
29],
[129,
-53],
[128,
15],
[90,
66],
[32,
66],
[89,
-31],
[66,
-40],
[73,
14],
[55,
51],
[127,
-82],
[44,
-13],
[85,
-110],
[80,
-132],
[101,
-91],
[73,
-162]],
[[26903,
59440],
[-95,
12],
[-38,
-81],
[-97,
-77],
[-70,
0],
[-61,
-76],
[-56,
27],
[-47,
90],
[-29,
-17],
[-36,
-141],
[-27,
5],
[-4,
-121],
[-97,
-163],
[-51,
-70],
[-29,
-74],
[-82,
120],
[-60,
-158],
[-58,
4],
[-65,
-14],
[6,
-290],
[-41,
-5],
[-35,
-135],
[-86,
-25]],
[[55230,
77704],
[67,
-229],
[89,
-169],
[-107,
-222]],
[[55155,
75778],
[-31,
-100]],
[[55124,
75678],
[-261,
218],
[-161,
213],
[-254,
176],
[-233,
434],
[56,
45],
[-127,
248],
[-5,
200],
[-179,
93],
[-85,
-255],
[-82,
198],
[6,
205],
[10,
9]],
[[53809,
77462],
[194,
-20],
[51,
100],
[94,
-97],
[109,
-11],
[-1,
165],
[97,
60],
[27,
239],
[221,
157]],
[[54601,
78055],
[88,
-73],
[208,
-253],
[229,
-114],
[104,
89]],
[[30081,
61241],
[-185,
100],
[-131,
-41],
[-169,
43],
[-130,
-110],
[-149,
184],
[24,
190],
[256,
-82],
[210,
-47],
[100,
131],
[-127,
256],
[2,
226],
[-175,
92],
[62,
163],
[170,
-26],
[241,
-93]],
[[54716,
79012],
[141,
-151],
[103,
-65],
[233,
73],
[22,
118],
[111,
18],
[135,
92],
[30,
-38],
[130,
74],
[66,
139],
[91,
36],
[297,
-180],
[59,
61]],
[[56134,
79189],
[155,
-161],
[19,
-159]],
[[56308,
78869],
[-170,
-123],
[-131,
-401],
[-168,
-401],
[-223,
-111]],
[[55616,
77833],
[-173,
26],
[-213,
-155]],
[[54601,
78055],
[-54,
200],
[-47,
6]],
[[83531,
44530],
[-117,
-11],
[-368,
414],
[259,
116],
[146,
-180],
[97,
-180],
[-17,
-159]],
[[84713,
45326],
[28,
-117],
[5,
-179]],
[[84746,
45030],
[-181,
-441],
[-238,
-130],
[-33,
71],
[25,
201],
[119,
360],
[275,
235]],
[[82749,
45797],
[100,
-158],
[172,
48],
[69,
-251],
[-321,
-119],
[-193,
-79],
[-149,
5],
[95,
340],
[153,
5],
[74,
209]],
[[84139,
45797],
[-41,
-328],
[-417,
-168],
[-370,
73],
[0,
216],
[220,
123],
[174,
-177],
[185,
45],
[249,
216]],
[[80172,
46575],
[533,
-59],
[61,
244],
[515,
-284],
[101,
-383],
[417,
-108],
[341,
-351],
[-317,
-225],
[-306,
238],
[-251,
-16],
[-288,
44],
[-260,
106],
[-322,
225],
[-204,
59],
[-116,
-74],
[-506,
243],
[-48,
254],
[-255,
44],
[191,
564],
[337,
-35],
[224,
-231],
[115,
-45],
[38,
-210]],
[[87423,
46908],
[-143,
-402],
[-27,
445],
[49,
212],
[58,
200],
[63,
-173],
[0,
-282]],
[[85346,
48536],
[-104,
-196],
[-192,
108],
[-54,
254],
[281,
29],
[69,
-195]],
[[86241,
48752],
[101,
-452],
[-234,
244],
[-232,
49],
[-157,
-39],
[-192,
21],
[65,
325],
[344,
24],
[305,
-172]],
[[89166,
49043],
[5,
-1925],
[4,
-1925]],
[[89175,
45193],
[-247,
485],
[-282,
118],
[-69,
-168],
[-352,
-18],
[118,
481],
[175,
164],
[-72,
642],
[-134,
496],
[-538,
500],
[-229,
50],
[-417,
546],
[-82,
-287],
[-107,
-52],
[-63,
216],
[-1,
257],
[-212,
290],
[299,
213],
[198,
-11],
[-23,
156],
[-407,
1],
[-110,
352],
[-248,
109],
[-117,
293],
[374,
143],
[142,
192],
[446,
-242],
[44,
-220],
[78,
-955],
[287,
-354],
[232,
627],
[319,
356],
[247,
1],
[238,
-206],
[206,
-212],
[298,
-113]],
[[84788,
51419],
[-223,
-587],
[-209,
-113],
[-267,
115],
[-463,
-29],
[-243,
-85],
[-39,
-447],
[248,
-526],
[150,
268],
[518,
201],
[-22,
-272],
[-121,
86],
[-121,
-347],
[-245,
-229],
[263,
-757],
[-50,
-203],
[249,
-682],
[-2,
-388],
[-148,
-173],
[-109,
207],
[134,
484],
[-273,
-229],
[-69,
164],
[36,
228],
[-200,
346],
[21,
576],
[-186,
-179],
[24,
-689],
[11,
-846],
[-176,
-85],
[-119,
173],
[79,
544],
[-43,
570],
[-117,
4],
[-86,
405],
[115,
387],
[40,
469],
[139,
891],
[58,
243],
[237,
439],
[217,
-174],
[350,
-82],
[319,
25],
[275,
429],
[48,
-132]],
[[85746,
51249],
[-15,
-517],
[-143,
58],
[-42,
-359],
[114,
-312],
[-78,
-71],
[-112,
374],
[-82,
755],
[56,
472],
[92,
215],
[20,
-322],
[164,
-52],
[26,
-241]],
[[80461,
51765],
[47,
-395],
[190,
-334],
[179,
121],
[177,
-43],
[162,
299],
[133,
52],
[263,
-166],
[226,
126],
[143,
822],
[107,
205],
[96,
672],
[319,
0],
[241,
-100]],
[[82744,
53024],
[-158,
-533],
[204,
-560],
[-48,
-272],
[312,
-546],
[-329,
-70],
[-93,
-403],
[12,
-535],
[-267,
-404],
[-7,
-589],
[-107,
-903],
[-41,
210],
[-316,
-266],
[-110,
361],
[-198,
34],
[-139,
189],
[-330,
-212],
[-101,
285],
[-182,
-32],
[-229,
68],
[-43,
793],
[-138,
164],
[-134,
505],
[-38,
517],
[32,
548],
[165,
392]],
[[79393,
47122],
[-308,
-12],
[-234,
494],
[-356,
482],
[-119,
358],
[-210,
481],
[-138,
443],
[-212,
827],
[-244,
493],
[-81,
508],
[-103,
461],
[-250,
372],
[-145,
506],
[-209,
330],
[-290,
652],
[-24,
300],
[178,
-24],
[430,
-114],
[246,
-577],
[215,
-401],
[153,
-246],
[263,
-635],
[283,
-9],
[233,
-405],
[161,
-495],
[211,
-270],
[-111,
-482],
[159,
-205],
[100,
-15],
[47,
-412],
[97,
-330],
[204,
-52],
[135,
-374],
[-70,
-735],
[-11,
-914]],
[[72530,
68413],
[-176,
-268],
[-108,
-553],
[269,
-224],
[262,
-289],
[362,
-332],
[381,
-76],
[160,
-301],
[215,
-56],
[334,
-138],
[231,
10],
[32,
234],
[-36,
375],
[21,
255]],
[[77035,
67277],
[20,
-224],
[-97,
-108],
[23,
-364],
[-199,
107],
[-359,
-408],
[8,
-338],
[-153,
-496],
[-14,
-288],
[-124,
-487],
[-217,
135],
[-11,
-612],
[-63,
-201],
[30,
-251],
[-137,
-140]],
[[74730,
63611],
[-39,
-216],
[-189,
7],
[-343,
-122],
[16,
-445],
[-148,
-349],
[-400,
-398],
[-311,
-695],
[-209,
-373],
[-276,
-387],
[-1,
-271],
[-138,
-146],
[-251,
-212],
[-129,
-31],
[-84,
-450],
[58,
-769],
[15,
-490],
[-118,
-561],
[-1,
-1004],
[-144,
-29],
[-126,
-450],
[84,
-195],
[-253,
-168],
[-93,
-401],
[-112,
-170],
[-263,
552],
[-128,
827],
[-107,
596],
[-97,
279],
[-148,
568],
[-69,
739],
[-48,
369],
[-253,
811],
[-115,
1145],
[-83,
756],
[1,
716],
[-54,
553],
[-404,
-353],
[-196,
70],
[-362,
716],
[133,
214],
[-82,
232],
[-326,
501]],
[[68937,
64577],
[185,
395],
[612,
-2],
[-56,
507],
[-156,
300],
[-31,
455],
[-182,
265],
[306,
619],
[323,
-45],
[290,
620],
[174,
599],
[270,
593],
[-4,
421],
[236,
342],
[-224,
292],
[-96,
400],
[-99,
517],
[137,
255],
[421,
-144],
[310,
88],
[268,
496]],
[[48278,
82406],
[46,
-422],
[-210,
-528],
[-493,
-349],
[-393,
89],
[225,
617],
[-145,
601],
[378,
463],
[210,
276]],
[[64978,
72558],
[244,
114],
[197,
338],
[186,
-17],
[122,
110],
[197,
-55],
[308,
-299],
[221,
-65],
[318,
-523],
[207,
-21],
[24,
-498]],
[[66909,
68203],
[137,
-310],
[112,
-357],
[266,
-260],
[7,
-520],
[133,
-96],
[23,
-272],
[-400,
-305],
[-105,
-687]],
[[67082,
65396],
[-523,
179],
[-303,
136],
[-313,
76],
[-118,
725],
[-133,
105],
[-214,
-106],
[-280,
-286],
[-339,
196],
[-281,
454],
[-267,
168],
[-186,
561],
[-205,
788],
[-149,
-96],
[-177,
196],
[-104,
-231]],
[[63490,
68261],
[-153,
311],
[-3,
314],
[-89,
0],
[46,
428],
[-143,
449],
[-340,
324],
[-193,
562],
[65,
461],
[139,
204],
[-21,
345],
[-182,
177],
[-180,
705]],
[[62436,
72541],
[-152,
473],
[55,
183],
[-87,
678],
[190,
168]],
[[63578,
73220],
[88,
-436],
[263,
-123],
[193,
-296],
[395,
-102],
[434,
156],
[27,
139]],
[[63490,
68261],
[-164,
29]],
[[63326,
68290],
[-187,
49],
[-204,
-567]],
[[62935,
67772],
[-516,
47],
[-784,
1188],
[-413,
414],
[-335,
160]],
[[60887,
69581],
[-112,
720]],
[[60775,
70301],
[615,
614],
[105,
715],
[-26,
431],
[152,
146],
[142,
369]],
[[61763,
72576],
[119,
92],
[324,
-77],
[97,
-150],
[133,
100]],
[[45969,
89843],
[-64,
-382],
[314,
-403],
[-361,
-451],
[-801,
-405],
[-240,
-107],
[-365,
87],
[-775,
187],
[273,
261],
[-605,
289],
[492,
114],
[-12,
174],
[-583,
137],
[188,
385],
[421,
87],
[433,
-400],
[422,
321],
[349,
-167],
[453,
315],
[461,
-42]],
[[59922,
69905],
[-49,
-186]],
[[59873,
69719],
[-100,
82],
[-58,
-394],
[69,
-66],
[-71,
-81],
[-12,
-156],
[131,
80]],
[[59832,
69184],
[7,
-230],
[-139,
-944]],
[[59518,
69025],
[80,
194],
[-19,
34],
[74,
276],
[56,
446],
[40,
149],
[8,
6]],
[[59757,
70130],
[93,
-1],
[25,
104],
[75,
8]],
[[59950,
70241],
[4,
-242],
[-38,
-90],
[6,
-4]],
[[54311,
73167],
[-100,
-465],
[41,
-183],
[-58,
-303],
[-213,
222],
[-141,
64],
[-387,
300],
[38,
304],
[325,
-54],
[284,
64],
[211,
51]],
[[52558,
74927],
[166,
-419],
[-39,
-782],
[-126,
38],
[-113,
-197],
[-105,
156],
[-11,
713],
[-64,
338],
[153,
-30],
[139,
183]],
[[53835,
78058],
[-31,
-291],
[67,
-251]],
[[53871,
77516],
[-221,
86],
[-226,
-210],
[15,
-293],
[-34,
-168],
[91,
-301],
[261,
-298],
[140,
-488],
[309,
-476],
[217,
3],
[68,
-130],
[-78,
-118],
[249,
-214],
[204,
-178],
[238,
-308],
[29,
-111],
[-52,
-211],
[-154,
276],
[-242,
97],
[-116,
-382],
[200,
-219],
[-33,
-309],
[-116,
-35],
[-148,
-506],
[-116,
-46],
[1,
181],
[57,
317],
[60,
126],
[-108,
342],
[-85,
298],
[-115,
74],
[-82,
255],
[-179,
107],
[-120,
238],
[-206,
38],
[-217,
267],
[-254,
384],
[-189,
340],
[-86,
585],
[-138,
68],
[-226,
195],
[-128,
-80],
[-161,
-274],
[-115,
-43]],
[[28453,
61504],
[187,
-53],
[147,
-142],
[46,
-161],
[-195,
-11],
[-84,
-99],
[-156,
95],
[-159,
215],
[34,
135],
[116,
41],
[64,
-20]],
[[59922,
69905],
[309,
-234],
[544,
630]],
[[60887,
69581],
[-53,
-89],
[-556,
-296],
[277,
-591],
[-92,
-101],
[-46,
-197],
[-212,
-82],
[-66,
-213],
[-120,
-182],
[-310,
94]],
[[59709,
67924],
[-9,
86]],
[[59832,
69184],
[41,
173],
[0,
362]],
[[87399,
70756],
[35,
-203],
[-156,
-357],
[-114,
189],
[-143,
-137],
[-73,
-346],
[-181,
168],
[2,
281],
[154,
352],
[158,
-68],
[114,
248],
[204,
-127]],
[[89159,
72524],
[-104,
-472],
[48,
-296],
[-145,
-416],
[-355,
-278],
[-488,
-36],
[-396,
-675],
[-186,
227],
[-12,
442],
[-483,
-130],
[-329,
-279],
[-325,
-11],
[282,
-435],
[-186,
-1004],
[-179,
-248],
[-135,
229],
[69,
533],
[-176,
172],
[-113,
405],
[263,
182],
[145,
371],
[280,
306],
[203,
403],
[553,
177],
[297,
-121],
[291,
1050],
[185,
-282],
[408,
591],
[158,
229],
[174,
723],
[-47,
664],
[117,
374],
[295,
108],
[152,
-819],
[-9,
-479],
[-256,
-595],
[4,
-610]],
[[89974,
76679],
[195,
-126],
[197,
250],
[62,
-663],
[-412,
-162],
[-244,
-587],
[-436,
404],
[-152,
-646],
[-308,
-9],
[-39,
587],
[138,
455],
[296,
33],
[81,
817],
[83,
460],
[326,
-615],
[213,
-198]],
[[69711,
75551],
[-159,
-109],
[-367,
-412],
[-121,
-422],
[-104,
-4],
[-76,
280],
[-353,
19],
[-57,
484],
[-135,
4],
[21,
593],
[-333,
431],
[-476,
-46],
[-326,
-86],
[-265,
533],
[-227,
223],
[-431,
423],
[-52,
51],
[-715,
-349],
[11,
-2178]],
[[65546,
74986],
[-142,
-29],
[-195,
463],
[-188,
166],
[-315,
-123],
[-123,
-197]],
[[64583,
75266],
[-15,
144],
[68,
246],
[-53,
206],
[-322,
202],
[-125,
530],
[-154,
150],
[-9,
192],
[270,
-56],
[11,
432],
[236,
96],
[243,
-88],
[50,
576],
[-50,
365],
[-278,
-28],
[-236,
144],
[-321,
-260],
[-259,
-124]],
[[63639,
77993],
[-142,
96],
[29,
304],
[-177,
395],
[-207,
-17],
[-235,
401],
[160,
448],
[-81,
120],
[222,
649],
[285,
-342],
[35,
431],
[573,
643],
[434,
15],
[612,
-409],
[329,
-239],
[295,
249],
[440,
12],
[356,
-306],
[80,
175],
[391,
-25],
[69,
280],
[-450,
406],
[267,
288],
[-52,
161],
[266,
153],
[-200,
405],
[127,
202],
[1039,
205],
[136,
146],
[695,
218],
[250,
245],
[499,
-127],
[88,
-612],
[290,
144],
[356,
-202],
[-23,
-322],
[267,
33],
[696,
558],
[-102,
-185],
[355,
-457],
[620,
-1500],
[148,
309],
[383,
-340],
[399,
151],
[154,
-106],
[133,
-341],
[194,
-115],
[119,
-251],
[358,
79],
[147,
-361]],
[[72294,
75601],
[-171,
87],
[-140,
212],
[-412,
62],
[-461,
16],
[-100,
-65],
[-396,
248],
[-158,
-122],
[-43,
-349],
[-457,
204],
[-183,
-84],
[-62,
-259]],
[[61551,
49585],
[-195,
-236],
[-68,
-246],
[-104,
-44],
[-40,
-416],
[-89,
-238],
[-54,
-393],
[-112,
-195]],
[[60889,
47817],
[-399,
590],
[-19,
343],
[-1007,
1203],
[-47,
65]],
[[59417,
50018],
[-3,
627],
[80,
239],
[137,
391],
[101,
431],
[-123,
678],
[-32,
296],
[-132,
411]],
[[59445,
53091],
[171,
352],
[188,
390]],
[[61626,
52895],
[-243,
-670],
[3,
-2152],
[165,
-488]],
[[70465,
73876],
[-526,
-89],
[-343,
192],
[-301,
-46],
[26,
340],
[303,
-98],
[101,
182]],
[[69725,
74357],
[212,
-58],
[355,
425],
[-329,
311],
[-198,
-147],
[-205,
223],
[234,
382],
[-83,
58]],
[[78495,
57780],
[-66,
713],
[178,
492],
[359,
112],
[261,
-84]],
[[79227,
59013],
[229,
-232],
[126,
407],
[246,
-217]],
[[79828,
58971],
[64,
-394],
[-34,
-708],
[-467,
-455],
[122,
-358],
[-292,
-43],
[-240,
-238]],
[[78981,
56775],
[-233,
87],
[-112,
307],
[-141,
611]],
[[85652,
73393],
[240,
-697],
[68,
-383],
[3,
-681],
[-105,
-325],
[-252,
-113],
[-222,
-245],
[-250,
-51],
[-31,
322],
[51,
443],
[-122,
615],
[206,
99],
[-190,
506]],
[[85048,
72883],
[17,
54],
[124,
-21],
[108,
266],
[197,
29],
[118,
39],
[40,
143]],
[[55575,
75742],
[52,
132]],
[[55627,
75874],
[66,
43],
[38,
196],
[50,
33],
[40,
-84],
[52,
-36],
[36,
-94],
[46,
-28],
[54,
-110],
[39,
4],
[-31,
-144],
[-33,
-71],
[9,
-44]],
[[55993,
75539],
[-62,
-23],
[-164,
-91],
[-13,
-121],
[-35,
5]],
[[63326,
68290],
[58,
-261],
[-25,
-135],
[89,
-445]],
[[63448,
67449],
[-196,
-16],
[-69,
282],
[-248,
57]],
[[79227,
59013],
[90,
266],
[12,
500],
[-224,
515],
[-18,
583],
[-211,
480],
[-210,
40],
[-56,
-205],
[-163,
-17],
[-83,
104],
[-293,
-353],
[-6,
530],
[68,
623],
[-188,
27],
[-16,
355],
[-120,
182]],
[[77809,
62643],
[59,
218],
[237,
384]],
[[78380,
63852],
[162,
-466],
[125,
-537],
[342,
-5],
[108,
-515],
[-178,
-155],
[-80,
-212],
[333,
-353],
[231,
-699],
[175,
-520],
[210,
-411],
[70,
-418],
[-50,
-590]],
[[59757,
70130],
[99,
482],
[138,
416],
[5,
21]],
[[59999,
71049],
[125,
-31],
[45,
-231],
[-151,
-223],
[-68,
-323]],
[[47857,
53158],
[-73,
-5],
[-286,
282],
[-252,
449],
[-237,
324],
[-187,
381]],
[[46822,
54589],
[66,
189],
[15,
172],
[126,
320],
[129,
276]],
[[54125,
64088],
[-197,
-220],
[-156,
324],
[-439,
255]],
[[52633,
68486],
[136,
137],
[24,
250],
[-30,
244],
[191,
228],
[86,
189],
[135,
170],
[16,
454]],
[[53191,
70158],
[326,
-204],
[117,
51],
[232,
-98],
[368,
-264],
[130,
-526],
[250,
-114],
[391,
-248],
[296,
-293],
[136,
153],
[133,
272],
[-65,
452],
[87,
288],
[200,
277],
[192,
80],
[375,
-121],
[95,
-264],
[104,
-2],
[88,
-101],
[276,
-70],
[68,
-195]],
[[56944,
63578],
[0,
-1180],
[-320,
-2],
[-3,
-248]],
[[56621,
62148],
[-1108,
1131],
[-1108,
1132],
[-280,
-323]],
[[72718,
55024],
[-42,
-615],
[-116,
-168],
[-242,
-135],
[-132,
470],
[-49,
849],
[126,
959],
[192,
-328],
[129,
-416],
[134,
-616]],
[[58049,
33472],
[96,
-178],
[-85,
-288],
[-47,
-192],
[-155,
-93],
[-51,
-188],
[-99,
-59],
[-209,
454],
[148,
374],
[151,
232],
[130,
120],
[121,
-182]],
[[56314,
82678],
[-23,
150],
[30,
162],
[-123,
94],
[-291,
103]],
[[55907,
83187],
[-59,
497]],
[[55848,
83684],
[318,
181],
[466,
-38],
[273,
59],
[39,
-123],
[148,
-38],
[267,
-287]],
[[56523,
82432],
[-67,
182],
[-142,
64]],
[[55848,
83684],
[10,
445],
[136,
371],
[262,
202],
[221,
-442],
[223,
12],
[53,
453]],
[[57579,
84537],
[134,
-136],
[24,
-287],
[89,
-348]],
[[47592,
66920],
[-42,
0],
[7,
-317],
[-172,
-19],
[-90,
-134],
[-126,
0],
[-100,
76],
[-234,
-63],
[-91,
-460],
[-86,
-44],
[-131,
-745],
[-386,
-637],
[-92,
-816],
[-114,
-265],
[-33,
-213],
[-625,
-48],
[-5,
1]],
[[45272,
63236],
[13,
274],
[106,
161],
[91,
308],
[-18,
200],
[96,
417],
[155,
376],
[93,
95],
[74,
344],
[6,
315],
[100,
365],
[185,
216],
[177,
603],
[5,
8],
[139,
227],
[259,
65],
[218,
404],
[140,
158],
[232,
493],
[-70,
735],
[106,
508],
[37,
312],
[179,
399],
[278,
270],
[206,
244],
[186,
612],
[87,
362],
[205,
-2],
[167,
-251],
[264,
41],
[288,
-131],
[121,
-6]],
[[57394,
79070],
[66,
87],
[185,
58],
[204,
-184],
[115,
-22],
[125,
-159],
[-20,
-200],
[101,
-97],
[40,
-247],
[97,
-150],
[-19,
-88],
[52,
-60],
[-74,
-44],
[-164,
18],
[-27,
81],
[-58,
-47],
[20,
-106],
[-76,
-188],
[-49,
-203],
[-70,
-64]],
[[57842,
77455],
[-50,
270],
[30,
252],
[-9,
259],
[-160,
352],
[-89,
249],
[-86,
175],
[-84,
58]],
[[63761,
43212],
[74,
-251],
[69,
-390],
[45,
-711],
[72,
-276],
[-28,
-284],
[-49,
-174],
[-94,
347],
[-53,
-175],
[53,
-438],
[-24,
-250],
[-77,
-137],
[-18,
-500],
[-109,
-689],
[-137,
-814],
[-172,
-1120],
[-106,
-821],
[-125,
-685],
[-226,
-140],
[-243,
-250],
[-160,
151],
[-220,
211],
[-77,
312],
[-18,
524],
[-98,
471],
[-26,
425],
[50,
426],
[128,
102],
[1,
197],
[133,
447],
[25,
377],
[-65,
280],
[-52,
372],
[-23,
544],
[97,
331],
[38,
375],
[138,
22],
[155,
121],
[103,
107],
[122,
7],
[158,
337],
[229,
364],
[83,
297],
[-38,
253],
[118,
-71],
[153,
410],
[6,
356],
[92,
264],
[96,
-254]],
[[23016,
65864],
[-107,
-518],
[-49,
-426],
[-20,
-791],
[-27,
-289],
[48,
-322],
[86,
-288],
[56,
-458],
[184,
-440],
[65,
-337],
[109,
-291],
[295,
-157],
[114,
-247],
[244,
165],
[212,
60],
[208,
106],
[175,
101],
[176,
241],
[67,
345],
[22,
496],
[48,
173],
[188,
155],
[294,
137],
[246,
-21],
[169,
50],
[66,
-125],
[-9,
-285],
[-149,
-351],
[-66,
-360],
[51,
-103],
[-42,
-255],
[-69,
-461],
[-71,
152],
[-58,
-10]],
[[24381,
59170],
[-314,
636],
[-144,
191],
[-226,
155],
[-156,
-43],
[-223,
-223],
[-140,
-58],
[-196,
156],
[-208,
112],
[-260,
271],
[-208,
83],
[-314,
275],
[-233,
282],
[-70,
158],
[-155,
35],
[-284,
187],
[-116,
270],
[-299,
335],
[-139,
373],
[-66,
288],
[93,
57],
[-29,
169],
[64,
153],
[1,
204],
[-93,
266],
[-25,
235],
[-94,
298],
[-244,
587],
[-280,
462],
[-135,
368],
[-238,
241],
[-51,
145],
[42,
365],
[-142,
138],
[-164,
287],
[-69,
412],
[-149,
48],
[-162,
311],
[-130,
288],
[-12,
184],
[-149,
446],
[-99,
452],
[5,
227],
[-201,
234],
[-93,
-25],
[-159,
163],
[-44,
-240],
[46,
-284],
[27,
-444],
[95,
-243],
[206,
-407],
[46,
-139],
[42,
-42],
[37,
-203],
[49,
8],
[56,
-381],
[85,
-150],
[59,
-210],
[174,
-300],
[92,
-550],
[83,
-259],
[77,
-277],
[15,
-311],
[134,
-20],
[112,
-268],
[100,
-264],
[-6,
-106],
[-117,
-217],
[-49,
3],
[-74,
359],
[-181,
337],
[-201,
286],
[-142,
150],
[9,
432],
[-42,
320],
[-132,
183],
[-191,
264],
[-37,
-76],
[-70,
154],
[-171,
143],
[-164,
343],
[20,
44],
[115,
-33],
[103,
221],
[10,
266],
[-214,
422],
[-163,
163],
[-102,
369],
[-103,
388],
[-129,
472],
[-113,
531]],
[[17464,
69802],
[316,
46],
[353,
64],
[-26,
-116],
[419,
-287],
[634,
-416],
[552,
4],
[221,
0],
[0,
244],
[481,
0],
[102,
-210],
[142,
-186],
[165,
-260],
[92,
-309],
[69,
-325],
[144,
-178],
[230,
-177],
[175,
467],
[227,
11],
[196,
-236],
[139,
-404],
[96,
-346],
[164,
-337],
[61,
-414],
[78,
-277],
[217,
-184],
[197,
-130],
[108,
18]],
[[55993,
75539],
[95,
35],
[128,
9]],
[[46619,
59216],
[93,
107],
[47,
348],
[88,
14],
[194,
-165],
[157,
117],
[107,
-39],
[42,
131],
[1114,
9],
[62,
414],
[-48,
73],
[-134,
2550],
[-134,
2550],
[425,
10]],
[[51185,
61897],
[1,
-1361],
[-152,
-394],
[-24,
-364],
[-247,
-94],
[-379,
-51],
[-102,
-210],
[-178,
-23]],
[[46801,
57931],
[13,
184],
[-24,
229],
[-104,
166],
[-54,
338],
[-13,
368]],
[[77375,
56448],
[-27,
439],
[86,
452],
[-94,
350],
[23,
644],
[-113,
306],
[-90,
707],
[-50,
746],
[-121,
490],
[-183,
-297],
[-315,
-421],
[-156,
53],
[-172,
138],
[96,
732],
[-58,
554],
[-218,
681],
[34,
213],
[-163,
76],
[-197,
481]],
[[77809,
62643],
[-159,
-137],
[-162,
-256],
[-196,
-26],
[-127,
-639],
[-117,
-107],
[134,
-519],
[177,
-431],
[113,
-390],
[-101,
-514],
[-96,
-109],
[66,
-296],
[185,
-470],
[32,
-330],
[-4,
-274],
[108,
-539],
[-152,
-551],
[-135,
-607]],
[[55380,
75322],
[-58,
46],
[-78,
192],
[-120,
118]],
[[55338,
76294],
[74,
-101],
[40,
-82],
[91,
-63],
[106,
-123],
[-22,
-51]],
[[74375,
79706],
[292,
102],
[530,
509],
[423,
278],
[242,
-182],
[289,
-8],
[186,
-276],
[277,
-22],
[402,
-148],
[270,
411],
[-113,
348],
[288,
612],
[311,
-244],
[252,
-69],
[327,
-152],
[53,
-443],
[394,
-248],
[263,
109],
[351,
78],
[279,
-78],
[272,
-284],
[168,
-302],
[258,
6],
[350,
-96],
[255,
146],
[366,
98],
[407,
416],
[166,
-63],
[146,
-198],
[331,
49]],
[[59599,
43773],
[209,
48],
[334,
-166],
[73,
74],
[193,
16],
[99,
177],
[167,
-10],
[303,
230],
[221,
342]],
[[61198,
44484],
[45,
-265],
[-11,
-588],
[34,
-519],
[11,
-923],
[49,
-290],
[-83,
-422],
[-108,
-410],
[-177,
-366],
[-254,
-225],
[-313,
-287],
[-313,
-634],
[-107,
-108],
[-194,
-420],
[-115,
-136],
[-23,
-421],
[132,
-448],
[54,
-346],
[4,
-177],
[49,
29],
[-8,
-579],
[-45,
-275],
[65,
-101],
[-41,
-245],
[-116,
-211],
[-229,
-199],
[-334,
-320],
[-122,
-219],
[24,
-248],
[71,
-40],
[-24,
-311]],
[[59119,
34780],
[-211,
5]],
[[58908,
34785],
[-24,
261],
[-41,
265]],
[[58843,
35311],
[-23,
212],
[49,
659],
[-72,
419],
[-133,
832]],
[[58664,
37433],
[292,
671],
[74,
426],
[42,
53],
[31,
348],
[-45,
175],
[12,
442],
[54,
409],
[0,
748],
[-145,
190],
[-132,
43],
[-60,
146],
[-128,
125],
[-232,
-12],
[-18,
220]],
[[58409,
41417],
[-26,
421],
[843,
487]],
[[59226,
42325],
[159,
-284],
[77,
54],
[110,
-149],
[16,
-237],
[-59,
-274],
[21,
-417],
[181,
-365],
[85,
410],
[120,
124],
[-24,
760],
[-116,
427],
[-100,
191],
[-97,
-9],
[-77,
768],
[77,
449]],
[[46619,
59216],
[-184,
405],
[-168,
435],
[-184,
157],
[-133,
173],
[-155,
-6],
[-135,
-129],
[-138,
51],
[-96,
-189]],
[[45426,
60113],
[-24,
318],
[78,
291],
[34,
557],
[-30,
583],
[-34,
294],
[28,
295],
[-72,
281],
[-146,
255]],
[[45260,
62987],
[60,
197],
[1088,
-4],
[-53,
853],
[68,
304],
[261,
53],
[-9,
1512],
[911,
-31],
[1,
895]],
[[59226,
42325],
[-147,
153],
[85,
549],
[87,
205],
[-53,
490],
[56,
479],
[47,
160],
[-71,
501],
[-131,
264]],
[[59099,
45126],
[273,
-110],
[55,
-164],
[95,
-275],
[77,
-804]],
[[78372,
54256],
[64,
-56],
[164,
-356],
[116,
-396],
[16,
-398],
[-29,
-269],
[27,
-203],
[20,
-349],
[98,
-163],
[109,
-523],
[-5,
-199],
[-197,
-40],
[-263,
438],
[-329,
469],
[-32,
301],
[-161,
395],
[-38,
489],
[-100,
322],
[30,
431],
[-61,
250]],
[[77801,
54399],
[48,
105],
[227,
-258],
[22,
-304],
[183,
71],
[91,
243]],
[[80461,
51765],
[204,
-202],
[214,
110],
[56,
500],
[119,
112],
[333,
128],
[199,
467],
[137,
374]],
[[82069,
53798],
[214,
411],
[140,
462],
[112,
2],
[143,
-299],
[13,
-257],
[183,
-165],
[231,
-177],
[-20,
-232],
[-186,
-29],
[50,
-289],
[-205,
-201]],
[[54540,
33696],
[-207,
446],
[-108,
432],
[-62,
575],
[-68,
428],
[-93,
910],
[-7,
707],
[-35,
322],
[-108,
243],
[-144,
489],
[-146,
708],
[-60,
371],
[-226,
577],
[-17,
453]],
[[56448,
40227],
[228,
134],
[180,
-34],
[109,
-133],
[2,
-49]],
[[55526,
35946],
[0,
-2182],
[-248,
-302],
[-149,
-43],
[-175,
112],
[-125,
43],
[-47,
252],
[-109,
162],
[-133,
-292]],
[[96049,
38125],
[228,
-366],
[144,
-272],
[-105,
-142],
[-153,
160],
[-199,
266],
[-179,
313],
[-184,
416],
[-38,
201],
[119,
-9],
[156,
-201],
[122,
-200],
[89,
-166]],
[[54125,
64088],
[68,
-919],
[104,
-153],
[4,
-188],
[116,
-203],
[-60,
-254],
[-107,
-1199],
[-15,
-769],
[-354,
-557],
[-120,
-778],
[115,
-219],
[0,
-380],
[178,
-13],
[-28,
-279]],
[[53939,
57955],
[-52,
-13],
[-188,
647],
[-65,
24],
[-217,
-331],
[-215,
173],
[-150,
34],
[-80,
-83],
[-163,
18],
[-164,
-252],
[-141,
-14],
[-337,
305],
[-131,
-145],
[-142,
10],
[-104,
223],
[-279,
221],
[-298,
-70],
[-72,
-128],
[-39,
-340],
[-80,
-238],
[-19,
-527]],
[[52361,
53399],
[-289,
-213],
[-105,
31],
[-107,
-132],
[-222,
13],
[-149,
370],
[-91,
427],
[-197,
389],
[-209,
-7],
[-245,
1]],
[[26191,
57131],
[-96,
186],
[-130,
238],
[-61,
200],
[-117,
185],
[-140,
267],
[31,
91],
[46,
-88],
[21,
41]],
[[26903,
59440],
[-24,
-57],
[-14,
-132],
[29,
-216],
[-64,
-202],
[-30,
-237],
[-9,
-261],
[15,
-152],
[7,
-266],
[-43,
-58],
[-26,
-253],
[19,
-156],
[-56,
-151],
[12,
-159],
[43,
-97]],
[[50920,
80916],
[143,
162],
[244,
869],
[380,
248],
[231,
-17]],
[[58639,
91676],
[-473,
-237],
[-224,
-54]],
[[55734,
91409],
[-172,
-24],
[-41,
-389],
[-523,
95],
[-74,
-329],
[-267,
2],
[-183,
-421],
[-278,
-655],
[-431,
-831],
[101,
-202],
[-97,
-234],
[-275,
10],
[-180,
-554],
[17,
-784],
[177,
-300],
[-92,
-694],
[-231,
-405],
[-122,
-341]],
[[53063,
85353],
[-187,
363],
[-548,
-684],
[-371,
-138],
[-384,
301],
[-99,
635],
[-88,
1363],
[256,
381],
[733,
496],
[549,
609],
[508,
824],
[668,
1141],
[465,
444],
[763,
741],
[610,
259],
[457,
-31],
[423,
489],
[506,
-26],
[499,
118],
[869,
-433],
[-358,
-158],
[305,
-371]],
[[56867,
96577],
[-620,
-241],
[-490,
137],
[191,
152],
[-167,
189],
[575,
119],
[110,
-222],
[401,
-134]],
[[55069,
97669],
[915,
-440],
[-699,
-233],
[-155,
-435],
[-243,
-111],
[-132,
-490],
[-335,
-23],
[-598,
361],
[252,
210],
[-416,
170],
[-541,
499],
[-216,
463],
[757,
212],
[152,
-207],
[396,
8],
[105,
202],
[408,
20],
[350,
-206]],
[[57068,
98086],
[545,
-207],
[-412,
-318],
[-806,
-70],
[-819,
98],
[-50,
163],
[-398,
11],
[-304,
271],
[858,
165],
[403,
-142],
[281,
177],
[702,
-148]],
[[98060,
26404],
[63,
-244],
[198,
239],
[80,
-249],
[0,
-249],
[-103,
-274],
[-182,
-435],
[-142,
-238],
[103,
-284],
[-214,
-7],
[-238,
-223],
[-75,
-387],
[-157,
-597],
[-219,
-264],
[-138,
-169],
[-256,
13],
[-180,
194],
[-302,
42],
[-46,
217],
[149,
438],
[349,
583],
[179,
111],
[200,
225],
[238,
310],
[167,
306],
[123,
441],
[106,
149],
[41,
330],
[195,
273],
[61,
-251]],
[[98502,
29218],
[202,
-622],
[5,
403],
[126,
-161],
[41,
-447],
[224,
-192],
[188,
-48],
[158,
226],
[141,
-69],
[-67,
-524],
[-85,
-345],
[-212,
12],
[-74,
-179],
[26,
-254],
[-41,
-110],
[-105,
-319],
[-138,
-404],
[-214,
-236],
[-48,
155],
[-116,
85],
[160,
486],
[-91,
326],
[-299,
236],
[8,
214],
[201,
206],
[47,
455],
[-13,
382],
[-113,
396],
[8,
104],
[-133,
244],
[-218,
523],
[-117,
418],
[104,
46],
[151,
-328],
[216,
-153],
[78,
-526]],
[[64752,
60417],
[-91,
413],
[-217,
975]],
[[64444,
61805],
[833,
591],
[185,
1182],
[-127,
418]],
[[65665,
65306],
[125,
-404],
[155,
-214],
[203,
-78],
[165,
-107],
[125,
-339],
[75,
-196],
[100,
-75],
[-1,
-132],
[-101,
-352],
[-44,
-166],
[-117,
-189],
[-104,
-404],
[-126,
31],
[-58,
-141],
[-44,
-300],
[34,
-395],
[-26,
-72],
[-128,
2],
[-174,
-221],
[-27,
-288],
[-63,
-125],
[-173,
5],
[-109,
-149],
[1,
-238],
[-134,
-165],
[-153,
56],
[-186,
-199],
[-128,
-34]],
[[65575,
65974],
[80,
201],
[35,
-51],
[-26,
-244],
[-37,
-108]],
[[68937,
64577],
[-203,
150],
[-83,
424],
[-215,
450],
[-512,
-111],
[-451,
-11],
[-391,
-83]],
[[28366,
54848],
[-93,
170],
[-59,
319],
[68,
158],
[-70,
40],
[-52,
196],
[-138,
164],
[-122,
-38],
[-56,
-205],
[-112,
-149],
[-61,
-20],
[-27,
-123],
[132,
-321],
[-75,
-76],
[-40,
-87],
[-130,
-30],
[-48,
353],
[-36,
-101],
[-92,
35],
[-56,
238],
[-114,
39],
[-72,
69],
[-119,
-1],
[-8,
-128],
[-32,
89]],
[[27070,
56232],
[100,
-212],
[-6,
-126],
[111,
-26],
[26,
48],
[77,
-145],
[136,
42],
[119,
150],
[168,
119],
[95,
176],
[153,
-34],
[-10,
-58],
[155,
-21],
[124,
-102],
[90,
-177],
[105,
-164]],
[[30452,
39739],
[-279,
340],
[-24,
242],
[-551,
593],
[-498,
646],
[-214,
365],
[-115,
488],
[46,
170],
[-236,
775],
[-274,
1090],
[-262,
1177],
[-114,
269],
[-87,
435],
[-216,
386],
[-198,
239],
[90,
264],
[-134,
563],
[86,
414],
[221,
373]],
[[85104,
55551],
[28,
-392],
[16,
-332],
[-94,
-540],
[-102,
602],
[-130,
-300],
[89,
-435],
[-79,
-277],
[-327,
343],
[-78,
428],
[84,
280],
[-176,
280],
[-87,
-245],
[-131,
23],
[-205,
-330],
[-46,
173],
[109,
498],
[175,
166],
[151,
223],
[98,
-268],
[212,
162],
[45,
264],
[196,
15],
[-16,
457],
[225,
-280],
[23,
-297],
[20,
-218]],
[[84439,
56653],
[-100,
-195],
[-87,
-373],
[-87,
-175],
[-171,
409],
[57,
158],
[70,
165],
[30,
367],
[153,
35],
[-44,
-398],
[205,
570],
[-26,
-563]],
[[82917,
56084],
[-369,
-561],
[136,
414],
[200,
364],
[167,
409],
[146,
587],
[49,
-482],
[-183,
-325],
[-146,
-406]],
[[83856,
57606],
[166,
-183],
[177,
1],
[-5,
-247],
[-129,
-251],
[-176,
-178],
[-10,
275],
[20,
301],
[-43,
282]],
[[84861,
57766],
[78,
-660],
[-214,
157],
[5,
-199],
[68,
-364],
[-132,
-133],
[-11,
416],
[-84,
31],
[-43,
357],
[163,
-47],
[-4,
224],
[-169,
451],
[266,
-13],
[77,
-220]],
[[83757,
58301],
[-74,
-510],
[-119,
295],
[-142,
450],
[238,
-22],
[97,
-213]],
[[83700,
61512],
[171,
-168],
[85,
153],
[26,
-150],
[-46,
-245],
[95,
-423],
[-73,
-491],
[-164,
-196],
[-43,
-476],
[62,
-471],
[147,
-65],
[123,
70],
[347,
-328],
[-27,
-321],
[91,
-142],
[-29,
-272],
[-216,
290],
[-103,
310],
[-71,
-217],
[-177,
354],
[-253,
-87],
[-138,
130],
[14,
244],
[87,
151],
[-83,
136],
[-36,
-213],
[-137,
340],
[-41,
257],
[-11,
566],
[112,
-195],
[29,
925],
[90,
535],
[169,
-1]],
[[93299,
46550],
[-78,
-59],
[-120,
227],
[-122,
375],
[-59,
450],
[38,
57],
[30,
-175],
[84,
-134],
[135,
-375],
[131,
-200],
[-39,
-166]],
[[92217,
47343],
[-146,
-48],
[-44,
-166],
[-152,
-144],
[-142,
-138],
[-148,
1],
[-228,
171],
[-158,
165],
[23,
183],
[249,
-86],
[152,
46],
[42,
283],
[40,
15],
[27,
-314],
[158,
45],
[78,
202],
[155,
211],
[-30,
348],
[166,
11],
[56,
-97],
[-5,
-327],
[-93,
-361]],
[[89166,
49043],
[482,
-407],
[513,
-338],
[192,
-302],
[154,
-297],
[43,
-349],
[462,
-365],
[68,
-313],
[-256,
-64],
[62,
-393],
[248,
-388],
[180,
-627],
[159,
20],
[-11,
-262],
[215,
-100],
[-84,
-111],
[295,
-249],
[-30,
-171],
[-184,
-41],
[-69,
153],
[-238,
66],
[-281,
89],
[-216,
377],
[-158,
325],
[-144,
517],
[-362,
259],
[-235,
-169],
[-170,
-195],
[35,
-436],
[-218,
-203],
[-155,
99],
[-288,
25]],
[[92538,
47921],
[-87,
-157],
[-52,
348],
[-65,
229],
[-126,
193],
[-158,
252],
[-200,
174],
[77,
143],
[150,
-166],
[94,
-130],
[117,
-142],
[111,
-248],
[106,
-189],
[33,
-307]],
[[53922,
82340],
[189,
174],
[434,
273],
[350,
200],
[277,
-100],
[21,
-144],
[268,
-7]],
[[55461,
82736],
[342,
-67],
[511,
9]],
[[56535,
81053],
[139,
-515],
[-29,
-166],
[-138,
-69],
[-252,
-491],
[71,
-266],
[-60,
35]],
[[56266,
79581],
[-264,
227],
[-200,
-84],
[-131,
61],
[-165,
-127],
[-140,
210],
[-114,
-81],
[-16,
36]],
[[31588,
61519],
[142,
-52],
[50,
-118],
[-71,
-149],
[-209,
4],
[-163,
-21],
[-16,
253],
[40,
86],
[227,
-3]],
[[86288,
75628],
[39,
-104]],
[[86327,
75524],
[-106,
36],
[-120,
-200],
[-83,
-202],
[10,
-424],
[-143,
-130],
[-50,
-105],
[-104,
-174],
[-185,
-97],
[-121,
-159],
[-9,
-256],
[-32,
-65],
[111,
-96],
[157,
-259]],
[[85048,
72883],
[-135,
112],
[-34,
-111],
[-81,
-49],
[-10,
112],
[-72,
54],
[-75,
94],
[76,
260],
[66,
69],
[-25,
108],
[71,
319],
[-18,
96],
[-163,
65],
[-131,
158]],
[[47929,
72498],
[-112,
-153],
[-146,
83],
[-143,
-65],
[42,
462],
[-26,
363],
[-124,
55],
[-67,
224],
[22,
386],
[111,
215],
[20,
239],
[58,
355],
[-6,
250],
[-56,
212],
[-12,
200]],
[[64113,
65205],
[-18,
430],
[75,
310],
[76,
64],
[84,
-185],
[5,
-346],
[-61,
-348]],
[[64274,
65130],
[-77,
-42],
[-84,
117]],
[[56308,
78869],
[120,
127],
[172,
-65],
[178,
-3],
[129,
-144],
[95,
91],
[205,
56],
[69,
139],
[118,
0]],
[[57842,
77455],
[124,
-109],
[131,
95],
[126,
-101]],
[[58223,
77340],
[6,
-152],
[-135,
-128],
[-84,
56],
[-78,
-713]],
[[56293,
76715],
[-51,
103],
[65,
99],
[-69,
74],
[-87,
-133],
[-162,
172],
[-22,
244],
[-169,
139],
[-31,
188],
[-151,
232]],
[[89901,
80562],
[280,
-1046],
[-411,
195],
[-171,
-854],
[271,
-605],
[-8,
-413],
[-211,
356],
[-182,
-457],
[-51,
496],
[31,
575],
[-32,
638],
[64,
446],
[13,
790],
[-163,
581],
[24,
808],
[257,
271],
[-110,
274],
[123,
83],
[73,
-391],
[96,
-569],
[-7,
-581],
[114,
-597]],
[[55461,
82736],
[63,
260],
[383,
191]],
[[99999,
92429],
[-305,
-30],
[-49,
187],
[-99645,
247],
[36,
24],
[235,
-1],
[402,
-169],
[-24,
-81],
[-286,
-141],
[-363,
-36],
[99999,
0]],
[[89889,
93835],
[-421,
-4],
[-569,
66],
[-49,
31],
[263,
234],
[348,
54],
[394,
-226],
[34,
-155]],
[[91869,
94941],
[-321,
-234],
[-444,
53],
[-516,
233],
[66,
192],
[518,
-89],
[697,
-155]],
[[90301,
95224],
[-219,
-439],
[-1023,
16],
[-461,
-139],
[-550,
384],
[149,
406],
[366,
111],
[734,
-26],
[1004,
-313]],
[[65981,
92363],
[-164,
-52],
[-907,
77],
[-74,
262],
[-503,
158],
[-40,
320],
[284,
126],
[-10,
323],
[551,
503],
[-255,
73],
[665,
518],
[-75,
268],
[621,
312],
[917,
380],
[925,
110],
[475,
220],
[541,
76],
[193,
-233],
[-187,
-184],
[-984,
-293],
[-848,
-282],
[-863,
-562],
[-414,
-577],
[-435,
-568],
[56,
-491],
[531,
-484]],
[[63639,
77993],
[-127,
-350],
[-269,
-97],
[-276,
-610],
[252,
-561],
[-27,
-398],
[303,
-696]],
[[61098,
76242],
[-354,
499],
[-317,
223],
[-240,
347],
[202,
95],
[231,
494],
[-156,
234],
[410,
241],
[-8,
129],
[-249,
-95]],
[[60617,
78409],
[9,
262],
[143,
165],
[269,
43],
[44,
197],
[-62,
326],
[113,
310],
[-3,
173],
[-410,
192],
[-162,
-6],
[-172,
277],
[-213,
-94],
[-352,
208],
[6,
116],
[-99,
256],
[-222,
29],
[-23,
183],
[70,
120],
[-178,
334],
[-288,
-57],
[-84,
30],
[-70,
-134],
[-104,
23]],
[[57772,
85719],
[316,
327],
[-291,
280]],
[[58639,
91676],
[286,
206],
[456,
-358],
[761,
-140],
[1050,
-668],
[213,
-281],
[18,
-393],
[-308,
-311],
[-454,
-157],
[-1240,
449],
[-204,
-75],
[453,
-433],
[18,
-274],
[18,
-604],
[358,
-180],
[217,
-153],
[36,
286],
[-168,
254],
[177,
224],
[672,
-368],
[233,
144],
[-186,
433],
[647,
578],
[256,
-34],
[260,
-206],
[161,
406],
[-231,
352],
[136,
353],
[-204,
367],
[777,
-190],
[158,
-331],
[-351,
-73],
[1,
-328],
[219,
-203],
[429,
128],
[68,
377],
[580,
282],
[970,
507],
[209,
-29],
[-273,
-359],
[344,
-61],
[199,
202],
[521,
16],
[412,
245],
[317,
-356],
[315,
391],
[-291,
343],
[145,
195],
[820,
-179],
[385,
-185],
[1006,
-675],
[186,
309],
[-282,
313],
[-8,
125],
[-335,
58],
[92,
280],
[-149,
461],
[-8,
189],
[512,
535],
[183,
537],
[206,
116],
[736,
-156],
[57,
-328],
[-263,
-479],
[173,
-189],
[89,
-413],
[-63,
-809],
[307,
-362],
[-120,
-395],
[-544,
-839],
[318,
-87],
[110,
213],
[306,
151],
[74,
293],
[240,
281],
[-162,
336],
[130,
390],
[-304,
49],
[-67,
328],
[222,
593],
[-361,
482],
[497,
398],
[-64,
421],
[139,
13],
[145,
-328],
[-109,
-570],
[297,
-108],
[-127,
426],
[465,
233],
[577,
31],
[513,
-337],
[-247,
492],
[-28,
630],
[483,
119],
[669,
-26],
[602,
77],
[-226,
309],
[321,
388],
[319,
16],
[540,
293],
[734,
79],
[93,
162],
[729,
55],
[227,
-133],
[624,
314],
[510,
-10],
[77,
255],
[265,
252],
[656,
242],
[476,
-191],
[-378,
-146],
[629,
-90],
[75,
-292],
[254,
143],
[812,
-7],
[626,
-289],
[223,
-221],
[-69,
-307],
[-307,
-175],
[-730,
-328],
[-209,
-175],
[345,
-83],
[410,
-149],
[251,
112],
[141,
-379],
[122,
153],
[444,
93],
[892,
-97],
[67,
-276],
[1162,
-88],
[15,
451],
[590,
-104],
[443,
4],
[449,
-312],
[128,
-378],
[-165,
-247],
[349,
-465],
[437,
-240],
[268,
620],
[446,
-266],
[473,
159],
[538,
-182],
[204,
166],
[455,
-83],
[-201,
549],
[367,
256],
[2509,
-384],
[236,
-351],
[727,
-451],
[1122,
112],
[553,
-98],
[231,
-244],
[-33,
-432],
[342,
-168],
[372,
121],
[492,
15],
[525,
-116],
[526,
66],
[484,
-526],
[344,
189],
[-224,
378],
[123,
262],
[886,
-165],
[578,
36],
[799,
-282],
[-99610,
-258],
[681,
-451],
[728,
-588],
[-24,
-367],
[187,
-147],
[-64,
429],
[754,
-88],
[544,
-553],
[-276,
-257],
[-455,
-61],
[-7,
-578],
[-111,
-122],
[-260,
17],
[-212,
206],
[-369,
172],
[-62,
257],
[-283,
96],
[-315,
-76],
[-151,
207],
[60,
219],
[-333,
-140],
[126,
-278],
[-158,
-251],
[99997,
-3],
[-357,
-260],
[-360,
44],
[250,
-315],
[166,
-487],
[128,
-159],
[32,
-244],
[-71,
-157],
[-518,
129],
[-777,
-445],
[-247,
-69],
[-425,
-415],
[-403,
-362],
[-102,
-269],
[-397,
409],
[-724,
-464],
[-126,
219],
[-268,
-253],
[-371,
81],
[-90,
-388],
[-333,
-572],
[10,
-239],
[316,
-132],
[-37,
-860],
[-258,
-22],
[-119,
-494],
[116,
-255],
[-486,
-302],
[-96,
-674],
[-415,
-144],
[-83,
-600],
[-400,
-551],
[-103,
407],
[-119,
862],
[-155,
1313],
[134,
819],
[234,
353],
[14,
276],
[432,
132],
[496,
744],
[479,
608],
[499,
471],
[223,
833],
[-337,
-50],
[-167,
-487],
[-705,
-649],
[-227,
727],
[-717,
-201],
[-696,
-990],
[230,
-362],
[-620,
-154],
[-430,
-61],
[20,
427],
[-431,
90],
[-344,
-291],
[-850,
102],
[-914,
-175],
[-899,
-1153],
[-1065,
-1394],
[438,
-74],
[136,
-370],
[270,
-132],
[178,
295],
[305,
-38],
[401,
-650],
[9,
-503],
[-217,
-590],
[-23,
-705],
[-126,
-945],
[-418,
-855],
[-94,
-409],
[-377,
-688],
[-374,
-682],
[-179,
-349],
[-370,
-346],
[-175,
-8],
[-175,
287],
[-373,
-432],
[-43,
-197]],
[[79187,
96845],
[-1566,
-228],
[507,
776],
[229,
66],
[208,
-38],
[704,
-336],
[-82,
-240]],
[[64204,
98169],
[-373,
-78],
[-250,
-45],
[-39,
-97],
[-324,
-98],
[-301,
140],
[158,
185],
[-618,
18],
[542,
107],
[422,
8],
[57,
-160],
[159,
142],
[262,
97],
[412,
-129],
[-107,
-90]],
[[77760,
97184],
[-606,
-73],
[-773,
170],
[-462,
226],
[-213,
423],
[-379,
117],
[722,
404],
[600,
133],
[540,
-297],
[640,
-572],
[-69,
-531]],
[[58449,
49909],
[110,
-333],
[-16,
-348],
[-80,
-74]],
[[58216,
49787],
[67,
-60],
[166,
182]],
[[45260,
62987],
[12,
249]],
[[61883,
60238],
[-37,
252],
[-83,
178],
[-22,
236],
[-143,
212],
[-148,
495],
[-79,
482],
[-192,
406],
[-124,
97],
[-184,
563],
[-32,
411],
[12,
350],
[-159,
655],
[-130,
231],
[-150,
122],
[-92,
339],
[15,
133],
[-77,
306],
[-81,
132],
[-108,
440],
[-170,
476],
[-141,
406],
[-139,
-3],
[44,
325],
[12,
206],
[34,
236]],
[[63448,
67449],
[109,
-510],
[137,
-135],
[47,
-207],
[190,
-249],
[16,
-243],
[-27,
-197],
[35,
-199],
[80,
-165],
[37,
-194],
[41,
-145]],
[[64274,
65130],
[53,
-226]],
[[64444,
61805],
[-801,
-226],
[-259,
-266],
[-199,
-620],
[-130,
-99],
[-70,
197],
[-106,
-30],
[-269,
60],
[-50,
59],
[-321,
-14],
[-75,
-53],
[-114,
153],
[-74,
-290],
[28,
-249],
[-121,
-189]],
[[59434,
56171],
[-39,
12],
[5,
294],
[-33,
203],
[-143,
233],
[-34,
426],
[34,
436],
[-129,
41],
[-19,
-132],
[-167,
-30],
[67,
-173],
[23,
-355],
[-152,
-324],
[-138,
-426],
[-144,
-61],
[-233,
345],
[-105,
-122],
[-29,
-172],
[-143,
-112],
[-9,
-122],
[-277,
0],
[-38,
122],
[-200,
20],
[-100,
-101],
[-77,
51],
[-143,
344],
[-48,
163],
[-200,
-81],
[-76,
-274],
[-72,
-528],
[-95,
-111],
[-85,
-65]],
[[56635,
55672],
[-23,
28]],
[[56351,
57163],
[3,
143],
[-102,
174],
[-3,
343],
[-58,
228],
[-98,
-34],
[28,
217],
[72,
246],
[-32,
245],
[92,
181],
[-58,
138],
[73,
365],
[127,
435],
[240,
-41],
[-14,
2345]],
[[60240,
63578],
[90,
-580],
[-61,
-107],
[40,
-608],
[102,
-706],
[106,
-145],
[152,
-219]],
[[59433,
56242],
[1,
-71]],
[[59434,
56171],
[3,
-460]],
[[59445,
53091],
[-171,
-272],
[-195,
1],
[-224,
-138],
[-176,
132],
[-115,
-161]],
[[56824,
55442],
[-189,
230]],
[[45357,
58612],
[-115,
460],
[-138,
210],
[122,
112],
[134,
415],
[66,
304]],
[[45367,
57897],
[-46,
453]],
[[95032,
44386],
[78,
-203],
[-194,
4],
[-106,
363],
[166,
-142],
[56,
-22]],
[[94680,
44747],
[-108,
-14],
[-170,
60],
[-58,
91],
[17,
235],
[183,
-93],
[91,
-124],
[45,
-155]],
[[94910,
44908],
[-42,
-109],
[-206,
512],
[-57,
353],
[94,
0],
[100,
-473],
[111,
-283]],
[[94409,
45654],
[12,
-119],
[-218,
251],
[-152,
212],
[-104,
197],
[41,
60],
[128,
-142],
[228,
-272],
[65,
-187]],
[[93760,
46238],
[-56,
-33],
[-121,
134],
[-114,
243],
[14,
99],
[166,
-250],
[111,
-193]],
[[46822,
54589],
[-75,
44],
[-200,
238],
[-144,
316],
[-49,
216],
[-34,
437]],
[[25613,
58487],
[-31,
-139],
[-161,
9],
[-100,
57],
[-115,
117],
[-154,
37],
[-79,
127]],
[[61984,
57352],
[91,
-109],
[54,
-245],
[125,
-247],
[138,
-2],
[262,
151],
[302,
70],
[245,
184],
[138,
39],
[99,
108],
[158,
20]],
[[63596,
57321],
[-2,
-9],
[-1,
-244],
[0,
-596],
[0,
-308],
[-125,
-363],
[-194,
-493]],
[[63596,
57321],
[89,
12],
[128,
88],
[147,
59],
[132,
202],
[105,
2],
[6,
-163],
[-25,
-344],
[1,
-310],
[-59,
-214],
[-78,
-639],
[-134,
-659],
[-172,
-755],
[-238,
-866],
[-237,
-661],
[-327,
-806],
[-278,
-479],
[-415,
-586],
[-259,
-450],
[-304,
-715],
[-64,
-312],
[-63,
-140]],
[[34125,
54109],
[333,
-119],
[30,
107],
[225,
43],
[298,
-159]],
[[34889,
53069],
[109,
-351],
[-49,
-254],
[-24,
-270],
[-71,
-248]],
[[56266,
79581],
[-77,
-154],
[-55,
-238]],
[[53809,
77462],
[62,
54]],
[[56639,
89578],
[-478,
-167],
[-269,
-413],
[43,
-361],
[-441,
-475],
[-537,
-509],
[-202,
-832],
[198,
-416],
[265,
-328],
[-255,
-666],
[-289,
-138],
[-106,
-992],
[-157,
-554],
[-337,
57],
[-158,
-468],
[-321,
-27],
[-89,
558],
[-232,
671],
[-211,
835]],
[[58908,
34785],
[-56,
-263],
[-163,
-63],
[-166,
320],
[-2,
204],
[76,
222],
[26,
172],
[80,
42],
[140,
-108]],
[[59999,
71049],
[-26,
452],
[68,
243]],
[[60041,
71744],
[74,
129],
[75,
130],
[15,
329],
[91,
-115],
[306,
165],
[147,
-112],
[229,
2],
[320,
222],
[149,
-10],
[316,
92]],
[[50518,
54209],
[-224,
-126]],
[[78495,
57780],
[-249,
271],
[-238,
-11],
[41,
464],
[-245,
-3],
[-22,
-650],
[-150,
-863],
[-90,
-522],
[19,
-428],
[181,
-18],
[113,
-539],
[50,
-512],
[155,
-338],
[168,
-69],
[144,
-306]],
[[77801,
54399],
[-110,
227],
[-47,
292],
[-148,
334],
[-135,
280],
[-45,
-347],
[-53,
328],
[30,
369],
[82,
566]],
[[68841,
72526],
[156,
598],
[-60,
440],
[-204,
140],
[72,
261],
[232,
-28],
[132,
326],
[89,
380],
[371,
137],
[-58,
-274],
[40,
-164],
[114,
15]],
[[64978,
72558],
[-52,
417],
[40,
618],
[-216,
200],
[71,
405],
[-184,
34],
[61,
498],
[262,
-145],
[244,
189],
[-202,
355],
[-80,
338],
[-224,
-151],
[-28,
-433],
[-87,
383]],
[[65546,
74986],
[313,
8],
[-45,
297],
[237,
204],
[234,
343],
[374,
-312],
[30,
-471],
[106,
-121],
[301,
27],
[93,
-108],
[137,
-609],
[317,
-408],
[181,
-278],
[291,
-289],
[369,
-253],
[-7,
-362]],
[[84713,
45326],
[32,
139],
[239,
133],
[194,
20],
[87,
74],
[105,
-74],
[-102,
-160],
[-289,
-258],
[-233,
-170]],
[[32866,
56937],
[160,
77],
[58,
-21],
[-11,
-440],
[-232,
-65],
[-50,
53],
[81,
163],
[-6,
233]],
[[52339,
72408],
[302,
239],
[195,
-71],
[-9,
-299],
[236,
217],
[20,
-113],
[-139,
-290],
[-2,
-273],
[96,
-147],
[-36,
-511],
[-183,
-297],
[53,
-322],
[143,
-10],
[70,
-281],
[106,
-92]],
[[60041,
71744],
[-102,
268],
[105,
222],
[-169,
-51],
[-233,
136],
[-191,
-340],
[-421,
-66],
[-225,
317],
[-300,
20],
[-64,
-245],
[-192,
-70],
[-268,
314],
[-303,
-11],
[-165,
588],
[-203,
328],
[135,
459],
[-176,
283],
[308,
565],
[428,
23],
[117,
449],
[529,
-78],
[334,
383],
[324,
167],
[459,
13],
[485,
-417],
[399,
-228],
[323,
91],
[239,
-53],
[328,
309]],
[[57776,
75399],
[33,
-228],
[243,
-190],
[-51,
-145],
[-330,
-33],
[-118,
-182],
[-232,
-319],
[-87,
276],
[3,
121]],
[[83826,
64992],
[-167,
-947],
[-119,
-485],
[-146,
499],
[-32,
438],
[163,
581],
[223,
447],
[127,
-176],
[-49,
-357]],
[[60889,
47817],
[-128,
-728],
[16,
-335],
[178,
-216],
[8,
-153],
[-76,
-357],
[16,
-180],
[-18,
-282],
[97,
-370],
[115,
-583],
[101,
-129]],
[[59099,
45126],
[-157,
177],
[-177,
100],
[-111,
99],
[-116,
150]],
[[58388,
46397],
[-161,
331],
[-55,
342]],
[[58449,
49909],
[98,
71],
[304,
-7],
[566,
45]],
[[60617,
78409],
[-222,
-48],
[-185,
-191],
[-260,
-31],
[-239,
-220],
[16,
-368],
[136,
-142],
[284,
35],
[-55,
-210],
[-304,
-103],
[-377,
-342],
[-154,
121],
[61,
277],
[-304,
173],
[50,
113],
[265,
197],
[-80,
135],
[-432,
149],
[-19,
221],
[-257,
-73],
[-103,
-325],
[-215,
-437]],
[[35174,
30629],
[-121,
-372],
[-313,
-328],
[-205,
118],
[-151,
-63],
[-256,
253],
[-189,
-19],
[-169,
327]],
[[6794,
61855],
[-41,
-99],
[-69,
84],
[8,
165],
[-46,
216],
[14,
65],
[48,
97],
[-19,
116],
[16,
55],
[21,
-11],
[107,
-100],
[49,
-51],
[45,
-79],
[71,
-207],
[-7,
-33],
[-108,
-126],
[-89,
-92]],
[[6645,
62777],
[-94,
-43],
[-47,
125],
[-32,
48],
[-3,
37],
[27,
50],
[99,
-56],
[73,
-90],
[-23,
-71]],
[[6456,
63091],
[-9,
-63],
[-149,
17],
[21,
72],
[137,
-26]],
[[6207,
63177],
[-15,
-34],
[-19,
8],
[-97,
21],
[-35,
133],
[-11,
24],
[74,
82],
[23,
-38],
[80,
-196]],
[[5737,
63567],
[-33,
-58],
[-93,
107],
[14,
43],
[43,
58],
[64,
-12],
[5,
-138]],
[[31350,
77248],
[48,
-194],
[-296,
-286],
[-286,
-204],
[-293,
-175],
[-147,
-351],
[-47,
-133],
[-3,
-313],
[92,
-313],
[115,
-15],
[-29,
216],
[83,
-131],
[-22,
-169],
[-188,
-96],
[-133,
11],
[-205,
-103],
[-121,
-29],
[-162,
-29],
[-231,
-171],
[408,
111],
[82,
-112],
[-389,
-177],
[-177,
-1],
[8,
72],
[-84,
-164],
[82,
-27],
[-60,
-424],
[-203,
-455],
[-20,
152],
[-61,
30],
[-91,
148],
[57,
-318],
[69,
-105],
[5,
-223],
[-89,
-230],
[-157,
-472],
[-25,
24],
[86,
402],
[-142,
225],
[-33,
491],
[-53,
-255],
[59,
-375],
[-183,
93],
[191,
-191],
[12,
-562],
[79,
-41],
[29,
-204],
[39,
-591],
[-176,
-439],
[-288,
-175],
[-182,
-346],
[-139,
-38],
[-141,
-217],
[-39,
-199],
[-305,
-383],
[-157,
-281],
[-131,
-351],
[-43,
-419],
[50,
-411],
[92,
-505],
[124,
-418],
[1,
-256],
[132,
-685],
[-9,
-398],
[-12,
-230],
[-69,
-361],
[-83,
-75],
[-137,
72],
[-44,
259],
[-105,
136],
[-148,
508],
[-129,
452],
[-42,
231],
[57,
393],
[-77,
325],
[-217,
494],
[-108,
90],
[-281,
-268],
[-49,
30],
[-135,
275],
[-174,
147],
[-314,
-75],
[-247,
66],
[-212,
-41],
[-114,
-92],
[50,
-157],
[-5,
-240],
[59,
-117],
[-53,
-77],
[-103,
87],
[-104,
-112],
[-202,
18],
[-207,
312],
[-242,
-73],
[-202,
137],
[-173,
-42],
[-234,
-138],
[-253,
-438],
[-276,
-255],
[-152,
-282],
[-63,
-266],
[-3,
-407],
[14,
-284],
[52,
-201]],
[[17464,
69802],
[-46,
302],
[-180,
340],
[-130,
71],
[-30,
169],
[-156,
30],
[-100,
159],
[-258,
59],
[-71,
95],
[-33,
324],
[-270,
594],
[-231,
821],
[10,
137],
[-123,
195],
[-215,
495],
[-38,
482],
[-148,
323],
[61,
489],
[-10,
507],
[-89,
453],
[109,
557],
[34,
536],
[33,
536],
[-50,
792],
[-88,
506],
[-80,
274],
[33,
115],
[402,
-200],
[148,
-558],
[69,
156],
[-45,
484],
[-94,
485]],
[[7498,
84325],
[-277,
-225],
[-142,
152],
[-43,
277],
[252,
210],
[148,
90],
[185,
-40],
[117,
-183],
[-240,
-281]],
[[4006,
85976],
[-171,
-92],
[-182,
110],
[-168,
161],
[274,
101],
[220,
-54],
[27,
-226]],
[[2297,
88264],
[171,
-113],
[173,
61],
[225,
-156],
[276,
-79],
[-23,
-64],
[-211,
-125],
[-211,
128],
[-106,
107],
[-245,
-34],
[-66,
52],
[17,
223]],
[[13740,
82958],
[-153,
223],
[-245,
188],
[-78,
515],
[-358,
478],
[-150,
558],
[-267,
38],
[-441,
15],
[-326,
170],
[-574,
613],
[-266,
112],
[-486,
211],
[-385,
-51],
[-546,
272],
[-330,
252],
[-309,
-125],
[58,
-411],
[-154,
-38],
[-321,
-123],
[-245,
-199],
[-308,
-126],
[-39,
348],
[125,
580],
[295,
182],
[-76,
148],
[-354,
-329],
[-190,
-394],
[-400,
-420],
[203,
-287],
[-262,
-424],
[-299,
-248],
[-278,
-180],
[-69,
-261],
[-434,
-305],
[-87,
-278],
[-325,
-252],
[-191,
45],
[-259,
-165],
[-282,
-201],
[-231,
-197],
[-477,
-169],
[-43,
99],
[304,
276],
[271,
182],
[296,
324],
[345,
66],
[137,
243],
[385,
353],
[62,
119],
[205,
208],
[48,
448],
[141,
349],
[-320,
-179],
[-90,
102],
[-150,
-215],
[-181,
300],
[-75,
-212],
[-104,
294],
[-278,
-236],
[-170,
0],
[-24,
352],
[50,
216],
[-179,
211],
[-361,
-113],
[-235,
277],
[-190,
142],
[-1,
334],
[-214,
252],
[108,
340],
[226,
330],
[99,
303],
[225,
43],
[191,
-94],
[224,
285],
[201,
-51],
[212,
183],
[-52,
270],
[-155,
106],
[205,
228],
[-170,
-7],
[-295,
-128],
[-85,
-131],
[-219,
131],
[-392,
-67],
[-407,
142],
[-117,
238],
[-351,
343],
[390,
247],
[620,
289],
[228,
0],
[-38,
-296],
[586,
23],
[-225,
366],
[-342,
225],
[-197,
296],
[-267,
252],
[-381,
187],
[155,
309],
[493,
19],
[350,
270],
[66,
287],
[284,
281],
[271,
68],
[526,
262],
[256,
-40],
[427,
315],
[421,
-124],
[201,
-266],
[123,
114],
[469,
-35],
[-16,
-136],
[425,
-101],
[283,
59],
[585,
-186],
[534,
-56],
[214,
-77],
[370,
96],
[421,
-177],
[302,
-83]],
[[30185,
57537],
[-8,
-139],
[-163,
-69],
[91,
-268],
[-3,
-309],
[-123,
-344],
[105,
-468],
[120,
38],
[62,
427],
[-86,
208],
[-14,
447],
[346,
241],
[-38,
278],
[97,
186],
[100,
-415],
[195,
-9],
[180,
-330],
[11,
-195],
[249,
-6],
[297,
61],
[159,
-264],
[213,
-74],
[155,
185],
[4,
149],
[344,
35],
[333,
9],
[-236,
-175],
[95,
-279],
[222,
-44],
[210,
-291],
[45,
-473],
[144,
13],
[109,
-139]],
[[80013,
63313],
[-371,
-505],
[-231,
-558],
[-61,
-410],
[212,
-623],
[260,
-772],
[252,
-365],
[169,
-475],
[127,
-1093],
[-37,
-1039],
[-232,
-389],
[-318,
-381],
[-227,
-492],
[-346,
-550],
[-101,
378],
[78,
401],
[-206,
335]],
[[96623,
40851],
[-92,
-78],
[-93,
259],
[10,
158],
[175,
-339]],
[[96418,
41756],
[45,
-476],
[-75,
74],
[-58,
-32],
[-39,
163],
[-6,
453],
[133,
-182]],
[[64752,
60417],
[-201,
-158],
[-54,
-263],
[-6,
-201],
[-277,
-249],
[-444,
-276],
[-249,
-417],
[-122,
-33],
[-83,
35],
[-163,
-245],
[-177,
-114],
[-233,
-30],
[-70,
-34],
[-61,
-156],
[-73,
-43],
[-43,
-150],
[-137,
13],
[-89,
-80],
[-192,
30],
[-72,
345],
[8,
323],
[-46,
174],
[-54,
437],
[-80,
243],
[56,
29],
[-29,
270],
[34,
114],
[-12,
257]],
[[58175,
37528],
[113,
-7],
[134,
-100],
[94,
71],
[148,
-59]],
[[59119,
34780],
[-70,
-430],
[-32,
-491],
[-72,
-267],
[-190,
-298],
[-54,
-86],
[-118,
-300],
[-77,
-303],
[-158,
-424],
[-314,
-609],
[-196,
-355],
[-210,
-269],
[-290,
-229],
[-141,
-31],
[-36,
-164],
[-169,
88],
[-138,
-113],
[-301,
114],
[-168,
-72],
[-115,
31],
[-286,
-233],
[-238,
-94],
[-171,
-223],
[-127,
-14],
[-117,
210],
[-94,
11],
[-120,
264],
[-13,
-82],
[-37,
159],
[2,
346],
[-90,
396],
[89,
108],
[-7,
453],
[-182,
553],
[-139,
501],
[-1,
1],
[-199,
768]],
[[58409,
41417],
[-210,
-81],
[-159,
-235],
[-33,
-205],
[-100,
-46],
[-241,
-486],
[-154,
-383],
[-94,
-13],
[-90,
68],
[-311,
65]]],
"bbox": [-180,
-85.60903777459767,
180,
83.64513000000001],
"transform": {
"scale": [0.0036000360003600037,
0.00169255860333201],
"translate": [-180,
-85.60903777459767]
}
}
/* -------------------------- */
/* enty */
/* -------------------------- */
var enty = function enty() {}
enty.data = () => data
return enty
}
exports.dataWorldTopo110m = dataWorldTopo110m
}));
/* d3 */
document.write("<script src='d3.v4.js'><\/script>")
document.write("<script src='d3-force-3d.bundle.js'><\/script>")
document.write("<script src='d3-force-bounce.js'><\/script>")
document.write("<script src='d3-force-magnetic.js'><\/script>")
document.write("<script src='d3-force-surface.js'><\/script>")
document.write("<script src='d3-geo.js'><\/script>")
document.write("<script src='d3-geo-polygon.js'><\/script>")
document.write("<script src='d3-geo-projection-clip-polyhedral.js'><\/script>")
document.write("<script src='d3-geo-voronoi.js'><\/script>")
/* topojson */
document.write("<script src='topojson.v3.js'><\/script>")
/* three */
document.write("<script src='three.min.js'><\/script>")
document.write("<script src='three-trackballcontrols.js'><\/script>")
@ECHO OFF
REM create file to load js components
SET outEnts=ents.js
if EXIST %outEnts% DEL %outEnts%
SET outEnls=enls.js
if EXIST %outEnls% DEL %outEnls%
setlocal enabledelayedexpansion
REM enls
echo /* d3 */ >> %outEnls%
for /f "delims=" %%f in ('dir /b /a-d /on d3*') do echo document.write("<script src='%%f'><\/script>") >> %outEnls%
echo /* topojson */ >> %outEnls%
for /f "delims=" %%f in ('dir /b /a-d /on topojson*') do echo document.write("<script src='%%f'><\/script>") >> %outEnls%
echo /* three */ >> %outEnls%
for /f "delims=" %%f in ('dir /b /a-d /on three*') do echo document.write("<script src='%%f'><\/script>") >> %outEnls%
REM ents
echo /* https://www.irt.org/script/974.htm */ >> %outEnts%
echo /* bosons */ >> %outEnts%
for /f "delims=" %%f in ('dir /b /a-d /on boson*') do echo document.write("<script src='%%f'><\/script>") >> %outEnts%
echo /* controls */ >> %outEnts%
for /f "delims=" %%f in ('dir /b /a-d /on control*') do echo document.write("<script src='%%f'><\/script>") >> %outEnts%
echo /* data */ >> %outEnts%
for /f "delims=" %%f in ('dir /b /a-d /on data*') do echo document.write("<script src='%%f'><\/script>") >> %outEnts%
echo /* forces */ >> %outEnts%
for /f "delims=" %%f in ('dir /b /a-d /on force*') do echo document.write("<script src='%%f'><\/script>") >> %outEnts%
echo /* geos projections */ >> %outEnts%
for /f "delims=" %%f in ('dir /b /a-d /on geo*') do echo document.write("<script src='%%f'><\/script>") >> %outEnts%
echo /* lib */ >> %outEnts%
for /f "delims=" %%f in ('dir /b /a-d /on lib*') do echo document.write("<script src='%%f'><\/script>") >> %outEnts%
echo /* muons */ >> %outEnts%
for /f "delims=" %%f in ('dir /b /a-d /on muon*') do echo document.write("<script src='%%f'><\/script>") >> %outEnts%
echo /* halo */ >> %outEnts%
for /f "delims=" %%f in ('dir /b /a-d /on halo*') do echo document.write("<script src='%%f'><\/script>") >> %outEnts%
echo /* x proxy */ >> %outEnts%
for /f "delims=" %%f in ('dir /b /a-d /on x*') do echo document.write("<script src='%%f'><\/script>") >> %outEnts%
echo /* renderers */ >> %outEnts%
for /f "delims=" %%f in ('dir /b /a-d /on render*') do echo document.write("<script src='%%f'><\/script>") >> %outEnts%
endlocal
:END
:eof
/* https://www.irt.org/script/974.htm */
/* bosons */
document.write("<script src='boson-clone.js'><\/script>")
document.write("<script src='boson-gist.js'><\/script>")
document.write("<script src='boson-image.js'><\/script>")
document.write("<script src='boson-init.js'><\/script>")
document.write("<script src='boson-mapper.js'><\/script>")
document.write("<script src='boson-polyhedral.js'><\/script>")
document.write("<script src='boson-proj3ct.js'><\/script>")
document.write("<script src='boson-props.js'><\/script>")
document.write("<script src='boson-snap.js'><\/script>")
document.write("<script src='boson-tim.js'><\/script>")
document.write("<script src='boson-versor.js'><\/script>")
/* controls */
document.write("<script src='control-mouseDown.js'><\/script>")
document.write("<script src='control-mouseUp.js'><\/script>")
document.write("<script src='control-raycaster.js'><\/script>")
document.write("<script src='control-timer.js'><\/script>")
document.write("<script src='control-versor.js'><\/script>")
document.write("<script src='control-wen.js'><\/script>")
/* data */
document.write("<script src='data-worldTopo110m.js'><\/script>")
/* forces */
/* geos projections */
document.write("<script src='geo-futuri.js'><\/script>")
document.write("<script src='geo-hedrals.js'><\/script>")
document.write("<script src='geo-natform.js'><\/script>")
document.write("<script src='geo-uniwen.js'><\/script>")
/* lib */
document.write("<script src='lib-complex.js'><\/script>")
document.write("<script src='lib-dat.gui.js'><\/script>")
/* muons */
document.write("<script src='muon-animation.js'><\/script>")
document.write("<script src='muon-anitem.js'><\/script>")
document.write("<script src='muon-geoj.js'><\/script>")
document.write("<script src='muon-geom.js'><\/script>")
document.write("<script src='muon-graticule.js'><\/script>")
document.write("<script src='muon-nat.js'><\/script>")
document.write("<script src='muon-ric.js'><\/script>")
document.write("<script src='muon-simulation.js'><\/script>")
document.write("<script src='muon-stace.js'><\/script>")
document.write("<script src='muon-store.js'><\/script>")
document.write("<script src='muon-timer.js'><\/script>")
document.write("<script src='muon-wen.js'><\/script>")
/* halo */
document.write("<script src='halo-core.js'><\/script>")
document.write("<script src='halo-geojson.js'><\/script>")
document.write("<script src='halo-img.js'><\/script>")
document.write("<script src='halo-nat.js'><\/script>")
document.write("<script src='halo-text.js'><\/script>")
/* x proxy */
document.write("<script src='x-s.js'><\/script>")
/* renderers */
document.write("<script src='render-renderer.js'><\/script>")
document.write("<script src='render-SVG.js'><\/script>")
document.write("<script src='render-webgl.js'><\/script>")
// <script src='https://d3js.org/d3.v4.min.js'></script>
// <script src='https://d3js.org/d3-geo.v1.min.js'></script>
// <script src='https://d3js.org/d3-geo-projection.v2.min.js'></script>
// <script src='https:////unpkg.com/d3-force-3d@1.0/build/d3-force-3d.bundle.min.js'></script>
// <script src='https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.0/topojson.min.js'></script>
// <script src='https:////cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js'></script>
// <script src='https:////unpkg.com/three-trackballcontrols-web@0.0.2/dist/three-trackballcontrols.min.js'></script>
// d3
document.write("<script src='https://d3js.org/d3.v4.min.js'><\/script>")
document.write("<script src='https://d3js.org/d3-geo.v1.min.js'><\/script>")
document.write("<script src='https://d3js.org/d3-geo-projection.v2.min.js'><\/script>")
document.write("<script src='https:////unpkg.com/d3-force-3d@1.0/build/d3-force-3d.bundle.min.js'><\/script>")
// topojson
document.write("<script src='https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.0/topojson.min.js'><\/script>")
// three
document.write("<script src='https:////cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js'><\/script>")
document.write("<script src='https:////unpkg.com/three-trackballcontrols-web@0.0.2/dist/three-trackballcontrols.min.js'><\/script>")
/*******************************************
* @geofuturi
*
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.geofuturi = global.geofuturi || {})));
}(this, function (exports) { 'use strict';
// Philippe Rivière’s Block 14ddff5e46b6fe9341dae91c3c83304b
// Updated August 6, 2017
// Furuti cubic projection #Carlos Furuti's cubic globe #1 - http://www.progonos.com/furuti/MapProj/Normal/ProjPoly/projPoly2.html
// Based on "Earth in a Cube" by Enrico Spinielli and on my research for d3-geo-projection/pull/86 and d3-geo/issues/46.
// Re-incorporating Jason Davies’ clipPolygon() code into d3v4.
// Code base at Fil/d3-geo:clip-polygon.
// See also https://bl.ocks.org/Fil/694ba0d0bc1fc4c24eb257dc210eb01a
// forked from Fil's block: Furuti 3 - projection.clipPolygon()
// LICENSE# Released under the The MIT License.
var geofuturi = function geofuturi(__mapper = {}) {
let renderer = __mapper("renderRenderer"),
width = renderer.width(),
height = renderer.height()
let f = __mapper({"props": bosonProps.bosonProps()}).props()
let g = __mapper("xs").m("geom")
let w = __mapper("xs").m("wen")
let versor = __mapper("xs").b("versor")()
let wen = __mapper("xs").c("wen")()
let scaleProj = Math.min(width/2, height)/Math.PI
let epsilon = 1e-6, epsilon2 = epsilon * epsilon
let asin = Math.asin, atan = Math.atan
let pi = Math.PI, degrees = 180 / pi, radians = pi / 180
let asin1_3 = Math.asin(1 / 3)
let sqrt1_2 = Math.SQRT1_2
let abs = Math.abs;
let eps = 1e-6
/*******************************************
* @polyhedron
*/
let vertices = []
let mode = "cartesian"
if ( mode === "spherical") {
let ang = 90,
phi1 = atan(sqrt1_2) * degrees // 35.264389682754654
vertices = [
[ (-1 * ang - 45), phi1], // 3
[ (0 * ang - 45), phi1], // 0
[ (1 * ang - 45), phi1], // 1
[ (2 * ang - 45), phi1], // 2
[ (-1 * ang - 45), -phi1], // 7
[ (0 * ang - 45), -phi1], // 4
[ (1 * ang - 45), -phi1], // 5
[ (2 * ang - 45), -phi1], // 6
]
} else {
vertices = [
[-1, -1, 1], // 0 // 0
[ 1, -1, 1], // 1 // 1
[ 1, 1, 1], // 2 // 2
[-1, 1, 1], // 3 // 3
[-1, -1, -1], // 5 // 4
[ 1, -1, -1], // 4 // 5
[ 1, 1, -1], // 7 // 6
[-1, 1, -1], // 6 // 7
].map(g.normalize)
.map(g.spherical)
.map(g.to_degrees)
vertices = d3.merge([
vertices,
])
}
let faces = [
[1, 0, 3, 2, 1], // N
[1, 2, 6, 5, 1],
[2, 3, 7, 6, 2],
[3, 0, 4, 7, 3],
[0, 1, 5, 4, 0],
[5, 6, 7, 4, 5] // S
].map(function(face) {
return face.map(function(i) {
return vertices[i]
})
})
/*******************************************
* @enty
*/
let enty = function( p={} ) {
if (!p.faciaRotation) p.faciaRotation = Math.PI / 4
if (!p.geoRotation) p.geoRotation = c => [-c[0], -c[1], 0]
if (!p.tree) p.tree = [-1, 4, 5, 2, 0, 1] // [-1, 0, 0, 0, 0, 4] //
if (!p.rotate) p.rotate = [28,-4,0] // California
if (!p.prjRaw) p.prjRaw = d3.geoGnomonicRaw
if (!p.faces) p.faces = faces
return __mapper("xs").b("polyhedral")(p)
}
return enty
}
exports.geofuturi = geofuturi
}));
/***************************
* @geoHedrals
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.geoHedrals = global.geoHedrals || {})));
}(this, function (exports) { 'use strict';
var geoHedrals = function geoHedrals(__mapper = {}) {
let renderer = __mapper("renderRenderer"),
width = renderer.width(),
height = renderer.height()
let f = __mapper("props")()
let g = __mapper("xs").m("geom")
let mwen = __mapper("xs").m("wen")
let versor = __mapper("xs").b("versor")()
let cwen = __mapper("xs").c("wen")()
let pi = Math.PI, degrees = 180 / pi, radians = pi / 180
/****************************
* @enty
*/
let enty = function( p={} ) {
if (!p.faciaRotation) p.faciaRotation = Math.PI / 4 // faciaRotation
if (!p.geoRotation) p.geoRotation = c => [-c[0], -c[1], 0] // geoRotation
if (!p.prjRaw) p.prjRaw = d3.geoGnomonicRaw // prjRaw
p.tree = f.entxx("tree", "trees", "treeidx", p) // tree
if (!p.tree) p.tree = [-1]
let {vertices, faces} = p
vertices = d3.merge([ vertices,]) // spher degrees eg. [-45, 35.2643]
// .map(g.normalize).map(g.spherical).map(g.to_degrees)
faces = faces.map(function(face) { // faces : points => vertices
return face.map(function(p) { // eg. [1, 0, 3, 2, 1]
return vertices[p]
}) // eg. [-45, 35], [-135, 35], [135, 35], [45, 354], [-45, 35]
})
p.faces = faces // faces
return __mapper("xs").b("polyhedral")(p) // get polyhedral projection
}
return enty
}
exports.geoHedrals = geoHedrals
}));
/*******************************************
* @geoNatform
*
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.geoNatform = global.geoNatform || {})))
}(this, function (exports) { "use strict"
let geoNatform = function geoNatform(__mapper = {}) {
let f = __mapper("props")()
let g = __mapper("xs").m("geom")
let mwen = __mapper("xs").m("wen")
let cwen = __mapper("xs").c("wen")
const geoscale = extent => d3.scaleLinear().domain(extent[0]).range(extent[1])
const cos = Math.cos, sin = Math.sin
const neg = x => x < 0 || (x === 0 && (1/x < 0))
const pos = x => x > 0 || (x === 0 && (1/x > 0))
const radians = Math.PI / 180
const tau = 2 * Math.PI
let state = {},
scale = [1, 1, 1],
rotate = [0, 0, 0],
translate = [0, 0, 0],
focale = Infinity,
zafin = [0,1],
dims = 3
let pointStream = function(props) { // anitem or form
let form = (props.form !== undefined) ? props.form : props
let natform = __mapper("xs").m("nat").natform(form) // m.nat.natform
let natstream = function (lambda, phi, radio=1) {
this.stream.point(...natform(lambda, phi, radio))
}
return natstream
}
let proform = function(props) {
let geoTrans = d3.geoTransform({
point: pointStream(props)})
let geoProj = p => geoTrans(p)
geoProj.stream = s => geoTrans.stream(s)
return geoProj
}
/****************************
* @enty
*/
let enty = function (props={}) {
let m = proform(props)
m.translate = _ => _ !== undefined ? (translate = _, m) : m
m.rotate = _ => _ !== undefined ? (rotate = _, m) : m
m.scale = _ => _ !== undefined ? (scale = _, m) : m
m.focale = _ => _ !== undefined ? (focale = _, m) : m
m.zafin = _ => _ !== undefined ? (zafin = _, m) : m
return m
}
return enty
}
exports.geoNatform = geoNatform
}))
/*******************************************
* @geoUniwen
*
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.geoUniwen = global.geoUniwen || {})))
}(this, function (exports) { "use strict"
let geoUniwen = function geoUniwen(__mapper = {}) {
let g = __mapper("xs").m("geom")
let mwen = __mapper("xs").m("wen")
let cwen = __mapper("xs").c("wen")
let state = {},
scale = [1, 1, 1],
rotate = [0, 0, 0],
translate = [0, 0, 0],
focale = Infinity,
zafin = [0,1]
let wenRotation = function(rot) {
let rox = mwen.matrix(rot !== undefined ? g.to_radians(rot) : cwen.rotInDrag())
return function(x, y, z=0) {
return mwen.rotateMatrix([x, y, z], rox)
}
}
let pointStream = function(x, y, z=0) {
let c = [x, y, z]
c = wenRotation(rotate)(...c)
z = (c[2] * zafin[1]) + zafin[0]
c = mwen.projection([ c[0], c[1], z ] , focale, scale )
c = c.map( (d,i) => d + (translate[i] || 0))
this.stream.point(...c)
}
let proform = function() {
let geoTrans = d3.geoTransform({
point: pointStream})
let geoProj = p => geoTrans(p)
geoProj.stream = s => geoTrans.stream(s)
return geoProj
}
/****************************
* @enty
*/
let enty = function (p={}) {
let m = proform(p)
m.translate = _ => _ !== undefined ? (translate = _, m) : m
m.rotate = _ => _ !== undefined ? (rotate = _, m) : m
m.scale = _ => _ !== undefined ? (scale = _, m) : m
m.focale = _ => _ !== undefined ? (focale = _, m) : m
m.zafin = _ => _ !== undefined ? (zafin = _, m) : m
return m
}
return enty
}
exports.geoUniwen = geoUniwen
}));
/**********************
* @haloCore
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.haloCore = global.haloCore || {})))
}(this, function (exports) { "use strict"
let haloCore = function haloCore(__mapper = {}) {
/**********************
* @enty
*/
let enty = function enty() {}
enty.ween = anima => (anima.inited !== true) ? (anima.inited = true, [anima]) : []
enty.gramn = anima => Array.of(__mapper("xs").b("snap")(anima, anima.tim.unitTime))
return enty
}
exports.haloCore = haloCore
}));
/**********************
* @haloGeojson
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.haloGeojson = global.haloGeojson || {})))
}(this, function (exports) { "use strict"
let haloGeojson = function haloGeojson(__mapper = {}) {
let f = __mapper("props")()
/**********************
* @gramify
*/
let gramify = function (anima, newAnigrams=[]) {
let ani = __mapper("xs").m("anitem")(anima)
let stace = ani.stace(), // stace
proform = ani.proform(), // proform
conform = ani.conform(), // conform
geoform = ani.geoform() // geoform
let json = (typeof geoform === "function") ? geoform(ani.anigram()) : geoform
if (conform) {
let conformer = __mapper("xs").b("gist")(conform)
json = __mapper("xs").b("proj3ct")(json, conformer) // conform
}
if (stace) {
let reformer = __mapper("xs").m("stace").getReform(stace)
json = __mapper("xs").b("proj3ct")(json, reformer) // reform
}
if (proform) {
let proformer = __mapper("xs").b("gist")(proform)
json = __mapper("xs").b("proj3ct")(json, proformer) // proform
}
if (stace) {
let lociformer = __mapper("xs").m("stace").getLociform(ani.anigram())
json = __mapper("xs").b("proj3ct")(json, lociformer) // lociform
}
newAnigrams = __mapper("xs")
.m("geoj").zorder(__mapper("xs")
.m("geoj").featurize(json, ani.anigram()))
return newAnigrams
}
/**********************
* @enty
*/
let enty = function enty() {}
enty.ween = anima => (anima.inited !== true) ? (anima.inited = true, [anima]) : []
enty.gramn = anima => gramify(anima)
enty.gramify = gramify
return enty
}
exports.haloGeojson = haloGeojson
}));
/***********
* @haloImg
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.haloImg = global.haloImg || {})))
}(this, function (exports) { "use strict"
let haloImg = function haloImg(__mapper = {}) {
let f = __mapper("props")()
let geoform = p => ({ // geoform
type: "Feature",
geometry: {
"type": "Point",
"coordinates": [0, 0]
},
properties: {
attr: {
"width": p.payload.img.width,
"height": p.payload.img.height,
["xlink:href"]: p.payload.img.url,
}
}
})
let gramn = function gramn(anima, newAnigrams = []) {
let ani = __mapper("xs").m("anitem")(anima)
let stace = ani.stace() // stace
geoform = ani.geoform() || geoform
let json = (typeof geoform === "function") ? geoform(ani.anigram()) : geoform
if (stace) {
let lociformer = __mapper("xs").m("stace").getLociform(ani.anigram())
json = __mapper("xs").b("proj3ct")(json, lociformer) // lociform
}
let newAnigram = ani.anigram()
newAnigram.sort = "img"
newAnigram.feature = json
newAnigram.feature.id = newAnigram.uid
newAnigrams.push(newAnigram)
return newAnigrams
}
/***************************
* @enty
*/
let enty = function enty() {}
enty.ween = anima => (anima.inited !== true) ? (anima.inited = true, [anima]) : []
enty.gramn = anima => gramn(anima)
return enty
}
exports.haloImg = haloImg
}))
/****************************
* @haloNat
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.haloNat = global.haloNat || {})))
}(this, function (exports) { "use strict"
let haloNat = function haloNat(__mapper = {}) {
let f = __mapper("props")()
let r = __mapper("xs").r("renderer"),
width = r.width(),
height = r.height()
let geoform = p => ({
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": Array.of(__mapper("xs").m("nat")
.multiconform(__mapper("xs").m("nat")
.nform(p.payload.form || p.form)))
},
"id": 0,
"properties": {}
})
/****************************
* @gramn
*/
let gramn = function gramn(anima, newAnigrams = []) {
let ani = __mapper("xs").m("anitem")(anima)
anima.geoform = ani.geoform() || geoform
newAnigrams = __mapper("xs").h("geojson").gramify(anima)
return newAnigrams
}
/****************************
* @enty
*/
let enty = function enty() {}
enty.ween = anima => (anima.inited !== true) ? (anima.inited = true, [anima]) : []
enty.gramn = anima => gramn(anima)
return enty
}
exports.haloNat = haloNat
}))
/***********
* @haloText
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.haloText = global.haloText || {})))
}(this, function (exports) { "use strict"
let haloText = function (__mapper = {}) {
let f = __mapper("props")()
let gramn = function gramn(anima, newAnigrams = []) {
let ani = __mapper("xs").m("anitem")(anima)
let stace = ani.stace(), // stace
geoform = ani.geoform() // geoform
let newAnigram = ani.anigram()
let json = (typeof geoform === "function") ? geoform(ani.anigram()) : geoform
if (stace) {
let lociformer = __mapper("xs").m("stace").getLociform(ani.anigram())
json = __mapper("xs").b("proj3ct")(json, lociformer) // lociform
}
let feature = json
feature.id = newAnigram.uid
newAnigram.sort = "text"
newAnigram.feature = feature
newAnigrams.push(newAnigram)
return newAnigrams
}
/***************************
* @enty
*/
let enty = function () {}
enty.ween = anima => (anima.inited !== true) ? (anima.inited = true, [anima]) : []
enty.gramn = anima => gramn(anima)
return enty
}
exports.haloText = haloText
}))
<!DOCTYPE html>
<meta charset="utf-8">
<title>animas</title>
<head >
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
div#fps,svg { position: fixed; top:0; left:0; color: white; }
</style>
</head>
<body style="cursor:crosshair"></body>
<div id="viewframe" class="viewframe"></div>
<script src='https://d3js.org/d3.v4.min.js'></script>
<script src='https://d3js.org/d3-geo.v1.min.js'></script>
<script src='https://d3js.org/d3-geo-projection.v2.min.js'></script>
<script src='https:////unpkg.com/d3-force-3d@1.0.7/build/d3-force-3d.bundle.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.0/topojson.min.js'></script>
<script src='https:////cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js'></script>
<script src='https:////unpkg.com/three-trackballcontrols-web@0.0.2/dist/three-trackballcontrols.min.js'></script>
<script src="enls.js"></script>
<script src="ents.js"></script>
<script>
let muonAlima = function muonAlima(__mapper) {
__mapper({"xs": xs.xs(__mapper)}) // PROXIES
__mapper("xs").b("init")({svg:1,versor:0,wen:1,webgl:1})
let f = __mapper({"props": bosonProps.bosonProps()}).props()
let g = __mapper("xs").m("geom")
let w = __mapper("xs").m("wen")
/**********************
* @
*/
let r = __mapper("xs").r("renderer"),
width = r.width(),
height = r.height()
let rotInit = [0,45,0],
rotation = [0,0,0],
rotMatrix,
stars = []
let versor = __mapper("xs").b("versor")()
let wen = __mapper("xs").c("wen")({rotInit})
/*******************************************
* @animas
*
*/
let tim = {"td":19800,"t0":0,"t1":1000,"t2":1,"t3":1,}
let aniCube = {
"tim": tim,
"ric": {"gid":"aniCube","cid":"aniCube","fid":"aniCube",},
"halo": "geojson",
"boform":{ "csx":0,"cf":111,"cs":111,"cw":0.1,"co":0.9,"cp":0.9,},
"geoform": (p) => {
let payload = p.payload
let ric = p.ric
let json = {type: "FeatureCollection", features: []}
let vertices = payload.vertices // payload.vertices
let faces = payload.faces // payload.faces
for (let i = 0, l = faces.length; i < l; i++) {
let face = faces[i] // face corners position
let geometry = {type:"Polygon",coordinates:[]}
geometry.coordinates = Array.of(face.corners.map(k=>vertices[k])) // eg [-1, 1, 1]
let feature = {type:"Feature",geometry:{},properties:{}}
feature.properties.ric = ric
feature.properties.ric.cid = "face"
feature.properties.ric.fid = i // face.name
feature.properties.sort = "feature"
feature.geometry = geometry
feature.properties.boform = face.boform
json.features.push(feature)
}
return json
},
"proform": {
"projection": "uniwen",
"translate": [ 280 , 200],
"scale": 60,
"rotate": [ [[[-5,-60]]] ,[[[50,200]]],0],
"focale": 4,
"zafin": [ [[[0,0,1,1,1,0]]], [[[0,0,1,1,1,0]]] ], // [0,1], // [1,0]
"dims": 3,
"control": "wen",
},
"payload": {
vertices: [
[-1, -1, 1], // 0
[ 1, -1, 1], // 1
[ 1, 1, 1], // 2
[-1, 1, 1], // 3
[ 1, -1, -1], // 4
[-1, -1, -1], // 5
[-1, 1, -1], // 6
[ 1, 1, -1], // 7
],
faces: [
{
corners: [0,1,2,3,0],
name: "front",
boform: { cf: 222, cs: 355, co: [[[0.2,0.09,0.9,0.2]]], cp: 1, }},
{
corners: [4,5,6,7,4],
name: "back",
boform: { cf: 888, cs: 455, co: [[[0.2,0.09,0.9,0.2]]], cp: 1, }},
{
corners: [1,4,7,2,1],
name: "right",
boform: { cf: 444, cs: 555, co: [[[0.2,0.09,0.9,0.2]]], cp: 1, }},
{
corners: [5,0,3,6,5],
name: "left",
boform: { cf: 555, cs: 655, co: [[[0.2,0.09,0.9,0.2]]], cp: 1, }},
{
corners: [3,2,7,6,3],
name: "bottom",
boform: { cf: 666, cs: 755, co: [[[0.2,0.09,0.9,0.2]]], cp: 1, }},
{
corners: [5,4,1,0,5],
name: "top",
boform: { cf: 777, cs: 855, co: [[[0.2,0.09,0.9,0.2]]], cp: 1, }}
],
}
}
// ------------------------------- img
let img = {
"tim": tim,
"ric": {"gid":"img","cid":"img","fid":"img",},
"halo":"img",
"boform": { "csx":0,"cf":[[[22,22]]],"cs":22,"cw":[[[0.7,0.7]]],"co":[[[0.7,0.7,]]],"cp":[[[0.5,0.5]]],},
"geoform": p => ({
type: "Feature",
geometry: {
"type": "Point",
"coordinates": [0, 0]
},
properties: {
attr: {
"width": p.payload.img.width,
"height": p.payload.img.height,
["xlink:href"]: p.payload.img.url,
}
}
}),
"stace": {
"x": [[[15, 15]]],
"y": [[[20, 20]]],
},
"payload": {
"img": {
"url":"ZIMG-501.jpg",
"width": [[[60, 60]]],
"height": [[[40 , 40]]],
},
}
}
/*******************************************
* @animas
*
*/
let animas = [
aniCube, // h.geojson g.uniwen
img, // h.img
]
let animaApi = function animaApi() {
__mapper("xs").m("store").apply({"type":"UPDANIMA","caller":"alima","animas":animas})
}
return animaApi
}
let __mapper = bosonMapper.bosonMapper()
__mapper({"muonAlima": muonAlima(__mapper)}).muonAlima(__mapper)
</script>
<body style="cursor:crosshair"></body>
/**
* @license Complex.js v2.0.3 11/02/2016
*
* Copyright (c) 2016, Robert Eisele (robert@xarg.org)
* Dual licensed under the MIT or GPL Version 2 licenses.
**/
/**
*
* This class allows the manipulation of complex numbers.
* You can pass a complex number in different formats. Either as object, double, string or two integer parameters.
*
* Object form
* { re: <real>, im: <imaginary> }
* { arg: <angle>, abs: <radius> }
* { phi: <angle>, r: <radius> }
*
* Array / Vector form
* [ real, imaginary ]
*
* Double form
* 99.3 - Single double value
*
* String form
* '23.1337' - Simple real number
* '15+3i' - a simple complex number
* '3-i' - a simple complex number
*
* Example:
*
* var c = new Complex('99.3+8i');
* c.mul({r: 3, i: 9}).div(4.9).sub(3, 2);
*
*/
(function(root) {
'use strict';
var P = {'re': 0, 'im': 0};
var cosh = function(x) {
return (Math.exp(x) + Math.exp(-x)) * 0.5;
};
var sinh = function(x) {
return (Math.exp(x) - Math.exp(-x)) * 0.5;
};
var hypot = function(x, y) {
var a = Math.abs(x);
var b = Math.abs(y);
if (a < 3000 && b < 3000) {
return Math.sqrt(a * a + b * b);
}
if (a < b) {
a = b;
b = x / y;
} else {
b = y / x;
}
return a * Math.sqrt(1 + b * b);
};
var parser_exit = function() {
throw SyntaxError('Invalid Param');
};
/**
* Calculates log(sqrt(a^2+b^2)) in a way to avoid overflows
*
* @param {number} a
* @param {number} b
* @returns {number}
*/
function logHypot(a, b) {
var _a = Math.abs(a);
var _b = Math.abs(b);
if (a === 0) {
return Math.log(_b);
}
if (b === 0) {
return Math.log(_a);
}
if (_a < 3000 && _b < 3000) {
return Math.log(a * a + b * b) * 0.5;
}
/* I got 4 ideas to compute this property without overflow:
*
* Testing 1000000 times with random samples for a,b ∈ [1, 1000000000] against a big decimal library to get an error estimate
*
* 1. Only eliminate the square root: (OVERALL ERROR: 3.9122483030951116e-11)
Math.log(a * a + b * b) / 2
*
*
* 2. Try to use the non-overflowing pythagoras: (OVERALL ERROR: 8.889760039210159e-10)
var fn = function(a, b) {
a = Math.abs(a);
b = Math.abs(b);
var t = Math.min(a, b);
a = Math.max(a, b);
t = t / a;
return Math.log(a) + Math.log(1 + t * t) / 2;
};
* 3. Abuse the identity cos(atan(y/x) = x / sqrt(x^2+y^2): (OVERALL ERROR: 3.4780178737037204e-10)
Math.log(a / Math.cos(Math.atan2(b, a)))
* 4. Use 3. and apply log rules: (OVERALL ERROR: 1.2014087502620896e-9)
Math.log(a) - Math.log(Math.cos(Math.atan2(b, a)))
*/
return Math.log(a / Math.cos(Math.atan2(b, a)));
}
var parse = function(a, b) {
if (a === undefined || a === null) {
P['re'] =
P['im'] = 0;
} else if (b !== undefined) {
P['re'] = a;
P['im'] = b;
} else switch (typeof a) {
case 'object':
if ('im' in a && 're' in a) {
P['re'] = a['re'];
P['im'] = a['im'];
} else if ('abs' in a && 'arg' in a) {
P['re'] = a['abs'] * Math.cos(a['arg']);
P['im'] = a['abs'] * Math.sin(a['arg']);
} else if ('r' in a && 'phi' in a) {
P['re'] = a['r'] * Math.cos(a['phi']);
P['im'] = a['r'] * Math.sin(a['phi']);
} else if (a.length === 2) { // Quick array check
P['re'] = a[0];
P['im'] = a[1];
} else {
parser_exit();
}
break;
case 'string':
P['im'] = /* void */
P['re'] = 0;
var tokens = a.match(/\d+\.?\d*e[+-]?\d+|\d+\.?\d*|\.\d+|./g);
var plus = 1;
var minus = 0;
if (tokens === null) {
parser_exit();
}
for (var i = 0; i < tokens.length; i++) {
var c = tokens[i];
if (c === ' ' || c === '\t' || c === '\n') {
/* void */
} else if (c === '+') {
plus++;
} else if (c === '-') {
minus++;
} else if (c === 'i' || c === 'I') {
if (plus + minus === 0) {
parser_exit();
}
if (tokens[i + 1] !== ' ' && !isNaN(tokens[i + 1])) {
P['im']+= parseFloat((minus % 2 ? '-' : '') + tokens[i + 1]);
i++;
} else {
P['im']+= parseFloat((minus % 2 ? '-' : '') + '1');
}
plus = minus = 0;
} else {
if (plus + minus === 0 || isNaN(c)) {
parser_exit();
}
if (tokens[i + 1] === 'i' || tokens[i + 1] === 'I') {
P['im']+= parseFloat((minus % 2 ? '-' : '') + c);
i++;
} else {
P['re']+= parseFloat((minus % 2 ? '-' : '') + c);
}
plus = minus = 0;
}
}
// Still something on the stack
if (plus + minus > 0) {
parser_exit();
}
break;
case 'number':
P['im'] = 0;
P['re'] = a;
break;
default:
parser_exit();
}
if (isNaN(P['re']) || isNaN(P['im'])) {
// If a calculation is NaN, we treat it as NaN and don't throw
//parser_exit();
}
};
/**
* @constructor
* @returns {Complex}
*/
function Complex(a, b) {
if (!(this instanceof Complex)) {
return new Complex(a, b);
}
parse(a, b); // mutates P
this['re'] = P['re'];
this['im'] = P['im'];
}
Complex.prototype = {
're': 0,
'im': 0,
/**
* Calculates the sign of a complex number, which is a normalized complex
*
* @returns {Complex}
*/
'sign': function() {
var abs = this['abs']();
return new Complex(
this['re'] / abs,
this['im'] / abs);
},
/**
* Adds two complex numbers
*
* @returns {Complex}
*/
'add': function(a, b) {
parse(a, b); // mutates P
return new Complex(
this['re'] + P['re'],
this['im'] + P['im']);
},
/**
* Subtracts two complex numbers
*
* @returns {Complex}
*/
'sub': function(a, b) {
parse(a, b); // mutates P
return new Complex(
this['re'] - P['re'],
this['im'] - P['im']);
},
/**
* Multiplies two complex numbers
*
* @returns {Complex}
*/
'mul': function(a, b) {
parse(a, b); // mutates P
// Besides the addition/subtraction, this helps having a solution for real Infinity
if (P['im'] === 0 && this['im'] === 0) {
return new Complex(this['re'] * P['re'], 0);
}
return new Complex(
this['re'] * P['re'] - this['im'] * P['im'],
this['re'] * P['im'] + this['im'] * P['re']);
},
/**
* Divides two complex numbers
*
* @returns {Complex}
*/
'div': function(a, b) {
parse(a, b); // mutates P
a = this['re'];
b = this['im'];
var c = P['re'];
var d = P['im'];
var t, x;
if (0 === d) {
if (0 === c) {
// Divisor is zero
return new Complex(
(a !== 0) ? (a / 0) : 0,
(b !== 0) ? (b / 0) : 0);
} else {
// Divisor is real
return new Complex(a / c, b / c);
}
}
if (Math.abs(c) < Math.abs(d)) {
x = c / d;
t = c * x + d;
return new Complex(
(a * x + b) / t,
(b * x - a) / t);
} else {
x = d / c;
t = d * x + c;
return new Complex(
(a + b * x) / t,
(b - a * x) / t);
}
},
/**
* Calculate the power of two complex numbers
*
* @returns {Complex}
*/
'pow': function(a, b) {
parse(a, b); // mutates P
a = this['re'];
b = this['im'];
if (a === 0 && b === 0) {
return Complex['ZERO'];
}
// If the exponent is real
if (P['im'] === 0) {
if (b === 0 && a >= 0) {
return new Complex(Math.pow(a, P['re']), 0);
} else if (a === 0) { // If base is fully imaginary
switch ((P['re'] % 4 + 4) % 4) {
case 0:
return new Complex(Math.pow(b, P['re']), 0);
case 1:
return new Complex(0, Math.pow(b, P['re']));
case 2:
return new Complex(-Math.pow(b, P['re']), 0);
case 3:
return new Complex(0, -Math.pow(b, P['re']));
}
}
}
/* I couldn't find a good formula, so here is a derivation and optimization
*
* z_1^z_2 = (a + bi)^(c + di)
* = exp((c + di) * log(a + bi)
* = pow(a^2 + b^2, (c + di) / 2) * exp(i(c + di)atan2(b, a))
* =>...
* Re = (pow(a^2 + b^2, c / 2) * exp(-d * atan2(b, a))) * cos(d * log(a^2 + b^2) / 2 + c * atan2(b, a))
* Im = (pow(a^2 + b^2, c / 2) * exp(-d * atan2(b, a))) * sin(d * log(a^2 + b^2) / 2 + c * atan2(b, a))
*
* =>...
* Re = exp(c * log(sqrt(a^2 + b^2)) - d * atan2(b, a)) * cos(d * log(sqrt(a^2 + b^2)) + c * atan2(b, a))
* Im = exp(c * log(sqrt(a^2 + b^2)) - d * atan2(b, a)) * sin(d * log(sqrt(a^2 + b^2)) + c * atan2(b, a))
*
* =>
* Re = exp(c * logsq2 - d * arg(z_1)) * cos(d * logsq2 + c * arg(z_1))
* Im = exp(c * logsq2 - d * arg(z_1)) * sin(d * logsq2 + c * arg(z_1))
*
*/
var arg = Math.atan2(b, a);
var loh = logHypot(a, b);
a = Math.exp(P['re'] * loh - P['im'] * arg);
b = P['im'] * loh + P['re'] * arg;
return new Complex(
a * Math.cos(b),
a * Math.sin(b));
},
/**
* Calculate the complex square root
*
* @returns {Complex}
*/
'sqrt': function() {
var a = this['re'];
var b = this['im'];
var r = this['abs']();
var re, im;
if (a >= 0) {
if (b === 0) {
return new Complex(Math.sqrt(a), 0);
}
re = 0.5 * Math.sqrt(2.0 * (r + a));
} else {
re = Math.abs(b) / Math.sqrt(2 * (r - a));
}
if (a <= 0) {
im = 0.5 * Math.sqrt(2.0 * (r - a));
} else {
im = Math.abs(b) / Math.sqrt(2 * (r + a));
}
return new Complex(re, b < 0 ? -im : im);
},
/**
* Calculate the complex exponent
*
* @returns {Complex}
*/
'exp': function() {
var tmp = Math.exp(this['re']);
if (this['im'] === 0) {
//return new Complex(tmp, 0);
}
return new Complex(
tmp * Math.cos(this['im']),
tmp * Math.sin(this['im']));
},
/**
* Calculate the natural log
*
* @returns {Complex}
*/
'log': function() {
var a = this['re'];
var b = this['im'];
if (b === 0 && a > 0) {
//return new Complex(Math.log(a), 0);
}
return new Complex(
logHypot(a, b),
Math.atan2(b, a));
},
/**
* Calculate the magnitude of the complex number
*
* @returns {number}
*/
'abs': function() {
return hypot(this['re'], this['im']);
},
/**
* Calculate the angle of the complex number
*
* @returns {number}
*/
'arg': function() {
return Math.atan2(this['im'], this['re']);
},
/**
* Calculate the sine of the complex number
*
* @returns {Complex}
*/
'sin': function() {
// sin(c) = (e^b - e^(-b)) / (2i)
var a = this['re'];
var b = this['im'];
return new Complex(
Math.sin(a) * cosh(b),
Math.cos(a) * sinh(b));
},
/**
* Calculate the cosine
*
* @returns {Complex}
*/
'cos': function() {
// cos(z) = (e^b + e^(-b)) / 2
var a = this['re'];
var b = this['im'];
return new Complex(
Math.cos(a) * cosh(b),
-Math.sin(a) * sinh(b));
},
/**
* Calculate the tangent
*
* @returns {Complex}
*/
'tan': function() {
// tan(c) = (e^(ci) - e^(-ci)) / (i(e^(ci) + e^(-ci)))
var a = 2 * this['re'];
var b = 2 * this['im'];
var d = Math.cos(a) + cosh(b);
return new Complex(
Math.sin(a) / d,
sinh(b) / d);
},
/**
* Calculate the cotangent
*
* @returns {Complex}
*/
'cot': function() {
// cot(c) = i(e^(ci) + e^(-ci)) / (e^(ci) - e^(-ci))
var a = 2 * this['re'];
var b = 2 * this['im'];
var d = Math.cos(a) - cosh(b);
return new Complex(
-Math.sin(a) / d,
sinh(b) / d);
},
/**
* Calculate the secant
*
* @returns {Complex}
*/
'sec': function() {
// sec(c) = 2 / (e^(ci) + e^(-ci))
var a = this['re'];
var b = this['im'];
var d = 0.5 * cosh(2 * b) + 0.5 * Math.cos(2 * a);
return new Complex(
Math.cos(a) * cosh(b) / d,
Math.sin(a) * sinh(b) / d);
},
/**
* Calculate the cosecans
*
* @returns {Complex}
*/
'csc': function() {
// csc(c) = 2i / (e^(ci) - e^(-ci))
var a = this['re'];
var b = this['im'];
var d = 0.5 * cosh(2 * b) - 0.5 * Math.cos(2 * a);
return new Complex(
Math.sin(a) * cosh(b) / d,
-Math.cos(a) * sinh(b) / d);
},
/**
* Calculate the complex arcus sinus
*
* @returns {Complex}
*/
'asin': function() {
// asin(c) = -i * log(ci + sqrt(1 - c^2))
var a = this['re'];
var b = this['im'];
var t1 = new Complex(
b * b - a * a + 1,
-2 * a * b)['sqrt']();
var t2 = new Complex(
t1['re'] - b,
t1['im'] + a)['log']();
return new Complex(t2['im'], -t2['re']);
},
/**
* Calculate the complex arcus cosinus
*
* @returns {Complex}
*/
'acos': function() {
// acos(c) = i * log(c - i * sqrt(1 - c^2))
var a = this['re'];
var b = this['im'];
var t1 = new Complex(
b * b - a * a + 1,
-2 * a * b)['sqrt']();
var t2 = new Complex(
t1['re'] - b,
t1['im'] + a)['log']();
return new Complex(Math.PI / 2 - t2['im'], t2['re']);
},
/**
* Calculate the complex arcus tangent
*
* @returns {Complex}
*/
'atan': function() {
// atan(c) = i / 2 log((i + x) / (i - x))
var a = this['re'];
var b = this['im'];
if (a === 0) {
if (b === 1) {
return new Complex(0, Infinity);
}
if (b === -1) {
return new Complex(0, -Infinity);
}
}
var d = a * a + (1.0 - b) * (1.0 - b);
var t1 = new Complex(
(1 - b * b - a * a) / d,
-2 * a / d).log();
return new Complex(-0.5 * t1['im'], 0.5 * t1['re']);
},
/**
* Calculate the complex arcus cotangent
*
* @returns {Complex}
*/
'acot': function() {
// acot(c) = i / 2 log((c - i) / (c + i))
var a = this['re'];
var b = this['im'];
if (b === 0) {
return new Complex(Math.atan2(1, a), 0);
}
var d = a * a + b * b;
return (d !== 0)
? new Complex(
a / d,
-b / d).atan()
: new Complex(
(a !== 0) ? a / 0 : 0,
(b !== 0) ?-b / 0 : 0).atan();
},
/**
* Calculate the complex arcus secant
*
* @returns {Complex}
*/
'asec': function() {
// asec(c) = -i * log(1 / c + sqrt(1 - i / c^2))
var a = this['re'];
var b = this['im'];
if (a === 0 && b === 0) {
return new Complex(0, Infinity);
}
var d = a * a + b * b;
return (d !== 0)
? new Complex(
a / d,
-b / d).acos()
: new Complex(
(a !== 0) ? a / 0 : 0,
(b !== 0) ?-b / 0 : 0).acos();
},
/**
* Calculate the complex arcus cosecans
*
* @returns {Complex}
*/
'acsc': function() {
// acsc(c) = -i * log(i / c + sqrt(1 - 1 / c^2))
var a = this['re'];
var b = this['im'];
if (a === 0 && b === 0) {
return new Complex(Math.PI / 2, Infinity);
}
var d = a * a + b * b;
return (d !== 0)
? new Complex(
a / d,
-b / d).asin()
: new Complex(
(a !== 0) ? a / 0 : 0,
(b !== 0) ?-b / 0 : 0).asin();
},
/**
* Calculate the complex sinh
*
* @returns {Complex}
*/
'sinh': function() {
// sinh(c) = (e^c - e^-c) / 2
var a = this['re'];
var b = this['im'];
return new Complex(
sinh(a) * Math.cos(b),
cosh(a) * Math.sin(b));
},
/**
* Calculate the complex cosh
*
* @returns {Complex}
*/
'cosh': function() {
// cosh(c) = (e^c + e^-c) / 2
var a = this['re'];
var b = this['im'];
return new Complex(
cosh(a) * Math.cos(b),
sinh(a) * Math.sin(b));
},
/**
* Calculate the complex tanh
*
* @returns {Complex}
*/
'tanh': function() {
// tanh(c) = (e^c - e^-c) / (e^c + e^-c)
var a = 2 * this['re'];
var b = 2 * this['im'];
var d = cosh(a) + Math.cos(b);
return new Complex(
sinh(a) / d,
Math.sin(b) / d);
},
/**
* Calculate the complex coth
*
* @returns {Complex}
*/
'coth': function() {
// coth(c) = (e^c + e^-c) / (e^c - e^-c)
var a = 2 * this['re'];
var b = 2 * this['im'];
var d = cosh(a) - Math.cos(b);
return new Complex(
sinh(a) / d,
-Math.sin(b) / d);
},
/**
* Calculate the complex coth
*
* @returns {Complex}
*/
'csch': function() {
// csch(c) = 2 / (e^c - e^-c)
var a = this['re'];
var b = this['im'];
var d = Math.cos(2 * b) - cosh(2 * a);
return new Complex(
-2 * sinh(a) * Math.cos(b) / d,
2 * cosh(a) * Math.sin(b) / d);
},
/**
* Calculate the complex sech
*
* @returns {Complex}
*/
'sech': function() {
// sech(c) = 2 / (e^c + e^-c)
var a = this['re'];
var b = this['im'];
var d = Math.cos(2 * b) + cosh(2 * a);
return new Complex(
2 * cosh(a) * Math.cos(b) / d,
-2 * sinh(a) * Math.sin(b) / d);
},
/**
* Calculate the complex asinh
*
* @returns {Complex}
*/
'asinh': function() {
// asinh(c) = log(c + sqrt(c^2 + 1))
var tmp = this['im'];
this['im'] = -this['re'];
this['re'] = tmp;
var res = this['asin']();
this['re'] = -this['im'];
this['im'] = tmp;
tmp = res['re'];
res['re'] = -res['im'];
res['im'] = tmp;
return res;
},
/**
* Calculate the complex asinh
*
* @returns {Complex}
*/
'acosh': function() {
// acosh(c) = log(c + sqrt(c^2 - 1))
var tmp;
var res = this['acos']();
if (res['im'] <= 0) {
tmp = res['re'];
res['re'] = -res['im'];
res['im'] = tmp;
} else {
tmp = res['im'];
res['im'] = -res['re'];
res['re'] = tmp;
}
return res;
},
/**
* Calculate the complex atanh
*
* @returns {Complex}
*/
'atanh': function() {
// atanh(c) = log((1+c) / (1-c)) / 2
var a = this['re'];
var b = this['im'];
var noIM = a > 1 && b === 0;
var oneMinus = 1 - a;
var onePlus = 1 + a;
var d = oneMinus * oneMinus + b * b;
var x = (d !== 0)
? new Complex(
(onePlus * oneMinus - b * b) / d,
(b * oneMinus + onePlus * b) / d)
: new Complex(
(a !== -1) ? (a / 0) : 0,
(b !== 0) ? (b / 0) : 0);
var temp = x['re'];
x['re'] = logHypot(x['re'], x['im']) / 2;
x['im'] = Math.atan2(x['im'], temp) / 2;
if (noIM) {
x['im'] = -x['im'];
}
return x;
},
/**
* Calculate the complex acoth
*
* @returns {Complex}
*/
'acoth': function() {
// acoth(c) = log((c+1) / (c-1)) / 2
var a = this['re'];
var b = this['im'];
if (a === 0 && b === 0) {
return new Complex(0, Math.PI / 2);
}
var d = a * a + b * b;
return (d !== 0)
? new Complex(
a / d,
-b / d).atanh()
: new Complex(
(a !== 0) ? a / 0 : 0,
(b !== 0) ?-b / 0 : 0).atanh();
},
/**
* Calculate the complex acsch
*
* @returns {Complex}
*/
'acsch': function() {
// acsch(c) = log((1+sqrt(1+c^2))/c)
var a = this['re'];
var b = this['im'];
if (b === 0) {
return new Complex(
(a !== 0)
? Math.log(a + Math.sqrt(a * a + 1))
: Infinity, 0);
}
var d = a * a + b * b;
return (d !== 0)
? new Complex(
a / d,
-b / d).asinh()
: new Complex(
(a !== 0) ? a / 0 : 0,
(b !== 0) ?-b / 0 : 0).asinh();
},
/**
* Calculate the complex asech
*
* @returns {Complex}
*/
'asech': function() {
// asech(c) = log((1+sqrt(1-c^2))/c)
var a = this['re'];
var b = this['im'];
if (a === 0 && b === 0) {
return new Complex(Infinity, 0);
}
var d = a * a + b * b;
return (d !== 0)
? new Complex(
a / d,
-b / d).acosh()
: new Complex(
(a !== 0) ? a / 0 : 0,
(b !== 0) ?-b / 0 : 0).acosh();
},
/**
* Calculate the complex inverse 1/z
*
* @returns {Complex}
*/
'inverse': function() {
var a = this['re'];
var b = this['im'];
var d = a * a + b * b;
return new Complex(
a !== 0 ? a / d : 0,
b !== 0 ?-b / d : 0);
},
/**
* Returns the complex conjugate
*
* @returns {Complex}
*/
'conjugate': function() {
return new Complex(this['re'], -this['im']);
},
/**
* Gets the negated complex number
*
* @returns {Complex}
*/
'neg': function() {
return new Complex(-this['re'], -this['im']);
},
/**
* Ceils the actual complex number
*
* @returns {Complex}
*/
'ceil': function(places) {
places = Math.pow(10, places || 0);
return new Complex(
Math.ceil(this['re'] * places) / places,
Math.ceil(this['im'] * places) / places);
},
/**
* Floors the actual complex number
*
* @returns {Complex}
*/
'floor': function(places) {
places = Math.pow(10, places || 0);
return new Complex(
Math.floor(this['re'] * places) / places,
Math.floor(this['im'] * places) / places);
},
/**
* Ceils the actual complex number
*
* @returns {Complex}
*/
'round': function(places) {
places = Math.pow(10, places || 0);
return new Complex(
Math.round(this['re'] * places) / places,
Math.round(this['im'] * places) / places);
},
/**
* Compares two complex numbers
*
* @returns {boolean}
*/
'equals': function(a, b) {
parse(a, b); // mutates P
return Math.abs(P['re'] - this['re']) <= Complex['EPSILON'] &&
Math.abs(P['im'] - this['im']) <= Complex['EPSILON'];
},
/**
* Clones the actual object
*
* @returns {Complex}
*/
'clone': function() {
return new Complex(this['re'], this['im']);
},
/**
* Gets a string of the actual complex number
*
* @returns {string}
*/
'toString': function() {
var a = this['re'];
var b = this['im'];
var ret = '';
if (isNaN(a) || isNaN(b)) {
return 'NaN';
}
if (a !== 0) {
ret+= a;
}
if (b !== 0) {
if (a !== 0) {
ret+= b < 0 ? ' - ' : ' + ';
} else if (b < 0) {
ret+= '-';
}
b = Math.abs(b);
if (1 !== b) {
ret+= b;
}
ret+= 'i';
}
if (!ret)
return '0';
return ret;
},
/**
* Returns the actual number as a vector
*
* @returns {Array}
*/
'toVector': function() {
return [this['re'], this['im']];
},
/**
* Returns the actual real value of the current object
*
* @returns {number|null}
*/
'valueOf': function() {
if (this['im'] === 0) {
return this['re'];
}
return null;
},
/**
* Checks if the given complex number is not a number
*
* @returns {boolean}
*/
'isNaN': function() {
return isNaN(this['re']) || isNaN(this['im']);
},
/**
* Checks if the given complex number is finite
*
* @returns {boolean}
*/
'isFinite': function() {
return isFinite(this['re']) && isFinite(this['im']);
}
};
Complex['ZERO'] = new Complex(0, 0);
Complex['ONE'] = new Complex(1, 0);
Complex['I'] = new Complex(0, 1);
Complex['PI'] = new Complex(Math.PI, 0);
Complex['E'] = new Complex(Math.E, 0);
Complex['EPSILON'] = 1e-16;
if (typeof define === 'function' && define['amd']) {
define([], function() {
return Complex;
});
} else if (typeof exports === 'object') {
module['exports'] = Complex;
} else {
root['Complex'] = Complex;
}
})(this);
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define([], factory);
else if(typeof exports === 'object')
exports["dat"] = factory();
else
root["dat"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId])
/******/ return installedModules[moduleId].exports;
/******/
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ exports: {},
/******/ id: moduleId,
/******/ loaded: false
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.__esModule = true;
var _index = __webpack_require__(1);
var _index2 = _interopRequireDefault(_index);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = _index2.default; /**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
module.exports = exports['default'];
/***/ },
/* 1 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.__esModule = true;
var _Color = __webpack_require__(2);
var _Color2 = _interopRequireDefault(_Color);
var _math = __webpack_require__(6);
var _math2 = _interopRequireDefault(_math);
var _interpret = __webpack_require__(3);
var _interpret2 = _interopRequireDefault(_interpret);
var _Controller = __webpack_require__(7);
var _Controller2 = _interopRequireDefault(_Controller);
var _BooleanController = __webpack_require__(8);
var _BooleanController2 = _interopRequireDefault(_BooleanController);
var _OptionController = __webpack_require__(10);
var _OptionController2 = _interopRequireDefault(_OptionController);
var _StringController = __webpack_require__(11);
var _StringController2 = _interopRequireDefault(_StringController);
var _NumberController = __webpack_require__(12);
var _NumberController2 = _interopRequireDefault(_NumberController);
var _NumberControllerBox = __webpack_require__(13);
var _NumberControllerBox2 = _interopRequireDefault(_NumberControllerBox);
var _NumberControllerSlider = __webpack_require__(14);
var _NumberControllerSlider2 = _interopRequireDefault(_NumberControllerSlider);
var _FunctionController = __webpack_require__(15);
var _FunctionController2 = _interopRequireDefault(_FunctionController);
var _ColorController = __webpack_require__(16);
var _ColorController2 = _interopRequireDefault(_ColorController);
var _dom = __webpack_require__(9);
var _dom2 = _interopRequireDefault(_dom);
var _GUI = __webpack_require__(17);
var _GUI2 = _interopRequireDefault(_GUI);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
exports.default = {
color: {
Color: _Color2.default,
math: _math2.default,
interpret: _interpret2.default
},
controllers: {
Controller: _Controller2.default,
BooleanController: _BooleanController2.default,
OptionController: _OptionController2.default,
StringController: _StringController2.default,
NumberController: _NumberController2.default,
NumberControllerBox: _NumberControllerBox2.default,
NumberControllerSlider: _NumberControllerSlider2.default,
FunctionController: _FunctionController2.default,
ColorController: _ColorController2.default
},
dom: {
dom: _dom2.default
},
gui: {
GUI: _GUI2.default
},
GUI: _GUI2.default
};
module.exports = exports['default'];
/***/ },
/* 2 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.__esModule = true;
var _interpret = __webpack_require__(3);
var _interpret2 = _interopRequireDefault(_interpret);
var _math = __webpack_require__(6);
var _math2 = _interopRequireDefault(_math);
var _toString = __webpack_require__(4);
var _toString2 = _interopRequireDefault(_toString);
var _common = __webpack_require__(5);
var _common2 = _interopRequireDefault(_common);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
var Color = function () {
function Color() {
_classCallCheck(this, Color);
this.__state = _interpret2.default.apply(this, arguments);
if (this.__state === false) {
throw new Error('Failed to interpret color arguments');
}
this.__state.a = this.__state.a || 1;
}
Color.prototype.toString = function toString() {
return (0, _toString2.default)(this);
};
Color.prototype.toHexString = function toHexString() {
return (0, _toString2.default)(this, true);
};
Color.prototype.toOriginal = function toOriginal() {
return this.__state.conversion.write(this);
};
return Color;
}();
function defineRGBComponent(target, component, componentHexIndex) {
Object.defineProperty(target, component, {
get: function get() {
if (this.__state.space === 'RGB') {
return this.__state[component];
}
Color.recalculateRGB(this, component, componentHexIndex);
return this.__state[component];
},
set: function set(v) {
if (this.__state.space !== 'RGB') {
Color.recalculateRGB(this, component, componentHexIndex);
this.__state.space = 'RGB';
}
this.__state[component] = v;
}
});
}
function defineHSVComponent(target, component) {
Object.defineProperty(target, component, {
get: function get() {
if (this.__state.space === 'HSV') {
return this.__state[component];
}
Color.recalculateHSV(this);
return this.__state[component];
},
set: function set(v) {
if (this.__state.space !== 'HSV') {
Color.recalculateHSV(this);
this.__state.space = 'HSV';
}
this.__state[component] = v;
}
});
}
Color.recalculateRGB = function (color, component, componentHexIndex) {
if (color.__state.space === 'HEX') {
color.__state[component] = _math2.default.component_from_hex(color.__state.hex, componentHexIndex);
} else if (color.__state.space === 'HSV') {
_common2.default.extend(color.__state, _math2.default.hsv_to_rgb(color.__state.h, color.__state.s, color.__state.v));
} else {
throw new Error('Corrupted color state');
}
};
Color.recalculateHSV = function (color) {
var result = _math2.default.rgb_to_hsv(color.r, color.g, color.b);
_common2.default.extend(color.__state, {
s: result.s,
v: result.v
});
if (!_common2.default.isNaN(result.h)) {
color.__state.h = result.h;
} else if (_common2.default.isUndefined(color.__state.h)) {
color.__state.h = 0;
}
};
Color.COMPONENTS = ['r', 'g', 'b', 'h', 's', 'v', 'hex', 'a'];
defineRGBComponent(Color.prototype, 'r', 2);
defineRGBComponent(Color.prototype, 'g', 1);
defineRGBComponent(Color.prototype, 'b', 0);
defineHSVComponent(Color.prototype, 'h');
defineHSVComponent(Color.prototype, 's');
defineHSVComponent(Color.prototype, 'v');
Object.defineProperty(Color.prototype, 'a', {
get: function get() {
return this.__state.a;
},
set: function set(v) {
this.__state.a = v;
}
});
Object.defineProperty(Color.prototype, 'hex', {
get: function get() {
if (!this.__state.space !== 'HEX') {
this.__state.hex = _math2.default.rgb_to_hex(this.r, this.g, this.b);
}
return this.__state.hex;
},
set: function set(v) {
this.__state.space = 'HEX';
this.__state.hex = v;
}
});
exports.default = Color;
module.exports = exports['default'];
/***/ },
/* 3 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.__esModule = true;
var _toString = __webpack_require__(4);
var _toString2 = _interopRequireDefault(_toString);
var _common = __webpack_require__(5);
var _common2 = _interopRequireDefault(_common);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
var INTERPRETATIONS = [
// Strings
{
litmus: _common2.default.isString,
conversions: {
THREE_CHAR_HEX: {
read: function read(original) {
var test = original.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);
if (test === null) {
return false;
}
return {
space: 'HEX',
hex: parseInt('0x' + test[1].toString() + test[1].toString() + test[2].toString() + test[2].toString() + test[3].toString() + test[3].toString(), 0)
};
},
write: _toString2.default
},
SIX_CHAR_HEX: {
read: function read(original) {
var test = original.match(/^#([A-F0-9]{6})$/i);
if (test === null) {
return false;
}
return {
space: 'HEX',
hex: parseInt('0x' + test[1].toString(), 0)
};
},
write: _toString2.default
},
CSS_RGB: {
read: function read(original) {
var test = original.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/);
if (test === null) {
return false;
}
return {
space: 'RGB',
r: parseFloat(test[1]),
g: parseFloat(test[2]),
b: parseFloat(test[3])
};
},
write: _toString2.default
},
CSS_RGBA: {
read: function read(original) {
var test = original.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/);
if (test === null) {
return false;
}
return {
space: 'RGB',
r: parseFloat(test[1]),
g: parseFloat(test[2]),
b: parseFloat(test[3]),
a: parseFloat(test[4])
};
},
write: _toString2.default
}
}
},
// Numbers
{
litmus: _common2.default.isNumber,
conversions: {
HEX: {
read: function read(original) {
return {
space: 'HEX',
hex: original,
conversionName: 'HEX'
};
},
write: function write(color) {
return color.hex;
}
}
}
},
// Arrays
{
litmus: _common2.default.isArray,
conversions: {
RGB_ARRAY: {
read: function read(original) {
if (original.length !== 3) {
return false;
}
return {
space: 'RGB',
r: original[0],
g: original[1],
b: original[2]
};
},
write: function write(color) {
return [color.r, color.g, color.b];
}
},
RGBA_ARRAY: {
read: function read(original) {
if (original.length !== 4) return false;
return {
space: 'RGB',
r: original[0],
g: original[1],
b: original[2],
a: original[3]
};
},
write: function write(color) {
return [color.r, color.g, color.b, color.a];
}
}
}
},
// Objects
{
litmus: _common2.default.isObject,
conversions: {
RGBA_OBJ: {
read: function read(original) {
if (_common2.default.isNumber(original.r) && _common2.default.isNumber(original.g) && _common2.default.isNumber(original.b) && _common2.default.isNumber(original.a)) {
return {
space: 'RGB',
r: original.r,
g: original.g,
b: original.b,
a: original.a
};
}
return false;
},
write: function write(color) {
return {
r: color.r,
g: color.g,
b: color.b,
a: color.a
};
}
},
RGB_OBJ: {
read: function read(original) {
if (_common2.default.isNumber(original.r) && _common2.default.isNumber(original.g) && _common2.default.isNumber(original.b)) {
return {
space: 'RGB',
r: original.r,
g: original.g,
b: original.b
};
}
return false;
},
write: function write(color) {
return {
r: color.r,
g: color.g,
b: color.b
};
}
},
HSVA_OBJ: {
read: function read(original) {
if (_common2.default.isNumber(original.h) && _common2.default.isNumber(original.s) && _common2.default.isNumber(original.v) && _common2.default.isNumber(original.a)) {
return {
space: 'HSV',
h: original.h,
s: original.s,
v: original.v,
a: original.a
};
}
return false;
},
write: function write(color) {
return {
h: color.h,
s: color.s,
v: color.v,
a: color.a
};
}
},
HSV_OBJ: {
read: function read(original) {
if (_common2.default.isNumber(original.h) && _common2.default.isNumber(original.s) && _common2.default.isNumber(original.v)) {
return {
space: 'HSV',
h: original.h,
s: original.s,
v: original.v
};
}
return false;
},
write: function write(color) {
return {
h: color.h,
s: color.s,
v: color.v
};
}
}
}
}];
var result = void 0;
var toReturn = void 0;
var interpret = function interpret() {
toReturn = false;
var original = arguments.length > 1 ? _common2.default.toArray(arguments) : arguments[0];
_common2.default.each(INTERPRETATIONS, function (family) {
if (family.litmus(original)) {
_common2.default.each(family.conversions, function (conversion, conversionName) {
result = conversion.read(original);
if (toReturn === false && result !== false) {
toReturn = result;
result.conversionName = conversionName;
result.conversion = conversion;
return _common2.default.BREAK;
}
});
return _common2.default.BREAK;
}
});
return toReturn;
};
exports.default = interpret;
module.exports = exports['default'];
/***/ },
/* 4 */
/***/ function(module, exports) {
'use strict';
exports.__esModule = true;
exports.default = function (color, forceCSSHex) {
var colorFormat = color.__state.conversionName.toString();
var r = Math.round(color.r);
var g = Math.round(color.g);
var b = Math.round(color.b);
var a = color.a;
var h = Math.round(color.h);
var s = color.s.toFixed(1);
var v = color.v.toFixed(1);
if (forceCSSHex || colorFormat === 'THREE_CHAR_HEX' || colorFormat === 'SIX_CHAR_HEX') {
var str = color.hex.toString(16);
while (str.length < 6) {
str = '0' + str;
}
return '#' + str;
} else if (colorFormat === 'CSS_RGB') {
return 'rgb(' + r + ',' + g + ',' + b + ')';
} else if (colorFormat === 'CSS_RGBA') {
return 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';
} else if (colorFormat === 'HEX') {
return '0x' + color.hex.toString(16);
} else if (colorFormat === 'RGB_ARRAY') {
return '[' + r + ',' + g + ',' + b + ']';
} else if (colorFormat === 'RGBA_ARRAY') {
return '[' + r + ',' + g + ',' + b + ',' + a + ']';
} else if (colorFormat === 'RGB_OBJ') {
return '{r:' + r + ',g:' + g + ',b:' + b + '}';
} else if (colorFormat === 'RGBA_OBJ') {
return '{r:' + r + ',g:' + g + ',b:' + b + ',a:' + a + '}';
} else if (colorFormat === 'HSV_OBJ') {
return '{h:' + h + ',s:' + s + ',v:' + v + '}';
} else if (colorFormat === 'HSVA_OBJ') {
return '{h:' + h + ',s:' + s + ',v:' + v + ',a:' + a + '}';
}
return 'unknown format';
};
module.exports = exports['default']; /**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
/***/ },
/* 5 */
/***/ function(module, exports) {
'use strict';
exports.__esModule = true;
/**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
var ARR_EACH = Array.prototype.forEach;
var ARR_SLICE = Array.prototype.slice;
/**
* Band-aid methods for things that should be a lot easier in JavaScript.
* Implementation and structure inspired by underscore.js
* http://documentcloud.github.com/underscore/
*/
var Common = {
BREAK: {},
extend: function extend(target) {
this.each(ARR_SLICE.call(arguments, 1), function (obj) {
var keys = this.isObject(obj) ? Object.keys(obj) : [];
keys.forEach(function (key) {
if (!this.isUndefined(obj[key])) {
target[key] = obj[key];
}
}.bind(this));
}, this);
return target;
},
defaults: function defaults(target) {
this.each(ARR_SLICE.call(arguments, 1), function (obj) {
var keys = this.isObject(obj) ? Object.keys(obj) : [];
keys.forEach(function (key) {
if (this.isUndefined(target[key])) {
target[key] = obj[key];
}
}.bind(this));
}, this);
return target;
},
compose: function compose() {
var toCall = ARR_SLICE.call(arguments);
return function () {
var args = ARR_SLICE.call(arguments);
for (var i = toCall.length - 1; i >= 0; i--) {
args = [toCall[i].apply(this, args)];
}
return args[0];
};
},
each: function each(obj, itr, scope) {
if (!obj) {
return;
}
if (ARR_EACH && obj.forEach && obj.forEach === ARR_EACH) {
obj.forEach(itr, scope);
} else if (obj.length === obj.length + 0) {
// Is number but not NaN
var key = void 0;
var l = void 0;
for (key = 0, l = obj.length; key < l; key++) {
if (key in obj && itr.call(scope, obj[key], key) === this.BREAK) {
return;
}
}
} else {
for (var _key in obj) {
if (itr.call(scope, obj[_key], _key) === this.BREAK) {
return;
}
}
}
},
defer: function defer(fnc) {
setTimeout(fnc, 0);
},
// if the function is called repeatedly, wait until threshold passes until we execute the function
debounce: function debounce(func, threshold, callImmediately) {
var timeout = void 0;
return function () {
var obj = this;
var args = arguments;
function delayed() {
timeout = null;
if (!callImmediately) func.apply(obj, args);
}
var callNow = callImmediately || !timeout;
clearTimeout(timeout);
timeout = setTimeout(delayed, threshold);
if (callNow) {
func.apply(obj, args);
}
};
},
toArray: function toArray(obj) {
if (obj.toArray) return obj.toArray();
return ARR_SLICE.call(obj);
},
isUndefined: function isUndefined(obj) {
return obj === undefined;
},
isNull: function isNull(obj) {
return obj === null;
},
isNaN: function (_isNaN) {
function isNaN(_x) {
return _isNaN.apply(this, arguments);
}
isNaN.toString = function () {
return _isNaN.toString();
};
return isNaN;
}(function (obj) {
return isNaN(obj);
}),
isArray: Array.isArray || function (obj) {
return obj.constructor === Array;
},
isObject: function isObject(obj) {
return obj === Object(obj);
},
isNumber: function isNumber(obj) {
return obj === obj + 0;
},
isString: function isString(obj) {
return obj === obj + '';
},
isBoolean: function isBoolean(obj) {
return obj === false || obj === true;
},
isFunction: function isFunction(obj) {
return Object.prototype.toString.call(obj) === '[object Function]';
}
};
exports.default = Common;
module.exports = exports['default'];
/***/ },
/* 6 */
/***/ function(module, exports) {
"use strict";
exports.__esModule = true;
/**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
var tmpComponent = void 0;
var ColorMath = {
hsv_to_rgb: function hsv_to_rgb(h, s, v) {
var hi = Math.floor(h / 60) % 6;
var f = h / 60 - Math.floor(h / 60);
var p = v * (1.0 - s);
var q = v * (1.0 - f * s);
var t = v * (1.0 - (1.0 - f) * s);
var c = [[v, t, p], [q, v, p], [p, v, t], [p, q, v], [t, p, v], [v, p, q]][hi];
return {
r: c[0] * 255,
g: c[1] * 255,
b: c[2] * 255
};
},
rgb_to_hsv: function rgb_to_hsv(r, g, b) {
var min = Math.min(r, g, b);
var max = Math.max(r, g, b);
var delta = max - min;
var h = void 0;
var s = void 0;
if (max !== 0) {
s = delta / max;
} else {
return {
h: NaN,
s: 0,
v: 0
};
}
if (r === max) {
h = (g - b) / delta;
} else if (g === max) {
h = 2 + (b - r) / delta;
} else {
h = 4 + (r - g) / delta;
}
h /= 6;
if (h < 0) {
h += 1;
}
return {
h: h * 360,
s: s,
v: max / 255
};
},
rgb_to_hex: function rgb_to_hex(r, g, b) {
var hex = this.hex_with_component(0, 2, r);
hex = this.hex_with_component(hex, 1, g);
hex = this.hex_with_component(hex, 0, b);
return hex;
},
component_from_hex: function component_from_hex(hex, componentIndex) {
return hex >> componentIndex * 8 & 0xFF;
},
hex_with_component: function hex_with_component(hex, componentIndex, value) {
return value << (tmpComponent = componentIndex * 8) | hex & ~(0xFF << tmpComponent);
}
};
exports.default = ColorMath;
module.exports = exports["default"];
/***/ },
/* 7 */
/***/ function(module, exports) {
'use strict';
exports.__esModule = true;
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
/**
* @class An "abstract" class that represents a given property of an object.
*
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
*
* @member dat.controllers
*/
var Controller = function () {
function Controller(object, property) {
_classCallCheck(this, Controller);
this.initialValue = object[property];
/**
* Those who extend this class will put their DOM elements in here.
* @type {DOMElement}
*/
this.domElement = document.createElement('div');
/**
* The object to manipulate
* @type {Object}
*/
this.object = object;
/**
* The name of the property to manipulate
* @type {String}
*/
this.property = property;
/**
* The function to be called on change.
* @type {Function}
* @ignore
*/
this.__onChange = undefined;
/**
* The function to be called on finishing change.
* @type {Function}
* @ignore
*/
this.__onFinishChange = undefined;
}
/**
* Specify that a function fire every time someone changes the value with
* this Controller.
*
* @param {Function} fnc This function will be called whenever the value
* is modified via this Controller.
* @returns {Controller} this
*/
Controller.prototype.onChange = function onChange(fnc) {
this.__onChange = fnc;
return this;
};
/**
* Specify that a function fire every time someone "finishes" changing
* the value wih this Controller. Useful for values that change
* incrementally like numbers or strings.
*
* @param {Function} fnc This function will be called whenever
* someone "finishes" changing the value via this Controller.
* @returns {Controller} this
*/
Controller.prototype.onFinishChange = function onFinishChange(fnc) {
this.__onFinishChange = fnc;
return this;
};
/**
* Change the value of <code>object[property]</code>
*
* @param {Object} newValue The new value of <code>object[property]</code>
*/
Controller.prototype.setValue = function setValue(newValue) {
this.object[this.property] = newValue;
if (this.__onChange) {
this.__onChange.call(this, newValue);
}
this.updateDisplay();
return this;
};
/**
* Gets the value of <code>object[property]</code>
*
* @returns {Object} The current value of <code>object[property]</code>
*/
Controller.prototype.getValue = function getValue() {
return this.object[this.property];
};
/**
* Refreshes the visual display of a Controller in order to keep sync
* with the object's current value.
* @returns {Controller} this
*/
Controller.prototype.updateDisplay = function updateDisplay() {
return this;
};
/**
* @returns {Boolean} true if the value has deviated from initialValue
*/
Controller.prototype.isModified = function isModified() {
return this.initialValue !== this.getValue();
};
return Controller;
}();
exports.default = Controller;
module.exports = exports['default'];
/***/ },
/* 8 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.__esModule = true;
var _Controller2 = __webpack_require__(7);
var _Controller3 = _interopRequireDefault(_Controller2);
var _dom = __webpack_require__(9);
var _dom2 = _interopRequireDefault(_dom);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
/**
* @class Provides a checkbox input to alter the boolean property of an object.
* @extends dat.controllers.Controller
*
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
*
* @member dat.controllers
*/
var BooleanController = function (_Controller) {
_inherits(BooleanController, _Controller);
function BooleanController(object, property) {
_classCallCheck(this, BooleanController);
var _this2 = _possibleConstructorReturn(this, _Controller.call(this, object, property));
var _this = _this2;
_this2.__prev = _this2.getValue();
_this2.__checkbox = document.createElement('input');
_this2.__checkbox.setAttribute('type', 'checkbox');
function onChange() {
_this.setValue(!_this.__prev);
}
_dom2.default.bind(_this2.__checkbox, 'change', onChange, false);
_this2.domElement.appendChild(_this2.__checkbox);
// Match original value
_this2.updateDisplay();
return _this2;
}
BooleanController.prototype.setValue = function setValue(v) {
var toReturn = _Controller.prototype.setValue.call(this, v);
if (this.__onFinishChange) {
this.__onFinishChange.call(this, this.getValue());
}
this.__prev = this.getValue();
return toReturn;
};
BooleanController.prototype.updateDisplay = function updateDisplay() {
if (this.getValue() === true) {
this.__checkbox.setAttribute('checked', 'checked');
this.__checkbox.checked = true;
this.__prev = true;
} else {
this.__checkbox.checked = false;
this.__prev = false;
}
return _Controller.prototype.updateDisplay.call(this);
};
return BooleanController;
}(_Controller3.default);
exports.default = BooleanController;
module.exports = exports['default'];
/***/ },
/* 9 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.__esModule = true;
var _common = __webpack_require__(5);
var _common2 = _interopRequireDefault(_common);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var EVENT_MAP = {
HTMLEvents: ['change'],
MouseEvents: ['click', 'mousemove', 'mousedown', 'mouseup', 'mouseover'],
KeyboardEvents: ['keydown']
}; /**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
var EVENT_MAP_INV = {};
_common2.default.each(EVENT_MAP, function (v, k) {
_common2.default.each(v, function (e) {
EVENT_MAP_INV[e] = k;
});
});
var CSS_VALUE_PIXELS = /(\d+(\.\d+)?)px/;
function cssValueToPixels(val) {
if (val === '0' || _common2.default.isUndefined(val)) {
return 0;
}
var match = val.match(CSS_VALUE_PIXELS);
if (!_common2.default.isNull(match)) {
return parseFloat(match[1]);
}
// TODO ...ems? %?
return 0;
}
/**
* @namespace
* @member dat.dom
*/
var dom = {
/**
*
* @param elem
* @param selectable
*/
makeSelectable: function makeSelectable(elem, selectable) {
if (elem === undefined || elem.style === undefined) return;
elem.onselectstart = selectable ? function () {
return false;
} : function () {};
elem.style.MozUserSelect = selectable ? 'auto' : 'none';
elem.style.KhtmlUserSelect = selectable ? 'auto' : 'none';
elem.unselectable = selectable ? 'on' : 'off';
},
/**
*
* @param elem
* @param horizontal
* @param vert
*/
makeFullscreen: function makeFullscreen(elem, hor, vert) {
var vertical = vert;
var horizontal = hor;
if (_common2.default.isUndefined(horizontal)) {
horizontal = true;
}
if (_common2.default.isUndefined(vertical)) {
vertical = true;
}
elem.style.position = 'absolute';
if (horizontal) {
elem.style.left = 0;
elem.style.right = 0;
}
if (vertical) {
elem.style.top = 0;
elem.style.bottom = 0;
}
},
/**
*
* @param elem
* @param eventType
* @param params
*/
fakeEvent: function fakeEvent(elem, eventType, pars, aux) {
var params = pars || {};
var className = EVENT_MAP_INV[eventType];
if (!className) {
throw new Error('Event type ' + eventType + ' not supported.');
}
var evt = document.createEvent(className);
switch (className) {
case 'MouseEvents':
{
var clientX = params.x || params.clientX || 0;
var clientY = params.y || params.clientY || 0;
evt.initMouseEvent(eventType, params.bubbles || false, params.cancelable || true, window, params.clickCount || 1, 0, // screen X
0, // screen Y
clientX, // client X
clientY, // client Y
false, false, false, false, 0, null);
break;
}
case 'KeyboardEvents':
{
var init = evt.initKeyboardEvent || evt.initKeyEvent; // webkit || moz
_common2.default.defaults(params, {
cancelable: true,
ctrlKey: false,
altKey: false,
shiftKey: false,
metaKey: false,
keyCode: undefined,
charCode: undefined
});
init(eventType, params.bubbles || false, params.cancelable, window, params.ctrlKey, params.altKey, params.shiftKey, params.metaKey, params.keyCode, params.charCode);
break;
}
default:
{
evt.initEvent(eventType, params.bubbles || false, params.cancelable || true);
break;
}
}
_common2.default.defaults(evt, aux);
elem.dispatchEvent(evt);
},
/**
*
* @param elem
* @param event
* @param func
* @param bool
*/
bind: function bind(elem, event, func, newBool) {
var bool = newBool || false;
if (elem.addEventListener) {
elem.addEventListener(event, func, bool);
} else if (elem.attachEvent) {
elem.attachEvent('on' + event, func);
}
return dom;
},
/**
*
* @param elem
* @param event
* @param func
* @param bool
*/
unbind: function unbind(elem, event, func, newBool) {
var bool = newBool || false;
if (elem.removeEventListener) {
elem.removeEventListener(event, func, bool);
} else if (elem.detachEvent) {
elem.detachEvent('on' + event, func);
}
return dom;
},
/**
*
* @param elem
* @param className
*/
addClass: function addClass(elem, className) {
if (elem.className === undefined) {
elem.className = className;
} else if (elem.className !== className) {
var classes = elem.className.split(/ +/);
if (classes.indexOf(className) === -1) {
classes.push(className);
elem.className = classes.join(' ').replace(/^\s+/, '').replace(/\s+$/, '');
}
}
return dom;
},
/**
*
* @param elem
* @param className
*/
removeClass: function removeClass(elem, className) {
if (className) {
if (elem.className === className) {
elem.removeAttribute('class');
} else {
var classes = elem.className.split(/ +/);
var index = classes.indexOf(className);
if (index !== -1) {
classes.splice(index, 1);
elem.className = classes.join(' ');
}
}
} else {
elem.className = undefined;
}
return dom;
},
hasClass: function hasClass(elem, className) {
return new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)').test(elem.className) || false;
},
/**
*
* @param elem
*/
getWidth: function getWidth(elem) {
var style = getComputedStyle(elem);
return cssValueToPixels(style['border-left-width']) + cssValueToPixels(style['border-right-width']) + cssValueToPixels(style['padding-left']) + cssValueToPixels(style['padding-right']) + cssValueToPixels(style.width);
},
/**
*
* @param elem
*/
getHeight: function getHeight(elem) {
var style = getComputedStyle(elem);
return cssValueToPixels(style['border-top-width']) + cssValueToPixels(style['border-bottom-width']) + cssValueToPixels(style['padding-top']) + cssValueToPixels(style['padding-bottom']) + cssValueToPixels(style.height);
},
/**
*
* @param el
*/
getOffset: function getOffset(el) {
var elem = el;
var offset = { left: 0, top: 0 };
if (elem.offsetParent) {
do {
offset.left += elem.offsetLeft;
offset.top += elem.offsetTop;
elem = elem.offsetParent;
} while (elem);
}
return offset;
},
// http://stackoverflow.com/posts/2684561/revisions
/**
*
* @param elem
*/
isActive: function isActive(elem) {
return elem === document.activeElement && (elem.type || elem.href);
}
};
exports.default = dom;
module.exports = exports['default'];
/***/ },
/* 10 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.__esModule = true;
var _Controller2 = __webpack_require__(7);
var _Controller3 = _interopRequireDefault(_Controller2);
var _dom = __webpack_require__(9);
var _dom2 = _interopRequireDefault(_dom);
var _common = __webpack_require__(5);
var _common2 = _interopRequireDefault(_common);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
/**
* @class Provides a select input to alter the property of an object, using a
* list of accepted values.
*
* @extends dat.controllers.Controller
*
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
* @param {Object|string[]} options A map of labels to acceptable values, or
* a list of acceptable string values.
*
* @member dat.controllers
*/
var OptionController = function (_Controller) {
_inherits(OptionController, _Controller);
function OptionController(object, property, opts) {
_classCallCheck(this, OptionController);
var _this2 = _possibleConstructorReturn(this, _Controller.call(this, object, property));
var options = opts;
var _this = _this2;
/**
* The drop down menu
* @ignore
*/
_this2.__select = document.createElement('select');
if (_common2.default.isArray(options)) {
var map = {};
_common2.default.each(options, function (element) {
map[element] = element;
});
options = map;
}
_common2.default.each(options, function (value, key) {
var opt = document.createElement('option');
opt.innerHTML = key;
opt.setAttribute('value', value);
_this.__select.appendChild(opt);
});
// Acknowledge original value
_this2.updateDisplay();
_dom2.default.bind(_this2.__select, 'change', function () {
var desiredValue = this.options[this.selectedIndex].value;
_this.setValue(desiredValue);
});
_this2.domElement.appendChild(_this2.__select);
return _this2;
}
OptionController.prototype.setValue = function setValue(v) {
var toReturn = _Controller.prototype.setValue.call(this, v);
if (this.__onFinishChange) {
this.__onFinishChange.call(this, this.getValue());
}
return toReturn;
};
OptionController.prototype.updateDisplay = function updateDisplay() {
if (_dom2.default.isActive(this.__select)) return this; // prevent number from updating if user is trying to manually update
this.__select.value = this.getValue();
return _Controller.prototype.updateDisplay.call(this);
};
return OptionController;
}(_Controller3.default);
exports.default = OptionController;
module.exports = exports['default'];
/***/ },
/* 11 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.__esModule = true;
var _Controller2 = __webpack_require__(7);
var _Controller3 = _interopRequireDefault(_Controller2);
var _dom = __webpack_require__(9);
var _dom2 = _interopRequireDefault(_dom);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
/**
* @class Provides a text input to alter the string property of an object.
*
* @extends dat.controllers.Controller
*
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
*
* @member dat.controllers
*/
var StringController = function (_Controller) {
_inherits(StringController, _Controller);
function StringController(object, property) {
_classCallCheck(this, StringController);
var _this2 = _possibleConstructorReturn(this, _Controller.call(this, object, property));
var _this = _this2;
function onChange() {
_this.setValue(_this.__input.value);
}
function onBlur() {
if (_this.__onFinishChange) {
_this.__onFinishChange.call(_this, _this.getValue());
}
}
_this2.__input = document.createElement('input');
_this2.__input.setAttribute('type', 'text');
_dom2.default.bind(_this2.__input, 'keyup', onChange);
_dom2.default.bind(_this2.__input, 'change', onChange);
_dom2.default.bind(_this2.__input, 'blur', onBlur);
_dom2.default.bind(_this2.__input, 'keydown', function (e) {
if (e.keyCode === 13) {
this.blur();
}
});
_this2.updateDisplay();
_this2.domElement.appendChild(_this2.__input);
return _this2;
}
StringController.prototype.updateDisplay = function updateDisplay() {
// Stops the caret from moving on account of:
// keyup -> setValue -> updateDisplay
if (!_dom2.default.isActive(this.__input)) {
this.__input.value = this.getValue();
}
return _Controller.prototype.updateDisplay.call(this);
};
return StringController;
}(_Controller3.default);
exports.default = StringController;
module.exports = exports['default'];
/***/ },
/* 12 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.__esModule = true;
var _Controller2 = __webpack_require__(7);
var _Controller3 = _interopRequireDefault(_Controller2);
var _common = __webpack_require__(5);
var _common2 = _interopRequireDefault(_common);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
function numDecimals(x) {
var _x = x.toString();
if (_x.indexOf('.') > -1) {
return _x.length - _x.indexOf('.') - 1;
}
return 0;
}
/**
* @class Represents a given property of an object that is a number.
*
* @extends dat.controllers.Controller
*
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
* @param {Object} [params] Optional parameters
* @param {Number} [params.min] Minimum allowed value
* @param {Number} [params.max] Maximum allowed value
* @param {Number} [params.step] Increment by which to change value
*
* @member dat.controllers
*/
var NumberController = function (_Controller) {
_inherits(NumberController, _Controller);
function NumberController(object, property, params) {
_classCallCheck(this, NumberController);
var _this = _possibleConstructorReturn(this, _Controller.call(this, object, property));
var _params = params || {};
_this.__min = _params.min;
_this.__max = _params.max;
_this.__step = _params.step;
if (_common2.default.isUndefined(_this.__step)) {
if (_this.initialValue === 0) {
_this.__impliedStep = 1; // What are we, psychics?
} else {
// Hey Doug, check this out.
_this.__impliedStep = Math.pow(10, Math.floor(Math.log(Math.abs(_this.initialValue)) / Math.LN10)) / 10;
}
} else {
_this.__impliedStep = _this.__step;
}
_this.__precision = numDecimals(_this.__impliedStep);
return _this;
}
NumberController.prototype.setValue = function setValue(v) {
var _v = v;
if (this.__min !== undefined && _v < this.__min) {
_v = this.__min;
} else if (this.__max !== undefined && _v > this.__max) {
_v = this.__max;
}
if (this.__step !== undefined && _v % this.__step !== 0) {
_v = Math.round(_v / this.__step) * this.__step;
}
return _Controller.prototype.setValue.call(this, _v);
};
/**
* Specify a minimum value for <code>object[property]</code>.
*
* @param {Number} minValue The minimum value for
* <code>object[property]</code>
* @returns {dat.controllers.NumberController} this
*/
NumberController.prototype.min = function min(v) {
this.__min = v;
return this;
};
/**
* Specify a maximum value for <code>object[property]</code>.
*
* @param {Number} maxValue The maximum value for
* <code>object[property]</code>
* @returns {dat.controllers.NumberController} this
*/
NumberController.prototype.max = function max(v) {
this.__max = v;
return this;
};
/**
* Specify a step value that dat.controllers.NumberController
* increments by.
*
* @param {Number} stepValue The step value for
* dat.controllers.NumberController
* @default if minimum and maximum specified increment is 1% of the
* difference otherwise stepValue is 1
* @returns {dat.controllers.NumberController} this
*/
NumberController.prototype.step = function step(v) {
this.__step = v;
this.__impliedStep = v;
this.__precision = numDecimals(v);
return this;
};
return NumberController;
}(_Controller3.default);
exports.default = NumberController;
module.exports = exports['default'];
/***/ },
/* 13 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.__esModule = true;
var _NumberController2 = __webpack_require__(12);
var _NumberController3 = _interopRequireDefault(_NumberController2);
var _dom = __webpack_require__(9);
var _dom2 = _interopRequireDefault(_dom);
var _common = __webpack_require__(5);
var _common2 = _interopRequireDefault(_common);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
function roundToDecimal(value, decimals) {
var tenTo = Math.pow(10, decimals);
return Math.round(value * tenTo) / tenTo;
}
/**
* @class Represents a given property of an object that is a number and
* provides an input element with which to manipulate it.
*
* @extends dat.controllers.Controller
* @extends dat.controllers.NumberController
*
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
* @param {Object} [params] Optional parameters
* @param {Number} [params.min] Minimum allowed value
* @param {Number} [params.max] Maximum allowed value
* @param {Number} [params.step] Increment by which to change value
*
* @member dat.controllers
*/
var NumberControllerBox = function (_NumberController) {
_inherits(NumberControllerBox, _NumberController);
function NumberControllerBox(object, property, params) {
_classCallCheck(this, NumberControllerBox);
var _this2 = _possibleConstructorReturn(this, _NumberController.call(this, object, property, params));
_this2.__truncationSuspended = false;
var _this = _this2;
/**
* {Number} Previous mouse y position
* @ignore
*/
var prevY = void 0;
function onChange() {
var attempted = parseFloat(_this.__input.value);
if (!_common2.default.isNaN(attempted)) {
_this.setValue(attempted);
}
}
function onFinish() {
if (_this.__onFinishChange) {
_this.__onFinishChange.call(_this, _this.getValue());
}
}
function onBlur() {
onFinish();
}
function onMouseDrag(e) {
var diff = prevY - e.clientY;
_this.setValue(_this.getValue() + diff * _this.__impliedStep);
prevY = e.clientY;
}
function onMouseUp() {
_dom2.default.unbind(window, 'mousemove', onMouseDrag);
_dom2.default.unbind(window, 'mouseup', onMouseUp);
onFinish();
}
function onMouseDown(e) {
_dom2.default.bind(window, 'mousemove', onMouseDrag);
_dom2.default.bind(window, 'mouseup', onMouseUp);
prevY = e.clientY;
}
_this2.__input = document.createElement('input');
_this2.__input.setAttribute('type', 'text');
// Makes it so manually specified values are not truncated.
_dom2.default.bind(_this2.__input, 'change', onChange);
_dom2.default.bind(_this2.__input, 'blur', onBlur);
_dom2.default.bind(_this2.__input, 'mousedown', onMouseDown);
_dom2.default.bind(_this2.__input, 'keydown', function (e) {
// When pressing enter, you can be as precise as you want.
if (e.keyCode === 13) {
_this.__truncationSuspended = true;
this.blur();
_this.__truncationSuspended = false;
onFinish();
}
});
_this2.updateDisplay();
_this2.domElement.appendChild(_this2.__input);
return _this2;
}
NumberControllerBox.prototype.updateDisplay = function updateDisplay() {
this.__input.value = this.__truncationSuspended ? this.getValue() : roundToDecimal(this.getValue(), this.__precision);
return _NumberController.prototype.updateDisplay.call(this);
};
return NumberControllerBox;
}(_NumberController3.default);
exports.default = NumberControllerBox;
module.exports = exports['default'];
/***/ },
/* 14 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.__esModule = true;
var _NumberController2 = __webpack_require__(12);
var _NumberController3 = _interopRequireDefault(_NumberController2);
var _dom = __webpack_require__(9);
var _dom2 = _interopRequireDefault(_dom);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
function map(v, i1, i2, o1, o2) {
return o1 + (o2 - o1) * ((v - i1) / (i2 - i1));
}
/**
* @class Represents a given property of an object that is a number, contains
* a minimum and maximum, and provides a slider element with which to
* manipulate it. It should be noted that the slider element is made up of
* <code>&lt;div&gt;</code> tags, <strong>not</strong> the html5
* <code>&lt;slider&gt;</code> element.
*
* @extends dat.controllers.Controller
* @extends dat.controllers.NumberController
*
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
* @param {Number} minValue Minimum allowed value
* @param {Number} maxValue Maximum allowed value
* @param {Number} stepValue Increment by which to change value
*
* @member dat.controllers
*/
var NumberControllerSlider = function (_NumberController) {
_inherits(NumberControllerSlider, _NumberController);
function NumberControllerSlider(object, property, min, max, step) {
_classCallCheck(this, NumberControllerSlider);
var _this2 = _possibleConstructorReturn(this, _NumberController.call(this, object, property, { min: min, max: max, step: step }));
var _this = _this2;
_this2.__background = document.createElement('div');
_this2.__foreground = document.createElement('div');
_dom2.default.bind(_this2.__background, 'mousedown', onMouseDown);
_dom2.default.addClass(_this2.__background, 'slider');
_dom2.default.addClass(_this2.__foreground, 'slider-fg');
function onMouseDown(e) {
document.activeElement.blur();
_dom2.default.bind(window, 'mousemove', onMouseDrag);
_dom2.default.bind(window, 'mouseup', onMouseUp);
onMouseDrag(e);
}
function onMouseDrag(e) {
e.preventDefault();
var bgRect = _this.__background.getBoundingClientRect();
_this.setValue(map(e.clientX, bgRect.left, bgRect.right, _this.__min, _this.__max));
return false;
}
function onMouseUp() {
_dom2.default.unbind(window, 'mousemove', onMouseDrag);
_dom2.default.unbind(window, 'mouseup', onMouseUp);
if (_this.__onFinishChange) {
_this.__onFinishChange.call(_this, _this.getValue());
}
}
_this2.updateDisplay();
_this2.__background.appendChild(_this2.__foreground);
_this2.domElement.appendChild(_this2.__background);
return _this2;
}
NumberControllerSlider.prototype.updateDisplay = function updateDisplay() {
var pct = (this.getValue() - this.__min) / (this.__max - this.__min);
this.__foreground.style.width = pct * 100 + '%';
return _NumberController.prototype.updateDisplay.call(this);
};
return NumberControllerSlider;
}(_NumberController3.default);
exports.default = NumberControllerSlider;
module.exports = exports['default'];
/***/ },
/* 15 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.__esModule = true;
var _Controller2 = __webpack_require__(7);
var _Controller3 = _interopRequireDefault(_Controller2);
var _dom = __webpack_require__(9);
var _dom2 = _interopRequireDefault(_dom);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
/**
* @class Provides a GUI interface to fire a specified method, a property of an object.
*
* @extends dat.controllers.Controller
*
* @param {Object} object The object to be manipulated
* @param {string} property The name of the property to be manipulated
*
* @member dat.controllers
*/
var FunctionController = function (_Controller) {
_inherits(FunctionController, _Controller);
function FunctionController(object, property, text) {
_classCallCheck(this, FunctionController);
var _this2 = _possibleConstructorReturn(this, _Controller.call(this, object, property));
var _this = _this2;
_this2.__button = document.createElement('div');
_this2.__button.innerHTML = text === undefined ? 'Fire' : text;
_dom2.default.bind(_this2.__button, 'click', function (e) {
e.preventDefault();
_this.fire();
return false;
});
_dom2.default.addClass(_this2.__button, 'button');
_this2.domElement.appendChild(_this2.__button);
return _this2;
}
FunctionController.prototype.fire = function fire() {
if (this.__onChange) {
this.__onChange.call(this);
}
this.getValue().call(this.object);
if (this.__onFinishChange) {
this.__onFinishChange.call(this, this.getValue());
}
};
return FunctionController;
}(_Controller3.default);
exports.default = FunctionController;
module.exports = exports['default'];
/***/ },
/* 16 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.__esModule = true;
var _Controller2 = __webpack_require__(7);
var _Controller3 = _interopRequireDefault(_Controller2);
var _dom = __webpack_require__(9);
var _dom2 = _interopRequireDefault(_dom);
var _Color = __webpack_require__(2);
var _Color2 = _interopRequireDefault(_Color);
var _interpret = __webpack_require__(3);
var _interpret2 = _interopRequireDefault(_interpret);
var _common = __webpack_require__(5);
var _common2 = _interopRequireDefault(_common);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } /**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
var ColorController = function (_Controller) {
_inherits(ColorController, _Controller);
function ColorController(object, property) {
_classCallCheck(this, ColorController);
var _this2 = _possibleConstructorReturn(this, _Controller.call(this, object, property));
_this2.__color = new _Color2.default(_this2.getValue());
_this2.__temp = new _Color2.default(0);
var _this = _this2;
_this2.domElement = document.createElement('div');
_dom2.default.makeSelectable(_this2.domElement, false);
_this2.__selector = document.createElement('div');
_this2.__selector.className = 'selector';
_this2.__saturation_field = document.createElement('div');
_this2.__saturation_field.className = 'saturation-field';
_this2.__field_knob = document.createElement('div');
_this2.__field_knob.className = 'field-knob';
_this2.__field_knob_border = '2px solid ';
_this2.__hue_knob = document.createElement('div');
_this2.__hue_knob.className = 'hue-knob';
_this2.__hue_field = document.createElement('div');
_this2.__hue_field.className = 'hue-field';
_this2.__input = document.createElement('input');
_this2.__input.type = 'text';
_this2.__input_textShadow = '0 1px 1px ';
_dom2.default.bind(_this2.__input, 'keydown', function (e) {
if (e.keyCode === 13) {
// on enter
onBlur.call(this);
}
});
_dom2.default.bind(_this2.__input, 'blur', onBlur);
_dom2.default.bind(_this2.__selector, 'mousedown', function () /* e */{
_dom2.default.addClass(this, 'drag').bind(window, 'mouseup', function () /* e */{
_dom2.default.removeClass(_this.__selector, 'drag');
});
});
var valueField = document.createElement('div');
_common2.default.extend(_this2.__selector.style, {
width: '122px',
height: '102px',
padding: '3px',
backgroundColor: '#222',
boxShadow: '0px 1px 3px rgba(0,0,0,0.3)'
});
_common2.default.extend(_this2.__field_knob.style, {
position: 'absolute',
width: '12px',
height: '12px',
border: _this2.__field_knob_border + (_this2.__color.v < 0.5 ? '#fff' : '#000'),
boxShadow: '0px 1px 3px rgba(0,0,0,0.5)',
borderRadius: '12px',
zIndex: 1
});
_common2.default.extend(_this2.__hue_knob.style, {
position: 'absolute',
width: '15px',
height: '2px',
borderRight: '4px solid #fff',
zIndex: 1
});
_common2.default.extend(_this2.__saturation_field.style, {
width: '100px',
height: '100px',
border: '1px solid #555',
marginRight: '3px',
display: 'inline-block',
cursor: 'pointer'
});
_common2.default.extend(valueField.style, {
width: '100%',
height: '100%',
background: 'none'
});
linearGradient(valueField, 'top', 'rgba(0,0,0,0)', '#000');
_common2.default.extend(_this2.__hue_field.style, {
width: '15px',
height: '100px',
border: '1px solid #555',
cursor: 'ns-resize',
position: 'absolute',
top: '3px',
right: '3px'
});
hueGradient(_this2.__hue_field);
_common2.default.extend(_this2.__input.style, {
outline: 'none',
// width: '120px',
textAlign: 'center',
// padding: '4px',
// marginBottom: '6px',
color: '#fff',
border: 0,
fontWeight: 'bold',
textShadow: _this2.__input_textShadow + 'rgba(0,0,0,0.7)'
});
_dom2.default.bind(_this2.__saturation_field, 'mousedown', fieldDown);
_dom2.default.bind(_this2.__field_knob, 'mousedown', fieldDown);
_dom2.default.bind(_this2.__hue_field, 'mousedown', function (e) {
setH(e);
_dom2.default.bind(window, 'mousemove', setH);
_dom2.default.bind(window, 'mouseup', fieldUpH);
});
function fieldDown(e) {
setSV(e);
// document.body.style.cursor = 'none';
_dom2.default.bind(window, 'mousemove', setSV);
_dom2.default.bind(window, 'mouseup', fieldUpSV);
}
function fieldUpSV() {
_dom2.default.unbind(window, 'mousemove', setSV);
_dom2.default.unbind(window, 'mouseup', fieldUpSV);
// document.body.style.cursor = 'default';
onFinish();
}
function onBlur() {
var i = (0, _interpret2.default)(this.value);
if (i !== false) {
_this.__color.__state = i;
_this.setValue(_this.__color.toOriginal());
} else {
this.value = _this.__color.toString();
}
}
function fieldUpH() {
_dom2.default.unbind(window, 'mousemove', setH);
_dom2.default.unbind(window, 'mouseup', fieldUpH);
onFinish();
}
function onFinish() {
if (_this.__onFinishChange) {
_this.__onFinishChange.call(_this, _this.__color.toOriginal());
}
}
_this2.__saturation_field.appendChild(valueField);
_this2.__selector.appendChild(_this2.__field_knob);
_this2.__selector.appendChild(_this2.__saturation_field);
_this2.__selector.appendChild(_this2.__hue_field);
_this2.__hue_field.appendChild(_this2.__hue_knob);
_this2.domElement.appendChild(_this2.__input);
_this2.domElement.appendChild(_this2.__selector);
_this2.updateDisplay();
function setSV(e) {
e.preventDefault();
var fieldRect = _this.__saturation_field.getBoundingClientRect();
var s = (e.clientX - fieldRect.left) / (fieldRect.right - fieldRect.left);
var v = 1 - (e.clientY - fieldRect.top) / (fieldRect.bottom - fieldRect.top);
if (v > 1) {
v = 1;
} else if (v < 0) {
v = 0;
}
if (s > 1) {
s = 1;
} else if (s < 0) {
s = 0;
}
_this.__color.v = v;
_this.__color.s = s;
_this.setValue(_this.__color.toOriginal());
return false;
}
function setH(e) {
e.preventDefault();
var fieldRect = _this.__hue_field.getBoundingClientRect();
var h = 1 - (e.clientY - fieldRect.top) / (fieldRect.bottom - fieldRect.top);
if (h > 1) {
h = 1;
} else if (h < 0) {
h = 0;
}
_this.__color.h = h * 360;
_this.setValue(_this.__color.toOriginal());
return false;
}
return _this2;
}
ColorController.prototype.updateDisplay = function updateDisplay() {
var i = (0, _interpret2.default)(this.getValue());
if (i !== false) {
var mismatch = false;
// Check for mismatch on the interpreted value.
_common2.default.each(_Color2.default.COMPONENTS, function (component) {
if (!_common2.default.isUndefined(i[component]) && !_common2.default.isUndefined(this.__color.__state[component]) && i[component] !== this.__color.__state[component]) {
mismatch = true;
return {}; // break
}
}, this);
// If nothing diverges, we keep our previous values
// for statefulness, otherwise we recalculate fresh
if (mismatch) {
_common2.default.extend(this.__color.__state, i);
}
}
_common2.default.extend(this.__temp.__state, this.__color.__state);
this.__temp.a = 1;
var flip = this.__color.v < 0.5 || this.__color.s > 0.5 ? 255 : 0;
var _flip = 255 - flip;
_common2.default.extend(this.__field_knob.style, {
marginLeft: 100 * this.__color.s - 7 + 'px',
marginTop: 100 * (1 - this.__color.v) - 7 + 'px',
backgroundColor: this.__temp.toHexString(),
border: this.__field_knob_border + 'rgb(' + flip + ',' + flip + ',' + flip + ')'
});
this.__hue_knob.style.marginTop = (1 - this.__color.h / 360) * 100 + 'px';
this.__temp.s = 1;
this.__temp.v = 1;
linearGradient(this.__saturation_field, 'left', '#fff', this.__temp.toHexString());
this.__input.value = this.__color.toString();
_common2.default.extend(this.__input.style, {
backgroundColor: this.__color.toHexString(),
color: 'rgb(' + flip + ',' + flip + ',' + flip + ')',
textShadow: this.__input_textShadow + 'rgba(' + _flip + ',' + _flip + ',' + _flip + ',.7)'
});
};
return ColorController;
}(_Controller3.default);
var vendors = ['-moz-', '-o-', '-webkit-', '-ms-', ''];
function linearGradient(elem, x, a, b) {
elem.style.background = '';
_common2.default.each(vendors, function (vendor) {
elem.style.cssText += 'background: ' + vendor + 'linear-gradient(' + x + ', ' + a + ' 0%, ' + b + ' 100%); ';
});
}
function hueGradient(elem) {
elem.style.background = '';
elem.style.cssText += 'background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);';
elem.style.cssText += 'background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);';
elem.style.cssText += 'background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);';
elem.style.cssText += 'background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);';
elem.style.cssText += 'background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);';
}
exports.default = ColorController;
module.exports = exports['default'];
/***/ },
/* 17 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.__esModule = true;
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; /**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
var _css = __webpack_require__(18);
var _css2 = _interopRequireDefault(_css);
var _saveDialogue = __webpack_require__(19);
var _saveDialogue2 = _interopRequireDefault(_saveDialogue);
var _ControllerFactory = __webpack_require__(20);
var _ControllerFactory2 = _interopRequireDefault(_ControllerFactory);
var _Controller = __webpack_require__(7);
var _Controller2 = _interopRequireDefault(_Controller);
var _BooleanController = __webpack_require__(8);
var _BooleanController2 = _interopRequireDefault(_BooleanController);
var _FunctionController = __webpack_require__(15);
var _FunctionController2 = _interopRequireDefault(_FunctionController);
var _NumberControllerBox = __webpack_require__(13);
var _NumberControllerBox2 = _interopRequireDefault(_NumberControllerBox);
var _NumberControllerSlider = __webpack_require__(14);
var _NumberControllerSlider2 = _interopRequireDefault(_NumberControllerSlider);
var _ColorController = __webpack_require__(16);
var _ColorController2 = _interopRequireDefault(_ColorController);
var _requestAnimationFrame = __webpack_require__(21);
var _requestAnimationFrame2 = _interopRequireDefault(_requestAnimationFrame);
var _CenteredDiv = __webpack_require__(22);
var _CenteredDiv2 = _interopRequireDefault(_CenteredDiv);
var _dom = __webpack_require__(9);
var _dom2 = _interopRequireDefault(_dom);
var _common = __webpack_require__(5);
var _common2 = _interopRequireDefault(_common);
var _style = __webpack_require__(23);
var _style2 = _interopRequireDefault(_style);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// CSS to embed in build
_css2.default.inject(_style2.default);
/** Outer-most className for GUI's */
var CSS_NAMESPACE = 'dg';
var HIDE_KEY_CODE = 72;
/** The only value shared between the JS and SCSS. Use caution. */
var CLOSE_BUTTON_HEIGHT = 20;
var DEFAULT_DEFAULT_PRESET_NAME = 'Default';
var SUPPORTS_LOCAL_STORAGE = function () {
try {
return 'localStorage' in window && window.localStorage !== null;
} catch (e) {
return false;
}
}();
var SAVE_DIALOGUE = void 0;
/** Have we yet to create an autoPlace GUI? */
var autoPlaceVirgin = true;
/** Fixed position div that auto place GUI's go inside */
var autoPlaceContainer = void 0;
/** Are we hiding the GUI's ? */
var hide = false;
/** GUI's which should be hidden */
var hideableGuis = [];
/**
* A lightweight controller library for JavaScript. It allows you to easily
* manipulate variables and fire functions on the fly.
* @class
*
* @member dat.gui
*
* @param {Object} [params]
* @param {String} [params.name] The name of this GUI.
* @param {Object} [params.load] JSON object representing the saved state of
* this GUI.
* @param {Boolean} [params.auto=true]
* @param {dat.gui.GUI} [params.parent] The GUI I'm nested in.
* @param {Boolean} [params.closed] If true, starts closed
* @param {Boolean} [params.closeOnTop] If true, close/open button shows on top of the GUI
*/
var GUI = function GUI(pars) {
var _this = this;
var params = pars || {};
/**
* Outermost DOM Element
* @type DOMElement
*/
this.domElement = document.createElement('div');
this.__ul = document.createElement('ul');
this.domElement.appendChild(this.__ul);
_dom2.default.addClass(this.domElement, CSS_NAMESPACE);
/**
* Nested GUI's by name
* @ignore
*/
this.__folders = {};
this.__controllers = [];
/**
* List of objects I'm remembering for save, only used in top level GUI
* @ignore
*/
this.__rememberedObjects = [];
/**
* Maps the index of remembered objects to a map of controllers, only used
* in top level GUI.
*
* @private
* @ignore
*
* @example
* [
* {
* propertyName: Controller,
* anotherPropertyName: Controller
* },
* {
* propertyName: Controller
* }
* ]
*/
this.__rememberedObjectIndecesToControllers = [];
this.__listening = [];
// Default parameters
params = _common2.default.defaults(params, {
closeOnTop: false,
autoPlace: true,
width: GUI.DEFAULT_WIDTH
});
params = _common2.default.defaults(params, {
resizable: params.autoPlace,
hideable: params.autoPlace
});
if (!_common2.default.isUndefined(params.load)) {
// Explicit preset
if (params.preset) {
params.load.preset = params.preset;
}
} else {
params.load = { preset: DEFAULT_DEFAULT_PRESET_NAME };
}
if (_common2.default.isUndefined(params.parent) && params.hideable) {
hideableGuis.push(this);
}
// Only root level GUI's are resizable.
params.resizable = _common2.default.isUndefined(params.parent) && params.resizable;
if (params.autoPlace && _common2.default.isUndefined(params.scrollable)) {
params.scrollable = true;
}
// params.scrollable = common.isUndefined(params.parent) && params.scrollable === true;
// Not part of params because I don't want people passing this in via
// constructor. Should be a 'remembered' value.
var useLocalStorage = SUPPORTS_LOCAL_STORAGE && localStorage.getItem(getLocalStorageHash(this, 'isLocal')) === 'true';
var saveToLocalStorage = void 0;
Object.defineProperties(this,
/** @lends dat.gui.GUI.prototype */
{
/**
* The parent <code>GUI</code>
* @type dat.gui.GUI
*/
parent: {
get: function get() {
return params.parent;
}
},
scrollable: {
get: function get() {
return params.scrollable;
}
},
/**
* Handles <code>GUI</code>'s element placement for you
* @type Boolean
*/
autoPlace: {
get: function get() {
return params.autoPlace;
}
},
/**
* Handles <code>GUI</code>'s position of open/close button
* @type Boolean
*/
closeOnTop: {
get: function get() {
return params.closeOnTop;
}
},
/**
* The identifier for a set of saved values
* @type String
*/
preset: {
get: function get() {
if (_this.parent) {
return _this.getRoot().preset;
}
return params.load.preset;
},
set: function set(v) {
if (_this.parent) {
_this.getRoot().preset = v;
} else {
params.load.preset = v;
}
setPresetSelectIndex(this);
_this.revert();
}
},
/**
* The width of <code>GUI</code> element
* @type Number
*/
width: {
get: function get() {
return params.width;
},
set: function set(v) {
params.width = v;
setWidth(_this, v);
}
},
/**
* The name of <code>GUI</code>. Used for folders. i.e
* a folder's name
* @type String
*/
name: {
get: function get() {
return params.name;
},
set: function set(v) {
// TODO Check for collisions among sibling folders
params.name = v;
if (titleRowName) {
titleRowName.innerHTML = params.name;
}
}
},
/**
* Whether the <code>GUI</code> is collapsed or not
* @type Boolean
*/
closed: {
get: function get() {
return params.closed;
},
set: function set(v) {
params.closed = v;
if (params.closed) {
_dom2.default.addClass(_this.__ul, GUI.CLASS_CLOSED);
} else {
_dom2.default.removeClass(_this.__ul, GUI.CLASS_CLOSED);
}
// For browsers that aren't going to respect the CSS transition,
// Lets just check our height against the window height right off
// the bat.
this.onResize();
if (_this.__closeButton) {
_this.__closeButton.innerHTML = v ? GUI.TEXT_OPEN : GUI.TEXT_CLOSED;
}
}
},
/**
* Contains all presets
* @type Object
*/
load: {
get: function get() {
return params.load;
}
},
/**
* Determines whether or not to use <a href="https://developer.mozilla.org/en/DOM/Storage#localStorage">localStorage</a> as the means for
* <code>remember</code>ing
* @type Boolean
*/
useLocalStorage: {
get: function get() {
return useLocalStorage;
},
set: function set(bool) {
if (SUPPORTS_LOCAL_STORAGE) {
useLocalStorage = bool;
if (bool) {
_dom2.default.bind(window, 'unload', saveToLocalStorage);
} else {
_dom2.default.unbind(window, 'unload', saveToLocalStorage);
}
localStorage.setItem(getLocalStorageHash(_this, 'isLocal'), bool);
}
}
}
});
// Are we a root level GUI?
if (_common2.default.isUndefined(params.parent)) {
params.closed = false;
_dom2.default.addClass(this.domElement, GUI.CLASS_MAIN);
_dom2.default.makeSelectable(this.domElement, false);
// Are we supposed to be loading locally?
if (SUPPORTS_LOCAL_STORAGE) {
if (useLocalStorage) {
_this.useLocalStorage = true;
var savedGui = localStorage.getItem(getLocalStorageHash(this, 'gui'));
if (savedGui) {
params.load = JSON.parse(savedGui);
}
}
}
this.__closeButton = document.createElement('div');
this.__closeButton.innerHTML = GUI.TEXT_CLOSED;
_dom2.default.addClass(this.__closeButton, GUI.CLASS_CLOSE_BUTTON);
if (params.closeOnTop) {
_dom2.default.addClass(this.__closeButton, GUI.CLASS_CLOSE_TOP);
this.domElement.insertBefore(this.__closeButton, this.domElement.childNodes[0]);
} else {
_dom2.default.addClass(this.__closeButton, GUI.CLASS_CLOSE_BOTTOM);
this.domElement.appendChild(this.__closeButton);
}
_dom2.default.bind(this.__closeButton, 'click', function () {
_this.closed = !_this.closed;
});
// Oh, you're a nested GUI!
} else {
if (params.closed === undefined) {
params.closed = true;
}
var _titleRowName = document.createTextNode(params.name);
_dom2.default.addClass(_titleRowName, 'controller-name');
var titleRow = addRow(_this, _titleRowName);
var onClickTitle = function onClickTitle(e) {
e.preventDefault();
_this.closed = !_this.closed;
return false;
};
_dom2.default.addClass(this.__ul, GUI.CLASS_CLOSED);
_dom2.default.addClass(titleRow, 'title');
_dom2.default.bind(titleRow, 'click', onClickTitle);
if (!params.closed) {
this.closed = false;
}
}
if (params.autoPlace) {
if (_common2.default.isUndefined(params.parent)) {
if (autoPlaceVirgin) {
autoPlaceContainer = document.createElement('div');
_dom2.default.addClass(autoPlaceContainer, CSS_NAMESPACE);
_dom2.default.addClass(autoPlaceContainer, GUI.CLASS_AUTO_PLACE_CONTAINER);
document.body.appendChild(autoPlaceContainer);
autoPlaceVirgin = false;
}
// Put it in the dom for you.
autoPlaceContainer.appendChild(this.domElement);
// Apply the auto styles
_dom2.default.addClass(this.domElement, GUI.CLASS_AUTO_PLACE);
}
// Make it not elastic.
if (!this.parent) {
setWidth(_this, params.width);
}
}
this.__resizeHandler = function () {
_this.onResizeDebounced();
};
_dom2.default.bind(window, 'resize', this.__resizeHandler);
_dom2.default.bind(this.__ul, 'webkitTransitionEnd', this.__resizeHandler);
_dom2.default.bind(this.__ul, 'transitionend', this.__resizeHandler);
_dom2.default.bind(this.__ul, 'oTransitionEnd', this.__resizeHandler);
this.onResize();
if (params.resizable) {
addResizeHandle(this);
}
saveToLocalStorage = function saveToLocalStorage() {
if (SUPPORTS_LOCAL_STORAGE && localStorage.getItem(getLocalStorageHash(_this, 'isLocal')) === 'true') {
localStorage.setItem(getLocalStorageHash(_this, 'gui'), JSON.stringify(_this.getSaveObject()));
}
};
// expose this method publicly
this.saveToLocalStorageIfPossible = saveToLocalStorage;
function resetWidth() {
var root = _this.getRoot();
root.width += 1;
_common2.default.defer(function () {
root.width -= 1;
});
}
if (!params.parent) {
resetWidth();
}
};
GUI.toggleHide = function () {
hide = !hide;
_common2.default.each(hideableGuis, function (gui) {
gui.domElement.style.display = hide ? 'none' : '';
});
};
GUI.CLASS_AUTO_PLACE = 'a';
GUI.CLASS_AUTO_PLACE_CONTAINER = 'ac';
GUI.CLASS_MAIN = 'main';
GUI.CLASS_CONTROLLER_ROW = 'cr';
GUI.CLASS_TOO_TALL = 'taller-than-window';
GUI.CLASS_CLOSED = 'closed';
GUI.CLASS_CLOSE_BUTTON = 'close-button';
GUI.CLASS_CLOSE_TOP = 'close-top';
GUI.CLASS_CLOSE_BOTTOM = 'close-bottom';
GUI.CLASS_DRAG = 'drag';
GUI.DEFAULT_WIDTH = 245;
GUI.TEXT_CLOSED = 'Close Controls';
GUI.TEXT_OPEN = 'Open Controls';
GUI._keydownHandler = function (e) {
if (document.activeElement.type !== 'text' && (e.which === HIDE_KEY_CODE || e.keyCode === HIDE_KEY_CODE)) {
GUI.toggleHide();
}
};
_dom2.default.bind(window, 'keydown', GUI._keydownHandler, false);
_common2.default.extend(GUI.prototype,
/** @lends dat.gui.GUI */
{
/**
* @param object
* @param property
* @returns {dat.controllers.Controller} The new controller that was added.
* @instance
*/
add: function add(object, property) {
return _add(this, object, property, {
factoryArgs: Array.prototype.slice.call(arguments, 2)
});
},
/**
* @param object
* @param property
* @returns {dat.controllers.ColorController} The new controller that was added.
* @instance
*/
addColor: function addColor(object, property) {
return _add(this, object, property, {
color: true
});
},
/**
* @param controller
* @instance
*/
remove: function remove(controller) {
// TODO listening?
this.__ul.removeChild(controller.__li);
this.__controllers.splice(this.__controllers.indexOf(controller), 1);
var _this = this;
_common2.default.defer(function () {
_this.onResize();
});
},
destroy: function destroy() {
if (this.autoPlace) {
autoPlaceContainer.removeChild(this.domElement);
}
_dom2.default.unbind(window, 'keydown', GUI._keydownHandler, false);
_dom2.default.unbind(window, 'resize', this.__resizeHandler);
if (this.saveToLocalStorageIfPossible) {
_dom2.default.unbind(window, 'unload', this.saveToLocalStorageIfPossible);
}
},
/**
* @param name
* @returns {dat.gui.GUI} The new folder.
* @throws {Error} if this GUI already has a folder by the specified
* name
* @instance
*/
addFolder: function addFolder(name) {
// We have to prevent collisions on names in order to have a key
// by which to remember saved values
if (this.__folders[name] !== undefined) {
throw new Error('You already have a folder in this GUI by the' + ' name "' + name + '"');
}
var newGuiParams = { name: name, parent: this };
// We need to pass down the autoPlace trait so that we can
// attach event listeners to open/close folder actions to
// ensure that a scrollbar appears if the window is too short.
newGuiParams.autoPlace = this.autoPlace;
// Do we have saved appearance data for this folder?
if (this.load && // Anything loaded?
this.load.folders && // Was my parent a dead-end?
this.load.folders[name]) {
// Did daddy remember me?
// Start me closed if I was closed
newGuiParams.closed = this.load.folders[name].closed;
// Pass down the loaded data
newGuiParams.load = this.load.folders[name];
}
var gui = new GUI(newGuiParams);
this.__folders[name] = gui;
var li = addRow(this, gui.domElement);
_dom2.default.addClass(li, 'folder');
return gui;
},
open: function open() {
this.closed = false;
},
close: function close() {
this.closed = true;
},
onResize: function onResize() {
// we debounce this function to prevent performance issues when rotating on tablet/mobile
var root = this.getRoot();
if (root.scrollable) {
var top = _dom2.default.getOffset(root.__ul).top;
var h = 0;
_common2.default.each(root.__ul.childNodes, function (node) {
if (!(root.autoPlace && node === root.__save_row)) {
h += _dom2.default.getHeight(node);
}
});
if (window.innerHeight - top - CLOSE_BUTTON_HEIGHT < h) {
_dom2.default.addClass(root.domElement, GUI.CLASS_TOO_TALL);
root.__ul.style.height = window.innerHeight - top - CLOSE_BUTTON_HEIGHT + 'px';
} else {
_dom2.default.removeClass(root.domElement, GUI.CLASS_TOO_TALL);
root.__ul.style.height = 'auto';
}
}
if (root.__resize_handle) {
_common2.default.defer(function () {
root.__resize_handle.style.height = root.__ul.offsetHeight + 'px';
});
}
if (root.__closeButton) {
root.__closeButton.style.width = root.width + 'px';
}
},
onResizeDebounced: _common2.default.debounce(function () {
this.onResize();
}, 50),
/**
* Mark objects for saving. The order of these objects cannot change as
* the GUI grows. When remembering new objects, append them to the end
* of the list.
*
* @param {Object...} objects
* @throws {Error} if not called on a top level GUI.
* @instance
*/
remember: function remember() {
if (_common2.default.isUndefined(SAVE_DIALOGUE)) {
SAVE_DIALOGUE = new _CenteredDiv2.default();
SAVE_DIALOGUE.domElement.innerHTML = _saveDialogue2.default;
}
if (this.parent) {
throw new Error('You can only call remember on a top level GUI.');
}
var _this = this;
_common2.default.each(Array.prototype.slice.call(arguments), function (object) {
if (_this.__rememberedObjects.length === 0) {
addSaveMenu(_this);
}
if (_this.__rememberedObjects.indexOf(object) === -1) {
_this.__rememberedObjects.push(object);
}
});
if (this.autoPlace) {
// Set save row width
setWidth(this, this.width);
}
},
/**
* @returns {dat.gui.GUI} the topmost parent GUI of a nested GUI.
* @instance
*/
getRoot: function getRoot() {
var gui = this;
while (gui.parent) {
gui = gui.parent;
}
return gui;
},
/**
* @returns {Object} a JSON object representing the current state of
* this GUI as well as its remembered properties.
* @instance
*/
getSaveObject: function getSaveObject() {
var toReturn = this.load;
toReturn.closed = this.closed;
// Am I remembering any values?
if (this.__rememberedObjects.length > 0) {
toReturn.preset = this.preset;
if (!toReturn.remembered) {
toReturn.remembered = {};
}
toReturn.remembered[this.preset] = getCurrentPreset(this);
}
toReturn.folders = {};
_common2.default.each(this.__folders, function (element, key) {
toReturn.folders[key] = element.getSaveObject();
});
return toReturn;
},
save: function save() {
if (!this.load.remembered) {
this.load.remembered = {};
}
this.load.remembered[this.preset] = getCurrentPreset(this);
markPresetModified(this, false);
this.saveToLocalStorageIfPossible();
},
saveAs: function saveAs(presetName) {
if (!this.load.remembered) {
// Retain default values upon first save
this.load.remembered = {};
this.load.remembered[DEFAULT_DEFAULT_PRESET_NAME] = getCurrentPreset(this, true);
}
this.load.remembered[presetName] = getCurrentPreset(this);
this.preset = presetName;
addPresetOption(this, presetName, true);
this.saveToLocalStorageIfPossible();
},
revert: function revert(gui) {
_common2.default.each(this.__controllers, function (controller) {
// Make revert work on Default.
if (!this.getRoot().load.remembered) {
controller.setValue(controller.initialValue);
} else {
recallSavedValue(gui || this.getRoot(), controller);
}
// fire onFinishChange callback
if (controller.__onFinishChange) {
controller.__onFinishChange.call(controller, controller.getValue());
}
}, this);
_common2.default.each(this.__folders, function (folder) {
folder.revert(folder);
});
if (!gui) {
markPresetModified(this.getRoot(), false);
}
},
listen: function listen(controller) {
var init = this.__listening.length === 0;
this.__listening.push(controller);
if (init) {
updateDisplays(this.__listening);
}
},
updateDisplay: function updateDisplay() {
_common2.default.each(this.__controllers, function (controller) {
controller.updateDisplay();
});
_common2.default.each(this.__folders, function (folder) {
folder.updateDisplay();
});
}
});
/**
* Add a row to the end of the GUI or before another row.
*
* @param gui
* @param [newDom] If specified, inserts the dom content in the new row
* @param [liBefore] If specified, places the new row before another row
*/
function addRow(gui, newDom, liBefore) {
var li = document.createElement('li');
if (newDom) {
li.appendChild(newDom);
}
if (liBefore) {
gui.__ul.insertBefore(li, liBefore);
} else {
gui.__ul.appendChild(li);
}
gui.onResize();
return li;
}
function markPresetModified(gui, modified) {
var opt = gui.__preset_select[gui.__preset_select.selectedIndex];
// console.log('mark', modified, opt);
if (modified) {
opt.innerHTML = opt.value + '*';
} else {
opt.innerHTML = opt.value;
}
}
function augmentController(gui, li, controller) {
controller.__li = li;
controller.__gui = gui;
_common2.default.extend(controller, {
options: function options(_options) {
if (arguments.length > 1) {
var nextSibling = controller.__li.nextElementSibling;
controller.remove();
return _add(gui, controller.object, controller.property, {
before: nextSibling,
factoryArgs: [_common2.default.toArray(arguments)]
});
}
if (_common2.default.isArray(_options) || _common2.default.isObject(_options)) {
var _nextSibling = controller.__li.nextElementSibling;
controller.remove();
return _add(gui, controller.object, controller.property, {
before: _nextSibling,
factoryArgs: [_options]
});
}
},
name: function name(v) {
controller.__li.firstElementChild.firstElementChild.innerHTML = v;
return controller;
},
listen: function listen() {
controller.__gui.listen(controller);
return controller;
},
remove: function remove() {
controller.__gui.remove(controller);
return controller;
}
});
// All sliders should be accompanied by a box.
if (controller instanceof _NumberControllerSlider2.default) {
var box = new _NumberControllerBox2.default(controller.object, controller.property, { min: controller.__min, max: controller.__max, step: controller.__step });
_common2.default.each(['updateDisplay', 'onChange', 'onFinishChange', 'step'], function (method) {
var pc = controller[method];
var pb = box[method];
controller[method] = box[method] = function () {
var args = Array.prototype.slice.call(arguments);
pb.apply(box, args);
return pc.apply(controller, args);
};
});
_dom2.default.addClass(li, 'has-slider');
controller.domElement.insertBefore(box.domElement, controller.domElement.firstElementChild);
} else if (controller instanceof _NumberControllerBox2.default) {
var r = function r(returned) {
// Have we defined both boundaries?
if (_common2.default.isNumber(controller.__min) && _common2.default.isNumber(controller.__max)) {
// Well, then lets just replace this with a slider.
// lets remember if the old controller had a specific name or was listening
var oldName = controller.__li.firstElementChild.firstElementChild.innerHTML;
var wasListening = controller.__gui.__listening.indexOf(controller) > -1;
controller.remove();
var newController = _add(gui, controller.object, controller.property, {
before: controller.__li.nextElementSibling,
factoryArgs: [controller.__min, controller.__max, controller.__step]
});
newController.name(oldName);
if (wasListening) newController.listen();
return newController;
}
return returned;
};
controller.min = _common2.default.compose(r, controller.min);
controller.max = _common2.default.compose(r, controller.max);
} else if (controller instanceof _BooleanController2.default) {
_dom2.default.bind(li, 'click', function () {
_dom2.default.fakeEvent(controller.__checkbox, 'click');
});
_dom2.default.bind(controller.__checkbox, 'click', function (e) {
e.stopPropagation(); // Prevents double-toggle
});
} else if (controller instanceof _FunctionController2.default) {
_dom2.default.bind(li, 'click', function () {
_dom2.default.fakeEvent(controller.__button, 'click');
});
_dom2.default.bind(li, 'mouseover', function () {
_dom2.default.addClass(controller.__button, 'hover');
});
_dom2.default.bind(li, 'mouseout', function () {
_dom2.default.removeClass(controller.__button, 'hover');
});
} else if (controller instanceof _ColorController2.default) {
_dom2.default.addClass(li, 'color');
controller.updateDisplay = _common2.default.compose(function (val) {
li.style.borderLeftColor = controller.__color.toString();
return val;
}, controller.updateDisplay);
controller.updateDisplay();
}
controller.setValue = _common2.default.compose(function (val) {
if (gui.getRoot().__preset_select && controller.isModified()) {
markPresetModified(gui.getRoot(), true);
}
return val;
}, controller.setValue);
}
function recallSavedValue(gui, controller) {
// Find the topmost GUI, that's where remembered objects live.
var root = gui.getRoot();
// Does the object we're controlling match anything we've been told to
// remember?
var matchedIndex = root.__rememberedObjects.indexOf(controller.object);
// Why yes, it does!
if (matchedIndex !== -1) {
// Let me fetch a map of controllers for thcommon.isObject.
var controllerMap = root.__rememberedObjectIndecesToControllers[matchedIndex];
// Ohp, I believe this is the first controller we've created for this
// object. Lets make the map fresh.
if (controllerMap === undefined) {
controllerMap = {};
root.__rememberedObjectIndecesToControllers[matchedIndex] = controllerMap;
}
// Keep track of this controller
controllerMap[controller.property] = controller;
// Okay, now have we saved any values for this controller?
if (root.load && root.load.remembered) {
var presetMap = root.load.remembered;
// Which preset are we trying to load?
var preset = void 0;
if (presetMap[gui.preset]) {
preset = presetMap[gui.preset];
} else if (presetMap[DEFAULT_DEFAULT_PRESET_NAME]) {
// Uhh, you can have the default instead?
preset = presetMap[DEFAULT_DEFAULT_PRESET_NAME];
} else {
// Nada.
return;
}
// Did the loaded object remember thcommon.isObject? && Did we remember this particular property?
if (preset[matchedIndex] && preset[matchedIndex][controller.property] !== undefined) {
// We did remember something for this guy ...
var value = preset[matchedIndex][controller.property];
// And that's what it is.
controller.initialValue = value;
controller.setValue(value);
}
}
}
}
function _add(gui, object, property, params) {
if (object[property] === undefined) {
throw new Error('Object "' + object + '" has no property "' + property + '"');
}
var controller = void 0;
if (params.color) {
controller = new _ColorController2.default(object, property);
} else {
var factoryArgs = [object, property].concat(params.factoryArgs);
controller = _ControllerFactory2.default.apply(gui, factoryArgs);
}
if (params.before instanceof _Controller2.default) {
params.before = params.before.__li;
}
recallSavedValue(gui, controller);
_dom2.default.addClass(controller.domElement, 'c');
var name = document.createElement('span');
_dom2.default.addClass(name, 'property-name');
name.innerHTML = controller.property;
var container = document.createElement('div');
container.appendChild(name);
container.appendChild(controller.domElement);
var li = addRow(gui, container, params.before);
_dom2.default.addClass(li, GUI.CLASS_CONTROLLER_ROW);
if (controller instanceof _ColorController2.default) {
_dom2.default.addClass(li, 'color');
} else {
_dom2.default.addClass(li, _typeof(controller.getValue()));
}
augmentController(gui, li, controller);
gui.__controllers.push(controller);
return controller;
}
function getLocalStorageHash(gui, key) {
// TODO how does this deal with multiple GUI's?
return document.location.href + '.' + key;
}
function addPresetOption(gui, name, setSelected) {
var opt = document.createElement('option');
opt.innerHTML = name;
opt.value = name;
gui.__preset_select.appendChild(opt);
if (setSelected) {
gui.__preset_select.selectedIndex = gui.__preset_select.length - 1;
}
}
function showHideExplain(gui, explain) {
explain.style.display = gui.useLocalStorage ? 'block' : 'none';
}
function addSaveMenu(gui) {
var div = gui.__save_row = document.createElement('li');
_dom2.default.addClass(gui.domElement, 'has-save');
gui.__ul.insertBefore(div, gui.__ul.firstChild);
_dom2.default.addClass(div, 'save-row');
var gears = document.createElement('span');
gears.innerHTML = '&nbsp;';
_dom2.default.addClass(gears, 'button gears');
// TODO replace with FunctionController
var button = document.createElement('span');
button.innerHTML = 'Save';
_dom2.default.addClass(button, 'button');
_dom2.default.addClass(button, 'save');
var button2 = document.createElement('span');
button2.innerHTML = 'New';
_dom2.default.addClass(button2, 'button');
_dom2.default.addClass(button2, 'save-as');
var button3 = document.createElement('span');
button3.innerHTML = 'Revert';
_dom2.default.addClass(button3, 'button');
_dom2.default.addClass(button3, 'revert');
var select = gui.__preset_select = document.createElement('select');
if (gui.load && gui.load.remembered) {
_common2.default.each(gui.load.remembered, function (value, key) {
addPresetOption(gui, key, key === gui.preset);
});
} else {
addPresetOption(gui, DEFAULT_DEFAULT_PRESET_NAME, false);
}
_dom2.default.bind(select, 'change', function () {
for (var index = 0; index < gui.__preset_select.length; index++) {
gui.__preset_select[index].innerHTML = gui.__preset_select[index].value;
}
gui.preset = this.value;
});
div.appendChild(select);
div.appendChild(gears);
div.appendChild(button);
div.appendChild(button2);
div.appendChild(button3);
if (SUPPORTS_LOCAL_STORAGE) {
var explain = document.getElementById('dg-local-explain');
var localStorageCheckBox = document.getElementById('dg-local-storage');
var saveLocally = document.getElementById('dg-save-locally');
saveLocally.style.display = 'block';
if (localStorage.getItem(getLocalStorageHash(gui, 'isLocal')) === 'true') {
localStorageCheckBox.setAttribute('checked', 'checked');
}
showHideExplain(gui, explain);
// TODO: Use a boolean controller, fool!
_dom2.default.bind(localStorageCheckBox, 'change', function () {
gui.useLocalStorage = !gui.useLocalStorage;
showHideExplain(gui, explain);
});
}
var newConstructorTextArea = document.getElementById('dg-new-constructor');
_dom2.default.bind(newConstructorTextArea, 'keydown', function (e) {
if (e.metaKey && (e.which === 67 || e.keyCode === 67)) {
SAVE_DIALOGUE.hide();
}
});
_dom2.default.bind(gears, 'click', function () {
newConstructorTextArea.innerHTML = JSON.stringify(gui.getSaveObject(), undefined, 2);
SAVE_DIALOGUE.show();
newConstructorTextArea.focus();
newConstructorTextArea.select();
});
_dom2.default.bind(button, 'click', function () {
gui.save();
});
_dom2.default.bind(button2, 'click', function () {
var presetName = prompt('Enter a new preset name.');
if (presetName) {
gui.saveAs(presetName);
}
});
_dom2.default.bind(button3, 'click', function () {
gui.revert();
});
// div.appendChild(button2);
}
function addResizeHandle(gui) {
var pmouseX = void 0;
gui.__resize_handle = document.createElement('div');
_common2.default.extend(gui.__resize_handle.style, {
width: '6px',
marginLeft: '-3px',
height: '200px',
cursor: 'ew-resize',
position: 'absolute'
// border: '1px solid blue'
});
function drag(e) {
e.preventDefault();
gui.width += pmouseX - e.clientX;
gui.onResize();
pmouseX = e.clientX;
return false;
}
function dragStop() {
_dom2.default.removeClass(gui.__closeButton, GUI.CLASS_DRAG);
_dom2.default.unbind(window, 'mousemove', drag);
_dom2.default.unbind(window, 'mouseup', dragStop);
}
function dragStart(e) {
e.preventDefault();
pmouseX = e.clientX;
_dom2.default.addClass(gui.__closeButton, GUI.CLASS_DRAG);
_dom2.default.bind(window, 'mousemove', drag);
_dom2.default.bind(window, 'mouseup', dragStop);
return false;
}
_dom2.default.bind(gui.__resize_handle, 'mousedown', dragStart);
_dom2.default.bind(gui.__closeButton, 'mousedown', dragStart);
gui.domElement.insertBefore(gui.__resize_handle, gui.domElement.firstElementChild);
}
function setWidth(gui, w) {
gui.domElement.style.width = w + 'px';
// Auto placed save-rows are position fixed, so we have to
// set the width manually if we want it to bleed to the edge
if (gui.__save_row && gui.autoPlace) {
gui.__save_row.style.width = w + 'px';
}
if (gui.__closeButton) {
gui.__closeButton.style.width = w + 'px';
}
}
function getCurrentPreset(gui, useInitialValues) {
var toReturn = {};
// For each object I'm remembering
_common2.default.each(gui.__rememberedObjects, function (val, index) {
var savedValues = {};
// The controllers I've made for thcommon.isObject by property
var controllerMap = gui.__rememberedObjectIndecesToControllers[index];
// Remember each value for each property
_common2.default.each(controllerMap, function (controller, property) {
savedValues[property] = useInitialValues ? controller.initialValue : controller.getValue();
});
// Save the values for thcommon.isObject
toReturn[index] = savedValues;
});
return toReturn;
}
function setPresetSelectIndex(gui) {
for (var index = 0; index < gui.__preset_select.length; index++) {
if (gui.__preset_select[index].value === gui.preset) {
gui.__preset_select.selectedIndex = index;
}
}
}
function updateDisplays(controllerArray) {
if (controllerArray.length !== 0) {
_requestAnimationFrame2.default.call(window, function () {
updateDisplays(controllerArray);
});
}
_common2.default.each(controllerArray, function (c) {
c.updateDisplay();
});
}
exports.default = GUI;
module.exports = exports['default'];
/***/ },
/* 18 */
/***/ function(module, exports) {
'use strict';
/**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
module.exports = {
load: function load(url, indoc) {
var doc = indoc || document;
var link = doc.createElement('link');
link.type = 'text/css';
link.rel = 'stylesheet';
link.href = url;
doc.getElementsByTagName('head')[0].appendChild(link);
},
inject: function inject(css, indoc) {
var doc = indoc || document;
var injected = document.createElement('style');
injected.type = 'text/css';
injected.innerHTML = css;
var head = doc.getElementsByTagName('head')[0];
try {
head.appendChild(injected);
} catch (e) {// Unable to inject CSS, probably because of a Content Security Policy
}
}
};
/***/ },
/* 19 */
/***/ function(module, exports) {
module.exports = "<div id=\"dg-save\" class=\"dg dialogue\">\n\n Here's the new load parameter for your <code>GUI</code>'s constructor:\n\n <textarea id=\"dg-new-constructor\"></textarea>\n\n <div id=\"dg-save-locally\">\n\n <input id=\"dg-local-storage\" type=\"checkbox\"/> Automatically save\n values to <code>localStorage</code> on exit.\n\n <div id=\"dg-local-explain\">The values saved to <code>localStorage</code> will\n override those passed to <code>dat.GUI</code>'s constructor. This makes it\n easier to work incrementally, but <code>localStorage</code> is fragile,\n and your friends may not see the same values you do.\n\n </div>\n\n </div>\n\n</div>";
/***/ },
/* 20 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.__esModule = true;
var _OptionController = __webpack_require__(10);
var _OptionController2 = _interopRequireDefault(_OptionController);
var _NumberControllerBox = __webpack_require__(13);
var _NumberControllerBox2 = _interopRequireDefault(_NumberControllerBox);
var _NumberControllerSlider = __webpack_require__(14);
var _NumberControllerSlider2 = _interopRequireDefault(_NumberControllerSlider);
var _StringController = __webpack_require__(11);
var _StringController2 = _interopRequireDefault(_StringController);
var _FunctionController = __webpack_require__(15);
var _FunctionController2 = _interopRequireDefault(_FunctionController);
var _BooleanController = __webpack_require__(8);
var _BooleanController2 = _interopRequireDefault(_BooleanController);
var _common = __webpack_require__(5);
var _common2 = _interopRequireDefault(_common);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var ControllerFactory = function ControllerFactory(object, property) {
var initialValue = object[property];
// Providing options?
if (_common2.default.isArray(arguments[2]) || _common2.default.isObject(arguments[2])) {
return new _OptionController2.default(object, property, arguments[2]);
}
// Providing a map?
if (_common2.default.isNumber(initialValue)) {
// Has min and max? (slider)
if (_common2.default.isNumber(arguments[2]) && _common2.default.isNumber(arguments[3])) {
// has step?
if (_common2.default.isNumber(arguments[4])) {
return new _NumberControllerSlider2.default(object, property, arguments[2], arguments[3], arguments[4]);
}
return new _NumberControllerSlider2.default(object, property, arguments[2], arguments[3]);
}
// number box
if (_common2.default.isNumber(arguments[4])) {
// has step
return new _NumberControllerBox2.default(object, property, { min: arguments[2], max: arguments[3], step: arguments[4] });
}
return new _NumberControllerBox2.default(object, property, { min: arguments[2], max: arguments[3] });
}
if (_common2.default.isString(initialValue)) {
return new _StringController2.default(object, property);
}
if (_common2.default.isFunction(initialValue)) {
return new _FunctionController2.default(object, property, '');
}
if (_common2.default.isBoolean(initialValue)) {
return new _BooleanController2.default(object, property);
}
return null;
}; /**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
exports.default = ControllerFactory;
module.exports = exports['default'];
/***/ },
/* 21 */
/***/ function(module, exports) {
"use strict";
exports.__esModule = true;
/**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
function requestAnimationFrame(callback) {
setTimeout(callback, 1000 / 60);
}
exports.default = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || requestAnimationFrame;
module.exports = exports["default"];
/***/ },
/* 22 */
/***/ function(module, exports, __webpack_require__) {
'use strict';
exports.__esModule = true;
var _dom = __webpack_require__(9);
var _dom2 = _interopRequireDefault(_dom);
var _common = __webpack_require__(5);
var _common2 = _interopRequireDefault(_common);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /**
* dat-gui JavaScript Controller Library
* http://code.google.com/p/dat-gui
*
* Copyright 2011 Data Arts Team, Google Creative Lab
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*/
var CenteredDiv = function () {
function CenteredDiv() {
_classCallCheck(this, CenteredDiv);
this.backgroundElement = document.createElement('div');
_common2.default.extend(this.backgroundElement.style, {
backgroundColor: 'rgba(0,0,0,0.8)',
top: 0,
left: 0,
display: 'none',
zIndex: '1000',
opacity: 0,
WebkitTransition: 'opacity 0.2s linear',
transition: 'opacity 0.2s linear'
});
_dom2.default.makeFullscreen(this.backgroundElement);
this.backgroundElement.style.position = 'fixed';
this.domElement = document.createElement('div');
_common2.default.extend(this.domElement.style, {
position: 'fixed',
display: 'none',
zIndex: '1001',
opacity: 0,
WebkitTransition: '-webkit-transform 0.2s ease-out, opacity 0.2s linear',
transition: 'transform 0.2s ease-out, opacity 0.2s linear'
});
document.body.appendChild(this.backgroundElement);
document.body.appendChild(this.domElement);
var _this = this;
_dom2.default.bind(this.backgroundElement, 'click', function () {
_this.hide();
});
}
CenteredDiv.prototype.show = function show() {
var _this = this;
this.backgroundElement.style.display = 'block';
this.domElement.style.display = 'block';
this.domElement.style.opacity = 0;
// this.domElement.style.top = '52%';
this.domElement.style.webkitTransform = 'scale(1.1)';
this.layout();
_common2.default.defer(function () {
_this.backgroundElement.style.opacity = 1;
_this.domElement.style.opacity = 1;
_this.domElement.style.webkitTransform = 'scale(1)';
});
};
/**
* Hide centered div
*/
CenteredDiv.prototype.hide = function hide() {
var _this = this;
var hide = function hide() {
_this.domElement.style.display = 'none';
_this.backgroundElement.style.display = 'none';
_dom2.default.unbind(_this.domElement, 'webkitTransitionEnd', hide);
_dom2.default.unbind(_this.domElement, 'transitionend', hide);
_dom2.default.unbind(_this.domElement, 'oTransitionEnd', hide);
};
_dom2.default.bind(this.domElement, 'webkitTransitionEnd', hide);
_dom2.default.bind(this.domElement, 'transitionend', hide);
_dom2.default.bind(this.domElement, 'oTransitionEnd', hide);
this.backgroundElement.style.opacity = 0;
// this.domElement.style.top = '48%';
this.domElement.style.opacity = 0;
this.domElement.style.webkitTransform = 'scale(1.1)';
};
CenteredDiv.prototype.layout = function layout() {
this.domElement.style.left = window.innerWidth / 2 - _dom2.default.getWidth(this.domElement) / 2 + 'px';
this.domElement.style.top = window.innerHeight / 2 - _dom2.default.getHeight(this.domElement) / 2 + 'px';
};
return CenteredDiv;
}();
exports.default = CenteredDiv;
module.exports = exports['default'];
/***/ },
/* 23 */
/***/ function(module, exports, __webpack_require__) {
exports = module.exports = __webpack_require__(24)();
// imports
// module
exports.push([module.id, ".dg {\n /** Clear list styles */\n /* Auto-place container */\n /* Auto-placed GUI's */\n /* Line items that don't contain folders. */\n /** Folder names */\n /** Hides closed items */\n /** Controller row */\n /** Name-half (left) */\n /** Controller-half (right) */\n /** Controller placement */\n /** Shorter number boxes when slider is present. */\n /** Ensure the entire boolean and function row shows a hand */\n /** allow overflow for color selector */ }\n .dg ul {\n list-style: none;\n margin: 0;\n padding: 0;\n width: 100%;\n clear: both; }\n .dg.ac {\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n height: 0;\n z-index: 0; }\n .dg:not(.ac) .main {\n /** Exclude mains in ac so that we don't hide close button */\n overflow: hidden; }\n .dg.main {\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear; }\n .dg.main.taller-than-window {\n overflow-y: auto; }\n .dg.main.taller-than-window .close-button {\n opacity: 1;\n /* TODO, these are style notes */\n margin-top: -1px;\n border-top: 1px solid #2c2c2c; }\n .dg.main ul.closed .close-button {\n opacity: 1 !important; }\n .dg.main:hover .close-button,\n .dg.main .close-button.drag {\n opacity: 1; }\n .dg.main .close-button {\n /*opacity: 0;*/\n -webkit-transition: opacity 0.1s linear;\n -o-transition: opacity 0.1s linear;\n -moz-transition: opacity 0.1s linear;\n transition: opacity 0.1s linear;\n border: 0;\n line-height: 19px;\n height: 20px;\n /* TODO, these are style notes */\n cursor: pointer;\n text-align: center;\n background-color: #000; }\n .dg.main .close-button.close-top {\n position: relative; }\n .dg.main .close-button.close-bottom {\n position: absolute; }\n .dg.main .close-button:hover {\n background-color: #111; }\n .dg.a {\n float: right;\n margin-right: 15px;\n overflow-y: visible; }\n .dg.a.has-save > ul.close-top {\n margin-top: 0; }\n .dg.a.has-save > ul.close-bottom {\n margin-top: 27px; }\n .dg.a.has-save > ul.closed {\n margin-top: 0; }\n .dg.a .save-row {\n top: 0;\n z-index: 1002; }\n .dg.a .save-row.close-top {\n position: relative; }\n .dg.a .save-row.close-bottom {\n position: fixed; }\n .dg li {\n -webkit-transition: height 0.1s ease-out;\n -o-transition: height 0.1s ease-out;\n -moz-transition: height 0.1s ease-out;\n transition: height 0.1s ease-out;\n -webkit-transition: overflow 0.1s linear;\n -o-transition: overflow 0.1s linear;\n -moz-transition: overflow 0.1s linear;\n transition: overflow 0.1s linear; }\n .dg li:not(.folder) {\n cursor: auto;\n height: 27px;\n line-height: 27px;\n padding: 0 4px 0 5px; }\n .dg li.folder {\n padding: 0;\n border-left: 4px solid transparent; }\n .dg li.title {\n cursor: pointer;\n margin-left: -4px; }\n .dg .closed li:not(.title),\n .dg .closed ul li,\n .dg .closed ul li > * {\n height: 0;\n overflow: hidden;\n border: 0; }\n .dg .cr {\n clear: both;\n padding-left: 3px;\n height: 27px;\n overflow: hidden; }\n .dg .property-name {\n cursor: default;\n float: left;\n clear: left;\n width: 40%;\n overflow: hidden;\n text-overflow: ellipsis; }\n .dg .c {\n float: left;\n width: 60%;\n position: relative; }\n .dg .c input[type=text] {\n border: 0;\n margin-top: 4px;\n padding: 3px;\n width: 100%;\n float: right; }\n .dg .has-slider input[type=text] {\n width: 30%;\n /*display: none;*/\n margin-left: 0; }\n .dg .slider {\n float: left;\n width: 66%;\n margin-left: -5px;\n margin-right: 0;\n height: 19px;\n margin-top: 4px; }\n .dg .slider-fg {\n height: 100%; }\n .dg .c input[type=checkbox] {\n margin-top: 7px; }\n .dg .c select {\n margin-top: 5px; }\n .dg .cr.function,\n .dg .cr.function .property-name,\n .dg .cr.function *,\n .dg .cr.boolean,\n .dg .cr.boolean * {\n cursor: pointer; }\n .dg .cr.color {\n overflow: visible; }\n .dg .selector {\n display: none;\n position: absolute;\n margin-left: -9px;\n margin-top: 23px;\n z-index: 10; }\n .dg .c:hover .selector,\n .dg .selector.drag {\n display: block; }\n .dg li.save-row {\n padding: 0; }\n .dg li.save-row .button {\n display: inline-block;\n padding: 0px 6px; }\n .dg.dialogue {\n background-color: #222;\n width: 460px;\n padding: 15px;\n font-size: 13px;\n line-height: 15px; }\n\n/* TODO Separate style and structure */\n#dg-new-constructor {\n padding: 10px;\n color: #222;\n font-family: Monaco, monospace;\n font-size: 10px;\n border: 0;\n resize: none;\n box-shadow: inset 1px 1px 1px #888;\n word-wrap: break-word;\n margin: 12px 0;\n display: block;\n width: 440px;\n overflow-y: scroll;\n height: 100px;\n position: relative; }\n\n#dg-local-explain {\n display: none;\n font-size: 11px;\n line-height: 17px;\n border-radius: 3px;\n background-color: #333;\n padding: 8px;\n margin-top: 10px; }\n #dg-local-explain code {\n font-size: 10px; }\n\n#dat-gui-save-locally {\n display: none; }\n\n/** Main type */\n.dg {\n color: #eee;\n font: 11px 'Lucida Grande', sans-serif;\n text-shadow: 0 -1px 0 #111;\n /** Auto place */\n /* Controller row, <li> */\n /** Controllers */ }\n .dg.main {\n /** Scrollbar */ }\n .dg.main::-webkit-scrollbar {\n width: 5px;\n background: #1a1a1a; }\n .dg.main::-webkit-scrollbar-corner {\n height: 0;\n display: none; }\n .dg.main::-webkit-scrollbar-thumb {\n border-radius: 5px;\n background: #676767; }\n .dg li:not(.folder) {\n background: #1a1a1a;\n border-bottom: 1px solid #2c2c2c; }\n .dg li.save-row {\n line-height: 25px;\n background: #dad5cb;\n border: 0; }\n .dg li.save-row select {\n margin-left: 5px;\n width: 108px; }\n .dg li.save-row .button {\n margin-left: 5px;\n margin-top: 1px;\n border-radius: 2px;\n font-size: 9px;\n line-height: 7px;\n padding: 4px 4px 5px 4px;\n background: #c5bdad;\n color: #fff;\n text-shadow: 0 1px 0 #b0a58f;\n box-shadow: 0 -1px 0 #b0a58f;\n cursor: pointer; }\n .dg li.save-row .button.gears {\n background: #c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;\n height: 7px;\n width: 8px; }\n .dg li.save-row .button:hover {\n background-color: #bab19e;\n box-shadow: 0 -1px 0 #b0a58f; }\n .dg li.folder {\n border-bottom: 0; }\n .dg li.title {\n padding-left: 16px;\n background: #000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;\n cursor: pointer;\n border-bottom: 1px solid rgba(255, 255, 255, 0.2); }\n .dg .closed li.title {\n background-image: url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==); }\n .dg .cr.boolean {\n border-left: 3px solid #806787; }\n .dg .cr.color {\n border-left: 3px solid; }\n .dg .cr.function {\n border-left: 3px solid #e61d5f; }\n .dg .cr.number {\n border-left: 3px solid #2FA1D6; }\n .dg .cr.number input[type=text] {\n color: #2FA1D6; }\n .dg .cr.string {\n border-left: 3px solid #1ed36f; }\n .dg .cr.string input[type=text] {\n color: #1ed36f; }\n .dg .cr.function:hover, .dg .cr.boolean:hover {\n background: #111; }\n .dg .c input[type=text] {\n background: #303030;\n outline: none; }\n .dg .c input[type=text]:hover {\n background: #3c3c3c; }\n .dg .c input[type=text]:focus {\n background: #494949;\n color: #fff; }\n .dg .c .slider {\n background: #303030;\n cursor: ew-resize; }\n .dg .c .slider-fg {\n background: #2FA1D6;\n max-width: 100%; }\n .dg .c .slider:hover {\n background: #3c3c3c; }\n .dg .c .slider:hover .slider-fg {\n background: #44abda; }\n", ""]);
// exports
/***/ },
/* 24 */
/***/ function(module, exports) {
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
// css base code, injected by the css-loader
module.exports = function() {
var list = [];
// return the list of modules as css string
list.toString = function toString() {
var result = [];
for(var i = 0; i < this.length; i++) {
var item = this[i];
if(item[2]) {
result.push("@media " + item[2] + "{" + item[1] + "}");
} else {
result.push(item[1]);
}
}
return result.join("");
};
// import a list of modules into the list
list.i = function(modules, mediaQuery) {
if(typeof modules === "string")
modules = [[null, modules, ""]];
var alreadyImportedModules = {};
for(var i = 0; i < this.length; i++) {
var id = this[i][0];
if(typeof id === "number")
alreadyImportedModules[id] = true;
}
for(i = 0; i < modules.length; i++) {
var item = modules[i];
// skip already imported module
// this implementation is not 100% perfect for weird media query combinations
// when a module is imported multiple times with different media queries.
// I hope this will never occur (Hey this way we have smaller bundles)
if(typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) {
if(mediaQuery && !item[2]) {
item[2] = mediaQuery;
} else if(mediaQuery) {
item[2] = "(" + item[2] + ") and (" + mediaQuery + ")";
}
list.push(item);
}
}
};
return list;
};
/***/ }
/******/ ])
});
;
//# sourceMappingURL=dat.gui.js.map
MIT License
Copyright (c) 2016
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.
/******************************************
* @muonAnimation
*
**/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.muonAnimation = global.muonAnimation || {})))
}(this, function (exports) { "use strict"
let muonAnimation = function muonAnimation(__mapper) {
let f = __mapper("props")()
let state = {}
state.animas = [] // global animas
/*******************************************
*
* @ANIMATION
*
**/
let aniListener = function aniListener(elapsed) {
state.animas = f.a(__mapper("muonStore").animasLive() )
/*******************************************
* @TIME
*/
state.animas = f.a(__mapper("muonStore").animasLive() )
for (let i=0; i<state.animas.length; i++) {
let anima = state.animas[i]
anima.tim = __mapper("bosonTim")(anima.tim, elapsed) // set time
if (elapsed > anima.tim.limit) {
anima.delled = 1 // crop by time
}
}
/*******************************************
* @STOP
*/
let maxlimit = state.animas.reduce((pre,item) => Math.max(pre,item.tim.limit),0)
if (isNaN(maxlimit)) state.animationStop()
if (maxlimit > 0 && elapsed > maxlimit) state.animationStop() // stop if spired
if (elapsed > maxlimit) state.animationStop() // stop if anigrams spired
/*******************************************
* @WEEN generate animas and offsprings
*/
for (let i=0; i<state.animas.length; i++) {
let anima = state.animas[i] // each anima in animas live
let newAnimas = __mapper("xs").m("store").ween(anima)
__mapper("xs").m("store").apply({"type":"UPDANIMA","caller":"alima","animas":newAnimas})
}
state.animas = f.a(__mapper("muonStore").animasLive() )
/*******************************************
* @SIM defaults position of nodes
*/
let sim = __mapper("xs").m("simulation").sim()
state.animas = __mapper("xs").m("simulation").simulate(sim, state.animas, elapsed)
/*******************************************
* @GRAMN animas to anigrams
*/
for (let i=0; i<state.animas.length; i++) {
let newAnigrams = __mapper("xs").m("store").gramn(state.animas[i]) /* GRAMN */
__mapper("xs").m("store").apply({"type":"UPDANIGRAM","caller":"store","anigrams":f.a(newAnigrams)})
}
let anigrams = __mapper("xs").m("store").anigrams()
/*******************************************
* @FPS
*/
if (__mapper("muonfps") && __mapper("muonfps").inited()) __mapper("muonfps").addloop()
/*******************************************
* @RENDER
*/
if (__mapper("renderSVG") !== undefined) __mapper("renderSVG").render(elapsed, anigrams)
if (__mapper("renderWebgl") !== undefined) __mapper("renderWebgl").render(elapsed, anigrams )
if (__mapper("renderCanvas") !== undefined) __mapper("renderCanvas").render(elapsed, anigrams )
}
/*******************************************
* @LISTENER
*/
if (state.animationStop === undefined) state.animationStop = __mapper("xs").c("timer").subscribe(aniListener)
/*******************************************
* @enty
*/
function enty() {}
enty.animationStop = () => state.animationStop
return enty
}
exports.muonAnimation = muonAnimation
}));
/***********
* @muonAnitem
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.muonAnitem = global.muonAnitem || {})))
}(this, function (exports) { "use strict"
var muonAnitem = function muonAnitem(__mapper = {}) {
let f = __mapper("props")()
/***************************************
* @anitem
*
*/
let anitem = {}
let setAnitem = function (d = {}) {
let a = anitem = {}
// if (d && d.form // form:{x,y,z}
// && typeof d.form === "object"
// && ( d.form.x !== undefined && d.form.y !== undefined && d.form.z !== undefined )) {
// a.form = d.form
// } else if (d // form:{}
// && d.form
// && typeof d.form === "object"
// && ( d.form.x === undefined && d.form.y === undefined && d.form.z === undefined )) {
// a.form = {}
// a.form.x = Object.assign( {}, d.form, {fas8: (d.form.fas8 || 0)} ) // set fas8 0
// a.form.y = Object.assign( {}, (d.form.y || d.form) , {fas8: d.form.fas8 - 90})
// a.form.z = Object.assign( {}, (d.form.z || d.form) )
// } else if (d // form:{x:}
// && d.form
// && typeof d.form === "object"
// && ( d.form.x !== undefined || d.form.y !== undefined || d.form.z !== undefined )) {
// a.form = {}
// a.form.x = Object.assign({}, d.form.x ) // defined
// a.form.y = Object.assign({}, (d.form.y || d.form.x) , {fas8: d.form.x.fas8 - 90})
// a.form.z = Object.assign({}, (d.form.z || d.form.x) )
// } else if (d // form:[{},{},{}]
// && d.form
// && Array.isArray(d.form)) {
// a.form = {}
// a.form.x = d.form[0]
// a.form.y = d.form[1] || Object.assign({}, d.form[0], {fas8: d.form.fas8 - 90})
// a.form.z = d.form[2] || Object.assign({}, d.form[0])
// } else {
// a.form = {}
// a.form.x = {}
// a.form.y = {}
// a.form.z = {}
// }
let c = {
stace: f.v((d||{}).stace), // stace: {a,b,c}
avatars: d.avatars, // avatars: {}
fields: d.fields, // fields: {pic, field}
form: d.form,
from: d.from, // from form in tern
fuel: d.fuel, // fuel
ereform: (d||{}).ereform, // ereform()
geoform: (d||{}).geoform, // geoform()
geometry: d.geometry, // geometry -- from f.gramn
graticule: d.graticule, // extent: {}
payload: d.payload, // {initN,eventN,autoN,autoP,outed,maxN}
nums: d.nums, // {ra2, pos, fas, step, dist, div, mod, z}
parent: d.parent || {}, // parent - default to empty object
parentuid: d.parentuid, // parentuid
pic: d, // pic:{}
coform: d.coform, // projection, scale, translate, rotate
conform: d.conform,
proform: d.proform, // projection, scale, translate, rotate
reticule: d.reticule, //
msg: d.msg, //
ric: d.ric, // {type, gid, cid, fid}
tim: d.tim, // tim: {t0,t1,t2,t3}
to: d.to, // to form in tern
trace: d.trace, // trace: {hquan, hmod}
boform: d.boform, // {csx,cf,cs,cw
voro: d.voro, // {hsamp, f, t}
vorts: d.vorts, // {pos,fas,step,dist,div,mod,z}
halo: d.halo, // d.halo, //
nid: d.nid, // nid
uid: d.uid, // uid
x: d.x, //
y: d.y, //
z: d.z, //
sort: d.sort, // sort
}
a = Object.assign(a, c)
return a
}
/***************************************
* getNode
*
*/
let getNode = function getNode(aniState = {}) {
let node = {
x: aniState.x,
y: aniState.y,
z: aniState.z,
_x: aniState._x, // past location
_y: aniState._y, // past location
_z: aniState._z, // past location
vx: aniState.vx,
vy: aniState.vy,
vz: aniState.vz,
}
return node
}
/***********
* @enty
*/
let enty = function( anima, t ) {
let anigram = {}
if (anima !== undefined) {
if (t !== undefined) {
anigram = __mapper("xs").b("snap")(anima, t)
} else if (anima.tim.unitTime !== undefined) {
let t = anima.tim.unitTime
anigram = __mapper("xs").b("snap")(anima, t)
}
setAnitem(anigram)
}
return enty
}
enty.anigram = (ani,t) => {
if (ani !== undefined) { // if give anima
if (t !== undefined) { // if given time
ani = __mapper("xs").b("snap")(ani, t) // anima snap to anigram
}
setAnitem(ani) // build anitem
}
return anitem // give anitem back
}
enty.getNode = getNode // anitem => node
enty.conform = (_) => { return _ !== undefined ? (anitem.conform = _, anitem) : anitem.conform }
enty.conform$2 = (_) => { return _ !== undefined ? (anitem.conform = _, anitem) : (delete anitem.conform.z, anitem.conform)}
enty.form = (_) => { return _ !== undefined ? (anitem.form = _, anitem) : anitem.form }
enty.form$2 = (_) => { return _ !== undefined ? (anitem.form = _, anitem) : (delete anitem.form.z, anitem.form)}
enty.from = (_) => { return _ !== undefined ? (anitem.from = _, anitem) : anitem.from }
enty.fuel = (_) => { return _ !== undefined ? (anitem.fuel = _, anitem) : anitem.fuel }
enty.ereform = (_) => { return _ !== undefined ? (anitem.ereform = _, anitem) : anitem.ereform }
enty.geoform = (_) => { return _ !== undefined ? (anitem.geoform = _, anitem) : anitem.geoform }
enty.graticule = (_) => { return _ !== undefined ? (anitem.graticule = _, anitem) : anitem.graticule }
enty.nums = (_) => { return _ !== undefined ? (anitem.nums = _, anitem) : anitem.nums }
enty.payload = (_) => { return _ !== undefined ? (anitem.payload = _, anitem) : anitem.payload }
enty.proform = (_) => { return _ !== undefined ? (anitem.proform = _, anitem) : anitem.proform }
enty.reticule = (_) => { return _ !== undefined ? (anitem.reticule = _, anitem) : anitem.reticule }
enty.ric = (_) => { return _ !== undefined ? (anitem.ric = _, anitem) : anitem.ric }
enty.stace = (_) => { return _ !== undefined ? (anitem.stace = _, anitem) : anitem.stace }
enty.tim = (_) => { return _ !== undefined ? (anitem.tim = _, anitem) : anitem.tim }
enty.boform = (_) => { return _ !== undefined ? (anitem.boform = _, anitem) : anitem.boform }
enty.trace = (_) => { return _ !== undefined ? (anitem.trace = _, anitem) : anitem.trace }
enty.to = (_) => { return _ !== undefined ? (anitem.to = _, anitem) : anitem.to }
enty.avatars = (_) => { return _ !== undefined ? (anitem.avatars = _, anitem) : anitem.avatars }
enty.parent = (_) => { return _ !== undefined ? (anitem.parent = _, anitem) : anitem.parent }
enty.segs = () => {
let segs = 0
segs = Math.max((anitem.form.x.seg5 || 0), segs)
segs = Math.max((anitem.form.y.seg5 || 0), segs)
segs = Math.max(((anitem.form.z||{}).seg5 || 0), segs)
return segs
}
return enty
}
exports.muonAnitem = muonAnitem
}))
/***********
* @muongeoj
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.muongeoj = global.muongeoj || {})))
}(this, function (exports) { "use strict"
// ref: https://bl.ocks.org/maartenzam/ec11de22bc8e5608a98f207f1c09bdb6
let muongeoj = function muongeoj(__mapper = {}) {
let f = __mapper("props")()
/**********************
* @resample
* Mike Bostock’s Block bfe064713436955c1ace
* Updated August 4, 2017
* Takes a sparse line string that assumes Cartesian interpolation in spherical
* coordinates and inserts interstitial points for greater accuracy when
* rendering with D3, which assumes spherical interpolation.
*/
let resample = function (coordinates) {
let i = 0,
j = -1,
n = coordinates.length,
source = coordinates.slice(),
p0, x0, y0,
p1 = coordinates[0], x1 = p1[0], y1 = p1[1],
dx, dy, d2,
m2 = 10 // squared minimum angular distance
while (++i < n) {
p0 = p1, x0 = x1, y0 = y1
p1 = source[i], x1 = p1[0], y1 = p1[1]
dx = x1 - x0, dy = y1 - y0, d2 = dx * dx + dy * dy
coordinates[++j] = p0
if (d2 > m2) for (let k = 1, m = Math.ceil(Math.sqrt(d2 / m2)); k < m; ++k) {
coordinates[++j] = [x0 + dx * k / m, y0 + dy * k / m]
}
}
coordinates[++j] = p1
coordinates.length = j + 1
}
/**********************
* @trim
*/
// Maarten
// Released under the The MIT License.
// ref: https://bl.ocks.org/maartenzam/ec11de22bc8e5608a98f207f1c09bdb6
let trim = function trim(json) {
let ret = {}
if (json.type === "FeatureCollection") {
ret.type = "FeatureCollection"
ret.features = []
for (let i=0; i<json.features.length; i++) {
let newFeature = {}
let feature = json.features[i]
newFeature.type = "Feature"
newFeature.properties = feature.properties
newFeature.geometry = {}
newFeature.geometry.coordinates = []
for (let j=0; j< feature.geometry.coordinates.length ; j++) { // geometries in feature array
let coords = largestPoly(feature.geometry.coordinates[j])
newFeature.geometry.type = "MultiPolygon"
newFeature.geometry.coordinates[j] = coords
}
ret.features[i] = Object.assign({}, newFeature)
}
} else if (json.type === "MultiLineString") {
ret = json
} else {
ret = json
}
return ret
}
/**********************
* @snip
* return dots segment
*/
let snip = function(form) {
let dims = __mapper("xs").m("stace").dims()
let braids = []
return function(json) {
let c = json.coordinates
for (let i=0; i < c.length; i++) {
let braid = f.unslide(c[i])
for (let j=0; j<braid.length; j++) {
let pa6 = (form[dims[j]] || {}).pa6
let pb7 = (form[dims[j]] || {}).pb7
braids[j] = f.streamRange(braid[j], pa6, pb7)
}
let coordinates = f.slide(braids) // join dim threads
json.coordinates = Array.of(coordinates)
}
return json
}
}
/**********************
* @largestPoly
*/
//polys: d.geometry object (GeoJSON)
let largestPoly = function largestPoly(json) {
let size = -Number.MAX_VALUE,
poly = null
for (let c = 0; c < json.length; c++) {
let tsize = (json.type === "MultiPolygon") ? d3.polygonArea(json[c][0]) : d3.polygonArea(json[c])
if (tsize > size) {
size = tsize
poly = c
}
}
return [json.type === "MultiPolygon" ? json[poly][0] : json[poly]]
}
let lineStringFromStream = function (coords, reverse = false, props={}) {
let geo = {}
geo.type = "LineString"
geo.coordinates = coords
geo.properties = props
return geo
}
let polygonFromStream = function (coords, reverse = false, props={}) {
if (reverse === true) coords = coords.slice().reverse()
let geo = {}
geo.type = "Polygon"
geo.coordinates = [coords]
geo.properties = props
return geo
}
let multLineStringFromStreamArray = function (coords, reverse = false, props={}) {
if (reverse === true) coords = coords.slice().reverse()
let geo = {}
geo.type = "MultiLineString"
geo.coordinates = coords
geo.properties = props
return geo
}
/**********************
* @geojize
*/
let geojize = function (anigrams) {
let features = []
for (let i=0; i<anigrams.length; i++) {
let anigram = anigrams[i]
let boform = anigram.boform
let feature = anigram.feature
feature.id = anigram.uid
let properties = feature.properties
properties.ric = anigram.ric
properties.sort = anigram.sort
properties.delled = anigram.delled
properties.pointRadius = properties.pointRadius
properties.hquan = undefined // geom items
properties.hmod = undefined //
let attr = properties.attr || {} // alima position
if (anigram.x) attr.x = anigram.x
if (anigram.y) attr.y = anigram.y
if (anigram.z) attr.z = anigram.z
properties.attr = attr
let style = properties.style || {}
style["fill"] = f.kolor(boform.cf,boform.csx)
style["stroke"] = f.kolor(boform.cs,boform.csx)
style["fill-opacity"] = boform.co
style["stroke-width"] = boform.cw
style["stroke-opacity"] = boform.cp
properties.style = style
features.push(feature)
}
return features
}
/**********************
* @featurize
*/
let featurize = function (json, anigram) {
let newAnigrams= []
if (json.type === "Feature") {
let newAnigram = __mapper("xs").b("clone")(anigram)
newAnigram.feature = json
newAnigram.sort = "feature"
newAnigrams.push(newAnigram)
} else if (json.type === "FeatureCollection") {
let features = json.features
for (let i=0; i<features.length; i++) {
let feature = features[i]
let properties = feature.properties || {}
let newAnigram = __mapper("xs").b("clone")(anigram)
let ric = Object.assign({},newAnigram.ric,properties.ric)
if (!ric.fid) ric.fid = i
else if (i > 0) ric.fid = ric.fid + "_" + i
newAnigram.ric = ric
let uid = __mapper("xs").m("ric").buildUID(newAnigram)
newAnigram.uid = uid
let boform = Object.assign({},newAnigram.boform,properties.boform)
newAnigram.boform = boform
newAnigram.sort = properties.sort || "feature"
newAnigram.feature = feature
newAnigrams.push(newAnigram)
}
} else if (json.type === "GeometryCollection") {
let geometries = json.geometries
for (let i=0; i<geometries.length; i++) {
let geometry = geometries[i]
let ani = __mapper("xs").m("anitem")(anigram)
let feature = {
"type": "Feature",
"geometry": geometry,
"properties": {
"boform": ani.boform(),
}
}
let newAnigram = __mapper("xs").b("clone")(anigram)
let ric = Object.assign({}, newAnigram.ric)
if (!ric.fid) ric.fid = i
else if (i > 0) ric.fid = ric.fid + "_" + i
newAnigram.ric = ric
let uid = __mapper("xs").m("ric").buildUID(newAnigram)
newAnigram.uid = uid
let boform = Object.assign({},newAnigram.boform)
newAnigram.boform = boform
newAnigram.sort = "feature"
newAnigram.feature = feature
newAnigram.sort = "feature"
newAnigrams.push(newAnigram)
}
} else { // geometry
let newAnigram = __mapper("xs").b("clone")(anigram)
let ani = __mapper("xs").m("anitem")(anigram)
let feature = {
"type": "Feature",
"geometry": {
"type": json.type,
"coordinates": json.coordinates
},
"properties": {
"boform": ani.boform(), // one boform
}
}
newAnigram.feature = feature
newAnigram.sort = "feature"
newAnigrams.push(newAnigram)
}
return newAnigrams
}
/**********************
* @zorder
*/
let zorder = function (anigrams) {
let zodered = anigrams
.map( d => {
let outring = d.feature.geometry.coordinates[0]
let z = 0
let dotsinring = outring.length
for (let k=0; k<dotsinring; k++) {
let ck = outring[k][2] // z camera view
z += ck
}
z = z / dotsinring
d.feature.properties.sort = z
return d
})
.sort( (a, b) => a.feature.properties.sort - b.feature.properties.sort )
return zodered
}
/**********************
* @enty
*/
let enty = function enty() {}
enty.resample = resample
enty.trim = trim
enty.snip = snip
enty.largestPoly = largestPoly
enty.lineStringFromStream = lineStringFromStream
enty.polygonFromStream = polygonFromStream
enty.multLineStringFromStreamArray = multLineStringFromStreamArray
enty.featurize = featurize
enty.geojize = geojize
enty.zorder = zorder
return enty
}
exports.muongeoj = muongeoj
}));
/***********
* @muongeom
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.muongeom = global.muongeom || {})))
}(this, function (exports) { "use strict"
let muongeom = function muongeom(__mapper = {}) {
let pi = Math.PI,
degrees = 180 / pi,
radians = pi / 180
let polar = function (cartesian) {
let lambda = Math.atan2(cartesian[0], cartesian[1])
let radio = Math.sqrt(cartesian[0] * cartesian[0] + cartesian[1] * cartesian[1])
return [
radio,
lambda
]
}
let cartesian = function (spherical) {
let lambda = spherical[0] * radians,
phi = spherical[1] * radians,
cosphi = Math.cos(phi)
return [
Math.cos(lambda) * cosphi ,
Math.sin(lambda) * cosphi ,
Math.sin(phi)
]
}
let spherical = function (cartesian) {
let r = Math.sqrt(cartesian[0] * cartesian[0] + cartesian[1] * cartesian[1]),
lat = Math.atan2(cartesian[2], r),
lng = Math.atan2(cartesian[1], cartesian[0])
let d = Math.sqrt(cartesian[0] * cartesian[0] + cartesian[1] * cartesian[1] + cartesian[2] * cartesian[2])
return [lng / radians, lat / radians, d]
}
let mapline = function (positions, verts) {
return verts
.map(function (v) {
return enty.spherical(positions[v])
})
}
let normalizeangle = function (angd) {
while (angd>=180) { angd -= 360 }
while (angd<-180) { angd += 360 }
return angd
}
// https://bl.ocks.org/mbostock/ece50c027bdf8cc20003a17d93e4f60e
// Copyright Mike Bostock
// Released under the GNU General Public License, version 3.
// Clips the specified subject polygon to the specified clip polygon;
// requires the clip polygon to be counterclockwise and convex.
// https://en.wikipedia.org/wiki/Sutherland–Hodgman_algorithm
let polygonClip = function(clip, subject) {
let input,
closed = polygonClosed(subject),
i = -1,
n = clip.length - polygonClosed(clip),
j,
m,
a = clip[n - 1],
b,
c,
d
while (++i < n) {
input = subject.slice()
subject.length = 0
b = clip[i]
c = input[(m = input.length - closed) - 1]
j = -1
while (++j < m) {
d = input[j]
if (polygonInside(d, a, b)) {
if (!polygonInside(c, a, b)) {
subject.push(polygonIntersect(c, d, a, b))
}
subject.push(d)
} else if (polygonInside(c, a, b)) {
subject.push(polygonIntersect(c, d, a, b))
}
c = d
}
if (closed) subject.push(subject[0])
a = b
}
return subject
}
function polygonInside(p, a, b) {
return (b[0] - a[0]) * (p[1] - a[1]) < (b[1] - a[1]) * (p[0] - a[0])
}
// Intersect two infinite lines cd and ab.
function polygonIntersect(c, d, a, b) {
let x1 = c[0], x3 = a[0], x21 = d[0] - x1, x43 = b[0] - x3,
y1 = c[1], y3 = a[1], y21 = d[1] - y1, y43 = b[1] - y3,
ua = (x43 * (y1 - y3) - y43 * (x1 - x3)) / (y43 * x21 - x43 * y21)
return [x1 + ua * x21, y1 + ua * y21]
}
// Returns true if the polygon is closed.
function polygonClosed(coordinates) {
let a = coordinates[0],
b = coordinates[coordinates.length - 1]
return !(a[0] - b[0] || a[1] - b[1])
}
// http://bl.ocks.org/johnburnmurdoch/60a427a44ea68e152da1771b28af9bdc
let pointInCircle = function(p, c, r){
return Math.pow(Math.pow(p.x - c.x,2) + Math.pow(p.y - c.y,2), 0.5) < r
}
let pointInPolygon = function (px, py, vs) {
return d3.polygonContains(vs, [px, py])
}
let polygonInPolygon = function(ps, vs) {
let inside = false
for (let i=0, n=ps.length; i<n; i++) {
let px = ps[i][0]
let py = ps[i][1]
inside = enty.pointInPolygon(px, py, vs)
}
return inside
}
let polygonInMultiPolygon = function(ps, mvs=[]) {
let inside = false
for (let i=0, n=mvs.length; i<n; i++) {
inside = enty.polygonInPolygon(ps, mvs[i])
if (inside === true) break
}
return inside
}
/**************************
* @enty
*/
let enty = function enty() {}
enty.polygonArea = polygon => d3.polygonArea(polygon)
enty.polygonRadius = polygon => Math.sqrt(Math.abs(d3.polygonArea(polygon))) / Math.PI
enty.polygonHull = points => d3.polygonHull(points)
enty.polygonContains = (polygon, p) => d3.polygonContains(polygon, p)
enty.polygonCentroid= polygon => d3.polygonCentroid(polygon)
enty.polygonLength = polygon => d3.polygonLength(polygon)
enty.minExtent = points => [Math.min(...points.map(d => d[0])), Math.min(...points.map(d => d[1]))]
enty.maxExtent = points => [Math.max(...points.map(d => d[0])), Math.max(...points.map(d => d[1]))]
enty.polygonExtent = points => [enty.minExtent(points), enty.maxExtent(points)]
enty.extentCentroid = extent => [(extent[0][0] + extent[1][0]) / 2, (extent[0][1] + extent[1][1]) / 2]
enty.extentEdges = extent => [extent[1][0] - extent[0][0], extent[1][1] - extent[0][1]]
enty.pointsInPolygon = (points, pol) => points.filter(p => enty.pointInPolygon(p[0],p[1], pol))
enty.cartesian = cartesian
enty.spherical = spherical
enty.mapline = mapline
enty.normalizeangle = normalizeangle
enty.polar = polar
enty.polygonClip = polygonClip
enty.pointInCircle = pointInCircle
enty.pointInPolygon = pointInPolygon
enty.polygonInPolygon = polygonInPolygon
enty.polygonInMultiPolygon = polygonInMultiPolygon
enty.dot = (x1, y1, x2, y2) => x1 * x2 + y1 * y2
enty.distance = (x1, y1, x2, y2) => {
let dx = x1 - x2
let dy = y1 - y2
return Math.sqrt(dx * dx + dy * dy)
}
enty.normalize$2 = (x, y) => {
let l = enty.distance(0, 0, x, y)
if (l > 0.00001) {
return [x / l, y / l]
} else {
return [0, 0]
}
}
enty.norm = (x, y) => enty.distance(0, 0, x, y)
enty.spherical = function(cartesian) {
return [
Math.atan2(cartesian[1], cartesian[0]),
Math.asin(Math.max(-1, Math.min(1, cartesian[2])))
]
}
enty.to_degrees = v => v.map(d => d * degrees)
enty.normalize = function (a) {
let d = Math.sqrt(a[0]*a[0] + a[1]*a[1] + a[2]*a[2])
return a.map (e => e / d)
}
enty.cartesian = function (spherical) {
let radians = Math.PI / 180
let lambda = spherical[0] * radians,
phi = spherical[1] * radians,
cosphi = Math.cos(phi)
return [
Math.cos(lambda) * cosphi ,
Math.sin(lambda) * cosphi ,
Math.sin(phi)
]
}
enty.add = function(v0, v1) {
return [v0[0] + v1[0],
v0[1] + v1[1],
v0[2] + v1[2]]
}
enty.degrees = () => 180 / Math.PI
enty.radians = () => Math.PI / 180
enty.to_radians = v => Array.isArray(v) ? v.map(d => d * Math.PI / 180)
: typeof(v) === "number" ? v * Math.PI / 180
: null
enty.to_degrees = v => Array.isArray(v) ? v.map(d => d * 180 / Math.PI) :
typeof(v) === "number" ? v * 180 / Math.PI : null
enty.coefsF0 = () => [
1.44224957030741,
0.240374928384568,
0.0686785509670194,
0.0178055502507087,
0.00228276285265497,
-1.48379585422573e-3,
-1.64287728109203e-3,
-1.02583417082273e-3,
-4.83607537673571e-4,
-1.67030822094781e-4,
-2.45024395166263e-5,
2.14092375450951e-5,
2.55897270486771e-5,
1.73086854400834e-5,
8.72756299984649e-6,
3.18304486798473e-6,
4.79323894565283e-7
-4.58968389565456e-7,
-5.62970586787826e-7,
-3.92135372833465e-7
]
enty.coefsG0 = () => [
1.15470053837925,
0.192450089729875,
0.0481125224324687,
0.010309826235529,
3.34114739114366e-4,
-1.50351632601465e-3,
-1.23044177962310e-3,
-6.75190201960282e-4,
-2.84084537293856e-4,
-8.21205120500051e-5,
-1.59257630018706e-6,
1.91691805888369e-5,
1.73095888028726e-5,
1.03865580818367e-5,
4.70614523937179e-6,
1.4413500104181e-6,
1.92757960170179e-8,
-3.82869799649063e-7,
-3.57526015225576e-7,
-2.2175964844211e-7
]
return enty
}
exports.muongeom = muongeom
}))
/***********
* @muonGraticule
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.muonGraticule = global.muonGraticule || {})))
}(this, function (exports) { "use strict"
// Version 0.0.0. Copyright 2017 Mike Bostock.
// GeoJSON in Three.js
let muonGraticule = function (__mapper = {}) {
let f = __mapper("props")()
const acos = Math.acos, asin = Math.asin, atan2 = Math.atan2, cos = Math.cos,
max = Math.max, min = Math.min, PI = Math.PI, sin = Math.sin, sqrt = Math.sqrt,
radians = PI / 180, degrees = 180 / PI, epsilon = 1e-5
let defaultMajor = [ [-180, 180, 90, 2.5], [-90, 90, 360, 2.5] ]
let defaultMinor = [ [-180, 180, 10, 2.5], [-80, 80, 10, 2.5] ]
/* *********************
* @idx index
* given number of rows and columsn and span between rows and columns
* give position of row.column
*/
let tidx = function (horq, verq, hd = 1, vd =1) {
return function(col, row) { // col, row
let ret = (row * hd) * (horq * vd) + col
return ret
}
}
/* *********************
* @ridx reverse index
*/
let ridx = function(horq, verq, hd = 1, vd =1) {
return function(idx) {
let ret = [Math.floor((( idx / hd) / vd) /horq), idx % horq]
return ret
}
}
/* *********************
* @getVerts
* mersCoords
* parsCoords
*/
let getVerts = function (mersCoords, parsCoords) {
let mersq = mersCoords.length // 12 x 7
let parsq = parsCoords.length // 7 x 13
let index = tidx(mersq, parsq) // 12, 7
let m0 = 0 // 0
let mn = mersq // 12
let p0 = 0 // 0
let pn = parsq // 6
let vertices = []
let faces = []
for (let j=p0; j<pn; j++) { // paralles 0 - 5
for (let i=m0; i<mn ; i++) { // meridians 0 - 11
let i0 = i
let i1 = (i + 1) % mersq // mer 12 is mer 0
let j0 = j
let j1 = (j + 1) //
vertices[index(i0,j0)] = mersCoords[i0][j0] // VERTICES
vertices[index(i0,j1)] = mersCoords[i0][j1]
vertices[index(i1,j0)] = mersCoords[i1][j0]
vertices[index(i1,j1)] = mersCoords[i1][j1]
}
}
return vertices
}
/* *********************
* @getFaces
*/
let getFaces = function (mersCoords, parsCoords, range, tile, vertices, bigPolygons) {
let mersq = mersCoords.length // 12 x 7
let parsq = parsCoords.length // 7 x 13
let index = tidx(mersq, parsq) // 12, 7
let m0 = 0 // 0
let mn = mersq // 12
let p0 = 0 // 0
let pn = parsq // 6
let faces = []
for (let i=m0; i<mn ; i++) { // meridians 0 - 11
for (let j=p0; j<pn; j++) { // parallels 0 - 5
let i0 = i
let i1 = (i + 1) % mersq // mer 12 is mer 0
let j0 = j
let j1 = (j + 1) //
let fs = bifaces(i,j, mersq, parsq, vertices, bigPolygons, mersCoords)
fs.forEach(f => faces.push(f))
}
}
return faces
}
/* *********************
* @getFacesParabolic
*/
let getFacesParabolic = function (mersCoords, parsCoords, vertex3, range, tile, vertices, bigPolygons) {
let mersq = mersCoords.length // 12 x 7
let parsq = parsCoords.length // 7 x 13
let index = tidx(mersq, parsq) // 12, 7
let m0 = 0 // 0
let mn = mersq // 12
let p0 = 0 // 0
let pn = parsq // 6
let faces = []
for (let i=m0; i<mn - 1; i++) { // meridians 0 - 11 parabolic: mn - 1
for (let j=p0; j<pn; j++) { // parallels 0 - 5
let i0 = i
let i1 = (i + 1) % (mersq) // mer 12 is mer 0
let j0 = j
let j1 = (j + 1) % (parsq) //
let fs = bifaces(i,j, mersq, parsq, vertices, bigPolygons, mersCoords)
fs.forEach(f => faces.push(f))
}
}
return faces
}
/* *********************
* @oneface
* a,b,c coord-vertices in [xn, yn] space give face verts indices
*/
let oneface = function (a, b, c, xn, yn) { // xy,ru,ry
let index = tidx(xn, yn)
return [ index(a[0],a[1]) , index(b[0],b[1]) , index(c[0],c[1]) ]
}
/* *********************
* @bifaces
* (i,h) in [xn,yn[]
* vertices to ...
* bigPolygons to filter coords if in pols
* mersCoords to get vert coords
*/
let bifaces = function bifaces (i, j, xn, yn, vertices, bigPolygons, mersCoords) {
let ret = []
let index = tidx(xn, yn)
let i0 = i
let i1 = (i + 1) % xn
let j0 = j
let j1 = (j + 1)
let inside = true
if (bigPolygons) inside = __mapper("xs").m("geom").polygonInMultiPolygon(
[ mersCoords[i0][j0], mersCoords[i1][j0], mersCoords[i1][j1], mersCoords[i0][j1] ],
bigPolygons // _e_
)
let f1 = oneface([i0,j0], [i1,j0], [i1,j1], xn, yn)
let f2 = oneface([i0,j0], [i1,j1], [i0,j1], xn, yn)
if (inside) {
ret.push(f1)
ret.push(f2)
}
return ret
}
/* *******************
* grarr
*/
let grarr = function (params = {}) {
let extent = params.extent // major, minor
let x_extent = extent[0]
let y_extent = extent[1]
let
X0 = x_extent[0],
X1 = x_extent[1],
DX = x_extent[2],
px = x_extent[3],
Y0 = y_extent[0],
Y1 = y_extent[1],
DY = y_extent[2],
py = y_extent[3]
let graticuleX = function graticuleX(y0, y1, dy) {
let y = d3.range(y0, y1 - epsilon, dy).concat(y1) // by intervals and close
return function(x) { return y.map(function(y) { return [x, y] }) }
}
let graticuleY = function graticuleY(x0, x1, dx) {
let x = d3.range(x0, x1 - epsilon, dx).concat(x1)
return function(y) { return x.map(function(x) { return [x, y] }) }
}
let X = graticuleX(Y0, Y1, py),
Y = graticuleY(X0, X1, px)
let mm1 = function mm1(_X, _X0, _X1, _DX) { // main meridinas
return d3.range(Math.ceil(_X0 / _DX) * _DX, _X1, _DX)
}
let mers = function mers(_X, _X0, _X1, _DX) {
let _mm1 = mm1(_X, _X0, _X1, _DX)
.sort((a, b) => a - b)
.filter((elem, pos, arr) => arr.indexOf(elem) == pos)
let ret = {type: "MultiLineString"}
ret.coordinates = _mm1.map(d => _X(d))
return ret
}
let mms = mers(X, X0, X1, DX) // _e_
let pp1 = function pp1(_Y, _Y0, _Y1, _DY) {
return d3.range(Math.ceil(_Y0 / _DY) * _DY, _Y1, _DY)
}
let pars = function pars(_Y, _Y0, _Y1, _DY) {
let _pp1 = pp1(_Y, _Y0, _Y1, _DY)
.sort((a, b) => a - b)
.filter((elem, pos, arr) => arr.indexOf(elem) === pos)
let ret = {type: "MultiLineString"}
ret.coordinates = _pp1.map(d => _Y(d))
return ret
}
let pps = pars(Y, Y0, Y1, DY)
let ret = { mms, pps }
return ret
}
/* *******************
* grarrx
*/
let grarrx = function (params = {}) {
let g = grarr(params)
let mersCoords = g.mms.coordinates
let parsCoords = g.pps.coordinates
let coords = [...mersCoords, ...parsCoords]
return coords
}
/* *******************
* geodes
*/
let geodes = function () {
let extent = [ [-180, 180, 90, 1], [-90, 90, 360, 1] ]
let ret = grarr({extent})
return ret
}
/* *******************
* equator
*/
let equator = function () {
let extent = [ [-180, 180, 90, 1], [-90, 90, 360, 1] ]
let ret = grarr({extent})
return ret.pps[0]
}
/* *****************
* merge
*/
let merge = function (major, minor, ret = {}) {
ret = {type: "MultiLineString"}
ret.coordinates = [...major, ...minor]
.sort((a, b) => a - b)
.filter((elem, pos, arr) => arr.indexOf(elem) == pos)
return ret
}
/* *****************
* reticule
*/
let reticule = function (ret = []) {
let retAng = ret[0]
let retRad = ret[1]
let ccs =
d3.range(retRad[0], retRad[1], retRad[2]) // range rad
.map(ro =>
d3.range(retAng[0], retAng[1] + epsilon , retAng[2]) // range ang - +epsilon
.map(t => [ro * Math.cos(t * Math.PI / 180), ro * Math.sin(t * Math.PI / 180)]))
let rrs =
d3.range(retAng[0], retAng[1], retAng[2])
.map(fi =>
d3.range(retRad[0], retRad[1], retRad[2])
.map(t => [t * Math.cos(fi * Math.PI / 180), t * Math.sin(fi * Math.PI / 180)]))
return { ccs, rrs }
}
/* *****************
* enty
*/
let enty = function () {}
enty.defaultMajor = () => defaultMajor
enty.defaultMinor = () => defaultMinor
enty.grarr = grarr
enty.grarrx = grarrx
enty.geodes = geodes
enty.getFaces = getFaces
enty.getFacesParabolic = getFacesParabolic
enty.getVerts = getVerts
enty.reticule = reticule
enty.ridx = ridx
return enty
}
exports.muonGraticule = muonGraticule
}))
/***************************
* @muonNat
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.muonNat = global.muonNat || {})))
}(this, function (exports) { "use strict"
let muonNat = function muonNat(__mapper = {}) {
let f = __mapper("props")()
const cos = Math.cos, sin = Math.sin
const neg = x => x < 0 || (x === 0 && (1/x < 0))
const pos = x => x > 0 || (x === 0 && (1/x > 0))
const radians = Math.PI / 180
const tau = 2 * Math.PI
/* **************************
* @rador : seg5 unit circle rador
* m.snap.snap (dim form => rador)
*/
let rador = function rador(form) {
let pts = []
const {m1,m2,n1,n2,n3,a,b,v0,v1,seg5} = form
const angUnit = tau / seg5 // dots per period
let angi = (form.angi) ? form.angi : (i, ang) => (i * ang) - Math.PI
let radi = (form.radi) ? form.radi : (i, rad, mult) => rad * ( 1 + mult * i )
let abs = (form.abs) ? form.abs : Math.abs
let nat = function (m1,m2,n1,n2,n3,a,b) {
return function(ang) {
let t1 = m1 * ang / 4
let t2 = m2 * ang / 4
let t = Math.pow(
Math.pow(abs(Math.cos(t1) / a), n2) // n2
+
Math.pow(abs(Math.sin(t2) / b), n3), // n3
-1 / n1) // n1
return t
}
}
for (let i = 0; i < seg5; i++) {
let ang = angi(i, angUnit * v1) // [0,360] => [-180,180]
let t = nat(m1,m2,n1,n2,n3,a,b)(ang)
let r = radi( i, t, v0) // increment radius with ang
pts.push(r)
}
return pts // dots in path: [0,...,seg5] => [0,1]
}
/* **************************
* @radorm
* g.natform
*/
let radorm = function radorm(form, s1extent=[-1,1]) { // radorm: [-1,1) => [-1,1]
let radorPts = f.norma(rador(form)) // rador: [-1,1] => [0,seg5)
let s1range = [0,radorPts.length-1] // [0, seg5]
let s2extent = d3.range(0,radorPts.length-1) // [0,...,seg5]
let s2range = radorPts // mormed form
let s1 = d3.scaleLinear().domain(s1extent).range(s1range) // [-1,1] => [0,seg5]
let s2 = d3.scaleLinear().domain(s2extent).range(s2range) // [0,..,seg5] => rador
return p => s2(s1(p)) // [0,1) =s1=> [0,seg5) =rador=> [0,1]
}
/* **************************
* @polarCoords
* m.nat.multiconform: form => dimstream
*/
let polarCoords = function (params) { // stream of scalars
let m1 = params.m1
let m2 = params.m2
let n1 = params.n1
let n2 = params.n2
let n3 = params.n3
let a = params.a
let b = params.b
let v0 = (params.v0 !== undefined) ? params.v0 : 0
let seg5 = Math.abs( params.seg5) // neg makes clockwise, 0 is ring, <0 text
let angUnit = 2 * Math.PI / seg5 // sector in RADs per symmetry
let t = 0
let maxRadio = 0
let pts = [] // points in path
for (let i = 0; i < seg5; i++) {
let ang = i * angUnit - Math.PI
let t1 = m1 * ang / 4 // m1, ngx
let t2 = m2 * ang / 4 // m2, ngy
t = Math.pow(
Math.pow(Math.abs(Math.cos(t1) / a), n2) // n2
+
Math.pow(Math.abs(Math.sin(t2) / b), n3), // n3
-1 / n1) // n1
t = t * ( 1 + v0 * i ) // increment radius with ang
if (t > maxRadio) maxRadio = t
pts.push(t)
}
let radUnit = 1 / maxRadio // * Math.SQRT1_2 / maxRadio normalize
pts = pts.map (d => d * radUnit )
return pts
}
/**********************
* @multiconform
* coordinates = Array.of(__mapper("xs").m("nat").multiconform(p.form))
*/
let multiconform = function(form) {
let radians = Math.PI / 180
let tau = 2 * Math.PI
let dimstreams = Object.keys(form)
dimstreams = dimstreams
.map(d => __mapper("xs").m("nat").polarCoords(form[d])) // conform
dimstreams = dimstreams
.map((d,i) => d.map(p => p * form[ Object.keys(form)[i]].ra2)) // size
dimstreams = dimstreams
.map((d,i) => d.map((p,j) => { // rotation
let formdim = form[Object.keys(form)[i]]
let angUnit = tau / d.length
let refAng = (formdim.w4 + formdim.fas8) * radians
let v1 = formdim.v1
let ang = ((j * angUnit * v1) - refAng + tau) % tau // j point
let r = p * Math.cos(ang) // each point
return r
}))
let streams = dimstreams
.map( (d,i) => {
let dim = Object.keys(form)[i]
let pa6 = form[dim].pa6
let pb7 = form[dim].pb7
return f.streamRange(d, pa6, pb7)
})
streams = f.slide(streams, "min")
return streams
}
/**********************
* @nform
* compleate form for natform
*/
let nform = function(form) {
let nform = {}
if (form // form:{x,y,z}
&& typeof form === "object"
&& ( form.x !== undefined && form.y !== undefined && form.z !== undefined )) {
nform = form
} else if (form
&& typeof form === "object"
&& ( form.x === undefined && form.y === undefined && form.z === undefined )) {
nform = {}
nform.x = Object.assign( {}, form, {fas8: (form.fas8 || 0)} ) // set fas8 0
nform.y = Object.assign( {}, (form.y || form) , {fas8: form.fas8 - 90})
nform.z = Object.assign( {}, (form.z || form) )
} else if (form
&& typeof form === "object"
&& ( form.x !== undefined || form.y !== undefined || form.z !== undefined )) {
nform = {}
nform.x = Object.assign({}, form.x ) // defined
nform.y = Object.assign({}, (form.y || form.x) , {fas8: form.x.fas8 - 90})
nform.z = Object.assign({}, (form.z || form.x) )
} else if (form
&& Array.isArray(form)) {
nform = {}
nform.x = form[0]
nform.y = form[1] || Object.assign({}, form[0], {fas8: form.fas8 - 90})
nform.z = form[2] || Object.assign({}, form[0])
} else {
nform = {}
nform.x = {}
nform.y = {}
nform.z = {}
}
return nform
}
let natform = function(form) {
let radioform = Object.values(form).map( (d,i) => {
let ret
if (i < 2 ) {
ret = p => radorm(d,[-Math.PI, Math.PI])(p)
} else if (i === 2 ) {
ret = radorm(d,[-Math.PI, Math.PI])
}
return ret
})
let scale = [1,1,1], rotation = [0,0,0], location = [0,0,0]
if (form) scale = Object.values(form).map(dim => dim.ra2)
if (form) rotation = Object.values(form).map(dim => dim.w4 * radians)
let coForm = {location, scale, rotation}
return function (l, p, radio=1) { // spherical degrees
let lambda = l * radians
let phi = p * radians
let c = coForm
let x = c.scale[0] * radioform[0](lambda) * cos(lambda + c.rotation[0]) * cos(phi) * radioform[2](phi)
let y = c.scale[1] * radioform[1](lambda) * sin(lambda + c.rotation[1]) * cos(phi) * radioform[2](phi)
let z = c.scale[2] * radioform[2](phi) * sin(phi + c.rotation[2])
return [x,y,z]
}
}
/***************************
* @enty
*/
let enty = function () {}
enty.rador = rador // form => pts (domain form.seg5 to [0,1] range)
enty.radorm = radorm // [0,1) =s1=> [0,seg5) =rador=> [0,1]
enty.polarCoords = polarCoords //
enty.multiconform = multiconform //
enty.nform = nform //
enty.natform = natform
return enty
}
exports.muonNat = muonNat
}))
/**********************
* @muonRic
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.muonRic = global.muonRic || {})))
}(this, function (exports) { "use strict"
let muonRic = function muonRic(__mapper = {}) {
let props = __mapper("props")()
// ric.halo: anima type
// ric.gid: group id
// ric.cid: class id
// ric.fid: form id
// aid: anima id
// nid: number id
// uid: unique id
// delled: is deleted {0,1}
// inited: is inited {0,1}
// gelded: is gelded {0,1} - no further replication
// sort: render sort
/***************************
* @getAnigramRic
*/
let getAnigramRic = function getAnigramRic(anigram, idx=0){
// single item in subgroup manged by position
// 0 gid, cid, fid
// 1 gid, fid
// 2 cid, fid
let ani = __mapper("xs").m("anitem").anigram(anigram)
let parent = ani.parent
let ric = anigram.ric
ric.halo = anigram.ric.halo
if (anigram.ric.gid === undefined) { // no gid in anigram
ric.gid = (parent.ric.gid||"gid") + "_" + idx // set gid by position
} else {
ric.gid = anigram.ric.gid // gid defined in anigram
}
if (anigram.ric.cid === undefined) { // no cid in anigram
ric.cid = parent.ric.cid + "_" + "_" + idx //cid from parent and index - larms
} else {
ric.cid = anigram.ric.cid // cid set in anigram
}
let itemsInClass = __mapper("muonStore").anigrams().filter(d=> d.ric.gid === ric.gid && d.ric.cid === ric.cid).length
if (anigram.ric.fid === undefined) { // no fid in anigram
ric.fid = ric.cid + "_" + idx + itemsInClass
} else if ( typeof anigram.ric.fid === "function" ) {
ric.fid = anigram.ric.fid() // fid - allow for random
} else if (idx > 0) { // fid defined but multiple subanigrams in form
ric.fid = anigram.ric.fid + "_" + "_" + idx // fid for multi position
} else {
ric.fid = anigram.ric.fid // fid - diff by pos
}
return ric
}
/**********************
* @enty
*/
let enty = function enty() {}
enty.getAnigramRic = getAnigramRic // build ric from anigram, i
enty.buildUIDFromRic = ric => ric.gid + "_" + ric.cid + "_" + ric.fid
enty.buildUID = anitem => enty.buildUIDFromRic(anitem.ric)
return enty
}
exports.muonRic = muonRic
}))
/***************************
* @muonSimulation
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.muonSimulation = global.muonSimulation || {})))
}(this, function (exports) { "use strict"
// simulation @forces
// stace.sim
// .stop()
// .numDimensions(3) // graph.numDimensions
// .nodes(stace.animas.filter(d => (d.ric.gid === "anima3d")))
// .force('link', d3_force.forceLink().id(d => d._id).links(stace.animas.filter(d => (d.ric.gid === "vortlink"))).strength(0.01))
// .force('charge', d3_force.forceManyBody().strength(-10.9))
// .force('center', d3_force.forceCenter(0))
// .restart()
// .on("tick", ()=> {
// console.log("------------ tick")
// __mapper("muonStore").apply({"type":"UPDANIMA","caller":"simulation ","animas":stace.sim.nodes()})
// })
// ------------------------- muonSimulation
let muonSimulation = function muonSimulation(__mapper = {}) {
let props = __mapper("props")()
let f = props.lib
let sim = d3_force.forceSimulation() //
let dim = 3
// simulate
// https://bl.ocks.org/frogcat/a06132f64b7164c1b1993c49dcd9178f
// https://www.nist.gov/sites/default/files/documents/2017/05/09/d3rave_poster.pdf
// ------------------------- initNodes
function initNodes(nodes, nDim) {
// console.log("p.simulation nodes", nodes)
for (let i = 0, n = nodes.length, node; i < n; ++i) {
node = nodes[i]
if ( node.x === undefined || isNaN(node.x)) node.x = 0
if ((node.y === undefined || isNaN(node.y)) && nDim > 1 ) node.y = 0
if ((node.z === undefined || isNaN(node.z)) && nDim > 2 ) node.z = 0
if (isNaN(node.vx)) node.vx = 0
if (nDim > 1 && isNaN(node.vy)) node.vy = 0
if (nDim > 2 && isNaN(node.vz)) node.vz = 0
}
return nodes
}
// ------------------------- simConstants
function simConstants(sim, fieldProps = {}) {
let cttes = {}
cttes.alpha = (fieldProps.alpha !== undefined) ? fieldProps.alpha : sim.alpha()
cttes.alphaMin = (fieldProps.alphaMin !== undefined) ? fieldProps.alphaMin : sim.alphaMin()
cttes.alphaDecay = (fieldProps.alphaDecay !== undefined) ? fieldProps.alphaDecay : sim.alphaDecay()
cttes.alphaTarget = (fieldProps.alphaTarget !== undefined) ? fieldProps.alphaTarget : sim.alphaTarget()
cttes.velocityDecay = (fieldProps.velocityDecay !== undefined) ? fieldProps.velocityDecay : sim.velocityDecay()
return cttes
}
/***************************
* @simulate
*/
let simulate = function simulate (sim, animas = [], elapsed = 0, dim = 3) {
let nodes = initNodes(animas, dim)
sim
.stop()
.numDimensions(3)
.nodes(nodes)
for (let i=0; i<nodes.length; i++) {
let anima = nodes[i]
if (anima.forces !== undefined ) { // force forces in animas
let forces = f.fa(anima.forces)
for (let j=0; j<forces.length; j++) {
let field = __mapper("xs").b("snap")(forces[j] , anima.tim.unitTime) /* snap field*/
let fieldProps = field // field properties
let cttes = simConstants(sim, fieldProps)
sim
.alpha(cttes.alpha)
.alphaMin(cttes.alphaMin)
.alphaDecay(cttes.alphaDecay)
.alphaTarget(cttes.alphaTarget)
.velocityDecay(cttes.velocityDecay)
.on("tick", ()=> {
if (field.ticked !== undefined) field.ticked
__mapper("xs").m("store").apply({"type":"UPDANIMA","caller":"simulation ","animas":nodes})
})
if (field.field !== undefined) { // field forces
let itemsNew = field.field({
"elapsed":elapsed,
"nodes":nodes,
"pic":fieldProps // properties snapped
})
for (let k=0; k < itemsNew.length; k++) {
sim.force(itemsNew[k].key, itemsNew[k].force) // muon forces
}
}
}
}
}
sim.restart()
return nodes
}
/***************************
* @enty
*/
let enty = function enty() {}
enty.sim = (_) => {if ( _ === undefined ) return sim; else { sim = _ ; return enty }}
enty.dim = (_) => {if ( _ === undefined ) return dim; else { dim = _ ; return enty }}
enty.simulate = simulate
return enty
}
exports.muonSimulation = muonSimulation
}))
/***********
* @muonStace
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.muonStace = global.muonStace || {})))
}(this, function (exports) { "use strict"
let muonStace = function (__mapper = {}) {
let f = __mapper("props")()
/* ***************************************
* getSiti situs: a:{x,y,z}
*
*/
let getSiti = function (anima, siti=[]) {
if (anima !== undefined) { // empty list of siti
let situs = __mapper("xs").m("stace").getSitus(anima)
if (situs !== undefined) { siti.push(situs) } // add situs
}
return siti
}
/* ***************************************
* getPositions
* get positions form anigram.stace
* called by getLocations if no situs
*
* stace: {"x": [[[200,400]]], "y": 100, "z": 0,}
*
* stace: [[[ () => [ [[[200,100,400]]] , 100, 0] ]]]
*
* stace = [[[ () => {
* let geo = {
* "type": "LineString",
* "coordinates": [ [200, 100, 0],[100, 100, 0],[400, 100, 0], ]
* }
* return f.ta(f.unslide(geo.coordinates))
* } ]]]
*
* stace = [[[ {
* "x": {
* "m1":4,"m2":4,"n1":2,"n2":2,"n3":2,"a":1,"b":1, // circle
* "ra2": 100,"v0": 0,"v1":1,"w4": 90,"seg5": 360,"pa6":0,"pb7":-1,"fas8": 0,
* },
* "y": {
* "m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
* "ra2": 100,"v0":0,"v1":1,"w4": 90,"seg5": 360,"pa6":0,"pb7":-1,"fas8": -90,
* },
* "z": {
* "m1":5,"m2":5,"n1":2,"n2":7,"n3":7,"a":1,"b":1, // star
* "ra2": 260,"v0": 0,"v1":1,"w4": 0,"seg5": 12,"pa6":0,"pb7":-1,"fas8": 0,
* }
* } ]]]
*
*/
let getLocsInDim = function (stateDim, parentCoords = []) { // get loc in stateDim if object
let locations = []
if (typeof stateDim === "number") {
locations.push(stateDim)
} else if (typeof stateDim === "object" && stateDim.pos !== undefined) {// stateDim pos
if (parentCoords.length > 0) {
if (typeof stateDim.pos === "number") { // one position
let pos = stateDim.pos % parentCoords.length // pos spec
if (pos < 0) pos = (pos + parentCoords.length) % parentCoords.length
let idx = Math.floor(pos)
let v = parentCoords[idx]
locations = Array.of(v)
} else if (Array.isArray(stateDim.pos)) {
let dist = stateDim.dist || 0 // distance to position
let fas = stateDim.fas || 0 // phase in positions
let pos0 = Math.floor(stateDim.pos[0]) // first of positions array
let pos1 = Math.floor(stateDim.pos[1]) // last of positions array
let step = Math.round(stateDim.step) || 1 // step between positions
if (pos0 <= pos1) {
locations = d3.range(pos0,pos1, step) // d3 create positional array
.map(d => d + fas) // displace positions by phase
.map(d => d % parentCoords.length) // mod (-1)
.map(d => Math.floor(d)) // integer position
.map(d => parentCoords[d]) // location from parent coords
.map(d => d + dist) // sum dist to dim location
} else {
locations = d3.range(pos1, pos0, step) // d3 create positional array
.map(d => d + fas) // displace positions by phase
.map(d => d % parentCoords.length) // mod
.map(d => Math.floor(d))
.map(d => parentCoords[d])
.map(d => d + dist)
}
}
}
}
return locations
}
let getParentCoords = function(a) { // get parent coords from a
let parentLocation,
parentGeometry,
parent = {},
parentCoords = []
parent = __mapper("xs").m("store").findAnigramFromUid(a.parentuid) || a.parent
if (parent && parent.geometry) {
parentGeometry = parent.geometry // geometry
parentCoords = parentGeometry[0] // outer ring tbf _e_
}
return parentCoords
}
let getLocs = function(a) { // get locations from stace positions
let parentCoords = getParentCoords(a) // get parent coords from a
let braid = [],
dims = __mapper("xs").m("stace").dims()
for (let i=0; i< dims.length; i++) {
let dimState = a.stace[dims[i]], // dim i stace
dimStream = f.unslide(parentCoords)[i] // dim i parent coords
braid[i] = getLocsInDim(dimState, dimStream)
}
let locations = f.slide(braid, "max")
return locations
}
let getPositions = function getPositions(anima, locations=[]) {
let a = __mapper("xs").m("anitem").anigram(anima)
if (a.stace !== undefined &&
Array.isArray(a.stace)) { // anima.stace.[x,y,z]
let location = a.stace // single location from stace array
locations.push(location)
return locations
}
if (a.stace !== undefined &&
typeof a.stace === "object") { // anima.stace.{x,y,z}
let locations = getLocs(a) // get locations from stace positions
return locations
}
if (a.stace === undefined &&
a.parentuid !== undefined) { // parent.{x,y,z}
let locations = []
let parentCoords = []
let parentGeometry
let parent = a.parent || __mapper("xs").m("store").findAnigramFromUid(a.parentuid)
if (parent !== undefined) {
locations = getPositions(parent)
}
return locations
}
if (locations === undefined) locations = [[0,0,0]]
return locations
}
/* ***************************************
* getLocations:
* stace situs stace.{x,y,z}
* or position stace.(pos,pos,pos}
*
*/
let getLocations = function getLocations(anima, locations=[]) {
let situs = getSiti(anima)
if (situs !== undefined) {
locations = situs
} else {
let positions = getPositions(anima)
if (positions !== undefined) {
locations = positions
}
}
return locations
}
/***************************************
* @getLocation abc on x, y, stateC
*
*/
let getLocation = function getLocation(anigram = {}) {
let siti = __mapper("xs").m("stace").getSiti(anigram) // {x,y,z}
let positions = __mapper("xs").m("stace").getPositions(anigram) //
let locations = []
if (siti && siti.length >0 && positions && positions.length >0) {
// siti: [ [0,0,0] ]
// locations: [ [300,200,0] ]
locations = f.slide([siti, positions], "max") // slide dim sites ****
}
let location = [0,0,0]
if (siti && siti.length > 0 && positions && positions.length >0) {
location = f.fa(siti[0]).map((d, i) => d + positions[0][i]) // force array
} else if (siti && siti.length >0 ) {
location = f.fa(siti[0])
} else if (positions && positions.length >0 ) {
location = positions[0]
}
return location // 3dim cartesian location
}
/* **************************************
* @getLociformer
* locifier(p): [x, y, z] => [x+p[0], y+p[1], z+p[2]]
*/
let getLociformer = function (anigram = {}) {
let location = __mapper("xs").m("stace").getLocation(anigram)
let projection = {
"projection": "uniwen",
"translate": [ location[0], location[1], location[2] ]
}
let lociform = __mapper("xs").b("gist")(projection)
return g => d3.geoProject(g, lociform)
}
let getLociform = function (anigram = {}) {
let location = __mapper("xs").m("stace").getLocation(anigram)
let projection = {
"projection": "uniwen",
"translate": [ location[0], location[1], location[2] ]
}
return __mapper("xs").b("gist")(projection)
}
/* **************************************
* @getLocifier
* locifier(p): [x, y, z] => [x+p[0], y+p[1], z+p[2]]
*/
let getLocifier = function (anigram = {}) {
let location = __mapper("xs").m("stace").getLocation(anigram)
let locifier = p => p.map( (d,i) => d + location[i] )
return locifier
}
/* **************************************
* @getReformer
*/
let getReformer = function (stace = {}) {
if ( stace && stace.x && stace.x.ref && stace.y && stace.y.ref) {
return function(json) {
let outring = json.geometry.coordinates[0]
let refs = f.unslide(outring)
let r0 = refs[0][stace.x.ref]
let r1 = refs[1][stace.y.ref]
let refpos = { "translate": [ r0, r1 ] }
let reform = __mapper("xs").g("unidentity")(refpos)
let reformer = d => d3.geoProject(d, reform)
return reformer(json) // reform
}
} else {
return d => d // identity
}
}
/* **************************************
* @getReform
*/
let getReform = function (stace = {}) {
if ( stace && stace.x && stace.x.ref && stace.y && stace.y.ref) {
return function(json) {
let outring = json.geometry.coordinates[0]
let refs = f.unslide(outring)
let r0 = refs[0][stace.x.ref]
let r1 = refs[1][stace.y.ref]
let projection = {
"projection": "identity",
"translate": [ r0, r1 ]
}
return __mapper("xs").m("identity").getproj(projection)
}
} else {
let projection = {
"projection": "identity",
}
return __mapper("xs").b("gist")(projection)
}
}
/***********
* @enty
*/
function enty() { return enty }
enty.getFixedLocation = anitem => anitem.stace.f // f: 1/0
enty.x = anitem => anitem.x // x
enty.y = anitem => anitem.y // y
enty.z = anitem => anitem.z // z
enty.dims = () => ["x","y","z"]
enty.getSitus = anitem => {
let ret = {}
if ( typeof enty.x(anitem) === "number" ) ret.x = enty.x(anitem)
if ( typeof enty.y(anitem) === "number" ) ret.y = enty.y(anitem)
if ( typeof enty.z(anitem) === "number" ) ret.z = enty.z(anitem)
if (Object.keys(ret).length === 0) ret = undefined
else ret = Object.values(ret)
return ret
}
enty.location = anitem => {
let x = enty.x(anitem)
let y = enty.y(anitem)
let z = enty.z(anitem)
let location = (x || y || z) ? [x,y,z] : undefined
return location
}
enty.getSiti = getSiti //
enty.getPositions = getPositions //
enty.getLocations = getLocations // anima => locations
enty.getLocation = getLocation // amima => [x,y,z]
enty.getLocifier = getLocifier //
enty.getLociformer = getLociformer // d3 projection
enty.getLociform = getLociform // projection
enty.getParentCoords = getParentCoords // getParentCoords
enty.getReformer = getReformer // getReformer
enty.getReform = getReform // getReform
return enty
}
exports.muonStace = muonStace
}));
/***********
* @muonStore
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.muonStore = global.muonStore || {})))
}(this, function (exports) { "use strict"
// ref: https://bl.ocks.org/mbostock/6081914 transitions
// https://github.com/d3/d3-ease#easeElasticOut
let muonStore = function muonStore(__mapper) {
let f = __mapper("props")()
let local = {}
local.animas = [] // animas array
local.aniset = {} // animas by uid
local.anigrams = [] // behavior - an anigram may have many avatars
let apply = function apply (action = {}) {
/***************************
* @UPDANIMA
*/
if (action.type === "UPDANIMA") {
let updAnimas = f.fa(action.animas) // get new animas as array
let elapsed = action.elapsed || 0
for (let i=0; i < updAnimas.length; i++) {
let updAnima = f.o(updAnimas[i]) // each new anima
let uid = (updAnima.uid !== undefined) // uid
? updAnima.uid
: __mapper("xs").m("ric").buildUID(updAnima)
let index = enty.findFromUid(uid, local.animas)
if (index !== -1) { // anima exists
if (updAnima.delled === 1 ) {
local.animas.splice(index, 1) // delete anima
} else {
local.animas[index] = updAnima // replace
}
} else {
updAnima.tim = __mapper("xs").b("tim")(updAnima.tim, elapsed) // set tim elapsed
updAnima.uid = uid // set uid if new anima
updAnima.nid = __mapper("xs").m("store").getNid() // node id in animas collection
local.aniset[updAnima.uid] = updAnima // set new anima by uid
local.animas[local.animas.length] = updAnima // register new anima
}
}
return local.animas
}
/***************************
* @UPDANIGRAM
*/
if (action.type === "UPDANIGRAM") {
let newAnigrams = action.anigrams
for (let i=0; i<newAnigrams.length; i++) {
if (newAnigrams[i] !== undefined) {
let newItem = newAnigrams[i] // new anigram
let index = enty.findIndex(newItem, local.anigrams) // find index
if (index === -1) index = local.anigrams.length // add holder if new
local.anigrams[index] = newItem // replace anigram
}
}
return local.anigrams
}
}
/* **************************
* @ween
* ween every generation
*/
let ween = function (anima, newItems = []) {
let anigram = __mapper("xs").m("anitem").anigram(anima)
if (anigram.halo === undefined) console.error("halo not defined")
if (anigram.halo === null) console.error("halo is null")
let halo = (anigram.halo !== undefined && typeof anigram.halo === "object")
? anigram.halo // halo in anima
: __mapper("xs").h(anigram.halo) // halo in store
let weened = halo.ween(anima) // ANIMA HALO.WEEN
weened.forEach(d => { // qualify each ween
d.uid = __mapper("xs").m("ric").buildUID(d) // uid for children
newItems.push(d)
})
return newItems
}
/* **************************
* @gramn
* gramn when rendering
*/
let gramn = function (anima, newItems = []) {
let anigram = __mapper("xs").m("anitem").anigram(anima)
let tim = anigram.tim,
elapsed = tim.elapsed,
wait = tim.wait
let newAnigrams = []
let halo
if ( anima && (elapsed || elapsed >= wait )) { // anima just born or beyond wait time
halo = (anigram.halo !== undefined && typeof anigram.halo === "object")
? anigram.halo // halo in anima
: __mapper("xs").h(anigram.halo) // or halo in store
if (halo) newAnigrams = halo.gramn(anima) // ANIMA HALO.GRAMN
else console.log("form ", halo, " not defined")
if (newAnigrams !== null) newItems = newItems.concat(f.a(newAnigrams))
else console.error("avatar gramn ", halo, " returns null")
}
if (newAnigrams !== undefined && newAnigrams.length > 0) { // check if avatars in new animas
for (let i=0; i<newAnigrams.length; i++) {
let newItem = newAnigrams[i] // each new item
if (newItem.avatars !== undefined) { // AVATARS
let avatars = (typeof newItem.avatars === "object") ? Object.values(newItem.avatars) : newItem.avatars
for (let j=0; j<avatars.length; j++) {
let newSubItems = []
let avatar = avatars[j]
avatar.uid = __mapper("xs").m("ric").buildUID(avatar) // uid for children
avatar.tim = anigram.tim // time from anima
avatar.parent = __mapper("xs").b("clone")(newItem) // parent is newItem
avatar.parentuid = newItem.uid // parentuid from newItem
newSubItems = enty.gramn(avatar) // AVATAR GRAMN halogram
newItems = newItems.concat(f.a(newSubItems))
}
}
}
}
return newItems
}
/***************************
* @enty
*/
function enty() {}
enty.apply = apply
enty.gramn = gramn
enty.ween = ween
enty.animasInGroupHowMany = anima =>
(anima === undefined)
? 0
: enty.animasLive()
.filter(d => d.ric.gid === anima.ric.gid).length
enty.animasInClassHowMany = anima =>
(anima === undefined)
? 0
: enty.animasLive()
.filter(d => (d.ric.gid === anima.ric.gid
&& d.ric.cid === anima.ric.cid)).length
enty.findIndex = (item, list) =>
list.findIndex(d =>
d.ric.gid === item.ric.gid &&
d.ric.cid === item.ric.cid &&
d.ric.fid === item.ric.fid
)
enty.findIndexFromRic = (ric, list) =>
list.findIndex(d =>
d.ric.gid === ric.gid &&
d.ric.cid === ric.cid &&
d.ric.fid === ric.fid
)
enty.findByUid = (item, list) => {
let uid = __mapper("xs").m("ric").buildUID(item)
return enty.findFromUid(uid, list)
}
enty.findFromUid = (uid, list) => list.findIndex(d => d.uid === uid )
enty.findIndexAnigramFromUid = uid => enty.anigrams().findIndex(d => d.uid === uid)
enty.findAnigramFromUid = uid => local.anigrams.find(d => d.uid === uid)
enty.born = d =>d.tim !== undefined && d.tim.unitElapsed !== undefined && d.tim.unitElapsed > f.epsilon
enty.unborn = d => d.tim === undefined && d.tim.elapsed === undefined && d.tim.unitElapsed === undefined && d.tim.unitElapsed < f.epsilon
enty.getAnimaByUID = uid => local.animas.find(d => d.uid === uid)
enty.animas = () => local.animas
enty.anigrams = () => local.anigrams
enty.animasAll = () => local.animas // animas including delled
enty.animasLive = () => local.animas.filter(d=>d.delled !==1 && d.delled !== true)
enty.token = () => local.animas.length + 1
enty.getNid = () => local.animas.length + 1
enty.getAnigramIdx = ric => enty.getAnitemIndex(local.anigrams,ric.gid,ric.cid,ric.fid)
enty.getAnigram = ric => local.anigrams[enty.getAnigramIdx(ric)] || null
return enty
}
exports.muonStore = muonStore
}))
/***************************
* @muonTimer
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.muonTimer = global.muonTimer || {})))
}(this, function (exports) { "use strict"
// copyright mbostock
// https://github.com/d3/d3-timer/blob/master/src/timer.js
let muonTimer = function muonTimer(__mapper = {}) {
let props = __mapper("props")()
let frame = 0, // is an animation frame pending?
timeout = 0, // is a timeout pending?
interval = 0, // are any timers active?
pokeDelay = 1000, // how frequently we check for clock skew
taskHead,
taskTail,
clockLast = 0,
clockNow = 0,
clockSkew = 0,
clock = typeof performance === "object" && performance.now ? performance : Date,
setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17) }
let now = function now() {
return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew)
}
function clearNow() {
clockNow = 0
}
let timer = function timer(callback, delay, time) {
let t = new Timer
t.restart(callback, delay, time)
return t
}
let timerFlush = function timerFlush() {
now() // Get the current time, if not already set.
++frame // Pretend we’ve set an alarm, if we haven’t already.
let t = taskHead, e
while (t) {
if ((e = clockNow - t._time) >= 0) t._call.call(null, e)
t = t._next
}
--frame
}
let Timer = function Timer() {
this._call =
this._time =
this._next = null
}
Timer.prototype = timer.prototype = {
constructor: Timer,
restart: function(callback, delay, time) {
if (typeof callback !== "function") throw new TypeError("callback is not a function")
time = (time == null ? now() : +time) + (delay == null ? 0 : +delay)
if (!this._next && taskTail !== this) {
if (taskTail) taskTail._next = this
else taskHead = this
taskTail = this
}
this._call = callback
this._time = time
sleep()
},
stop: function() {
if (this._call) {
this._call = null
this._time = Infinity
sleep()
}
}
,
resume: function(callback, delay, time) { // _e_
if (typeof callback !== "function") throw new TypeError("callback is not a function")
time = (time == null ? now() : time) + (delay == null ? 0 : +delay)
if (!this._next && taskTail !== this) {
if (taskTail) taskTail._next = this
else taskHead = this
taskTail = this
}
this._call = callback
this._time = time
sleep()
}
}
function wake() {
clockNow = (clockLast = clock.now()) + clockSkew
frame = timeout = 0
try {
timerFlush()
} finally {
frame = 0
nap()
clockNow = 0
}
}
function poke() {
let now = clock.now(), delay = now - clockLast
if (delay > pokeDelay) clockSkew -= delay, clockLast = now
}
function nap() {
let t0, t1 = taskHead, t2, time = Infinity
while (t1) {
if (t1._call) {
if (time > t1._time) time = t1._time
t0 = t1, t1 = t1._next
} else {
t2 = t1._next, t1._next = null
t1 = t0 ? t0._next = t2 : taskHead = t2
}
}
taskTail = t0
sleep(time)
}
function sleep(time) {
if (frame) return // Soonest alarm already set, or will be.
if (timeout) timeout = clearTimeout(timeout)
let delay = time - clockNow
if (delay > 24) {
if (time < Infinity) timeout = setTimeout(wake, delay)
if (interval) interval = clearInterval(interval)
} else {
if (!interval) clockLast = clockNow, interval = setInterval(poke, pokeDelay)
frame = 1, setFrame(wake)
}
}
/***************************
* @enty
*/
let enty = function enty() {}
enty.now = now
enty.Timer = Timer
enty.timer = timer
enty.timerFlush = timerFlush
return enty
}
exports.muonTimer = muonTimer
}));
/*******************************************
* @muonWen
*
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.muonWen = global.muonWen || {})))
}(this, function (exports) { "use strict"
// https://github.com/wenliang-developer
// https://codepen.io/wenliang-developer/pen/gMwvXR
// https://github.com/wenliang-developer/web-developer-site
let muonWen = function muonWen(__mapper = {}) {
let f = __mapper("props")()
function clip(n, m, M) { return n < M ? n > m ? n : m : M }
function comeCloser(n, goal, factor, limit) {
return (limit && Math.abs(goal - n) < limit) ? goal : n + (goal - n) / (factor || 10)
}
function dist(a, b) {
let dx = b[0] - a[0], dy = b[1] - a[1], dz = b[2] - a[2]
return Math.sqrt(dx*dx + dy*dy + dz*dz)
}
function normalize(v) {
let l = Math.sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2])
return [v[0] / l, v[1] / l, v[2] / l]
}
function projection(p, d, s) {
// let f = (s || 1) / (1 - p[2] / d);
// let f = (s || 1) / (1 - p[2] / d);
// return [p[0]*f, p[1]*f, p[2]];
let h = Array.isArray(s) ? s : Array.of(s)
let f0 = (h[0] || 1) / (1 - p[2] / d)
let f1 = (h[1] || h[0]) / (1 - p[2] / d)
return [p[0]*f0, p[1]*f1, p[2]]
}
function rotateX(p, a) {
let d = Math.sqrt(p[2] * p[2] + p[1] * p[1]),
na = Math.atan2(p[2], p[1]) + a
return [p[0], d * Math.cos(na), d * Math.sin(na)]
}
function rotateY(p, a) {
let d = Math.sqrt(p[2] * p[2] + p[0] * p[0]),
na = Math.atan2(p[0], p[2]) + a
return [d * Math.sin(na), p[1], d * Math.cos(na)]
}
function rotateZ(p, a) {
let d = Math.sqrt(p[1] * p[1] + p[0] * p[0]),
na = Math.atan2(p[1], p[0]) + a
return [d * Math.cos(na), d * Math.sin(na), p[2]]
}
function rotateMatrix(p, m) {
return [
p[0] * m[0] + p[1] * m[3] + p[2] * m[6],
p[0] * m[1] + p[1] * m[4] + p[2] * m[7],
p[0] * m[2] + p[1] * m[5] + p[2] * m[8]
]
}
function transpose33(m) {
return [
m[0], m[3], m[6],
m[1], m[4], m[7],
m[2], m[5], m[8]
]
}
function rotate3dMatrix(x, y, z, a) {
let c = 1 - Math.cos(a), s = Math.sin(a)
return [
1+c*(x*x-1), x*y*c+z*s, x*z*c-y*s,
x*y*c-z*s, 1+c*(y*y-1), y*z*c+x*s,
x*z*c+y*s, y*z*c-x*s, 1+c*(z*z-1)
]
}
function mul33(m, n) {
let m1 = m[0], m2 = m[1], m3 = m[2],
m4 = m[3], m5 = m[4], m6 = m[5],
m7 = m[6], m8 = m[7], m9 = m[8]
let n1 = n[0], n2 = n[1], n3 = n[2],
n4 = n[3], n5 = n[4], n6 = n[5],
n7 = n[6], n8 = n[7], n9 = n[8]
return [
m1*n1+m4*n2+m7*n3, m2*n1+m5*n2+m8*n3, m3*n1+m6*n2+m9*n3,
m1*n4+m4*n5+m7*n6, m2*n4+m5*n5+m8*n6, m3*n4+m6*n5+m9*n6,
m1*n7+m4*n8+m7*n9, m2*n7+m5*n8+m8*n9, m3*n7+m6*n8+m9*n9
]
}
function chainMul33(base) {
for(let i = 1, l = arguments.length; i < l; i++)
base = mul33(base, arguments[i])
return base
}
function dot(a, b) {
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
}
function cross(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]
]
}
function sub(a, b) {
return [a[0] - b[0], a[1] - b[1], a[2] - b[2]]
}
function add(a, b) {
return a.map ((d,i) => d + b[i])
}
function matrix (rotate, rotBase = [1,0,0,0,1,0,0,0,1]) {
let mx = rotate3dMatrix(1,0,0,rotate[0]),
my = rotate3dMatrix(0,1,0,rotate[1]),
mz = rotate3dMatrix(0,0,1,rotate[2])
let rotMatrix = chainMul33(mx, my, mz, rotBase)
return rotMatrix
}
/* *************************
* enty
*
*/
let enty = function enty() {}
enty.clip = clip
enty.comeCloser = comeCloser
enty.dist = dist
enty.normalize = normalize
enty.projection = projection
enty.rotateX = rotateX
enty.rotateY = rotateY
enty.rotateZ = rotateZ
enty.rotateMatrix = rotateMatrix
enty.transpose33 = transpose33
enty.rotate3dMatrix = rotate3dMatrix
enty.mul33 = mul33
enty.chainMul33 = chainMul33
enty.dot = dot
enty.cross = cross
enty.sub = sub
enty.add = add
enty.matrix = matrix
return enty
}
exports.muonWen = muonWen
}));
/***************************
* @renderRenderer
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.renderRenderer = global.renderRenderer || {})))
}(this, function (exports) { "use strict"
let renderRenderer = function renderRenderer(__mapper = {}) {
let props = __mapper("props")()
let width = props.width || 600
let height = props.height || 400
/***************************
* @enty
*/
let enty = function () {}
enty.width = function (_) {
if (_ === undefined) {
return width
} else {
width = _
return enty
}
}
enty.height = function (_) {
if (_ === undefined) {
return height
} else {
height = _
return enty
}
}
return enty
}
exports.renderRenderer = renderRenderer
}));
/***********
* @renderSVG
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.renderSVG = global.renderSVG || {})))
}(this, function (exports) { "use strict"
let renderSVG = function renderSVG(__mapper = {}) {
let f = __mapper("props")()
let state = {}
let updture = function (d) { // update boform to now
let dr = Object.assign({},d)
d.boform = d.boform || {}
dr.csx = (d.boform.now) ? now.boform.csx : d.boform.csx
dr.cf = (d.boform.now) ? now.boform.cf : d.boform.cf
dr.cs = (d.boform.now) ? now.boform.cs : d.boform.cs
dr.cw = (d.boform.now) ? now.boform.cw : d.boform.cw
dr.co = (d.boform.now) ? now.boform.co : d.boform.co
dr.cp = (d.boform.now) ? now.boform.cp : d.boform.cp
return dr
}
state.width = __mapper("xs").r("renderer").width()
state.height = __mapper("xs").r("renderer").height()
// https://bl.ocks.org/mbostock/3019563 // Margin Convention
let margin = {top: 20, right: 10, bottom: 20, left: 10}
let width = state.width - margin.left - margin.right,
height = state.height - margin.top - margin.bottom
let svglayer =
d3.select(".viewframe")
.append("svg")
.attr("id", "svglayer")
.attr("class", "svglayer")
.style("position", "absolute")
.attr("width", state.width)
.attr("height", state.height)
.style("top", 0)
.style("left", 0)
let svgElem = svglayer.append("rect")
.attr("id", "svg")
.attr("class", "svg")
.attr("width", state.width)
.attr("height", state.height)
.style("fill", "transparent")
.attr("pointer-events", "none")
.attr("overflow", "visible")
/* **************************
* @svg
*
*/
let svg = function svg () {
if (document.getElementById("viewframe") !== null) {
return d3.select("#viewframe")
} else {
return d3.select("#svg")
}
}
/* **************************
* @elems
*
*/
let elems = function elems(payload, data = ["data"], idfn = null) {
if ( d3.select(".muon-style-block").empty() ) {
d3.select("head").append("style").attr("class", "muon-style-block")
.html("")
}
if (payload == null ) { // if null return the layer
let svgLayer = d3.select("body").selectAll("svg").data(["svg"])
.enter().append("svg")
.attr("class", "svg")
.attr("id", "svg")
.attr("width", function() {return (typeof width !== "undefined") ? width : 600})
.attr("height", function() {return (typeof height !== "undefined") ? height : 400})
.style("border", "1px solid lightgray")
return svgLayer
}
else if (payload == "image") { // if image insert image
if ( d3.select(".image").empty() ) {
let img = svg.selectAll("image").data([0])
.enter()
.insert("svg:image")
.attr("xlink:href", "./image.jpg")
.attr("x", "0")
.attr("y", "0")
.attr("width", function() {return (typeof width !== "undefined") ? width : 600})
.attr("height", function() {return (typeof height !== "undefined") ? height : 400})
return img
}
}
// manage the dom elements
else if (typeof(payload) == "string") { // 'svg:g.links/path.link', data, idfn}
let parts = payload.split("/")
let layerpart = (parts[0]) ? parts[0] : "svg"
let elemspart = (parts[1]) ? parts[1] : null
let layerparts = layerpart.split(":")
let parentcls = (layerparts[0]) ? layerparts[0] : "svg"
let group = (layerparts[1]) ? layerparts[1] : "group"
let groupparts = group.split(".")
let groupref = (groupparts[0]) ? groupparts[0] : "g"
let layercls = (groupparts[1]) ? groupparts[1] : "layer"
let elemsparts = (elemspart) ? elemspart.split(".") : null
let elemtype = (elemsparts && elemsparts[0]) ? elemsparts[0] : "circle"
let elemcls = (elemsparts && elemsparts[1]) ? elemsparts[1] : "elems"
let layerMark = d3.select(parentcls).selectAll("." + layercls).data([layercls])
let layer = layerMark.enter().append("g")
.merge(layerMark)
.attr("class", layercls)
if (elemspart === null) {
return layer
} else {
if (!Array.isArray(data)) console.log("data is not an array")
let elemsupd = layer.selectAll("." + elemcls)
.data(data)
let elems = elemsupd
.enter().append(elemtype)
.merge(elemsupd)
.attr("class", elemcls)
let elemsExit = elemsupd.exit().remove()
return elems
}
}
}
/* **************************
* @render
*
*/
let render = function render (elapsed, anigrams, maxlimit) {
let features = __mapper("xs").m("geoj").geojize(anigrams) //
let svg = __mapper("renderSVG").svg()
let traceline = []
let gitems = d3.nest() // let framesByGid = f.groupBy(frames, "gid")
.key(function(d) { return d.properties.ric.gid })
.key(function(d) { return d.properties.ric.cid })
.entries(features) // features
for (let i in gitems) { // DOTS (seg5===0) each group gid
let gid = gitems[i].key, citems = gitems[i].values
for (let j in citems) { // each class cid
let cid = citems[j].key // cid
let fitems = citems[j].values // fitems
let now = fitems.slice(-1)[0]
let hmod = ((now||{}).hmod !== undefined) ? now.hmod : 1
let hquan = ((now||{}).hquan !== undefined) ? now.hquan : Infinity
/* ................. TEXTS ................. */
let texts = fitems
.filter(d => d.properties.sort === "text")
if (texts.length > 0) {
__mapper("renderSVG").elems("svg:g."+gid+"/text."+cid, texts, d=>d.id)
.text(d => d.properties.text)
.attr("x", d => d.geometry.coordinates[0]) // geo coord x
.attr("y", d => d.geometry.coordinates[1]) // geo coord y
.style("font-size", d => d.properties.style["font-size"])
.style("font-family", d => d.properties.style["font-family"])
.style("fill", d => d.properties.style.fill)
.style("stroke", d => d.properties.style.stroke)
.style("fill-opacity", d => d.properties.style["fill-opacity"])
.style("stroke-opacity", d => d.properties.style["stroke-opacity"])
.style("stroke-width", d => d.properties.style["stroke-width"])
.style("text-anchor", d => d.properties.style["text-anchor"])
}
/* ................. IMG ................. */
let imgs = fitems
.filter(d => d.properties.sort === "img")
if (imgs.length > 0) {
__mapper("renderSVG").elems("svg:g."+gid+"g."+cid, imgs, d=>d.id)
.data(() => imgs)
.append("svg:image")
.attr("d", d => d.properties.attr.img)
.attr("x", d => d.geometry.coordinates[0]) // geo coord x
.attr("y", d => d.geometry.coordinates[1]) // geo coord y
.attr("xlink:href", d => d.properties.attr["xlink:href"])
.attr("width", d => d.properties.attr.width)
.attr("height", d => d.properties.attr.height)
}
/* ................. GEOJSON FEATURE ................. */
let features = fitems
.filter(d => d.properties.sort === "feature") // __ geojson __
.filter((d,i) => (d.properties.delled !== 1)) // not delled
if (features.length > 0) {
__mapper("renderSVG").elems("svg:g."+gid+"/path."+cid, features, d=>d.id)
.attr("d", d => {
let object = d // .feature // geojson feature
let properties = object.properties || {} // geojson feature
let pointRadius = properties.pointRadius
let path = (pointRadius !== undefined) // geoPath
? d3.geoPath().pointRadius(pointRadius)
: d3.geoPath()
return path(object) // path
})
.style("fill", d => d.properties.style.fill)
.style("stroke", d => d.properties.style.stroke)
.style("fill-opacity", d => d.properties.style["fill-opacity"])
.style("stroke-opacity", d => d.properties.style["stroke-opacity"])
.style("stroke-width", d => d.properties.style["stroke-width"])
}
/* ................. END SVG FORMS ................. */
}
}
}
/* **************************
* @enty
*
*/
let enty = function enty() {}
enty.svg = svg
enty.elems = elems
enty.render = render
return enty
}
exports.renderSVG = renderSVG
}))
/***************************
* @renderWebgl
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.renderWebgl = global.renderWebgl || {})))
}(this, function (exports) { "use strict"
let renderWebgl = function renderWebgl(__mapper = {}) {
let state = {}
let radians = Math.PI / 180
state.width = __mapper("xs").r("renderer").width()
state.height = __mapper("xs").r("renderer").height()
state.renderer = new THREE.WebGLRenderer({antialias: true})
state.domElem = state.renderer.domElement // canvas
state.domElem.innerHTML = "" // Wipe DOM
state.domElem.style.display = "block"
state.context = state.domElem.getContext("webgl")
/* canvas */
d3.select(".viewframe")
.append(() => d3.select(state.domElem)
.attr("id", "canvas")
.attr("class", "overlay")
.style("position", "absolute; top:0px; left:0px; z-index:1")
.node()
)
/* navInfo */
state.navInfo = document.createElement("div") // Add nav info section
state.navInfo.classList.add("graph-nav-info")
state.navInfo.innerHTML = "MOVE mouse &amp; press LEFT/A: rotate, MIDDLE/S: zoom, RIGHT/D: pan"
document.body.appendChild(state.navInfo) // state.domElem.appendChild(navInfo);
/* tooltip */
state.toolTipElem = document.createElement("div") // Setup tooltip
state.toolTipElem.classList.add("graph-tooltip")
document.body.appendChild(state.toolTipElem) // state.domElem.appendChild(state.toolTipElem);
/* raycaster */
state.mouse = new THREE.Vector2()
state.mouse.x = -2 // Initialize off canvas
state.mouse.y = -2
state.mouse = __mapper("xs").c("raycaster").mouse()
state.toolTipElem.style.top = (state.mouse.y - 40) + "px" // Move tooltip
state.toolTipElem.style.left = (state.mouse.x - 20) + "px"
/* cameraPropsSet */
let cameraPropsSet = (camera, cameraProps) => {
if (cameraProps !== undefined) {
if ( cameraProps.rotate !== undefined) {
if (cameraProps.rotate[0] !== undefined) camera.rotation.x = cameraProps.rotate[0] * radians
if (cameraProps.rotate[1] !== undefined) camera.rotation.y = cameraProps.rotate[1] * radians
if (cameraProps.rotate[2] !== undefined) camera.rotation.z = cameraProps.rotate[2] * radians
}
if ( cameraProps.position !== undefined) {
if (cameraProps.position[0] !== undefined) camera.position.x = cameraProps.position[0]
if (cameraProps.position[1] !== undefined) camera.position.y = cameraProps.position[1]
if (cameraProps.position[2] !== undefined) camera.position.z = cameraProps.position[2]
}
}
return camera
}
/* camera container */
state.camera = new THREE.PerspectiveCamera(45, state.width / state.height, 0.1, 9000) // Setup camera
state.camera.position.x = 0
state.camera.position.y = 0
state.camera.position.z = 900
state.camera.rotation.x = 0
state.camera.rotation.y = 0
state.camera.rotation.z = 0
state.camera.distance2nodesFactor = 300
state.camera.lookAt(new THREE.Vector3(0, 0, 0))
function resizeCanvas() {
if (state.width && state.height) {
state.renderer.setSize(state.width, state.height)
state.camera.aspect = state.width/state.height
state.camera.updateProjectionMatrix()
}
}
resizeCanvas()
/* scene */
state.scene = new THREE.Scene() // Setup scene
state.scene.add(new THREE.AmbientLight(0x333333))
let light = new THREE.DirectionalLight(0xe4eef9, .7)
light.position.set(12, 12, 8)
/* controls */
__mapper("controlRaycaster").control(state.domElem) // state.domNode
state.raycaster = new THREE.Raycaster() // Capture mouse coords on move
state.controls = new TrackballControls(state.camera, state.domElem) // Add camera interaction
state.controls.rotateSpeed = 1.0
state.controls.zoomSpeed = 1.2
state.controls.panSpeed = 0.8
state.controls.noZoom = false
state.controls.noPan = false
state.controls.staticMoving = true
state.controls.dynamicDampingFactor = 0.3
state.controls.keys = [ 65, 83, 68 ]
// state.controls.addEventListener( 'change', () => console.log("control change") );
/* simulation */
state.vaNodes = []
state.vaLinks = []
/***************************
* @render
*/
let render = function (elapsed, anigrams, maxlimit) {
let features = __mapper("xs").m("geoj").geojize(anigrams)
/* clean canvas */
while(state.scene.children.length > 0){
state.scene.remove(state.scene.children[0]) // clear the scene
}
/* items to add to scene */
let gitems = d3.nest() // let framesByGid = f.groupBy(frames, "gid")
.key(function(d) { return d.properties.ric.gid })
.key(function(d) { return d.properties.ric.cid })
.entries(features)
for (let i in gitems) { // DOTS (seg5===0) each group gid
let gid = gitems[i].key, citems = gitems[i].values
for (let j in citems) { // each class cid
let cid = citems[j].key // cid
let fitems = citems[j].values // fitems
let now = fitems.slice(-1)[0]
let items = []
/* ................. GEOJSON FEATURE ................. */
items = fitems.filter(d => d.properties.sort === "feature")
if (items.length > 0) {
let denser = point => new THREE.Vector3(...point)
for (let k in items) { // DOTS (seg5===0) each group gid
let item = items[k] // feature
let feature = item // .feature
let style = item.properties.style
let geometry = feature.geometry // rings in MultiPolygon, MultiLineString
if (geometry.type === "Point") {
let node = item
state.material_color = style.fill
state.geometry = new THREE.SphereGeometry( 5, 32, 32 )
state.wireframe = new THREE.WireframeGeometry( state.geometry )
state.material = new THREE.MeshBasicMaterial( {
color: state.material_color,
transparent: true,
opacity: 0.75
})
let sphere = new THREE.Mesh(
state.wireframe,
state.material
)
sphere.position.x = node.x || node.geometry.coordinates[0]
sphere.position.y = node.y || node.geometry.coordinates[1] || 0
sphere.position.z = node.z || node.geometry.coordinates[2] || 0
state.scene.add(node._sphere = sphere)
} else if (geometry.type === "MultiPolygon") {
let threeMaterial = new THREE.LineBasicMaterial({
color: style.stroke,
opacity: style["stroke-opacity"],
})
for (let i=0; i<geometry.coordinates.length; i++) {
let coordinates = geometry.coordinates[i]
let threeGeometry = new THREE.Geometry
coordinates.forEach(function(line) {
d3.pairs(line.map(denser), function(a, b) {
threeGeometry.vertices.push(a, b)
})
let object = new THREE.LineSegments(threeGeometry, threeMaterial)
if (object) state.scene.add(object)
})
}
} else if (geometry.type === "LineString") {
let threeMaterial = new THREE.LineBasicMaterial({
color: style.stroke,
opacity: style["stroke-opacity"],
})
let coordinates = Array.of(geometry.coordinates)
let threeGeometry = new THREE.Geometry
coordinates.forEach(function(line) {
d3.pairs(line.map(denser), function(a, b) {
threeGeometry.vertices.push(a, b)
})
let object = new THREE.LineSegments(threeGeometry, threeMaterial)
if (object) state.scene.add(object)
})
} else {
let threeMaterial = new THREE.LineBasicMaterial({
color: style.stroke,
opacity: style["stroke-opacity"],
})
let coordinates = geometry.coordinates
let threeGeometry = new THREE.Geometry
coordinates.forEach(function(line) {
d3.pairs(line.map(denser), function(a, b) {
threeGeometry.vertices.push(a, b)
})
let object = new THREE.LineSegments(threeGeometry, threeMaterial)
if (object) state.scene.add(object)
})
}
}
}
/* ................. IMG ................. */
let imgs = fitems.filter(d => d.properties.sort === "img")
if (imgs.length > 0) {
for (let k in imgs) {
let img = imgs[k]
let href = img.properties.attr["xlink:href"]
let map = new THREE.TextureLoader().load( href )
let material = new THREE.SpriteMaterial( {
map: map,
color: 0xffffff,
fog: true
})
let threeMaterial = new THREE.Sprite( material )
threeMaterial.scale.set(200, 200, 1)
state.scene.add( threeMaterial )
}
}
/* ................. 3LINK ................. */
let threelinks = fitems.filter(d => d.properties.sort === "threelink")
if (threelinks.length > 0) {
for (let k in threelinks) {
let link = threelinks[k]
state.scene.add(link._line = link.line)
}
}
} // citems
} // gitems
if (state.mouse !== undefined) {
state.raycaster.setFromCamera(state.mouse, state.camera) // Update tooltip
const intersects = state.raycaster.intersectObjects(state.scene.children)
/* if (intersects.length > 0) console.log(" ****************** webgl intersects" , intersects) */
state.toolTipElem.innerHTML = intersects.length ? intersects[0].object.index || "Hi e" : "Hi e"
}
state.controls.update() // Frame cycle
state.renderer.render(state.scene, state.camera)
}
/***************************
* @enty
*/
let enty = function enty() {}
enty.render = render
return enty
}
exports.renderWebgl = renderWebgl
}))
/*******************************************
* @xs
*/
(function (global, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) :
typeof define === "function" && define.amd ? define(["exports"], factory) :
(factory((global.xs = global.xs || {})))
}(this, function (exports) { "use strict"
let xs = function (__mapper = {}) {
let f = __mapper({"props": bosonProps.bosonProps()}).props()
let item = function (params, pres = ["control", "force", "muon", "render", "shade"], ret=null) {
let cap = s => (s == null) ? "" : s.charAt(0).toUpperCase() + s.slice(1) // capitalize string
let nome = null
if (typeof(params) === "object") nome = params.nome
else if (typeof(params) === "string") nome = params
let itemNames = pres.reduce((p,q) => [...p, q+nome, q+cap(nome) ],[]) // item syn names
for (let i = 0; i < itemNames.length; i++) {
let itemName = itemNames[i]
if (__mapper(itemName) !== undefined) { // item in mapper
ret = __mapper(itemName)
break
} else if (enty[nome] !== undefined ) {
ret = enty[nome]()
break
} else {
let item
try {
item = eval(itemName) // eval
} catch(e) {
//
}
if (typeof item === "object") {
ret = __mapper({ // register in mapper
[itemName]: item[itemName](__mapper)
})[itemName] // item
break
} else if (typeof item === "function") {
ret = item
break
} else {
//
}
}
}
return ret
}
/*******************************************
* @enty
*/
let enty = function enty() {}
enty.item = enty.i = item
enty.boson = enty.b = function (params, pres = ["boson"], ret=null) {
return enty.item(params, pres = ["boson"], ret=null)
}
enty.control = enty.c = function (params, pres = ["control"], ret=null) {
return enty.item(params, pres = ["control"], ret=null)
}
enty.data = enty.d = function (params, pres = ["data"], ret=null) {
return enty.item(params, pres = ["data"], ret=null)
}
enty.force = enty.f = function (params, pres = ["force", "field"], ret=null) {
return enty.item(params, pres = ["force", "force", "field"], ret=null)
}
enty.geo = enty.g = function (params, pres = ["geojson", "proj"], ret=null) {
return enty.item(params, pres = ["geojson", "geo", "proj", "d3.geo"], ret=null)
}
enty.muon = enty.m = function (params, pres = ["muon", "mod", "plugin"], ret=null) {
return enty.item(params, pres = ["muon", "mod", "plugin"], ret=null)
}
enty.render = enty.r = function (params, pres = ["render"], ret=null) {
return enty.item(params, pres = ["render"], ret=null)
}
enty.halo = enty.h = function (params, pres = ["halo"], ret=null) {
return enty.item(params, pres = ["halo"], ret=null)
}
return enty
}
exports.xs = xs
}));
<!DOCTYPE html>
<meta charset="utf-8">
<title>animas</title>
<head >
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
div#fps,svg { position: fixed; top:0; left:0; color: white; }
</style>
</head>
<body style="cursor:crosshair"></body>
<div id="viewframe" class="viewframe"></div>
<script src='https://d3js.org/d3.v4.min.js'></script>
<script src='https://d3js.org/d3-geo.v1.min.js'></script>
<script src='https://d3js.org/d3-geo-projection.v2.min.js'></script>
<script src='https:////unpkg.com/d3-force-3d@1.0.7/build/d3-force-3d.bundle.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.0/topojson.min.js'></script>
<script src='https:////cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js'></script>
<script src='https:////unpkg.com/three-trackballcontrols-web@0.0.2/dist/three-trackballcontrols.min.js'></script>
<script src="enls.js"></script>
<script src="ents.js"></script>
<script>
let muonAlima = function muonAlima(__mapper) {
__mapper({"xs": xs.xs(__mapper)}) // PROXIES
__mapper("xs").b("init")({canvas:0,svg:1,versor:0,wen:1,webgl:0,img:1,gui:0,fps:0,stats:0}) // INIT
let renderer = __mapper("renderRenderer"),
width = renderer.width(),
height = renderer.height(),
scaleView = Math.min(width/2, height)/Math.PI
let f = __mapper({"props": bosonProps.bosonProps()}).props()
let g = __mapper("xs").m("geom")
let mwen = __mapper("xs").m("wen")
let cwen = __mapper("xs").c("wen")()
let bversor = __mapper("xs").b("versor")()
/*******************************************
* @pics
*/
let tim = {"td":36800,"t0":0,"t1":1000,"t2":1,"t3":1,}
let formCirc = {
"x": {
"m1":4,"m2":4,"n1":2,"n2":2,"n3":2,"a":1,"b":1, // circle
"ra2": 100,
"v0": 0, "v1": 1,
"seg5": [[[360,360]]],
"w4": [[[90 , 90 - 0 * 360]]],
"pa6":0,
"pb7":360,
"fas8": 0,
},
"y": {
"m1":4,"m2":4,"n1":2,"n2":2,"n3":2,"a":1,"b":1, // circle
"ra2": 100,
"v0": 0, "v1": 1,
"seg5": [[[360,360]]],
"w4": [[[90 , 90 - 0 * 360]]],
"pa6":0,
"pb7":360,
"fas8": -90,
},
}
let formNat = {
"x": {
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2": 100,
"v0": 0, "v1": 1,
"seg5": [[[360,360]]],
"w4": [[[90 , 90 - 0 * 360]]],
"pa6":0,
"pb7":360,
"fas8": 0,
},
"y": {
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2": 100,
"v0": 0, "v1": 1,
"seg5": [[[360,360]]],
"w4": [[[90 , 90 - 0 * 360]]],
"pa6":0,
"pb7":360,
"fas8": -90,
},
}
let stace = {
"m1":4,"m2":4,"n1":2,"n2":2,"n3":2,"a":4,"b":2, // circle
"ra2": 30,
"v0": 0,"v1": 1,
"w4": 0,
"seg5": 360,
"pa6": 0,
"pb7": -1,
"fas8": 0,
}
let proform = {
"projection": "uniwen",
"translate": [ [[[300,350]]], 200 ],
"scale": 1,
"rotate": [ 0, 0, [[[0,0]]] ],
"focale": 12,
"zafin": [1,0],
"dims": 2,
"control": "wen",
}
let boform = { "csx":0,"cf":[[[500,888,650]]],"co":[[[0.9,0.9]]],"cs":[[[111,666]]],"cw":[[[0.3,0.9]]],"cp":[[[0.7,0.9]]],}
let tureCirc = { "csx":0,"cf":[[[500,888,650]]],"co":[[[0.19,0.19]]],"cs":[[[111,666]]],"cw":[[[0.3,0.9]]],"cp":[[[0.7,0.9]]],}
/*******************************************
* @animas
*
*/
let nat = {
"tim": tim,
"ric": {"gid":"nat","cid":"nat","fid":"nat",},
"halo": "geojson",
"geoform": (p) => ({
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": Array.of(__mapper("xs").m("nat")
.multiconform(__mapper("xs").m("nat")
.nform(p.payload.form)))
},
"id": 0,
"properties": {}
}) ,
"stace": [[[ stace ]]],
"proform": proform,
"boform": boform,
"payload": { form:formNat },
}
let circ = {
"tim": tim,
"ric": {"gid":"nat","cid":"nat","fid":"circ",},
"halo": "geojson",
"geoform": (p) => ({
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": Array.of(__mapper("xs").m("nat")
.multiconform(__mapper("xs").m("nat")
.nform(p.payload.form)))
},
"id": 0,
"properties": {}
}),
"stace": [[[ stace ]]],
"proform": proform,
"boform": tureCirc,
"payload": { form:formCirc },
}
// ------------------------------- img
let img = {
"tim": tim,
"ric": {"gid":"img","cid":"img","fid":"img",},
"halo":"img",
"boform": { "csx":0,"cf":[[[22,22]]],"cs":22,"cw":[[[0.7,0.7]]],"co":[[[0.7,0.7,]]],"cp":[[[0.5,0.5]]],},
"geoform": p => ({
type: "Feature",
geometry: {
"type": "Point",
"coordinates": [0, 0]
},
properties: {
attr: {
"width": p.payload.img.width,
"height": p.payload.img.height,
["xlink:href"]: p.payload.img.url,
}
}
}),
"stace": {
"x": [[[15, 15]]],
"y": [[[20, 20]]],
},
"payload": {
"img": {
"url":"zimg-501.jpg",
"width": [[[60, 60]]],
"height": [[[40 , 40]]],
},
}
}
// ------------------------------- text
let text = {
"tim": tim,
"ric": {"gid":"text","cid":"text","fid":"text",},
"halo":"text",
"boform": { "csx":0,"cf":[[[111,111]]],"cs":111,"cw":[[[0.7,0.7]]],"co":[[[0.7,0.7,]]],"cp":[[[0.5,0.5]]],},
"geoform": p => ({
type: "Feature",
geometry: {
"type": "Point",
"coordinates": [0, 0]
},
properties: {
text: p.payload.text.text,
style: {
["font-size"]: p.payload.text.style["font-size"],
}
}
}),
"stace": {
"x": [[[150, 150]]],
"y": [[[200, 200]]],
},
"payload": {
"text": {
"text":"hi e",
"style": {
["font-size"]: 12,
["font-family"]: "BankFuturistic",
["text-anchor"]: "center",
}
},
}
}
let animas = [
nat, // h.geojson g.uniwen
circ, // h.geojson g.uniwen
img, // h.img
text, // h.text
]
return () => __mapper("xs").m("store").apply({"type":"UPDANIMA","caller":"alima","animas":animas})
}
let __mapper = bosonMapper.bosonMapper()
__mapper({"muonAlima": muonAlima(__mapper)}).muonAlima(__mapper)
</script>
<body style="cursor:crosshair"></body>
<!DOCTYPE html>
<meta charset="utf-8">
<title>animas</title>
<head >
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
div#fps,svg { position: fixed; top:0; left:0; color: white; }
</style>
</head>
<body style="cursor:crosshair"></body>
<div id="viewframe" class="viewframe"></div>
<script src="enls.js"></script>
<script src="ents.js"></script>
<script>
/*******************************************
* @alima
*/
let muonAlima = function muonAlima(__mapper) {
let f = __mapper({"props": bosonProps.bosonProps()}).props()
__mapper({"xs": xs.xs(__mapper)}) // PROXIES
__mapper("xs").b("init")({canvas:0,svg:1,versor:0,wen:1,webgl:0,img:1,gui:0,fps:0,stats:0}) // INIT
/*******************************************
* @pics
*/
let tim = {"td":36800,"t0":0,"t1":1000,"t2":1,"t3":1,}
let formCirc = {
"x": {
"m1":4,"m2":4,"n1":2,"n2":2,"n3":2,"a":1,"b":1, // circ
"ra2": 60,
"v0": 0, "v1": 1,
"seg5": [[[360,360]]],
"w4": [[[90 , 90 - 0 * 360]]],
"pa6":0,
"pb7":360,
"fas8": 0,
},
"y": {
"m1":4,"m2":4,"n1":2,"n2":2,"n3":2,"a":1,"b":1, // circ
"ra2": 60,
"v0": 0, "v1": 1,
"seg5": [[[360,360]]],
"w4": [[[90 , 90 - 0 * 360]]],
"pa6":0,
"pb7":360,
"fas8": -90,
},
}
let form = {
"x": {
"m1":2,"m2":2,"n1":0.3,"n2":-3,"n3":8,"a":8,"b":8, // egg
"ra2": 60,
"v0": 0, "v1": 1,
"seg5": [[[360,360]]],
"w4": [[[90 , 90 - 0 * 360]]],
"pa6":0,
"pb7":360,
"fas8": 0,
},
"y": {
"m1":2,"m2":2,"n1":0.3,"n2":-3,"n3":8,"a":8,"b":8, // egg
"ra2": 60,
"v0": 0, "v1": 1,
"seg5": [[[360,360]]],
"w4": [[[90 , 90 - 0 * 360]]],
"pa6":0,
"pb7":360,
"fas8": -90,
},
}
let stace =
{
"m1":4,"m2":4,"n1":2,"n2":2,"n3":2,"a":4,"b":2, // circle
"ra2": 30,
"v0": 0,"v1": 1,
"w4": 0,
"seg5": 360,
"pa6": 0,
"pb7": -1,
"fas8": 0,
}
let proform = {
"projections": ["uniwen","unidentity","identity","universor","unimercator"],
"projectidx": 0,
"translate": [ [[[200,250]]], 150 ],
"scale": 1.2,
"rotate": [ 0, 0, [[[0,0]]] ],
"focale": 12,
"zafin": [1,0],
"dims": 2,
"control": "wen",
}
let boform = { "csx":0,"cf":[[[500,888,650]]],"co":[[[0.9,0.9]]],"cs":[[[111,666]]],"cw":[[[0.3,0.9]]],"cp":[[[0.7,0.9]]],}
let boformCirc = { "csx":0,"cf":[[[500,888,650]]],"co":[[[0.19,0.19]]],"cs":[[[111,666]]],"cw":[[[0.3,0.9]]],"cp":[[[0.7,0.9]]],}
/*******************************************
* @animas
*
*/
let nat = {
"tim": tim,
"ric": {"gid":"nat","cid":"nat","fid":"nat",},
"halo": "nat",
"stace": [[[ stace ]]],
"boform": boform,
"proform": proform,
"payload":{"form": form},
}
let circ = {
"tim": tim,
"ric": {"gid":"nat","cid":"nat","fid":"formCirc",},
"halo": "nat",
"stace": [[[ stace ]]],
"boform": boformCirc,
"proform": proform,
"payload":{"form": formCirc},
}
/*******************************************
* @animaApi
*
*/
let animas = [
nat, // h.nat
circ, // h.nat
]
let animaApi = function animaApi() {
__mapper("xs").m("store").apply({"type":"UPDANIMA","caller":"alima","animas":animas})
}
return animaApi
}
let __mapper = bosonMapper.bosonMapper()
__mapper({"muonAlima": muonAlima(__mapper)}).muonAlima(__mapper)
</script>
<body style="cursor:crosshair"></body>
<!DOCTYPE html>
<meta charset="utf-8">
<title>animas</title>
<head >
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
div#fps,svg { position: fixed; top:0; left:0; color: white; }
</style>
</head>
<body style="cursor:crosshair"></body>
<div id="viewframe" class="viewframe"></div>
<script src="enls.js"></script>
<script src="ents.js"></script>
<script>
/*******************************************
* @alima
*/
let muonAlima = function muonAlima(__mapper) {
__mapper({"xs": xs.xs(__mapper)}) // PROXIES
__mapper("xs").b("init")({canvas:0,svg:1,versor:0,wen:1,webgl:0,img:1,gui:0,fps:0,stats:0}) // INIT
/**********************
* @libs
*/
let renderer = __mapper("renderRenderer"),
width = renderer.width(),
height = renderer.height(),
scaleView = Math.min(width/2, height)/Math.PI
let f = __mapper({"props": bosonProps.bosonProps()}).props()
/*******************************************
* @pics
*/
let tim = {"td":16800,"t0":0,"t1":1000,"t2":1,"t3":1,}
let formCirc = {
"x": {
"m1":4,"m2":4,"n1":2,"n2":2,"n3":2,"a":1,"b":1, // circ
"ra2": 100,
"v0": 0, "v1": 1,
"seg5": [[[360,360]]],
"w4": [[[90 , 90 - 0 * 360]]],
"pa6":0,
"pb7":360,
"fas8": 0,
},
"y": {
"m1":4,"m2":4,"n1":2,"n2":2,"n3":2,"a":1,"b":1, // circ
"ra2": 100,
"v0": 0, "v1": 1,
"seg5": [[[360,360]]],
"w4": [[[90 , 90 - 0 * 360]]],
"pa6":0,
"pb7":360,
"fas8": -90,
},
}
let form = {
"x": {
"m1":6,"m2":6,"n1":2,"n2":2,"n3":0,"a":2,"b":1, // tri
"m1":[[[2,6]]],"m2":[[[2,6]]],"n1":[[[0.3,2]]],"n2":[[[-3,2]]],"n3":[[[8,0]]],"a":[[[8,2]]],"b":[[[8,1]]], // tri
"m1":[[[2,6,6]]],"m2":[[[2,6,6]]],"n1":[[[0.3,2,2]]],"n2":[[[-3,2,2]]],"n3":[[[8,0,0]]],"a":[[[8,2,3]]],"b":[[[8,1,1]]], // tri
"ra2": 100,
"v0": 0, "v1": 1,
"seg5": [[[360,360]]],
"w4": [[[90 , 90 - 0 * 360]]],
"pa6":0,
"pb7":360,
"fas8": 0,
},
"y": {
"m1":6,"m2":6,"n1":2,"n2":2,"n3":0,"a":2,"b":1, // tri
"m1":[[[2,6]]],"m2":[[[2,6]]],"n1":[[[0.3,2]]],"n2":[[[-3,2]]],"n3":[[[8,0]]],"a":[[[8,2]]],"b":[[[8,1]]], // tri
"m1":[[[2,6,6]]],"m2":[[[2,6,6]]],"n1":[[[0.3,2,2]]],"n2":[[[-3,2,2]]],"n3":[[[8,0,0]]],"a":[[[8,2,3]]],"b":[[[8,1,1]]], // tri
"ra2": 100,
"v0": 0, "v1": 1,
"seg5": [[[360,360]]],
"w4": [[[90 , 90 - 0 * 360]]],
"pa6":0,
"pb7":360,
"fas8": -90,
},
}
let stace =
{
"m1":4,"m2":4,"n1":2,"n2":2,"n3":2,"a":4,"b":2, // circle
"ra2": 30,
"v0": 0,"v1": 1,
"w4": 0,
"seg5": 360,
"pa6": 0,
"pb7": -1,
"fas8": 0,
}
let proform = {
"projections": ["uniwen","unidentity","identity","universor","unimercator"],
"projectidx": 0,
"translate": [ [[[300,350]]], 200 ],
"scale": 1,
"rotate": [ 0, 0, [[[0,0]]] ],
"focale": 12,
"zafin": [1,0],
"dims": 2,
"control": "wen",
}
let boform = { "csx":0,"cf":[[[500,888,650]]],"co":[[[0.9,0.9]]],"cs":[[[111,666]]],"cw":[[[0.3,0.9]]],"cp":[[[0.7,0.9]]],}
let boformCirc = { "csx":0,"cf":[[[500,888,650]]],"co":[[[0.19,0.19]]],"cs":[[[444,666]]],"cw":[[[0.3,0.9]]],"cp":[[[0.9,0.9]]],}
/*******************************************
* @animas
*
*/
let nat = {
"tim": tim,
"ric": {"gid":"nat","cid":"nat","fid":"nat",},
"halo": "nat",
"stace": [[[ stace ]]],
"boform": boform,
"proform": proform,
"payload": { form:form },
}
let circ = {
"tim": tim,
"ric": {"gid":"nat","cid":"nat","fid":"formCirc",},
"halo": "nat",
"stace": [[[ stace ]]],
"boform": boformCirc,
"proform": proform,
"payload": { form:formCirc },
}
let img = {
"tim": tim,
"ric": {"gid":"img","cid":"img","fid":"img",},
"halo": "img",
"boform": { "csx":0,"cf":[[[22,22]]],"cs":22,"cw":[[[0.7,0.7]]],"co":[[[0.7,0.7,]]],"cp":[[[0.5,0.5]]],},
"geoform": p => ({
type: "Feature",
geometry: {
"type": "Point",
"coordinates": [0, 0]
},
properties: {
attr: {
"width": p.payload.img.width,
"height": p.payload.img.height,
["xlink:href"]: p.payload.img.url,
}
}
}),
"stace": {
"x": [[[15, 15]]],
"y": [[[20, 20]]],
},
"payload": {
"img": {
"url":"zimg-501.jpg",
"width": [[[60, 60]]],
"height": [[[40 , 40]]],
},
}
}
/*******************************************
* @animaApi
*
*/
let animas = [
nat, // h.nat
circ, // h.nat
img, // h.img
]
let animaApi = function animaApi() {
__mapper("xs").m("store").apply({"type":"UPDANIMA","caller":"alima","animas":animas})
}
return animaApi
}
let __mapper = bosonMapper.bosonMapper()
__mapper({"muonAlima": muonAlima(__mapper)}).muonAlima(__mapper)
</script>
<body style="cursor:crosshair"></body>
<!DOCTYPE html>
<meta charset="utf-8">
<title>animas</title>
<head >
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
div#fps,svg { position: fixed; top:0; left:0; color: white; }
</style>
</head>
<body style="cursor:crosshair"></body>
<div id="viewframe" class="viewframe"></div>
<script src='https://d3js.org/d3.v4.min.js'></script>
<script src='https://d3js.org/d3-geo.v1.min.js'></script>
<script src='https://d3js.org/d3-geo-projection.v2.min.js'></script>
<script src='https:////unpkg.com/d3-force-3d@1.0.7/build/d3-force-3d.bundle.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.0/topojson.min.js'></script>
<script src='https:////cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js'></script>
<script src='https:////unpkg.com/three-trackballcontrols-web@0.0.2/dist/three-trackballcontrols.min.js'></script>
<script src="enls.js"></script>
<script src="ents.js"></script>
<script>
let muonAlima = function muonAlima(__mapper) {
__mapper({"xs": xs.xs(__mapper)}) // PROXIES
__mapper("xs").b("init")({svg:1,versor:1,webgl:1,img:0}) // INIT
let f = __mapper({"props": bosonProps.bosonProps()}).props()
/*******************************************
* @pics
*
*/
let tim = {"td":3800,"t0":0,"t1":1000,"t2":1,"t3":1,}
let form = {
"x": {
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2":62,
"v0": 0,"v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": 0,
},
"y": {
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2": 62,
"v0":0,"v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": -90,
},
}
let proform = {
"projection": "uniwen",
"scale": 1.2,
"translate": [ [[[300,300]]], 200 ],
"rotate": [ 0, 0, [[[0,360]]] ],
"dims": 2,
}
/*******************************************
* @animas
*
*/
let geoform = {
"tim": tim,
"ric": {"gid":"geoform","cid":"geoform","fid":"geoform",},
"halo":"geojson",
"boform": { "csx":0,"cf":[[[666,666]]],"cs":666,"cw":[[[0.7,0.7]]],"co":[[[0.7,0.7,]]],"cp":[[[0.5,0.5]]],},
"geoform": (p) => ({
"type": "Feature",
"geometry": {
"type": "Polygon",
"coordinates": Array.of(__mapper("xs").m("nat")
.multiconform(__mapper("xs").m("nat")
.nform(p.payload.form)))
},
"id": 0,
"properties": {}
}),
"proform": proform,
"payload": { form:form },
}
let animas = [
geoform, // h.geojson g.uniwen
]
return () => __mapper("xs").m("store").apply({"type":"UPDANIMA","caller":"alima","animas":animas})
}
let __mapper = bosonMapper.bosonMapper()
__mapper({"muonAlima": muonAlima(__mapper)}).muonAlima(__mapper)
</script>
<body style="cursor:crosshair"></body>
<!DOCTYPE html>
<meta charset="utf-8">
<title>animas</title>
<head >
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
div#fps,svg { position: fixed; top:0; left:0; color: white; }
</style>
</head>
<body style="cursor:crosshair"></body>
<div id="viewframe" class="viewframe"></div>
<script src="enls.js"></script>
<script src="ents.js"></script>
<script>
let muonAlima = function muonAlima(__mapper) {
__mapper({"xs": xs.xs(__mapper)}) // PROXIES
__mapper("xs").b("init")({svg:1,versor:1,webgl:1,img:0}) // INIT
let f = __mapper({"props": bosonProps.bosonProps()}).props()
/*******************************************
* @pics
*
*/
let tim = {"td":3800,"t0":0,"t1":1000,"t2":1,"t3":1,}
let form = {
"x": {
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2":62,
"v0": 0,"v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": 0,
},
"y": {
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2": 62,
"v0":0,"v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": -90,
},
}
let proform = {
"projection": "uniwen",
"scale": 1.0,
"translate": [ [[[300,300]]], 100 ],
"rotate": [ 0, 0, [[[0, 0 * 360]]] ],
"dims": 2,
}
/*******************************************
* @animas
*
*/
let geoform = {
"tim": tim,
"ric": {"gid":"geoform","cid":"geoform","fid":"geoform",},
"halo":"geojson",
"boform": { "csx":0,"cf":[[[666,666]]],"cs":666,"cw":[[[0.7,0.7]]],"co":[[[0.7,0.7,]]],"cp":[[[0.5,0.5]]],},
"geoform": [[[ (p) => ({
"type": "LineString",
"coordinates": [
[90 + 0, 90 + 0],
[90 + 0, 90 + 60],
[90 + 60, 90 + 60],
[90 + 60, 90 + 0],
[90 + 0, [[[90 + 0, 360]]] ]
]
}) ]]],
"proform": proform,
}
let animas = [
geoform, // h.geojson g.uniwen
]
return () => __mapper("xs").m("store").apply({"type":"UPDANIMA","caller":"alima","animas":animas})
}
let __mapper = bosonMapper.bosonMapper()
__mapper({"muonAlima": muonAlima(__mapper)}).muonAlima(__mapper)
</script>
<body style="cursor:crosshair"></body>
<!DOCTYPE html>
<meta charset="utf-8">
<title>animas</title>
<head >
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
div#fps,svg { position: fixed; top:0; left:0; color: white; }
</style>
</head>
<body style="cursor:crosshair"></body>
<div id="viewframe" class="viewframe"></div>
<script src="enls.js"></script>
<script src="ents.js"></script>
<script>
let muonAlima = function muonAlima(__mapper) {
__mapper({"xs": xs.xs(__mapper)}) // PROXIES
__mapper("xs").b("init")({svg:1,versor:1,webgl:1,img:0}) // INIT
let f = __mapper({"props": bosonProps.bosonProps()}).props()
/*******************************************
* @pics
*
*/
let tim = {"td":3800,"t0":0,"t1":1000,"t2":1,"t3":1,}
let proform = {
"projection": "uniwen",
"scale": 0.1,
"translate": [ [[[300,300]]], 200 ],
"rotate": [ 0, 0, [[[0, 3 * 360]]] ],
"dims": 2,
}
/*******************************************
* @animas
*
*/
let geoform = {
"tim": tim,
"ric": {"gid":"geoform","cid":"geoform","fid":"geoform",},
"halo":"geojson",
"boform": { "csx":0,"cf":[[[666,666]]],"cs":666,"cw":[[[0.7,0.7]]],"co":[[[0.7,0.7,]]],"cp":[[[0.5,0.5]]],},
"geoform": {
"type": "Point",
"coordinates":
[180 + 0, [[[180 + 0, 360]]] ]
},
"proform": proform,
}
let animas = [
geoform, // h.geojson g.uniwen
]
return () => __mapper("xs").m("store").apply({"type":"UPDANIMA","caller":"alima","animas":animas})
}
let __mapper = bosonMapper.bosonMapper()
__mapper({"muonAlima": muonAlima(__mapper)}).muonAlima(__mapper)
</script>
<body style="cursor:crosshair"></body>
<!DOCTYPE html>
<meta charset="utf-8">
<title>animas</title>
<head >
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
div#fps,svg { position: fixed; top:0; left:0; color: white; }
</style>
</head>
<body style="cursor:crosshair"></body>
<div id="viewframe" class="viewframe"></div>
<script src="enls.js"></script>
<script src="ents.js"></script>
<script>
let muonAlima = function muonAlima(__mapper) {
__mapper({"xs": xs.xs(__mapper)}) // PROXIES
__mapper("xs").b("init")({svg:1,versor:1,webgl:1,img:0}) // INIT
let f = __mapper({"props": bosonProps.bosonProps()}).props()
/*******************************************
* @pics
*
*/
let tim = {"td":3800,"t0":0,"t1":1000,"t2":1,"t3":1,}
let form = {
"x": {
"m1":[[[4,4]]],"m2":[[[4,4]]],"n1":2,"n2":2,"n3":2,"a":1,"b":1,// circle
"m1":3,"m2":3,"n1":1,"n2":1,"n3":1,"a":1,"b":1,//
"m1":[[[4,8]]],"m2":[[[4,8]]],"n1":2,"n2":2,"n3":2,"a":1,"b":1,// circle
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2":62,
"v0": 0,"v1":1,
"w4": 0, // [[[0,0,0,-9 * 90,-9 * 90 ,0 ,0]]], // [[[180,360,180]]], // [[[0,-360,0]]],
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": 0,
},
"y": {
"m1":[[[4,4]]],"m2":[[[4,4]]],"n1":2,"n2":2,"n3":2,"a":1,"b":1, // circle
"m1":3,"m2":3,"n1":1,"n2":1,"n3":1,"a":1,"b":1,//
"m1":[[[4,8]]],"m2":[[[4,8]]],"n1":27,"n2":2,"n3":2,"a":1,"b":1,// circle
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2": 62,
"v0":0,"v1":1,
"w4": 0, // [[[0,0,0,-9 * 90,-9 * 90, 0 ,0]]], // [[[60, 60 + 1 * 360]]], // [[[0,-360,0]]],
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": -90, // fas8, antifase
},
}
let proform = {
"projection": "orthographic", "scale": [[[100,0.5]]],
"translate": [ 300, 200 ],
"rotate": [ [[[0, - 0 * 360]]], 0, 0 ],
"control": "versor",
}
/*******************************************
* @animas
*
*/
let geoform = {
"tim": tim,
"ric": {"gid":"geoform","cid":"geoform","fid":"geoform",},
"halo":"geojson",
"boform": { "csx":0,"cf":[[[666,666]]],"cs":666,"cw":[[[0.7,0.7]]],"co":[[[0.7,0.7,]]],"cp":[[[0.5,0.5]]],},
"geoform": [[[ () => {
let geo = Object.assign({},
topojson.feature(
__mapper("xs").d("worldTopo110m").data(),
__mapper("xs").d("worldTopo110m").data().objects.land
)
)
geo = __mapper("xs").m("geoj").trim(geo)
return geo
} ]]],
"proform": proform,
}
let animas = [
geoform, // h.geojson g.uniwen
]
return () => __mapper("xs").m("store").apply({"type":"UPDANIMA","caller":"alima","animas":animas})
}
let __mapper = bosonMapper.bosonMapper()
__mapper({"muonAlima": muonAlima(__mapper)}).muonAlima(__mapper)
</script>
<body style="cursor:crosshair"></body>
<!DOCTYPE html>
<meta charset="utf-8">
<title>animas</title>
<head >
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
div#fps,svg { position: fixed; top:0; left:0; color: white; }
</style>
</head>
<body style="cursor:crosshair"></body>
<div id="viewframe" class="viewframe"></div>
<script src='https://d3js.org/d3.v4.min.js'></script>
<script src='https://d3js.org/d3-geo.v1.min.js'></script>
<script src='https://d3js.org/d3-geo-projection.v2.min.js'></script>
<script src='https:////unpkg.com/d3-force-3d@1.0.7/build/d3-force-3d.bundle.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.0/topojson.min.js'></script>
<script src='https:////cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js'></script>
<script src='https:////unpkg.com/three-trackballcontrols-web@0.0.2/dist/three-trackballcontrols.min.js'></script>
<script src="enls.js"></script>
<script src="ents.js"></script>
<script>
let muonAlima = function muonAlima(__mapper) {
__mapper({"xs": xs.xs(__mapper)}) // PROXIES
__mapper("xs").b("init")({svg:1,wen:1,versor:1,img:0,webgl:1}) // INIT
let f = __mapper({"props": bosonProps.bosonProps()}).props()
let g = __mapper("xs").m("geom")
/*******************************************
* @port
*
*/
let r = __mapper("xs").r("renderer"),
width = r.width(),
height = r.height()
/*******************************************
* @pics
*/
let tim = {"td":18200,"t0":0,"t1":1000,"t2":1,"t3":1,}
let stace = {
"x": 0,
"y": 0,
"z": 0,
}
let proform = {
"projection": "hedrals",
"scale": 30,
"rotate": [ [[[0,-60]]], [[[0,-60]]], [[[0,-60]]] ],
"translate": [ 300, 200 ],
// "tree": [-1, 4, 5, 2, 0, 1],
"trees": [
[-1, 4, 5, 2, 0, 1],
[-1, 4, 5, 0, 0, 1],
[-1, 0, 0, 0, 0, 4],
[-1, 2, 3, 0, 1, 4],
[-1, 2, 0, 2, 1, 1],
[-1, 0, 1, 2, 1, 2],
[-1, 4, 1, 2, 0, 3],
[-1, 0, 1, 2, 1, 2],
[-1, 0, 1, 2, 0, 2],
[-1, 0, 1, 5, 0, 2],
],
"treeidx": [[[0,9.1,0]]],
"faciaRotation": [[[Math.PI / 1 ,Math.PI / 1]]],
"vertices": [
[-1, -1, 1], // 0 // 0
[ 1, -1, 1], // 1 // 1
[ 1, 1, 1], // 2 // 2
[-1, 1, 1], // 3 // 3
[-1, -1, -1], // 5 // 4
[ 1, -1, -1], // 4 // 5
[ 1, 1, -1], // 7 // 6
[-1, 1, -1], // 6 // 7
].map(g.normalize) // eg. [0.5773, -0.577, 0.5773]
.map(g.spherical) // eg. [-0.7853, 0.6154]
.map(g.to_degrees) ,
"faces": [
[1, 0, 3, 2, 1], // N
[1, 2, 6, 5, 1],
[2, 3, 7, 6, 2],
[3, 0, 4, 7, 3],
[0, 1, 5, 4, 0],
[5, 6, 7, 4, 5] // S
],
"control": "versor",
}
/*******************************************
* @animas
*
*/
// ------------------------------- geograt
let geograt = {
"tim": tim,
"ric": {"gid":"geograt","cid":"geograt","fid":"geograt",},
"halo":"geojson",
"geoform": (anitem) => {
let payload = anitem.payload
let graticule = payload.graticule
let grarr = __mapper("xs").m("graticule").grarr(graticule)
let mersCoords = grarr.mms.coordinates
let parsCoords = grarr.pps.coordinates
let coords = [].concat(mersCoords).concat(parsCoords)
let json = { type: "MultiLineString", coordinates: coords }
return json
},
"boform": { "csx":0,"cf":[[[111,111]]],"cs":666,"cw":0.39,"co":[[[0.5,0.5]]],"cp":[[[0.9,0.9]]],},
"proform": proform,
"payload": {
"graticule": {
"extent": [ [-180, 180, [[[30,45,30,45,30]]], [[[30,45,30,45,30]]]], [-90, 90, [[[12,6,12,6,12]]], [[[12,6,12,6,12]]]] ],
}
},
"stace": {} ,
}
// ------------------------------- geoearth
let geoearth = {
"tim": tim,
"ric": {"gid":"geoearth","cid":"geoearth","fid":"geoearth",},
"halo": "geojson",
"boform":{ "csx":0,
"cf":[[[555,333,555,333,555,333,555]]],
"cs":333,"cw":0.2,"co":0.4,"cp":0.9,},
"proform": proform,
"geoform": () => {
let geo = Object.assign({},
topojson.feature(
__mapper("xs").d("worldTopo110m").data(),
__mapper("xs").d("worldTopo110m").data().objects.land
)
)
geo = __mapper("xs").m("geoj").trim(geo)
return geo
} ,
}
// ------------------------------- geoearth
let geoshpere = {
"tim": tim,
"ric": {"gid":"geoshpere","cid":"geoshpere","fid":"geoshpere",},
"halo": "geojson",
"boform":{ "csx":0,"cf":444,"cs":333,"cw":0.9,"co":0.04,"cp":0.9,},
"proform": proform,
"geoform": {"type": "Sphere"}
}
// ------------------------------- img
let img = {
"tim": tim,
"ric": {"gid":"img","cid":"img","fid":"img",},
"halo":"img",
"boform": { "csx":0,"cf":[[[22,22]]],"cs":22,"cw":[[[0.7,0.7]]],"co":[[[0.7,0.7,]]],"cp":[[[0.5,0.5]]],},
"geoform": p => ({
type: "Feature",
geometry: {
"type": "Point",
"coordinates": [0, 0]
},
properties: {
attr: {
"width": p.payload.img.width,
"height": p.payload.img.height,
["xlink:href"]: p.payload.img.url,
}
}
}),
"stace": {
"x": [[[15, 15]]],
"y": [[[20, 20]]],
},
"payload": {
"img": {
"url":"zimg-501.jpg",
"width": [[[60, 60]]],
"height": [[[40 , 40]]],
},
}
}
// ------------------------------- text
let text = {
"tim": tim,
"ric": {"gid":"text","cid":"text","fid":"text",},
"halo":"text",
"boform": { "csx":0,"cf":[[[111,111]]],"cs":111,"cw":[[[0.7,0.7]]],"co":[[[0.7,0.7,]]],"cp":[[[0.5,0.5]]],},
"geoform": p => ({
type: "Feature",
geometry: {
"type": "Point",
"coordinates": [0, 0]
},
properties: {
text: p.payload.text.text,
style: {
["font-size"]: p.payload.text.style["font-size"],
}
}
}),
"stace": {
"x": [[[150, 150]]],
"y": [[[200, 200]]],
},
"payload": {
"text": {
"text":"hi e",
"style": {
["font-size"]: 12,
["font-family"]: "BankFuturistic",
["text-anchor"]: "center",
}
},
}
}
/*******************************************
* @animaApi
*
*/
let animas = [
geograt, // h.geojson
geoearth, // h.geojson
geoshpere, // h.geojson
img, // h.img
text, // h.text
]
let animaApi = function animaApi() {
__mapper("xs").m("store").apply({"type":"UPDANIMA","caller":"alima","animas":animas})
}
return animaApi
}
let __mapper = bosonMapper.bosonMapper()
__mapper({"muonAlima": muonAlima(__mapper)}).muonAlima(__mapper)
</script>
<body style="cursor:crosshair"></body>
<!DOCTYPE html>
<meta charset="utf-8">
<title>animas</title>
<head >
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
div#fps,svg { position: fixed; top:0; left:0; color: white; }
</style>
</head>
<body style="cursor:crosshair"></body>
<div id="viewframe" class="viewframe"></div>
<script src='https://d3js.org/d3.v4.min.js'></script>
<script src='https://d3js.org/d3-geo.v1.min.js'></script>
<script src='https://d3js.org/d3-geo-projection.v2.min.js'></script>
<script src='https:////unpkg.com/d3-force-3d@1.0.7/build/d3-force-3d.bundle.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.0/topojson.min.js'></script>
<script src='https:////cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js'></script>
<script src='https:////unpkg.com/three-trackballcontrols-web@0.0.2/dist/three-trackballcontrols.min.js'></script>
<script src="enls.js"></script>
<script src="ents.js"></script>
<script>
/*******************************************
* @alima
*
*/
let muonAlima = function muonAlima(__mapper) {
__mapper({"xs": xs.xs(__mapper)}) // PROXIES
__mapper("xs").b("init")({svg:1,wen:1,versor:1,img:0,webgl:1}) // INIT
let f = __mapper({"props": bosonProps.bosonProps()}).props() // props
let g = __mapper("xs").m("geom")
/*******************************************
* @port
*
*/
let r = __mapper("xs").r("renderer"),
width = r.width(),
height = r.height()
/*******************************************
* @pics
*/
let tim = {"td":18200,"t0":0,"t1":1000,"t2":1,"t3":1,}
let form = {
"x": {
"m1":[[[4,4]]],"m2":[[[4,4]]],"n1":2,"n2":2,"n3":2,"a":1,"b":1,// circle
"m1":3,"m2":3,"n1":1,"n2":1,"n3":1,"a":1,"b":1,//
"m1":[[[4,8]]],"m2":[[[4,8]]],"n1":2,"n2":2,"n3":2,"a":1,"b":1,// circling
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2": 162,
"v0": 0,"v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": 0,
},
"y": {
"m1":[[[4,4]]],"m2":[[[4,4]]],"n1":2,"n2":2,"n3":2,"a":1,"b":1, // circle
"m1":3,"m2":3,"n1":1,"n2":1,"n3":1,"a":1,"b":1,//
"m1":[[[4,8]]],"m2":[[[4,8]]],"n1":27,"n2":2,"n3":2,"a":1,"b":1,// circling
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2": 162,
"v0":0,"v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": 0,
},
"z": {
"m1":[[[3,3]]],"m2":[[[3,3]]],"n1":1,"n2":1,"n3":1,"a":1,"b":1, // tri
"ra2": 30,
"v0": 0,"v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": 0,
}
}
let stace = {
"x": 0,
"y": 0,
"z": 0,
}
let graticule = {
"extent": [ [-180, 180, [[[30,45,30,45,30]]], [[[30,45,30,45,30]]]], [-90, 90, [[[12,6,12,6,12]]], [[[12,6,12,6,12]]]] ],
}
let proform = {
"projection": "futuri",
"scale": 30,
"rotate": [ [[[0,-60]]], [[[0,-60]]], [[[0,-60]]] ],
"translate": [ 300, 200 ],
"faciaRotation": [[[Math.PI / 1 ,Math.PI / 1]]],
"control": "versor",
}
let payload = {
"scale": 1,
"rotate": [28,-4,0],
"tree": [-1, 4, 5, 2, 0, 1], // [-1, 0, 0 , 0, 0, 4 ], //
"faciaRotation": Math.PI / 4,
"vertices": [
[-1, -1, 1], // 0 // 0
[ 1, -1, 1], // 1 // 1
[ 1, 1, 1], // 2 // 2
[-1, 1, 1], // 3 // 3
[-1, -1, -1], // 5 // 4
[ 1, -1, -1], // 4 // 5
[ 1, 1, -1], // 7 // 6
[-1, 1, -1], // 6 // 7
],
"polyhedron": [
[1, 0, 3, 2, 1], // N
[1, 2, 6, 5, 1],
[2, 3, 7, 6, 2],
[3, 0, 4, 7, 3],
[0, 1, 5, 4, 0],
[5, 6, 7, 4, 5] // S
],
"graticule": {
"extent": [ [-180, 180, [[[30,45,30,45,30]]], [[[30,45,30,45,30]]]], [-90, 90, [[[12,6,12,6,12]]], [[[12,6,12,6,12]]]] ],
}
}
/*******************************************
* @animas
*
*/
// ------------------------------- geoline
let geoline = {
"tim": tim,
"ric": {"gid":"geoform","cid":"geoform","fid":"geoline",},
"halo":"geojson",
"boform": { "csx":0,"cf":[[[666,666]]],"cs":666,"cw":[[[0.7,0.7]]],"co":[[[0.7,0.7,]]],"cp":[[[0.5,0.5]]],},
"geoform": [[[ () => ({
"type": "LineString",
"coordinates": [
[-90, 0],
[90 , [[[0, 0]]] ]
]
}) ]]],
"proform": proform,
}
// ------------------------------- geopoint
let geopoint = {
"tim": tim,
"ric": {"gid":"geoform","cid":"geoform","fid":"geopoint",},
"halo":"geojson",
"boform": { "csx":0,"cf":[[[666,666]]],"cs":666,"cw":[[[0.7,0.7]]],"co":[[[0.7,0.7,]]],"cp":[[[0.5,0.5]]],},
"geoform": [[[ () => ({
"type": "Point",
"coordinates": [0,90]
}) ]]],
"proform": proform,
}
// ------------------------------- geograt
let geograt = {
"tim": tim,
"ric": {"gid":"geograt","cid":"geograt","fid":"geograt",},
"halo":"geojson",
"geoform": (anitem) => {
let payload = anitem.payload
let graticule = payload.graticule
let grarr = __mapper("xs").m("graticule").grarr(graticule)
let mersCoords = grarr.mms.coordinates
let parsCoords = grarr.pps.coordinates
let coords = [].concat(mersCoords).concat(parsCoords)
let json = { type: "MultiLineString", coordinates: coords }
return json
},
"boform": { "csx":0,"cf":[[[111,111]]],"cs":666,"cw":0.49,"co":[[[0.5,0.5]]],"cp":[[[0.9,0.9]]],},
"proform": {
"projection": "futuri",
"scale": 30,
"translate": [ 300, 200 ],
"rotate": [ [[[0,-60]]], [[[0,-60]]], [[[0,-60]]] ],
"step": [[[0,0,1.1,1.1,0,0]]],
"prjlat": [[[1,1]]],
"prjlagr": [[[0.5,0.5]]],
"prjrad": [[[2,2]]],
"faciaRotation": [[[Math.PI / 1 ,Math.PI / 1]]],
"control": "versor",
},
"payload": {
"graticule": {
"extent": [ [-180, 180, [[[30,45,30,45,30]]], [[[30,45,30,45,30]]]], [-90, 90, [[[12,6,12,6,12]]], [[[12,6,12,6,12]]]] ],
}
},
"stace": {
"x": 0,
"y": 0,
"z": 0,
},
}
// ------------------------------- geoearth
let geoearth = {
"tim": tim,
"ric": {"gid":"geoearth","cid":"geoearth","fid":"geoearth",},
"halo": "geojson",
"boform":{ "csx":0,"cf":[[[555,333,555,333,555,333,555]]],"cs":333,"cw":0.2,"co":0.4,"cp":0.9,},
"geoform": () => {
let geo = Object.assign({},
topojson.feature(
__mapper("xs").d("worldTopo110m").data(),
__mapper("xs").d("worldTopo110m").data().objects.land
)
)
geo = __mapper("xs").m("geoj").trim(geo)
return geo
},
"proform": {
"projection": "hedrals",
"scale": 30,
"rotate": [28,-4,0],
"translate": [ 300, 200 ],
"tree": [-1, 4, 5, 2, 0, 1], // [-1, 0, 0 , 0, 0, 4 ], //
"faciaRotation": [[[Math.PI / 1 ,Math.PI / 1]]],
"vertices": [
[-1, -1, 1], // 0 // 0
[ 1, -1, 1], // 1 // 1
[ 1, 1, 1], // 2 // 2
[-1, 1, 1], // 3 // 3
[-1, -1, -1], // 5 // 4
[ 1, -1, -1], // 4 // 5
[ 1, 1, -1], // 7 // 6
[-1, 1, -1], // 6 // 7
].map(g.normalize) // eg. [0.5773, -0.577, 0.5773]
.map(g.spherical) // eg. [-0.7853, 0.6154]
.map(g.to_degrees),
"faces": [
[1, 0, 3, 2, 1], // N
[1, 2, 6, 5, 1],
[2, 3, 7, 6, 2],
[3, 0, 4, 7, 3],
[0, 1, 5, 4, 0],
[5, 6, 7, 4, 5] // S
],
"control": "versor",
},
}
// ------------------------------- geoform
let geoform = {
"tim": tim,
"ric": {"gid":"geoform","cid":"geoform","fid":"geoform",},
"halo":"geojson",
"boform": { "csx":0,"cf":[[[666,666]]],"cs":666,"cw":[[[0.7,0.7]]],"co":[[[0.7,0.7,]]],"cp":[[[0.5,0.5]]],},
"geoform": (ani) => ({
"type": "Polygon",
"coordinates": [ [
[0 + 0, 0 + 0],
[0 + 0, 0 + 60],
[0 + 60, 0 + 60],
[0 + 60, 0 + 0],
[0 + 0, 0 + 0 ]
] ]
}),
"proform": proform,
}
// ------------------------------- geosphere
let geosphere = {
"tim": tim,
"ric": {"gid":"geosphere","cid":"geosphere","fid":"geosphere",},
"halo":"geojson",
"boform":{ "csx":0,"cf":444,"cs":333,"cw":0.9,"co":0.04,"cp":0.9,},
"proform":proform,
"geoform": () => ({"type": "Sphere"})
}
/*******************************************
* @animaApi
*
*/
let animas = [
geograt, // h.geograt g.futuri
geoearth, // h.geojson g.hedrals
geosphere, // h.geojson g.futuri
geoform, // h.geojson g.futuri
geoline, // h.geojson g.futuri
geopoint, // h.geojson g.futuri
]
let animaApi = function animaApi() {
__mapper("xs").m("store").apply({"type":"UPDANIMA","caller":"alima","animas":animas})
}
return animaApi
}
let __mapper = bosonMapper.bosonMapper()
__mapper({"muonAlima": muonAlima(__mapper)}).muonAlima(__mapper)
</script>
<body style="cursor:crosshair"></body>
<!DOCTYPE html>
<meta charset="utf-8">
<title>animas</title>
<head >
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
div#fps,svg { position: fixed; top:0; left:0; color: white; }
</style>
</head>
<body style="cursor:crosshair"></body>
<div id="viewframe" class="viewframe"></div>
<script src='https://d3js.org/d3.v4.min.js'></script>
<script src='https://d3js.org/d3-geo.v1.min.js'></script>
<script src='https://d3js.org/d3-geo-projection.v2.min.js'></script>
<script src='https:////unpkg.com/d3-force-3d@1.0.7/build/d3-force-3d.bundle.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.0/topojson.min.js'></script>
<script src='https:////cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js'></script>
<script src='https:////unpkg.com/three-trackballcontrols-web@0.0.2/dist/three-trackballcontrols.min.js'></script>
<script src="enls.js"></script>
<script src="ents.js"></script>
<script>
let muonAlima = function muonAlima(__mapper) {
__mapper({"xs": xs.xs(__mapper)}) // PROXIES
__mapper("xs").b("init")({canvas:0,svg:0,versor:0,wen:0,webgl:1,img:0,gui:0,fps:0,stats:0}) // INIT
let renderer = __mapper("renderRenderer"),
width = renderer.width(),
height = renderer.height(),
scaleProj = Math.min(width/2, height)/Math.PI
/*******************************************
* @pics
*
*/
let tim = {"td":19800,"t0":0,"t1":1000,"t2":1,"t3":1,}
let form = {
"x": {
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2": 250,
"v0": 0, "v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": 0,
},
"y": {
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2": 250,
"v0":0,"v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": 0,
},
"z": {
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2": 250,
"v0": 0, "v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": 0,
}
}
let stace = {
"x": 0,
"y": 0,
"z": 0,
}
let graticule = {
"extent": [ [-180, 180, [[[45,45]]], 45], [-180, 180, 22.5, 22.5] ],
}
let conform = {
"projection": "natform",
"form": form,
}
let proform = {
"projection": "uniwen",
}
// ------------------------------- threegrat
let threegrat = {
"tim": tim,
"ric": {"gid":"threegrat","cid":"threegrat","fid":"threegrat",},
"halo":"geojson",
"boform":{ "csx":0,"cf":[[[666,666]]],"cs":333,"cw":0.3,"co":[[[0.3,0.3,0.3]]],"cp":[[[0.3,0.3,0.3]]],},
"geoform": (p) => {
let grarrx = __mapper("xs").m("graticule").grarrx(p.payload.graticule)
return {type: "MultiLineString", coordinates: grarrx}
},
"conform": conform,
"stace": stace,
"payload": { "graticule": graticule, },
x: 25,
y: 25,
z: 25,
}
// ------------------------------- earth
let earth = {
"tim": tim,
"ric": {"gid":"earth","cid":"earth","fid":"earth",},
"halo":"geojson",
"boform":{ "csx":0,"cf":777,"cs":777,"cw":0.3,"co":[[[0.7,0.7,0.7]]],"cp":[[[0.7,0.7,0.7]]],},
"geoform": ()=> {
let json = Object.assign({},
topojson.mesh(
__mapper("xs").d("worldTopo110m").data(),
__mapper("xs").d("worldTopo110m").data().objects.land
)
)
json = __mapper("xs").m("geoj").trim(json)
return json
},
"stace": stace,
"conform": conform,
"proform": proform,
}
// ------------------------------- img
let img = {
"tim": tim,
"ric": {"gid":"img","cid":"img","fid":"img",},
"halo":"img",
"boform": { "csx":0,"cf":[[[22,22]]],"cs":22,"cw":[[[0.7,0.7]]],"co":[[[0.7,0.7,]]],"cp":[[[0.5,0.5]]],},
"geoform": p => ({
type: "Feature",
geometry: {
"type": "Point",
"coordinates": [0, 0]
},
properties: {
attr: {
"width": p.payload.img.width,
"height": p.payload.img.height,
["xlink:href"]: p.payload.img.url,
}
}
}),
"stace": {
"x": [[[15, 15]]],
"y": [[[20, 20]]],
},
"payload": {
"img": {
"url":"zimg-501.jpg",
"width": [[[60, 60]]],
"height": [[[40 , 40]]],
},
}
}
/*******************************************
* @animas
*
*/
let animas = [
img, // h.img
threegrat, // h.geojson g.natform
earth, // h.geojson g.natform
]
let animaApi = function animaApi() {
__mapper("xs").m("store").apply({"type":"UPDANIMA","caller":"alima","animas":animas})
}
return animaApi
}
let __mapper = bosonMapper.bosonMapper()
__mapper({"muonAlima": muonAlima(__mapper)}).muonAlima(__mapper)
</script>
<body style="cursor:crosshair"></body>
<!DOCTYPE html>
<meta charset="utf-8">
<title>animas</title>
<head >
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
div#fps,svg { position: fixed; top:0; left:0; color: white; }
</style>
</head>
<body style="cursor:crosshair"></body>
<div id="viewframe" class="viewframe"></div>
<script src='https://d3js.org/d3.v4.min.js'></script>
<script src='https://d3js.org/d3-geo.v1.min.js'></script>
<script src='https://d3js.org/d3-geo-projection.v2.min.js'></script>
<script src='https:////unpkg.com/d3-force-3d@1.0.7/build/d3-force-3d.bundle.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.0/topojson.min.js'></script>
<script src='https:////cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js'></script>
<script src='https:////unpkg.com/three-trackballcontrols-web@0.0.2/dist/three-trackballcontrols.min.js'></script>
<script src="enls.js"></script>
<script src="ents.js"></script>
<script>
let muonAlima = function muonAlima(__mapper) {
__mapper({"xs": xs.xs(__mapper)}) // PROXIES
__mapper("xs").b("init")({svg:1,versor:0,wen:1,webgl:1})
let f = __mapper({"props": bosonProps.bosonProps()}).props()
let g = __mapper("xs").m("geom")
let w = __mapper("xs").m("wen")
/**********************
* @
*/
let r = __mapper("xs").r("renderer"),
width = r.width(),
height = r.height()
let rotInit = [0,45,0],
rotation = [0,0,0],
rotMatrix,
stars = []
let versor = __mapper("xs").b("versor")()
let wen = __mapper("xs").c("wen")({rotInit})
/*******************************************
* @pics
*
*/
let tim = {"td":19800,"t0":0,"t1":1000,"t2":1,"t3":1,}
let form = {
"x": {
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2": 250,
"v0": 0, "v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": 0,
},
"y": {
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2": 250,
"v0":0,"v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": 0,
},
"z": {
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2": 250 / Math.sqrt(2),
"v0": 0, "v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": 0,
}
}
/*******************************************
* @animas
*
*/
let aniCube = {
"tim": tim,
"ric": {"gid":"aniCube","cid":"aniCube","fid":"aniCube",},
"halo": "geojson",
"boform":{ "csx":0,"cf":111,"cs":111,"cw":0.1,"co":0.9,"cp":0.9,},
"geoform": (p) => {
let payload = p.payload
let ric = p.ric
let json = {type: "FeatureCollection", features: []}
let vertices = payload.vertices // payload.vertices
let faces = payload.faces // payload.faces
for (let i = 0, l = faces.length; i < l; i++) {
let face = faces[i] // face corners position
let geometry = {type:"Polygon",coordinates:[]}
geometry.coordinates = face.corners.map(k=>vertices[k]) // eg [-1, 1, 1]
.map(g.normalize) // eg. [0.5773, -0.577, 0.5773]
.map(g.spherical) // eg. [-0.7853, 0.6154]
.map(g.to_degrees)
geometry.coordinates = Array.of(geometry.coordinates)
let feature = {type:"Feature",geometry:{},properties:{}}
feature.properties.ric = ric
feature.properties.ric.cid = "face"
feature.properties.ric.fid = i // face.name
feature.properties.sort = "feature"
feature.geometry = geometry
feature.properties.boform = face.boform
json.features.push(feature)
}
return json
},
"conform": {
"projection": "natform",
"form": form,
},
"proform": {
"projection": "uniwen",
"translate": [ 320 , 200],
"scale": 1,
"rotate": [-5,50,0],
"focale": 400,
"zafin": [ [[[0,0,1,1,1,0]]], [[[0,0,1,1,1,0]]] ], // [0,1], // [1,0]
"dims": 3,
"control": "wen",
},
"payload": {
vertices: [
[-1, -1, 1], // 0
[ 1, -1, 1], // 1
[ 1, 1, 1], // 2
[-1, 1, 1], // 3
[ 1, -1, -1], // 4
[-1, -1, -1], // 5
[-1, 1, -1], // 6
[ 1, 1, -1], // 7
],
faces: [
{
corners: [0,1,2,3,0],
name: "front",
boform: { cf: 222, cs: 355, co: [[[0.2,0.09,0.9,0.2]]], cp: 1, }},
{
corners: [4,5,6,7,4],
name: "back",
boform: { cf: 888, cs: 455, co: [[[0.2,0.09,0.9,0.2]]], cp: 1, }},
{
corners: [1,4,7,2,1],
name: "right",
boform: { cf: 444, cs: 555, co: [[[0.2,0.09,0.9,0.2]]], cp: 1, }},
{
corners: [5,0,3,6,5],
name: "left",
boform: { cf: 555, cs: 655, co: [[[0.2,0.09,0.9,0.2]]], cp: 1, }},
{
corners: [3,2,7,6,3],
name: "bottom",
boform: { cf: 666, cs: 755, co: [[[0.2,0.09,0.9,0.2]]], cp: 1, }},
{
corners: [5,4,1,0,5],
name: "top",
boform: { cf: 777, cs: 855, co: [[[0.2,0.09,0.9,0.2]]], cp: 1, }}
],
}
}
// ------------------------------- img
let img = {
"tim": tim,
"ric": {"gid":"img","cid":"img","fid":"img",},
"halo":"img",
"boform": { "csx":0,"cf":[[[22,22]]],"cs":22,"cw":[[[0.7,0.7]]],"co":[[[0.7,0.7,]]],"cp":[[[0.5,0.5]]],},
"geoform": p => ({
type: "Feature",
geometry: {
"type": "Point",
"coordinates": [0, 0]
},
properties: {
attr: {
"width": p.payload.img.width,
"height": p.payload.img.height,
["xlink:href"]: p.payload.img.url,
}
}
}),
"stace": {
"x": [[[15, 15]]],
"y": [[[20, 20]]],
},
"payload": {
"img": {
"url":"zimg-501.jpg",
"width": [[[60, 60]]],
"height": [[[40 , 40]]],
},
}
}
/*******************************************
* @animas
*
*/
let animas = [
aniCube, // h.geojson g.uniwen
// img, // h.img
]
let animaApi = function animaApi() {
__mapper("xs").m("store").apply({"type":"UPDANIMA","caller":"alima","animas":animas})
}
return animaApi
}
let __mapper = bosonMapper.bosonMapper()
__mapper({"muonAlima": muonAlima(__mapper)}).muonAlima(__mapper)
</script>
<body style="cursor:crosshair"></body>
<!DOCTYPE html>
<meta charset="utf-8">
<title>animas</title>
<head >
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
div#fps,svg { position: fixed; top:0; left:0; color: white; }
</style>
</head>
<body style="cursor:crosshair"></body>
<div id="viewframe" class="viewframe"></div>
<script src='https://d3js.org/d3.v4.min.js'></script>
<script src='https://d3js.org/d3-geo.v1.min.js'></script>
<script src='https://d3js.org/d3-geo-projection.v2.min.js'></script>
<script src='https:////unpkg.com/d3-force-3d@1.0.7/build/d3-force-3d.bundle.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.0/topojson.min.js'></script>
<script src='https:////cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js'></script>
<script src='https:////unpkg.com/three-trackballcontrols-web@0.0.2/dist/three-trackballcontrols.min.js'></script>
<script src="enls.js"></script>
<script src="ents.js"></script>
<script>
let muonAlima = function muonAlima(__mapper) {
__mapper({"xs": xs.xs(__mapper)}) // PROXIES
__mapper("xs").b("init")({svg:1,versor:0,wen:1,webgl:1})
let f = __mapper({"props": bosonProps.bosonProps()}).props()
let g = __mapper("xs").m("geom")
let w = __mapper("xs").m("wen")
/**********************
* @
*/
let r = __mapper("xs").r("renderer"),
width = r.width(),
height = r.height()
let rotInit = [0,45,0],
rotation = [0,0,0],
rotMatrix,
stars = []
let versor = __mapper("xs").b("versor")()
let wen = __mapper("xs").c("wen")({rotInit})
/*******************************************
* @animas
*
*/
let tim = {"td":19800,"t0":0,"t1":1000,"t2":1,"t3":1,}
let aniCube = {
"tim": tim,
"ric": {"gid":"aniCube","cid":"aniCube","fid":"aniCube",},
"halo": "geojson",
"boform":{ "csx":0,"cf":111,"cs":111,"cw":0.1,"co":0.9,"cp":0.9,},
"geoform": (p) => {
let payload = p.payload
let ric = p.ric
let json = {type: "FeatureCollection", features: []}
let vertices = payload.vertices // payload.vertices
let faces = payload.faces // payload.faces
for (let i = 0, l = faces.length; i < l; i++) {
let face = faces[i] // face corners position
let geometry = {type:"Polygon",coordinates:[]}
geometry.coordinates = Array.of(face.corners.map(k=>vertices[k])) // eg [-1, 1, 1]
let feature = {type:"Feature",geometry:{},properties:{}}
feature.properties.ric = ric
feature.properties.ric.cid = "face"
feature.properties.ric.fid = i // face.name
feature.properties.sort = "feature"
feature.geometry = geometry
feature.properties.boform = face.boform
json.features.push(feature)
}
return json
},
"proform": {
"projection": "uniwen",
"translate": [ 280 , 200],
"scale": 60,
"rotate": [-5,50,0],
"focale": 4,
"zafin": [ [[[0,0,1,1,1,0]]], [[[0,0,1,1,1,0]]] ], // [0,1], // [1,0]
"dims": 3,
"control": "wen",
},
"payload": {
vertices: [
[-1, -1, 1], // 0
[ 1, -1, 1], // 1
[ 1, 1, 1], // 2
[-1, 1, 1], // 3
[ 1, -1, -1], // 4
[-1, -1, -1], // 5
[-1, 1, -1], // 6
[ 1, 1, -1], // 7
],
faces: [
{
corners: [0,1,2,3,0],
name: "front",
boform: { cf: 222, cs: 355, co: [[[0.2,0.09,0.9,0.2]]], cp: 1, }},
{
corners: [4,5,6,7,4],
name: "back",
boform: { cf: 888, cs: 455, co: [[[0.2,0.09,0.9,0.2]]], cp: 1, }},
{
corners: [1,4,7,2,1],
name: "right",
boform: { cf: 444, cs: 555, co: [[[0.2,0.09,0.9,0.2]]], cp: 1, }},
{
corners: [5,0,3,6,5],
name: "left",
boform: { cf: 555, cs: 655, co: [[[0.2,0.09,0.9,0.2]]], cp: 1, }},
{
corners: [3,2,7,6,3],
name: "bottom",
boform: { cf: 666, cs: 755, co: [[[0.2,0.09,0.9,0.2]]], cp: 1, }},
{
corners: [5,4,1,0,5],
name: "top",
boform: { cf: 777, cs: 855, co: [[[0.2,0.09,0.9,0.2]]], cp: 1, }}
],
}
}
// ------------------------------- img
let img = {
"tim": tim,
"ric": {"gid":"img","cid":"img","fid":"img",},
"halo":"img",
"boform": { "csx":0,"cf":[[[22,22]]],"cs":22,"cw":[[[0.7,0.7]]],"co":[[[0.7,0.7,]]],"cp":[[[0.5,0.5]]],},
"geoform": p => ({
type: "Feature",
geometry: {
"type": "Point",
"coordinates": [0, 0]
},
properties: {
attr: {
"width": p.payload.img.width,
"height": p.payload.img.height,
["xlink:href"]: p.payload.img.url,
}
}
}),
"stace": {
"x": [[[15, 15]]],
"y": [[[20, 20]]],
},
"payload": {
"img": {
"url":"zimg-501.jpg",
"width": [[[60, 60]]],
"height": [[[40 , 40]]],
},
}
}
/*******************************************
* @animas
*
*/
let animas = [
aniCube, // h.geojson g.uniwen
img, // h.img
]
let animaApi = function animaApi() {
__mapper("xs").m("store").apply({"type":"UPDANIMA","caller":"alima","animas":animas})
}
return animaApi
}
let __mapper = bosonMapper.bosonMapper()
__mapper({"muonAlima": muonAlima(__mapper)}).muonAlima(__mapper)
</script>
<body style="cursor:crosshair"></body>
<!DOCTYPE html>
<meta charset="utf-8">
<title>animas</title>
<head >
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
div#fps,svg { position: fixed; top:0; left:0; color: white; }
</style>
</head>
<body style="cursor:crosshair"></body>
<div id="viewframe" class="viewframe"></div>
<script src='https://d3js.org/d3.v4.min.js'></script>
<script src='https://d3js.org/d3-geo.v1.min.js'></script>
<script src='https://d3js.org/d3-geo-projection.v2.min.js'></script>
<script src='https:////unpkg.com/d3-force-3d@1.0.7/build/d3-force-3d.bundle.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.0/topojson.min.js'></script>
<script src='https:////cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js'></script>
<script src='https:////unpkg.com/three-trackballcontrols-web@0.0.2/dist/three-trackballcontrols.min.js'></script>
<script src="enls.js"></script>
<script src="ents.js"></script>
<script>
let muonAlima = function muonAlima(__mapper) {
__mapper({"xs": xs.xs(__mapper)}) // PROXIES
__mapper("xs").b("init")({svg:1,versor:0,wen:1,webgl:1})
let f = __mapper({"props": bosonProps.bosonProps()}).props()
let g = __mapper("xs").m("geom")
let w = __mapper("xs").m("wen")
/**********************
* @
*/
let r = __mapper("xs").r("renderer"),
width = r.width(),
height = r.height()
let rotInit = [0,0,0],
rotation = [0,0,0],
rotMatrix,
stars = []
let versor = __mapper("xs").b("versor")()
let wen = __mapper("xs").c("wen")({rotInit})
/*******************************************
* @pics
*
*/
let tim = {"td":19800,"t0":0,"t1":1000,"t2":1,"t3":1,}
let formCube = {
"x": {
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2": 120 ,
"v0": 0, "v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": 0,
},
"y": {
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2": 120,
"v0":0,"v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": -90,
},
"z": {
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2": 120 / Math.sqrt(2), // _e_
"v0": 0, "v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": 0,
}
}
let formGratiCube = {
"x": {
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2": 120 ,
"v0": 0, "v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": 0,
},
"y": {
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2": 120,
"v0":0,"v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": -90,
},
"z": {
"m1":4,"m2":4,"n1":100,"n2":100,"n3":100,"a":1,"b":1, // square
"ra2": 120 / 2, // _e_
"v0": 0, "v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": 0,
}
}
let formSphere = {
"x": {
"m1":4,"m2":4,"n1":2,"n2":2,"n3":2,"a":1,"b":1, // circle
"ra2": 120,
"v0": 0, "v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": 0,
},
"y": {
"m1":4,"m2":4,"n1":2,"n2":2,"n3":2,"a":1,"b":1, // circle
"ra2": 120,
"v0":0,"v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": -90,
},
"z": {
"m1":4,"m2":4,"n1":2,"n2":2,"n3":2,"a":1,"b":1, // circle
"ra2": 120,
"v0": 0, "v1":1,
"w4": 0,
"seg5": 360,"pa6":0,"pb7":-1,
"fas8": 0,
}
}
let proformCube = {
"projection": "uniwen",
"translate": [ 250 , 200],
"scale": 1,
"rotate": [-5,50, [[[45,45]]] ], // [-5,50,0], //
"focale": 400,
"zafin": [0,1], // [ [[[0,0,1,1,1,0]]], [[[0,0,1,1,1,0]]] ], // [1,0]
"dims": 3,
"control": "wen",
}
let proformEarth = {
"projection": "uniwen",
"translate": [ 250 , 200],
"scale": 1,
"rotate": [-5,50, 0 ], // [-5,50,0], //
"focale": 400,
"zafin": [0,1], // [ [[[0,0,1,1,1,0]]], [[[0,0,1,1,1,0]]] ], // [1,0]
"dims": 3,
"control": "wen",
}
/*******************************************
* @animas
*
*/
let aniEarth = {
"tim": tim,
"ric": {"gid":"aniEarth","cid":"aniEarth","fid":"aniEarth",},
"halo": "geojson",
"boform":{ "csx":0,"cf":444,"cs":444,"cw":0.1,"co":0.9,"cp":0.9,},
"geoform": (p) => {
let ric = p.ric
let json = Object.assign({},
topojson.mesh(
__mapper("xs").d("worldTopo110m").data(),
__mapper("xs").d("worldTopo110m").data().objects.land
)
)
return json
},
"conform": {
"projection": "natform",
"form": formCube,
},
"proform": proformEarth,
}
// ------------------------------- img
let img = {
"tim": tim,
"ric": {"gid":"img","cid":"img","fid":"img",},
"halo":"img",
"boform": { "csx":0,"cf":[[[22,22]]],"cs":22,"cw":[[[0.7,0.7]]],"co":[[[0.7,0.7,]]],"cp":[[[0.5,0.5]]],},
"geoform": p => ({
type: "Feature",
geometry: {
"type": "Point",
"coordinates": [0, 0]
},
properties: {
attr: {
"width": p.payload.img.width,
"height": p.payload.img.height,
["xlink:href"]: p.payload.img.url,
}
}
}),
"stace": {
"x": [[[15, 15]]],
"y": [[[20, 20]]],
},
"payload": {
"img": {
"url":"zimg-501.jpg",
"width": [[[60, 60]]],
"height": [[[40 , 40]]],
},
}
}
// ------------------------------- aniCube
let aniCube = {
"tim": tim,
"ric": {"gid":"aniCube","cid":"aniCube","fid":"aniCube",},
"halo": "geojson",
"boform":{ "csx":0,"cf":333,"cs":111,"cw":0.1,"co":0.9,"cp":0.9,},
"geoform": (p) => {
let payload = p.payload
let ric = p.ric
let json = {type: "FeatureCollection", features: []}
let vertices = payload.vertices // payload.vertices
let faces = payload.faces // payload.faces
for (let i = 0, l = faces.length; i < l; i++) {
let face = faces[i] // face corners position
let geometry = {type:"Polygon",coordinates:[]}
geometry.coordinates = face.corners.map(k=>vertices[k]) // eg [-1, 1, 1]
.map(g.normalize) // eg. [0.5773, -0.577, 0.5773]
.map(g.spherical) // eg. [-0.7853, 0.6154]
.map(g.to_degrees)
geometry.coordinates = Array.of(geometry.coordinates)
let feature = {type:"Feature",geometry:{},properties:{}}
feature.properties.ric = ric
feature.properties.ric.cid = "face"
feature.properties.ric.fid = i // face.name
feature.properties.sort = "feature"
feature.geometry = geometry
feature.properties.boform = face.boform
json.features.push(feature)
}
return json
},
"conform": {
"projection": "natform",
"form": formSphere,
},
"proform": proformCube,
"payload": {
vertices: [
[-1, -1, 1], // 0
[ 1, -1, 1], // 1
[ 1, 1, 1], // 2
[-1, 1, 1], // 3
[ 1, -1, -1], // 4
[-1, -1, -1], // 5
[-1, 1, -1], // 6
[ 1, 1, -1], // 7
],
faces: [
{
corners: [0,1,2,3,0],
name: "front",
boform: { cf: 222, cs: 355, co: [[[0.7,0.7]]], cp: 1, }},
{
corners: [4,5,6,7,4],
name: "back",
boform: { cf: 888, cs: 455, co: [[[0.7,0.7]]], cp: 1, }},
{
corners: [1,4,7,2,1],
name: "right",
boform: { cf: 444, cs: 555, co: [[[0.7,0.7]]], cp: 1, }},
{
corners: [5,0,3,6,5],
name: "left",
boform: { cf: 555, cs: 655, co: [[[0.7,0.7]]], cp: 1, }},
{
corners: [3,2,7,6,3],
name: "bottom",
boform: { cf: 666, cs: 755, co: [[[0.7,0.7]]], cp: 1, }},
{
corners: [5,4,1,0,5],
name: "top",
boform: { cf: 777, cs: 855, co: [[[0.7,0.7]]], cp: 1, }}
],
}
}
// ------------------------------- gratiCube
let gratiCube = {
"tim": tim,
"ric": {"gid":"gratiCube","cid":"gratiCube","fid":"gratiCube",},
"halo":"geojson",
"geoform": (anitem) => {
let payload = anitem.payload
let graticule = payload.graticule
let grarr = __mapper("xs").m("graticule").grarr(graticule)
let mersCoords = grarr.mms.coordinates
let parsCoords = grarr.pps.coordinates
let coords = [].concat(mersCoords).concat(parsCoords)
let json = { type: "MultiLineString", coordinates: coords }
return json
},
"boform": { "csx":0,"cf":[[[666,666]]],"cs":666,"cw":3.39,"co":[[[0.5,0.5]]],"cp":[[[0.9,0.9]]],},
"conform": {
"projection": "natform",
"form": formGratiCube,
},
"proform": proformEarth,
"payload": {
"graticule": {
"extent": [ [-180, 180, 90, 90 ], [-90, 90, 45, 45] ],
}
},
}
// ------------------------------- gratiCirc
let gratiCirc = {
"tim": tim,
"ric": {"gid":"gratiCube","cid":"gratiCube","fid":"gratiCirc",},
"halo":"geojson",
"geoform": (anitem) => {
let payload = anitem.payload
let graticule = payload.graticule
let grarr = __mapper("xs").m("graticule").grarr(graticule)
let mersCoords = grarr.mms.coordinates
let parsCoords = grarr.pps.coordinates
let coords = [].concat(mersCoords).concat(parsCoords)
let json = { type: "MultiLineString", coordinates: coords }
return json
},
"boform": { "csx":0,"cf":[[[111,111]]],"cs":666,"cw":0.39,"co":[[[0.5,0.5]]],"cp":[[[0.9,0.9]]],},
"conform": {
"projection": "natform",
"form": formSphere,
},
"proform": proformEarth,
"payload": {
"graticule": {
"extent": [ [-180, 180, 90, 90 ], [-90, 90, 45, 45] ],
}
},
}
/*******************************************
* @animas
*
*/
let animas = [
aniEarth, // h.geojson g.natform g.uniwen
aniCube, // h.geojson g.uniwen
gratiCube, // h.geojson
gratiCirc, // h.geojson
img, // h.img
]
let animaApi = function animaApi() {
__mapper("xs").m("store").apply({"type":"UPDANIMA","caller":"alima","animas":animas})
}
return animaApi
}
let __mapper = bosonMapper.bosonMapper()
__mapper({"muonAlima": muonAlima(__mapper)}).muonAlima(__mapper)
</script>
<body style="cursor:crosshair"></body>
<!DOCTYPE html>
<meta charset="utf-8">
<title>animas</title>
<head >
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
div#fps,svg { position: fixed; top:0; left:0; color: white; }
</style>
</head>
<body style="cursor:crosshair"></body>
<div id="viewframe" class="viewframe"></div>
<script src='https://d3js.org/d3.v4.min.js'></script>
<script src='https://d3js.org/d3-geo.v1.min.js'></script>
<script src='https://d3js.org/d3-geo-projection.v2.min.js'></script>
<script src='https:////unpkg.com/d3-force-3d@1.0.7/build/d3-force-3d.bundle.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/topojson/3.0.0/topojson.min.js'></script>
<script src='https:////cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js'></script>
<script src='https:////unpkg.com/three-trackballcontrols-web@0.0.2/dist/three-trackballcontrols.min.js'></script>
<script src="enls.js"></script>
<script src="ents.js"></script>
<script>
let muonAlima = function muonAlima(__mapper) {
__mapper({"xs": xs.xs(__mapper)}) // PROXIES
__mapper("xs").b("init")({svg:1,versor:1,wen:1,webgl:1,pos:0}) // INIT
let f = __mapper({'props': bosonProps.bosonProps()}).props()
/**********************
* @
*/
let width = __mapper("renderRenderer").width()
let height = __mapper("renderRenderer").height()
let g = __mapper("xs").m("geom")
let w = __mapper("xs").m("wen")
/*******************************************
* @pics
*/
let tim = {"td":19800,"t0":0,"t1":1000,"t2":1,"t3":1,}
let proformCube = {
"projections": ["uniwen","unidentity","identity","universor","unimercator"],
"projectidx": 0,
"translate": [ [[[320,320]]] , 200],
"scale": 60,
"rotate": [-5,50,0],
"focale": 4,
"zafin": [ [[[0,0,1,1,1,0]]] ,[[[0,0,1,1,1,0]]] ], // [0,1], // [1,0]
"dims": 3,
"control": "wen",
}
let graticule = {
"extent": [ [-180, 180, [[[30,45,30,45,30]]], [[[30,45,30,45,30]]]], [-90, 90, [[[12,6,12,6,12]]], [[[12,6,12,6,12]]]] ],
}
let proformFuture = {
"projection": "futuri",
"scale": 30,
"translate": [ 250, 200, 0 ],
"rotate": [28,-4,0],
"trees": [
[-1, 0, 1, 5, 0, 2],
],
"treeidx": [[[0,0,0]]],
"faciaRotation": Math.PI / 1,
"control": "versor",
}
let geograt = {
"tim": tim,
"ric": {"gid":"geograt","cid":"geograt","fid":"geograt",},
"geoform": (p) => {
return {
type: "MultiLineString",
coordinates: __mapper("xs").m("graticule").grarrx(p.graticule)
}
},
"halo":"geojson",
"boform": { "csx":0,"cf":[[[111,111]]],"cs":666,"cw":0.3,"co":[[[0.05,0.05]]],"cp":[[[0.9,0.9]]],},
"graticule": graticule,
"proform": proformFuture,
}
let geoearth = {
"tim": tim,
"ric": {"gid":"geoearth","cid":"geoearth","fid":"geoearth",},
"halo":"geojson",
"boform":{ "csx":0,
"cf":[[[555,333,555,333,555,333,555]]],
"cs":333,"cw":0.2,"co":0.4,"cp":0.9,},
"proform": proformFuture,
"geoform": [[[ () => {
let geo = Object.assign({},
topojson.feature(
__mapper("xs").d("worldTopo110m").data(),
__mapper("xs").d("worldTopo110m").data().objects.land
)
)
geo = __mapper("xs").m("geoj").trim(geo)
return geo
} ]]],
}
let geosphere = {
"tim": tim,
"ric": {"gid":"geosphere","cid":"geosphere","fid":"geosphere",},
"halo":"geojson",
"boform":{ "csx":0,"cf":444,"cs":333,"cw":0.9,"co":0.04,"cp":0.9,},
"proform": proformFuture,
"geoform": [[[ () => {
let geo = {"type": "Sphere"}
return geo
} ]]],
}
// ------------------------- img
let img = {
"tim": tim,
"ric": {"gid":"img","cid":"img","fid":"img",},
"halo":"img",
"boform": { "csx":0,"cf":[[[22,22]]],"cs":22,"cw":[[[0.7,0.7]]],"co":[[[0.7,0.7,]]],"cp":[[[0.5,0.5]]],},
"geoform": p => ({
type: "Feature",
geometry: {
"type": "Point",
"coordinates": [0, 0]
},
properties: {
attr: {
"width": p.payload.img.width,
"height": p.payload.img.height,
["xlink:href"]: p.payload.img.url,
}
}
}),
"stace": {
"x": [[[15, 15]]],
"y": [[[20, 20]]],
},
"payload": {
"img": {
"url":"zimg-501.jpg",
"width": [[[60, 60]]],
"height": [[[40 , 40]]],
},
}
}
let animas = [
img, // h.img
geograt, // h.geojson g.futuri
geoearth, // h.geojson g.futuri
geosphere, // h.geojson g.futuri
]
return () => __mapper("xs").m("store").apply({"type":"UPDANIMA","caller":"alima","animas":animas})
}
let __mapper = bosonMapper.bosonMapper()
__mapper({"muonAlima": muonAlima(__mapper)}).muonAlima(__mapper)
</script>
<body style="cursor:crosshair"></body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment