improved chart
This commit is contained in:
parent
82b16964d0
commit
f05a80b3d7
|
@ -0,0 +1,6 @@
|
||||||
|
testenv
|
||||||
|
testdir
|
||||||
|
node_modules
|
||||||
|
testlink
|
||||||
|
dirview.egg-info
|
||||||
|
__pycache__
|
24
Dockerfile
24
Dockerfile
|
@ -1,7 +1,19 @@
|
||||||
FROM ubuntu:disco
|
FROM ubuntu:bionic
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN sed -i -E 's/(archive|security).ubuntu.com/192.168.1.142/' /etc/apt/sources.list && \
|
||||||
apt-get install -y python3-pip git
|
sed -i -E 's/^deb-src/# deb-src/' /etc/apt/sources.list && \
|
||||||
|
apt-get update && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive \
|
||||||
|
apt-get install -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" \
|
||||||
|
wget gpg git && \
|
||||||
|
wget -qO- http://artifact.scc.net.davepedu.com/repo/apt/extpython/dists/bionic/install | bash /dev/stdin && \
|
||||||
|
apt-get update && \
|
||||||
|
DEBIAN_FRONTEND=noninteractive \
|
||||||
|
apt-get install -y -o Dpkg::Options::="--force-confdef" -o Dpkg::Options::="--force-confold" \
|
||||||
|
extpython-python3.7 && \
|
||||||
|
apt-get clean autoclean && \
|
||||||
|
apt-get autoremove -y && \
|
||||||
|
rm -rf /var/lib/{apt,dpkg,cache,log}/
|
||||||
|
|
||||||
# RUN apt-get update && \
|
# RUN apt-get update && \
|
||||||
# apt-get install -y python3 git wget && \
|
# apt-get install -y python3 git wget && \
|
||||||
|
@ -12,7 +24,7 @@ RUN apt-get update && \
|
||||||
ADD . /tmp/code
|
ADD . /tmp/code
|
||||||
|
|
||||||
RUN cd /tmp/code && \
|
RUN cd /tmp/code && \
|
||||||
pip3 install -r requirements.txt && \
|
/opt/extpython/3.7/bin/pip3 install -r requirements.txt && \
|
||||||
python3 setup.py install
|
/opt/extpython/3.7/bin/python3 setup.py install
|
||||||
|
|
||||||
ENTRYPOINT ["dirviewd"]
|
ENTRYPOINT ["/opt/extpython/3.7/bin/dirviewd"]
|
||||||
|
|
412
assets/js/app.js
412
assets/js/app.js
|
@ -1,161 +1,9 @@
|
||||||
import * as d3 from 'd3'
|
import * as d3 from 'd3'
|
||||||
import * as voronoiMap from 'd3-voronoi-map'
|
import treemap from 'd3-hierarchy'
|
||||||
//import {voronoiTreemap} from 'd3-voronoi-treemap'
|
|
||||||
import randomColor from 'randomcolor'
|
import randomColor from 'randomcolor'
|
||||||
import chroma from 'chroma-js'
|
import filesize from 'filesize'
|
||||||
import roundTo from 'round-to'
|
// import chroma from 'chroma-js'
|
||||||
|
// import roundTo from 'round-to'
|
||||||
|
|
||||||
d3.voronoiTreemap = function() {
|
|
||||||
|
|
||||||
//begin: constants
|
|
||||||
var DEFAULT_CONVERGENCE_RATIO = 0.01;
|
|
||||||
var DEFAULT_MAX_ITERATION_COUNT = 50;
|
|
||||||
var DEFAULT_MIN_WEIGHT_RATIO = 0.01;
|
|
||||||
var DEFAULT_PRNG = Math.random;
|
|
||||||
//end: constants
|
|
||||||
|
|
||||||
/////// Inputs ///////
|
|
||||||
var clip = [
|
|
||||||
[0, 0],
|
|
||||||
[0, 1],
|
|
||||||
[1, 1],
|
|
||||||
[1, 0]
|
|
||||||
]; // clipping polygon
|
|
||||||
var extent = [
|
|
||||||
[0, 0],
|
|
||||||
[1, 1]
|
|
||||||
]; // extent of the clipping polygon
|
|
||||||
var size = [1, 1]; // [width, height] of the clipping polygon
|
|
||||||
var convergenceRatio = DEFAULT_CONVERGENCE_RATIO; // targeted allowed error ratio; default 0.01 stops computation when cell areas error <= 1% clipping polygon's area
|
|
||||||
var maxIterationCount = DEFAULT_MAX_ITERATION_COUNT; // maximum allowed iteration; stops computation even if convergence is not reached; use a large amount for a sole converge-based computation stop
|
|
||||||
var minWeightRatio = DEFAULT_MIN_WEIGHT_RATIO; // used to compute the minimum allowed weight; default 0.01 means 1% of max weight; handle near-zero weights, and leaves enought space for cell hovering
|
|
||||||
var prng = DEFAULT_PRNG; // pseudorandom number generator
|
|
||||||
|
|
||||||
//begin: internals
|
|
||||||
var _voronoiMap = voronoiMap.voronoiMap();
|
|
||||||
//end: internals
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////////
|
|
||||||
///////// API /////////
|
|
||||||
///////////////////////
|
|
||||||
|
|
||||||
function _voronoiTreemap(rootNode) {
|
|
||||||
_voronoiMap.weight(function (d) {
|
|
||||||
return d.value;
|
|
||||||
})
|
|
||||||
.convergenceRatio(convergenceRatio)
|
|
||||||
.maxIterationCount(maxIterationCount)
|
|
||||||
.minWeightRatio(minWeightRatio)
|
|
||||||
.prng(prng);
|
|
||||||
|
|
||||||
recurse(clip, rootNode);
|
|
||||||
};
|
|
||||||
|
|
||||||
_voronoiTreemap.convergenceRatio = function (_) {
|
|
||||||
if (!arguments.length) {
|
|
||||||
return convergenceRatio;
|
|
||||||
}
|
|
||||||
|
|
||||||
convergenceRatio = _;
|
|
||||||
return _voronoiTreemap;
|
|
||||||
};
|
|
||||||
|
|
||||||
_voronoiTreemap.maxIterationCount = function (_) {
|
|
||||||
if (!arguments.length) {
|
|
||||||
return maxIterationCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
maxIterationCount = _;
|
|
||||||
return _voronoiTreemap;
|
|
||||||
};
|
|
||||||
|
|
||||||
_voronoiTreemap.minWeightRatio = function (_) {
|
|
||||||
if (!arguments.length) {
|
|
||||||
return minWeightRatio;
|
|
||||||
}
|
|
||||||
|
|
||||||
minWeightRatio = _;
|
|
||||||
return _voronoiTreemap;
|
|
||||||
};
|
|
||||||
|
|
||||||
_voronoiTreemap.clip = function (_) {
|
|
||||||
if (!arguments.length) {
|
|
||||||
return clip;
|
|
||||||
}
|
|
||||||
|
|
||||||
//begin: use voronoiMap.clip() to handle clkip/extent/size computation and borderline input (non-counterclockwise, non-convex, ...)
|
|
||||||
_voronoiMap.clip(_);
|
|
||||||
//end: use voronoiMap.clip() to handle
|
|
||||||
clip = _voronoiMap.clip();
|
|
||||||
extent = _voronoiMap.extent();
|
|
||||||
size = _voronoiMap.size();
|
|
||||||
return _voronoiTreemap;
|
|
||||||
};
|
|
||||||
|
|
||||||
_voronoiTreemap.extent = function (_) {
|
|
||||||
if (!arguments.length) {
|
|
||||||
return extent;
|
|
||||||
}
|
|
||||||
|
|
||||||
//begin: use voronoiMap.extent() to handle clkip/extent/size computation
|
|
||||||
_voronoiMap.extent(_);
|
|
||||||
//end: use voronoiMap.clip() to handle
|
|
||||||
clip = _voronoiMap.clip();
|
|
||||||
extent = _voronoiMap.extent();
|
|
||||||
size = _voronoiMap.size();
|
|
||||||
return _voronoiTreemap;
|
|
||||||
};
|
|
||||||
|
|
||||||
_voronoiTreemap.size = function (_) {
|
|
||||||
if (!arguments.length) {
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
//begin: use voronoiMap.size()
|
|
||||||
_voronoiMap.size(_);
|
|
||||||
//end: use voronoiMap.clip() to handle clip/extent/size computation
|
|
||||||
clip = _voronoiMap.clip();
|
|
||||||
extent = _voronoiMap.extent();
|
|
||||||
size = _voronoiMap.size();
|
|
||||||
return _voronoiTreemap;
|
|
||||||
};
|
|
||||||
|
|
||||||
_voronoiTreemap.prng = function (_) {
|
|
||||||
if (!arguments.length) {
|
|
||||||
return prng;
|
|
||||||
}
|
|
||||||
|
|
||||||
prng = _;
|
|
||||||
return _voronoiTreemap;
|
|
||||||
};
|
|
||||||
|
|
||||||
///////////////////////
|
|
||||||
/////// Private ///////
|
|
||||||
///////////////////////
|
|
||||||
|
|
||||||
function recurse(clippingPolygon, node) {
|
|
||||||
var voronoiMapRes;
|
|
||||||
|
|
||||||
//assign polygon to node
|
|
||||||
node.polygon = clippingPolygon;
|
|
||||||
|
|
||||||
if (node.height != 0) {
|
|
||||||
//compute one-level Voronoi map of children
|
|
||||||
voronoiMapRes = _voronoiMap.clip(clippingPolygon)(node.children);
|
|
||||||
//begin: recurse on children
|
|
||||||
voronoiMapRes.polygons.forEach(function (cp) {
|
|
||||||
recurse(cp, cp.site.originalObject.data.originalData);
|
|
||||||
})
|
|
||||||
//end: recurse on children
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return _voronoiTreemap;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var DIR = 1
|
var DIR = 1
|
||||||
var FILE = 2
|
var FILE = 2
|
||||||
|
@ -163,7 +11,6 @@ var ROOT = 3
|
||||||
var LINK = 4
|
var LINK = 4
|
||||||
var SPECIAL = 5
|
var SPECIAL = 5
|
||||||
|
|
||||||
|
|
||||||
var cellColors = {}
|
var cellColors = {}
|
||||||
cellColors[DIR] = randomColor();
|
cellColors[DIR] = randomColor();
|
||||||
cellColors[FILE] = randomColor();
|
cellColors[FILE] = randomColor();
|
||||||
|
@ -171,217 +18,94 @@ cellColors[ROOT] = randomColor();
|
||||||
cellColors[LINK] = randomColor();
|
cellColors[LINK] = randomColor();
|
||||||
cellColors[SPECIAL] = randomColor();
|
cellColors[SPECIAL] = randomColor();
|
||||||
|
|
||||||
|
|
||||||
function boot() {
|
function boot() {
|
||||||
draw_graph();
|
prep_graph();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
boot: function(){boot();}
|
boot: function(){boot();}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function prep_graph() {
|
||||||
// function add_colors(data) {
|
d3.json("/chart.json?n=" + _node + "&depth=" + _graph_depth).then(draw_graph);
|
||||||
// data.color = randomColor();
|
|
||||||
// data.children.forEach(function(child){
|
|
||||||
// add_colors(child);
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
function draw_graph() {
|
|
||||||
// d3.json("/static/sampledata.json").then(function(rootData) {
|
|
||||||
d3.json("/chart.json?n=x&depth=2").then(function(rootData) {
|
|
||||||
initData();
|
|
||||||
// add_colors(rootData);
|
|
||||||
initLayout(rootData);
|
|
||||||
|
|
||||||
hierarchy = d3.hierarchy(rootData).sum(function(d){ return d.weight; });
|
|
||||||
// console.log(hierarchy)
|
|
||||||
_voronoiTreemap
|
|
||||||
.clip(circlingPolygon)
|
|
||||||
(hierarchy);
|
|
||||||
|
|
||||||
console.log(rootData);
|
|
||||||
drawTreemap(hierarchy);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//begin: constants
|
function can_click(d) {
|
||||||
var _2PI = 2*Math.PI;
|
return d.data.typ >= 0 && d.data.num_children > 0
|
||||||
//end: constants
|
|
||||||
|
|
||||||
//begin: layout conf.
|
|
||||||
var svgWidth = 1500,
|
|
||||||
svgHeight = 600,
|
|
||||||
margin = {top: 10, right: 10, bottom: 10, left: 10},
|
|
||||||
height = svgHeight - margin.top - margin.bottom,
|
|
||||||
width = svgWidth - margin.left - margin.right,
|
|
||||||
halfWidth = width/2,
|
|
||||||
halfHeight = height/2,
|
|
||||||
quarterWidth = width/4,
|
|
||||||
quarterHeight = height/4,
|
|
||||||
titleY = 20,
|
|
||||||
legendsMinY = height - 20,
|
|
||||||
treemapRadius = 0,
|
|
||||||
treemapCenter = [halfWidth, halfHeight+5];
|
|
||||||
//end: layout conf.
|
|
||||||
|
|
||||||
//begin: treemap conf.
|
|
||||||
var _voronoiTreemap = d3.voronoiTreemap();
|
|
||||||
var hierarchy, circlingPolygon;
|
|
||||||
//end: treemap conf.
|
|
||||||
|
|
||||||
//begin: drawing conf.
|
|
||||||
var fontScale = d3.scaleLinear();
|
|
||||||
//end: drawing conf.
|
|
||||||
|
|
||||||
//begin: reusable d3Selection
|
|
||||||
var svg, drawingArea, treemapContainer;
|
|
||||||
//end: reusable d3Selection
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function initData(rootData) {
|
|
||||||
circlingPolygon = computeCirclingPolygon(treemapRadius);
|
|
||||||
fontScale.domain([3, 20]).range([8, 20]).clamp(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function computeCirclingPolygon(radius) {
|
function draw_graph(data) {
|
||||||
/*var points = 60,
|
var chart_width = document.getElementsByTagName("body")[0].clientWidth;
|
||||||
increment = _2PI/points,
|
var chart_height = window.innerHeight * 0.5;
|
||||||
circlingPolygon = [];
|
|
||||||
|
|
||||||
for (var a=0, i=0; i<points; i++, a+=increment) {
|
var treemapLayout = d3.treemap().tile(d3.treemapBinary); // treemapBinary, treemapSquarify
|
||||||
circlingPolygon.push(
|
|
||||||
[radius + radius*Math.cos(a), radius + radius*Math.sin(a)]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
return circlingPolygon;*/
|
treemapLayout
|
||||||
|
.size([chart_width, chart_height])
|
||||||
|
.paddingTop(25)
|
||||||
|
.paddingRight(6)
|
||||||
|
.paddingBottom(6)
|
||||||
|
.paddingLeft(6)
|
||||||
|
|
||||||
return [[-svgWidth/2,-svgHeight/2], [svgWidth/2,-svgHeight/2], [svgWidth/2,svgHeight/2], [-svgWidth/2,svgHeight/2]]
|
|
||||||
};
|
|
||||||
|
|
||||||
function initLayout(rootData) {
|
d3.select('svg').attr('width', chart_width).attr('height', chart_height);
|
||||||
svg = d3.select("svg")
|
|
||||||
.attr("width", svgWidth)
|
|
||||||
.attr("height", svgHeight);
|
|
||||||
|
|
||||||
drawingArea = svg.append("g")
|
var root = d3.hierarchy(data);
|
||||||
.classed("drawingArea", true)
|
|
||||||
.attr("transform", "translate("+[margin.left,margin.top]+")");
|
|
||||||
|
|
||||||
treemapContainer = drawingArea.append("g")
|
treemapLayout(root);
|
||||||
.classed("treemap-container", true)
|
|
||||||
.attr("transform", "translate("+treemapCenter+")");
|
|
||||||
|
|
||||||
treemapContainer.append("path")
|
var nodes = d3.select('svg g.chart')
|
||||||
.classed("world", true)
|
.selectAll('g')
|
||||||
.attr("transform", "translate("+[-treemapRadius,-treemapRadius]+")")
|
.data(root.descendants())
|
||||||
.attr("d", "M"+circlingPolygon.join(",")+"Z");
|
.enter()
|
||||||
|
.append('g')
|
||||||
|
.attr('class', function(d) {return can_click(d) ? 'can-navigate' : 'no-navigate'})
|
||||||
|
.attr('transform', function(d) {return 'translate(' + [d.x0, d.y0] + ')'})
|
||||||
|
|
||||||
// drawTitle();
|
nodes
|
||||||
drawLegends(rootData);
|
.attr('width', function(d) { return d.x1 - d.x0; })
|
||||||
}
|
.attr('height', function(d) { return d.y1 - d.y0; })
|
||||||
|
|
||||||
// function drawTitle() {
|
// Create the colored rectangles
|
||||||
// drawingArea.append("text")
|
nodes
|
||||||
// .attr("id", "title")
|
.append('rect')
|
||||||
// .attr("transform", "translate("+[halfWidth, titleY]+")")
|
// .attr('fill', function(d){return randomColor()})
|
||||||
// .attr("text-anchor", "middle")
|
.attr('width', function(d) { return d.x1 - d.x0; })
|
||||||
// .text("The Global Economy by GDP (as of 01/2017)")
|
.attr('height', function(d) { return d.y1 - d.y0; })
|
||||||
// }
|
.attr('id', function(d) {return "node-" + d.data.id;})
|
||||||
|
.on('click', function(d){if(can_click(d)) window.location = "/?n=" + d.data.id;})
|
||||||
|
|
||||||
function drawLegends(rootData) {
|
// Create clip paths for clipping the contents of the nodes
|
||||||
var legendHeight = 13,
|
nodes
|
||||||
interLegend = 4,
|
.append('clipPath')
|
||||||
colorWidth = legendHeight*6,
|
.attr('id', function(d) {return "clip-" + d.data.id;})
|
||||||
continents = rootData.children.reverse();
|
.append('use')
|
||||||
|
.attr('href', function(d) {return "#node-" + d.data.id;})
|
||||||
|
|
||||||
var legendContainer = drawingArea.append("g")
|
|
||||||
.classed("legend", true)
|
|
||||||
.attr("transform", "translate("+[0, legendsMinY]+")");
|
|
||||||
|
|
||||||
var legends = legendContainer.selectAll(".legend")
|
// Name labels
|
||||||
.data(continents)
|
nodes
|
||||||
.enter();
|
.append('a')
|
||||||
|
.attr('href', function(d){if(can_click(d)) return "/?n=" + d.data.id;})
|
||||||
var legend = legends.append("g")
|
.append('text')
|
||||||
.classed("legend", true)
|
.attr('dx', 2)
|
||||||
.attr("transform", function(d,i){
|
.attr('dy', "1em")
|
||||||
return "translate("+[0, -i*(legendHeight+interLegend)]+")";
|
.attr('clip-path', function(d) {return "url(#clip-" + d.data.id + ")"})
|
||||||
})
|
.text(function(d) {
|
||||||
|
return d.data.name + (d.data.typ == DIR? "/":"")
|
||||||
legend.append("rect")
|
|
||||||
.classed("legend-color", true)
|
|
||||||
.attr("y", -legendHeight)
|
|
||||||
.attr("width", colorWidth)
|
|
||||||
.attr("height", legendHeight)
|
|
||||||
.style("fill", function(d){ return cellColors[d.typ]; });
|
|
||||||
legend.append("text")
|
|
||||||
.classed("tiny", true)
|
|
||||||
.attr("transform", "translate("+[colorWidth+5, -2]+")")
|
|
||||||
.text(function(d){ return d.name; });
|
|
||||||
|
|
||||||
legendContainer.append("text")
|
|
||||||
.attr("transform", "translate("+[0, -continents.length*(legendHeight+interLegend)-5]+")")
|
|
||||||
.text("Continents");
|
|
||||||
}
|
|
||||||
|
|
||||||
function format_percent(value) {
|
|
||||||
return roundTo(value * 100, 2) + "%";
|
|
||||||
}
|
|
||||||
|
|
||||||
function drawTreemap(hierarchy) {
|
|
||||||
var leaves=hierarchy.leaves();
|
|
||||||
|
|
||||||
var cells = treemapContainer.append("g")
|
|
||||||
.classed('cells', true)
|
|
||||||
.attr("transform", "translate("+[-treemapRadius,-treemapRadius]+")")
|
|
||||||
.selectAll(".cell")
|
|
||||||
.data(leaves)
|
|
||||||
.enter()
|
|
||||||
.append("path")
|
|
||||||
.classed("cell", true)
|
|
||||||
.attr("d", function(d){ return "M"+d.polygon.join(",")+"z"; })
|
|
||||||
.style("fill", function(d){
|
|
||||||
return cellColors[d.data.typ];
|
|
||||||
});
|
|
||||||
|
|
||||||
var labels = treemapContainer.append("g")
|
|
||||||
.classed('labels', true)
|
|
||||||
.attr("transform", "translate("+[-treemapRadius,-treemapRadius]+")")
|
|
||||||
.selectAll(".label")
|
|
||||||
.data(leaves)
|
|
||||||
.enter()
|
|
||||||
.append("g")
|
|
||||||
.classed("label", true)
|
|
||||||
.attr("transform", function(d){
|
|
||||||
return "translate("+[d.polygon.site.x, d.polygon.site.y]+")";
|
|
||||||
})
|
})
|
||||||
.style("font-size", function(d){ return fontScale(d.data.weight*100); });
|
|
||||||
|
|
||||||
labels.append("text")
|
// Size values
|
||||||
.classed("name", true)
|
nodes
|
||||||
.html(function(d){
|
.append('text')
|
||||||
return d.data.name; //(d.data.weight<1)? d.data.code : d.data.name;
|
.attr('dx', 2)
|
||||||
});
|
.attr('dy', "2em")
|
||||||
labels.append("text")
|
.text(function(d) {
|
||||||
.classed("value", true)
|
return filesize(d.data.value);
|
||||||
.text(function(d){ return format_percent(d.data.weight); });
|
})
|
||||||
|
.attr('clip-path', function(d) {return "url(#clip-" + d.data.id + ")"})
|
||||||
|
|
||||||
var hoverers = treemapContainer.append("g")
|
var nodecnt = 0
|
||||||
.classed('hoverers', true)
|
nodes.each(function(){nodecnt++;})
|
||||||
.attr("transform", "translate("+[-treemapRadius,-treemapRadius]+")")
|
console.log("total nodes: " + nodecnt)
|
||||||
.selectAll(".hoverer")
|
|
||||||
.data(leaves)
|
|
||||||
.enter()
|
|
||||||
.append("path")
|
|
||||||
.classed("hoverer", true)
|
|
||||||
.attr("d", function(d){ return "M"+d.polygon.join(",")+"z"; });
|
|
||||||
|
|
||||||
hoverers.append("title")
|
|
||||||
.text(function(d) { return d.data.name + "\n" + format_percent(d.value); });
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ class AppWeb(object):
|
||||||
return self.tpl.get_template(template). \
|
return self.tpl.get_template(template). \
|
||||||
render(**kwargs,
|
render(**kwargs,
|
||||||
NodeType=NodeType,
|
NodeType=NodeType,
|
||||||
NodeGroup=NodeGroup) #, **self.get_default_vars())
|
NodeGroup=NodeGroup) #, **self.get_default_vars())
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def index(self, n=None):
|
def index(self, n=None):
|
||||||
|
@ -69,62 +69,79 @@ class AppWeb(object):
|
||||||
dur = time() - start
|
dur = time() - start
|
||||||
return page + f"\n<!-- render time: {round(dur, 4)} -->"
|
return page + f"\n<!-- render time: {round(dur, 4)} -->"
|
||||||
|
|
||||||
# yield str(self.db.root)
|
|
||||||
# yield "Ready<br />"
|
|
||||||
# from time import time
|
|
||||||
# start = time()
|
|
||||||
# num_nodes = len([i for i in self.db.root.iter()])
|
|
||||||
# dur = time() - start
|
|
||||||
# yield f"num nodes: {num_nodes} in {round(dur, 3)}"
|
|
||||||
|
|
||||||
@cherrypy.expose
|
@cherrypy.expose
|
||||||
def chart_json(self, n, depth=2):
|
def chart_json(self, n, depth=2):
|
||||||
# try:
|
start = time()
|
||||||
# node = self.db.index[int(n)]
|
try:
|
||||||
# except (ValueError, KeyError):
|
node = self.db.index[int(n)]
|
||||||
# raise cherrypy.HTTPError(404)
|
except (ValueError, KeyError):
|
||||||
node = self.db.root
|
raise cherrypy.HTTPError(404)
|
||||||
|
|
||||||
data = AppWeb.export_children(node, depth=int(depth))
|
data = AppWeb.export_children(node, depth=int(depth))
|
||||||
|
data["render_time"] = round(time() - start, 4)
|
||||||
|
|
||||||
cherrypy.response.headers["Content-type"] = "application/json"
|
cherrypy.response.headers["Content-type"] = "application/json"
|
||||||
return json.dumps(data).encode("utf-8")
|
return json.dumps(data).encode("utf-8")
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def export_children(entry, depth, max_children=10):
|
def export_children(entry, depth, min_children=25, max_children=50):
|
||||||
|
"""
|
||||||
|
:param entry: node to recurse from. is included as the parent
|
||||||
|
:param depth: how many layers to add under the parent node
|
||||||
|
:param max_children: maximum number of children under a node, others are combined
|
||||||
|
:param thresh: nodes smaller than this size will be combined into a group
|
||||||
|
"""
|
||||||
children = []
|
children = []
|
||||||
if depth:
|
if depth:
|
||||||
others = []
|
|
||||||
|
|
||||||
for child in entry.children:
|
for child in entry.children:
|
||||||
child_data = AppWeb.export_children(child, depth - 1)
|
if child.total_size > 0:
|
||||||
|
children.append(AppWeb.export_children(child,
|
||||||
|
depth=depth - 1,
|
||||||
|
min_children=min_children,
|
||||||
|
max_children=max_children))
|
||||||
|
|
||||||
if entry.total_size > 0:
|
children.sort(key=lambda c: c["value"],
|
||||||
child_data["weight"] = child_data["size"] / entry.total_size
|
reverse=True)
|
||||||
else:
|
|
||||||
child_data["weight"] = 0
|
|
||||||
|
|
||||||
if len(children) < max_children:
|
# scan down the children until we've covered $thresh of the parent size
|
||||||
children.append(child_data)
|
thresh = 0.95 # The lower (1-$thresh) of nodes, sorted by size, will be combined into a group
|
||||||
else:
|
min_size = 100 / max_children / 100 # 50 max children means nodes under 2% max size must be combined
|
||||||
others.append(child_data)
|
child_sum = 0
|
||||||
|
|
||||||
|
last_offset = 0
|
||||||
|
for offset, child in enumerate(children):
|
||||||
|
child_sum += child["value"]
|
||||||
|
last_offset = offset
|
||||||
|
if offset > max_children:
|
||||||
|
break # max children
|
||||||
|
# continue # min children
|
||||||
|
if child["value"] / entry.total_size < min_size and offset > min_children:
|
||||||
|
break
|
||||||
|
if child_sum / entry.total_size > thresh:
|
||||||
|
break
|
||||||
|
|
||||||
|
others = children[last_offset + 1:]
|
||||||
|
children = children[0:last_offset + 1]
|
||||||
|
|
||||||
if others:
|
if others:
|
||||||
other_sz = sum([i["size"] for i in others])
|
other_sz = sum([i["value"] for i in others])
|
||||||
children.append({"name": f"({len(others)} others)",
|
other_children = sum([i["num_children"] for i in others])
|
||||||
"typ": NodeType.SPECIAL.value,
|
children.append({"id": id(others[0]),
|
||||||
"size": other_sz,
|
"name": f"({len(others)} others)",
|
||||||
|
"typ": -1,
|
||||||
|
"value": max(other_sz, 1),
|
||||||
"children": [],
|
"children": [],
|
||||||
"weight": other_sz / entry.total_size if entry.total_size > 0 else 0,
|
"num_children": other_children,
|
||||||
|
"total_children": child["total_children"],
|
||||||
})
|
})
|
||||||
|
|
||||||
children.sort(key=lambda c: c["size"],
|
return {"id": id(entry),
|
||||||
reverse=True)
|
"name": entry.name,
|
||||||
|
|
||||||
return {"name": entry.name,
|
|
||||||
"typ": entry.typ.value,
|
"typ": entry.typ.value,
|
||||||
"size": entry.total_size,
|
"value": max(entry.total_size, 1),
|
||||||
"children": children}
|
"children": children,
|
||||||
|
"num_children": len(entry.children),
|
||||||
|
"total_children": entry.total_children, }
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -141,7 +158,7 @@ def main():
|
||||||
logging.basicConfig(level=logging.INFO if args.debug else logging.WARNING,
|
logging.basicConfig(level=logging.INFO if args.debug else logging.WARNING,
|
||||||
format="%(asctime)-15s %(levelname)-8s %(filename)s:%(lineno)d %(message)s")
|
format="%(asctime)-15s %(levelname)-8s %(filename)s:%(lineno)d %(message)s")
|
||||||
|
|
||||||
tpl_dir = os.path.join(APPROOT, "templates") if not args.debug else "templates"
|
tpl_dir = os.path.join(APPROOT, "templates")
|
||||||
db = DbUpdater(args.dir, args.cache)
|
db = DbUpdater(args.dir, args.cache)
|
||||||
db.start()
|
db.start()
|
||||||
|
|
||||||
|
|
16
gruntfile.js
16
gruntfile.js
|
@ -23,6 +23,17 @@ module.exports = function(grunt) {
|
||||||
dev: webpackConfig,
|
dev: webpackConfig,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
babel: {
|
||||||
|
options: {
|
||||||
|
sourceMap: true
|
||||||
|
},
|
||||||
|
dist: {
|
||||||
|
files: {
|
||||||
|
"static/scripts.js": "static/scripts.jsx"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
/*concat: {
|
/*concat: {
|
||||||
deps_js: {
|
deps_js: {
|
||||||
src: [
|
src: [
|
||||||
|
@ -40,7 +51,7 @@ module.exports = function(grunt) {
|
||||||
watch: {
|
watch: {
|
||||||
concat: {
|
concat: {
|
||||||
files: ['assets/js/*.js'],
|
files: ['assets/js/*.js'],
|
||||||
tasks: ['webpack:dev'],
|
tasks: ['webpack:dev', 'babel'],
|
||||||
// options: {
|
// options: {
|
||||||
// spawn: false
|
// spawn: false
|
||||||
// }
|
// }
|
||||||
|
@ -53,8 +64,9 @@ module.exports = function(grunt) {
|
||||||
// grunt.loadNpmTasks('grunt-contrib-cssmin');
|
// grunt.loadNpmTasks('grunt-contrib-cssmin');
|
||||||
// grunt.loadNpmTasks('grunt-contrib-concat');
|
// grunt.loadNpmTasks('grunt-contrib-concat');
|
||||||
grunt.loadNpmTasks('grunt-webpack');
|
grunt.loadNpmTasks('grunt-webpack');
|
||||||
|
grunt.loadNpmTasks('grunt-babel');
|
||||||
|
|
||||||
// grunt.registerTask('default', ['less:website', 'cssmin:website', 'concat:dist']);
|
// grunt.registerTask('default', ['less:website', 'cssmin:website', 'concat:dist']);
|
||||||
grunt.registerTask('default', ['webpack:dev']);
|
grunt.registerTask('default', ['webpack:dev', 'babel']);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,12 +11,14 @@
|
||||||
"chroma-js": "^2.0.3",
|
"chroma-js": "^2.0.3",
|
||||||
"d3": "^5.9.2",
|
"d3": "^5.9.2",
|
||||||
"d3-voronoi-treemap": "^1.1.0",
|
"d3-voronoi-treemap": "^1.1.0",
|
||||||
"randomcolor": "^0.5.4",
|
"filesize": "^4.1.2",
|
||||||
"round-to": "^4.0.0"
|
"randomcolor": "^0.5.4"
|
||||||
},
|
},
|
||||||
"scripts": {},
|
"scripts": {},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.4.5",
|
||||||
"grunt": "^1.0.4",
|
"grunt": "^1.0.4",
|
||||||
|
"grunt-babel": "^8.0.0",
|
||||||
"grunt-contrib-concat": "^1.0.1",
|
"grunt-contrib-concat": "^1.0.1",
|
||||||
"grunt-contrib-watch": "^1.1.0",
|
"grunt-contrib-watch": "^1.1.0",
|
||||||
"grunt-webpack": "^3.1.3",
|
"grunt-webpack": "^3.1.3",
|
||||||
|
|
4
setup.py
4
setup.py
|
@ -16,7 +16,5 @@ setup(name='dirview',
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
package_data={'dirview': ['../templates/*.html',
|
package_data={'dirview': ['../templates/*.html',
|
||||||
# '../templates/fragments/*.html',
|
'../static/scripts.js']},
|
||||||
# '../styles/dist/*'
|
|
||||||
]},
|
|
||||||
zip_safe=False)
|
zip_safe=False)
|
||||||
|
|
|
@ -3,6 +3,10 @@
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>NAS Viewer</title>
|
<title>NAS Viewer</title>
|
||||||
|
<script type="text/javascript">
|
||||||
|
var _node = {{ node|id }};
|
||||||
|
var _graph_depth = 2;
|
||||||
|
</script>
|
||||||
<script src="/static/scripts.js" type="text/javascript"></script>
|
<script src="/static/scripts.js" type="text/javascript"></script>
|
||||||
<style>
|
<style>
|
||||||
* {
|
* {
|
||||||
|
@ -22,10 +26,30 @@
|
||||||
float: right;
|
float: right;
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
|
svg {
|
||||||
|
/*width: 1650px;*/
|
||||||
|
/*height: 600px;*/
|
||||||
|
max-width: 100%;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 10px;
|
||||||
|
font-family: arial, sans-serif;
|
||||||
|
}
|
||||||
|
svg rect {
|
||||||
|
fill: cadetblue;
|
||||||
|
opacity: 0.3;
|
||||||
|
stroke: white;
|
||||||
|
}
|
||||||
|
svg g.chart>g.can-navigate:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
svg g.chart>g.can-navigate:hover a {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
svg a:hover {
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
svg {
|
svg {
|
||||||
background-color: rgb(250,250,250);
|
background-color: rgb(250,250,250);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,11 +102,11 @@
|
||||||
.legend-color {
|
.legend-color {
|
||||||
stroke-width: 1px;
|
stroke-width: 1px;
|
||||||
stroke:darkgrey;
|
stroke:darkgrey;
|
||||||
}
|
}*/
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body onload="Application.boot();">
|
<body onload="Application.boot();">
|
||||||
<svg></svg>
|
<svg><g class="chart"></g></svg>
|
||||||
<div class="viewer">
|
<div class="viewer">
|
||||||
<h1>{{ node.path|pathjoin }}</h1>
|
<h1>{{ node.path|pathjoin }}</h1>
|
||||||
<div>
|
<div>
|
||||||
|
|
|
@ -4,11 +4,12 @@ module.exports = {
|
||||||
entry: './assets/js/main.js',
|
entry: './assets/js/main.js',
|
||||||
output: {
|
output: {
|
||||||
path: path.resolve('static'),
|
path: path.resolve('static'),
|
||||||
filename: 'scripts.js',
|
filename: 'scripts.jsx',
|
||||||
libraryTarget: 'var',
|
libraryTarget: 'var',
|
||||||
library: 'Application'
|
library: 'Application'
|
||||||
},
|
},
|
||||||
module: {
|
module: {
|
||||||
|
// devtool: 'source-map'
|
||||||
/*loaders: [
|
/*loaders: [
|
||||||
{ test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ }
|
{ test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ }
|
||||||
]*/
|
]*/
|
||||||
|
|
191
yarn.lock
191
yarn.lock
|
@ -2,6 +2,123 @@
|
||||||
# yarn lockfile v1
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@babel/code-frame@^7.0.0":
|
||||||
|
version "7.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8"
|
||||||
|
integrity sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/highlight" "^7.0.0"
|
||||||
|
|
||||||
|
"@babel/core@^7.4.5":
|
||||||
|
version "7.4.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.4.5.tgz#081f97e8ffca65a9b4b0fdc7e274e703f000c06a"
|
||||||
|
integrity sha512-OvjIh6aqXtlsA8ujtGKfC7LYWksYSX8yQcM8Ay3LuvVeQ63lcOKgoZWVqcpFwkd29aYU9rVx7jxhfhiEDV9MZA==
|
||||||
|
dependencies:
|
||||||
|
"@babel/code-frame" "^7.0.0"
|
||||||
|
"@babel/generator" "^7.4.4"
|
||||||
|
"@babel/helpers" "^7.4.4"
|
||||||
|
"@babel/parser" "^7.4.5"
|
||||||
|
"@babel/template" "^7.4.4"
|
||||||
|
"@babel/traverse" "^7.4.5"
|
||||||
|
"@babel/types" "^7.4.4"
|
||||||
|
convert-source-map "^1.1.0"
|
||||||
|
debug "^4.1.0"
|
||||||
|
json5 "^2.1.0"
|
||||||
|
lodash "^4.17.11"
|
||||||
|
resolve "^1.3.2"
|
||||||
|
semver "^5.4.1"
|
||||||
|
source-map "^0.5.0"
|
||||||
|
|
||||||
|
"@babel/generator@^7.4.4":
|
||||||
|
version "7.4.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.4.4.tgz#174a215eb843fc392c7edcaabeaa873de6e8f041"
|
||||||
|
integrity sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/types" "^7.4.4"
|
||||||
|
jsesc "^2.5.1"
|
||||||
|
lodash "^4.17.11"
|
||||||
|
source-map "^0.5.0"
|
||||||
|
trim-right "^1.0.1"
|
||||||
|
|
||||||
|
"@babel/helper-function-name@^7.1.0":
|
||||||
|
version "7.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53"
|
||||||
|
integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/helper-get-function-arity" "^7.0.0"
|
||||||
|
"@babel/template" "^7.1.0"
|
||||||
|
"@babel/types" "^7.0.0"
|
||||||
|
|
||||||
|
"@babel/helper-get-function-arity@^7.0.0":
|
||||||
|
version "7.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3"
|
||||||
|
integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==
|
||||||
|
dependencies:
|
||||||
|
"@babel/types" "^7.0.0"
|
||||||
|
|
||||||
|
"@babel/helper-split-export-declaration@^7.4.4":
|
||||||
|
version "7.4.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz#ff94894a340be78f53f06af038b205c49d993677"
|
||||||
|
integrity sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==
|
||||||
|
dependencies:
|
||||||
|
"@babel/types" "^7.4.4"
|
||||||
|
|
||||||
|
"@babel/helpers@^7.4.4":
|
||||||
|
version "7.4.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.4.4.tgz#868b0ef59c1dd4e78744562d5ce1b59c89f2f2a5"
|
||||||
|
integrity sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==
|
||||||
|
dependencies:
|
||||||
|
"@babel/template" "^7.4.4"
|
||||||
|
"@babel/traverse" "^7.4.4"
|
||||||
|
"@babel/types" "^7.4.4"
|
||||||
|
|
||||||
|
"@babel/highlight@^7.0.0":
|
||||||
|
version "7.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4"
|
||||||
|
integrity sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==
|
||||||
|
dependencies:
|
||||||
|
chalk "^2.0.0"
|
||||||
|
esutils "^2.0.2"
|
||||||
|
js-tokens "^4.0.0"
|
||||||
|
|
||||||
|
"@babel/parser@^7.4.4", "@babel/parser@^7.4.5":
|
||||||
|
version "7.4.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.5.tgz#04af8d5d5a2b044a2a1bffacc1e5e6673544e872"
|
||||||
|
integrity sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==
|
||||||
|
|
||||||
|
"@babel/template@^7.1.0", "@babel/template@^7.4.4":
|
||||||
|
version "7.4.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.4.tgz#f4b88d1225689a08f5bc3a17483545be9e4ed237"
|
||||||
|
integrity sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==
|
||||||
|
dependencies:
|
||||||
|
"@babel/code-frame" "^7.0.0"
|
||||||
|
"@babel/parser" "^7.4.4"
|
||||||
|
"@babel/types" "^7.4.4"
|
||||||
|
|
||||||
|
"@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5":
|
||||||
|
version "7.4.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.4.5.tgz#4e92d1728fd2f1897dafdd321efbff92156c3216"
|
||||||
|
integrity sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==
|
||||||
|
dependencies:
|
||||||
|
"@babel/code-frame" "^7.0.0"
|
||||||
|
"@babel/generator" "^7.4.4"
|
||||||
|
"@babel/helper-function-name" "^7.1.0"
|
||||||
|
"@babel/helper-split-export-declaration" "^7.4.4"
|
||||||
|
"@babel/parser" "^7.4.5"
|
||||||
|
"@babel/types" "^7.4.4"
|
||||||
|
debug "^4.1.0"
|
||||||
|
globals "^11.1.0"
|
||||||
|
lodash "^4.17.11"
|
||||||
|
|
||||||
|
"@babel/types@^7.0.0", "@babel/types@^7.4.4":
|
||||||
|
version "7.4.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.4.tgz#8db9e9a629bb7c29370009b4b779ed93fe57d5f0"
|
||||||
|
integrity sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==
|
||||||
|
dependencies:
|
||||||
|
esutils "^2.0.2"
|
||||||
|
lodash "^4.17.11"
|
||||||
|
to-fast-properties "^2.0.0"
|
||||||
|
|
||||||
"@webassemblyjs/ast@1.8.5":
|
"@webassemblyjs/ast@1.8.5":
|
||||||
version "1.8.5"
|
version "1.8.5"
|
||||||
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359"
|
resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.8.5.tgz#51b1c5fe6576a34953bf4b253df9f0d490d9e359"
|
||||||
|
@ -546,7 +663,7 @@ chalk@^1.0.0:
|
||||||
strip-ansi "^3.0.0"
|
strip-ansi "^3.0.0"
|
||||||
supports-color "^2.0.0"
|
supports-color "^2.0.0"
|
||||||
|
|
||||||
chalk@^2.4.1, chalk@~2.4.1:
|
chalk@^2.0.0, chalk@^2.4.1, chalk@~2.4.1:
|
||||||
version "2.4.2"
|
version "2.4.2"
|
||||||
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
|
||||||
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
|
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
|
||||||
|
@ -705,6 +822,13 @@ continuable-cache@^0.3.1:
|
||||||
resolved "https://registry.yarnpkg.com/continuable-cache/-/continuable-cache-0.3.1.tgz#bd727a7faed77e71ff3985ac93351a912733ad0f"
|
resolved "https://registry.yarnpkg.com/continuable-cache/-/continuable-cache-0.3.1.tgz#bd727a7faed77e71ff3985ac93351a912733ad0f"
|
||||||
integrity sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=
|
integrity sha1-vXJ6f67XfnH/OYWskzUakSczrQ8=
|
||||||
|
|
||||||
|
convert-source-map@^1.1.0:
|
||||||
|
version "1.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20"
|
||||||
|
integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==
|
||||||
|
dependencies:
|
||||||
|
safe-buffer "~5.1.1"
|
||||||
|
|
||||||
copy-concurrently@^1.0.0:
|
copy-concurrently@^1.0.0:
|
||||||
version "1.0.5"
|
version "1.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0"
|
resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0"
|
||||||
|
@ -1109,6 +1233,13 @@ debug@^3.1.0, debug@^3.2.6:
|
||||||
dependencies:
|
dependencies:
|
||||||
ms "^2.1.1"
|
ms "^2.1.1"
|
||||||
|
|
||||||
|
debug@^4.1.0:
|
||||||
|
version "4.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
|
||||||
|
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
|
||||||
|
dependencies:
|
||||||
|
ms "^2.1.1"
|
||||||
|
|
||||||
decamelize@^1.1.2, decamelize@^1.2.0:
|
decamelize@^1.1.2, decamelize@^1.2.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
|
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
|
||||||
|
@ -1286,6 +1417,11 @@ estraverse@^4.1.0, estraverse@^4.1.1:
|
||||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
|
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13"
|
||||||
integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=
|
integrity sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=
|
||||||
|
|
||||||
|
esutils@^2.0.2:
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b"
|
||||||
|
integrity sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=
|
||||||
|
|
||||||
eventemitter2@~0.4.13:
|
eventemitter2@~0.4.13:
|
||||||
version "0.4.14"
|
version "0.4.14"
|
||||||
resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-0.4.14.tgz#8f61b75cde012b2e9eb284d4545583b5643b61ab"
|
resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-0.4.14.tgz#8f61b75cde012b2e9eb284d4545583b5643b61ab"
|
||||||
|
@ -1393,6 +1529,11 @@ figgy-pudding@^3.5.1:
|
||||||
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
|
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
|
||||||
integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==
|
integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==
|
||||||
|
|
||||||
|
filesize@^4.1.2:
|
||||||
|
version "4.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/filesize/-/filesize-4.1.2.tgz#fcd570af1353cea97897be64f56183adb995994b"
|
||||||
|
integrity sha512-iSWteWtfNcrWQTkQw8ble2bnonSl7YJImsn9OZKpE2E4IHhXI78eASpDYUljXZZdYj36QsEKjOs/CsiDqmKMJw==
|
||||||
|
|
||||||
fill-range@^4.0.0:
|
fill-range@^4.0.0:
|
||||||
version "4.0.0"
|
version "4.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7"
|
resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7"
|
||||||
|
@ -1613,6 +1754,11 @@ global-prefix@^1.0.1:
|
||||||
is-windows "^1.0.1"
|
is-windows "^1.0.1"
|
||||||
which "^1.2.14"
|
which "^1.2.14"
|
||||||
|
|
||||||
|
globals@^11.1.0:
|
||||||
|
version "11.12.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
|
||||||
|
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
|
||||||
|
|
||||||
globule@^1.0.0:
|
globule@^1.0.0:
|
||||||
version "1.2.1"
|
version "1.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d"
|
resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d"
|
||||||
|
@ -1627,6 +1773,11 @@ graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2:
|
||||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
|
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
|
||||||
integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
|
integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==
|
||||||
|
|
||||||
|
grunt-babel@^8.0.0:
|
||||||
|
version "8.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/grunt-babel/-/grunt-babel-8.0.0.tgz#92ef63aafadf938c488dc2f926ac9846e0c93d1b"
|
||||||
|
integrity sha512-WuiZFvGzcyzlEoPIcY1snI234ydDWeWWV5bpnB7PZsOLHcDsxWKnrR1rMWEUsbdVPPjvIirwFNsuo4CbJmsdFQ==
|
||||||
|
|
||||||
grunt-cli@~1.2.0:
|
grunt-cli@~1.2.0:
|
||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/grunt-cli/-/grunt-cli-1.2.0.tgz#562b119ebb069ddb464ace2845501be97b35b6a8"
|
resolved "https://registry.yarnpkg.com/grunt-cli/-/grunt-cli-1.2.0.tgz#562b119ebb069ddb464ace2845501be97b35b6a8"
|
||||||
|
@ -2073,6 +2224,11 @@ isobject@^3.0.0, isobject@^3.0.1:
|
||||||
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
|
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
|
||||||
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
|
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
|
||||||
|
|
||||||
|
js-tokens@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||||
|
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
|
||||||
|
|
||||||
js-yaml@~3.13.0:
|
js-yaml@~3.13.0:
|
||||||
version "3.13.1"
|
version "3.13.1"
|
||||||
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
|
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
|
||||||
|
@ -2081,6 +2237,11 @@ js-yaml@~3.13.0:
|
||||||
argparse "^1.0.7"
|
argparse "^1.0.7"
|
||||||
esprima "^4.0.0"
|
esprima "^4.0.0"
|
||||||
|
|
||||||
|
jsesc@^2.5.1:
|
||||||
|
version "2.5.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
|
||||||
|
integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
|
||||||
|
|
||||||
json-parse-better-errors@^1.0.2:
|
json-parse-better-errors@^1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
|
resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9"
|
||||||
|
@ -2098,6 +2259,13 @@ json5@^1.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
minimist "^1.2.0"
|
minimist "^1.2.0"
|
||||||
|
|
||||||
|
json5@^2.1.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850"
|
||||||
|
integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==
|
||||||
|
dependencies:
|
||||||
|
minimist "^1.2.0"
|
||||||
|
|
||||||
kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
|
kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0:
|
||||||
version "3.2.2"
|
version "3.2.2"
|
||||||
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
|
resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64"
|
||||||
|
@ -3028,7 +3196,7 @@ resolve-url@^0.2.1:
|
||||||
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
|
resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
|
||||||
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
|
integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=
|
||||||
|
|
||||||
resolve@^1.10.0:
|
resolve@^1.10.0, resolve@^1.3.2:
|
||||||
version "1.11.0"
|
version "1.11.0"
|
||||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.0.tgz#4014870ba296176b86343d50b60f3b50609ce232"
|
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.11.0.tgz#4014870ba296176b86343d50b60f3b50609ce232"
|
||||||
integrity sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==
|
integrity sha512-WL2pBDjqT6pGUNSUzMw00o4T7If+z4H2x3Gz893WoUQ5KW8Vr9txp00ykiP16VBaZF5+j/OcXJHZ9+PCvdiDKw==
|
||||||
|
@ -3060,11 +3228,6 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
|
||||||
hash-base "^3.0.0"
|
hash-base "^3.0.0"
|
||||||
inherits "^2.0.1"
|
inherits "^2.0.1"
|
||||||
|
|
||||||
round-to@^4.0.0:
|
|
||||||
version "4.0.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/round-to/-/round-to-4.0.0.tgz#7576de9f721e58bd8116757fc3ba10f44d5b3886"
|
|
||||||
integrity sha512-2HD3qSm7FGv1uBQywsK43YtSeXQhh5CUscaFGsvbr38oZzfLqoPQAPw2ngvpXKruAEsn7WuPXdq1mrUSkR70MQ==
|
|
||||||
|
|
||||||
run-queue@^1.0.0, run-queue@^1.0.3:
|
run-queue@^1.0.0, run-queue@^1.0.3:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47"
|
resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47"
|
||||||
|
@ -3113,7 +3276,7 @@ schema-utils@^1.0.0:
|
||||||
ajv-errors "^1.0.0"
|
ajv-errors "^1.0.0"
|
||||||
ajv-keywords "^3.1.0"
|
ajv-keywords "^3.1.0"
|
||||||
|
|
||||||
"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.5.0, semver@^5.6.0:
|
"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0:
|
||||||
version "5.7.0"
|
version "5.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b"
|
||||||
integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==
|
integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==
|
||||||
|
@ -3237,7 +3400,7 @@ source-map-url@^0.4.0:
|
||||||
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
|
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
|
||||||
integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=
|
integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=
|
||||||
|
|
||||||
source-map@^0.5.3, source-map@^0.5.6:
|
source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6:
|
||||||
version "0.5.7"
|
version "0.5.7"
|
||||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||||
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
|
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
|
||||||
|
@ -3503,6 +3666,11 @@ to-arraybuffer@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
|
resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43"
|
||||||
integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=
|
integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=
|
||||||
|
|
||||||
|
to-fast-properties@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
|
||||||
|
integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=
|
||||||
|
|
||||||
to-object-path@^0.3.0:
|
to-object-path@^0.3.0:
|
||||||
version "0.3.0"
|
version "0.3.0"
|
||||||
resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"
|
resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af"
|
||||||
|
@ -3533,6 +3701,11 @@ trim-newlines@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613"
|
resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613"
|
||||||
integrity sha1-WIeWa7WCpFA6QetST301ARgVphM=
|
integrity sha1-WIeWa7WCpFA6QetST301ARgVphM=
|
||||||
|
|
||||||
|
trim-right@^1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
|
||||||
|
integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=
|
||||||
|
|
||||||
tslib@^1.9.0:
|
tslib@^1.9.0:
|
||||||
version "1.9.3"
|
version "1.9.3"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
|
||||||
|
|
Loading…
Reference in New Issue