From 273d0d5d23a9606385f089cf025b143717c4b975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Thu, 25 Feb 2016 21:03:33 +0100 Subject: [PATCH 01/87] infobox/location: show uci in one box --- lib/infobox/location.js | 74 +++++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/lib/infobox/location.js b/lib/infobox/location.js index 216a6e5..1080f44 100644 --- a/lib/infobox/location.js +++ b/lib/infobox/location.js @@ -9,42 +9,48 @@ define(function () { h2.textContent = result.display_name }) + var latDiv = document.createElement("div") var h3lat = document.createElement("h3") h3lat.textContent = "Breitengrad" - el.appendChild(h3lat) + h3lat.id = "h3-latitude" + latDiv.appendChild(h3lat) var txt1 = document.createElement("textarea") txt1.id = "location-latitude" txt1.value = d.lat.toFixed(9) var p = document.createElement("p") p.appendChild(txt1) p.appendChild(createCopyButton(txt1.id)) - el.appendChild(p) + latDiv.appendChild(p) + el.appendChild(latDiv) + var longDiv = document.createElement("div") var h3lng = document.createElement("h3") h3lng.textContent = "Längengrad" - el.appendChild(h3lng) + longDiv.appendChild(h3lng) var txt2 = document.createElement("textarea") txt2.id = "location-longitude" txt2.value = d.lng.toFixed(9) var p2 = document.createElement("p") p2.appendChild(txt2) p2.appendChild(createCopyButton(txt2.id)) - el.appendChild(p2) + longDiv.appendChild(p2) + longDiv.id = "div-longitude" + el.appendChild(longDiv) var a1 = document.createElement("a") a1.textContent = "plain" a1.onclick = function() { - switch2plain() - return false + switch2plain() + return false } a1.href = config.siteURL var a2 = document.createElement("a") a2.textContent = "uci" a2.onclick = function() { - switch2uci() - return false + switch2uci() + return false } - a2.href = config.siteURL + a2.href = "#" var p3 = document.createElement("p") p3.textContent = "Du kannst zwischen " @@ -57,36 +63,38 @@ define(function () { el.appendChild(p3) function createCopyButton(id) { - var btn = document.createElement("button") - btn.className = "ion-ios-copy" - btn.title = "Kopiere" - btn.onclick = function() { - copy2clip(id) - } - return btn + var btn = document.createElement("button") + btn.className = "ion-ios-copy" + btn.title = "Kopieren" + btn.onclick = function() { + copy2clip(id) + } + return btn } + function copy2clip(id) { - var copyTextarea = document.querySelector("#" + id) - copyTextarea.select() - try { - var successful = document.execCommand("copy") - var msg = successful ? "successful" : "unsuccessful" - console.log("Copying text command was " + msg) - } catch (err) { - console.log("Oops, unable to copy") - } + var copyTextarea = document.querySelector("#" + id) + copyTextarea.select() + try { + document.execCommand("copy") + } catch (err) { + console.log(err) + } } + function switch2plain() { - var box1 = document.getElementById("location-latitude") - box1.value = d.lat.toFixed(9) - var box2 = document.getElementById("location-longitude") - box2.value = d.lng.toFixed(9) + var box1 = document.getElementById("location-latitude") + box1.value = d.lat.toFixed(9) + var box2 = document.getElementById("location-longitude") + box2.value = d.lng.toFixed(9) + document.getElementById("h3-latitude").textContent = "Breitengrad" + document.getElementById("div-longitude").style.display = "block" } + function switch2uci() { - var box1 = document.getElementById("location-latitude") - box1.value = "uci set gluon-node-info.@location[0].latitude='" + d.lat.toFixed(9) + "'" - var box2 = document.getElementById("location-longitude") - box2.value = "uci set gluon-node-info.@location[0].longitude='" + d.lng.toFixed(9) + "'" + document.getElementById("location-latitude").value = "uci set gluon-node-info.@location[0].latitude='" + d.lat.toFixed(9) + "'; uci set gluon-node-info.@location[0].longitude='" + d.lng.toFixed(9) + "'" + document.getElementById("h3-latitude").textContent = "Befehl" + document.getElementById("div-longitude").style.display = "none" } } }) From 9f48cb1f3b676c35b23e5d84f856189d5f053c82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Thu, 25 Feb 2016 21:20:25 +0100 Subject: [PATCH 02/87] location: remove debug prints also some style corrections --- lib/infobox/location.js | 2 +- lib/infobox/main.js | 7 +++---- lib/map.js | 1 - 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/lib/infobox/location.js b/lib/infobox/location.js index 1080f44..c61d23d 100644 --- a/lib/infobox/location.js +++ b/lib/infobox/location.js @@ -43,7 +43,7 @@ define(function () { switch2plain() return false } - a1.href = config.siteURL + a1.href = "#" var a2 = document.createElement("a") a2.textContent = "uci" a2.onclick = function() { diff --git a/lib/infobox/main.js b/lib/infobox/main.js index 70b6a6e..deebc03 100644 --- a/lib/infobox/main.js +++ b/lib/infobox/main.js @@ -42,10 +42,9 @@ define(["infobox/link", "infobox/node", "infobox/location"], function (Link, Nod } self.gotoLocation = function (d) { - console.log("goto location called with ", d) - create() - new Location(config, el, router, d) - } + create() + new Location(config, el, router, d) + } return self } diff --git a/lib/map.js b/lib/map.js index d6bda4a..712839e 100644 --- a/lib/map.js +++ b/lib/map.js @@ -275,7 +275,6 @@ define(["map/clientlayer", "map/labelslayer", } function contextMenuGotoLocation(e) { - console.log("context menu called at ", e) router.gotoLocation(e.latlng) } From 97a00b6925e3f428ecd53c388fa596b4544d4803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Sat, 27 Feb 2016 14:43:27 +0100 Subject: [PATCH 03/87] forcegraph: show links with unknown nodes --- lib/filters/nodefilter.js | 2 +- lib/forcegraph.js | 2 +- lib/infobox/link.js | 11 +++++++---- lib/infobox/node.js | 10 ++++++---- lib/linklist.js | 2 +- lib/main.js | 31 +++++++++++++++++++------------ lib/title.js | 2 +- 7 files changed, 36 insertions(+), 24 deletions(-) diff --git a/lib/filters/nodefilter.js b/lib/filters/nodefilter.js index e4e979d..920352d 100644 --- a/lib/filters/nodefilter.js +++ b/lib/filters/nodefilter.js @@ -24,7 +24,7 @@ define([], function () { }) n.graph.links = data.graph.links.filter( function (d) { - return filteredIds.has(d.source.id) && filteredIds.has(d.target.id) + return !d.sourceid || (filteredIds.has(d.source.id) && filteredIds.has(d.target.id)) }) return n diff --git a/lib/forcegraph.js b/lib/forcegraph.js index 2cf49f3..995fd8a 100644 --- a/lib/forcegraph.js +++ b/lib/forcegraph.js @@ -685,7 +685,7 @@ define(["d3"], function (d3) { d.source.neighbours[d.target.o.id] = {node: d.target, link: d} d.target.neighbours[d.source.o.id] = {node: d.source, link: d} - if (d.o.source.node && d.o.target.node) + if (d.o.source && d.o.target) linksDict[d.o.id] = d }) diff --git a/lib/infobox/link.js b/lib/infobox/link.js index acbb432..df91163 100644 --- a/lib/infobox/link.js +++ b/lib/infobox/link.js @@ -1,10 +1,13 @@ define(function () { return function (config, el, router, d) { + var unknown = !(d.source.node) var h2 = document.createElement("h2") var a1 = document.createElement("a") - a1.href = "#" - a1.onclick = router.node(d.source.node) - a1.textContent = d.source.node.nodeinfo.hostname + if (!unknown) { + a1.href = "#" + a1.onclick = router.node(d.source.node) + } + a1.textContent = unknown ? d.source.id : d.source.node.nodeinfo.hostname h2.appendChild(a1) h2.appendChild(document.createTextNode(" → ")) var a2 = document.createElement("a") @@ -20,7 +23,7 @@ define(function () { attributeEntry(attributes, "TQ", showTq(d)) attributeEntry(attributes, "Entfernung", showDistance(d)) attributeEntry(attributes, "Typ", d.type) - var hw1 = dictGet(d.source.node.nodeinfo, ["hardware", "model"]) + var hw1 = unknown ? null : dictGet(d.source.node.nodeinfo, ["hardware", "model"]) var hw2 = dictGet(d.target.node.nodeinfo, ["hardware", "model"]) attributeEntry(attributes, "Hardware", (hw1 != null ? hw1 : "unbekannt") + " – " + (hw2 != null ? hw2 : "unbekannt")) diff --git a/lib/infobox/node.js b/lib/infobox/node.js index 90b00d8..39b8183 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -326,6 +326,7 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], var tbody = document.createElement("tbody") d.neighbours.forEach( function (d) { + var unknown = !(d.node) var tr = document.createElement("tr") var td1 = document.createElement("td") @@ -335,12 +336,13 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], var td2 = document.createElement("td") var a1 = document.createElement("a") a1.classList.add("hostname") - a1.textContent = d.node.nodeinfo.hostname - a1.href = "#" - a1.onclick = router.node(d.node) + a1.textContent = unknown ? d.id : d.node.nodeinfo.hostname + if (!unknown) + a1.href = "#" + a1.onclick = router.node(d.node) td2.appendChild(a1) - if (has_location(d.node)) { + if (!unknown && has_location(d.node)) { var span = document.createElement("span") span.classList.add("icon") span.classList.add("ion-location") diff --git a/lib/linklist.js b/lib/linklist.js index e195dde..1fc8574 100644 --- a/lib/linklist.js +++ b/lib/linklist.js @@ -1,6 +1,6 @@ define(["sorttable", "virtual-dom"], function (SortTable, V) { function linkName(d) { - return d.source.node.nodeinfo.hostname + " – " + d.target.node.nodeinfo.hostname + return (d.source.node ? d.source.node.nodeinfo.hostname : d.source.id) + " – " + d.target.node.nodeinfo.hostname } var headings = [{ name: "Knoten", diff --git a/lib/main.js b/lib/main.js index e12cd92..38f85e3 100644 --- a/lib/main.js +++ b/lib/main.js @@ -66,10 +66,7 @@ function (moment, Router, L, GUI, numeral) { }) graph.links.forEach( function (d) { - if (graph.nodes[d.source].node) - d.source = graph.nodes[d.source] - else - d.source = undefined + d.source = graph.nodes[d.source] if (graph.nodes[d.target].node) d.target = graph.nodes[d.target] @@ -78,14 +75,19 @@ function (moment, Router, L, GUI, numeral) { }) var links = graph.links.filter( function (d) { - return d.source !== undefined && d.target !== undefined + return d.target !== undefined }) links.forEach( function (d) { - var ids = [d.source.node.nodeinfo.node_id, d.target.node.nodeinfo.node_id] - d.id = ids.sort().join("-") + var unknown = (d.source.node === undefined) + var ids + if (unknown) + ids = [d.source.id.replace(/:/g, ""), d.target.node.nodeinfo.node_id] + else + ids = [d.source.node.nodeinfo.node_id, d.target.node.nodeinfo.node_id] + d.id = ids.join("-") - if (!("location" in d.source.node.nodeinfo && "location" in d.target.node.nodeinfo)) + if (unknown || !("location" in d.source.node.nodeinfo && "location" in d.target.node.nodeinfo)) return d.latlngs = [] @@ -100,10 +102,6 @@ function (moment, Router, L, GUI, numeral) { }) links.forEach( function (d) { - d.source.node.neighbours.push({ node: d.target.node, link: d, incoming: false }) - d.target.node.neighbours.push({ node: d.source.node, link: d, incoming: true }) - if (d.type !== "tunnel") - d.source.node.meshlinks = d.source.node.meshlinks ? d.source.node.meshlinks + 1 : 1 if (d.type === "tunnel") d.type = "VPN" else if (d.type === "wireless") @@ -112,6 +110,15 @@ function (moment, Router, L, GUI, numeral) { d.type = "Kabel" else d.type = "N/A" + var unknown = (d.source.node === undefined) + if (unknown) { + d.target.node.neighbours.push({ id: d.source.id, link: d, incoming: true }) + return + } + d.source.node.neighbours.push({ node: d.target.node, link: d, incoming: false }) + d.target.node.neighbours.push({ node: d.source.node, link: d, incoming: true }) + if (d.type !== "VPN") + d.source.node.meshlinks = d.source.node.meshlinks ? d.source.node.meshlinks + 1 : 1 }) links.sort( function (a, b) { diff --git a/lib/title.js b/lib/title.js index 372dd75..e9377a4 100644 --- a/lib/title.js +++ b/lib/title.js @@ -20,7 +20,7 @@ define(function () { this.gotoLink = function (d) { if (d) - setTitle(d.source.node.nodeinfo.hostname + " – " + d.target.node.nodeinfo.hostname) + setTitle((d.source.node ? d.source.node.nodeinfo.hostname : d.source.id) + " – " + d.target.node.nodeinfo.hostname) } this.gotoLocation = function() { From 2e823a90c8cabf4ec743df82dd0d19bebd8b1478 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Sun, 28 Feb 2016 01:24:04 +0100 Subject: [PATCH 04/87] nodefilter: filter unknown nodes --- lib/filters/nodefilter.js | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/filters/nodefilter.js b/lib/filters/nodefilter.js index 920352d..319a71e 100644 --- a/lib/filters/nodefilter.js +++ b/lib/filters/nodefilter.js @@ -12,10 +12,11 @@ define([], function () { n.graph = {} n.graph.nodes = data.graph.nodes.filter( function (d) { - if (!d.node) - return true - - var r = filter(d.node) + var r + if (d.node) + r = filter(d.node) + else + r = filter({}) if (r) filteredIds.add(d.id) @@ -24,7 +25,7 @@ define([], function () { }) n.graph.links = data.graph.links.filter( function (d) { - return !d.sourceid || (filteredIds.has(d.source.id) && filteredIds.has(d.target.id)) + return filteredIds.has(d.source.id) && filteredIds.has(d.target.id) }) return n From c541f5b721bce0f1777bb470e9f10176e107f469 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Tue, 1 Mar 2016 19:50:14 +0100 Subject: [PATCH 05/87] main: fix missing location error --- lib/main.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/main.js b/lib/main.js index 38f85e3..5fd96d6 100644 --- a/lib/main.js +++ b/lib/main.js @@ -87,7 +87,13 @@ function (moment, Router, L, GUI, numeral) { ids = [d.source.node.nodeinfo.node_id, d.target.node.nodeinfo.node_id] d.id = ids.join("-") - if (unknown || !("location" in d.source.node.nodeinfo && "location" in d.target.node.nodeinfo)) + if (unknown || + !d.source.node.nodeinfo.location || + !d.target.node.nodeinfo.location || + isNaN(d.source.node.nodeinfo.location.latitude) || + isNaN(d.source.node.nodeinfo.location.longitude) || + isNaN(d.target.node.nodeinfo.location.latitude) || + isNaN(d.target.node.nodeinfo.location.longitude)) return d.latlngs = [] From 23ded770893a45bf303c3e5021372a2945051809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Wed, 2 Mar 2016 10:45:41 +0100 Subject: [PATCH 06/87] infobox/location: more detailed command --- lib/infobox/location.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/infobox/location.js b/lib/infobox/location.js index c61d23d..b656362 100644 --- a/lib/infobox/location.js +++ b/lib/infobox/location.js @@ -92,7 +92,7 @@ define(function () { } function switch2uci() { - document.getElementById("location-latitude").value = "uci set gluon-node-info.@location[0].latitude='" + d.lat.toFixed(9) + "'; uci set gluon-node-info.@location[0].longitude='" + d.lng.toFixed(9) + "'" + document.getElementById("location-latitude").value = "gluon-node-info.@location[0]='location'; gluon-node-info.@location[0].share_location='1'; uci set gluon-node-info.@location[0].latitude='" + d.lat.toFixed(9) + "'; uci set gluon-node-info.@location[0].longitude='" + d.lng.toFixed(9) + "'; uci commit gluon-node-info" document.getElementById("h3-latitude").textContent = "Befehl" document.getElementById("div-longitude").style.display = "none" } From 24987f4963346eafd8992d6445af9192c55d4b6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Wed, 2 Mar 2016 21:55:44 +0100 Subject: [PATCH 07/87] forcegraph: draw unseen nodes orange --- lib/forcegraph.js | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/lib/forcegraph.js b/lib/forcegraph.js index 995fd8a..fac79bd 100644 --- a/lib/forcegraph.js +++ b/lib/forcegraph.js @@ -19,7 +19,9 @@ define(["d3"], function (d3) { var nodes = [] var uplinkNodes = [] var nonUplinkNodes = [] + var unseenNodes = [] var unknownNodes = [] + var graphNodes = [] var savedPanZoom var draggedNode @@ -313,6 +315,7 @@ define(["d3"], function (d3) { var unknownColor = "#D10E2A" var nonUplinkColor = "#F2E3C6" var uplinkColor = "#5BAAEB" + var unseenColor = "#FFA726" var highlightColor = "rgba(252, 227, 198, 0.15)" var nodeRadius = 6 var cableColor = "#50B0F0" @@ -364,6 +367,11 @@ define(["d3"], function (d3) { ctx.drawImage(uplinkNode, scale * r * d.x - uplinkNode.width / 2, scale * r * d.y - uplinkNode.height / 2) }) + var unseenNode = drawNode(unseenColor, nodeRadius, scale, r) + unseenNodes.filter(visibleNodes).forEach(function (d) { + ctx.drawImage(unseenNode, scale * r * d.x - unseenNode.width / 2, scale * r * d.y - unseenNode.height / 2) + }) + ctx.restore() // -- draw clients -- @@ -695,10 +703,12 @@ define(["d3"], function (d3) { }) }) - nodes = intNodes.filter(function (d) { return d.o.node }) + nodes = intNodes.filter(function (d) { return !d.o.unseen && d.o.node }) uplinkNodes = nodes.filter(function (d) { return d.o.node.flags.uplink }) nonUplinkNodes = nodes.filter(function (d) { return !d.o.node.flags.uplink }) + unseenNodes = intNodes.filter(function (d) { return d.o.unseen && d.o.node }) unknownNodes = intNodes.filter(function (d) { return !d.o.node }) + graphNodes = nodes.concat(unseenNodes).concat(unknownNodes) if (localStorageTest()) { var save = JSON.parse(localStorage.getItem("graph/nodeposition")) @@ -718,9 +728,9 @@ define(["d3"], function (d3) { } } - var diameter = graphDiameter(intNodes) + var diameter = graphDiameter(graphNodes) - force.nodes(intNodes) + force.nodes(graphNodes) .links(intLinks) .size([diameter, diameter]) From 593a96e07e3ec65503812e8c5384f1def1f89528 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Wed, 2 Mar 2016 22:34:35 +0100 Subject: [PATCH 08/87] infobox/node: more detailed lastseen --- lib/infobox/node.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/infobox/node.js b/lib/infobox/node.js index 39b8183..c1f34b3 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -39,7 +39,10 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], function showStatus(d) { return function (el) { el.classList.add(d.flags.online ? "online" : "offline") - el.textContent = (d.flags.online ? "online " : "offline, " + d.lastseen.fromNow(true)) + " (Stand " + d.lastseen.format("DD.MM.YYYY, H:mm:ss)") + if (d.flags.online) + el.textContent = "online, letzte Nachricht vor " + d.lastseen.fromNow(true) + " (" + d.lastseen.format("DD.MM.YYYY, H:mm:ss") + ")" + else + el.textContent = "offline, letzte Nachricht vor " + d.lastseen.fromNow(true) + " (" + d.lastseen.format("DD.MM.YYYY, H:mm:ss") + ")" } } From 4c8b2c03c6a8a07ac04f3c3428875ce84915a77d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Thu, 3 Mar 2016 20:00:18 +0100 Subject: [PATCH 09/87] infobox/location: fix uci commands --- lib/infobox/location.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/infobox/location.js b/lib/infobox/location.js index b656362..128ad74 100644 --- a/lib/infobox/location.js +++ b/lib/infobox/location.js @@ -92,7 +92,7 @@ define(function () { } function switch2uci() { - document.getElementById("location-latitude").value = "gluon-node-info.@location[0]='location'; gluon-node-info.@location[0].share_location='1'; uci set gluon-node-info.@location[0].latitude='" + d.lat.toFixed(9) + "'; uci set gluon-node-info.@location[0].longitude='" + d.lng.toFixed(9) + "'; uci commit gluon-node-info" + document.getElementById("location-latitude").value = "uci set gluon-node-info.@location[0]='location'; uci set gluon-node-info.@location[0].share_location='1'; uci set gluon-node-info.@location[0].latitude='" + d.lat.toFixed(9) + "'; uci set gluon-node-info.@location[0].longitude='" + d.lng.toFixed(9) + "'; uci commit gluon-node-info" document.getElementById("h3-latitude").textContent = "Befehl" document.getElementById("div-longitude").style.display = "none" } From 309878d6075d6c7b5bc4a2f85aad5f57abd073d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Sat, 5 Mar 2016 11:49:10 +0100 Subject: [PATCH 10/87] forcegraph: partially revert 'draw unseen nodes orange' --- lib/forcegraph.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/forcegraph.js b/lib/forcegraph.js index fac79bd..a3d6e3a 100644 --- a/lib/forcegraph.js +++ b/lib/forcegraph.js @@ -21,7 +21,6 @@ define(["d3"], function (d3) { var nonUplinkNodes = [] var unseenNodes = [] var unknownNodes = [] - var graphNodes = [] var savedPanZoom var draggedNode @@ -708,7 +707,6 @@ define(["d3"], function (d3) { nonUplinkNodes = nodes.filter(function (d) { return !d.o.node.flags.uplink }) unseenNodes = intNodes.filter(function (d) { return d.o.unseen && d.o.node }) unknownNodes = intNodes.filter(function (d) { return !d.o.node }) - graphNodes = nodes.concat(unseenNodes).concat(unknownNodes) if (localStorageTest()) { var save = JSON.parse(localStorage.getItem("graph/nodeposition")) @@ -728,9 +726,9 @@ define(["d3"], function (d3) { } } - var diameter = graphDiameter(graphNodes) + var diameter = graphDiameter(intNodes) - force.nodes(graphNodes) + force.nodes(intNodes) .links(intLinks) .size([diameter, diameter]) From f7bc41dcecd5dc3f3292086870ad578e776fdcfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Sat, 5 Mar 2016 11:54:31 +0100 Subject: [PATCH 11/87] infobox/node: lastseen proper quantity --- lib/infobox/node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/infobox/node.js b/lib/infobox/node.js index c1f34b3..400749e 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -40,9 +40,9 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], return function (el) { el.classList.add(d.flags.online ? "online" : "offline") if (d.flags.online) - el.textContent = "online, letzte Nachricht vor " + d.lastseen.fromNow(true) + " (" + d.lastseen.format("DD.MM.YYYY, H:mm:ss") + ")" + el.textContent = "online, letzte Nachricht vor " + d.lastseen.fromNow() + " (" + d.lastseen.format("DD.MM.YYYY, H:mm:ss") + ")" else - el.textContent = "offline, letzte Nachricht vor " + d.lastseen.fromNow(true) + " (" + d.lastseen.format("DD.MM.YYYY, H:mm:ss") + ")" + el.textContent = "offline, letzte Nachricht vor " + d.lastseen.fromNow() + " (" + d.lastseen.format("DD.MM.YYYY, H:mm:ss") + ")" } } From 8d4cc879941bd6c2bb0a23cdf50c2d660c0e9c46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Sat, 5 Mar 2016 12:38:43 +0100 Subject: [PATCH 12/87] main: unseen nodes are online --- lib/main.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/main.js b/lib/main.js index 5fd96d6..db37039 100644 --- a/lib/main.js +++ b/lib/main.js @@ -61,8 +61,13 @@ function (moment, Router, L, GUI, numeral) { var graph = dataGraph.batadv graph.nodes.forEach( function (d) { - if (d.node_id in graphnodes) + if (d.node_id in graphnodes) { d.node = graphnodes[d.node_id] + if (d.unseen) { + d.node.flags.online = true + d.node.flags.unseen = true + } + } }) graph.links.forEach( function (d) { From 2e414cd5b83e9ba5815230476f0ff85bf4902cd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Sat, 5 Mar 2016 12:45:14 +0100 Subject: [PATCH 13/87] infobox/node: unseen status orange --- lib/infobox/node.js | 2 +- scss/main.scss | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/infobox/node.js b/lib/infobox/node.js index 400749e..2c53bc3 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -38,7 +38,7 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], function showStatus(d) { return function (el) { - el.classList.add(d.flags.online ? "online" : "offline") + el.classList.add(d.flags.unseen ? "unseen" : (d.flags.online ? "online" : "offline")) if (d.flags.online) el.textContent = "online, letzte Nachricht vor " + d.lastseen.fromNow() + " (" + d.lastseen.format("DD.MM.YYYY, H:mm:ss") + ")" else diff --git a/scss/main.scss b/scss/main.scss index 17e3bc1..109463d 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -284,6 +284,10 @@ table { color: #D43E2A !important; } +.unseen { + color: #D89100 !important; +} + .sidebar { z-index: 5; width: $sidebarwidth; From a7c18b3a0af169017d140ebc98f7f47d50fdbfd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Sat, 5 Mar 2016 14:21:33 +0100 Subject: [PATCH 14/87] infobox/node: eliminate duplicate 'vor' --- lib/infobox/node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/infobox/node.js b/lib/infobox/node.js index 2c53bc3..aeae59a 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -40,9 +40,9 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], return function (el) { el.classList.add(d.flags.unseen ? "unseen" : (d.flags.online ? "online" : "offline")) if (d.flags.online) - el.textContent = "online, letzte Nachricht vor " + d.lastseen.fromNow() + " (" + d.lastseen.format("DD.MM.YYYY, H:mm:ss") + ")" + el.textContent = "online, letzte Nachricht " + d.lastseen.fromNow() + " (" + d.lastseen.format("DD.MM.YYYY, H:mm:ss") + ")" else - el.textContent = "offline, letzte Nachricht vor " + d.lastseen.fromNow() + " (" + d.lastseen.format("DD.MM.YYYY, H:mm:ss") + ")" + el.textContent = "offline, letzte Nachricht " + d.lastseen.fromNow() + " (" + d.lastseen.format("DD.MM.YYYY, H:mm:ss") + ")" } } From 2eace51bfeda6fa85946ad38edd1dd5bdca67602 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Tue, 8 Mar 2016 20:01:38 +0100 Subject: [PATCH 15/87] add configurable linkinfos --- lib/infobox/link.js | 45 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/lib/infobox/link.js b/lib/infobox/link.js index df91163..b0c080c 100644 --- a/lib/infobox/link.js +++ b/lib/infobox/link.js @@ -1,4 +1,37 @@ define(function () { + function showStatImg(o, source, target) { + var content, caption + + if (o.thumbnail) { + content = document.createElement("img") + content.src = o.thumbnail.replace("{SOURCE}", source).replace("{TARGET}", target) + } + + if (o.caption) { + caption = o.caption.replace("{SOURCE}", source).replace("{TARGET}", target) + + if (!content) + content = document.createTextNode(caption) + } + + var p = document.createElement("p") + + if (o.href) { + var link = document.createElement("a") + link.target = "_blank" + link.href = o.href.replace("{SOURCE}", source).replace("{TARGET}", target) + link.appendChild(content) + + if (caption && o.thumbnail) + link.title = caption + + p.appendChild(link) + } else + p.appendChild(content) + + return p + } + return function (config, el, router, d) { var unknown = !(d.source.node) var h2 = document.createElement("h2") @@ -26,7 +59,17 @@ define(function () { var hw1 = unknown ? null : dictGet(d.source.node.nodeinfo, ["hardware", "model"]) var hw2 = dictGet(d.target.node.nodeinfo, ["hardware", "model"]) attributeEntry(attributes, "Hardware", (hw1 != null ? hw1 : "unbekannt") + " – " + (hw2 != null ? hw2 : "unbekannt")) - el.appendChild(attributes) + + if (config.linkInfos) { + var source = d.source.node_id + var target = d.target.node_id + config.linkInfos.forEach( function (linkInfo) { + var h4 = document.createElement("h4") + h4.textContent = linkInfo.name + el.appendChild(h4) + el.appendChild(showStatImg(linkInfo, source, target)) + }) + } } }) From 11a157c58aa088c95579071c62d1fad43711b884 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Tue, 8 Mar 2016 20:07:20 +0100 Subject: [PATCH 16/87] readme: add linkinfos --- README.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 424b63a..04bd923 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ property and optionally `url` and `config` properties. If no `url` is supplied ## nodeInfos (array, optional) -This option allows to show client statistics depending on following case-sensitive parameters: +This option allows to show node statistics depending on following case-sensitive parameters: - `name` caption of statistics segment in infobox - `href` absolute or relative URL to statistics image @@ -137,6 +137,25 @@ Examples for `globalInfos` using Grafana server rendering: } ] +## linkInfos (array, optional) + +This option allows to show link statistics depending on the following case-sensitive parameters: + +- `name` caption of statistics segment in infobox +- `href` absolute or relative URL to statistics image +- `thumbnail` absolute or relative URL to thumbnail image, + can be the same like `href` +- `caption` is shown, if `thumbnail` is not present (no thumbnail in infobox) + +To insert the source or target node-id in either `href`, `thumbnail` or `caption` +you can use the case-sensitive template strings `{SOURCE}` and `{TARGET}`. + + "linkInfos": [ + { "href": "stats/dashboard/db/links?var-source={SOURCE}&var-target={TARGET}", + "thumbnail": "stats/render/dashboard-solo/db/links?panelId=1&fullscreen&theme=light&width=800&height=600&var-source={SOURCE}&var-target={TARGET}" + } + ] + ## siteNames (array, optional) In this array name definitions for site statistics and node info can be saved. This requires one object for each site code. This object must contain: From 8d22417789aadf794723baba0ed512b35e2d04f9 Mon Sep 17 00:00:00 2001 From: "ffggrz.de" Date: Wed, 16 Mar 2016 00:39:09 +0100 Subject: [PATCH 17/87] added fixed center option added option to fix the map on a specific coordinate --- README.md | 16 ++++++++++++++++ lib/map.js | 5 ++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 04bd923..8b6100b 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,22 @@ property and optionally `url` and `config` properties. If no `url` is supplied `name` is assumed to name a [Leaflet-provider](http://leaflet-extras.github.io/leaflet-providers/preview/). +## fixedCenter (array, optional) + +This option allows to fix the map at one specific coordinate depending on following case-sensitive parameters: + +- `lat` latitude of the center point +- `lng` longitude of the center point +- `radius` visible radius around the center in km + +Examples for `fixedCenter`: + + "fixedCenter": { + "lat": 50.80, + "lng": 12.07, + "radius": 30 + } + ## nodeInfos (array, optional) This option allows to show node statistics depending on following case-sensitive parameters: diff --git a/lib/map.js b/lib/map.js index 712839e..43f75b6 100644 --- a/lib/map.js +++ b/lib/map.js @@ -447,7 +447,10 @@ define(["map/clientlayer", "map/labelslayer", var lines = addLinksToMap(linkDict, linkScale, data.graph.links, router) groupLines = L.featureGroup(lines).addTo(map) - barycenter = calcBarycenter(data.nodes.all.filter(has_location)) + if (typeof config.fixedCenter === "undefined") + barycenter = calcBarycenter(data.nodes.all.filter(has_location)) + else + barycenter = L.circle(L.latLng(new L.LatLng(config.fixedCenter.lat, config.fixedCenter.lng)), config.fixedCenter.radius * 1000) var nodesOnline = subtract(data.nodes.all.filter(online), data.nodes.new) var nodesOffline = subtract(data.nodes.all.filter(offline), data.nodes.lost) From fc2a1e38722af778fb0c97081eed29f1992100b8 Mon Sep 17 00:00:00 2001 From: viisauksena Date: Sat, 12 Mar 2016 16:24:57 +0100 Subject: [PATCH 18/87] proportions: allow hiding of statistics and add gateway client statistics Update proportions.js: enable onclick hiding of Statistics

and add clients per GW

hiding works by clicking on H2 element, so you can have the overview you like [need to add some hidden line in scss/main.scss also] clients per GW is based on nodes.json and the offered clientcount by the nodes directly (so this is only rough idea of reality, for alfred this means extra timedifferences upto 30 minutes) update main.scss: to allow hiding of statistics element add this to allow statistics element hiding use consistent var table and dict Names change gwTable and gwDict (and gw2 ...) to gwNodes and gwClients --- lib/proportions.js | 128 ++++++++++++++++++++++++--------------------- scss/main.scss | 4 ++ 2 files changed, 72 insertions(+), 60 deletions(-) diff --git a/lib/proportions.js b/lib/proportions.js index 49ba4ca..651bd96 100644 --- a/lib/proportions.js +++ b/lib/proportions.js @@ -23,8 +23,11 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc var uplinkTable = document.createElement("table") uplinkTable.classList.add("proportion") - var gwTable = document.createElement("table") - gwTable.classList.add("proportion") + var gwNodesTable = document.createElement("table") + gwNodesTable.classList.add("proportion") + + var gwClientsTable = document.createElement("table") + gwClientsTable.classList.add("proportion") var siteTable = document.createElement("table") siteTable.classList.add("proportion") @@ -80,6 +83,25 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc return Object.keys(dict).map(function (d) { return [d, dict[d], key, f] }) } + function count2(nodes, key, f) { + var dict = {} + + nodes.forEach( function (d) { + var v = dictGet(d, key.slice(0)) + + if (f !== undefined) + v = f(v) + + if (v === null) + return + + dict[v] = d.statistics.clients + (v in dict ? dict[v] : 0) + }) + + return Object.keys(dict).map(function (d) { return [d, dict[d], key, f] }) + } + + function addFilter(filter) { return function () { filterManager.addFilter(filter) @@ -139,6 +161,7 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc var geoDict = count(nodes, ["nodeinfo", "location"], function (d) { return d ? "ja" : "nein" }) + var autoDict = count(nodes, ["nodeinfo", "software", "autoupdater"], function (d) { if (d === null) return null @@ -147,11 +170,22 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc else return "(deaktiviert)" }) + var uplinkDict = count(nodes, ["flags", "uplink"], function (d) { return d ? "ja" : "nein" }) - var gwDict = count(nodes, ["statistics", "gateway"], function (d) { + var gwNodesDict = count(nodes, ["statistics", "gateway"], function (d) { + if (d === null) + return null + + if (d in nodeDict) + return nodeDict[d].nodeinfo.hostname + + return d + }) + + var gwClientsDict = count2(onlineNodes, ["statistics", "gateway"], function (d) { if (d === null) return null @@ -175,71 +209,45 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc fillTable("Firmware", fwTable, fwDict.sort(function (a, b) { return vercomp(b[0], a[0]) })) fillTable("Hardware", hwTable, hwDict.sort(function (a, b) { return b[1] - a[1] })) fillTable("Koordinaten", geoTable, geoDict.sort(function (a, b) { return b[1] - a[1] })) - fillTable("Autom. Updates", autoTable, autoDict.sort(function (a, b) { return b[1] - a[1] })) fillTable("Uplink", uplinkTable, uplinkDict.sort(function (a, b) { return b[1] - a[1] })) - fillTable("Gewähltes Gateway", gwTable, gwDict.sort(function (a, b) { return b[1] - a[1] })) + fillTable("Autom. Updates", autoTable, autoDict.sort(function (a, b) { return b[1] - a[1] })) + fillTable("Nodes on Gateway", gwNodesTable, gwNodesDict.sort(function (a, b) { return b[1] - a[1] })) + fillTable("Clients on Gateway", gwClientsTable, gwClientsDict.sort(function (a, b) { return b[1] - a[1] })) fillTable("Site", siteTable, siteDict.sort(function (a, b) { return b[1] - a[1] })) } + self.render = function (el) { var h2 - h2 = document.createElement("h2") - h2.textContent = "Status" - el.appendChild(h2) - el.appendChild(statusTable) - - h2 = document.createElement("h2") - h2.textContent = "Firmwareversionen" - el.appendChild(h2) - el.appendChild(fwTable) - - if(config.siteNames || config.showSites) { - h2 = document.createElement("h2") - h2.textContent = "Orte" - el.appendChild(h2) - el.appendChild(siteTable) - } - - h2 = document.createElement("h2") - h2.textContent = "Hardwaremodelle" - el.appendChild(h2) - el.appendChild(hwTable) - - h2 = document.createElement("h2") - h2.textContent = "Auf der Karte sichtbar" - el.appendChild(h2) - el.appendChild(geoTable) - - h2 = document.createElement("h2") - h2.textContent = "Autoupdater" - el.appendChild(h2) - el.appendChild(autoTable) - - h2 = document.createElement("h2") - h2.textContent = "Uplink" - el.appendChild(h2) - el.appendChild(uplinkTable) - - h2 = document.createElement("h2") - h2.textContent = "Gewählter Gateway" - el.appendChild(h2) - el.appendChild(gwTable) - - h2 = document.createElement("h2") - h2.textContent = "Site" - el.appendChild(h2) - el.appendChild(siteTable) + self.renderSingle(el, "Status", statusTable) + self.renderSingle(el, "Gewählter Gateway", gwNodesTable) + self.renderSingle(el, "Clients on Gateway", gwClientsTable) + self.renderSingle(el, "Firmwareversionen", fwTable) + self.renderSingle(el, "Uplink", uplinkTable) + self.renderSingle(el, "Hardwaremodelle", hwTable) + self.renderSingle(el, "Auf der Karte sichtbar", geoTable) + self.renderSingle(el, "Autoupdater", autoTable) + self.renderSingle(el, "Site", siteTable) if (config.globalInfos) - config.globalInfos.forEach( function (globalInfo) { - h2 = document.createElement("h2") - h2.textContent = globalInfo.name - el.appendChild(h2) + config.globalInfos.forEach(function (globalInfo) { + h2 = document.createElement("h2") + h2.textContent = globalInfo.name + el.appendChild(h2) + el.appendChild(showStatGlobal(globalInfo)) + }) + } - el.appendChild(showStatGlobal(globalInfo)) - }) - } - - return self + self.renderSingle = function (el, heading, table) { + var h2 + h2 = document.createElement("h2") + h2.textContent = heading + h2.onclick = function () { + table.classList.toggle("hidden") + } + el.appendChild(h2) + el.appendChild(table) + } + return self } }) diff --git a/scss/main.scss b/scss/main.scss index 109463d..8a28ae6 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -127,6 +127,10 @@ table.attributes td { display: none; } + .container table.hidden { + display: none; + } + p { line-height: 1.67em; } From 78de449b88a9d642b77f97c922664210ca2d2e3a Mon Sep 17 00:00:00 2001 From: David Kolossa Date: Wed, 23 Mar 2016 12:24:35 +0100 Subject: [PATCH 19/87] map: fixed display errors on high zoom levels * client dots and labels only showed up on zoom levels up to 18 --- lib/map.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/map.js b/lib/map.js index 43f75b6..9469c1f 100644 --- a/lib/map.js +++ b/lib/map.js @@ -290,6 +290,12 @@ define(["map/clientlayer", "map/labelslayer", } }) + var maxLayerZoom = Math.max.apply(Math, config.mapLayers.map( + function(d) { + return (typeof d.config !== "undefined" && typeof d.config.maxZoom !== "undefined") ? d.config.maxZoom : 18 + })) + + layers[0].layer.addTo(map) layers.forEach( function (d) { @@ -320,11 +326,11 @@ define(["map/clientlayer", "map/labelslayer", d.forEach(addLayer) } - var clientLayer = new ClientLayer({minZoom: 15}) + var clientLayer = new ClientLayer({minZoom: 15, maxZoom: maxLayerZoom}) clientLayer.addTo(map) clientLayer.setZIndex(5) - var labelsLayer = new LabelsLayer() + var labelsLayer = new LabelsLayer({maxZoom: maxLayerZoom}) labelsLayer.addTo(map) labelsLayer.setZIndex(6) From 961a18fec42ac8aeb76a1a196739e908f32a7354 Mon Sep 17 00:00:00 2001 From: Benjamin Date: Wed, 16 Mar 2016 20:40:08 +0100 Subject: [PATCH 20/87] infobox: added support for iframes --- helper.js | 81 +++++++++++++++++++++++++++++++++++++++++++++ lib/infobox/link.js | 34 +++---------------- lib/infobox/node.js | 33 ++---------------- lib/proportions.js | 31 +---------------- package.json | 1 + 5 files changed, 90 insertions(+), 90 deletions(-) diff --git a/helper.js b/helper.js index dd326e5..0a15839 100644 --- a/helper.js +++ b/helper.js @@ -73,6 +73,13 @@ function localStorageTest() { } } +function listReplace(s, subst) { + for (key in subst) { + s = s.replace(key, subst[key]) + } + return s +} + /* Helpers working with nodes */ function offline(d) { @@ -138,3 +145,77 @@ function attributeEntry(el, label, value) { return td } + +function createIframe(opt, width, height) { + el = document.createElement("iframe") + width = typeof width !== 'undefined' ? width : '525px'; + height = typeof height !== 'undefined' ? width : '350px'; + + if (opt.src) + el.src = opt.src + else + el.src = opt + + if (opt.frameBorder) + el.frameBorder = opt.frameBorder + else + el.frameBorder = 1 + + if (opt.width) + el.width = opt.width + else + el.width = width + + if (opt.height) + el.height = opt.height + else + el.height = height + + el.scrolling = "no" + el.seamless = "seamless" + + return el +} + +function showStat(o, subst) { + var content, caption + subst = typeof subst !== 'undefined' ? subst : {}; + + if (o.thumbnail) { + content = document.createElement("img") + content.src = listReplace(o.thumbnail, subst) + } + + if (o.caption) { + caption = listReplace(o.caption, subst) + + if (!content) + content = document.createTextNode(caption) + } + + if (o.iframe) { + content = createIframe(o.iframe) + if (o.iframe.src) + content.src = listReplace(o.iframe.src, subst) + else + content.src = listReplace(o.iframe, subst) + } + + var p = document.createElement("p") + + if (o.href) { + var link = document.createElement("a") + link.target = "_blank" + link.href = listReplace(o.href, subst) + link.appendChild(content) + + if (caption && o.thumbnail) + link.title = caption + + p.appendChild(link) + } else + p.appendChild(content) + + return p +} + diff --git a/lib/infobox/link.js b/lib/infobox/link.js index b0c080c..794753a 100644 --- a/lib/infobox/link.js +++ b/lib/infobox/link.js @@ -1,35 +1,9 @@ define(function () { function showStatImg(o, source, target) { - var content, caption - - if (o.thumbnail) { - content = document.createElement("img") - content.src = o.thumbnail.replace("{SOURCE}", source).replace("{TARGET}", target) - } - - if (o.caption) { - caption = o.caption.replace("{SOURCE}", source).replace("{TARGET}", target) - - if (!content) - content = document.createTextNode(caption) - } - - var p = document.createElement("p") - - if (o.href) { - var link = document.createElement("a") - link.target = "_blank" - link.href = o.href.replace("{SOURCE}", source).replace("{TARGET}", target) - link.appendChild(content) - - if (caption && o.thumbnail) - link.title = caption - - p.appendChild(link) - } else - p.appendChild(content) - - return p + var subst = {} + subst["{SOURCE}"] = source + subst["{TARGET}"] = target + return showStat(o, subst) } return function (config, el, router, d) { diff --git a/lib/infobox/node.js b/lib/infobox/node.js index aeae59a..0a262cb 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -220,36 +220,9 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], } function showStatImg(o, nodeId) { - var content, caption - - if (o.thumbnail) { - content = document.createElement("img") - content.src = o.thumbnail.replace("{NODE_ID}", nodeId) - } - - if (o.caption) { - caption = o.caption.replace("{NODE_ID}", nodeId) - - if (!content) - content = document.createTextNode(caption) - } - - var p = document.createElement("p") - - if (o.href) { - var link = document.createElement("a") - link.target = "_blank" - link.href = o.href.replace("{NODE_ID}", nodeId) - link.appendChild(content) - - if (caption && o.thumbnail) - link.title = caption - - p.appendChild(link) - } else - p.appendChild(content) - - return p + var subst = {} + subst["{NODE_ID}"] = nodeId + return showStat(o, subst) } return function(config, el, router, d) { diff --git a/lib/proportions.js b/lib/proportions.js index 49ba4ca..b503ad8 100644 --- a/lib/proportions.js +++ b/lib/proportions.js @@ -30,36 +30,7 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc siteTable.classList.add("proportion") function showStatGlobal(o) { - var content, caption - - if (o.thumbnail) { - content = document.createElement("img") - content.src = o.thumbnail - } - - if (o.caption) { - caption = o.caption - - if (!content) - content = document.createTextNode(caption) - } - - var p = document.createElement("p") - - if (o.href) { - var link = document.createElement("a") - link.target = "_blank" - link.href = o.href - link.appendChild(content) - - if (caption && o.thumbnail) - link.title = caption - - p.appendChild(link) - } else - p.appendChild(content) - - return p + return showStat(o) } function count(nodes, key, f) { diff --git a/package.json b/package.json index 911ab17..c2bc317 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "node": true }, "globals": { + "showStat": false, "attributeEntry": false, "dictGet": false, "getJSON": false, From 40dd7d2a0a833c834052b3155b7c32255e1a7df9 Mon Sep 17 00:00:00 2001 From: David Kolossa Date: Thu, 24 Mar 2016 00:42:58 +0100 Subject: [PATCH 21/87] stats: Fix inaccuracies if lat or long is missing * please also note that freifunk-gluon/gluon#703 exists. --- lib/proportions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/proportions.js b/lib/proportions.js index 951d6ab..6ba58ab 100644 --- a/lib/proportions.js +++ b/lib/proportions.js @@ -159,7 +159,7 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc var fwDict = count(nodes, ["nodeinfo", "software", "firmware", "release"]) var hwDict = count(nodes, ["nodeinfo", "hardware", "model"]) var geoDict = count(nodes, ["nodeinfo", "location"], function (d) { - return d ? "ja" : "nein" + return d && d.longitude && d.latitude ? "ja" : "nein" }) var autoDict = count(nodes, ["nodeinfo", "software", "autoupdater"], function (d) { From 08e00d4b91adbcc6a6498da0518a80002258f9b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Mon, 28 Mar 2016 22:58:45 +0200 Subject: [PATCH 22/87] infobox/node: nodeinfos {NODE_NAME} support --- lib/infobox/node.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/infobox/node.js b/lib/infobox/node.js index 0a262cb..a9fecca 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -219,9 +219,10 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], return au.enabled ? "aktiviert (" + au.branch + ")" : "deaktiviert" } - function showStatImg(o, nodeId) { + function showStatImg(o, d) { var subst = {} - subst["{NODE_ID}"] = nodeId + subst["{NODE_ID}"] = d.nodeinfo.node_id ? d.nodeinfo.node_id : "unknown" + subst["{NODE_NAME}"] = d.nodeinfo.hostname ? d.nodeinfo.hostname : "unknown" return showStat(o, subst) } @@ -263,7 +264,7 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], var h4 = document.createElement("h4") h4.textContent = nodeInfo.name el.appendChild(h4) - el.appendChild(showStatImg(nodeInfo, d.nodeinfo.node_id)) + el.appendChild(showStatImg(nodeInfo, d)) }) if (d.neighbours.length > 0) { From 31545c758d911e370a4ccb38aa8917c4f8af17de Mon Sep 17 00:00:00 2001 From: anoy Date: Sat, 2 Apr 2016 22:47:57 +0200 Subject: [PATCH 23/87] infobox/location: beautify location-sidebar and cleanup sourcecode --- lib/infobox/location.js | 128 ++++++++++++++++++++-------------------- scss/main.scss | 21 +++++++ 2 files changed, 85 insertions(+), 64 deletions(-) diff --git a/lib/infobox/location.js b/lib/infobox/location.js index 128ad74..08805b0 100644 --- a/lib/infobox/location.js +++ b/lib/infobox/location.js @@ -1,80 +1,83 @@ define(function () { return function (config, el, router, d) { - var h2 = document.createElement("h2") - h2.textContent = "Location: " + d.toString() - el.appendChild(h2) + var sidebarTitle = document.createElement("h2") + sidebarTitle.textContent = "Location: " + d.toString() + el.appendChild(sidebarTitle) - getJSON("https://nominatim.openstreetmap.org/reverse?format=json&lat=" + d.lat + "&lon=" + d.lng + "&zoom=18&addressdetail=0") + getJSON("https://nominatim.openstreetmap.org/reverse?format=json&lat=" + d.lat + "&lon=" + d.lng + "&zoom=18&addressdetails=0") .then(function(result) { - h2.textContent = result.display_name + if(result.display_name) + sidebarTitle.textContent = result.display_name }) - var latDiv = document.createElement("div") - var h3lat = document.createElement("h3") - h3lat.textContent = "Breitengrad" - h3lat.id = "h3-latitude" - latDiv.appendChild(h3lat) - var txt1 = document.createElement("textarea") - txt1.id = "location-latitude" - txt1.value = d.lat.toFixed(9) - var p = document.createElement("p") - p.appendChild(txt1) - p.appendChild(createCopyButton(txt1.id)) - latDiv.appendChild(p) - el.appendChild(latDiv) + var editLat = document.createElement("input") + editLat.type = "text" + editLat.value = d.lat.toFixed(9) + el.appendChild(createBox("lat", "Breitengrad", editLat)) - var longDiv = document.createElement("div") - var h3lng = document.createElement("h3") - h3lng.textContent = "Längengrad" - longDiv.appendChild(h3lng) - var txt2 = document.createElement("textarea") - txt2.id = "location-longitude" - txt2.value = d.lng.toFixed(9) - var p2 = document.createElement("p") - p2.appendChild(txt2) - p2.appendChild(createCopyButton(txt2.id)) - longDiv.appendChild(p2) - longDiv.id = "div-longitude" - el.appendChild(longDiv) + var editLng = document.createElement("input") + editLng.type = "text" + editLng.value = d.lng.toFixed(9) + el.appendChild(createBox("lng", "Längengrad", editLng)) - var a1 = document.createElement("a") - a1.textContent = "plain" - a1.onclick = function() { + var editUci = document.createElement("textarea") + editUci.value = + "uci set gluon-node-info.@location[0]='location'; " + + "uci set gluon-node-info.@location[0].share_location='1';" + + "uci set gluon-node-info.@location[0].latitude='" + d.lat.toFixed(9) + "';" + + "uci set gluon-node-info.@location[0].longitude='" + d.lng.toFixed(9) + "';" + + "uci commit gluon-node-info" + + el.appendChild(createBox("uci", "Befehl", editUci, false)) + + var linkPlain = document.createElement("a") + linkPlain.textContent = "plain" + linkPlain.onclick = function() { switch2plain() return false } - a1.href = "#" - var a2 = document.createElement("a") - a2.textContent = "uci" - a2.onclick = function() { + linkPlain.href = "#" + + var linkUci = document.createElement("a") + linkUci.textContent = "uci" + linkUci.onclick = function() { switch2uci() return false } - a2.href = "#" + linkUci.href = "#" - var p3 = document.createElement("p") - p3.textContent = "Du kannst zwischen " - p3.appendChild(a1) - var t1 = document.createTextNode(" und ") - p3.appendChild(t1) - p3.appendChild(a2) - var t2 = document.createTextNode(" wechseln.") - p3.appendChild(t2) - el.appendChild(p3) + var hintText = document.createElement("p") + hintText.appendChild(document.createTextNode("Du kannst zwischen ")) + hintText.appendChild(linkPlain) + hintText.appendChild(document.createTextNode(" und ")) + hintText.appendChild(linkUci) + hintText.appendChild(document.createTextNode(" wechseln.")) + el.appendChild(hintText) - function createCopyButton(id) { + function createBox(name, title, inputElem, isVisible) { + var visible = typeof isVisible !== "undefined" ? isVisible : true + var box = document.createElement("div") + var heading = document.createElement("h3") + heading.textContent = title + box.appendChild(heading) var btn = document.createElement("button") btn.className = "ion-ios-copy" btn.title = "Kopieren" - btn.onclick = function() { - copy2clip(id) - } - return btn + btn.onclick = function() { copy2clip(inputElem.id) } + inputElem.id = "location-" + name + inputElem.readOnly = true + var line = document.createElement("p") + line.appendChild(inputElem) + line.appendChild(btn) + box.appendChild(line) + box.id = "box-" + name + box.style.display = visible ? "block" : "none" + return box } function copy2clip(id) { - var copyTextarea = document.querySelector("#" + id) - copyTextarea.select() + var copyField = document.querySelector("#" + id) + copyField.select() try { document.execCommand("copy") } catch (err) { @@ -83,18 +86,15 @@ define(function () { } function switch2plain() { - var box1 = document.getElementById("location-latitude") - box1.value = d.lat.toFixed(9) - var box2 = document.getElementById("location-longitude") - box2.value = d.lng.toFixed(9) - document.getElementById("h3-latitude").textContent = "Breitengrad" - document.getElementById("div-longitude").style.display = "block" + document.getElementById("box-uci").style.display = "none" + document.getElementById("box-lat").style.display = "block" + document.getElementById("box-lng").style.display = "block" } function switch2uci() { - document.getElementById("location-latitude").value = "uci set gluon-node-info.@location[0]='location'; uci set gluon-node-info.@location[0].share_location='1'; uci set gluon-node-info.@location[0].latitude='" + d.lat.toFixed(9) + "'; uci set gluon-node-info.@location[0].longitude='" + d.lng.toFixed(9) + "'; uci commit gluon-node-info" - document.getElementById("h3-latitude").textContent = "Befehl" - document.getElementById("div-longitude").style.display = "none" + document.getElementById("box-uci").style.display = "block" + document.getElementById("box-lat").style.display = "none" + document.getElementById("box-lng").style.display = "none" } } }) diff --git a/scss/main.scss b/scss/main.scss index 8a28ae6..3660109 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -151,6 +151,27 @@ table.attributes td { img { max-width: 100%; } + + input[type="text"], textarea { + box-shadow: 0 1px 3px rgba(0,0,0,0.12),0 1px 2px rgba(0,0,0,0.24); + border-radius: 5px; + border: none; + line-height: 1.67em; + vertical-align: bottom; + margin-right: 0.7em; + padding: 3px 6px; + font-family: monospace; + width: 70%; + max-width: 500px; + min-height: 42px; + font-size: 1.15em; + } + + textarea { + resize: vertical; + overflow: auto; + max-height: 300px; + } } button { From bc7e7888a5e9b484456d896e98d1381f61609435 Mon Sep 17 00:00:00 2001 From: eberhab Date: Wed, 20 Apr 2016 14:04:46 +0200 Subject: [PATCH 24/87] helper: str replace function should replace all instances of placeholder --- helper.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/helper.js b/helper.js index 0a15839..87eeaad 100644 --- a/helper.js +++ b/helper.js @@ -75,7 +75,8 @@ function localStorageTest() { function listReplace(s, subst) { for (key in subst) { - s = s.replace(key, subst[key]) + var re = new RegExp(key, 'g'); + s = s.replace(re, subst[key]) } return s } From 51c1c57e48017f9e9802ee05af62f83d3bd9f419 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Thu, 21 Apr 2016 22:32:22 +0200 Subject: [PATCH 25/87] Save selected layer in local storage (#17) --- lib/map.js | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/map.js b/lib/map.js index 9469c1f..bd45447 100644 --- a/lib/map.js +++ b/lib/map.js @@ -172,7 +172,7 @@ define(["map/clientlayer", "map/labelslayer", var map, userLocation var layerControl - var customLayers = new Set() + var customLayers = {} var baseLayers = {} var locateUserButton = new LocateButton(function (d) { @@ -259,16 +259,16 @@ define(["map/clientlayer", "map/labelslayer", if (layerName in baseLayers) return - if (customLayers.has(layerName)) + if (layerName in customLayers) return try { var layer = L.tileLayer.provider(layerName) layerControl.addBaseLayer(layer, layerName) - customLayers.add(layerName) + customLayers[layerName] = layer if (localStorageTest()) - localStorage.setItem("map/customLayers", JSON.stringify(Array.from(customLayers))) + localStorage.setItem("map/customLayers", JSON.stringify(Object.keys(customLayers))) } catch (e) { return } @@ -324,8 +324,21 @@ define(["map/clientlayer", "map/labelslayer", if (d) d.forEach(addLayer) + + d = JSON.parse(localStorage.getItem("map/selectedLayer")) + d = d && d.name in baseLayers ? baseLayers[d.name] : d && d.name in customLayers ? customLayers[d.name] : false + + if (d) { + map.removeLayer(layers[0].layer) + map.addLayer(d) + } } + map.on("baselayerchange", function(e) { + if (localStorageTest()) + localStorage.setItem("map/selectedLayer", JSON.stringify({name: e.name})) + }) + var clientLayer = new ClientLayer({minZoom: 15, maxZoom: maxLayerZoom}) clientLayer.addTo(map) clientLayer.setZIndex(5) From 8497a5f833c95495e8271f70dbaa7721481220a4 Mon Sep 17 00:00:00 2001 From: anoy Date: Thu, 21 Apr 2016 22:34:21 +0200 Subject: [PATCH 26/87] reimplement feature 'encoded url' (#16) change symbol names for better readability beautify location-sidebar cleanup sourcecode * change symbols to unicode-names * reimplement feature 'encoded url' --- lib/gui.js | 2 +- lib/map.js | 6 +++--- lib/router.js | 6 ++++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/gui.js b/lib/gui.js index ff52361..4ce989d 100644 --- a/lib/gui.js +++ b/lib/gui.js @@ -57,7 +57,7 @@ function (chroma, Map, Sidebar, Tabs, Container, Meshstats, Legend, Linklist, contentDiv.appendChild(buttons) var buttonToggle = document.createElement("button") - buttonToggle.textContent = "" + buttonToggle.textContent = "\uF133" buttonToggle.onclick = function () { if (content.constructor === Map) router.view("g") diff --git a/lib/map.js b/lib/map.js index bd45447..a9aa8f2 100644 --- a/lib/map.js +++ b/lib/map.js @@ -18,7 +18,7 @@ define(["map/clientlayer", "map/labelslayer", onAdd: function () { var button = L.DomUtil.create("button", "add-layer") - button.textContent = "" + button.textContent = "\uF2C7" // L.DomEvent.disableClickPropagation(button) // Click propagation isn't disabled as this causes problems with the @@ -46,7 +46,7 @@ define(["map/clientlayer", "map/labelslayer", onAdd: function () { var button = L.DomUtil.create("button", "locate-user") - button.textContent = "" + button.textContent = "\uF2E9" L.DomEvent.disableClickPropagation(button) L.DomEvent.addListener(button, "click", this.onClick, this) @@ -85,7 +85,7 @@ define(["map/clientlayer", "map/labelslayer", onAdd: function () { var button = L.DomUtil.create("button", "coord-picker") - button.textContent = "" + button.textContent = "\uF2A6" // Click propagation isn't disabled as this causes problems with the // location picking mode; instead propagation is stopped in onClick(). diff --git a/lib/router.js b/lib/router.js index 7aa6aae..fb56bb1 100644 --- a/lib/router.js +++ b/lib/router.js @@ -78,6 +78,8 @@ define(function () { if (!s) return false + s = decodeURIComponent(s) + if (!s.startsWith("#!")) return false @@ -94,7 +96,7 @@ define(function () { var id if (args[0] === "n") { - id = decodeURIComponent(args[1]) + id = args[1] if (id in objects.nodes) { currentObject = { node: objects.nodes[id] } gotoNode(objects.nodes[id]) @@ -103,7 +105,7 @@ define(function () { } if (args[0] === "l") { - id = decodeURIComponent(args[1]) + id = args[1] if (id in objects.links) { currentObject = { link: objects.links[id] } gotoLink(objects.links[id]) From 2a78af420845248dd2f7873943b5c7b925f07c1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Fri, 22 Apr 2016 01:05:32 +0200 Subject: [PATCH 27/87] proportions: correct use of online vs all nodes --- lib/proportions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/proportions.js b/lib/proportions.js index 0805131..f1bbb7d 100644 --- a/lib/proportions.js +++ b/lib/proportions.js @@ -146,7 +146,7 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc return d ? "ja" : "nein" }) - var gwNodesDict = count(nodes, ["statistics", "gateway"], function (d) { + var gwNodesDict = count(onlineNodes, ["statistics", "gateway"], function (d) { if (d === null) return null @@ -166,7 +166,7 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc return d }) - var siteDict = count(onlineNodes, ["nodeinfo", "system", "site_code"], function (d) { + var siteDict = count(nodes, ["nodeinfo", "system", "site_code"], function (d) { var rt = d if (config.siteNames) config.siteNames.forEach( function (t) { From 2f28c51da18b0701386560cb7cbb17285b28dee4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Sun, 24 Apr 2016 01:02:17 +0200 Subject: [PATCH 28/87] forcegraph, main: l2tp support --- lib/forcegraph.js | 14 +++++++------- lib/main.js | 12 ++++++++---- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/lib/forcegraph.js b/lib/forcegraph.js index a3d6e3a..7d96ce3 100644 --- a/lib/forcegraph.js +++ b/lib/forcegraph.js @@ -214,7 +214,7 @@ define(["d3"], function (d3) { function drawLabel(d) { var neighbours = d.neighbours.filter(function (d) { - return d.link.o.type !== "VPN" + return d.link.o.type !== "fastd" && d.link.o.type !== "L2TP" }) var sum = neighbours.reduce(function (a, b) { @@ -332,8 +332,8 @@ define(["d3"], function (d3) { ctx.moveTo(d.source.x + dx * nodeRadius, d.source.y + dy * nodeRadius) ctx.lineTo(d.target.x - dx * nodeRadius, d.target.y - dy * nodeRadius) ctx.strokeStyle = d.o.type === "Kabel" ? cableColor : d.color - ctx.globalAlpha = d.o.type === "VPN" ? 0.1 : 0.8 - ctx.lineWidth = d.o.type === "VPN" ? 1.5 : 2.5 + ctx.globalAlpha = d.o.type === "fastd" || d.o.type === "L2TP" ? 0.1 : 0.8 + ctx.lineWidth = d.o.type === "fastd" || d.o.type === "L2TP" ? 1.5 : 2.5 ctx.stroke() }) @@ -523,7 +523,7 @@ define(["d3"], function (d3) { } var links = intLinks.filter(function (d) { - return d.o.type !== "VPN" + return d.o.type !== "fastd" && d.o.type !== "L2TP" }).filter(function (d) { return distanceLink(e, d.source, d.target) < LINE_RADIUS }) @@ -584,13 +584,13 @@ define(["d3"], function (d3) { .charge(-250) .gravity(0.1) .linkDistance(function (d) { - if (d.o.type === "VPN") + if (d.o.type === "fastd" || d.o.type === "L2TP") return 0 else return LINK_DISTANCE }) .linkStrength(function (d) { - if (d.o.type === "VPN") + if (d.o.type === "fastd" || d.o.type === "L2TP") return 0 else return Math.max(0.5, 1 / d.o.tq) @@ -644,7 +644,7 @@ define(["d3"], function (d3) { e.source = newNodesDict[d.source.id] e.target = newNodesDict[d.target.id] - if (d.type === "VPN") + if (d.type === "fastd" || d.type === "L2TP") e.color = "rgba(255, 255, 255, " + (0.6 / d.tq) + ")" else e.color = linkScale(d.tq).hex() diff --git a/lib/main.js b/lib/main.js index db37039..13649f7 100644 --- a/lib/main.js +++ b/lib/main.js @@ -113,9 +113,13 @@ function (moment, Router, L, GUI, numeral) { }) links.forEach( function (d) { - if (d.type === "tunnel") - d.type = "VPN" - else if (d.type === "wireless") + console.log(d) + if (d.type === "tunnel" || d.type === "fastd") + d.type = "fastd" + else if (d.type === "l2tp") { + d.type = "L2TP" + d.target.node.flags.uplink = true + } else if (d.type === "wireless") d.type = "Wifi" else if (d.type === "other") d.type = "Kabel" @@ -128,7 +132,7 @@ function (moment, Router, L, GUI, numeral) { } d.source.node.neighbours.push({ node: d.target.node, link: d, incoming: false }) d.target.node.neighbours.push({ node: d.source.node, link: d, incoming: true }) - if (d.type !== "VPN") + if (d.type !== "fastd" && d.type !== "L2TP") d.source.node.meshlinks = d.source.node.meshlinks ? d.source.node.meshlinks + 1 : 1 }) From 075076a2fed48ce8dbb6df2a090600739230f8a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?PetaByteBoy=20//=20Milan=20P=C3=A4ssler?= Date: Sun, 24 Apr 2016 19:47:48 +0200 Subject: [PATCH 29/87] infobox/*infos: fix iframe height option --- helper.js | 4 ++-- lib/infobox/.charts.js.swp | Bin 0 -> 16384 bytes lib/main.js | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) create mode 100644 lib/infobox/.charts.js.swp diff --git a/helper.js b/helper.js index 87eeaad..e14faf3 100644 --- a/helper.js +++ b/helper.js @@ -150,7 +150,7 @@ function attributeEntry(el, label, value) { function createIframe(opt, width, height) { el = document.createElement("iframe") width = typeof width !== 'undefined' ? width : '525px'; - height = typeof height !== 'undefined' ? width : '350px'; + height = typeof height !== 'undefined' ? height : '350px'; if (opt.src) el.src = opt.src @@ -195,7 +195,7 @@ function showStat(o, subst) { } if (o.iframe) { - content = createIframe(o.iframe) + content = createIframe(o.iframe, o.width, o.height) if (o.iframe.src) content.src = listReplace(o.iframe.src, subst) else diff --git a/lib/infobox/.charts.js.swp b/lib/infobox/.charts.js.swp new file mode 100644 index 0000000000000000000000000000000000000000..243ae9186354c11289bebd332b34f45a8cab25d6 GIT binary patch literal 16384 zcmYc?2=nw+FxN9-U|?VnU|=|X>1P<<2`L6CDF%juq$H3iL0pfq@C? z-!>@Ch(28JNe0Du4k1FZjlou7f>8b1TWT7CwG8TKN|zXJ~jr1#cT`=jcg1IUTh2uCTt80I&2IKs%#7lDr^i4Tx<*s zcUT!1cC#`t^s_QBB(X9uc(5`sxU(`axUn)Y7_c%h@Ub#5++$&2xXZ%8u$P5_p@)Tm zA(VxIA%um2!GVQ=!JdVIL63!jL7jzxL5+ohftiJY;T|&s!v)fiI>DQc6~Le@ zu}GmRKR?&0w4@|IuUNrWAv%_U0W1X;cgZZ%O9rh2@yRSM(MwE8(NF>@*G+<`SJH&4 zg_+}$S*BpCkdmKVnwy$eqL*Bhnpl$Rnv)9RX(**+mce!C>npevC6j^r3ER8C8^G!g)Ydpf=$7&xhS=y zv?veR0jUtLf{j9UnS!lCvaw!zYF=tlVo55h6G?C#Bxp!;T}oydB)}9DYW0#b^B@7F zsRn?MH+}e&rAVX4>A&hp$6xIb?RlNz%?snWTvDlSz!h$L}{^JZejtF zxe!rgvukw}s%tf286RXD)UM?GoSf9;lKdjLT?z_tv1o`vdYLJ)3bqPRPEKM{Y7Shr z5-3`W@j0z1HKjB;70GpQ<8`1$(#WC7`8i15QUY_S>QZ3k@-( zh*VHeDoe~Mr6?{H6qG8ItQ3?=GILXv5K*d>omvU<9xM-ob9pjyX|7<4oWUX4va~1_ z8Vkj+OpZMRAbA$*J5&o2D>94qD)dS+le6{W)AEaQ6H7G85_1sYf?GL6wSp~DWd+g+ zcPuDOaqEU!1}}18K1OyB#0Iz*;KeUIcrX3`((;QGQu9)BQj3cfa`N*F6p~8Q z!6A^Dmsx_P2n3g^#d-xr`6c-!l?AEb)WV>k07(vD_k(n5K7P^sl~|o5|mkCnNkUq(2%qvIUCv0XoUpST_O4TIU$(^NNo|gZxB9# z+fYo;5_3SVFf+0+Ffgdq(#L8*E|LLChPnB9AU=|ICBqaYB;V<4 zA=z$Zk^xc;wO+}{49rE*oPn$vNvj1|DO9J0f|dfv<){ufG*!@2Ff)MpUkTDERkBiu z273e?ilE?vR32#I2rfYsY!&iKb07@_uyU{{TzxXQa{;Mpz|wj7DWDPrL@_8RfEsgP z4WJ$sA{~KbbwHh+w9Ir+dB>2FnwFWDsu8V}YzzvG6l0}W9i-|b*;q#*#TcX#)c-eU zU|=u@_3H!}7+~}JNBJ2TCh;>cWb!jGnDH|(nDR3)@bfb;yyRnGc)`cOaDFf*)A?yqcU)UHJ?y)g29Ajf(*u=)buz-z$ zVI~^`!wfbChDv46j%j7#_1SFg#*qU^u|az%ZSa zfuWR@fkBUzfkBOxfq{*cf#CxS1H(-g28Jmt3=DNF3=9@53=B#v3=Hd-85rg=Gcfcr zGcdF=GceRKGceRLGcbfQGcY(ZGcaf}Gcf#PVqkd0#K5qRiGg7`69YpV69Ypj69YpW z69YpS69Yp469a=k69a=c69a=669a=46C}RPKyi+@FOO3a+@6EBb0Fyvlw@l`1fq6> z0UK=yHrmJ}169}n zENlT2g+(H`+y#~5;7Sh^QJ_dbq-(gl@=9})Qi~L96#NwI6*QDUuF>#Q&{lwmYijBh z=VT_QY8YxNSSf&IArf#$fJ$>e1zQDhqAkcT*Dy5D0R1qYYy9z`40NIx{aNwIVj!Fcx7e zq`C%6DA+=E7lX8bor!LO9$2A&nnpz-h%{4JO13uiK0g*r?a)_fr0Rw8ifSc?}RtkBk8T*Gs5lilc|dIdITJNyz?^_Pj*}B}a*`60 zvmpbD;2v2tIF{i#93{%YQdm{N!XNB74UmHo@f1*$pPN~ns+X9PqfuIv0~v5iPc88Z z_V?4&)GNtI&4UNI0z@xt&==(2TBJS;wEqYaR!{(&1y0bVML8%kpt7N~C!a3u^) z6d+-31toh>c~p>Cl$e`Zl3G-(mzAHHr=g^#gklV$d{b+wPqu6 zD}qZBa|=*pi%SxVO2G0Oa0Lpw;DKGJp`Zpj%1|9BC=mVxr6RbyAhC&=VKDOn#K-Ui z2J#fhT!d#}A&n5xgS7t9Qxn{BkbZ<8pv8PzPJVuo1}HD-<>i-aXe#JK@)C-!Oi-B* zb~~tLuLmMPTV=tFc%1<)z4 zXs~s$3bqPKC3#R&6+mpXiGVUaaL*a80=X=J3nDi@K=y#c2-%++VA~K50Vx7E(m@Oa z#+YoHmbXj0tq7@Drl7HC}e{o z31TORL^TZTb&wI@_(fKkRFbC$9c4jjGJ(_}c?P5mZN>z{7YHjsgNbNXLV7tMmw}8b zPAzdPDJjZKDlJLXPy$s8x**r-f+Ivp2a Date: Mon, 9 May 2016 18:17:45 +0200 Subject: [PATCH 30/87] fix examples --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8b6100b..4cac2ca 100644 --- a/README.md +++ b/README.md @@ -119,12 +119,12 @@ Examples for `nodeInfos`: { "name": "Clientstatistik", "href": "stats/dashboard/db/node-byid?var-nodeid={NODE_ID}", - "thumbnail": "stats/render/dashboard-solo/db/node-byid?panelId=1&fullscreen&theme=light&width=600&height=300&var-nodeid={NODE_ID}" + "thumbnail": "stats/render/dashboard-solo/db/node-byid?panelId=1&fullscreen&theme=light&width=600&height=300&var-nodeid={NODE_ID}", "caption": "Knoten {NODE_ID}" }, { "name": "Uptime", "href": "stats/dashboard/db/node-byid?var-nodeid={NODE_ID}", - "thumbnail": "stats/render/dashboard-solo/db/node-byid?panelId=2&fullscreen&theme=light&width=600&height=300&var-nodeid={NODE_ID}" + "thumbnail": "stats/render/dashboard-solo/db/node-byid?panelId=2&fullscreen&theme=light&width=600&height=300&var-nodeid={NODE_ID}", "caption": "Knoten {NODE_ID}" } ] From e1e510c308df53eeed533dcee9828c004fcad6b9 Mon Sep 17 00:00:00 2001 From: Xaver Maierhofer Date: Thu, 19 May 2016 17:47:13 +0200 Subject: [PATCH 31/87] use libsass (#22) Avoid ruby dependency --- Gruntfile.js | 2 +- README.md | 8 +++----- package.json | 4 +++- tasks/build.js | 23 +++++++++++++++++++---- 4 files changed, 26 insertions(+), 11 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index b53c51d..b63ad56 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -17,7 +17,7 @@ module.exports = function (grunt) { grunt.loadTasks("tasks") - grunt.registerTask("default", ["bower-install-simple", "lint", "saveRevision", "copy", "sass", "requirejs"]) + grunt.registerTask("default", ["bower-install-simple", "lint", "saveRevision", "copy", "sass", "postcss", "requirejs"]) grunt.registerTask("lint", ["eslint"]) grunt.registerTask("dev", ["default", "connect:server", "watch"]) } diff --git a/README.md b/README.md index 4cac2ca..587694f 100644 --- a/README.md +++ b/README.md @@ -21,18 +21,16 @@ HopGlass is a frontend for the [HopGlass Server](https://github.com/plumpudding/ # Installing dependencies -Install npm and Sass with your package-manager. On Debian-like systems run: +Install npm package-manager. On Debian-like systems run: - sudo apt-get install npm ruby-sass - -or if you have bundler you can install ruby-sass simply via `bundle install` + sudo apt-get install npm On Mac you have to install only npm via brew and sass /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" brew install node sudo gem install sass - + Execute these commands on your server as a normal user to prepare the dependencies: git clone https://github.com/plumpudding/hopglass diff --git a/package.json b/package.json index c2bc317..d5cbd37 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "test": "node -e \"require('grunt').cli()\" '' clean lint" }, "devDependencies": { + "autoprefixer": "^6.3.3", "grunt": "^0.4.5", "grunt-check-dependencies": "^0.6.0", "grunt-contrib-clean": "^0.6.0", @@ -11,7 +12,8 @@ "grunt-contrib-copy": "^0.5.0", "grunt-contrib-cssmin": "^0.12.2", "grunt-contrib-requirejs": "^0.4.4", - "grunt-contrib-sass": "^0.9.2", + "grunt-sass": "^1.1.0", + "grunt-postcss": "^0.7.2", "grunt-contrib-uglify": "^0.5.1", "grunt-contrib-watch": "^0.6.1", "grunt-eslint": "^10.0.0", diff --git a/tasks/build.js b/tasks/build.js index 7b3ee0a..5a8c918 100644 --- a/tasks/build.js +++ b/tasks/build.js @@ -56,15 +56,29 @@ module.exports = function(grunt) { } }, sass: { + options: { + sourceMap: true, + outputStyle: "compressed" + }, dist: { - options: { - style: "compressed" - }, files: { "build/style.css": "scss/main.scss" } } }, + postcss: { + options: { + map: true, + processors: [ + require("autoprefixer")({ + browsers: ["last 2 versions"] + }) + ] + }, + dist: { + src: "build/style.css" + } + }, cssmin: { target: { files: { @@ -106,5 +120,6 @@ module.exports = function(grunt) { grunt.loadNpmTasks("grunt-bower-install-simple") grunt.loadNpmTasks("grunt-contrib-copy") grunt.loadNpmTasks("grunt-contrib-requirejs") - grunt.loadNpmTasks("grunt-contrib-sass") + grunt.loadNpmTasks("grunt-sass") + grunt.loadNpmTasks("grunt-postcss") } From 31d14648056d3a3e26c0b3c8e63e3c302a6c0ecf Mon Sep 17 00:00:00 2001 From: Xaver Maierhofer Date: Thu, 19 May 2016 17:47:32 +0200 Subject: [PATCH 32/87] clean scss (#21) * [TASK] CGL - Formation * [TASK] Generic font fallback * [TASK] Remove swp file --- lib/infobox/.charts.js.swp | Bin 16384 -> 0 bytes scss/_filters.scss | 6 +++--- scss/_legend.scss | 33 ++++++++++++++------------------- scss/_map.scss | 26 +++++++++++++++++++------- scss/_reset.scss | 6 ++++++ scss/_shadow.scss | 24 ++++++++++-------------- scss/main.scss | 16 ++++++++-------- 7 files changed, 60 insertions(+), 51 deletions(-) delete mode 100644 lib/infobox/.charts.js.swp diff --git a/lib/infobox/.charts.js.swp b/lib/infobox/.charts.js.swp deleted file mode 100644 index 243ae9186354c11289bebd332b34f45a8cab25d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 zcmYc?2=nw+FxN9-U|?VnU|=|X>1P<<2`L6CDF%juq$H3iL0pfq@C? z-!>@Ch(28JNe0Du4k1FZjlou7f>8b1TWT7CwG8TKN|zXJ~jr1#cT`=jcg1IUTh2uCTt80I&2IKs%#7lDr^i4Tx<*s zcUT!1cC#`t^s_QBB(X9uc(5`sxU(`axUn)Y7_c%h@Ub#5++$&2xXZ%8u$P5_p@)Tm zA(VxIA%um2!GVQ=!JdVIL63!jL7jzxL5+ohftiJY;T|&s!v)fiI>DQc6~Le@ zu}GmRKR?&0w4@|IuUNrWAv%_U0W1X;cgZZ%O9rh2@yRSM(MwE8(NF>@*G+<`SJH&4 zg_+}$S*BpCkdmKVnwy$eqL*Bhnpl$Rnv)9RX(**+mce!C>npevC6j^r3ER8C8^G!g)Ydpf=$7&xhS=y zv?veR0jUtLf{j9UnS!lCvaw!zYF=tlVo55h6G?C#Bxp!;T}oydB)}9DYW0#b^B@7F zsRn?MH+}e&rAVX4>A&hp$6xIb?RlNz%?snWTvDlSz!h$L}{^JZejtF zxe!rgvukw}s%tf286RXD)UM?GoSf9;lKdjLT?z_tv1o`vdYLJ)3bqPRPEKM{Y7Shr z5-3`W@j0z1HKjB;70GpQ<8`1$(#WC7`8i15QUY_S>QZ3k@-( zh*VHeDoe~Mr6?{H6qG8ItQ3?=GILXv5K*d>omvU<9xM-ob9pjyX|7<4oWUX4va~1_ z8Vkj+OpZMRAbA$*J5&o2D>94qD)dS+le6{W)AEaQ6H7G85_1sYf?GL6wSp~DWd+g+ zcPuDOaqEU!1}}18K1OyB#0Iz*;KeUIcrX3`((;QGQu9)BQj3cfa`N*F6p~8Q z!6A^Dmsx_P2n3g^#d-xr`6c-!l?AEb)WV>k07(vD_k(n5K7P^sl~|o5|mkCnNkUq(2%qvIUCv0XoUpST_O4TIU$(^NNo|gZxB9# z+fYo;5_3SVFf+0+Ffgdq(#L8*E|LLChPnB9AU=|ICBqaYB;V<4 zA=z$Zk^xc;wO+}{49rE*oPn$vNvj1|DO9J0f|dfv<){ufG*!@2Ff)MpUkTDERkBiu z273e?ilE?vR32#I2rfYsY!&iKb07@_uyU{{TzxXQa{;Mpz|wj7DWDPrL@_8RfEsgP z4WJ$sA{~KbbwHh+w9Ir+dB>2FnwFWDsu8V}YzzvG6l0}W9i-|b*;q#*#TcX#)c-eU zU|=u@_3H!}7+~}JNBJ2TCh;>cWb!jGnDH|(nDR3)@bfb;yyRnGc)`cOaDFf*)A?yqcU)UHJ?y)g29Ajf(*u=)buz-z$ zVI~^`!wfbChDv46j%j7#_1SFg#*qU^u|az%ZSa zfuWR@fkBUzfkBOxfq{*cf#CxS1H(-g28Jmt3=DNF3=9@53=B#v3=Hd-85rg=Gcfcr zGcdF=GceRKGceRLGcbfQGcY(ZGcaf}Gcf#PVqkd0#K5qRiGg7`69YpV69Ypj69YpW z69YpS69Yp469a=k69a=c69a=669a=46C}RPKyi+@FOO3a+@6EBb0Fyvlw@l`1fq6> z0UK=yHrmJ}169}n zENlT2g+(H`+y#~5;7Sh^QJ_dbq-(gl@=9})Qi~L96#NwI6*QDUuF>#Q&{lwmYijBh z=VT_QY8YxNSSf&IArf#$fJ$>e1zQDhqAkcT*Dy5D0R1qYYy9z`40NIx{aNwIVj!Fcx7e zq`C%6DA+=E7lX8bor!LO9$2A&nnpz-h%{4JO13uiK0g*r?a)_fr0Rw8ifSc?}RtkBk8T*Gs5lilc|dIdITJNyz?^_Pj*}B}a*`60 zvmpbD;2v2tIF{i#93{%YQdm{N!XNB74UmHo@f1*$pPN~ns+X9PqfuIv0~v5iPc88Z z_V?4&)GNtI&4UNI0z@xt&==(2TBJS;wEqYaR!{(&1y0bVML8%kpt7N~C!a3u^) z6d+-31toh>c~p>Cl$e`Zl3G-(mzAHHr=g^#gklV$d{b+wPqu6 zD}qZBa|=*pi%SxVO2G0Oa0Lpw;DKGJp`Zpj%1|9BC=mVxr6RbyAhC&=VKDOn#K-Ui z2J#fhT!d#}A&n5xgS7t9Qxn{BkbZ<8pv8PzPJVuo1}HD-<>i-aXe#JK@)C-!Oi-B* zb~~tLuLmMPTV=tFc%1<)z4 zXs~s$3bqPKC3#R&6+mpXiGVUaaL*a80=X=J3nDi@K=y#c2-%++VA~K50Vx7E(m@Oa z#+YoHmbXj0tq7@Drl7HC}e{o z31TORL^TZTb&wI@_(fKkRFbC$9c4jjGJ(_}c?P5mZN>z{7YHjsgNbNXLV7tMmw}8b zPAzdPDJjZKDlJLXPy$s8x**r-f+Ivp2a Date: Sun, 22 May 2016 00:25:46 +0200 Subject: [PATCH 33/87] meshstats: fix NaN client count --- lib/meshstats.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/meshstats.js b/lib/meshstats.js index f0ce186..3174eee 100644 --- a/lib/meshstats.js +++ b/lib/meshstats.js @@ -9,7 +9,7 @@ define(function () { var totalNewNodes = sum(d.nodes.new.map(one)) var totalLostNodes = sum(d.nodes.lost.map(one)) var totalClients = sum(d.nodes.all.filter(online).map( function (d) { - return d.statistics.clients + return d.statistics.clients ? d.statistics.clients : 0 })) var totalGateways = sum(d.nodes.all.filter(online).filter( function (d) { return d.flags.gateway From 20f0f08de35b250bcebb57617fb4bf7ce8f290aa Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sun, 22 May 2016 03:12:08 +0200 Subject: [PATCH 34/87] Replace MapQuest with OpenStreetMap.HOT in example config (#26) MapQuest Open Tiles service is announced to be discontinued and already started removing tiles at the highest zoom level. MapQuest provides a replacement service requiring custom javascript code to be injected, which I don't consider a good idea. OpenStreetMap.HOT is a OpenStreetMap map style using pastel colours and thus is lot better than Mapnik for rendering stuff on it. --- config.json.example | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/config.json.example b/config.json.example index c4616e2..933ba02 100644 --- a/config.json.example +++ b/config.json.example @@ -5,14 +5,8 @@ "showContact": true, "maxAge": 14, "mapLayers": [ - { "name": "MapQuest", - "url": "https://otile{s}-s.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.jpg", - "config": { - "subdomains": "1234", - "type": "osm", - "attribution": "Tiles © MapQuest, Data CC-BY-SA OpenStreetMap", - "maxZoom": 18 - } + { + "name": "OpenStreetMap.HOT" }, { "name": "Stamen.TonerLite" From 971938507690324c59f93adc3baf74f82a00086f Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sun, 22 May 2016 12:30:31 +0200 Subject: [PATCH 35/87] map: dynamically select maxLayerZoom (#27) Fixes clients/names being hidden accidentally (in certain conditions). Also added auto-zoom-out to ensure zoom is in bounds --- lib/map.js | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/lib/map.js b/lib/map.js index a9aa8f2..aca0097 100644 --- a/lib/map.js +++ b/lib/map.js @@ -290,12 +290,6 @@ define(["map/clientlayer", "map/labelslayer", } }) - var maxLayerZoom = Math.max.apply(Math, config.mapLayers.map( - function(d) { - return (typeof d.config !== "undefined" && typeof d.config.maxZoom !== "undefined") ? d.config.maxZoom : 18 - })) - - layers[0].layer.addTo(map) layers.forEach( function (d) { @@ -334,19 +328,23 @@ define(["map/clientlayer", "map/labelslayer", } } - map.on("baselayerchange", function(e) { - if (localStorageTest()) - localStorage.setItem("map/selectedLayer", JSON.stringify({name: e.name})) - }) - - var clientLayer = new ClientLayer({minZoom: 15, maxZoom: maxLayerZoom}) + var clientLayer = new ClientLayer({minZoom: 15}) clientLayer.addTo(map) clientLayer.setZIndex(5) - var labelsLayer = new LabelsLayer({maxZoom: maxLayerZoom}) + var labelsLayer = new LabelsLayer({}) labelsLayer.addTo(map) labelsLayer.setZIndex(6) + map.on("baselayerchange", function(e) { + map.options.maxZoom = e.layer.options.maxZoom + clientLayer.options.maxZoom = map.options.maxZoom + labelsLayer.options.maxZoom = map.options.maxZoom + if (map.getZoom() > map.options.maxZoom) map.setZoom(map.options.maxZoom) + if (localStorageTest()) + localStorage.setItem("map/selectedLayer", JSON.stringify({name: e.name})) + }) + var nodeDict = {} var linkDict = {} var highlight From 3971c362508fdf4e9a692b38fa60a4aefec6a0e1 Mon Sep 17 00:00:00 2001 From: Xaver Maierhofer Date: Sun, 22 May 2016 12:30:44 +0200 Subject: [PATCH 36/87] add .editorconfig (#25) --- .editorconfig | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..f0abb4f --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +# EditorConfig is awesome: http://EditorConfig.org + +# top-most EditorConfig file +root = true +charset = utf-8 + +# Get rid of whitespace to avoid diffs with a bunch of EOL changes +trim_trailing_whitespace = true + +[*] +end_of_line = lf +insert_final_newline = true + +[*.{js,html,scss,json}] +indent_size = 2 +indent_style = space From 1bcd2b797dc1ac2dc804084f6934a33112e942f6 Mon Sep 17 00:00:00 2001 From: Xaver Maierhofer Date: Sun, 22 May 2016 18:18:07 +0200 Subject: [PATCH 37/87] remove obsolete Gemfile (#28) --- Gemfile | 2 -- Gemfile.lock | 13 ------------- 2 files changed, 15 deletions(-) delete mode 100644 Gemfile delete mode 100644 Gemfile.lock diff --git a/Gemfile b/Gemfile deleted file mode 100644 index bc67cf1..0000000 --- a/Gemfile +++ /dev/null @@ -1,2 +0,0 @@ -source 'https://rubygems.org' -gem "sass" \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock deleted file mode 100644 index 1f6e618..0000000 --- a/Gemfile.lock +++ /dev/null @@ -1,13 +0,0 @@ -GEM - remote: https://rubygems.org/ - specs: - sass (3.4.16) - -PLATFORMS - ruby - -DEPENDENCIES - sass - -BUNDLED WITH - 1.10.6 From 93355f28ba601d618ed0cae7debc6aabcbdfc78b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Thu, 2 Jun 2016 22:43:53 +0200 Subject: [PATCH 38/87] meshstats: dynamic gateway count --- lib/filters/nodefilter.js | 3 +-- lib/meshstats.js | 6 ++++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/filters/nodefilter.js b/lib/filters/nodefilter.js index 319a71e..17e6b41 100644 --- a/lib/filters/nodefilter.js +++ b/lib/filters/nodefilter.js @@ -4,9 +4,8 @@ define([], function () { var n = Object.create(data) n.nodes = {} - for (var key in data.nodes) { + for (var key in data.nodes) n.nodes[key] = data.nodes[key].filter(filter) - } var filteredIds = new Set() diff --git a/lib/meshstats.js b/lib/meshstats.js index 3174eee..e9b9845 100644 --- a/lib/meshstats.js +++ b/lib/meshstats.js @@ -11,9 +11,11 @@ define(function () { var totalClients = sum(d.nodes.all.filter(online).map( function (d) { return d.statistics.clients ? d.statistics.clients : 0 })) - var totalGateways = sum(d.nodes.all.filter(online).filter( function (d) { + var totalGateways = sum(Array.from(new Set(d.nodes.all.filter(online).map( function(d) { + return d.statistics.gateway + }).concat(d.nodes.all.filter( function (d) { return d.flags.gateway - }).map(one)) + })))).map(one)) var nodetext = [{ count: totalOnlineNodes, label: "online" }, { count: totalNewNodes, label: "neu" }, From 4c6ba69dd381b3661935eb0e7bdc75ee8581e586 Mon Sep 17 00:00:00 2001 From: Milan Paessler Date: Thu, 2 Jun 2016 23:17:06 +0200 Subject: [PATCH 39/87] meshstats: don't count undefined as gateway --- lib/meshstats.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/meshstats.js b/lib/meshstats.js index e9b9845..96d19fd 100644 --- a/lib/meshstats.js +++ b/lib/meshstats.js @@ -15,7 +15,9 @@ define(function () { return d.statistics.gateway }).concat(d.nodes.all.filter( function (d) { return d.flags.gateway - })))).map(one)) + })))).map(function(d) { + return (typeof d === "string") ? 1 : 0 + })) var nodetext = [{ count: totalOnlineNodes, label: "online" }, { count: totalNewNodes, label: "neu" }, From 2da97bca161551d130e46d27245b4a4dd1afc77d Mon Sep 17 00:00:00 2001 From: Moritz Date: Fri, 3 Jun 2016 00:43:08 +0200 Subject: [PATCH 40/87] meshstats: show offline nodes (#39) --- lib/meshstats.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/meshstats.js b/lib/meshstats.js index 96d19fd..b10f7c4 100644 --- a/lib/meshstats.js +++ b/lib/meshstats.js @@ -6,6 +6,7 @@ define(function () { self.setData = function (d) { var totalNodes = sum(d.nodes.all.map(one)) var totalOnlineNodes = sum(d.nodes.all.filter(online).map(one)) + var totalOfflineNodes = sum(d.nodes.all.filter(function (node) {return !node.flags.online}).map(one)) var totalNewNodes = sum(d.nodes.new.map(one)) var totalLostNodes = sum(d.nodes.lost.map(one)) var totalClients = sum(d.nodes.all.filter(online).map( function (d) { @@ -20,6 +21,7 @@ define(function () { })) var nodetext = [{ count: totalOnlineNodes, label: "online" }, + { count: totalOfflineNodes, label: "offline" }, { count: totalNewNodes, label: "neu" }, { count: totalLostNodes, label: "verschwunden" } ].filter( function (d) { return d.count > 0 } ) From 2bbdd1e07775332508671a3b5382f390e9f17613 Mon Sep 17 00:00:00 2001 From: Johannes Rudolph Date: Sun, 5 Jun 2016 22:55:26 +0200 Subject: [PATCH 41/87] main: filter duplicate nodes from different data sources * add jquery * filter duplicate nodes by online state * remove old stuff * remove debug output * remove curly braces --- lib/main.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/main.js b/lib/main.js index 396aed1..21fabe9 100644 --- a/lib/main.js +++ b/lib/main.js @@ -4,12 +4,14 @@ function (moment, Router, L, GUI, numeral) { function handleData(data) { var dataNodes = {} dataNodes.nodes = [] + dataNodes.nodeIds = [] var dataGraph = {} dataGraph.batadv = {} dataGraph.batadv.nodes = [] dataGraph.batadv.links = [] + function rearrangeLinks(d) { d.source += dataGraph.batadv.nodes.length d.target += dataGraph.batadv.nodes.length @@ -32,11 +34,22 @@ function (moment, Router, L, GUI, numeral) { vererr = "Unsupported nodes version: " + data[i].version console.log(vererr) //silent fail } else { - dataNodes.nodes = dataNodes.nodes.concat(data[i].nodes) + data[i].nodes.forEach(fillData) dataNodes.timestamp = data[i].timestamp } } + function fillData (node) { + var position = dataNodes.nodeIds.indexOf(node.nodeinfo.node_id) + if(position === -1){ + dataNodes.nodes.push(node) + dataNodes.nodeIds.push(node.nodeinfo.node_id) + } + else + if(node.flags.online === true) + dataNodes.nodes[position] = node + } + var nodes = dataNodes.nodes.filter( function (d) { return "firstseen" in d && "lastseen" in d }) From f80ea1ca8f536b15be59eaba1e8cf524e490c212 Mon Sep 17 00:00:00 2001 From: eberhab Date: Wed, 8 Jun 2016 23:23:56 +0200 Subject: [PATCH 42/87] infobox: added wifi channel, airtime and batctl nexthop (#38) * infobox: added wifi channel, airtime and batctl nexthop * simplify * kill all semicolons * update data locations I'd suggest that channel information go under nodeinfo. Airtime and nexthop are changing variables which should go under statistics. * filter out nodes with faulty nodeinfo * additional nexthop key The nexthop to the batman gateway has now been made available in gluon master where it will be called "gateway_nexthop" the "nexthop" key is also currently in use and should eventually be removed * sidebar/node: cosmetic changes to gateway/nexthop * remove data validity check * move wifi helper function to sidebar/node * cosmetics --- helper.js | 26 +++++++-------- lib/infobox/node.js | 80 ++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 92 insertions(+), 14 deletions(-) diff --git a/helper.js b/helper.js index e14faf3..93acf69 100644 --- a/helper.js +++ b/helper.js @@ -1,23 +1,23 @@ function get(url) { return new Promise(function(resolve, reject) { - var req = new XMLHttpRequest(); - req.open('GET', url); + var req = new XMLHttpRequest() + req.open('GET', url) req.onload = function() { if (req.status == 200) { - resolve(req.response); + resolve(req.response) } else { - reject(Error(req.statusText)); + reject(Error(req.statusText)) } - }; + } req.onerror = function() { - reject(Error("Network Error")); - }; + reject(Error("Network Error")) + } - req.send(); - }); + req.send() + }) } function getJSON(url) { @@ -75,7 +75,7 @@ function localStorageTest() { function listReplace(s, subst) { for (key in subst) { - var re = new RegExp(key, 'g'); + var re = new RegExp(key, 'g') s = s.replace(re, subst[key]) } return s @@ -149,8 +149,8 @@ function attributeEntry(el, label, value) { function createIframe(opt, width, height) { el = document.createElement("iframe") - width = typeof width !== 'undefined' ? width : '525px'; - height = typeof height !== 'undefined' ? height : '350px'; + width = typeof width !== 'undefined' ? width : '525px' + height = typeof height !== 'undefined' ? height : '350px' if (opt.src) el.src = opt.src @@ -180,7 +180,7 @@ function createIframe(opt, width, height) { function showStat(o, subst) { var content, caption - subst = typeof subst !== 'undefined' ? subst : {}; + subst = typeof subst !== 'undefined' ? subst : {} if (o.thumbnail) { content = document.createElement("img") diff --git a/lib/infobox/node.js b/lib/infobox/node.js index a9fecca..3b7dd6e 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -81,6 +81,54 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], return d.firstseen.fromNow(true) } + function wifiChannelAlias(ch) { + var chlist = { + "1": "2412 MHz", + "2": "2417 MHz", + "3": "2422 MHz", + "4": "2427 MHz", + "5": "2432 MHz", + "6": "2437 MHz", + "7": "2442 MHz", + "8": "2447 MHz", + "9": "2452 MHz", + "10": "2457 MHz", + "11": "2462 MHz", + "12": "2467 MHz", + "13": "2472 MHz", + "36": "5180 MHz (Indoors)", + "40": "5200 MHz (Indoors)", + "44": "5220 MHz (Indoors)", + "48": "5240 MHz (Indoors)", + "52": "5260 MHz (Indoors/DFS/TPC)", + "56": "5280 MHz (Indoors/DFS/TPC)", + "60": "5300 MHz (Indoors/DFS/TPC)", + "64": "5320 MHz (Indoors/DFS/TPC)", + "100": "5500 MHz (DFS) !!", + "104": "5520 MHz (DFS) !!", + "108": "5540 MHz (DFS) !!", + "112": "5560 MHz (DFS) !!", + "116": "5580 MHz (DFS) !!", + "120": "5600 MHz (DFS) !!", + "124": "5620 MHz (DFS) !!", + "128": "5640 MHz (DFS) !!", + "132": "5660 MHz (DFS) !!", + "136": "5680 MHz (DFS) !!", + "140": "5700 MHz (DFS) !!" + } + if (!(ch in chlist)) + return "" + else + return chlist[ch] + } + + function showWifiChannel(ch) { + if (!ch) + return undefined + + return ch + " (" + wifiChannelAlias(ch) + ")" + } + function showClients(d) { if (!d.flags.online) return undefined @@ -180,6 +228,32 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], } } + function showAirtime(band, val) { + if (!val) + return undefined + + return function (el) { + el.appendChild(showBar("airtime" + band.toString(), val)) + } + } + + function showGateway(d) { + var nh + if (dictGet(d.statistics, ["nexthop"])) + nh = dictGet(d.statistics, ["nexthop"]) + if (dictGet(d.statistics, ["gateway_nexthop"])) + nh = dictGet(d.statistics, ["gateway_nexthop"]) + var gw = dictGet(d.statistics, ["gateway"]) + + if (gw && !nh) + return gw + if (gw && nh) + if (gw === nh) + return gw + else + return nh + " -> ... -> " + gw + } + function showPages(d) { var webpages = dictGet(d.nodeinfo, ["pages"]) if (webpages === null) @@ -248,11 +322,15 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], attributeEntry(attributes, "Site", showSite(d, config)) attributeEntry(attributes, "Uptime", showUptime(d)) attributeEntry(attributes, "Teil des Netzes", showFirstseen(d)) + attributeEntry(attributes, "Kanal 2.4 GHz", showWifiChannel(dictGet(d.nodeinfo, ["wireless", "chan2"]))) + attributeEntry(attributes, "Kanal 5 GHz", showWifiChannel(dictGet(d.nodeinfo, ["wireless", "chan5"]))) + attributeEntry(attributes, "Airtime 2.4 GHz", showAirtime(2, dictGet(d.statistics, ["wireless", "airtime2"]))) + attributeEntry(attributes, "Airtime 5 GHz", showAirtime(5, dictGet(d.statistics, ["wireless", "airtime5"]))) attributeEntry(attributes, "Systemlast", showLoad(d)) attributeEntry(attributes, "Arbeitsspeicher", showRAM(d)) attributeEntry(attributes, "IP Adressen", showIPs(d)) attributeEntry(attributes, "Webseite", showPages(d)) - attributeEntry(attributes, "Gewähltes Gateway", dictGet(d.statistics, ["gateway"])) + attributeEntry(attributes, "Gewähltes Gateway", showGateway(d)) attributeEntry(attributes, "Autom. Updates", showAutoupdate(d)) attributeEntry(attributes, "Clients", showClients(d)) From 8435885e5c226836780b90d29e8478af228d98b2 Mon Sep 17 00:00:00 2001 From: Moorviper Date: Mon, 4 Jul 2016 10:57:04 +0200 Subject: [PATCH 43/87] Router pics (#37) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add a padding to sidebar for better use on mobile devices * allow other things as text in attributeEntry Now it is possible to use pictures and other stuff in this function * Show Router-Pic with double fallback 3 Möglichkeiten 1. in config wird externe Quelle angegeben 2. wenn nicht wird in ./nodes/ geseucht 3. ansonsten Knotenname + Knotenname in erster Zeile extern via: cdn "hwImg": [ { "thumbnail": "https://cdn.rawgit.com/Moorviper/meshviewer_hwpics/master/nodes/{MODELHASH}.svg", "caption": "Knoten {MODELHASH}" } ] aktueller nicht cdn: "hwImg": [ { "thumbnail": "https://rawgit.com/Moorviper/meshviewer_hwpics/master/nodes/{MODELHASH}.svg", "caption": "Knoten {MODELHASH}" } ] --- helper.js | 7 ++++- lib/infobox/node.js | 71 +++++++++++++++++++++++++++++++++++++++++++-- scss/_sidebar.scss | 40 +++++++++++++++++++++++++ scss/main.scss | 38 ++++++++++++++++++++++++ 4 files changed, 152 insertions(+), 4 deletions(-) diff --git a/helper.js b/helper.js index 93acf69..beb23c4 100644 --- a/helper.js +++ b/helper.js @@ -130,7 +130,12 @@ function attributeEntry(el, label, value) { var tr = document.createElement("tr") var th = document.createElement("th") - th.textContent = label + if (typeof label === "string") + th.textContent = label + + else + th.appendChild(label) + tr.appendChild(th) var td = document.createElement("td") diff --git a/lib/infobox/node.js b/lib/infobox/node.js index 3b7dd6e..b5f0110 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -293,6 +293,40 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], return au.enabled ? "aktiviert (" + au.branch + ")" : "deaktiviert" } + function showNodeImg(o, model) { + if (!model) + return undefined + + var content, caption + var modelhash = model.split("").reduce(function(a, b) { + a = ((a << 5) - a) + b.charCodeAt(0) + return a & a + }, 0) + + if (o.thumbnail) { + content = document.createElement("img") + content.id = "routerpicture" + content.classList.add("nodeImg") + content.src = o.thumbnail.replace("{MODELHASH}", modelhash) + content.onerror = function() { + console.log("Router-Bild nicht vorhanden !!! create an issue @ https://github.com/Moorviper/Freifunk-Router-Anleitungen/issues") + document.getElementById("routerpicdiv").outerHTML = "Knotenname" + } + } + + if (o.caption) { + caption = o.caption.replace("{MODELHASH}", modelhash) + + if (!content) + content = document.createTextNode(caption) + } + + var p = document.createElement("p") + p.appendChild(content) + + return content +} + function showStatImg(o, d) { var subst = {} subst["{NODE_ID}"] = d.nodeinfo.node_id ? d.nodeinfo.node_id : "unknown" @@ -301,13 +335,44 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], } return function(config, el, router, d) { - var h2 = document.createElement("h2") - h2.textContent = d.nodeinfo.hostname - el.appendChild(h2) + var top = document.createElement("div") + top.id = "routerpicdiv" + try { + if (config.hwImg) + config.hwImg.forEach(function(hwImg) { + try { + top.appendChild(showNodeImg(hwImg, d.nodeinfo.hardware.model)) + } + catch (err) { + console.log(err.message) + } + }) + + else + { + var localpic = [] // create fallback-config-data + localpic.push({ + thumbnail: "./nodes/{MODELHASH}.svg", + caption: "Knoten {MODELHASH}" + }) + localpic.forEach(function(localpic) { + try { + top.appendChild(showNodeImg(localpic, d.nodeinfo.hardware.model)) + } + catch (err) { + console.log(err.message) + } + }) + } + } + catch (err) { + console.log(err.message) + } var attributes = document.createElement("table") attributes.classList.add("attributes") + attributeEntry(attributes, top, d.nodeinfo.hostname) attributeEntry(attributes, "Status", showStatus(d)) attributeEntry(attributes, "Gateway", d.flags.gateway ? "ja" : null) attributeEntry(attributes, "Koordinaten", showGeoURI(d)) diff --git a/scss/_sidebar.scss b/scss/_sidebar.scss index e69de29..062d689 100644 --- a/scss/_sidebar.scss +++ b/scss/_sidebar.scss @@ -0,0 +1,40 @@ +.nodeheader { + width: 90%; + position: relative; + z-index: 2; +} + +.nodeheader img { + width: 30%; + max-height: 180px; + margin: auto; + text-align: center; + max-width: 128px; + display: block; + z-index: 2; +} +.nodeheader img .none{ + display: none; +} + +.nodeheader span { + background-color: silver; + background-color: hsla(0, 0%, 100%, 0.5); + position: absolute; + bottom: 0; + width: 100%; + line-height: 1.5em; + text-align: center; + color: black; + font-weight: bold; + font-size: large; + z-index: 2; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.limit { + min-height: 1px; + max-height: 1px; +} diff --git a/scss/main.scss b/scss/main.scss index e290144..de63995 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -101,6 +101,11 @@ table th.sort-up:after { content: '\f104'; } +table.attributes { + top: 1px; + display: block; +} + table.attributes th { text-align: left; font-weight: bold; @@ -116,11 +121,44 @@ table.attributes td { line-height: 1.41em; } +table.attributes tr:first-child { + max-height: 128px; + max-width: 128px; + min-width: 128px; + min-height: 128px; + /*height: 128px;*/ + /*background-color: green;*/ +} + +table.attributes tr:first-child td{ + font-weight: bold; + /*background-color: red;*/ + font-size: large; + vertical-align:bottom; +} + +table.attributes tr:first-child th{ + font-weight: bold; + /*background-color: red;*/ + font-size: large; + vertical-align:bottom; +} + +.nodenamesidebar { + position: relative; + font-weight: bold; + /*background-color: red;*/ + font-size: large; + vertical-align:bottom; + bottom: 0px; +} + .sidebar { .infobox, .container { @include shadow(2); background: rgba(255, 255, 255, 0.97); border-radius: 2px; + padding-bottom: 30px; } .container.hidden { From 1b332508a073bc942ba2257c6316b7cd3e991093 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Mon, 4 Jul 2016 10:58:26 +0200 Subject: [PATCH 44/87] Shorten device name in sidebar stats (#46) This way, version codes on TP-Link devices and processor names are visible --- lib/proportions.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/proportions.js b/lib/proportions.js index f1bbb7d..f851c49 100644 --- a/lib/proportions.js +++ b/lib/proportions.js @@ -128,7 +128,13 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc return d ? "online" : "offline" }) var fwDict = count(nodes, ["nodeinfo", "software", "firmware", "release"]) - var hwDict = count(nodes, ["nodeinfo", "hardware", "model"]) + var hwDict = count(nodes, ["nodeinfo", "hardware", "model"], function (d) { + if (d) { + d = d.replace(/\(r\)|\(tm\)/gi, "").replace(/AMD |Intel |TP-Link | CPU| Processor/g, "") + if (d.indexOf("@") > 0) d = d.substring(0, d.indexOf("@")) + } + return d + }) var geoDict = count(nodes, ["nodeinfo", "location"], function (d) { return d && d.longitude && d.latitude ? "ja" : "nein" }) From 2844a203d58b99644c04843a48060f5e9b59fb91 Mon Sep 17 00:00:00 2001 From: eberhab Date: Mon, 4 Jul 2016 11:00:43 +0200 Subject: [PATCH 45/87] iframe width relates to sidebar width (#44) --- helper.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper.js b/helper.js index beb23c4..5343980 100644 --- a/helper.js +++ b/helper.js @@ -154,7 +154,7 @@ function attributeEntry(el, label, value) { function createIframe(opt, width, height) { el = document.createElement("iframe") - width = typeof width !== 'undefined' ? width : '525px' + width = typeof width !== 'undefined' ? width : '100%' height = typeof height !== 'undefined' ? height : '350px' if (opt.src) From 760cca6806a2d1b236fea490e5ef4aa85c3e6aff Mon Sep 17 00:00:00 2001 From: Marvin W Date: Mon, 4 Jul 2016 11:29:16 +0200 Subject: [PATCH 46/87] Properly handle link types (#47) * Properly handle link types * fixup! Properly handle link types --- lib/forcegraph.js | 14 +++++++------- lib/main.js | 25 ++++++++++++++++++------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/lib/forcegraph.js b/lib/forcegraph.js index 7d96ce3..3b5db8e 100644 --- a/lib/forcegraph.js +++ b/lib/forcegraph.js @@ -214,7 +214,7 @@ define(["d3"], function (d3) { function drawLabel(d) { var neighbours = d.neighbours.filter(function (d) { - return d.link.o.type !== "fastd" && d.link.o.type !== "L2TP" + return !d.link.o.isVPN }) var sum = neighbours.reduce(function (a, b) { @@ -332,8 +332,8 @@ define(["d3"], function (d3) { ctx.moveTo(d.source.x + dx * nodeRadius, d.source.y + dy * nodeRadius) ctx.lineTo(d.target.x - dx * nodeRadius, d.target.y - dy * nodeRadius) ctx.strokeStyle = d.o.type === "Kabel" ? cableColor : d.color - ctx.globalAlpha = d.o.type === "fastd" || d.o.type === "L2TP" ? 0.1 : 0.8 - ctx.lineWidth = d.o.type === "fastd" || d.o.type === "L2TP" ? 1.5 : 2.5 + ctx.globalAlpha = d.o.isVPN ? 0.1 : 0.8 + ctx.lineWidth = d.o.isVPN ? 1.5 : 2.5 ctx.stroke() }) @@ -523,7 +523,7 @@ define(["d3"], function (d3) { } var links = intLinks.filter(function (d) { - return d.o.type !== "fastd" && d.o.type !== "L2TP" + return !d.o.isVPN }).filter(function (d) { return distanceLink(e, d.source, d.target) < LINE_RADIUS }) @@ -584,13 +584,13 @@ define(["d3"], function (d3) { .charge(-250) .gravity(0.1) .linkDistance(function (d) { - if (d.o.type === "fastd" || d.o.type === "L2TP") + if (d.o.isVPN) return 0 else return LINK_DISTANCE }) .linkStrength(function (d) { - if (d.o.type === "fastd" || d.o.type === "L2TP") + if (d.o.isVPN) return 0 else return Math.max(0.5, 1 / d.o.tq) @@ -644,7 +644,7 @@ define(["d3"], function (d3) { e.source = newNodesDict[d.source.id] e.target = newNodesDict[d.target.id] - if (d.type === "fastd" || d.type === "L2TP") + if (d.isVPN) e.color = "rgba(255, 255, 255, " + (0.6 / d.tq) + ")" else e.color = linkScale(d.tq).hex() diff --git a/lib/main.js b/lib/main.js index 21fabe9..744dfb5 100644 --- a/lib/main.js +++ b/lib/main.js @@ -126,17 +126,28 @@ function (moment, Router, L, GUI, numeral) { }) links.forEach( function (d) { - if (d.type === "tunnel" || d.type === "fastd") + if (d.type === "tunnel") { + d.type = "VPN" + d.isVPN = true + } else if (d.type === "fastd") { d.type = "fastd" - else if (d.type === "l2tp") { + d.isVPN = true + } else if (d.type === "l2tp") { d.type = "L2TP" - d.target.node.flags.uplink = true - } else if (d.type === "wireless") + d.isVPN = true + } else if (d.type === "gre") { + d.type = "GRE" + d.isVPN = true + } else if (d.type === "wireless") { d.type = "Wifi" - else if (d.type === "other") + d.isVPN = false + } else if (d.type === "other") { d.type = "Kabel" - else + d.isVPN = false + } else { d.type = "N/A" + d.isVPN = false + } var unknown = (d.source.node === undefined) if (unknown) { d.target.node.neighbours.push({ id: d.source.id, link: d, incoming: true }) @@ -144,7 +155,7 @@ function (moment, Router, L, GUI, numeral) { } d.source.node.neighbours.push({ node: d.target.node, link: d, incoming: false }) d.target.node.neighbours.push({ node: d.source.node, link: d, incoming: true }) - if (d.type !== "fastd" && d.type !== "L2TP") + if (!d.isVPN) d.source.node.meshlinks = d.source.node.meshlinks ? d.source.node.meshlinks + 1 : 1 }) From 8f7b1e15ce4991f1b38d6d8ecb230f2c5b16d850 Mon Sep 17 00:00:00 2001 From: Milan Paessler Date: Mon, 4 Jul 2016 12:45:19 +0200 Subject: [PATCH 47/87] Revert "Router pics (#37)" This reverts commit 8435885e5c226836780b90d29e8478af228d98b2. --- helper.js | 7 +---- lib/infobox/node.js | 71 ++------------------------------------------- scss/_sidebar.scss | 40 ------------------------- scss/main.scss | 38 ------------------------ 4 files changed, 4 insertions(+), 152 deletions(-) diff --git a/helper.js b/helper.js index 5343980..a3aba8b 100644 --- a/helper.js +++ b/helper.js @@ -130,12 +130,7 @@ function attributeEntry(el, label, value) { var tr = document.createElement("tr") var th = document.createElement("th") - if (typeof label === "string") - th.textContent = label - - else - th.appendChild(label) - + th.textContent = label tr.appendChild(th) var td = document.createElement("td") diff --git a/lib/infobox/node.js b/lib/infobox/node.js index b5f0110..3b7dd6e 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -293,40 +293,6 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], return au.enabled ? "aktiviert (" + au.branch + ")" : "deaktiviert" } - function showNodeImg(o, model) { - if (!model) - return undefined - - var content, caption - var modelhash = model.split("").reduce(function(a, b) { - a = ((a << 5) - a) + b.charCodeAt(0) - return a & a - }, 0) - - if (o.thumbnail) { - content = document.createElement("img") - content.id = "routerpicture" - content.classList.add("nodeImg") - content.src = o.thumbnail.replace("{MODELHASH}", modelhash) - content.onerror = function() { - console.log("Router-Bild nicht vorhanden !!! create an issue @ https://github.com/Moorviper/Freifunk-Router-Anleitungen/issues") - document.getElementById("routerpicdiv").outerHTML = "Knotenname" - } - } - - if (o.caption) { - caption = o.caption.replace("{MODELHASH}", modelhash) - - if (!content) - content = document.createTextNode(caption) - } - - var p = document.createElement("p") - p.appendChild(content) - - return content -} - function showStatImg(o, d) { var subst = {} subst["{NODE_ID}"] = d.nodeinfo.node_id ? d.nodeinfo.node_id : "unknown" @@ -335,44 +301,13 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], } return function(config, el, router, d) { - var top = document.createElement("div") - top.id = "routerpicdiv" - try { - if (config.hwImg) - config.hwImg.forEach(function(hwImg) { - try { - top.appendChild(showNodeImg(hwImg, d.nodeinfo.hardware.model)) - } - catch (err) { - console.log(err.message) - } - }) - - else - { - var localpic = [] // create fallback-config-data - localpic.push({ - thumbnail: "./nodes/{MODELHASH}.svg", - caption: "Knoten {MODELHASH}" - }) - localpic.forEach(function(localpic) { - try { - top.appendChild(showNodeImg(localpic, d.nodeinfo.hardware.model)) - } - catch (err) { - console.log(err.message) - } - }) - } - } - catch (err) { - console.log(err.message) - } + var h2 = document.createElement("h2") + h2.textContent = d.nodeinfo.hostname + el.appendChild(h2) var attributes = document.createElement("table") attributes.classList.add("attributes") - attributeEntry(attributes, top, d.nodeinfo.hostname) attributeEntry(attributes, "Status", showStatus(d)) attributeEntry(attributes, "Gateway", d.flags.gateway ? "ja" : null) attributeEntry(attributes, "Koordinaten", showGeoURI(d)) diff --git a/scss/_sidebar.scss b/scss/_sidebar.scss index 062d689..e69de29 100644 --- a/scss/_sidebar.scss +++ b/scss/_sidebar.scss @@ -1,40 +0,0 @@ -.nodeheader { - width: 90%; - position: relative; - z-index: 2; -} - -.nodeheader img { - width: 30%; - max-height: 180px; - margin: auto; - text-align: center; - max-width: 128px; - display: block; - z-index: 2; -} -.nodeheader img .none{ - display: none; -} - -.nodeheader span { - background-color: silver; - background-color: hsla(0, 0%, 100%, 0.5); - position: absolute; - bottom: 0; - width: 100%; - line-height: 1.5em; - text-align: center; - color: black; - font-weight: bold; - font-size: large; - z-index: 2; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.limit { - min-height: 1px; - max-height: 1px; -} diff --git a/scss/main.scss b/scss/main.scss index de63995..e290144 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -101,11 +101,6 @@ table th.sort-up:after { content: '\f104'; } -table.attributes { - top: 1px; - display: block; -} - table.attributes th { text-align: left; font-weight: bold; @@ -121,44 +116,11 @@ table.attributes td { line-height: 1.41em; } -table.attributes tr:first-child { - max-height: 128px; - max-width: 128px; - min-width: 128px; - min-height: 128px; - /*height: 128px;*/ - /*background-color: green;*/ -} - -table.attributes tr:first-child td{ - font-weight: bold; - /*background-color: red;*/ - font-size: large; - vertical-align:bottom; -} - -table.attributes tr:first-child th{ - font-weight: bold; - /*background-color: red;*/ - font-size: large; - vertical-align:bottom; -} - -.nodenamesidebar { - position: relative; - font-weight: bold; - /*background-color: red;*/ - font-size: large; - vertical-align:bottom; - bottom: 0px; -} - .sidebar { .infobox, .container { @include shadow(2); background: rgba(255, 255, 255, 0.97); border-radius: 2px; - padding-bottom: 30px; } .container.hidden { From cfd778dadb30500977fb4706c1889a9b2fbbac56 Mon Sep 17 00:00:00 2001 From: codedust Date: Sat, 23 Jul 2016 16:49:35 +0200 Subject: [PATCH 48/87] Fix number of decimal places being displayed in the CPU load bar (#54) --- lib/infobox/node.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/infobox/node.js b/lib/infobox/node.js index 3b7dd6e..668019e 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -204,7 +204,7 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], } var label = document.createElement("label") - label.textContent = (v) + label.textContent = +(Math.round(v + "e+2") + "e-2") span.appendChild(label) return span From 07d5e3f636615758d64d3a3ffa202de5298ac0aa Mon Sep 17 00:00:00 2001 From: Daniel Krah Date: Sat, 23 Jul 2016 16:52:49 +0200 Subject: [PATCH 49/87] check IPv4/IPv6 (#56) --- lib/infobox/node.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/infobox/node.js b/lib/infobox/node.js index 668019e..3130365 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -160,7 +160,10 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], if (link) { var a = document.createElement("a") - a.href = "http://[" + ip + "]/" + if (ip.includes(".")) + a.href = "http://" + ip + "/" + else + a.href = "http://[" + ip + "]/" a.textContent = ip el.appendChild(a) } else From 46de672dc9d8f7810bd69ee91454a5daa18fa213 Mon Sep 17 00:00:00 2001 From: Milan Paessler Date: Sat, 23 Jul 2016 16:33:49 +0000 Subject: [PATCH 50/87] main: support for ffmap-backend vpn link notation --- lib/main.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/main.js b/lib/main.js index 744dfb5..67787e5 100644 --- a/lib/main.js +++ b/lib/main.js @@ -126,7 +126,7 @@ function (moment, Router, L, GUI, numeral) { }) links.forEach( function (d) { - if (d.type === "tunnel") { + if (d.type === "tunnel" || d.vpn) { d.type = "VPN" d.isVPN = true } else if (d.type === "fastd") { From bf2e858c2446b3aed5895d726a1d6f27dd6790af Mon Sep 17 00:00:00 2001 From: Marvin W Date: Mon, 1 Aug 2016 23:25:29 +0200 Subject: [PATCH 51/87] Make sure hopglass does not break when server reports nodes without hostname. (#58) --- lib/nodelist.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/nodelist.js b/lib/nodelist.js index efcaf80..ee1409c 100644 --- a/lib/nodelist.js +++ b/lib/nodelist.js @@ -21,7 +21,11 @@ define(["sorttable", "virtual-dom", "numeral"], function (SortTable, V, numeral) var headings = [{ name: "Knoten", sort: function (a, b) { - return a.nodeinfo.hostname.localeCompare(b.nodeinfo.hostname) + var aname = typeof a.nodeinfo.hostname === "string" ? a.nodeinfo.hostname : a.nodeinfo.node_id + var bname = typeof b.nodeinfo.hostname === "string" ? b.nodeinfo.hostname : b.nodeinfo.node_id + if (typeof aname === "string" && typeof bname === "string") + return aname.localeCompare(bname) + return typeof aname === "string" ? 1 : typeof bname === "string" ? -1 : 0 }, reverse: false }, From cb065d8d07accbd502aa74a9d54f392afd931d61 Mon Sep 17 00:00:00 2001 From: Marvin W Date: Fri, 5 Aug 2016 19:47:25 +0200 Subject: [PATCH 52/87] Fully resolve gateway names in hopglass (#57) Depends on hopglass/hopglass-server#56 --- lib/infobox/node.js | 42 ++++++++++++++++++++++++++---------------- lib/main.js | 9 +++++++++ lib/meshstats.js | 2 +- lib/proportions.js | 18 ++++++++++++------ 4 files changed, 48 insertions(+), 23 deletions(-) diff --git a/lib/infobox/node.js b/lib/infobox/node.js index 3130365..0304d5f 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -240,7 +240,20 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], } } - function showGateway(d) { + function createLink(target, router) { + var link = document.createElement("a") + if (!target) return link + var unknown = !(target.node) + link.classList.add("hostname") + link.textContent = unknown ? (target.id ? target.id : target) : target.node.nodeinfo.hostname + if (!unknown) { + link.href = "#" + link.onclick = router.node(target.node) + } + return link + } + + function showGateway(d, router) { var nh if (dictGet(d.statistics, ["nexthop"])) nh = dictGet(d.statistics, ["nexthop"]) @@ -248,13 +261,16 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], nh = dictGet(d.statistics, ["gateway_nexthop"]) var gw = dictGet(d.statistics, ["gateway"]) - if (gw && !nh) - return gw - if (gw && nh) - if (gw === nh) - return gw - else - return nh + " -> ... -> " + gw + if (!gw) return null + return function (el) { + if (nh) { + el.appendChild(createLink(nh, router)) + if (gw !== nh) + el.appendChild(document.createTextNode(" -> ... -> ")) + } + if (gw !== nh) + el.appendChild(createLink(gw, router)) + } } function showPages(d) { @@ -333,7 +349,7 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], attributeEntry(attributes, "Arbeitsspeicher", showRAM(d)) attributeEntry(attributes, "IP Adressen", showIPs(d)) attributeEntry(attributes, "Webseite", showPages(d)) - attributeEntry(attributes, "Gewähltes Gateway", showGateway(d)) + attributeEntry(attributes, "Gewähltes Gateway", showGateway(d, router)) attributeEntry(attributes, "Autom. Updates", showAutoupdate(d)) attributeEntry(attributes, "Clients", showClients(d)) @@ -392,13 +408,7 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], tr.appendChild(td1) var td2 = document.createElement("td") - var a1 = document.createElement("a") - a1.classList.add("hostname") - a1.textContent = unknown ? d.id : d.node.nodeinfo.hostname - if (!unknown) - a1.href = "#" - a1.onclick = router.node(d.node) - td2.appendChild(a1) + td2.appendChild(createLink(d, router)) if (!unknown && has_location(d.node)) { var span = document.createElement("span") diff --git a/lib/main.js b/lib/main.js index 67787e5..79dcdd5 100644 --- a/lib/main.js +++ b/lib/main.js @@ -123,6 +123,15 @@ function (moment, Router, L, GUI, numeral) { nodes.forEach( function (d) { d.neighbours = [] + if (d.statistics) { + /*eslint camelcase:0*/ + if ("gateway" in d.statistics && d.statistics.gateway in graphnodes) + d.statistics.gateway = {"node": graphnodes[d.statistics.gateway], "id": d.statistics.gateway} + if ("nexthop" in d.statistics && d.statistics.nexthop in graphnodes) + d.statistics.nexthop = {"node": graphnodes[d.statistics.nexthop], "id": d.statistics.nexthop} + if ("gateway_nexthop" in d.statistics && d.statistics.gateway_nexthop in graphnodes) + d.statistics.gateway_nexthop = {"node": graphnodes[d.statistics.gateway_nexthop], "id": d.statistics.gateway_nexthop} + } }) links.forEach( function (d) { diff --git a/lib/meshstats.js b/lib/meshstats.js index b10f7c4..9d50044 100644 --- a/lib/meshstats.js +++ b/lib/meshstats.js @@ -13,7 +13,7 @@ define(function () { return d.statistics.clients ? d.statistics.clients : 0 })) var totalGateways = sum(Array.from(new Set(d.nodes.all.filter(online).map( function(d) { - return d.statistics.gateway + return ("gateway" in d.statistics && d.statistics.gateway.id) ? d.statistics.gateway.id : d.statistics.gateway }).concat(d.nodes.all.filter( function (d) { return d.flags.gateway })))).map(function(d) { diff --git a/lib/proportions.js b/lib/proportions.js index f851c49..f5b0b26 100644 --- a/lib/proportions.js +++ b/lib/proportions.js @@ -156,8 +156,11 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc if (d === null) return null - if (d in nodeDict) - return nodeDict[d].nodeinfo.hostname + if (d.node) + return d.node.nodeinfo.hostname + + if (d.id) + return d.id return d }) @@ -166,8 +169,11 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc if (d === null) return null - if (d in nodeDict) - return nodeDict[d].nodeinfo.hostname + if (d.node) + return d.node.nodeinfo.hostname + + if (d.id) + return d.id return d }) @@ -188,8 +194,8 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc fillTable("Koordinaten", geoTable, geoDict.sort(function (a, b) { return b[1] - a[1] })) fillTable("Uplink", uplinkTable, uplinkDict.sort(function (a, b) { return b[1] - a[1] })) fillTable("Autom. Updates", autoTable, autoDict.sort(function (a, b) { return b[1] - a[1] })) - fillTable("Nodes an Gateway", gwNodesTable, gwNodesDict.sort(function (a, b) { return b[1] - a[1] })) - fillTable("Clients an Gateway", gwClientsTable, gwClientsDict.sort(function (a, b) { return b[1] - a[1] })) + fillTable("Gateway", gwNodesTable, gwNodesDict.sort(function (a, b) { return b[1] - a[1] })) + fillTable("Gateway", gwClientsTable, gwClientsDict.sort(function (a, b) { return b[1] - a[1] })) fillTable("Site", siteTable, siteDict.sort(function (a, b) { return b[1] - a[1] })) } From 00a8e5117dd50dbcfedc6004a9cf5859a7af786a Mon Sep 17 00:00:00 2001 From: Daniel Krah Date: Sat, 3 Sep 2016 01:31:26 +0200 Subject: [PATCH 53/87] fix es6-shim/es6-shim.map (#62) --- tasks/build.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tasks/build.js b/tasks/build.js index 5a8c918..d76ccfc 100644 --- a/tasks/build.js +++ b/tasks/build.js @@ -19,7 +19,8 @@ module.exports = function(grunt) { dest: "build/" }, vendorjs: { - src: [ "es6-shim/es6-shim.min.js" ], + src: ["es6-shim/es6-shim.min.js", + "es6-shim/es6-shim.map"], expand: true, cwd: "bower_components/", dest: "build/vendor/" From 808b8c1986ae943ae6f1152d165786ede146d532 Mon Sep 17 00:00:00 2001 From: Daniel Krah Date: Sat, 5 Nov 2016 21:23:27 +0100 Subject: [PATCH 54/87] Count Clients in a Mesh (#61) This functions count all clients in a meshcloud. It count over wireless and cable links not over VPN links via l2tp or fastd. --- lib/infobox/node.js | 58 ++++++++++++++++++++++++++++++++++++++++++++- scss/main.scss | 7 ++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/lib/infobox/node.js b/lib/infobox/node.js index 0304d5f..4310548 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -133,14 +133,70 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], if (!d.flags.online) return undefined + var meshclients = getMeshClients(d) + resetMeshClients(d) + var before = " (" + var after = " in der lokalen Wolke)" return function (el) { el.appendChild(document.createTextNode(d.statistics.clients > 0 ? d.statistics.clients : "keine")) + el.appendChild(document.createTextNode(before)) + el.appendChild(document.createTextNode(meshclients > 0 ? meshclients : "keine")) + el.appendChild(document.createTextNode(after)) el.appendChild(document.createElement("br")) var span = document.createElement("span") span.classList.add("clients") span.textContent = " ".repeat(d.statistics.clients) el.appendChild(span) + + var spanmesh = document.createElement("span") + spanmesh.classList.add("clientsMesh") + spanmesh.textContent = " ".repeat(meshclients - d.statistics.clients) + el.appendChild(spanmesh) + } + } + + function getMeshClients(node) { + var meshclients = node.statistics.clients + + if (!node) + return 0 + + if (node.parsed) + return 0 + + node.parsed = 1 + node.neighbours.forEach(function (neighbour) { + if (!neighbour.link.isVPN && neighbour.node) + meshclients += getMeshClients(neighbour.node) + }) + + return meshclients + } + + function resetMeshClients(node) { + if (!node.parsed) + return + + node.parsed = 0 + + node.neighbours.forEach(function (neighbour) { + if (!neighbour.link.isVPN && neighbour.node) + resetMeshClients(neighbour.node) + }) + + return + } + + function showMeshClients(d) { + if (!d.flags.online) + return undefined + + var meshclients = getMeshClients(d) + resetMeshClients(d) + return function (el) { + el.appendChild(document.createTextNode(meshclients > 0 ? meshclients : "keine")) + el.appendChild(document.createElement("br")) } } @@ -351,7 +407,7 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], attributeEntry(attributes, "Webseite", showPages(d)) attributeEntry(attributes, "Gewähltes Gateway", showGateway(d, router)) attributeEntry(attributes, "Autom. Updates", showAutoupdate(d)) - attributeEntry(attributes, "Clients", showClients(d)) + attributeEntry(attributes, "Clients", showClients(d), showMeshClients(d)) el.appendChild(attributes) diff --git a/scss/main.scss b/scss/main.scss index e290144..4a7170e 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -143,6 +143,13 @@ table.attributes td { white-space: normal; } +.infobox .clientsMesh { + font-family: "ionicons"; + color: #dbdbdb; + word-spacing: -0.2em; + white-space: normal; +} + .infobox { position: relative; padding: 0.25em 0; From 5599be5cd6ee7d5ae3520f53bf271d7dab39560f Mon Sep 17 00:00:00 2001 From: Milan Pssler Date: Sat, 5 Nov 2016 21:44:57 +0100 Subject: [PATCH 55/87] re-add uplink detection, this time generic fixes l2tp uplink detection --- lib/main.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/main.js b/lib/main.js index 79dcdd5..eac2a0f 100644 --- a/lib/main.js +++ b/lib/main.js @@ -157,6 +157,10 @@ function (moment, Router, L, GUI, numeral) { d.type = "N/A" d.isVPN = false } + + if (d.isVPN && d.target.node) + d.target.node.flags.uplink = true + var unknown = (d.source.node === undefined) if (unknown) { d.target.node.neighbours.push({ id: d.source.id, link: d, incoming: true }) From e9711c6efc0da44fbc55022add67cb0667ff3c2a Mon Sep 17 00:00:00 2001 From: Milan Pssler Date: Sat, 5 Nov 2016 23:01:25 +0100 Subject: [PATCH 56/87] new example config --- config.json.example | 36 +++++++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/config.json.example b/config.json.example index 933ba02..ded5050 100644 --- a/config.json.example +++ b/config.json.example @@ -1,8 +1,8 @@ { - "dataPath": "https://map.luebeck.freifunk.net/data/", - "siteName": "Freifunk Lübeck", + "dataPath": "https://map.ffdus.de/data/", + "siteName": "Freifunk Flingern", "mapSigmaScale": 0.5, - "showContact": true, + "showContact": true, "maxAge": 14, "mapLayers": [ { @@ -12,10 +12,32 @@ "name": "Stamen.TonerLite" } ], + "nodeInfos": [ + { "href": "https://map.eulenfunk.de/stats/dashboard/db/node-byid?var-nodeid={NODE_ID}", + "thumbnail": "https://map.eulenfunk.de/stats/render/dashboard-solo/db/node-byid?panelId=1&theme=light&width=600&height=300&var-nodeid={NODE_ID}" + }, + { "href": "https://map.eulenfunk.de/stats/dashboard/db/node-byid?var-nodeid={NODE_ID}", + "thumbnail": "https://map.eulenfunk.de/stats/render/dashboard-solo/db/node-byid?panelId=2&theme=light&width=600&height=500&var-nodeid={NODE_ID}" + }, + { "href": "https://map.eulenfunk.de/stats/dashboard/db/node-byid?var-nodeid={NODE_ID}", + "thumbnail": "https://map.eulenfunk.de/stats/render/dashboard-solo/db/node-byid?panelId=3&theme=light&width=600&height=200&var-nodeid={NODE_ID}" + } + ], + "globalInfos": [ + { "href": "https://map.eulenfunk.de/stats/dashboard/db/global?var-job=dus", + "thumbnail": "https://map.eulenfunk.de/stats/render/dashboard-solo/db/global?panelId=1&&theme=light&width=800&height=600&var-job=dus" + }, + { "href": "https://map.eulenfunk.de/stats/dashboard/db/global?var-job=dus", + "thumbnail": "https://map.eulenfunk.de/stats/render/dashboard-solo/db/global?panelId=8&&theme=light&width=800&height=600&var-job=dus" + } + ], + "linkInfos": [ + { "href": "https://map.eulenfunk.de/stats/dashboard/db/links?var-source={SOURCE}&var-target={TARGET}", + "thumbnail": "https://map.eulenfunk.de/stats/render/dashboard-solo/db/links?panelId=1&&theme=light&width=800&height=600&var-source={SOURCE}&var-target={TARGET}" + } + ], "siteNames": [ - { "site": "ffhl", "name": "Lübeck" }, - { "site": "ffeh", "name": "Entenhausen" }, - { "site": "ffgt", "name": "Gothamcity" }, - { "site": "ffal", "name": "Atlantis" } + { "site": "dus", "name": "Flingern" } ] } + From 84aee4822931e4480f19219eb13551731af6e6f7 Mon Sep 17 00:00:00 2001 From: Moorviper Date: Mon, 4 Jul 2016 10:57:04 +0200 Subject: [PATCH 57/87] Router pics (#37) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add a padding to sidebar for better use on mobile devices * allow other things as text in attributeEntry Now it is possible to use pictures and other stuff in this function * Show Router-Pic with double fallback 3 Möglichkeiten 1. in config wird externe Quelle angegeben 2. wenn nicht wird in ./nodes/ geseucht 3. ansonsten Knotenname + Knotenname in erster Zeile extern via: cdn "hwImg": [ { "thumbnail": "https://cdn.rawgit.com/Moorviper/meshviewer_hwpics/master/nodes/{MODELHASH}.svg", "caption": "Knoten {MODELHASH}" } ] aktueller nicht cdn: "hwImg": [ { "thumbnail": "https://rawgit.com/Moorviper/meshviewer_hwpics/master/nodes/{MODELHASH}.svg", "caption": "Knoten {MODELHASH}" } ] --- helper.js | 7 ++++- lib/infobox/node.js | 71 +++++++++++++++++++++++++++++++++++++++++++-- scss/_sidebar.scss | 40 +++++++++++++++++++++++++ scss/main.scss | 38 ++++++++++++++++++++++++ 4 files changed, 152 insertions(+), 4 deletions(-) diff --git a/helper.js b/helper.js index a3aba8b..5343980 100644 --- a/helper.js +++ b/helper.js @@ -130,7 +130,12 @@ function attributeEntry(el, label, value) { var tr = document.createElement("tr") var th = document.createElement("th") - th.textContent = label + if (typeof label === "string") + th.textContent = label + + else + th.appendChild(label) + tr.appendChild(th) var td = document.createElement("td") diff --git a/lib/infobox/node.js b/lib/infobox/node.js index 4310548..9d4daa7 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -368,6 +368,40 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], return au.enabled ? "aktiviert (" + au.branch + ")" : "deaktiviert" } + function showNodeImg(o, model) { + if (!model) + return undefined + + var content, caption + var modelhash = model.split("").reduce(function(a, b) { + a = ((a << 5) - a) + b.charCodeAt(0) + return a & a + }, 0) + + if (o.thumbnail) { + content = document.createElement("img") + content.id = "routerpicture" + content.classList.add("nodeImg") + content.src = o.thumbnail.replace("{MODELHASH}", modelhash) + content.onerror = function() { + console.log("Router-Bild nicht vorhanden !!! create an issue @ https://github.com/Moorviper/Freifunk-Router-Anleitungen/issues") + document.getElementById("routerpicdiv").outerHTML = "Knotenname" + } + } + + if (o.caption) { + caption = o.caption.replace("{MODELHASH}", modelhash) + + if (!content) + content = document.createTextNode(caption) + } + + var p = document.createElement("p") + p.appendChild(content) + + return content +} + function showStatImg(o, d) { var subst = {} subst["{NODE_ID}"] = d.nodeinfo.node_id ? d.nodeinfo.node_id : "unknown" @@ -376,13 +410,44 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], } return function(config, el, router, d) { - var h2 = document.createElement("h2") - h2.textContent = d.nodeinfo.hostname - el.appendChild(h2) + var top = document.createElement("div") + top.id = "routerpicdiv" + try { + if (config.hwImg) + config.hwImg.forEach(function(hwImg) { + try { + top.appendChild(showNodeImg(hwImg, d.nodeinfo.hardware.model)) + } + catch (err) { + console.log(err.message) + } + }) + + else + { + var localpic = [] // create fallback-config-data + localpic.push({ + thumbnail: "./nodes/{MODELHASH}.svg", + caption: "Knoten {MODELHASH}" + }) + localpic.forEach(function(localpic) { + try { + top.appendChild(showNodeImg(localpic, d.nodeinfo.hardware.model)) + } + catch (err) { + console.log(err.message) + } + }) + } + } + catch (err) { + console.log(err.message) + } var attributes = document.createElement("table") attributes.classList.add("attributes") + attributeEntry(attributes, top, d.nodeinfo.hostname) attributeEntry(attributes, "Status", showStatus(d)) attributeEntry(attributes, "Gateway", d.flags.gateway ? "ja" : null) attributeEntry(attributes, "Koordinaten", showGeoURI(d)) diff --git a/scss/_sidebar.scss b/scss/_sidebar.scss index e69de29..062d689 100644 --- a/scss/_sidebar.scss +++ b/scss/_sidebar.scss @@ -0,0 +1,40 @@ +.nodeheader { + width: 90%; + position: relative; + z-index: 2; +} + +.nodeheader img { + width: 30%; + max-height: 180px; + margin: auto; + text-align: center; + max-width: 128px; + display: block; + z-index: 2; +} +.nodeheader img .none{ + display: none; +} + +.nodeheader span { + background-color: silver; + background-color: hsla(0, 0%, 100%, 0.5); + position: absolute; + bottom: 0; + width: 100%; + line-height: 1.5em; + text-align: center; + color: black; + font-weight: bold; + font-size: large; + z-index: 2; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.limit { + min-height: 1px; + max-height: 1px; +} diff --git a/scss/main.scss b/scss/main.scss index 4a7170e..a582582 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -101,6 +101,11 @@ table th.sort-up:after { content: '\f104'; } +table.attributes { + top: 1px; + display: block; +} + table.attributes th { text-align: left; font-weight: bold; @@ -116,11 +121,44 @@ table.attributes td { line-height: 1.41em; } +table.attributes tr:first-child { + max-height: 128px; + max-width: 128px; + min-width: 128px; + min-height: 128px; + /*height: 128px;*/ + /*background-color: green;*/ +} + +table.attributes tr:first-child td{ + font-weight: bold; + /*background-color: red;*/ + font-size: large; + vertical-align:bottom; +} + +table.attributes tr:first-child th{ + font-weight: bold; + /*background-color: red;*/ + font-size: large; + vertical-align:bottom; +} + +.nodenamesidebar { + position: relative; + font-weight: bold; + /*background-color: red;*/ + font-size: large; + vertical-align:bottom; + bottom: 0px; +} + .sidebar { .infobox, .container { @include shadow(2); background: rgba(255, 255, 255, 0.97); border-radius: 2px; + padding-bottom: 30px; } .container.hidden { From 1641bc24370723846931eb5f1684a866b5fcbf6a Mon Sep 17 00:00:00 2001 From: Milan Pssler Date: Sun, 6 Nov 2016 00:11:49 +0100 Subject: [PATCH 58/87] router pics hopglass changes - don't use display block on the table, instead make the close button position absolute - show the old style heading when no source is defined - clean up the indention and some small things --- config.json.example | 5 ++++ helper.js | 5 ++-- lib/infobox/node.js | 73 +++++++++++++++++---------------------------- scss/_sidebar.scss | 58 +++++++++++++++++------------------ scss/main.scss | 14 ++++----- 5 files changed, 68 insertions(+), 87 deletions(-) diff --git a/config.json.example b/config.json.example index ded5050..b1879f0 100644 --- a/config.json.example +++ b/config.json.example @@ -38,6 +38,11 @@ ], "siteNames": [ { "site": "dus", "name": "Flingern" } + ], + "hwImg": [ + { "thumbnail": "https://cdn.rawgit.com/Moorviper/meshviewer_hwpics/master/nodes/{MODELHASH}.svg", + "caption": "Knoten {MODELHASH}" + } ] } diff --git a/helper.js b/helper.js index 5343980..6e00702 100644 --- a/helper.js +++ b/helper.js @@ -132,9 +132,10 @@ function attributeEntry(el, label, value) { var th = document.createElement("th") if (typeof label === "string") th.textContent = label - - else + else { th.appendChild(label) + tr.className = "routerpic" + } tr.appendChild(th) diff --git a/lib/infobox/node.js b/lib/infobox/node.js index 9d4daa7..d7a5acd 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -378,15 +378,12 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], return a & a }, 0) - if (o.thumbnail) { - content = document.createElement("img") - content.id = "routerpicture" - content.classList.add("nodeImg") - content.src = o.thumbnail.replace("{MODELHASH}", modelhash) - content.onerror = function() { - console.log("Router-Bild nicht vorhanden !!! create an issue @ https://github.com/Moorviper/Freifunk-Router-Anleitungen/issues") - document.getElementById("routerpicdiv").outerHTML = "Knotenname" - } + content = document.createElement("img") + content.id = "routerpicture" + content.classList.add("nodeImg") + content.src = o.thumbnail.replace("{MODELHASH}", modelhash) + content.onerror = function() { + document.getElementById("routerpicdiv").outerHTML = "Knotenname" } if (o.caption) { @@ -400,7 +397,7 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], p.appendChild(content) return content -} + } function showStatImg(o, d) { var subst = {} @@ -410,44 +407,30 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], } return function(config, el, router, d) { - var top = document.createElement("div") - top.id = "routerpicdiv" - try { - if (config.hwImg) - config.hwImg.forEach(function(hwImg) { - try { - top.appendChild(showNodeImg(hwImg, d.nodeinfo.hardware.model)) - } - catch (err) { - console.log(err.message) - } - }) - - else - { - var localpic = [] // create fallback-config-data - localpic.push({ - thumbnail: "./nodes/{MODELHASH}.svg", - caption: "Knoten {MODELHASH}" - }) - localpic.forEach(function(localpic) { - try { - top.appendChild(showNodeImg(localpic, d.nodeinfo.hardware.model)) - } - catch (err) { - console.log(err.message) - } - }) - } - } - catch (err) { - console.log(err.message) - } - var attributes = document.createElement("table") attributes.classList.add("attributes") - attributeEntry(attributes, top, d.nodeinfo.hostname) + if (config.hwImg) { + var top = document.createElement("div") + top.id = "routerpicdiv" + try { + config.hwImg.forEach(function(hwImg) { + try { + top.appendChild(showNodeImg(hwImg, d.nodeinfo.hardware.model)) + } catch (err) { + console.log(err.message) + } + }) + } catch (err) { + console.log(err.message) + } + attributeEntry(attributes, top, d.nodeinfo.hostname) + } else { + var h2 = document.createElement("h2") + h2.textContent = d.nodeinfo.hostname + el.appendChild(h2) + } + attributeEntry(attributes, "Status", showStatus(d)) attributeEntry(attributes, "Gateway", d.flags.gateway ? "ja" : null) attributeEntry(attributes, "Koordinaten", showGeoURI(d)) diff --git a/scss/_sidebar.scss b/scss/_sidebar.scss index 062d689..0d3e497 100644 --- a/scss/_sidebar.scss +++ b/scss/_sidebar.scss @@ -1,40 +1,36 @@ .nodeheader { - width: 90%; - position: relative; - z-index: 2; + width: 90%; + position: relative; + z-index: 2; } .nodeheader img { - width: 30%; - max-height: 180px; - margin: auto; - text-align: center; - max-width: 128px; - display: block; - z-index: 2; + width: 30%; + max-height: 180px; + margin: auto; + text-align: center; + max-width: 128px; + display: block; + z-index: 2; } -.nodeheader img .none{ - display: none; + +.nodeheader img .none { + display: none; } .nodeheader span { - background-color: silver; - background-color: hsla(0, 0%, 100%, 0.5); - position: absolute; - bottom: 0; - width: 100%; - line-height: 1.5em; - text-align: center; - color: black; - font-weight: bold; - font-size: large; - z-index: 2; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.limit { - min-height: 1px; - max-height: 1px; + background-color: silver; + background-color: hsla(0, 0%, 100%, 0.5); + position: absolute; + bottom: 0; + width: 100%; + line-height: 1.5em; + text-align: center; + color: black; + font-weight: bold; + font-size: large; + z-index: 2; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } diff --git a/scss/main.scss b/scss/main.scss index a582582..68cc4eb 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -101,11 +101,6 @@ table th.sort-up:after { content: '\f104'; } -table.attributes { - top: 1px; - display: block; -} - table.attributes th { text-align: left; font-weight: bold; @@ -121,7 +116,7 @@ table.attributes td { line-height: 1.41em; } -table.attributes tr:first-child { +table.attributes tr.routerpic { max-height: 128px; max-width: 128px; min-width: 128px; @@ -130,14 +125,14 @@ table.attributes tr:first-child { /*background-color: green;*/ } -table.attributes tr:first-child td{ +table.attributes tr.routerpic td { font-weight: bold; /*background-color: red;*/ font-size: large; vertical-align:bottom; } -table.attributes tr:first-child th{ +table.attributes tr.routerpic th { font-weight: bold; /*background-color: red;*/ font-size: large; @@ -158,7 +153,6 @@ table.attributes tr:first-child th{ @include shadow(2); background: rgba(255, 255, 255, 0.97); border-radius: 2px; - padding-bottom: 30px; } .container.hidden { @@ -264,6 +258,8 @@ button.close { border-radius: 0; color: rgba(0, 0, 0, 0.5); font-family: "ionicons"; + position: absolute; + right: 0; &:hover { color: #dc0067; From 7eb0675be067e5c97e1e1559c176c80806d0c77a Mon Sep 17 00:00:00 2001 From: Milan Pssler Date: Sun, 6 Nov 2016 17:06:41 +0100 Subject: [PATCH 59/87] fix meshclients for orange nodes --- lib/infobox/node.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/infobox/node.js b/lib/infobox/node.js index d7a5acd..0e7e993 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -157,7 +157,9 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], } function getMeshClients(node) { - var meshclients = node.statistics.clients + var meshclients = 0 + if (node.statistics && !isNaN(node.statistics.clients)) + meshclients = node.statistics.clients if (!node) return 0 From 224240c1c46d0222503f0affafe5e210d032110a Mon Sep 17 00:00:00 2001 From: Milan Pssler Date: Thu, 17 Nov 2016 19:47:56 +0100 Subject: [PATCH 60/87] forcegraph: bidirectional links --- lib/forcegraph.js | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/lib/forcegraph.js b/lib/forcegraph.js index 3b5db8e..4823307 100644 --- a/lib/forcegraph.js +++ b/lib/forcegraph.js @@ -242,7 +242,8 @@ define(["d3"], function (d3) { } function visibleLinks(d) { - return (d.source.x > screenRect.left && d.source.x < screenRect.right && + return (d.o.isVPN || + d.source.x > screenRect.left && d.source.x < screenRect.right && d.source.y > screenRect.top && d.source.y < screenRect.bottom) || (d.target.x > screenRect.left && d.target.x < screenRect.right && d.target.y > screenRect.top && d.target.y < screenRect.bottom) @@ -324,13 +325,16 @@ define(["d3"], function (d3) { links.forEach(function (d) { var dx = d.target.x - d.source.x var dy = d.target.y - d.source.y - var a = Math.sqrt(dx * dx + dy * dy) + var a = Math.sqrt(dx * dx + dy * dy) * 2 dx /= a dy /= a + var distancex = d.target.x - d.source.x - (10 * dx) + var distancey = d.target.y - d.source.y - (10 * dy) + ctx.beginPath() ctx.moveTo(d.source.x + dx * nodeRadius, d.source.y + dy * nodeRadius) - ctx.lineTo(d.target.x - dx * nodeRadius, d.target.y - dy * nodeRadius) + ctx.lineTo(d.target.x - (distancex / 2) - dx * nodeRadius, d.target.y - (distancey / 2) - dy * nodeRadius) ctx.strokeStyle = d.o.type === "Kabel" ? cableColor : d.color ctx.globalAlpha = d.o.isVPN ? 0.1 : 0.8 ctx.lineWidth = d.o.isVPN ? 1.5 : 2.5 @@ -470,32 +474,34 @@ define(["d3"], function (d3) { requestAnimationFrame(redraw) } - function distance(a, b) { - return Math.pow(a.x - b.x, 2) + Math.pow(a.y - b.y, 2) + function distance(ax, ay, bx, by) { + return Math.pow(ax - bx, 2) + Math.pow(ay - by, 2) } function distancePoint(a, b) { - return Math.sqrt(distance(a, b)) + return Math.sqrt(distance(a.x, a.y, b.x, b.y)) } function distanceLink(p, a, b) { /* http://stackoverflow.com/questions/849211 */ - var l2 = distance(a, b) + var bx = b.x - ((b.x - a.x) / 2) + var by = b.y - ((b.y - a.y) / 2) + + var l2 = distance(a.x, a.y, bx, by) if (l2 === 0) - return distance(p, a) + return distance(p.x, p.y, a.x, a.y) - var t = ((p.x - a.x) * (b.x - a.x) + (p.y - a.y) * (b.y - a.y)) / l2 + var t = ((p.x - a.x) * (bx - a.x) + (p.y - a.y) * (by - a.y)) / l2 if (t < 0) - return distance(p, a) + return distance(p.x, p.y, a.x, a.y) if (t > 1) - return distance(p, b) + return distance(p.x, p.y, bx, by) - return Math.sqrt(distance(p, { x: a.x + t * (b.x - a.x), - y: a.y + t * (b.y - a.y) })) + return Math.sqrt(distance(p.x, p.y, a.x + t * (bx - a.x), a.y + t * (by - a.y) )) } function translateXY(d) { @@ -696,6 +702,15 @@ define(["d3"], function (d3) { linksDict[d.o.id] = d }) + intLinks.forEach(function (d) { + if (linksDict[d.target.o.node_id + "-" + d.source.o.node_id]) + return + + var obj = { source: d.target, target: d.source, o: { isVPN: d.o.isVPN, type: "dead", id: d.target.o.node_id + "-" + d.source.o.node_id, tq: 1 }, color: "rgba(255, 255, 255, 0.6)" } + intLinks.push(obj) + linksDict[d.target.o.node_id + "-" + d.source.o.node_id] = obj + }) + intNodes.forEach(function (d) { d.neighbours = Object.keys(d.neighbours).map(function (k) { return d.neighbours[k] From 5a5ce1d3461547385ce8a361b7f178a6e3b005f1 Mon Sep 17 00:00:00 2001 From: Milan Pssler Date: Thu, 17 Nov 2016 23:05:56 +0100 Subject: [PATCH 61/87] forcegraph: decrease line radius to increase click accuracy --- lib/forcegraph.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/forcegraph.js b/lib/forcegraph.js index 4823307..7ac8ff6 100644 --- a/lib/forcegraph.js +++ b/lib/forcegraph.js @@ -1,7 +1,7 @@ define(["d3"], function (d3) { var margin = 200 var NODE_RADIUS = 15 - var LINE_RADIUS = 12 + var LINE_RADIUS = 7 return function (config, linkScale, sidebar, router) { var self = this From 7d145141c12ab30078eeedbefeedea2e1cd41692 Mon Sep 17 00:00:00 2001 From: Milan Paessler Date: Sat, 19 Nov 2016 01:59:44 +0100 Subject: [PATCH 62/87] infobox/node: handle unknown model when showing router img --- lib/infobox/node.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/infobox/node.js b/lib/infobox/node.js index 0e7e993..f8e0228 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -372,7 +372,7 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], function showNodeImg(o, model) { if (!model) - return undefined + return document.createTextNode("Knotenname") var content, caption var modelhash = model.split("").reduce(function(a, b) { @@ -418,7 +418,7 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], try { config.hwImg.forEach(function(hwImg) { try { - top.appendChild(showNodeImg(hwImg, d.nodeinfo.hardware.model)) + top.appendChild(showNodeImg(hwImg, dictGet(d, ["nodeinfo", "hardware", "model"]))) } catch (err) { console.log(err.message) } From 9e7049c9e36e2eec77ed80716b34be9e07dd33dd Mon Sep 17 00:00:00 2001 From: Milan Paessler Date: Sat, 19 Nov 2016 02:17:08 +0100 Subject: [PATCH 63/87] infobox/node: resolve nexthop and gateway from data not perfect yet: the mac address doesn't always match --- lib/datadistributor.js | 5 +++++ lib/gui.js | 1 + lib/infobox/main.js | 7 ++++++- lib/infobox/node.js | 25 ++++++++++++++++++------- 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/lib/datadistributor.js b/lib/datadistributor.js index 67cf7eb..72d1f15 100644 --- a/lib/datadistributor.js +++ b/lib/datadistributor.js @@ -34,6 +34,11 @@ define(["filters/nodefilter"], function (NodeFilter) { filteredData = new NodeFilter(filter)(data) + filteredData.nodeDict = {} + filteredData.nodes.all.forEach(function (d) { + filteredData.nodeDict[dictGet(d, ["nodeinfo", "network", "mac"]).substr(9)] = d + }) + targets.forEach( function (t) { t.setData(filteredData) }) diff --git a/lib/gui.js b/lib/gui.js index 4ce989d..2e85f8d 100644 --- a/lib/gui.js +++ b/lib/gui.js @@ -85,6 +85,7 @@ function (chroma, Map, Sidebar, Tabs, Container, Meshstats, Legend, Linklist, fanoutUnfiltered.add(meshstats) fanoutUnfiltered.add(newnodeslist) fanoutUnfiltered.add(lostnodeslist) + fanoutUnfiltered.add(infobox) fanout.add(nodelist) fanout.add(linklist) fanout.add(statistics) diff --git a/lib/infobox/main.js b/lib/infobox/main.js index deebc03..d6e0195 100644 --- a/lib/infobox/main.js +++ b/lib/infobox/main.js @@ -2,6 +2,7 @@ define(["infobox/link", "infobox/node", "infobox/location"], function (Link, Nod return function (config, sidebar, router) { var self = this var el + var nodeDict function destroy() { if (el && el.parentNode) { @@ -33,7 +34,7 @@ define(["infobox/link", "infobox/node", "infobox/location"], function (Link, Nod self.gotoNode = function (d) { create() - new Node(config, el, router, d) + new Node(config, el, router, d, nodeDict) } self.gotoLink = function (d) { @@ -46,6 +47,10 @@ define(["infobox/link", "infobox/node", "infobox/location"], function (Link, Nod new Location(config, el, router, d) } + self.setData = function (d) { + nodeDict = d.nodeDict + } + return self } }) diff --git a/lib/infobox/node.js b/lib/infobox/node.js index f8e0228..4ce939e 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -311,7 +311,18 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], return link } - function showGateway(d, router) { + function lookupNode(d, nodeDict) { + if (!d) + return null + + var node = nodeDict[d.substr(9)] + if (!node) + return d + + return {node: node} + } + + function showGateway(d, router, nodeDict) { var nh if (dictGet(d.statistics, ["nexthop"])) nh = dictGet(d.statistics, ["nexthop"]) @@ -322,12 +333,12 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], if (!gw) return null return function (el) { if (nh) { - el.appendChild(createLink(nh, router)) - if (gw !== nh) + el.appendChild(createLink(lookupNode(nh, nodeDict), router)) + if (nh.substr(9) !== gw.substr(9)) el.appendChild(document.createTextNode(" -> ... -> ")) } - if (gw !== nh) - el.appendChild(createLink(gw, router)) + if (!nh || nh.substr(9) !== gw.substr(9)) + el.appendChild(createLink(lookupNode(gw, nodeDict), router)) } } @@ -408,7 +419,7 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], return showStat(o, subst) } - return function(config, el, router, d) { + return function(config, el, router, d, nodeDict) { var attributes = document.createElement("table") attributes.classList.add("attributes") @@ -455,7 +466,7 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], attributeEntry(attributes, "Arbeitsspeicher", showRAM(d)) attributeEntry(attributes, "IP Adressen", showIPs(d)) attributeEntry(attributes, "Webseite", showPages(d)) - attributeEntry(attributes, "Gewähltes Gateway", showGateway(d, router)) + attributeEntry(attributes, "Gewähltes Gateway", showGateway(d, router, nodeDict)) attributeEntry(attributes, "Autom. Updates", showAutoupdate(d)) attributeEntry(attributes, "Clients", showClients(d), showMeshClients(d)) From 0171ebe7e1910baf6bdb98522dd7af6c74766b4d Mon Sep 17 00:00:00 2001 From: Milan Paessler Date: Sat, 19 Nov 2016 02:27:21 +0100 Subject: [PATCH 64/87] infobox/node: non-clickable mac adresses should be black --- lib/infobox/node.js | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/infobox/node.js b/lib/infobox/node.js index 4ce939e..9e1f623 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -299,16 +299,18 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], } function createLink(target, router) { - var link = document.createElement("a") - if (!target) return link + if (!target) return document.createTextNode("unknown") var unknown = !(target.node) - link.classList.add("hostname") - link.textContent = unknown ? (target.id ? target.id : target) : target.node.nodeinfo.hostname + var text = unknown ? (target.id ? target.id : target) : target.node.nodeinfo.hostname if (!unknown) { + var link = document.createElement("a") + link.classList.add("hostname-link") link.href = "#" link.onclick = router.node(target.node) + link.textContent = text + return link } - return link + return document.createTextNode(text) } function lookupNode(d, nodeDict) { From 2ca2604403dcc3a2a6b0314a490cf940f309b994 Mon Sep 17 00:00:00 2001 From: Milan Pssler Date: Sat, 19 Nov 2016 09:37:00 +0100 Subject: [PATCH 65/87] infobox/node: change mac used to lookup nodes --- lib/datadistributor.js | 5 ----- lib/infobox/main.js | 6 +++++- lib/infobox/node.js | 8 ++++---- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/lib/datadistributor.js b/lib/datadistributor.js index 72d1f15..67cf7eb 100644 --- a/lib/datadistributor.js +++ b/lib/datadistributor.js @@ -34,11 +34,6 @@ define(["filters/nodefilter"], function (NodeFilter) { filteredData = new NodeFilter(filter)(data) - filteredData.nodeDict = {} - filteredData.nodes.all.forEach(function (d) { - filteredData.nodeDict[dictGet(d, ["nodeinfo", "network", "mac"]).substr(9)] = d - }) - targets.forEach( function (t) { t.setData(filteredData) }) diff --git a/lib/infobox/main.js b/lib/infobox/main.js index d6e0195..d90497d 100644 --- a/lib/infobox/main.js +++ b/lib/infobox/main.js @@ -48,7 +48,11 @@ define(["infobox/link", "infobox/node", "infobox/location"], function (Link, Nod } self.setData = function (d) { - nodeDict = d.nodeDict + nodeDict = {} + d.graph.nodes.forEach(function (d) { + nodeDict[d.id.substr(0, 8)] = d + }) + } return self diff --git a/lib/infobox/node.js b/lib/infobox/node.js index 9e1f623..fcc5de6 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -317,11 +317,11 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], if (!d) return null - var node = nodeDict[d.substr(9)] + var node = nodeDict[d.substr(0, 8)] if (!node) return d - return {node: node} + return node } function showGateway(d, router, nodeDict) { @@ -336,10 +336,10 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], return function (el) { if (nh) { el.appendChild(createLink(lookupNode(nh, nodeDict), router)) - if (nh.substr(9) !== gw.substr(9)) + if (nh.substr(0, 8) !== gw.substr(0, 8)) el.appendChild(document.createTextNode(" -> ... -> ")) } - if (!nh || nh.substr(9) !== gw.substr(9)) + if (!nh || nh.substr(0, 8) !== gw.substr(0, 8)) el.appendChild(createLink(lookupNode(gw, nodeDict), router)) } } From 94662cb3dc9b82b5fd809ae812accd228bcd7b87 Mon Sep 17 00:00:00 2001 From: Milan Pssler Date: Sat, 19 Nov 2016 10:57:30 +0100 Subject: [PATCH 66/87] proportions: lookup gateway name --- lib/proportions.js | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/lib/proportions.js b/lib/proportions.js index f5b0b26..3d18103 100644 --- a/lib/proportions.js +++ b/lib/proportions.js @@ -23,7 +23,7 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc var uplinkTable = document.createElement("table") uplinkTable.classList.add("proportion") - var gwNodesTable = document.createElement("table") + var gwNodesTable = document.createElement("table") gwNodesTable.classList.add("proportion") var gwClientsTable = document.createElement("table") @@ -119,9 +119,8 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc var onlineNodes = data.nodes.all.filter(online) var nodes = onlineNodes.concat(data.nodes.lost) var nodeDict = {} - - data.nodes.all.forEach(function (d) { - nodeDict[d.nodeinfo.node_id] = d + data.graph.nodes.forEach(function (d) { + nodeDict[d.id.substr(0, 8)] = d }) var statusDict = count(nodes, ["flags", "online"], function (d) { @@ -156,11 +155,12 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc if (d === null) return null - if (d.node) - return d.node.nodeinfo.hostname - - if (d.id) - return d.id + var n = nodeDict[d.substr(0, 8)] + if (!n) + return d + var name = dictGet(n, ["node", "nodeinfo", "hostname"]) + if (name) + return name return d }) @@ -169,11 +169,12 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc if (d === null) return null - if (d.node) - return d.node.nodeinfo.hostname - - if (d.id) - return d.id + var n = nodeDict[d.substr(0, 8)] + if (!n) + return d + var name = dictGet(n, ["node", "nodeinfo", "hostname"]) + if (name) + return name return d }) From 7e6d054e980b2f2d0798cb449bc9c62abef7b8fd Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Sat, 26 Nov 2016 00:10:27 +0100 Subject: [PATCH 67/87] scss: Fix a few CSS problems (#73) * Set text color on body * Fix not being able to scroll more then sidebar height in Firefox * Fix button color being set by browser stylesheet instead of site stylesheet --- scss/main.scss | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scss/main.scss b/scss/main.scss index 68cc4eb..34fd594 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -71,6 +71,7 @@ body { padding: 0; font-family: 'Roboto Slab', serif; font-size: 11pt; + color: #333; } th.sort-header::selection { @@ -219,6 +220,7 @@ button { @include shadow(1); border-radius: 0.9em; background: rgba(255, 255, 255, 0.7); + color: #333; border: none; cursor: pointer; height: 1.8em; @@ -361,7 +363,7 @@ table { position: absolute; top: $buttondistance; left: $buttondistance; - margin-bottom: $buttondistance; + padding-bottom: $buttondistance; transition: left 0.5s; } From 44bb8e9d3df334aa607ecba46f2894afc48d66ad Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sat, 10 Dec 2016 11:45:21 +0100 Subject: [PATCH 68/87] Use resolved data if gateway was already resolved (#78) This is now very dirty, I think the old approach was better (although it requires a server side change) --- lib/infobox/node.js | 3 +++ lib/proportions.js | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/lib/infobox/node.js b/lib/infobox/node.js index fcc5de6..38b56e8 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -317,6 +317,9 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], if (!d) return null + if (d.node || d.id) + return d + var node = nodeDict[d.substr(0, 8)] if (!node) return d diff --git a/lib/proportions.js b/lib/proportions.js index 3d18103..cf5f80d 100644 --- a/lib/proportions.js +++ b/lib/proportions.js @@ -155,6 +155,12 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc if (d === null) return null + if (d.node) + return d.node.nodeinfo.hostname + + if (d.id) + return d.id + var n = nodeDict[d.substr(0, 8)] if (!n) return d @@ -169,6 +175,12 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc if (d === null) return null + if (d.node) + return d.node.nodeinfo.hostname + + if (d.id) + return d.id + var n = nodeDict[d.substr(0, 8)] if (!n) return d From 5cb88e8d069b5ae9e3bc3351e1f0b21e0fe592fe Mon Sep 17 00:00:00 2001 From: Marvin W Date: Sat, 7 Jan 2017 18:43:04 +0100 Subject: [PATCH 69/87] Use server side resolving only, add proper support for nexthop resolving (#81) * Revert "Use resolved data if gateway was already resolved (#78)" This reverts commit 44bb8e9d3df334aa607ecba46f2894afc48d66ad. * Revert "proportions: lookup gateway name" This reverts commit 94662cb3dc9b82b5fd809ae812accd228bcd7b87. * Revert "infobox/node: change mac used to lookup nodes" This reverts commit 2ca2604403dcc3a2a6b0314a490cf940f309b994. * Revert "infobox/node: resolve nexthop and gateway from data" This reverts commit 9e7049c9e36e2eec77ed80716b34be9e07dd33dd. * Resolve nexthop full chain if possible requires hopglass/hopglass-server#79 * Correctly handle sidecase when nodes on route report inconsistent gateway --- lib/gui.js | 1 - lib/infobox/main.js | 11 +---------- lib/infobox/node.js | 46 ++++++++++++++++++++++----------------------- lib/proportions.js | 21 ++++----------------- 4 files changed, 28 insertions(+), 51 deletions(-) diff --git a/lib/gui.js b/lib/gui.js index 2e85f8d..4ce989d 100644 --- a/lib/gui.js +++ b/lib/gui.js @@ -85,7 +85,6 @@ function (chroma, Map, Sidebar, Tabs, Container, Meshstats, Legend, Linklist, fanoutUnfiltered.add(meshstats) fanoutUnfiltered.add(newnodeslist) fanoutUnfiltered.add(lostnodeslist) - fanoutUnfiltered.add(infobox) fanout.add(nodelist) fanout.add(linklist) fanout.add(statistics) diff --git a/lib/infobox/main.js b/lib/infobox/main.js index d90497d..deebc03 100644 --- a/lib/infobox/main.js +++ b/lib/infobox/main.js @@ -2,7 +2,6 @@ define(["infobox/link", "infobox/node", "infobox/location"], function (Link, Nod return function (config, sidebar, router) { var self = this var el - var nodeDict function destroy() { if (el && el.parentNode) { @@ -34,7 +33,7 @@ define(["infobox/link", "infobox/node", "infobox/location"], function (Link, Nod self.gotoNode = function (d) { create() - new Node(config, el, router, d, nodeDict) + new Node(config, el, router, d) } self.gotoLink = function (d) { @@ -47,14 +46,6 @@ define(["infobox/link", "infobox/node", "infobox/location"], function (Link, Nod new Location(config, el, router, d) } - self.setData = function (d) { - nodeDict = {} - d.graph.nodes.forEach(function (d) { - nodeDict[d.id.substr(0, 8)] = d - }) - - } - return self } }) diff --git a/lib/infobox/node.js b/lib/infobox/node.js index 38b56e8..f975f64 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -313,21 +313,7 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], return document.createTextNode(text) } - function lookupNode(d, nodeDict) { - if (!d) - return null - - if (d.node || d.id) - return d - - var node = nodeDict[d.substr(0, 8)] - if (!node) - return d - - return node - } - - function showGateway(d, router, nodeDict) { + function showGateway(d, router) { var nh if (dictGet(d.statistics, ["nexthop"])) nh = dictGet(d.statistics, ["nexthop"]) @@ -337,13 +323,27 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], if (!gw) return null return function (el) { - if (nh) { - el.appendChild(createLink(lookupNode(nh, nodeDict), router)) - if (nh.substr(0, 8) !== gw.substr(0, 8)) - el.appendChild(document.createTextNode(" -> ... -> ")) + var num = 0 + while (gw && nh && gw.id !== nh.id && num < 10) { + if (num !== 0) el.appendChild(document.createTextNode(" -> ")) + el.appendChild(createLink(nh, router)) + num++ + if (!nh.node || !nh.node.statistics) break + if (dictGet(nh.node.statistics, ["gateway"]).id !== gw.id) break + if (dictGet(nh.node.statistics, ["gateway_nexthop"])) + nh = dictGet(nh.node.statistics, ["gateway_nexthop"]) + else if (dictGet(nh.node.statistics, ["nexthop"])) + nh = dictGet(nh.node.statistics, ["nexthop"]) + else + break } - if (!nh || nh.substr(0, 8) !== gw.substr(0, 8)) - el.appendChild(createLink(lookupNode(gw, nodeDict), router)) + if (gw && nh && gw.id !== nh.id) { + if (num !== 0) el.appendChild(document.createTextNode(" -> ")) + num++ + el.appendChild(document.createTextNode("...")) + } + if (num !== 0) el.appendChild(document.createTextNode(" -> ")) + el.appendChild(createLink(gw, router)) } } @@ -424,7 +424,7 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], return showStat(o, subst) } - return function(config, el, router, d, nodeDict) { + return function(config, el, router, d) { var attributes = document.createElement("table") attributes.classList.add("attributes") @@ -471,7 +471,7 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], attributeEntry(attributes, "Arbeitsspeicher", showRAM(d)) attributeEntry(attributes, "IP Adressen", showIPs(d)) attributeEntry(attributes, "Webseite", showPages(d)) - attributeEntry(attributes, "Gewähltes Gateway", showGateway(d, router, nodeDict)) + attributeEntry(attributes, "Gewähltes Gateway", showGateway(d, router)) attributeEntry(attributes, "Autom. Updates", showAutoupdate(d)) attributeEntry(attributes, "Clients", showClients(d), showMeshClients(d)) diff --git a/lib/proportions.js b/lib/proportions.js index cf5f80d..f5b0b26 100644 --- a/lib/proportions.js +++ b/lib/proportions.js @@ -23,7 +23,7 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc var uplinkTable = document.createElement("table") uplinkTable.classList.add("proportion") - var gwNodesTable = document.createElement("table") + var gwNodesTable = document.createElement("table") gwNodesTable.classList.add("proportion") var gwClientsTable = document.createElement("table") @@ -119,8 +119,9 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc var onlineNodes = data.nodes.all.filter(online) var nodes = onlineNodes.concat(data.nodes.lost) var nodeDict = {} - data.graph.nodes.forEach(function (d) { - nodeDict[d.id.substr(0, 8)] = d + + data.nodes.all.forEach(function (d) { + nodeDict[d.nodeinfo.node_id] = d }) var statusDict = count(nodes, ["flags", "online"], function (d) { @@ -161,13 +162,6 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc if (d.id) return d.id - var n = nodeDict[d.substr(0, 8)] - if (!n) - return d - var name = dictGet(n, ["node", "nodeinfo", "hostname"]) - if (name) - return name - return d }) @@ -181,13 +175,6 @@ define(["chroma-js", "virtual-dom", "numeral-intl", "filters/genericnode", "verc if (d.id) return d.id - var n = nodeDict[d.substr(0, 8)] - if (!n) - return d - var name = dictGet(n, ["node", "nodeinfo", "hostname"]) - if (name) - return name - return d }) From ccc5f0f5267fe6caf366abff61660a2587ac9e97 Mon Sep 17 00:00:00 2001 From: vsandre Date: Fri, 3 Feb 2017 23:02:20 +0100 Subject: [PATCH 70/87] nodelist: Add node id to the href of node name in the table (#84) So it is possible to open multiple node pages in a new window/tab --- lib/nodelist.js | 2 +- lib/simplenodelist.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/nodelist.js b/lib/nodelist.js index ee1409c..2130061 100644 --- a/lib/nodelist.js +++ b/lib/nodelist.js @@ -56,7 +56,7 @@ define(["sorttable", "virtual-dom", "numeral"], function (SortTable, V, numeral) td1Content.push(V.h("a", { className: aClass.join(" "), onclick: router.node(d), - href: "#" + href: "#!n:" + d.nodeinfo.node_id }, d.nodeinfo.hostname)) if (has_location(d)) diff --git a/lib/simplenodelist.js b/lib/simplenodelist.js index 3a7e548..8a763df 100644 --- a/lib/simplenodelist.js +++ b/lib/simplenodelist.js @@ -41,7 +41,7 @@ define(["moment", "virtual-dom"], function (moment, V) { td1Content.push(V.h("a", { className: aClass.join(" "), onclick: router.node(d), - href: "#" + href: "#!n:" + d.nodeinfo.node_id }, d.nodeinfo.hostname)) if (has_location(d)) From 1a6a4329b5417991d9ba0019065e0e5c9dcb1648 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?PetaByteBoy=20//=20Milan=20P=C3=A4ssler?= Date: Wed, 8 Feb 2017 09:35:26 +0100 Subject: [PATCH 71/87] forcegraph: only draw clients when zoomed in --- lib/forcegraph.js | 41 +++++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/lib/forcegraph.js b/lib/forcegraph.js index 7ac8ff6..992f1b9 100644 --- a/lib/forcegraph.js +++ b/lib/forcegraph.js @@ -380,31 +380,32 @@ define(["d3"], function (d3) { // -- draw clients -- ctx.save() ctx.beginPath() - nodes.filter(visibleNodes).forEach(function (d) { - var clients = d.o.node.statistics.clients - if (clients === 0) - return + if (scale > 0.9) + nodes.filter(visibleNodes).forEach(function (d) { + var clients = d.o.node.statistics.clients + if (clients === 0) + return - var startDistance = 16 - var radius = 3 - var a = 1.2 - var startAngle = Math.PI + var startDistance = 16 + var radius = 3 + var a = 1.2 + var startAngle = Math.PI - for (var orbit = 0, i = 0; i < clients; orbit++) { - var distance = startDistance + orbit * 2 * radius * a - var n = Math.floor((Math.PI * distance) / (a * radius)) - var delta = clients - i + for (var orbit = 0, i = 0; i < clients; orbit++) { + var distance = startDistance + orbit * 2 * radius * a + var n = Math.floor((Math.PI * distance) / (a * radius)) + var delta = clients - i - for (var j = 0; j < Math.min(delta, n); i++, j++) { - var angle = 2 * Math.PI / n * j - var x = d.x + distance * Math.cos(angle + startAngle) - var y = d.y + distance * Math.sin(angle + startAngle) + for (var j = 0; j < Math.min(delta, n); i++, j++) { + var angle = 2 * Math.PI / n * j + var x = d.x + distance * Math.cos(angle + startAngle) + var y = d.y + distance * Math.sin(angle + startAngle) - ctx.moveTo(x, y) - ctx.arc(x, y, radius, 0, 2 * Math.PI) + ctx.moveTo(x, y) + ctx.arc(x, y, radius, 0, 2 * Math.PI) + } } - } - }) + }) ctx.fillStyle = clientColor ctx.fill() From 5f98da27170c18ffaf33c576d2746baf6eee6af0 Mon Sep 17 00:00:00 2001 From: Daniel Krah Date: Sat, 11 Feb 2017 01:20:04 +0100 Subject: [PATCH 72/87] Update README.md (#86) change installation of sass on mac. Version via gem is outdated --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 587694f..ae7bba7 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ On Mac you have to install only npm via brew and sass /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" brew install node - sudo gem install sass + npm install node-sass Execute these commands on your server as a normal user to prepare the dependencies: From a7756c44e83a606c761d6f4bf5502fccce8c5a4a Mon Sep 17 00:00:00 2001 From: kb-light Date: Sat, 11 Feb 2017 01:21:20 +0100 Subject: [PATCH 73/87] infobox/link: linkinfos {SOURCE_NAME} and {TARGET_NAME} support (#82) --- lib/infobox/link.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/infobox/link.js b/lib/infobox/link.js index 794753a..82b2d9f 100644 --- a/lib/infobox/link.js +++ b/lib/infobox/link.js @@ -1,8 +1,10 @@ define(function () { - function showStatImg(o, source, target) { + function showStatImg(o, d) { var subst = {} - subst["{SOURCE}"] = source - subst["{TARGET}"] = target + subst["{SOURCE}"] = d.source.node_id + subst["{SOURCE_NAME}"] = d.source.node.nodeinfo.hostname ? d.source.node.nodeinfo.hostname : "unknown" + subst["{TARGET}"] = d.target.node_id + subst["{TARGET_NAME}"] = d.target.node.nodeinfo.hostname ? d.target.node.nodeinfo.hostname : "unknown" return showStat(o, subst) } @@ -35,15 +37,12 @@ define(function () { attributeEntry(attributes, "Hardware", (hw1 != null ? hw1 : "unbekannt") + " – " + (hw2 != null ? hw2 : "unbekannt")) el.appendChild(attributes) - if (config.linkInfos) { - var source = d.source.node_id - var target = d.target.node_id + if (config.linkInfos) config.linkInfos.forEach( function (linkInfo) { var h4 = document.createElement("h4") h4.textContent = linkInfo.name el.appendChild(h4) - el.appendChild(showStatImg(linkInfo, source, target)) + el.appendChild(showStatImg(linkInfo, d)) }) - } } }) From b2c2627d73936efbea7723ba022a9e714ec1d4ed Mon Sep 17 00:00:00 2001 From: Milan Paessler Date: Tue, 14 Feb 2017 21:31:06 +0100 Subject: [PATCH 74/87] infobox: fix error when gateway could not be resolved --- lib/infobox/node.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/infobox/node.js b/lib/infobox/node.js index f975f64..34e1ee2 100644 --- a/lib/infobox/node.js +++ b/lib/infobox/node.js @@ -329,6 +329,7 @@ define(["moment", "numeral", "tablesort", "tablesort.numeric"], el.appendChild(createLink(nh, router)) num++ if (!nh.node || !nh.node.statistics) break + if (!dictGet(nh.node.statistics, ["gateway"]) || !dictGet(nh.node.statistics, ["gateway"]).id) break if (dictGet(nh.node.statistics, ["gateway"]).id !== gw.id) break if (dictGet(nh.node.statistics, ["gateway_nexthop"])) nh = dictGet(nh.node.statistics, ["gateway_nexthop"]) From 8f7c63bbce3d086a4c0d312c23530c355e2e632f Mon Sep 17 00:00:00 2001 From: H4ndl3 Date: Mon, 13 Mar 2017 22:54:36 +0100 Subject: [PATCH 75/87] add loading animation Create _loader.scss Update main.scss Update _base.scss Update gui.js Update index.html removed trailing spaces removed trailing white spaces for real --- html/index.html | 10 ++++++++++ lib/gui.js | 3 +++ scss/_base.scss | 4 ++++ scss/_loader.scss | 23 +++++++++++++++++++++++ scss/main.scss | 1 + 5 files changed, 41 insertions(+) create mode 100644 scss/_loader.scss diff --git a/html/index.html b/html/index.html index fc4ff6e..1ab6e4d 100644 --- a/html/index.html +++ b/html/index.html @@ -14,5 +14,15 @@ +
+

+ Lade
+
+ Karte & Knoten... +

+ +
diff --git a/lib/gui.js b/lib/gui.js index 4ce989d..4e14c50 100644 --- a/lib/gui.js +++ b/lib/gui.js @@ -48,6 +48,9 @@ function (chroma, Map, Sidebar, Tabs, Container, Meshstats, Legend, Linklist, } } + var loader = document.getElementsByClassName("loader")[0] + loader.classList.add("hide") + contentDiv = document.createElement("div") contentDiv.classList.add("content") document.body.appendChild(contentDiv) diff --git a/scss/_base.scss b/scss/_base.scss index 52f18c3..21ca3ff 100644 --- a/scss/_base.scss +++ b/scss/_base.scss @@ -28,3 +28,7 @@ h5 { h6 { font-size: 0.67em; } + +.hide { + display: none; +} diff --git a/scss/_loader.scss b/scss/_loader.scss new file mode 100644 index 0000000..d56c27e --- /dev/null +++ b/scss/_loader.scss @@ -0,0 +1,23 @@ +.loader { + color: #000000; + font-size: 1.8em; + line-height: 2; + margin: 30vh auto; + text-align: center; +} + +.spinner { + animation: .6s spinner ease-in-out infinite alternate; + border-bottom: 2px solid #000000; + border-radius: 50%; + display: inline-block; + height: 64px; + margin-top: 10px; + width: 64px; +} + +@keyframes spinner { + to { + transform: rotate(360deg); + } +} diff --git a/scss/main.scss b/scss/main.scss index 34fd594..47cbed9 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -4,6 +4,7 @@ @import '_leaflet'; @import '_leaflet.label'; @import '_filters'; +@import '_loader'; $minscreenwidth: 630pt; $sidebarwidth: 420pt; From 35589eabef585ec8982600aa7b94c7370d762c3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Thu, 16 Mar 2017 23:08:49 +0100 Subject: [PATCH 76/87] fix html indention --- html/index.html | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/html/index.html b/html/index.html index 1ab6e4d..76bc02d 100644 --- a/html/index.html +++ b/html/index.html @@ -14,15 +14,15 @@ -
-

- Lade
-
- Karte & Knoten... -

- -
+
+

+ Lade
+
+ Karte & Knoten... +

+ +
From 100268f3b7e4d0e256331c1b8ecb0bc26aa64663 Mon Sep 17 00:00:00 2001 From: Andreas Ziegler Date: Sun, 2 Apr 2017 16:13:05 +0200 Subject: [PATCH 77/87] change links to new upstream project name in readme & about box (#91) --- README.md | 8 ++++---- lib/about.js | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index ae7bba7..cf65dca 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -[![Build Status](https://travis-ci.org/plumpudding/hopglass.svg?branch=master)](https://travis-ci.org/plumpudding/hopglass) +[![Build Status](https://travis-ci.org/hopglass/hopglass.svg?branch=master)](https://travis-ci.org/hopglass/hopglass) # HopGlass -HopGlass is a frontend for the [HopGlass Server](https://github.com/plumpudding/hopglass-server). +HopGlass is a frontend for the [HopGlass Server](https://github.com/hopglass/hopglass-server). # Screenshots @@ -33,7 +33,7 @@ On Mac you have to install only npm via brew and sass Execute these commands on your server as a normal user to prepare the dependencies: - git clone https://github.com/plumpudding/hopglass + git clone https://github.com/hopglass/hopglass cd hopglass npm install npm install grunt-cli @@ -52,7 +52,7 @@ Copy `config.json.example` to `build/config.json` and change it to match your co ## dataPath (string/array) -`dataPath` can be either a string containing the address of a [HopGlass Server](https://github.com/plumpudding/hopglass-server) or an array containing multiple addresses. +`dataPath` can be either a string containing the address of a [HopGlass Server](https://github.com/hopglass/hopglass-server) or an array containing multiple addresses. Don't forget the trailing slash! Also, proxying the data through a webserver will allow GZip and thus will greatly reduce bandwidth consumption. It may help with firewall problems too. diff --git a/lib/about.js b/lib/about.js index 6a44b78..8005371 100644 --- a/lib/about.js +++ b/lib/about.js @@ -29,8 +29,8 @@ define(function () { s += "https://www.gnu.org/licenses/.

" s += "

The source code is available at " - s += "" - s += "https://github.com/plumpudding/hopglass." + s += "" + s += "https://github.com/hopglass/hopglass." el.innerHTML = s } From 1235d8cb462d2336726e14e7bf975ea38ae628f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20W=C3=BCllhorst?= Date: Wed, 12 Apr 2017 01:56:05 +0200 Subject: [PATCH 78/87] lib/map: support wms layers. (#89) --- lib/map.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/map.js b/lib/map.js index aca0097..57198ea 100644 --- a/lib/map.js +++ b/lib/map.js @@ -286,7 +286,7 @@ define(["map/clientlayer", "map/labelslayer", var layers = config.mapLayers.map( function (d) { return { "name": d.name, - "layer": "url" in d ? L.tileLayer(d.url, d.config) : L.tileLayer.provider(d.name) + "layer": "url" in d ? "layers" in d.config ? L.tileLayer.wms(d.url, d.config) : L.tileLayer(d.url, d.config) : L.tileLayer.provider(d.name) } }) From 587740af808fdcea3a6911dd461249621038a055 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?PetaByteBoy=20//=20Milan=20P=C3=A4ssler?= Date: Wed, 12 Apr 2017 02:22:47 +0200 Subject: [PATCH 79/87] change map layers in default config --- config.json.example | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/config.json.example b/config.json.example index b1879f0..f7b40c3 100644 --- a/config.json.example +++ b/config.json.example @@ -5,11 +5,25 @@ "showContact": true, "maxAge": 14, "mapLayers": [ + { "name": "CartoDB", + "url": "https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png", + "config": { + "maxZoom": 18, + "attribution": "© OpenStreetMap, © | CARTO" + } + }, { "name": "OpenStreetMap.HOT" }, { - "name": "Stamen.TonerLite" + "name": "Luftbilder NRW", + "url": "https://www.wms.nrw.de/geobasis/wms_nw_dop20?", + "config": { + "maxZoom": 20, + "attribution": "DOP20, Land NRW (2017), Datenlizenz Deutschland - Namensnennung - Version 2.0 (www.govdata.de/dl-de/by-2-0)", + "format": "image/jpeg", + "layers": "nw_dop20" + } } ], "nodeInfos": [ From 11368e60def87a5b5f17e7b73b9a0a1213b02451 Mon Sep 17 00:00:00 2001 From: JJX Date: Fri, 24 Aug 2018 11:40:27 +0200 Subject: [PATCH 80/87] Updated DOP-NRW WMS URL MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Der alte WMS Dienst für Luftbilder des Landes wird in Kürze abgeschaltet, dies ist der Neue. --- config.json.example | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.json.example b/config.json.example index f7b40c3..f1e6b2c 100644 --- a/config.json.example +++ b/config.json.example @@ -17,12 +17,12 @@ }, { "name": "Luftbilder NRW", - "url": "https://www.wms.nrw.de/geobasis/wms_nw_dop20?", + "url": "https://www.wms.nrw.de/geobasis/wms_nw_dop?", "config": { "maxZoom": 20, "attribution": "DOP20, Land NRW (2017), Datenlizenz Deutschland - Namensnennung - Version 2.0 (www.govdata.de/dl-de/by-2-0)", "format": "image/jpeg", - "layers": "nw_dop20" + "layers": "nw_dop_rgb" } } ], From 93e0a9c7582ec0038dfe965fa366bf7a33b891a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Sun, 20 Jan 2019 15:07:35 +0100 Subject: [PATCH 81/87] update deps, fix build with node v10 --- package.json | 11 +- tasks/build.js | 3 +- yarn.lock | 3321 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 3329 insertions(+), 6 deletions(-) create mode 100644 yarn.lock diff --git a/package.json b/package.json index d5cbd37..796da69 100644 --- a/package.json +++ b/package.json @@ -5,20 +5,21 @@ }, "devDependencies": { "autoprefixer": "^6.3.3", - "grunt": "^0.4.5", + "dart-sass": "^1.16.1", + "grunt": "^1.0.3", + "grunt-bower-install-simple": "^1.1.2", "grunt-check-dependencies": "^0.6.0", "grunt-contrib-clean": "^0.6.0", "grunt-contrib-connect": "^0.8.0", "grunt-contrib-copy": "^0.5.0", "grunt-contrib-cssmin": "^0.12.2", "grunt-contrib-requirejs": "^0.4.4", - "grunt-sass": "^1.1.0", - "grunt-postcss": "^0.7.2", "grunt-contrib-uglify": "^0.5.1", "grunt-contrib-watch": "^0.6.1", "grunt-eslint": "^10.0.0", - "grunt-bower-install-simple": "^1.1.2", - "grunt-git-describe": "^2.3.2" + "grunt-git-describe": "^2.3.2", + "grunt-postcss": "^0.7.2", + "grunt-sass": "^3.0.2" }, "eslintConfig": { "env": { diff --git a/tasks/build.js b/tasks/build.js index d76ccfc..0843dfe 100644 --- a/tasks/build.js +++ b/tasks/build.js @@ -59,7 +59,8 @@ module.exports = function(grunt) { sass: { options: { sourceMap: true, - outputStyle: "compressed" + outputStyle: "compressed", + implementation: require("dart-sass") }, dist: { files: { diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..1f00f87 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,3321 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +accepts@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.0.3.tgz#92b1db0d4f3db47b0530df6e15ae97db514dc2f8" + integrity sha1-krHbDU89tHsFMN9uFa6X21FNwvg= + dependencies: + mime "~1.2.11" + negotiator "0.4.6" + +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + integrity sha1-DNkKVhCT810KmSVsIrcGlDP60Rc= + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU= + +ansi-regex@^0.2.0, ansi-regex@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-0.2.1.tgz#0d8e946967a3d8143f93e24e298525fc1b2235f9" + integrity sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk= + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= + +ansi-regex@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9" + integrity sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w== + +ansi-styles@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.1.0.tgz#eaecbf66cd706882760b2f4691582b8f55d7a7de" + integrity sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94= + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +aproba@^1.0.3: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + integrity sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w== + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.2, argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + +arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E= + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + integrity sha1-GdOGodntxufByF04iu28xW0zYC0= + +async@0.1.15: + version "0.1.15" + resolved "https://registry.yarnpkg.com/async/-/async-0.1.15.tgz#2180eaca2cf2a6ca5280d41c0585bec9b3e49bd3" + integrity sha1-IYDqyizypspSgNQcBYW+ybPkm9M= + +async@~0.2.9: + version "0.2.10" + resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" + integrity sha1-trvgsGdLnXGXCMo43owjfLUmw9E= + +async@~0.9.0: + version "0.9.2" + resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" + integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= + +async@~1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= + +atob@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + +autoprefixer@^6.3.3: + version "6.7.7" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-6.7.7.tgz#1dbd1c835658e35ce3f9984099db00585c782014" + integrity sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ= + dependencies: + browserslist "^1.7.6" + caniuse-db "^1.0.30000634" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^5.2.16" + postcss-value-parser "^3.2.3" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +basic-auth-connect@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/basic-auth-connect/-/basic-auth-connect-1.0.0.tgz#fdb0b43962ca7b40456a7c2bb48fe173da2d2122" + integrity sha1-/bC0OWLKe0BFanwrtI/hc9otISI= + +batch@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.5.0.tgz#fd2e05a7a5d696b4db9314013e285d8ff3557ec3" + integrity sha1-/S4Fp6XWlrTbkxQBPihdj/NVfsM= + +binary-extensions@^1.0.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.12.0.tgz#c2d780f53d45bba8317a8902d4ceeaf3a6385b14" + integrity sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg== + +body-parser@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.3.1.tgz#1a74513fc7897d70db56589e0d03f0a13f1bfa94" + integrity sha1-GnRRP8eJfXDbVlieDQPwoT8b+pQ= + dependencies: + bytes "1.0.0" + qs "0.6.6" + raw-body "1.1.6" + type-is "1.2.1" + +bower-config@^0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/bower-config/-/bower-config-0.5.3.tgz#98fc5b41a87870ef9cbb9297635cf81f5505fdb1" + integrity sha1-mPxbQah4cO+cu5KXY1z4H1UF/bE= + dependencies: + graceful-fs "~2.0.0" + mout "~0.9.0" + optimist "~0.6.0" + osenv "0.0.3" + +bower@1.8.4: + version "1.8.4" + resolved "https://registry.yarnpkg.com/bower/-/bower-1.8.4.tgz#e7876a076deb8137f7d06525dc5e8c66db82f28a" + integrity sha1-54dqB23rgTf30GUl3F6MZtuC8oo= + +brace-expansion@^1.0.0, brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^2.3.0, braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +browserify-zlib@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d" + integrity sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0= + dependencies: + pako "~0.2.0" + +browserslist@^1.7.6: + version "1.7.7" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-1.7.7.tgz#0bd76704258be829b2398bb50e4b62d1a166b0b9" + integrity sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk= + dependencies: + caniuse-db "^1.0.30000639" + electron-to-chromium "^1.2.7" + +buffer-crc32@0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.1.tgz#be3e5382fc02b6d6324956ac1af98aa98b08534c" + integrity sha1-vj5TgvwCttYySVasGvmKqYsIU0w= + +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== + +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= + +bytes@1, bytes@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-1.0.0.tgz#3569ede8ba34315fab99c3e92cb04c7220de1fa8" + integrity sha1-NWnt6Lo0MV+rmcPpLLBMciDeH6g= + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha1-MIvur/3ygRkFHvodkyITyRuPkuc= + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + integrity sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk= + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= + +caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: + version "1.0.30000929" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000929.tgz#f18c557b9cbf33e2787134c915b82e3ed3331b87" + integrity sha512-bap0KDH7KJ2Hc4zWb1bBJwsyl+76jOukW6TH8uxaVI7BrzF2CnibTj53ro7VZAHB+ucMlIGBC1rhG2BQY0ekeg== + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + integrity sha1-qg0yYptu6XIgBBHL1EYckHvCt60= + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +chalk@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^0.5.0, chalk@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.5.1.tgz#663b3a648b68b55d04690d49167aa837858f2174" + integrity sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ= + dependencies: + ansi-styles "^1.1.0" + escape-string-regexp "^1.0.0" + has-ansi "^0.1.0" + strip-ansi "^0.3.0" + supports-color "^0.2.0" + +chalk@^1.0.0, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@~2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +check-dependencies@^0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/check-dependencies/-/check-dependencies-0.7.1.tgz#722335efd4d64d0c86aabfeb75988afaf856d318" + integrity sha1-ciM179TWTQyGqr/rdZiK+vhW0xg= + dependencies: + bower-config "^0.5.2" + chalk "^0.5.1" + findup-sync "^0.1.3" + lodash "^2.4.1" + semver "^2.3.1" + +chokidar@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" + integrity sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.0" + braces "^2.3.0" + glob-parent "^3.1.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + lodash.debounce "^4.0.8" + normalize-path "^2.1.1" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + upath "^1.0.5" + optionalDependencies: + fsevents "^1.2.2" + +chownr@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" + integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +clean-css@^3.1.0: + version "3.4.28" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-3.4.28.tgz#bf1945e82fc808f55695e6ddeaec01400efd03ff" + integrity sha1-vxlF6C/ICPVWlebd6uwBQA79A/8= + dependencies: + commander "2.8.x" + source-map "0.4.x" + +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + integrity sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE= + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= + +coffeescript@~1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/coffeescript/-/coffeescript-1.10.0.tgz#e7aa8301917ef621b35d8a39f348dcdd1db7e33e" + integrity sha1-56qDAZF+9iGzXYo580jc3R234z4= + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= + +colors@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" + integrity sha1-FopHAXVran9RoSzgyXv6KMCE7WM= + +commander@2.8.x: + version "2.8.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" + integrity sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ= + dependencies: + graceful-readlink ">= 1.0.0" + +component-emitter@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + integrity sha1-E3kY1teCg/ffemt8WmPhQOaUJeY= + +compressible@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-1.1.0.tgz#124d8a7bba18a05a410a2f25bad413b1b94aff67" + integrity sha1-Ek2Ke7oYoFpBCi8lutQTsblK/2c= + +compression@1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.0.7.tgz#fc4bff261df4e37a130006f2db2a99a34896f55a" + integrity sha1-/Ev/Jh3043oTAAby2yqZo0iW9Vo= + dependencies: + accepts "1.0.3" + bytes "1.0.0" + compressible "1.1.0" + on-headers "0.0.0" + vary "0.1.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= + +concat-stream@^1.4.1, concat-stream@^1.4.6: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +connect-livereload@~0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/connect-livereload/-/connect-livereload-0.4.1.tgz#0f8a1a816bc9baffae4637ccea917462fe35917a" + integrity sha1-D4oagWvJuv+uRjfM6pF0Yv41kXo= + +connect-timeout@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/connect-timeout/-/connect-timeout-1.1.0.tgz#fc80615fc7a5b3863bd0319af2491d2d7fdc5f05" + integrity sha1-/IBhX8els4Y70DGa8kkdLX/cXwU= + dependencies: + debug "0.8.1" + +connect@~2.19.5: + version "2.19.6" + resolved "https://registry.yarnpkg.com/connect/-/connect-2.19.6.tgz#d473fd7949c55b423a64f8420dbd069db77cd9d2" + integrity sha1-1HP9eUnFW0I6ZPhCDb0Gnbd82dI= + dependencies: + basic-auth-connect "1.0.0" + body-parser "1.3.1" + bytes "1.0.0" + compression "1.0.7" + connect-timeout "1.1.0" + cookie "0.1.2" + cookie-parser "1.1.0" + cookie-signature "1.0.3" + csurf "1.2.1" + debug "1.0.2" + errorhandler "1.0.2" + escape-html "1.0.1" + express-session "1.2.1" + fresh "0.2.2" + method-override "2.0.2" + morgan "1.1.1" + multiparty "3.2.8" + on-headers "0.0.0" + parseurl "1.0.1" + pause "0.0.1" + qs "0.6.6" + response-time "2.0.0" + serve-favicon "2.0.1" + serve-index "1.1.1" + serve-static "1.2.3" + type-is "1.2.1" + vhost "1.0.0" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= + +cookie-parser@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.1.0.tgz#2f8265aa3b55733a85eef207f0e2530c3e8cf705" + integrity sha1-L4JlqjtVczqF7vIH8OJTDD6M9wU= + dependencies: + cookie "0.1.2" + cookie-signature "1.0.3" + +cookie-signature@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.3.tgz#91cd997cc51fb641595738c69cda020328f50ff9" + integrity sha1-kc2ZfMUftkFZVzjGnNoCAyj1D/k= + +cookie@0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.1.2.tgz#72fec3d24e48a3432073d90c12642005061004b1" + integrity sha1-cv7D0k5Io0Mgc9kMEmQgBQYQBLE= + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= + +csrf-tokens@~1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/csrf-tokens/-/csrf-tokens-1.0.4.tgz#49672568b2703348644eacaf61cdbdc054ba56f2" + integrity sha1-SWclaLJwM0hkTqyvYc29wFS6VvI= + dependencies: + rndm "1" + scmp "~0.0.3" + uid2 "~0.0.2" + +csurf@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/csurf/-/csurf-1.2.1.tgz#3928fa237592ed5824a7c221d8581bf356a9da76" + integrity sha1-OSj6I3WS7Vgkp8Ih2Fgb81ap2nY= + dependencies: + csrf-tokens "~1.0.2" + +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha1-mI3zP+qxke95mmE2nddsF635V+o= + dependencies: + array-find-index "^1.0.1" + +d@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" + integrity sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8= + dependencies: + es5-ext "^0.10.9" + +d@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/d/-/d-0.1.1.tgz#da184c535d18d8ee7ba2aa229b914009fae11309" + integrity sha1-2hhMU10Y2O57oqoim5FACfrhEwk= + dependencies: + es5-ext "~0.10.2" + +dart-sass@^1.16.1: + version "1.16.1" + resolved "https://registry.yarnpkg.com/dart-sass/-/dart-sass-1.16.1.tgz#872366e52ec8350977b2782dad80a87c2ad9188f" + integrity sha512-d5fmseG+9km7Ky56fZ1fy+eq21ARiWrw+gG/HmEOnO512toPg1pRJ79PoCH7NYM/2CwF05AutoFrp058lQasfQ== + dependencies: + chokidar "^2.0.0" + +dateformat@~1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-1.0.12.tgz#9f124b67594c937ff706932e4a642cca8dbbfee9" + integrity sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk= + dependencies: + get-stdin "^4.0.1" + meow "^3.3.0" + +debug@0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-0.8.1.tgz#20ff4d26f5e422cb68a1bacbbb61039ad8c1c130" + integrity sha1-IP9NJvXkIstoobrLu2EDmtjBwTA= + +debug@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-1.0.2.tgz#3849591c10cce648476c3c7c2e2e3416db5963c4" + integrity sha1-OElZHBDM5khHbDx8Li40FttZY8Q= + dependencies: + ms "0.6.2" + +debug@^2.1.1, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +debug@~0.7.0: + version "0.7.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-0.7.4.tgz#06e1ea8082c2cb14e39806e22e2f6f757f92af39" + integrity sha1-BuHqgILCyxTjmAbiLi9vdX+Srzk= + +decamelize@^1.0.0, decamelize@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + +deep-is@~0.1.2: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ= + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= + +diff@^2.0.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/diff/-/diff-2.2.3.tgz#60eafd0d28ee906e4e8ff0a52c1229521033bf99" + integrity sha1-YOr9DSjukG5Oj/ClLBIpUhAzv5k= + +doctrine@^0.6.2: + version "0.6.4" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-0.6.4.tgz#81428491a942ef18b0492056eda3800eee57d61d" + integrity sha1-gUKEkalC7xiwSSBW7aOADu5X1h0= + dependencies: + esutils "^1.1.6" + isarray "0.0.1" + +ee-first@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.0.3.tgz#6c98c4089abecb5a7b85c1ac449aa603d3b3dabe" + integrity sha1-bJjECJq+y1p7hcGsRJqmA9Oz2r4= + +electron-to-chromium@^1.2.7: + version "1.3.103" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.103.tgz#a695777efdbc419cad6cbb0e58458251302cd52f" + integrity sha512-tObPqGmY9X8MUM8i3MEimYmbnLLf05/QV5gPlkR8MQ3Uj8G8B2govE1U4cQcBYtv3ymck9Y8cIOu4waoiykMZQ== + +error-ex@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + +errorhandler@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/errorhandler/-/errorhandler-1.0.2.tgz#587d47bbbbc48cffe132c3acda7215c902558108" + integrity sha1-WH1Hu7vEjP/hMsOs2nIVyQJVgQg= + +es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.5, es5-ext@~0.10.6: + version "0.10.47" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.47.tgz#d24232e1380daad5449a817be19bde9729024a11" + integrity sha512-/1TItLfj+TTfWoeRcDn/0FbGV6SNo4R+On2GGVucPU/j3BWnXE2Co8h8CTo4Tu34gFJtnmwS9xiScKs4EjZhdw== + dependencies: + es6-iterator "~2.0.3" + es6-symbol "~3.1.1" + next-tick "1" + +es6-iterator@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-0.1.3.tgz#d6f58b8c4fc413c249b4baa19768f8e4d7c8944e" + integrity sha1-1vWLjE/EE8JJtLqhl2j45NfIlE4= + dependencies: + d "~0.1.1" + es5-ext "~0.10.5" + es6-symbol "~2.0.1" + +es6-iterator@~2.0.1, es6-iterator@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha1-p96IkUGgWpSwhUQDstCg+/qY87c= + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-map@^0.1.1: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + integrity sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA= + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-set "~0.1.5" + es6-symbol "~3.1.1" + event-emitter "~0.3.5" + +es6-promise@^3.0.2: + version "3.3.1" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.3.1.tgz#a08cdde84ccdbf34d027a1451bc91d4bcd28a613" + integrity sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM= + +es6-set@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + integrity sha1-0rPsXU2ADO2BjbU40ol02wpzzLE= + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" + +es6-symbol@3.1.1, es6-symbol@^3.1.1, es6-symbol@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + integrity sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc= + dependencies: + d "1" + es5-ext "~0.10.14" + +es6-symbol@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-2.0.1.tgz#761b5c67cfd4f1d18afb234f691d678682cb3bf3" + integrity sha1-dhtcZ8/U8dGK+yNPaR1nhoLLO/M= + dependencies: + d "~0.1.1" + es5-ext "~0.10.5" + +es6-weak-map@^0.1.2: + version "0.1.4" + resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-0.1.4.tgz#706cef9e99aa236ba7766c239c8b9e286ea7d228" + integrity sha1-cGzvnpmqI2undmwjnIueKG6n0ig= + dependencies: + d "~0.1.1" + es5-ext "~0.10.6" + es6-iterator "~0.1.3" + es6-symbol "~2.0.1" + +escape-html@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.1.tgz#181a286ead397a39a92857cfb1d43052e356bff0" + integrity sha1-GBoobq05ejmpKFfPsdQwUuNWv/A= + +escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= + +escope@2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/escope/-/escope-2.0.6.tgz#c1bac24870605bb384ba073dce0417c9305eddeb" + integrity sha1-wbrCSHBgW7OEugc9zgQXyTBe3es= + dependencies: + es6-map "^0.1.1" + es6-weak-map "^0.1.2" + esrecurse "^1.2.0" + estraverse ">=1.9.0" + util-extend "^1.0.1" + +eslint@^0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-0.18.0.tgz#e1117ccd86af174b0312ffe82509019d5b50759b" + integrity sha1-4RF8zYavF0sDEv/oJQkBnVtQdZs= + dependencies: + chalk "^1.0.0" + concat-stream "^1.4.6" + debug "^2.1.1" + doctrine "^0.6.2" + escape-string-regexp "^1.0.2" + escope "2.0.6" + espree "^1.12.0" + estraverse "^2.0.0" + estraverse-fb "^1.3.1" + globals "^6.1.0" + js-yaml "^3.2.5" + minimatch "^2.0.1" + mkdirp "^0.5.0" + object-assign "^2.0.0" + optionator "^0.5.0" + strip-json-comments "~1.0.1" + text-table "~0.2.0" + user-home "^1.0.0" + xml-escape "~1.0.0" + +espree@^1.12.0: + version "1.12.3" + resolved "https://registry.yarnpkg.com/espree/-/espree-1.12.3.tgz#04ceeada91bda077a38c040c125ba186b13bb3cc" + integrity sha1-BM7q2pG9oHejjAQMEluhhrE7s8w= + +esprima@^2.6.0: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + integrity sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE= + +esprima@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esrecurse@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-1.2.0.tgz#25e3b3ab76ad8a1da2d38e9393fd76b8456a706f" + integrity sha1-JeOzq3atih2i046Tk/12uEVqcG8= + dependencies: + estraverse ">=1.9.0" + +estraverse-fb@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/estraverse-fb/-/estraverse-fb-1.3.2.tgz#d323a4cb5e5ac331cea033413a9253e1643e07c4" + integrity sha1-0yOky15awzHOoDNBOpJT4WQ+B8Q= + +estraverse@>=1.9.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM= + +estraverse@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-2.0.0.tgz#5ae46963243600206674ccb24a09e16674fcdca1" + integrity sha1-WuRpYyQ2ACBmdMyySgnhZnT83KE= + +esutils@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.1.6.tgz#c01ccaa9ae4b897c6d0c3e210ae52f3c7a844375" + integrity sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U= + +event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk= + dependencies: + d "1" + es5-ext "~0.10.14" + +eventemitter2@~0.4.13: + version "0.4.14" + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-0.4.14.tgz#8f61b75cde012b2e9eb284d4545583b5643b61ab" + integrity sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas= + +exit@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha1-BjJjj42HfMghB9MKD/8aF8uhzQw= + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +express-session@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.2.1.tgz#2741a1661eb3a4a17a7db0a48049fbf05574e465" + integrity sha1-J0GhZh6zpKF6fbCkgEn78FV05GU= + dependencies: + buffer-crc32 "0.2.1" + cookie "0.1.2" + cookie-signature "1.0.3" + debug "0.8.1" + on-headers "0.0.0" + uid2 "0.0.3" + utils-merge "1.0.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +fast-levenshtein@~1.0.0: + version "1.0.7" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-1.0.7.tgz#0178dcdee023b92905193af0959e8a7639cfdcb9" + integrity sha1-AXjc3uAjuSkFGTrwlZ6KdjnP3Lk= + +faye-websocket@~0.4.3: + version "0.4.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.4.4.tgz#c14c5b3bf14d7417ffbfd990c0a7495cd9f337bc" + integrity sha1-wUxbO/FNdBf/v9mQwKdJXNnzN7w= + +figures@^1.0.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + integrity sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4= + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +findup-sync@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.1.3.tgz#7f3e7a97b82392c653bf06589bd85190e93c3683" + integrity sha1-fz56l7gjksZTvwZYm9hRkOk8NoM= + dependencies: + glob "~3.2.9" + lodash "~2.4.1" + +findup-sync@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-0.3.0.tgz#37930aa5d816b777c03445e1966cc6790a4c0b16" + integrity sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY= + dependencies: + glob "~5.0.0" + +finished@1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/finished/-/finished-1.2.2.tgz#41608eafadfd65683b46a1220bc4b1ec3daedcd8" + integrity sha1-QWCOr639ZWg7RqEiC8Sx7D2u3Ng= + dependencies: + ee-first "1.0.3" + +for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + dependencies: + map-cache "^0.2.2" + +fresh@0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.2.2.tgz#9731dcf5678c7faeb44fb903c4f72df55187fa77" + integrity sha1-lzHc9WeMf660T7kDxPct9VGH+nc= + +fs-minipass@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + integrity sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ== + dependencies: + minipass "^2.2.1" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= + +fsevents@^1.2.2: + version "1.2.7" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.7.tgz#4851b664a3783e52003b3c66eb0eee1074933aa4" + integrity sha512-Pxm6sI2MeBD7RdD12RYsqaP0nMiwx8eZBXCa6z2L+mRHm2DYrOYwihmhjpkdjUHwQhslWQjRpEgNq4XvBmaAuw== + dependencies: + nan "^2.9.2" + node-pre-gyp "^0.10.0" + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +gaze@~0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/gaze/-/gaze-0.5.2.tgz#40b709537d24d1d45767db5a908689dfe69ac44f" + integrity sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8= + dependencies: + globule "~0.1.0" + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4= + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + +getobject@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/getobject/-/getobject-0.1.0.tgz#047a449789fa160d018f5486ed91320b6ec7885c" + integrity sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw= + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob@^7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" + integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@~3.1.21: + version "3.1.21" + resolved "https://registry.yarnpkg.com/glob/-/glob-3.1.21.tgz#d29e0a055dea5138f4d07ed40e8982e83c2066cd" + integrity sha1-0p4KBV3qUTj00H7UDomC6DwgZs0= + dependencies: + graceful-fs "~1.2.0" + inherits "1" + minimatch "~0.2.11" + +glob@~3.2.9: + version "3.2.11" + resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" + integrity sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0= + dependencies: + inherits "2" + minimatch "0.3" + +glob@~5.0.0: + version "5.0.15" + resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" + integrity sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E= + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@~7.0.0: + version "7.0.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.0.6.tgz#211bafaf49e525b8cd93260d14ab136152b3f57a" + integrity sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo= + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^6.1.0: + version "6.4.1" + resolved "https://registry.yarnpkg.com/globals/-/globals-6.4.1.tgz#8498032b3b6d1cc81eebc5f79690d8fe29fabf4f" + integrity sha1-hJgDKzttHMge68X3lpDY/in6v08= + +globule@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/globule/-/globule-0.1.0.tgz#d9c8edde1da79d125a151b79533b978676346ae5" + integrity sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU= + dependencies: + glob "~3.1.21" + lodash "~1.0.1" + minimatch "~0.2.11" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2: + version "4.1.15" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" + integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== + +graceful-fs@~1.2.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-1.2.3.tgz#15a4806a57547cb2d2dbf27f42e89a8c3451b364" + integrity sha1-FaSAaldUfLLS2/J/QuiajDRRs2Q= + +graceful-fs@~2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-2.0.3.tgz#7cd2cdb228a4a3f36e95efa6cc142de7d1a136d0" + integrity sha1-fNLNsiiko/Nule+mzBQt59GhNtA= + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= + +grunt-bower-install-simple@^1.1.2: + version "1.2.7" + resolved "https://registry.yarnpkg.com/grunt-bower-install-simple/-/grunt-bower-install-simple-1.2.7.tgz#9442b48a1d9abafa0b3530c82344432ea6cb5d40" + integrity sha512-5we1xo8In1ZnWxN73YhttAb25ya1U8VbEa71Ep2v2SMP61aZaa2JZsG04jZaN26zyI/Dbrxj3aKWmLAuN4/MeA== + dependencies: + bower "1.8.4" + chalk "2.4.1" + strip-ansi "5.0.0" + +grunt-check-dependencies@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/grunt-check-dependencies/-/grunt-check-dependencies-0.6.0.tgz#f7206a3a61041a21cd273b86e3a52cbee974ea74" + integrity sha1-9yBqOmEEGiHNJzuG46Usvul06nQ= + dependencies: + check-dependencies "^0.7.1" + lodash.clonedeep "^2.4.1" + +grunt-cli@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/grunt-cli/-/grunt-cli-1.2.0.tgz#562b119ebb069ddb464ace2845501be97b35b6a8" + integrity sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg= + dependencies: + findup-sync "~0.3.0" + grunt-known-options "~1.1.0" + nopt "~3.0.6" + resolve "~1.1.0" + +grunt-contrib-clean@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/grunt-contrib-clean/-/grunt-contrib-clean-0.6.0.tgz#f532dba4b8212674c7c013e146bda6638b9048f6" + integrity sha1-9TLbpLghJnTHwBPhRr2mY4uQSPY= + dependencies: + rimraf "~2.2.1" + +grunt-contrib-connect@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/grunt-contrib-connect/-/grunt-contrib-connect-0.8.0.tgz#1f70043e3a473ae8fb7a8acbf929ce104eaf4323" + integrity sha1-H3AEPjpHOuj7eorL+SnOEE6vQyM= + dependencies: + async "~0.9.0" + connect "~2.19.5" + connect-livereload "~0.4.0" + open "0.0.5" + portscanner "~0.2.3" + +grunt-contrib-copy@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/grunt-contrib-copy/-/grunt-contrib-copy-0.5.0.tgz#410075ac45a5856ba191b1cc725725450d4a0215" + integrity sha1-QQB1rEWlhWuhkbHMclclRQ1KAhU= + +grunt-contrib-cssmin@^0.12.2: + version "0.12.3" + resolved "https://registry.yarnpkg.com/grunt-contrib-cssmin/-/grunt-contrib-cssmin-0.12.3.tgz#4157596096fb7656fc464b4cc7b0746de1f39014" + integrity sha1-QVdZYJb7dlb8RktMx7B0beHzkBQ= + dependencies: + chalk "^1.0.0" + clean-css "^3.1.0" + maxmin "^1.1.0" + +grunt-contrib-requirejs@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/grunt-contrib-requirejs/-/grunt-contrib-requirejs-0.4.4.tgz#87f2165a981e48a45d22f8cc5299d0934031b972" + integrity sha1-h/IWWpgeSKRdIvjMUpnQk0AxuXI= + dependencies: + requirejs "~2.1.0" + +grunt-contrib-uglify@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/grunt-contrib-uglify/-/grunt-contrib-uglify-0.5.1.tgz#15f0aa5e8e8ba421aea980879ee505bc712b6cde" + integrity sha1-FfCqXo6LpCGuqYCHnuUFvHErbN4= + dependencies: + chalk "^0.5.1" + lodash "^2.4.1" + maxmin "^0.2.0" + uglify-js "^2.4.0" + +grunt-contrib-watch@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/grunt-contrib-watch/-/grunt-contrib-watch-0.6.1.tgz#64fdcba25a635f5b4da1b6ce6f90da0aeb6e3f15" + integrity sha1-ZP3LolpjX1tNobbOb5DaCutuPxU= + dependencies: + async "~0.2.9" + gaze "~0.5.1" + lodash "~2.4.1" + tiny-lr-fork "0.0.5" + +grunt-eslint@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/grunt-eslint/-/grunt-eslint-10.0.0.tgz#756dcc0aa3c26df5a6834d947efa7af3219268b7" + integrity sha1-dW3MCqPCbfWmg02Ufvp68yGSaLc= + dependencies: + chalk "^1.0.0" + eslint "^0.18.0" + +grunt-git-describe@^2.3.2: + version "2.4.4" + resolved "https://registry.yarnpkg.com/grunt-git-describe/-/grunt-git-describe-2.4.4.tgz#6d32c03c4a191d397ec3ec1fff6abe74bef0436c" + integrity sha512-R4vwvMdFMbwCfF26NPRc/Jw6d49v2aK3+P/nwKg8GHH/siE2OFmzfUHGYbbru8S55NwpLsLxxL1glIJfl9ZZOw== + dependencies: + grunt-util-args "~0.0.5" + grunt-util-options "~0.0.4" + grunt-util-process "~0.0.3" + grunt-util-spawn "~0.0.3" + +grunt-known-options@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/grunt-known-options/-/grunt-known-options-1.1.1.tgz#6cc088107bd0219dc5d3e57d91923f469059804d" + integrity sha512-cHwsLqoighpu7TuYj5RonnEuxGVFnztcUqTqp5rXFGYL4OuPFofwC4Ycg7n9fYwvK6F5WbYgeVOwph9Crs2fsQ== + +grunt-legacy-log-utils@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.0.1.tgz#d2f442c7c0150065d9004b08fd7410d37519194e" + integrity sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA== + dependencies: + chalk "~2.4.1" + lodash "~4.17.10" + +grunt-legacy-log@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/grunt-legacy-log/-/grunt-legacy-log-2.0.0.tgz#c8cd2c6c81a4465b9bbf2d874d963fef7a59ffb9" + integrity sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw== + dependencies: + colors "~1.1.2" + grunt-legacy-log-utils "~2.0.0" + hooker "~0.2.3" + lodash "~4.17.5" + +grunt-legacy-util@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/grunt-legacy-util/-/grunt-legacy-util-1.1.1.tgz#e10624e7c86034e5b870c8a8616743f0a0845e42" + integrity sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A== + dependencies: + async "~1.5.2" + exit "~0.1.1" + getobject "~0.1.0" + hooker "~0.2.3" + lodash "~4.17.10" + underscore.string "~3.3.4" + which "~1.3.0" + +grunt-postcss@^0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/grunt-postcss/-/grunt-postcss-0.7.2.tgz#57b7647b877d42ad32cf9d4cd110080fffb438ab" + integrity sha1-V7dke4d9Qq0yz51M0RAID/+0OKs= + dependencies: + chalk "^1.0.0" + diff "^2.0.2" + es6-promise "^3.0.2" + postcss "^5.0.0" + +grunt-sass@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/grunt-sass/-/grunt-sass-3.0.2.tgz#b4f01567ce3df4460fcc788e9e5e4c65263425ed" + integrity sha512-Ogq4cWqBre71gZIkgxIxevgzZHSIIsrKu/5yvPDl4Mvib0A4TRTJEQUdpQ0YV1iai0DPjayz02vDJE6KUVHQ2w== + +grunt-util-args@~0.0.5: + version "0.0.6" + resolved "https://registry.yarnpkg.com/grunt-util-args/-/grunt-util-args-0.0.6.tgz#64de823381e4666e32f83de43982b92a4835eeae" + integrity sha512-4KyEuzSxaOG4Hq9Z+hUPDUYfDpajSQpqm/pwFJwpgb/Ovb9Dt6t3ed3G72ROB+dnYPlCvp0cVB/uhr2ATweOVw== + +grunt-util-options@~0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/grunt-util-options/-/grunt-util-options-0.0.4.tgz#4dae5e308bf9d64285e26c942d0574f30d92a8f0" + integrity sha512-LobA4rbryvmUHgFoTVR2Wqm85Jz9QlPPBp6vkH0a82HlxSv9x/ssgjA2B5Nt77TsUOOxT/8Oawk8dNtlAgznow== + dependencies: + grunt-util-property "^0.0.2" + +grunt-util-process@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/grunt-util-process/-/grunt-util-process-0.0.3.tgz#7eb67a9042c9dcd21302d241d9b02520363776a5" + integrity sha512-P//HbGFm4BVO9l6P5ILiibjLDZ4n+1sAq5FRfuk9yzmcgUbe+t2NsBba930jVekD2S6kie4dBvmy40+GguViSg== + +grunt-util-property@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/grunt-util-property/-/grunt-util-property-0.0.2.tgz#ca54536bc6844afc235b0ccd854d2d4b29ce4b30" + integrity sha512-NxrejQerh//FZpDHJL8eAYsY84KOddc+OYcNiKrl1iErdRFaMscl6EsuFjrva/qGhRo2YQITDsmWW8cAQVOXZA== + +grunt-util-spawn@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/grunt-util-spawn/-/grunt-util-spawn-0.0.3.tgz#b04c6383f4ba43236deb583941dc8c9e4e67cd80" + integrity sha512-DIMbGoAL9RXV0v3le8dTPjjf/bgFoB3be/AiX2S7GnE2mGyQYWCTj07DPzefiRJ7VbDGqIeg4bSOT5sHyPApbQ== + +grunt@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/grunt/-/grunt-1.0.3.tgz#b3c99260c51d1b42835766e796527b60f7bba374" + integrity sha512-/JzmZNPfKorlCrrmxWqQO4JVodO+DVd5XX4DkocL/1WlLlKVLE9+SdEIempOAxDhWPysLle6afvn/hg7Ck2k9g== + dependencies: + coffeescript "~1.10.0" + dateformat "~1.0.12" + eventemitter2 "~0.4.13" + exit "~0.1.1" + findup-sync "~0.3.0" + glob "~7.0.0" + grunt-cli "~1.2.0" + grunt-known-options "~1.1.0" + grunt-legacy-log "~2.0.0" + grunt-legacy-util "~1.1.1" + iconv-lite "~0.4.13" + js-yaml "~3.5.2" + minimatch "~3.0.2" + mkdirp "~0.5.1" + nopt "~3.0.6" + path-is-absolute "~1.0.0" + rimraf "~2.6.2" + +gzip-size@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-0.2.0.tgz#e3a2a191205fe56ee326f5c271435dfaecfb3e1c" + integrity sha1-46KhkSBf5W7jJvXCcUNd+uz7Phw= + dependencies: + browserify-zlib "^0.1.4" + concat-stream "^1.4.1" + +gzip-size@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-1.0.0.tgz#66cf8b101047227b95bace6ea1da0c177ed5c22f" + integrity sha1-Zs+LEBBHInuVus5uodoMF37Vwi8= + dependencies: + browserify-zlib "^0.1.4" + concat-stream "^1.4.1" + +has-ansi@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-0.1.0.tgz#84f265aae8c0e6a88a12d7022894b7568894c62e" + integrity sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4= + dependencies: + ansi-regex "^0.2.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo= + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0= + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +hooker@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/hooker/-/hooker-0.2.3.tgz#b834f723cc4a242aa65963459df6d984c5d3d959" + integrity sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk= + +hosted-git-info@^2.1.4: + version "2.7.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== + +iconv-lite@^0.4.4, iconv-lite@~0.4.13: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== + dependencies: + minimatch "^3.0.4" + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha1-ji1INIdCEhtKghi3oTfppSBJ3IA= + dependencies: + repeating "^2.0.0" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-1.0.2.tgz#ca4309dadee6b54cc0b8d247e8d7c7a0975bdc9b" + integrity sha1-ykMJ2t7mtUzAuNJH6NfHoJdb3Js= + +inherits@2, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74= + dependencies: + builtin-modules "^1.0.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== + dependencies: + kind-of "^6.0.0" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + integrity sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + integrity sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A= + dependencies: + is-extglob "^2.1.1" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + dependencies: + kind-of "^3.0.2" + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= + +is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +isarray@1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= + +js-base64@^2.1.9: + version "2.5.0" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.5.0.tgz#42255ba183ab67ce59a0dee640afdc00ab5ae93e" + integrity sha512-wlEBIZ5LP8usDylWbDNhKPEFVFdI5hCHpnVoT/Ysvoi/PRhJENm/Rlh9TvjYB38HFfKZN7OzEbRjmjvLkFw11g== + +js-yaml@^3.2.5: + version "3.12.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.1.tgz#295c8632a18a23e054cf5c9d3cecafe678167600" + integrity sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@~3.5.2: + version "3.5.5" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.5.5.tgz#0377c38017cabc7322b0d1fbcd25a491641f2fbe" + integrity sha1-A3fDgBfKvHMisNH7zSWkkWQfL74= + dependencies: + argparse "^1.0.2" + esprima "^2.6.0" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + integrity sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA== + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + integrity sha1-odePw6UEdMuAhF07O24dpJpEbo4= + +levn@~0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.2.5.tgz#ba8d339d0ca4a610e3a3f145b9caf48807155054" + integrity sha1-uo0znQykphDjo/FFucr0iAcVUFQ= + dependencies: + prelude-ls "~1.1.0" + type-check "~0.3.1" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +lodash._arraypool@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._arraypool/-/lodash._arraypool-2.4.1.tgz#e88eecb92e2bb84c9065612fd958a0719cd47f94" + integrity sha1-6I7suS4ruEyQZWEv2VigcZzUf5Q= + +lodash._basebind@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._basebind/-/lodash._basebind-2.4.1.tgz#e940b9ebdd27c327e0a8dab1b55916c5341e9575" + integrity sha1-6UC5690nwyfgqNqxtVkWxTQelXU= + dependencies: + lodash._basecreate "~2.4.1" + lodash._setbinddata "~2.4.1" + lodash._slice "~2.4.1" + lodash.isobject "~2.4.1" + +lodash._baseclone@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._baseclone/-/lodash._baseclone-2.4.1.tgz#30f823e57e17e3735d383bd62b60b387543b4186" + integrity sha1-MPgj5X4X43NdODvWK2Czh1Q7QYY= + dependencies: + lodash._getarray "~2.4.1" + lodash._releasearray "~2.4.1" + lodash._slice "~2.4.1" + lodash.assign "~2.4.1" + lodash.foreach "~2.4.1" + lodash.forown "~2.4.1" + lodash.isarray "~2.4.1" + lodash.isobject "~2.4.1" + +lodash._basecreate@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-2.4.1.tgz#f8e6f5b578a9e34e541179b56b8eeebf4a287e08" + integrity sha1-+Ob1tXip405UEXm1a47uv0oofgg= + dependencies: + lodash._isnative "~2.4.1" + lodash.isobject "~2.4.1" + lodash.noop "~2.4.1" + +lodash._basecreatecallback@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._basecreatecallback/-/lodash._basecreatecallback-2.4.1.tgz#7d0b267649cb29e7a139d0103b7c11fae84e4851" + integrity sha1-fQsmdknLKeehOdAQO3wR+uhOSFE= + dependencies: + lodash._setbinddata "~2.4.1" + lodash.bind "~2.4.1" + lodash.identity "~2.4.1" + lodash.support "~2.4.1" + +lodash._basecreatewrapper@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._basecreatewrapper/-/lodash._basecreatewrapper-2.4.1.tgz#4d31f2e7de7e134fbf2803762b8150b32519666f" + integrity sha1-TTHy595+E0+/KAN2K4FQsyUZZm8= + dependencies: + lodash._basecreate "~2.4.1" + lodash._setbinddata "~2.4.1" + lodash._slice "~2.4.1" + lodash.isobject "~2.4.1" + +lodash._createwrapper@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._createwrapper/-/lodash._createwrapper-2.4.1.tgz#51d6957973da4ed556e37290d8c1a18c53de1607" + integrity sha1-UdaVeXPaTtVW43KQ2MGhjFPeFgc= + dependencies: + lodash._basebind "~2.4.1" + lodash._basecreatewrapper "~2.4.1" + lodash._slice "~2.4.1" + lodash.isfunction "~2.4.1" + +lodash._getarray@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._getarray/-/lodash._getarray-2.4.1.tgz#faf1f7f810fa985a251c2187404481094839e5ee" + integrity sha1-+vH3+BD6mFolHCGHQESBCUg55e4= + dependencies: + lodash._arraypool "~2.4.1" + +lodash._isnative@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._isnative/-/lodash._isnative-2.4.1.tgz#3ea6404b784a7be836c7b57580e1cdf79b14832c" + integrity sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw= + +lodash._maxpoolsize@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._maxpoolsize/-/lodash._maxpoolsize-2.4.1.tgz#9d482f463b8e66afbe59c2c14edb117060172334" + integrity sha1-nUgvRjuOZq++WcLBTtsRcGAXIzQ= + +lodash._objecttypes@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz#7c0b7f69d98a1f76529f890b0cdb1b4dfec11c11" + integrity sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE= + +lodash._releasearray@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._releasearray/-/lodash._releasearray-2.4.1.tgz#a6139630d76d1536b07ddc80962889b082f6a641" + integrity sha1-phOWMNdtFTawfdyAliiJsIL2pkE= + dependencies: + lodash._arraypool "~2.4.1" + lodash._maxpoolsize "~2.4.1" + +lodash._setbinddata@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._setbinddata/-/lodash._setbinddata-2.4.1.tgz#f7c200cd1b92ef236b399eecf73c648d17aa94d2" + integrity sha1-98IAzRuS7yNrOZ7s9zxkjReqlNI= + dependencies: + lodash._isnative "~2.4.1" + lodash.noop "~2.4.1" + +lodash._shimkeys@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz#6e9cc9666ff081f0b5a6c978b83e242e6949d203" + integrity sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM= + dependencies: + lodash._objecttypes "~2.4.1" + +lodash._slice@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash._slice/-/lodash._slice-2.4.1.tgz#745cf41a53597b18f688898544405efa2b06d90f" + integrity sha1-dFz0GlNZexj2iImFREBe+isG2Q8= + +lodash.assign@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-2.4.1.tgz#84c39596dd71181a97b0652913a7c9675e49b1aa" + integrity sha1-hMOVlt1xGBqXsGUpE6fJZ15Jsao= + dependencies: + lodash._basecreatecallback "~2.4.1" + lodash._objecttypes "~2.4.1" + lodash.keys "~2.4.1" + +lodash.bind@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.bind/-/lodash.bind-2.4.1.tgz#5d19fa005c8c4d236faf4742c7b7a1fcabe29267" + integrity sha1-XRn6AFyMTSNvr0dCx7eh/Kvikmc= + dependencies: + lodash._createwrapper "~2.4.1" + lodash._slice "~2.4.1" + +lodash.clonedeep@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-2.4.1.tgz#f29203b40b12fee0a45d3631648259bebabc7868" + integrity sha1-8pIDtAsS/uCkXTYxZIJZvrq8eGg= + dependencies: + lodash._baseclone "~2.4.1" + lodash._basecreatecallback "~2.4.1" + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= + +lodash.foreach@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.foreach/-/lodash.foreach-2.4.1.tgz#fe3fc3a34c86c94cab6f9522560282741e016309" + integrity sha1-/j/Do0yGyUyrb5UiVgKCdB4BYwk= + dependencies: + lodash._basecreatecallback "~2.4.1" + lodash.forown "~2.4.1" + +lodash.forown@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.forown/-/lodash.forown-2.4.1.tgz#78b41eafe1405fa966459ea4193fd502d084524b" + integrity sha1-eLQer+FAX6lmRZ6kGT/VAtCEUks= + dependencies: + lodash._basecreatecallback "~2.4.1" + lodash._objecttypes "~2.4.1" + lodash.keys "~2.4.1" + +lodash.identity@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.identity/-/lodash.identity-2.4.1.tgz#6694cffa65fef931f7c31ce86c74597cf560f4f1" + integrity sha1-ZpTP+mX++TH3wxzobHRZfPVg9PE= + +lodash.isarray@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-2.4.1.tgz#b52a326c1f62f6d7da73a31d5401df6ef44f0fa1" + integrity sha1-tSoybB9i9tfac6MdVAHfbvRPD6E= + dependencies: + lodash._isnative "~2.4.1" + +lodash.isfunction@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.isfunction/-/lodash.isfunction-2.4.1.tgz#2cfd575c73e498ab57e319b77fa02adef13a94d1" + integrity sha1-LP1XXHPkmKtX4xm3f6Aq3vE6lNE= + +lodash.isobject@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-2.4.1.tgz#5a2e47fe69953f1ee631a7eba1fe64d2d06558f5" + integrity sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU= + dependencies: + lodash._objecttypes "~2.4.1" + +lodash.keys@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-2.4.1.tgz#48dea46df8ff7632b10d706b8acb26591e2b3727" + integrity sha1-SN6kbfj/djKxDXBrissmWR4rNyc= + dependencies: + lodash._isnative "~2.4.1" + lodash._shimkeys "~2.4.1" + lodash.isobject "~2.4.1" + +lodash.noop@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.noop/-/lodash.noop-2.4.1.tgz#4fb54f816652e5ae10e8f72f717a388c7326538a" + integrity sha1-T7VPgWZS5a4Q6PcvcXo4jHMmU4o= + +lodash.support@~2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/lodash.support/-/lodash.support-2.4.1.tgz#320e0b67031673c28d7a2bb5d9e0331a45240515" + integrity sha1-Mg4LZwMWc8KNeiu12eAzGkUkBRU= + dependencies: + lodash._isnative "~2.4.1" + +lodash@^2.4.1, lodash@~2.4.1: + version "2.4.2" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-2.4.2.tgz#fadd834b9683073da179b3eae6d9c0d15053f73e" + integrity sha1-+t2DS5aDBz2hebPq5tnA0VBT9z4= + +lodash@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-1.0.2.tgz#8f57560c83b59fc270bd3d561b690043430e2551" + integrity sha1-j1dWDIO1n8JwvT1WG2kAQ0MOJVE= + +lodash@~4.17.10, lodash@~4.17.5: + version "4.17.11" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" + integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== + +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + integrity sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc= + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha1-W0b4AUft7leIcPCG0Eghz5mOVR8= + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lru-cache@2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + integrity sha1-bUUk6LlV+V1PW1iFHOId1y+06VI= + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0= + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + dependencies: + object-visit "^1.0.0" + +maxmin@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/maxmin/-/maxmin-0.2.2.tgz#a36ced8cc22e3abcd108cfb797a3a4b40275593f" + integrity sha1-o2ztjMIuOrzRCM+3l6OktAJ1WT8= + dependencies: + chalk "^0.5.0" + figures "^1.0.1" + gzip-size "^0.2.0" + pretty-bytes "^0.1.0" + +maxmin@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/maxmin/-/maxmin-1.1.0.tgz#71365e84a99dd8f8b3f7d5fde2f00d1e7f73be61" + integrity sha1-cTZehKmd2Piz99X94vANHn9zvmE= + dependencies: + chalk "^1.0.0" + figures "^1.0.1" + gzip-size "^1.0.0" + pretty-bytes "^1.0.0" + +meow@^3.1.0, meow@^3.3.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha1-cstmi0JSKCkKu/qFaJJYcwioAfs= + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + +method-override@2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/method-override/-/method-override-2.0.2.tgz#00531278c79789640bf27e97e26a3a5a1f7cca73" + integrity sha1-AFMSeMeXiWQL8n6X4mo6Wh98ynM= + dependencies: + methods "1.0.1" + parseurl "1.0.1" + vary "0.1.0" + +methods@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.0.1.tgz#75bc91943dffd7da037cf3eeb0ed73a0037cd14b" + integrity sha1-dbyRlD3/19oDfPPusO1zoAN80Us= + +micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +mime-types@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-1.0.0.tgz#6a7b4a6af2e7d92f97afe03f047c7801e8f001d2" + integrity sha1-antKavLn2S+Xr+A/BHx4AejwAdI= + +mime@1.2.11, mime@~1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.2.11.tgz#58203eed86e3a5ef17aed2b7d9ebd47f0a60dd10" + integrity sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA= + +minimatch@0.3: + version "0.3.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" + integrity sha1-J12O2qxPG7MyZHIInnlJyDlGmd0= + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +"minimatch@2 || 3", minimatch@^3.0.2, minimatch@^3.0.4, minimatch@~3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^2.0.1: + version "2.0.10" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-2.0.10.tgz#8d087c39c6b38c001b97fca7ce6d0e1e80afbac7" + integrity sha1-jQh8OcazjAAbl/ynzm0OHoCvusc= + dependencies: + brace-expansion "^1.0.0" + +minimatch@~0.2.11: + version "0.2.14" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.2.14.tgz#c74e780574f63c6f9a090e90efbe6ef53a6a756a" + integrity sha1-x054BXT2PG+aCQ6Q775u9TpqdWo= + dependencies: + lru-cache "2" + sigmund "~1.0.0" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= + +minimist@^1.1.3, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= + +minipass@^2.2.1, minipass@^2.3.4: + version "2.3.5" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.5.tgz#cacebe492022497f656b0f0f51e2682a9ed2d848" + integrity sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA== + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.2.1.tgz#dd27ea6136243c7c880684e8672bb3a45fd9b614" + integrity sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA== + dependencies: + minipass "^2.2.1" + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= + dependencies: + minimist "0.0.8" + +morgan@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.1.1.tgz#cde45d2e807ebcc439745846ea80392e69098146" + integrity sha1-zeRdLoB+vMQ5dFhG6oA5LmkJgUY= + dependencies: + bytes "1.0.0" + +mout@~0.9.0: + version "0.9.1" + resolved "https://registry.yarnpkg.com/mout/-/mout-0.9.1.tgz#84f0f3fd6acc7317f63de2affdcc0cee009b0477" + integrity sha1-hPDz/WrMcxf2PeKv/cwM7gCbBHc= + +ms@0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.6.2.tgz#d89c2124c6fdc1353d65a8b77bf1aac4b193708c" + integrity sha1-2JwhJMb9wTU9Zai3e/GqxLGTcIw= + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +multiparty@3.2.8: + version "3.2.8" + resolved "https://registry.yarnpkg.com/multiparty/-/multiparty-3.2.8.tgz#bde21301dad294286e155b2b60710c6ae04ae64f" + integrity sha1-veITAdrSlChuFVsrYHEMauBK5k8= + dependencies: + readable-stream "~1.1.9" + stream-counter "~0.2.0" + +nan@^2.9.2: + version "2.12.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.12.1.tgz#7b1aa193e9aa86057e3c7bbd0ac448e770925552" + integrity sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw== + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +needle@^2.2.1: + version "2.2.4" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.4.tgz#51931bff82533b1928b7d1d69e01f1b00ffd2a4e" + integrity sha512-HyoqEb4wr/rsoaIDfTH2aVL9nWtQqba2/HvMv+++m8u0dz808MaagKILxtfeSN7QU7nvbQ79zk3vYOJp9zsNEA== + dependencies: + debug "^2.1.2" + iconv-lite "^0.4.4" + sax "^1.2.4" + +negotiator@0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.4.6.tgz#f45faf9fa833ed3ca51250ea9a7ddfc4267a44b3" + integrity sha1-9F+vn6gz7TylElDqmn3fxCZ6RLM= + +next-tick@1: + version "1.0.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" + integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= + +node-pre-gyp@^0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" + integrity sha512-d1xFs+C/IPS8Id0qPTZ4bUT8wWryfR/OzzAFxweG+uLN85oPzyo2Iw6bVlLQ/JOdgNonXLCoRyqDzDWq4iw72A== + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00= + dependencies: + abbrev "1" + osenv "^0.1.4" + +nopt@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-2.0.0.tgz#ca7416f20a5e3f9c3b86180f96295fa3d0b52e0d" + integrity sha1-ynQW8gpeP5w7hhgPlilfo9C1Lg0= + dependencies: + abbrev "1" + +nopt@~3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + integrity sha1-xkZdvwirzU2zWTF/eaxopkayj/k= + dependencies: + abbrev "1" + +noptify@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/noptify/-/noptify-0.0.3.tgz#58f654a73d9753df0c51d9686dc92104a67f4bbb" + integrity sha1-WPZUpz2XU98MUdlobckhBKZ/S7s= + dependencies: + nopt "~2.0.0" + +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= + +npm-bundled@^1.0.1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" + integrity sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g== + +npm-packlist@^1.1.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.2.0.tgz#55a60e793e272f00862c7089274439a4cc31fc7f" + integrity sha512-7Mni4Z8Xkx0/oegoqlcao/JpPCPEMtUvsmB0q7mgvlMinykJLSRTYuFqoQLYgGY8biuxIeiHO+QNJKbCfljewQ== + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= + +object-assign@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-2.1.1.tgz#43c36e5d569ff8e4816c4efa8be02d26967c18aa" + integrity sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo= + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + dependencies: + isobject "^3.0.0" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + dependencies: + isobject "^3.0.1" + +on-headers@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-0.0.0.tgz#ee2817f8344325785cd9c2df2b242bbc17caf4c4" + integrity sha1-7igX+DRDJXhc2cLfKyQrvBfK9MQ= + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= + dependencies: + wrappy "1" + +open@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/open/-/open-0.0.5.tgz#42c3e18ec95466b6bf0dc42f3a2945c3f0cad8fc" + integrity sha1-QsPhjslUZra/DcQvOilFw/DK2Pw= + +optimist@~0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +optionator@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.5.0.tgz#b75a8995a2d417df25b6e4e3862f50aa88651368" + integrity sha1-t1qJlaLUF98ltuTjhi9QqohlE2g= + dependencies: + deep-is "~0.1.2" + fast-levenshtein "~1.0.0" + levn "~0.2.5" + prelude-ls "~1.1.1" + type-check "~0.3.1" + wordwrap "~0.0.2" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= + +os-tmpdir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= + +osenv@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.0.3.tgz#cd6ad8ddb290915ad9e22765576025d411f29cb6" + integrity sha1-zWrY3bKQkVrZ4idlV2Al1BHynLY= + +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g== + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +pako@~0.2.0: + version "0.2.9" + resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" + integrity sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU= + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= + dependencies: + error-ex "^1.2.0" + +parseurl@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.0.1.tgz#2e57dce6efdd37c3518701030944c22bf388b7b4" + integrity sha1-Llfc5u/dN8NRhwEDCUTCK/OIt7Q= + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= + dependencies: + pinkie-promise "^2.0.0" + +path-is-absolute@^1.0.0, path-is-absolute@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +pause@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" + integrity sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10= + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= + +portscanner@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/portscanner/-/portscanner-0.2.3.tgz#40d8adc92e01b205ab020aa16f0e386ac5ed1978" + integrity sha1-QNityS4BsgWrAgqhbw44asXtGXg= + dependencies: + async "0.1.15" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + +postcss-value-parser@^3.2.3: + version "3.3.1" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" + integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== + +postcss@^5.0.0, postcss@^5.2.16: + version "5.2.18" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-5.2.18.tgz#badfa1497d46244f6390f58b319830d9107853c5" + integrity sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg== + dependencies: + chalk "^1.1.3" + js-base64 "^2.1.9" + source-map "^0.5.6" + supports-color "^3.2.3" + +prelude-ls@~1.1.0, prelude-ls@~1.1.1, prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= + +pretty-bytes@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-0.1.2.tgz#cd90294d58a1ca4e8a5d0fb9c8225998881acf00" + integrity sha1-zZApTVihyk6KXQ+5yCJZmIgazwA= + +pretty-bytes@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-1.0.4.tgz#0a22e8210609ad35542f8c8d5d2159aff0751c84" + integrity sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ= + dependencies: + get-stdin "^4.0.1" + meow "^3.1.0" + +process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== + +qs@0.6.6: + version "0.6.6" + resolved "https://registry.yarnpkg.com/qs/-/qs-0.6.6.tgz#6e015098ff51968b8a3c819001d5f2c89bc4b107" + integrity sha1-bgFQmP9RlouKPIGQAdXyyJvEsQc= + +qs@~0.5.2: + version "0.5.6" + resolved "https://registry.yarnpkg.com/qs/-/qs-0.5.6.tgz#31b1ad058567651c526921506b9a8793911a0384" + integrity sha1-MbGtBYVnZRxSaSFQa5qHk5EaA4Q= + +range-parser@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.0.3.tgz#6872823535c692e2c2a0103826afd82c2e0ff175" + integrity sha1-aHKCNTXGkuLCoBA4Jq/YLC4P8XU= + +raw-body@1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-1.1.6.tgz#98e9df9a7e2df994931b7cdb4b2a6b9694a74f02" + integrity sha1-mOnfmn4t+ZSTG3zbSyprlpSnTwI= + dependencies: + bytes "1" + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.2.2: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + integrity sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readable-stream@~1.1.8, readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha1-fPTFTvZI44EwhMY23SB54WbAgdk= + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readdirp@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94= + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + +repeat-element@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.3.tgz#782e0d825c0c5a3bb39731f84efee6b742e6b1ce" + integrity sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g== + +repeat-string@^1.5.2, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo= + dependencies: + is-finite "^1.0.0" + +requirejs@~2.1.0: + version "2.1.22" + resolved "https://registry.yarnpkg.com/requirejs/-/requirejs-2.1.22.tgz#dd78fd2d34180c0d62c724b5b8aebc0664e0366f" + integrity sha1-3Xj9LTQYDA1ixyS1uK68BmTgNm8= + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + +resolve@~1.1.0: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= + +response-time@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/response-time/-/response-time-2.0.0.tgz#65cb39fd50de2f4ffdbdd285f1855966bd6fcb36" + integrity sha1-Zcs5/VDeL0/9vdKF8YVZZr1vyzY= + dependencies: + on-headers "0.0.0" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + integrity sha1-YTObci/mo1FWiSENJOFMlhSGE+8= + dependencies: + align-text "^0.1.1" + +rimraf@^2.6.1, rimraf@~2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" + integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== + dependencies: + glob "^7.1.3" + +rimraf@~2.2.1: + version "2.2.8" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" + integrity sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI= + +rndm@1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/rndm/-/rndm-1.2.0.tgz#f33fe9cfb52bbfd520aa18323bc65db110a1b76c" + integrity sha1-8z/pz7Urv9UgqhgyO8ZdsRCht2w= + +safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + +scmp@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/scmp/-/scmp-0.0.3.tgz#3648df2d7294641e7f78673ffc29681d9bad9073" + integrity sha1-NkjfLXKUZB5/eGc//CloHZutkHM= + +"semver@2 || 3 || 4 || 5", semver@^5.3.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" + integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== + +semver@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-2.3.2.tgz#b9848f25d6cf36333073ec9ef8856d42f1233e52" + integrity sha1-uYSPJdbPNjMwc+ye+IVtQvEjPlI= + +send@0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/send/-/send-0.4.3.tgz#9627b23b7707fbf6373831cac5793330b594b640" + integrity sha1-lieyO3cH+/Y3ODHKxXkzMLWUtkA= + dependencies: + debug "1.0.2" + escape-html "1.0.1" + finished "1.2.2" + fresh "0.2.2" + mime "1.2.11" + range-parser "~1.0.0" + +serve-favicon@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.0.1.tgz#4826975d9f173ca3a4158e9698161f75dec7afec" + integrity sha1-SCaXXZ8XPKOkFY6WmBYfdd7Hr+w= + dependencies: + fresh "0.2.2" + +serve-index@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.1.1.tgz#eadadd8fd07413add17a301c657f52fc05f19d2f" + integrity sha1-6trdj9B0E63RejAcZX9S/AXxnS8= + dependencies: + accepts "1.0.3" + batch "0.5.0" + +serve-static@1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.2.3.tgz#93cecbc340f079ecb8589281d1dc31c26c0cd158" + integrity sha1-k87Lw0Dweey4WJKB0dwxwmwM0Vg= + dependencies: + escape-html "1.0.1" + parseurl "1.0.1" + send "0.4.3" + +set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + integrity sha1-fbCPnT0i3H945Trzw79GZuzfzPE= + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + integrity sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +sigmund@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA= + +signal-exit@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0= + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== + dependencies: + atob "^2.1.1" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= + +source-map@0.4.x: + version "0.4.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.4.4.tgz#eba4f5da9c0dc999de68032d8b4f76173652036b" + integrity sha1-66T12pwNyZneaAMti092FzZSA2s= + dependencies: + amdefine ">=0.0.4" + +source-map@^0.5.6, source-map@~0.5.1: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= + +spdx-correct@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" + integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" + integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz#81c0ce8f21474756148bbb5f3bfc0f36bf15d76e" + integrity sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g== + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@^1.0.3: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" + integrity sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug== + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +stream-counter@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/stream-counter/-/stream-counter-0.2.0.tgz#ded266556319c8b0e222812b9cf3b26fa7d947de" + integrity sha1-3tJmVWMZyLDiIoErnPOyb6fZR94= + dependencies: + readable-stream "~1.1.8" + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2": + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ= + +string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.0.0.tgz#f78f68b5d0866c20b2c9b8c61b5298508dc8756f" + integrity sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow== + dependencies: + ansi-regex "^4.0.0" + +strip-ansi@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.3.0.tgz#25f48ea22ca79187f3174a4db8759347bb126220" + integrity sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA= + dependencies: + ansi-regex "^0.2.1" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8= + dependencies: + ansi-regex "^3.0.0" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= + dependencies: + is-utf8 "^0.2.0" + +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI= + dependencies: + get-stdin "^4.0.1" + +strip-json-comments@~1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-1.0.4.tgz#1e15fbcac97d3ee99bf2d73b4c656b082bbafb91" + integrity sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E= + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= + +supports-color@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-0.2.0.tgz#d92de2694eb3f67323973d7ae3d8b55b4c22190a" + integrity sha1-2S3iaU6z9nMjlz1649i1W0wiGQo= + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + +supports-color@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + integrity sha1-ZawFBLOVQXHYpklGsq48u4pfVPY= + dependencies: + has-flag "^1.0.0" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +tar@^4: + version "4.4.8" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" + integrity sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ== + dependencies: + chownr "^1.1.1" + fs-minipass "^1.2.5" + minipass "^2.3.4" + minizlib "^1.1.1" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.2" + +text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= + +tiny-lr-fork@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/tiny-lr-fork/-/tiny-lr-fork-0.0.5.tgz#1e99e1e2a8469b736ab97d97eefa98c71f76ed0a" + integrity sha1-Hpnh4qhGm3NquX2X7vqYxx927Qo= + dependencies: + debug "~0.7.0" + faye-websocket "~0.4.3" + noptify "~0.0.3" + qs "~0.5.2" + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha1-WIeWa7WCpFA6QetST301ARgVphM= + +type-check@~0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha1-WITKtRLPHTVeP7eE8wgEsrUg23I= + dependencies: + prelude-ls "~1.1.2" + +type-is@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.2.1.tgz#73d448080a4f1dd18acb1eefff62968c5b5d54a2" + integrity sha1-c9RICApPHdGKyx7v/2KWjFtdVKI= + dependencies: + mime-types "1.0.0" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= + +uglify-js@^2.4.0: + version "2.8.29" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.29.tgz#29c5733148057bb4e1f75df35b7a9cb72e6a59dd" + integrity sha1-KcVzMUgFe7Th913zW3qcty5qWd0= + dependencies: + source-map "~0.5.1" + yargs "~3.10.0" + optionalDependencies: + uglify-to-browserify "~1.0.0" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + integrity sha1-bgkk1r2mta/jSeOabWMoUKD4grc= + +uid2@0.0.3, uid2@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.3.tgz#483126e11774df2f71b8b639dcd799c376162b82" + integrity sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I= + +underscore.string@~3.3.4: + version "3.3.5" + resolved "https://registry.yarnpkg.com/underscore.string/-/underscore.string-3.3.5.tgz#fc2ad255b8bd309e239cbc5816fd23a9b7ea4023" + integrity sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg== + dependencies: + sprintf-js "^1.0.3" + util-deprecate "^1.0.2" + +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + integrity sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ= + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +upath@^1.0.5: + version "1.1.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" + integrity sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw== + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + +user-home@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/user-home/-/user-home-1.1.1.tgz#2b5be23a32b63a7c9deb8d0f28d485724a3df190" + integrity sha1-K1viOjK2Onyd640PKNSFcko98ZA= + +util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= + +util-extend@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/util-extend/-/util-extend-1.0.3.tgz#a7c216d267545169637b3b6edc6ca9119e2ff93f" + integrity sha1-p8IW0mdUUWljeztu3GypEZ4v+T8= + +utils-merge@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" + integrity sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg= + +validate-npm-package-license@^3.0.1: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +vary@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/vary/-/vary-0.1.0.tgz#df0945899e93c0cc5bd18cc8321d9d21e74f6176" + integrity sha1-3wlFiZ6TwMxb0YzIMh2dIedPYXY= + +vhost@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/vhost/-/vhost-1.0.0.tgz#654513f289a4f898aab745bbd633e40180c9c4c0" + integrity sha1-ZUUT8omk+Jiqt0W71jPkAYDJxMA= + +which@~1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== + dependencies: + string-width "^1.0.2 || 2" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + integrity sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0= + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + integrity sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8= + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= + +xml-escape@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/xml-escape/-/xml-escape-1.0.0.tgz#00963d697b2adf0c185c4e04e73174ba9b288eb2" + integrity sha1-AJY9aXsq3wwYXE4E5zF0upsojrI= + +yallist@^3.0.0, yallist@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" + integrity sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A== + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + integrity sha1-9+572FfdfB0tOMDnTvvWgdFDH9E= + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0" From f416c3349834f766cf22da27abc5eab04b6c43c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Sun, 20 Jan 2019 15:18:59 +0100 Subject: [PATCH 82/87] fix(travis): update nodejs, build process --- .travis.yml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/.travis.yml b/.travis.yml index 50cef3f..588a62d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: node_js -before_install: - - gem install sass - - npm install -g grunt-cli +node_js: + - "node" install: - - npm install -script: grunt + - yarn +script: node_modules/.bin/grunt From 0a05523dd15a340553204736fca1cacac474bfb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Sun, 20 Jan 2019 18:15:14 +0100 Subject: [PATCH 83/87] remove bower and jshashes --- Gruntfile.js | 2 +- README.md | 3 +- app.js | 26 +++--- bower.json | 36 -------- build.js | 2 +- index.html | 14 +-- lib/map/clientlayer.js | 9 +- package.json | 15 +++- scss/_leaflet.label.scss | 2 +- scss/_leaflet.scss | 2 +- tasks/build.js | 32 ++----- tasks/linting.js | 5 -- yarn.lock | 190 +++++++++++++++++++++++++++++++-------- 13 files changed, 206 insertions(+), 132 deletions(-) delete mode 100644 bower.json diff --git a/Gruntfile.js b/Gruntfile.js index b63ad56..ee52833 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -17,7 +17,7 @@ module.exports = function (grunt) { grunt.loadTasks("tasks") - grunt.registerTask("default", ["bower-install-simple", "lint", "saveRevision", "copy", "sass", "postcss", "requirejs"]) + grunt.registerTask("default", ["lint", "saveRevision", "copy", "sass", "postcss", "requirejs"]) grunt.registerTask("lint", ["eslint"]) grunt.registerTask("dev", ["default", "connect:server", "watch"]) } diff --git a/README.md b/README.md index cf65dca..9f9f06a 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,7 @@ HopGlass is a frontend for the [HopGlass Server](https://github.com/hopglass/hop # Dependencies -- npm -- bower +- yarn (recommended) or npm - grunt-cli - Sass (>= 3.2) diff --git a/app.js b/app.js index e848121..f63c931 100644 --- a/app.js +++ b/app.js @@ -1,20 +1,20 @@ require.config({ baseUrl: "lib", paths: { - "leaflet": "../bower_components/leaflet/dist/leaflet", - "leaflet.label": "../bower_components/Leaflet.label/dist/leaflet.label", - "leaflet.providers": "../bower_components/leaflet-providers/leaflet-providers", - "chroma-js": "../bower_components/chroma-js/chroma.min", - "moment": "../bower_components/moment/min/moment-with-locales.min", - "tablesort": "../bower_components/tablesort/tablesort.min", - "tablesort.numeric": "../bower_components/tablesort/src/sorts/tablesort.numeric", - "d3": "../bower_components/d3/d3.min", - "numeral": "../bower_components/numeraljs/min/numeral.min", - "numeral-intl": "../bower_components/numeraljs/min/languages.min", - "virtual-dom": "../bower_components/virtual-dom/dist/virtual-dom", - "rbush": "../bower_components/rbush/rbush", + "leaflet": "../node_modules/leaflet/dist/leaflet", + "leaflet.label": "../node_modules/leaflet-label/dist/leaflet.label", + "leaflet.providers": "../node_modules/leaflet-providers/leaflet-providers", + "chroma-js": "../node_modules/chroma-js/chroma.min", + "moment": "../node_modules/moment/min/moment-with-locales.min", + "tablesort": "../node_modules/tablesort/tablesort.min", + "tablesort.numeric": "../node_modules/tablesort/src/sorts/tablesort.numeric", + "d3": "../node_modules/d3/d3.min", + "numeral": "../node_modules/numeraljs/min/numeral.min", + "numeral-intl": "../node_modules/numeraljs/min/languages.min", + "virtual-dom": "../node_modules/virtual-dom/dist/virtual-dom", + "rbush": "../node_modules/rbush/rbush", "helper": "../helper", - "jshashes": "../bower_components/jshashes/hashes" + "jshashes": "../node_modules/jshashes/hashes" }, shim: { "leaflet.label": ["leaflet"], diff --git a/bower.json b/bower.json deleted file mode 100644 index be1795a..0000000 --- a/bower.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "HopGlass", - "ignore": [ - "node_modules", - "bower_components", - "**/.*", - "test", - "tests" - ], - "dependencies": { - "Leaflet.label": "~0.2.1", - "chroma-js": "~0.6.1", - "leaflet": "~0.7.3", - "ionicons": "~2.0.1", - "moment": "~2.9.0", - "requirejs": "~2.1.16", - "tablesort": "https://github.com/tristen/tablesort.git#v3.0.2", - "roboto-slab-fontface": "*", - "es6-shim": "~0.27.1", - "almond": "~0.3.1", - "r.js": "~2.1.16", - "d3": "~3.5.5", - "numeraljs": "~1.5.3", - "roboto-fontface": "~0.3.0", - "virtual-dom": "~2.0.1", - "leaflet-providers": "~1.0.27", - "rbush": "https://github.com/mourner/rbush.git#~1.3.5", - "jshashes": "~1.0.5" - }, - "authors": [ - "Milan Pässler ", - "Nils Schneider " - ], - "license": "AGPL3", - "private": true -} diff --git a/build.js b/build.js index 021929a..7412f0c 100644 --- a/build.js +++ b/build.js @@ -1,6 +1,6 @@ ({ baseUrl: "lib", - name: "../bower_components/almond/almond", + name: "../node_modules/almond/almond", mainConfigFile: "app.js", include: "../app", wrap: true, diff --git a/index.html b/index.html index fcbf858..7a0a5a4 100644 --- a/index.html +++ b/index.html @@ -3,14 +3,14 @@ - - - - - + + + + + - - + + diff --git a/lib/map/clientlayer.js b/lib/map/clientlayer.js index c3fb439..4d8b9f8 100644 --- a/lib/map/clientlayer.js +++ b/lib/map/clientlayer.js @@ -1,15 +1,12 @@ -define(["leaflet", "jshashes"], - function (L, jsHashes) { - var MD5 = new jsHashes.MD5() - +define(["leaflet"], + function (L) { return L.TileLayer.Canvas.extend({ setData: function (d) { this.data = d //pre-calculate start angles this.data.all().forEach(function (d) { - var hash = MD5.hex(d.node.nodeinfo.node_id) - d.startAngle = (parseInt(hash.substr(0, 2), 16) / 255) * 2 * Math.PI + d.startAngle = (parseInt(d.node.nodeinfo.node_id.substr(10, 2), 16) / 255) * 2 * Math.PI }) this.redraw() }, diff --git a/package.json b/package.json index 796da69..de8ebe1 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,6 @@ "autoprefixer": "^6.3.3", "dart-sass": "^1.16.1", "grunt": "^1.0.3", - "grunt-bower-install-simple": "^1.1.2", "grunt-check-dependencies": "^0.6.0", "grunt-contrib-clean": "^0.6.0", "grunt-contrib-connect": "^0.8.0", @@ -21,6 +20,20 @@ "grunt-postcss": "^0.7.2", "grunt-sass": "^3.0.2" }, + "dependencies": { + "almond": "^0.3.3", + "chroma-js": "^0.7.8", + "d3": "^3.5.17", + "leaflet": "^0.7.7", + "leaflet-label": "^0.2.1-0", + "leaflet-providers": "^1.5.0", + "moment": "^2.23.0", + "numeraljs": "^1.5.6", + "rbush": "^1.4.3", + "requirejs": "^2.3.2", + "tablesort": "3.0.2", + "virtual-dom": "^2.1.1" + }, "eslintConfig": { "env": { "browser": true, diff --git a/scss/_leaflet.label.scss b/scss/_leaflet.label.scss index b96f885..4bdebf9 120000 --- a/scss/_leaflet.label.scss +++ b/scss/_leaflet.label.scss @@ -1 +1 @@ -../bower_components/Leaflet.label/dist/leaflet.label.css \ No newline at end of file +../node_modules/leaflet-label/dist/leaflet.label.css \ No newline at end of file diff --git a/scss/_leaflet.scss b/scss/_leaflet.scss index afb51f7..047e9d7 120000 --- a/scss/_leaflet.scss +++ b/scss/_leaflet.scss @@ -1 +1 @@ -../bower_components/leaflet/dist/leaflet.css \ No newline at end of file +../node_modules/leaflet/dist/leaflet.css \ No newline at end of file diff --git a/tasks/build.js b/tasks/build.js index 0843dfe..6a923ac 100644 --- a/tasks/build.js +++ b/tasks/build.js @@ -1,6 +1,6 @@ module.exports = function(grunt) { grunt.config.merge({ - bowerdir: "bower_components", + nodedir: "node_modules", copy: { html: { options: { @@ -22,7 +22,7 @@ module.exports = function(grunt) { src: ["es6-shim/es6-shim.min.js", "es6-shim/es6-shim.map"], expand: true, - cwd: "bower_components/", + cwd: "node_modules/", dest: "build/vendor/" }, robotoSlab: { @@ -31,7 +31,7 @@ module.exports = function(grunt) { ], expand: true, dest: "build/", - cwd: "bower_components/roboto-slab-fontface" + cwd: "node_modules/roboto-slab-fontface" }, roboto: { src: [ "fonts/*", @@ -39,7 +39,7 @@ module.exports = function(grunt) { ], expand: true, dest: "build/", - cwd: "bower_components/roboto-fontface" + cwd: "node_modules/roboto-fontface" }, ionicons: { src: [ "fonts/*", @@ -47,13 +47,13 @@ module.exports = function(grunt) { ], expand: true, dest: "build/", - cwd: "bower_components/ionicons/" + cwd: "node_modules/ionicons/" }, leafletImages: { src: [ "images/*" ], expand: true, dest: "build/", - cwd: "bower_components/leaflet/dist/" + cwd: "node_modules/leaflet/dist/" } }, sass: { @@ -84,31 +84,18 @@ module.exports = function(grunt) { cssmin: { target: { files: { - "build/style.css": [ "bower_components/leaflet/dist/leaflet.css", - "bower_components/Leaflet.label/dist/leaflet.label.css", + "build/style.css": [ "node_modules/leaflet/dist/leaflet.css", + "node_modules/leaflet-label/dist/leaflet.label.css", "style.css" ] } } }, - "bower-install-simple": { - options: { - directory: "<%=bowerdir%>", - color: true, - interactive: false, - production: true - }, - "prod": { - options: { - production: true - } - } - }, requirejs: { compile: { options: { baseUrl: "lib", - name: "../bower_components/almond/almond", + name: "../node_modules/almond/almond", mainConfigFile: "app.js", include: "../app", wrap: true, @@ -119,7 +106,6 @@ module.exports = function(grunt) { } }) - grunt.loadNpmTasks("grunt-bower-install-simple") grunt.loadNpmTasks("grunt-contrib-copy") grunt.loadNpmTasks("grunt-contrib-requirejs") grunt.loadNpmTasks("grunt-sass") diff --git a/tasks/linting.js b/tasks/linting.js index a05bce0..e6f2df7 100644 --- a/tasks/linting.js +++ b/tasks/linting.js @@ -4,11 +4,6 @@ module.exports = function (grunt) { options: { install: true }, - bower: { - options: { - packageManager: "bower" - } - }, npm: {} }, eslint: { diff --git a/yarn.lock b/yarn.lock index 1f00f87..e049dd8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -24,6 +24,11 @@ align-text@^0.1.1, align-text@^0.1.3: longest "^1.0.1" repeat-string "^1.5.2" +almond@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/almond/-/almond-0.3.3.tgz#a0e7c95ac7624d6417b4494b1e68bff693168a20" + integrity sha1-oOfJWsdiTWQXtElLHmi/9pMWiiA= + amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" @@ -44,11 +49,6 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= -ansi-regex@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.0.0.tgz#70de791edf021404c3fd615aa89118ae0432e5a9" - integrity sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w== - ansi-styles@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.1.0.tgz#eaecbf66cd706882760b2f4691582b8f55d7a7de" @@ -219,11 +219,6 @@ bower-config@^0.5.2: optimist "~0.6.0" osenv "0.0.3" -bower@1.8.4: - version "1.8.4" - resolved "https://registry.yarnpkg.com/bower/-/bower-1.8.4.tgz#e7876a076deb8137f7d06525dc5e8c66db82f28a" - integrity sha1-54dqB23rgTf30GUl3F6MZtuC8oo= - brace-expansion@^1.0.0, brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -248,6 +243,11 @@ braces@^2.3.0, braces@^2.3.1: split-string "^3.0.2" to-regex "^3.0.1" +browser-split@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/browser-split/-/browser-split-0.0.1.tgz#7b097574f8e3ead606fb4664e64adfdda2981a93" + integrity sha1-ewl1dPjj6tYG+0Zk5krf3aKYGpM= + browserify-zlib@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d" @@ -316,6 +316,11 @@ camelcase@^2.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" integrity sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8= +camelize@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/camelize/-/camelize-1.0.0.tgz#164a5483e630fa4321e5af07020e531831b2609b" + integrity sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs= + caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: version "1.0.30000929" resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000929.tgz#f18c557b9cbf33e2787134c915b82e3ed3331b87" @@ -329,15 +334,6 @@ center-align@^0.1.1: align-text "^0.1.3" lazy-cache "^1.0.3" -chalk@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" - integrity sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - chalk@^0.5.0, chalk@^0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.5.1.tgz#663b3a648b68b55d04690d49167aa837858f2174" @@ -405,6 +401,11 @@ chownr@^1.1.1: resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.1.tgz#54726b8b8fff4df053c42187e801fb4412df1494" integrity sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g== +chroma-js@^0.7.8: + version "0.7.8" + resolved "https://registry.yarnpkg.com/chroma-js/-/chroma-js-0.7.8.tgz#4765881b3cc368a571677917e81b5cd3ff041d40" + integrity sha1-R2WIGzzDaKVxZ3kX6Btc0/8EHUA= + class-utils@^0.3.5: version "0.3.6" resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" @@ -611,6 +612,11 @@ currently-unhandled@^0.4.1: dependencies: array-find-index "^1.0.1" +d3@^3.5.17: + version "3.5.17" + resolved "https://registry.yarnpkg.com/d3/-/d3-3.5.17.tgz#bc46748004378b21a360c9fc7cf5231790762fb8" + integrity sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g= + d@1: version "1.0.0" resolved "https://registry.yarnpkg.com/d/-/d-1.0.0.tgz#754bb5bfe55451da69a58b94d45f4c5b0462d58f" @@ -729,6 +735,11 @@ doctrine@^0.6.2: esutils "^1.1.6" isarray "0.0.1" +dom-walk@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" + integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg= + ee-first@1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.0.3.tgz#6c98c4089abecb5a7b85c1ac449aa603d3b3dabe" @@ -746,6 +757,15 @@ error-ex@^1.2.0: dependencies: is-arrayish "^0.2.1" +error@^4.3.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/error/-/error-4.4.0.tgz#bf69ff251fb4a279c19adccdaa6b61e90d9bf12a" + integrity sha1-v2n/JR+0onnBmtzNqmth6Q2b8So= + dependencies: + camelize "^1.0.0" + string-template "~0.2.0" + xtend "~4.0.0" + errorhandler@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/errorhandler/-/errorhandler-1.0.2.tgz#587d47bbbbc48cffe132c3acda7215c902558108" @@ -920,6 +940,13 @@ esutils@^1.1.6: resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.1.6.tgz#c01ccaa9ae4b897c6d0c3e210ae52f3c7a844375" integrity sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U= +ev-store@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/ev-store/-/ev-store-7.0.0.tgz#1ab0c7f82136505dd74b31d17701cb2be6d26558" + integrity sha1-GrDH+CE2UF3XSzHRdwHLK+bSZVg= + dependencies: + individual "^3.0.0" + event-emitter@~0.3.5: version "0.3.5" resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" @@ -1184,6 +1211,14 @@ glob@~7.0.0: once "^1.3.0" path-is-absolute "^1.0.0" +global@^4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/global/-/global-4.3.2.tgz#e76989268a6c74c38908b1305b10fc0e394e9d0f" + integrity sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8= + dependencies: + min-document "^2.19.0" + process "~0.5.1" + globals@^6.1.0: version "6.4.1" resolved "https://registry.yarnpkg.com/globals/-/globals-6.4.1.tgz#8498032b3b6d1cc81eebc5f79690d8fe29fabf4f" @@ -1218,15 +1253,6 @@ graceful-fs@~2.0.0: resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= -grunt-bower-install-simple@^1.1.2: - version "1.2.7" - resolved "https://registry.yarnpkg.com/grunt-bower-install-simple/-/grunt-bower-install-simple-1.2.7.tgz#9442b48a1d9abafa0b3530c82344432ea6cb5d40" - integrity sha512-5we1xo8In1ZnWxN73YhttAb25ya1U8VbEa71Ep2v2SMP61aZaa2JZsG04jZaN26zyI/Dbrxj3aKWmLAuN4/MeA== - dependencies: - bower "1.8.4" - chalk "2.4.1" - strip-ansi "5.0.0" - grunt-check-dependencies@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/grunt-check-dependencies/-/grunt-check-dependencies-0.6.0.tgz#f7206a3a61041a21cd273b86e3a52cbee974ea74" @@ -1530,6 +1556,11 @@ indent-string@^2.1.0: dependencies: repeating "^2.0.0" +individual@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/individual/-/individual-3.0.0.tgz#e7ca4f85f8957b018734f285750dc22ec2f9862d" + integrity sha1-58pPhfiVewGHNPKFdQ3CLsL5hi0= + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -1680,6 +1711,11 @@ is-number@^3.0.0: dependencies: kind-of "^3.0.2" +is-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + integrity sha1-iVJojF7C/9awPsyF52ngKQMINHA= + is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -1774,6 +1810,21 @@ lazy-cache@^1.0.3: resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" integrity sha1-odePw6UEdMuAhF07O24dpJpEbo4= +leaflet-label@^0.2.1-0: + version "0.2.1-0" + resolved "https://registry.yarnpkg.com/leaflet-label/-/leaflet-label-0.2.1-0.tgz#b91a678a4d78ac4c47cb230d3926254fd2a7e612" + integrity sha1-uRpnik14rExHyyMNOSYlT9Kn5hI= + +leaflet-providers@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/leaflet-providers/-/leaflet-providers-1.5.0.tgz#06d598231ef36f8d0566c219cedf18cef2ff80f5" + integrity sha512-btncloSyOHrgYNexoz2dRpCl+U9iDQME91RsOWQWNAD9jQUPAkq9mxuTvL/O9VOwrqcEtzhvuHBHIOacJAZDxQ== + +leaflet@^0.7.7: + version "0.7.7" + resolved "https://registry.yarnpkg.com/leaflet/-/leaflet-0.7.7.tgz#1e352ba54e63d076451fa363c900890cb2cf75ee" + integrity sha1-HjUrpU5j0HZFH6NjyQCJDLLPde4= + levn@~0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/levn/-/levn-0.2.5.tgz#ba8d339d0ca4a610e3a3f145b9caf48807155054" @@ -2132,6 +2183,13 @@ mime@1.2.11, mime@~1.2.11: resolved "https://registry.yarnpkg.com/mime/-/mime-1.2.11.tgz#58203eed86e3a5ef17aed2b7d9ebd47f0a60dd10" integrity sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA= +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU= + dependencies: + dom-walk "^0.1.0" + minimatch@0.3: version "0.3.0" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" @@ -2207,6 +2265,11 @@ mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: dependencies: minimist "0.0.8" +moment@^2.23.0: + version "2.23.0" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.23.0.tgz#759ea491ac97d54bac5ad776996e2a58cc1bc225" + integrity sha512-3IE39bHVqFbWWaPOMHZF98Q9c3LDKGTmypMiTM2QygGXXElkFWIH7GxfmlwmY2vwa+wmNsoYZmG2iusf1ZjJoA== + morgan@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.1.1.tgz#cde45d2e807ebcc439745846ea80392e69098146" @@ -2278,6 +2341,11 @@ next-tick@1: resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.0.0.tgz#ca86d1fe8828169b0120208e3dc8424b9db8342c" integrity sha1-yobR/ogoFpsBICCOPchCS524NCw= +next-tick@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-0.2.2.tgz#75da4a927ee5887e39065880065b7336413b310d" + integrity sha1-ddpKkn7liH45BliABltzNkE7MQ0= + node-pre-gyp@^0.10.0: version "0.10.3" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" @@ -2378,6 +2446,11 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= +numeraljs@^1.5.6: + version "1.5.6" + resolved "https://registry.yarnpkg.com/numeraljs/-/numeraljs-1.5.6.tgz#91ac1901578a42657b877583a28b5ea040a83271" + integrity sha1-kawZAVeKQmV7h3WDooteoECoMnE= + object-assign@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-2.1.1.tgz#43c36e5d569ff8e4816c4efa8be02d26967c18aa" @@ -2591,6 +2664,11 @@ process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" integrity sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw== +process@~0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" + integrity sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8= + qs@0.6.6: version "0.6.6" resolved "https://registry.yarnpkg.com/qs/-/qs-0.6.6.tgz#6e015098ff51968b8a3c819001d5f2c89bc4b107" @@ -2613,6 +2691,11 @@ raw-body@1.1.6: dependencies: bytes "1" +rbush@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/rbush/-/rbush-1.4.3.tgz#7874e2d38911d2719ea27731d32445da5ec4394c" + integrity sha1-eHTi04kR0nGeoncx0yRF2l7EOUw= + rc@^1.2.7: version "1.2.8" resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" @@ -2710,6 +2793,11 @@ repeating@^2.0.0: dependencies: is-finite "^1.0.0" +requirejs@^2.3.2: + version "2.3.6" + resolved "https://registry.yarnpkg.com/requirejs/-/requirejs-2.3.6.tgz#e5093d9601c2829251258c0b9445d4d19fa9e7c9" + integrity sha512-ipEzlWQe6RK3jkzikgCupiTbTvm4S0/CAU5GlgptkN5SO6F3u0UD0K18wy6ErDqiCyP4J4YYe1HuAShvsxePLg== + requirejs@~2.1.0: version "2.1.22" resolved "https://registry.yarnpkg.com/requirejs/-/requirejs-2.1.22.tgz#dd78fd2d34180c0d62c724b5b8aebc0664e0366f" @@ -2985,6 +3073,11 @@ stream-counter@~0.2.0: dependencies: readable-stream "~1.1.8" +string-template@~0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" + integrity sha1-QpMuWYo1LQH8IuwzZ9nYTuxsmt0= + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -3014,13 +3107,6 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -strip-ansi@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.0.0.tgz#f78f68b5d0866c20b2c9b8c61b5298508dc8756f" - integrity sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow== - dependencies: - ansi-regex "^4.0.0" - strip-ansi@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.3.0.tgz#25f48ea22ca79187f3174a4db8759347bb126220" @@ -3090,6 +3176,11 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" +tablesort@3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/tablesort/-/tablesort-3.0.2.tgz#8fea0aff8f167bc4415af6c616018188f09a7380" + integrity sha1-j+oK/48We8RBWvbGFgGBiPCac4A= + tar@^4: version "4.4.8" resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.8.tgz#b19eec3fde2a96e64666df9fdb40c5ca1bc3747d" @@ -3266,6 +3357,20 @@ vhost@1.0.0: resolved "https://registry.yarnpkg.com/vhost/-/vhost-1.0.0.tgz#654513f289a4f898aab745bbd633e40180c9c4c0" integrity sha1-ZUUT8omk+Jiqt0W71jPkAYDJxMA= +virtual-dom@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/virtual-dom/-/virtual-dom-2.1.1.tgz#80eda2d481b9ede0c049118cefcb4a05f21d1375" + integrity sha1-gO2i1IG57eDASRGM78tKBfIdE3U= + dependencies: + browser-split "0.0.1" + error "^4.3.0" + ev-store "^7.0.0" + global "^4.3.0" + is-object "^1.0.1" + next-tick "^0.2.2" + x-is-array "0.1.0" + x-is-string "0.1.0" + which@~1.3.0: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" @@ -3300,11 +3405,26 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= +x-is-array@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/x-is-array/-/x-is-array-0.1.0.tgz#de520171d47b3f416f5587d629b89d26b12dc29d" + integrity sha1-3lIBcdR7P0FvVYfWKbidJrEtwp0= + +x-is-string@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" + integrity sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI= + xml-escape@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/xml-escape/-/xml-escape-1.0.0.tgz#00963d697b2adf0c185c4e04e73174ba9b288eb2" integrity sha1-AJY9aXsq3wwYXE4E5zF0upsojrI= +xtend@~4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + integrity sha1-pcbVMr5lbiPbgg77lDofBJmNY68= + yallist@^3.0.0, yallist@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.3.tgz#b4b049e314be545e3ce802236d6cd22cd91c3de9" From a971dcfeedd746e6bb8b4613ea7f4fb235753691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Sun, 20 Jan 2019 20:21:17 +0100 Subject: [PATCH 84/87] update installation instructions --- README.md | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 9f9f06a..111fade 100644 --- a/README.md +++ b/README.md @@ -14,28 +14,32 @@ HopGlass is a frontend for the [HopGlass Server](https://github.com/hopglass/hop # Dependencies +- NodeJS - yarn (recommended) or npm -- grunt-cli -- Sass (>= 3.2) # Installing dependencies Install npm package-manager. On Debian-like systems run: - sudo apt-get install npm + sudo apt-get install nodejs -On Mac you have to install only npm via brew and sass +**Note:** The official Debian packages for NodeJS are quite old, you might want to check at [NodeSource](https://github.com/nodesource/distributions/blob/master/README.md) for current binaries installable with your distribution's package manager. + +On Mac you can install nodejs and yarn via brew: /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" brew install node - npm install node-sass + brew install yarn + +On Arch Linux you can install nodejs and yarn via pacman: + + sudo pacman -S nodejs yarn Execute these commands on your server as a normal user to prepare the dependencies: git clone https://github.com/hopglass/hopglass cd hopglass - npm install - npm install grunt-cli + yarn install # or `npm install` # Building From 420be21fa5e671f11ac884c943740b46a2b49e90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Thu, 24 Jan 2019 00:26:00 +0100 Subject: [PATCH 85/87] add version number --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index de8ebe1..b540825 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,6 @@ { "name": "hopglass", + "version": "1.0.0", "scripts": { "test": "node -e \"require('grunt').cli()\" '' clean lint" }, From fe17e32886b62792a3b9683aca3470af2ce1628f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Milan=20P=C3=A4ssler?= Date: Sat, 26 Jan 2019 04:11:47 +0100 Subject: [PATCH 86/87] fix: roboto and ionicons --- html/index.html | 4 ++-- index.html | 4 ++-- package.json | 2 ++ scss/main.scss | 2 +- tasks/build.js | 16 +++++----------- yarn.lock | 10 ++++++++++ 6 files changed, 22 insertions(+), 16 deletions(-) diff --git a/html/index.html b/html/index.html index 76bc02d..e834814 100644 --- a/html/index.html +++ b/html/index.html @@ -4,8 +4,8 @@ - - + + diff --git a/index.html b/index.html index 7a0a5a4..1fdb406 100644 --- a/index.html +++ b/index.html @@ -3,8 +3,8 @@ - - + + diff --git a/package.json b/package.json index b540825..7ba6584 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "almond": "^0.3.3", "chroma-js": "^0.7.8", "d3": "^3.5.17", + "ionicons": "^2.0.1", "leaflet": "^0.7.7", "leaflet-label": "^0.2.1-0", "leaflet-providers": "^1.5.0", @@ -32,6 +33,7 @@ "numeraljs": "^1.5.6", "rbush": "^1.4.3", "requirejs": "^2.3.2", + "roboto-fontface": "^0.10.0", "tablesort": "3.0.2", "virtual-dom": "^2.1.1" }, diff --git a/scss/main.scss b/scss/main.scss index 47cbed9..2719709 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -70,7 +70,7 @@ $buttondistance: 12pt; body { margin: 0; padding: 0; - font-family: 'Roboto Slab', serif; + font-family: 'Roboto-Slab', serif; font-size: 11pt; color: #333; } diff --git a/tasks/build.js b/tasks/build.js index 6a923ac..f74c4e2 100644 --- a/tasks/build.js +++ b/tasks/build.js @@ -25,21 +25,15 @@ module.exports = function(grunt) { cwd: "node_modules/", dest: "build/vendor/" }, - robotoSlab: { - src: [ "fonts/*", - "roboto-slab-fontface.css" - ], - expand: true, - dest: "build/", - cwd: "node_modules/roboto-slab-fontface" - }, roboto: { - src: [ "fonts/*", - "roboto-fontface.css" + src: [ "fonts/roboto/*", + "fonts/roboto-slab/*", + "css/roboto/roboto-fontface.css", + "css/roboto-slab/roboto-slab-fontface.css" ], expand: true, dest: "build/", - cwd: "node_modules/roboto-fontface" + cwd: "node_modules/roboto-fontface/" }, ionicons: { src: [ "fonts/*", diff --git a/yarn.lock b/yarn.lock index e049dd8..955d05b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1584,6 +1584,11 @@ ini@~1.3.0: resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== +ionicons@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ionicons/-/ionicons-2.0.1.tgz#ca398113293ea870244f538f0aabbd4b5b209a3e" + integrity sha1-yjmBEyk+qHAkT1OPCqu9S1sgmj4= + is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" @@ -2849,6 +2854,11 @@ rndm@1: resolved "https://registry.yarnpkg.com/rndm/-/rndm-1.2.0.tgz#f33fe9cfb52bbfd520aa18323bc65db110a1b76c" integrity sha1-8z/pz7Urv9UgqhgyO8ZdsRCht2w= +roboto-fontface@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/roboto-fontface/-/roboto-fontface-0.10.0.tgz#7eee40cfa18b1f7e4e605eaf1a2740afb6fd71b0" + integrity sha512-OlwfYEgA2RdboZohpldlvJ1xngOins5d7ejqnIBWr9KaMxsnBqotpptRXTyfNRLnFpqzX6sTDt+X+a+6udnU8g== + safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" From d70d3d7c5f6722354acb9b9c003224cd439f8c14 Mon Sep 17 00:00:00 2001 From: Alexander <7adietri@users.noreply.github.com> Date: Fri, 1 Feb 2019 06:49:24 +0100 Subject: [PATCH 87/87] Add Node.js LTS version in travis.yml (#105) --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 588a62d..8e0acfe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: node_js node_js: + - "lts/*" - "node" install: - yarn