Merge branch 'master' of http://github.com/mbostock/d3
This commit is contained in:
Коммит
87adc077b9
12
Makefile
12
Makefile
|
@ -94,8 +94,10 @@ d3.layout.js: \
|
||||||
src/start.js \
|
src/start.js \
|
||||||
src/layout/layout.js \
|
src/layout/layout.js \
|
||||||
src/layout/chord.js \
|
src/layout/chord.js \
|
||||||
|
src/layout/force.js \
|
||||||
src/layout/pie.js \
|
src/layout/pie.js \
|
||||||
src/layout/stack.js \
|
src/layout/stack.js \
|
||||||
|
src/layout/treemap.js \
|
||||||
src/end.js
|
src/end.js
|
||||||
|
|
||||||
d3.geo.js: \
|
d3.geo.js: \
|
||||||
|
@ -132,6 +134,9 @@ d3.geom.js: \
|
||||||
src/geom/quadtree.js \
|
src/geom/quadtree.js \
|
||||||
src/end.js
|
src/end.js
|
||||||
|
|
||||||
|
tests: \
|
||||||
|
tests/test-format.test
|
||||||
|
|
||||||
%.min.js: %.js Makefile
|
%.min.js: %.js Makefile
|
||||||
@rm -f $@
|
@rm -f $@
|
||||||
$(JS_COMPILER) --js $< --js_output_file $@
|
$(JS_COMPILER) --js $< --js_output_file $@
|
||||||
|
@ -141,5 +146,12 @@ d3.js d3%.js: Makefile
|
||||||
cat $(filter %.js,$^) > $@
|
cat $(filter %.js,$^) > $@
|
||||||
@chmod a-w $@
|
@chmod a-w $@
|
||||||
|
|
||||||
|
%.test: %.js %.out d3.js
|
||||||
|
@/bin/echo -n "test: $* "
|
||||||
|
@node $< > $*.actual
|
||||||
|
@diff -U 3 $*.out $*.actual && rm -f $*.actual \
|
||||||
|
&& echo '\033[1;32mPASS\033[0m' \
|
||||||
|
|| echo test: $* '\033[1;31mFAIL\033[0m'
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f d3*.js
|
rm -f d3*.js
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
(function(){d3 = {version: "1.4.0"}; // semver
|
(function(){d3 = {version: "1.5.1"}; // semver
|
||||||
if (!Date.now) Date.now = function() {
|
if (!Date.now) Date.now = function() {
|
||||||
return +new Date();
|
return +new Date();
|
||||||
};
|
};
|
||||||
|
@ -335,30 +335,45 @@ function d3_dispatch(type) {
|
||||||
d3.format = function(specifier) {
|
d3.format = function(specifier) {
|
||||||
var match = d3_format_re.exec(specifier),
|
var match = d3_format_re.exec(specifier),
|
||||||
fill = match[1] || " ",
|
fill = match[1] || " ",
|
||||||
sign = d3_format_signs[match[3]] || d3_format_signs["-"],
|
sign = match[3] || "",
|
||||||
zfill = match[5],
|
zfill = match[5],
|
||||||
width = +match[6],
|
width = +match[6],
|
||||||
comma = match[7],
|
comma = match[7],
|
||||||
precision = match[8],
|
precision = match[8],
|
||||||
type = match[9];
|
type = match[9];
|
||||||
if (precision) precision = precision.substring(1);
|
if (precision) precision = precision.substring(1);
|
||||||
if (zfill) fill = "0"; // TODO align = "=";
|
if (zfill) {
|
||||||
|
fill = "0"; // TODO align = "=";
|
||||||
|
if (comma) width -= Math.floor((width - 1) / 4);
|
||||||
|
}
|
||||||
if (type == "d") precision = "0";
|
if (type == "d") precision = "0";
|
||||||
return function(value) {
|
return function(value) {
|
||||||
var number = +value,
|
var number = +value,
|
||||||
negative = (number < 0) && (number = -number);
|
negative = (number < 0) && (number = -number) ? "\u2212" : sign;
|
||||||
|
|
||||||
|
// Return the empty string for floats formatted as ints.
|
||||||
if ((type == "d") && (number % 1)) return "";
|
if ((type == "d") && (number % 1)) return "";
|
||||||
|
|
||||||
|
// Convert the input value to the desired precision.
|
||||||
if (precision) value = number.toFixed(precision);
|
if (precision) value = number.toFixed(precision);
|
||||||
else value = "" + number;
|
else value = "" + number;
|
||||||
if (comma) {
|
|
||||||
var i = value.lastIndexOf("."),
|
// If the fill character is 0, the sign and group is applied after the fill.
|
||||||
f = i >= 0 ? value.substring(i) : (i = value.length, ""),
|
if (zfill) {
|
||||||
t = [];
|
var length = value.length + negative.length;
|
||||||
while (i > 0) t.push(value.substring(i -= 3, i + 3));
|
if (length < width) value = new Array(width - length + 1).join(fill) + value;
|
||||||
value = t.reverse().join(",") + f;
|
if (comma) value = d3_format_group(value);
|
||||||
|
value = negative + value;
|
||||||
}
|
}
|
||||||
var length = (value = sign(negative, value)).length;
|
|
||||||
if (length < width) value = new Array(width - length + 1).join(fill) + value;
|
// Otherwise (e.g., space-filling), the sign and group is applied before.
|
||||||
|
else {
|
||||||
|
if (comma) value = d3_format_group(value);
|
||||||
|
value = negative + value;
|
||||||
|
var length = value.length;
|
||||||
|
if (length < width) value = new Array(width - length + 1).join(fill) + value;
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -366,11 +381,14 @@ d3.format = function(specifier) {
|
||||||
// [[fill]align][sign][#][0][width][,][.precision][type]
|
// [[fill]align][sign][#][0][width][,][.precision][type]
|
||||||
var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/;
|
var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/;
|
||||||
|
|
||||||
var d3_format_signs = {
|
// Apply comma grouping for thousands.
|
||||||
"+": function(negative, value) { return (negative ? "\u2212" : "+") + value; },
|
function d3_format_group(value) {
|
||||||
" ": function(negative, value) { return (negative ? "\u2212" : " ") + value; },
|
var i = value.lastIndexOf("."),
|
||||||
"-": function(negative, value) { return negative ? "\u2212" + value : value; }
|
f = i >= 0 ? value.substring(i) : (i = value.length, ""),
|
||||||
};
|
t = [];
|
||||||
|
while (i > 0) t.push(value.substring(i -= 3, i + 3));
|
||||||
|
return t.reverse().join(",") + f;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* TERMS OF USE - EASING EQUATIONS
|
* TERMS OF USE - EASING EQUATIONS
|
||||||
*
|
*
|
||||||
|
|
375
d3.layout.js
375
d3.layout.js
|
@ -150,6 +150,200 @@ d3.layout.chord = function() {
|
||||||
|
|
||||||
return chord;
|
return chord;
|
||||||
};
|
};
|
||||||
|
// A rudimentary force layout using Gauss-Seidel.
|
||||||
|
d3.layout.force = function() {
|
||||||
|
var force = {},
|
||||||
|
event = d3.dispatch("tick"),
|
||||||
|
size = [1, 1],
|
||||||
|
alpha = .5,
|
||||||
|
distance = 30,
|
||||||
|
interval,
|
||||||
|
nodes,
|
||||||
|
links,
|
||||||
|
distances;
|
||||||
|
|
||||||
|
function tick() {
|
||||||
|
var n = distances.length,
|
||||||
|
i, // current index
|
||||||
|
o, // current link
|
||||||
|
s, // current source
|
||||||
|
t, // current target
|
||||||
|
l, // current distance
|
||||||
|
x, // x-distance
|
||||||
|
y; // y-distance
|
||||||
|
|
||||||
|
// gauss-seidel relaxation
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
o = distances[i];
|
||||||
|
s = o.source;
|
||||||
|
t = o.target;
|
||||||
|
x = t.x - s.x;
|
||||||
|
y = t.y - s.y;
|
||||||
|
if (l = Math.sqrt(x * x + y * y)) {
|
||||||
|
l = alpha / (o.distance * o.distance) * (l - distance * o.distance) / l;
|
||||||
|
x *= l;
|
||||||
|
y *= l;
|
||||||
|
if (s.fixed) {
|
||||||
|
if (t.fixed) continue;
|
||||||
|
t.x -= x;
|
||||||
|
t.y -= y;
|
||||||
|
} else if (t.fixed) {
|
||||||
|
s.x += x;
|
||||||
|
s.y += y;
|
||||||
|
} else {
|
||||||
|
s.x += x;
|
||||||
|
s.y += y;
|
||||||
|
t.x -= x;
|
||||||
|
t.y -= y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// simulated annealing, basically
|
||||||
|
if ((alpha *= .99) < 1e-6) force.stop();
|
||||||
|
|
||||||
|
event.tick.dispatch({type: "tick"});
|
||||||
|
}
|
||||||
|
|
||||||
|
force.on = function(type, listener) {
|
||||||
|
event[type].add(listener);
|
||||||
|
return force;
|
||||||
|
};
|
||||||
|
|
||||||
|
force.nodes = function(x) {
|
||||||
|
if (!arguments.length) return nodes;
|
||||||
|
nodes = x;
|
||||||
|
return force;
|
||||||
|
};
|
||||||
|
|
||||||
|
force.links = function(x) {
|
||||||
|
if (!arguments.length) return links;
|
||||||
|
links = x;
|
||||||
|
return force;
|
||||||
|
};
|
||||||
|
|
||||||
|
force.size = function(x) {
|
||||||
|
if (!arguments.length) return size;
|
||||||
|
size = x;
|
||||||
|
return force;
|
||||||
|
};
|
||||||
|
|
||||||
|
force.distance = function(d) {
|
||||||
|
if (!arguments.length) return distance;
|
||||||
|
distance = d;
|
||||||
|
return force;
|
||||||
|
};
|
||||||
|
|
||||||
|
force.start = function() {
|
||||||
|
var i,
|
||||||
|
j,
|
||||||
|
k,
|
||||||
|
n = nodes.length,
|
||||||
|
m = links.length,
|
||||||
|
w = size[0],
|
||||||
|
h = size[1],
|
||||||
|
o;
|
||||||
|
|
||||||
|
var paths = [];
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
o = nodes[i];
|
||||||
|
o.x = o.x || Math.random() * w;
|
||||||
|
o.y = o.y || Math.random() * h;
|
||||||
|
o.fixed = 0;
|
||||||
|
paths[i] = [];
|
||||||
|
for (j = 0; j < n; ++j) {
|
||||||
|
paths[i][j] = Infinity;
|
||||||
|
}
|
||||||
|
paths[i][i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < m; ++i) {
|
||||||
|
o = links[i];
|
||||||
|
paths[o.source][o.target] = 1;
|
||||||
|
paths[o.target][o.source] = 1;
|
||||||
|
o.source = nodes[o.source];
|
||||||
|
o.target = nodes[o.target];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Floyd-Warshall
|
||||||
|
for (k = 0; k < n; ++k) {
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
for (j = 0; j < n; ++j) {
|
||||||
|
paths[i][j] = Math.min(paths[i][j], paths[i][k] + paths[k][j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
distances = [];
|
||||||
|
for (i = 0; i < n; ++i) {
|
||||||
|
for (j = i + 1; j < n; ++j) {
|
||||||
|
distances.push({
|
||||||
|
source: nodes[i],
|
||||||
|
target: nodes[j],
|
||||||
|
distance: paths[i][j] * paths[i][j]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
distances.sort(function(a, b) {
|
||||||
|
return a.distance - b.distance;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (interval) clearInterval(interval);
|
||||||
|
interval = setInterval(tick, 24);
|
||||||
|
return force;
|
||||||
|
};
|
||||||
|
|
||||||
|
force.resume = function() {
|
||||||
|
alpha = .1;
|
||||||
|
if (!interval) interval = setInterval(tick, 24);
|
||||||
|
return force;
|
||||||
|
};
|
||||||
|
|
||||||
|
force.stop = function() {
|
||||||
|
interval = clearInterval(interval);
|
||||||
|
return force;
|
||||||
|
};
|
||||||
|
|
||||||
|
// use `node.call(force.drag)` to make nodes draggable
|
||||||
|
force.drag = function() {
|
||||||
|
var node, element;
|
||||||
|
|
||||||
|
this
|
||||||
|
.on("mouseover", function(d) { d.fixed = true; })
|
||||||
|
.on("mouseout", function(d) { if (d != node) d.fixed = false; })
|
||||||
|
.on("mousedown", mousedown);
|
||||||
|
|
||||||
|
d3.select(window)
|
||||||
|
.on("mousemove", mousemove)
|
||||||
|
.on("mouseup", mouseup);
|
||||||
|
|
||||||
|
function mousedown(d) {
|
||||||
|
(node = d).fixed = true;
|
||||||
|
element = this;
|
||||||
|
d3.event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousemove() {
|
||||||
|
if (!node) return;
|
||||||
|
var m = d3.svg.mouse(element);
|
||||||
|
node.x = m[0];
|
||||||
|
node.y = m[1];
|
||||||
|
force.resume(); // restart annealing
|
||||||
|
}
|
||||||
|
|
||||||
|
function mouseup() {
|
||||||
|
if (!node) return;
|
||||||
|
mousemove();
|
||||||
|
node.fixed = false;
|
||||||
|
node = element = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return force;
|
||||||
|
};
|
||||||
|
|
||||||
|
return force;
|
||||||
|
};
|
||||||
d3.layout.pie = function() {
|
d3.layout.pie = function() {
|
||||||
var value = Number,
|
var value = Number,
|
||||||
sort = null,
|
sort = null,
|
||||||
|
@ -407,4 +601,185 @@ function d3_layout_stackMaxIndex(array) {
|
||||||
function d3_layout_stackSum(p, d) {
|
function d3_layout_stackSum(p, d) {
|
||||||
return p + d.y;
|
return p + d.y;
|
||||||
}
|
}
|
||||||
|
// Squarified Treemaps by Mark Bruls, Kees Huizing, and Jarke J. van Wijk
|
||||||
|
d3.layout.treemap = function() {
|
||||||
|
var children = d3_layout_treemapChildren,
|
||||||
|
value = d3_layout_treemapValue,
|
||||||
|
round = Math.round,
|
||||||
|
size = [1, 1]; // width, height
|
||||||
|
|
||||||
|
// Recursively compute the node depth and value.
|
||||||
|
// Also converts the data representation into a standard tree structure.
|
||||||
|
// Also sorts child nodes by descending value to optimize squarification.
|
||||||
|
function sum(data, depth, nodes) {
|
||||||
|
var datas = children.call(treemap, data, depth),
|
||||||
|
node = {depth: depth, data: data};
|
||||||
|
nodes.push(node);
|
||||||
|
if (datas) {
|
||||||
|
var i = -1,
|
||||||
|
n = datas.length,
|
||||||
|
c = node.children = [],
|
||||||
|
v = 0,
|
||||||
|
j = depth + 1;
|
||||||
|
while (++i < n) {
|
||||||
|
d = sum(datas[i], j, nodes);
|
||||||
|
if (d.value > 0) { // ignore NaN, negative, etc.
|
||||||
|
c.push(d);
|
||||||
|
v += d.value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
node.value = v;
|
||||||
|
} else {
|
||||||
|
node.value = value.call(treemap, data, depth);
|
||||||
|
}
|
||||||
|
if (!depth) scale(node, size[0] * size[1] / node.value); // root
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively compute the node area based on value & scale.
|
||||||
|
function scale(node, k) {
|
||||||
|
var children = node.children;
|
||||||
|
node.area = node.value * k;
|
||||||
|
if (children) {
|
||||||
|
var i = -1,
|
||||||
|
n = children.length;
|
||||||
|
while (++i < n) scale(children[i], k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recursively arranges the specified node's children into squarified rows.
|
||||||
|
function squarify(node) {
|
||||||
|
if (!node.children) return;
|
||||||
|
var rect = {x: node.x, y: node.y, dx: node.dx, dy: node.dy},
|
||||||
|
row = [],
|
||||||
|
children = node.children.slice().sort(d3_layout_treemapSort),
|
||||||
|
child,
|
||||||
|
best = Infinity, // the best row score so far
|
||||||
|
score, // the current row score
|
||||||
|
u = Math.min(rect.dx, rect.dy), // initial orientation
|
||||||
|
n;
|
||||||
|
row.area = 0;
|
||||||
|
while ((n = children.length) > 0) {
|
||||||
|
row.push(child = children[n - 1]);
|
||||||
|
row.area += child.area;
|
||||||
|
if ((score = worst(row, u)) <= best) { // continue with this orientation
|
||||||
|
children.pop();
|
||||||
|
best = score;
|
||||||
|
} else { // abort, and try a different orientation
|
||||||
|
row.area -= row.pop().area;
|
||||||
|
position(row, u, rect, false);
|
||||||
|
u = Math.min(rect.dx, rect.dy);
|
||||||
|
row.length = row.area = 0;
|
||||||
|
best = Infinity;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (row.length) {
|
||||||
|
position(row, u, rect, true);
|
||||||
|
row.length = row.area = 0;
|
||||||
|
}
|
||||||
|
node.children.forEach(squarify);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Computes the score for the specified row, as the worst aspect ratio.
|
||||||
|
function worst(row, u) {
|
||||||
|
var s = row.area,
|
||||||
|
r,
|
||||||
|
rmax = 0,
|
||||||
|
rmin = Infinity,
|
||||||
|
i = -1,
|
||||||
|
n = row.length;
|
||||||
|
while (++i < n) {
|
||||||
|
r = row[i].area;
|
||||||
|
if (r < rmin) rmin = r;
|
||||||
|
if (r > rmax) rmax = r;
|
||||||
|
}
|
||||||
|
s *= s;
|
||||||
|
u *= u;
|
||||||
|
return Math.max((u * rmax) / s, s / (u * rmin));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Positions the specified row of nodes. Modifies `rect`.
|
||||||
|
function position(row, u, rect, flush) {
|
||||||
|
var i = -1,
|
||||||
|
n = row.length,
|
||||||
|
x = rect.x,
|
||||||
|
y = rect.y,
|
||||||
|
v = u ? round(row.area / u) : 0,
|
||||||
|
o;
|
||||||
|
if (u == rect.dx) { // horizontal subdivision
|
||||||
|
if (flush || v > rect.dy) v = rect.dy; // over+underflow
|
||||||
|
while (++i < n) {
|
||||||
|
o = row[i];
|
||||||
|
o.x = x;
|
||||||
|
o.y = y;
|
||||||
|
o.dy = v;
|
||||||
|
x += o.dx = round(o.area / v);
|
||||||
|
}
|
||||||
|
o.dx += rect.x + rect.dx - x; // rounding error
|
||||||
|
rect.y += v;
|
||||||
|
rect.dy -= v;
|
||||||
|
} else { // vertical subdivision
|
||||||
|
if (flush || v > rect.dx) v = rect.dx; // over+underflow
|
||||||
|
while (++i < n) {
|
||||||
|
o = row[i];
|
||||||
|
o.x = x;
|
||||||
|
o.y = y;
|
||||||
|
o.dx = v;
|
||||||
|
y += o.dy = round(o.area / v);
|
||||||
|
}
|
||||||
|
o.dy += rect.y + rect.dy - y; // rounding error
|
||||||
|
rect.x += v;
|
||||||
|
rect.dx -= v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function treemap(d) {
|
||||||
|
var nodes = [],
|
||||||
|
root = sum(d, 0, nodes);
|
||||||
|
root.x = 0;
|
||||||
|
root.y = 0;
|
||||||
|
root.dx = size[0];
|
||||||
|
root.dy = size[1];
|
||||||
|
squarify(root);
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
treemap.children = function(x) {
|
||||||
|
if (!arguments.length) return children;
|
||||||
|
children = x;
|
||||||
|
return treemap;
|
||||||
|
};
|
||||||
|
|
||||||
|
treemap.value = function(x) {
|
||||||
|
if (!arguments.length) return value;
|
||||||
|
value = x;
|
||||||
|
return treemap;
|
||||||
|
};
|
||||||
|
|
||||||
|
treemap.size = function(x) {
|
||||||
|
if (!arguments.length) return size;
|
||||||
|
size = x;
|
||||||
|
return treemap;
|
||||||
|
};
|
||||||
|
|
||||||
|
treemap.round = function(x) {
|
||||||
|
if (!arguments.length) return round != Number;
|
||||||
|
round = x ? Math.round : Number;
|
||||||
|
return treemap;
|
||||||
|
};
|
||||||
|
|
||||||
|
return treemap;
|
||||||
|
};
|
||||||
|
|
||||||
|
function d3_layout_treemapChildren(d) {
|
||||||
|
return d.children;
|
||||||
|
}
|
||||||
|
|
||||||
|
function d3_layout_treemapValue(d) {
|
||||||
|
return d.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function d3_layout_treemapSort(a, b) {
|
||||||
|
return b.area - a.area;
|
||||||
|
}
|
||||||
})()
|
})()
|
|
@ -1,7 +1,14 @@
|
||||||
(function(){function A(a){return a.reduce(B,0)}function C(a){for(var j=1,f=0,c=a[0].y,i,e=a.length;j<e;++j)if((i=a[j].y)>c){f=j;c=i}return f}function B(a,j){return a+j.y}d3.layout={};d3.layout.chord=function(){function a(){var g={},l=[],t=d3.range(b),q=[],r,n,w,o,s;c=[];i=[];r=0;for(o=-1;++o<b;){n=0;for(s=-1;++s<b;)n+=e[o][s];l.push(n);q.push(d3.range(b));r+=n}k&&t.sort(function(x,u){return k(l[x],l[u])});m&&q.forEach(function(x,u){x.sort(function(D,E){return m(e[u][D],e[u][E])})});r=(2*Math.PI-h*
|
(function(){function A(c){return c.reduce(B,0)}function C(c){for(var h=1,n=0,i=c[0].y,o,l=c.length;h<l;++h)if((o=c[h].y)>i){n=h;i=o}return n}function B(c,h){return c+h.y}function D(c){return c.children}function E(c){return c.value}function F(c,h){return h.area-c.area}d3.layout={};d3.layout.chord=function(){function c(){var a={},j=[],f=d3.range(g),s=[],t,k,q,r,u;i=[];o=[];t=0;for(r=-1;++r<g;){k=0;for(u=-1;++u<g;)k+=l[r][u];j.push(k);s.push(d3.range(g));t+=k}p&&f.sort(function(y,x){return p(j[y],j[x])});
|
||||||
b)/r;n=0;for(o=-1;++o<b;){w=n;for(s=-1;++s<b;){var v=t[o],y=q[o][s],z=e[v][y];g[v+"-"+y]={index:v,subindex:y,startAngle:n,endAngle:n+=z*r,value:z}}i.push({index:v,startAngle:w,endAngle:n,value:(n-w)/r});n+=h}for(o=-1;++o<b;)for(s=o-1;++s<b;){t=g[o+"-"+s];q=g[s+"-"+o];if(t.value||q.value)c.push({source:t,target:q})}p&&j()}function j(){c.sort(function(g,l){g=Math.min(g.source.value,g.target.value);l=Math.min(l.source.value,l.target.value);return p(g,l)})}var f={},c,i,e,b,h=0,k,m,p;f.matrix=function(g){if(!arguments.length)return e;
|
e&&s.forEach(function(y,x){y.sort(function(G,H){return e(l[x][G],l[x][H])})});t=(2*Math.PI-m*g)/t;k=0;for(r=-1;++r<g;){q=k;for(u=-1;++u<g;){var v=f[r],w=s[r][u],z=l[v][w];a[v+"-"+w]={index:v,subindex:w,startAngle:k,endAngle:k+=z*t,value:z}}o.push({index:v,startAngle:q,endAngle:k,value:(k-q)/t});k+=m}for(r=-1;++r<g;)for(u=r-1;++u<g;){f=a[r+"-"+u];s=a[u+"-"+r];if(f.value||s.value)i.push({source:f,target:s})}b&&h()}function h(){i.sort(function(a,j){a=Math.min(a.source.value,a.target.value);j=Math.min(j.source.value,
|
||||||
b=(e=g)&&e.length;c=i=null;return f};f.padding=function(g){if(!arguments.length)return h;h=g;c=i=null;return f};f.sortGroups=function(g){if(!arguments.length)return k;k=g;c=i=null;return f};f.sortSubgroups=function(g){if(!arguments.length)return m;m=g;c=null;return f};f.sortChords=function(g){if(!arguments.length)return p;p=g;c&&j();return f};f.chords=function(){c||a();return c};f.groups=function(){i||a();return i};return f};d3.layout.pie=function(){function a(e){var b=+(typeof c=="function"?c.apply(this,
|
j.target.value);return b(a,j)})}var n={},i,o,l,g,m=0,p,e,b;n.matrix=function(a){if(!arguments.length)return l;g=(l=a)&&l.length;i=o=null;return n};n.padding=function(a){if(!arguments.length)return m;m=a;i=o=null;return n};n.sortGroups=function(a){if(!arguments.length)return p;p=a;i=o=null;return n};n.sortSubgroups=function(a){if(!arguments.length)return e;e=a;i=null;return n};n.sortChords=function(a){if(!arguments.length)return b;b=a;i&&h();return n};n.chords=function(){i||c();return i};n.groups=
|
||||||
arguments):c),h=(typeof i=="function"?i.apply(this,arguments):i)-c,k=d3.range(e.length);f!=null&&k.sort(function(g,l){return f(e[g],e[l])});var m=e.map(j);h/=m.reduce(function(g,l){return g+l},0);var p=k.map(function(g){return{value:d=m[g],startAngle:b,endAngle:b+=d*h}});return e.map(function(g,l){return p[k[l]]})}var j=Number,f=null,c=0,i=2*Math.PI;a.value=function(e){if(!arguments.length)return j;j=e;return a};a.sort=function(e){if(!arguments.length)return f;f=e;return a};a.startAngle=function(e){if(!arguments.length)return c;
|
function(){o||c();return o};return n};d3.layout.force=function(){function c(){var b=e.length,a,j,f,s,t,k,q;for(a=0;a<b;++a){j=e[a];f=j.source;s=j.target;k=s.x-f.x;q=s.y-f.y;if(t=Math.sqrt(k*k+q*q)){t=o/(j.distance*j.distance)*(t-l*j.distance)/t;k*=t;q*=t;if(f.fixed){if(!s.fixed){s.x-=k;s.y-=q}}else if(s.fixed){f.x+=k;f.y+=q}else{f.x+=k;f.y+=q;s.x-=k;s.y-=q}}}if((o*=0.99)<1.0E-6)h.stop();n.tick.dispatch({type:"tick"})}var h={},n=d3.dispatch("tick"),i=[1,1],o=0.5,l=30,g,m,p,e;h.on=function(b,a){n[b].add(a);
|
||||||
c=e;return a};a.endAngle=function(e){if(!arguments.length)return i;i=e;return a};return a};d3.layout.stack=function(){function a(c){var i=c.length,e=c[0].length,b,h,k,m=F[j](c);G[f](c,m);for(h=0;h<e;++h){b=1;for(k=c[m[0]][h].y0;b<i;++b)c[m[b]][h].y0=k+=c[m[b-1]][h].y}return c}var j="default",f="zero";a.order=function(c){if(!arguments.length)return j;j=c;return a};a.offset=function(c){if(!arguments.length)return f;f=c;return a};return a};var F={"inside-out":function(a){var j=a.length,f,c=a.map(C),
|
return h};h.nodes=function(b){if(!arguments.length)return m;m=b;return h};h.links=function(b){if(!arguments.length)return p;p=b;return h};h.size=function(b){if(!arguments.length)return i;i=b;return h};h.distance=function(b){if(!arguments.length)return l;l=b;return h};h.start=function(){var b,a,j,f=m.length;j=p.length;var s=i[0],t=i[1],k=[];for(b=0;b<f;++b){a=m[b];a.x=a.x||Math.random()*s;a.y=a.y||Math.random()*t;a.fixed=0;k[b]=[];for(a=0;a<f;++a)k[b][a]=Infinity;k[b][b]=0}for(b=0;b<j;++b){a=p[b];
|
||||||
i=a.map(A),e=d3.range(j).sort(function(p,g){return c[p]-c[g]}),b=0,h=0,k=[],m=[];for(a=0;a<j;a++){f=e[a];if(b<h){b+=i[f];k.push(f)}else{h+=i[f];m.push(f)}}return m.reverse().concat(k)},reverse:function(a){return d3.range(a.length).reverse()},"default":function(a){return d3.range(a.length)}},G={silhouette:function(a,j){var f=a.length,c=a[0].length,i=[],e=0,b,h,k;for(h=0;h<c;++h){for(k=b=0;b<f;b++)k+=a[b][h].y;if(k>e)e=k;i.push(k)}h=0;for(b=j[0];h<c;++h)a[b][h].y0=(e-i[h])/2},wiggle:function(a,j){var f=
|
k[a.source][a.target]=1;k[a.target][a.source]=1;a.source=m[a.source];a.target=m[a.target]}for(j=0;j<f;++j)for(b=0;b<f;++b)for(a=0;a<f;++a)k[b][a]=Math.min(k[b][a],k[b][j]+k[j][a]);e=[];for(b=0;b<f;++b)for(a=b+1;a<f;++a)e.push({source:m[b],target:m[a],distance:k[b][a]*k[b][a]});e.sort(function(q,r){return q.distance-r.distance});g&&clearInterval(g);g=setInterval(c,24);return h};h.resume=function(){o=0.1;g||(g=setInterval(c,24));return h};h.stop=function(){g=clearInterval(g);return h};h.drag=function(){function b(){if(a){var f=
|
||||||
a.length,c=a[0],i=c.length,e,b,h,k,m,p=j[0],g,l,t,q,r,n;a[p][0].y0=r=n=0;for(b=1;b<i;++b){for(g=e=0;e<f;++e)g+=a[e][b].y;l=e=0;for(q=c[b].x-c[b-1].x;e<f;++e){h=0;k=j[e];for(t=(a[k][b].y-a[k][b-1].y)/(2*q);h<e;++h)t+=(a[m=j[h]][b].y-a[m][b-1].y)/q;l+=t*a[k][b].y}a[p][b].y0=r-=g?l/g*q:0;if(r<n)n=r}for(b=0;b<i;++b)a[p][b].y0-=n},zero:function(a,j){for(var f=0,c=a[0].length,i=j[0];f<c;++f)a[i][f].y0=0}}})();
|
d3.svg.mouse(j);a.x=f[0];a.y=f[1];h.resume()}}var a,j;this.on("mouseover",function(f){f.fixed=true}).on("mouseout",function(f){if(f!=a)f.fixed=false}).on("mousedown",function(f){(a=f).fixed=true;j=this;d3.event.preventDefault()});d3.select(window).on("mousemove",b).on("mouseup",function(){if(a){b();a.fixed=false;a=j=null}});return h};return h};d3.layout.pie=function(){function c(l){var g=+(typeof i=="function"?i.apply(this,arguments):i),m=(typeof o=="function"?o.apply(this,arguments):o)-i,p=d3.range(l.length);
|
||||||
|
n!=null&&p.sort(function(a,j){return n(l[a],l[j])});var e=l.map(h);m/=e.reduce(function(a,j){return a+j},0);var b=p.map(function(a){return{value:d=e[a],startAngle:g,endAngle:g+=d*m}});return l.map(function(a,j){return b[p[j]]})}var h=Number,n=null,i=0,o=2*Math.PI;c.value=function(l){if(!arguments.length)return h;h=l;return c};c.sort=function(l){if(!arguments.length)return n;n=l;return c};c.startAngle=function(l){if(!arguments.length)return i;i=l;return c};c.endAngle=function(l){if(!arguments.length)return o;
|
||||||
|
o=l;return c};return c};d3.layout.stack=function(){function c(i){var o=i.length,l=i[0].length,g,m,p,e=I[h](i);J[n](i,e);for(m=0;m<l;++m){g=1;for(p=i[e[0]][m].y0;g<o;++g)i[e[g]][m].y0=p+=i[e[g-1]][m].y}return i}var h="default",n="zero";c.order=function(i){if(!arguments.length)return h;h=i;return c};c.offset=function(i){if(!arguments.length)return n;n=i;return c};return c};var I={"inside-out":function(c){var h=c.length,n,i=c.map(C),o=c.map(A),l=d3.range(h).sort(function(b,a){return i[b]-i[a]}),g=0,
|
||||||
|
m=0,p=[],e=[];for(c=0;c<h;c++){n=l[c];if(g<m){g+=o[n];p.push(n)}else{m+=o[n];e.push(n)}}return e.reverse().concat(p)},reverse:function(c){return d3.range(c.length).reverse()},"default":function(c){return d3.range(c.length)}},J={silhouette:function(c,h){var n=c.length,i=c[0].length,o=[],l=0,g,m,p;for(m=0;m<i;++m){for(p=g=0;g<n;g++)p+=c[g][m].y;if(p>l)l=p;o.push(p)}m=0;for(g=h[0];m<i;++m)c[g][m].y0=(l-o[m])/2},wiggle:function(c,h){var n=c.length,i=c[0],o=i.length,l,g,m,p,e,b=h[0],a,j,f,s,t,k;c[b][0].y0=
|
||||||
|
t=k=0;for(g=1;g<o;++g){for(a=l=0;l<n;++l)a+=c[l][g].y;j=l=0;for(s=i[g].x-i[g-1].x;l<n;++l){m=0;p=h[l];for(f=(c[p][g].y-c[p][g-1].y)/(2*s);m<l;++m)f+=(c[e=h[m]][g].y-c[e][g-1].y)/s;j+=f*c[p][g].y}c[b][g].y0=t-=a?j/a*s:0;if(t<k)k=t}for(g=0;g<o;++g)c[b][g].y0-=k},zero:function(c,h){for(var n=0,i=c[0].length,o=h[0];n<i;++n)c[o][n].y0=0}};d3.layout.treemap=function(){function c(e,b,a){var j=l.call(o,e,b),f={depth:b,data:e};a.push(f);if(j){e=-1;for(var s=j.length,t=f.children=[],k=0,q=b+1;++e<s;){d=c(j[e],
|
||||||
|
q,a);if(d.value>0){t.push(d);k+=d.value}}f.value=k}else f.value=g.call(o,e,b);b||h(f,p[0]*p[1]/f.value);return f}function h(e,b){var a=e.children;e.area=e.value*b;if(a)for(var j=-1,f=a.length;++j<f;)h(a[j],b)}function n(e){if(e.children){var b={x:e.x,y:e.y,dx:e.dx,dy:e.dy},a=[],j=e.children.slice().sort(F),f,s=Infinity,t=Math.min(b.dx,b.dy);for(a.area=0;(f=j.length)>0;){a.push(f=j[f-1]);a.area+=f.area;f=t;for(var k=a.area,q=void 0,r=0,u=Infinity,v=-1,w=a.length;++v<w;){q=a[v].area;if(q<u)u=q;if(q>
|
||||||
|
r)r=q}k*=k;f*=f;if((f=Math.max(f*r/k,k/(f*u)))<=s){j.pop();s=f}else{a.area-=a.pop().area;i(a,t,b,false);t=Math.min(b.dx,b.dy);a.length=a.area=0;s=Infinity}}if(a.length){i(a,t,b,true);a.length=a.area=0}e.children.forEach(n)}}function i(e,b,a,j){var f=-1,s=e.length,t=a.x,k=a.y,q=b?m(e.area/b):0,r;if(b==a.dx){if(j||q>a.dy)q=a.dy;for(;++f<s;){r=e[f];r.x=t;r.y=k;r.dy=q;t+=r.dx=m(r.area/q)}r.dx+=a.x+a.dx-t;a.y+=q;a.dy-=q}else{if(j||q>a.dx)q=a.dx;for(;++f<s;){r=e[f];r.x=t;r.y=k;r.dx=q;k+=r.dy=m(r.area/q)}r.dy+=
|
||||||
|
a.y+a.dy-k;a.x+=q;a.dx-=q}}function o(e){var b=[];e=c(e,0,b);e.x=0;e.y=0;e.dx=p[0];e.dy=p[1];n(e);return b}var l=D,g=E,m=Math.round,p=[1,1];o.children=function(e){if(!arguments.length)return l;l=e;return o};o.value=function(e){if(!arguments.length)return g;g=e;return o};o.size=function(e){if(!arguments.length)return p;p=e;return o};o.round=function(e){if(!arguments.length)return m!=Number;m=e?Math.round:Number;return o};return o}})();
|
||||||
|
|
|
@ -1,39 +1,39 @@
|
||||||
(function(){function ua(a){for(var b=-1,d=a.length,g=[];++b<d;)g.push(a[b]);return g}function v(a){return typeof a=="function"?a:function(){return a}}function C(a,b){return function(){var d=b.apply(a,arguments);return arguments.length?a:d}}function va(a){return a==null}function da(a){return a.replace(/(^\s+)|(\s+$)/g,"").replace(/\s+/g," ")}function ea(a){arguments[0]=this;a.apply(this,arguments);return this}function wa(){var a={},b=[];a.add=function(d){for(var g=0;g<b.length;g++)if(b[g].listener==
|
(function(){function ua(a){for(var b=-1,d=a.length,g=[];++b<d;)g.push(a[b]);return g}function v(a){return typeof a=="function"?a:function(){return a}}function C(a,b){return function(){var d=b.apply(a,arguments);return arguments.length?a:d}}function va(a){return a==null}function da(a){return a.replace(/(^\s+)|(\s+$)/g,"").replace(/\s+/g," ")}function ea(a){arguments[0]=this;a.apply(this,arguments);return this}function wa(){var a={},b=[];a.add=function(d){for(var g=0;g<b.length;g++)if(b[g].listener==
|
||||||
d)return a;b.push({listener:d,on:true});return a};a.remove=function(d){for(var g=0;g<b.length;g++){var e=b[g];if(e.listener==d){e.on=false;b=b.slice(0,g).concat(b.slice(g+1));break}}return a};a.dispatch=function(){for(var d=b,g=0,e=d.length;g<e;g++){var c=d[g];c.on&&c.listener.apply(this,arguments)}};return a}function fa(a){return function(b){return 1-a(1-b)}}function ga(a){return function(b){return 0.5*(b<0.5?a(2*b):2-a(2-2*b))}}function xa(a){return a}function R(a){return function(b){return Math.pow(b,
|
d)return a;b.push({listener:d,on:true});return a};a.remove=function(d){for(var g=0;g<b.length;g++){var e=b[g];if(e.listener==d){e.on=false;b=b.slice(0,g).concat(b.slice(g+1));break}}return a};a.dispatch=function(){for(var d=b,g=0,e=d.length;g<e;g++){var c=d[g];c.on&&c.listener.apply(this,arguments)}};return a}function fa(a){for(var b=a.lastIndexOf("."),d=b>=0?a.substring(b):(b=a.length,""),g=[];b>0;)g.push(a.substring(b-=3,b+3));return g.reverse().join(",")+d}function ga(a){return function(b){return 1-
|
||||||
a)}}function ya(a){return 1-Math.cos(a*Math.PI/2)}function za(a){return a?Math.pow(2,10*(a-1))-0.0010:0}function Aa(a){return 1-Math.sqrt(1-a*a)}function Ba(a){return a<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+0.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+0.9375:7.5625*(a-=2.625/2.75)*a+0.984375}function J(a,b,d){return{r:a,g:b,b:d,toString:Ca}}function Ca(){return"#"+S(this.r)+S(this.g)+S(this.b)}function S(a){return a<16?"0"+a.toString(16):a.toString(16)}function T(a,b,d){var g=0,e=0,c=0,f,h;
|
a(1-b)}}function ha(a){return function(b){return 0.5*(b<0.5?a(2*b):2-a(2-2*b))}}function xa(a){return a}function R(a){return function(b){return Math.pow(b,a)}}function ya(a){return 1-Math.cos(a*Math.PI/2)}function za(a){return a?Math.pow(2,10*(a-1))-0.0010:0}function Aa(a){return 1-Math.sqrt(1-a*a)}function Ba(a){return a<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+0.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+0.9375:7.5625*(a-=2.625/2.75)*a+0.984375}function J(a,b,d){return{r:a,g:b,b:d,toString:Ca}}
|
||||||
if(f=/([a-z]+)\((.*)\)/i.exec(a)){h=f[2].split(",");switch(f[1]){case "hsl":return d(parseFloat(h[0]),parseFloat(h[1])/100,parseFloat(h[2])/100);case "rgb":return b(U(h[0]),U(h[1]),U(h[2]))}}if(d=G[a])return b(d.r,d.g,d.b);if(a!=null&&a.charAt(0)=="#"){if(a.length==4){g=a.charAt(1);g+=g;e=a.charAt(2);e+=e;c=a.charAt(3);c+=c}else if(a.length==7){g=a.substring(1,3);e=a.substring(3,5);c=a.substring(5,7)}g=parseInt(g,16);e=parseInt(e,16);c=parseInt(c,16)}return b(g,e,c)}function Da(a,b,d){var g=Math.min(a/=
|
function Ca(){return"#"+S(this.r)+S(this.g)+S(this.b)}function S(a){return a<16?"0"+a.toString(16):a.toString(16)}function T(a,b,d){var g=0,e=0,c=0,f,h;if(f=/([a-z]+)\((.*)\)/i.exec(a)){h=f[2].split(",");switch(f[1]){case "hsl":return d(parseFloat(h[0]),parseFloat(h[1])/100,parseFloat(h[2])/100);case "rgb":return b(U(h[0]),U(h[1]),U(h[2]))}}if(d=G[a])return b(d.r,d.g,d.b);if(a!=null&&a.charAt(0)=="#"){if(a.length==4){g=a.charAt(1);g+=g;e=a.charAt(2);e+=e;c=a.charAt(3);c+=c}else if(a.length==7){g=
|
||||||
255,b/=255,d/=255),e=Math.max(a,b,d),c=e-g,f=(e+g)/2;if(c){g=f<0.5?c/(e+g):c/(2-e-g);a=a==e?(b-d)/c+(b<d?6:0):b==e?(d-a)/c+2:(a-b)/c+4;a*=60}else g=a=0;return V(a,g,f)}function U(a){var b=parseFloat(a);return a.charAt(a.length-1)=="%"?Math.round(b*2.55):b}function V(a,b,d){return{h:a,s:b,l:d,toString:Ea}}function Ea(){return"hsl("+this.h+","+this.s*100+"%,"+this.l*100+"%)"}function W(a,b,d){function g(f){if(f>360)f-=360;else if(f<0)f+=360;if(f<60)return e+(c-e)*f/60;if(f<180)return c;if(f<240)return e+
|
a.substring(1,3);e=a.substring(3,5);c=a.substring(5,7)}g=parseInt(g,16);e=parseInt(e,16);c=parseInt(c,16)}return b(g,e,c)}function Da(a,b,d){var g=Math.min(a/=255,b/=255,d/=255),e=Math.max(a,b,d),c=e-g,f=(e+g)/2;if(c){g=f<0.5?c/(e+g):c/(2-e-g);a=a==e?(b-d)/c+(b<d?6:0):b==e?(d-a)/c+2:(a-b)/c+4;a*=60}else g=a=0;return V(a,g,f)}function U(a){var b=parseFloat(a);return a.charAt(a.length-1)=="%"?Math.round(b*2.55):b}function V(a,b,d){return{h:a,s:b,l:d,toString:Ea}}function Ea(){return"hsl("+this.h+","+
|
||||||
(c-e)*(240-f)/60;return e}var e,c;a%=360;if(a<0)a+=360;b=b<0?0:b>1?1:b;d=d<0?0:d>1?1:d;c=d<=0.5?d*(1+b):d+b-d*b;e=2*d-c;return J(Math.round(g(a+120)*255),Math.round(g(a)*255),Math.round(g(a-120)*255))}function y(a){function b(e){for(var c=[],f,h,i,k,j=0,o=a.length;j<o;j++){i=a[j];c.push(f=[]);f.parentNode=i.parentNode;f.parentData=i.parentData;for(var p=0,m=i.length;p<m;p++)if(k=i[p]){f.push(h=e(k));if(h&&"__data__"in k)h.__data__=k.__data__}else f.push(null)}return y(c)}function d(e){for(var c=[],
|
this.s*100+"%,"+this.l*100+"%)"}function W(a,b,d){function g(f){if(f>360)f-=360;else if(f<0)f+=360;if(f<60)return e+(c-e)*f/60;if(f<180)return c;if(f<240)return e+(c-e)*(240-f)/60;return e}var e,c;a%=360;if(a<0)a+=360;b=b<0?0:b>1?1:b;d=d<0?0:d>1?1:d;c=d<=0.5?d*(1+b):d+b-d*b;e=2*d-c;return J(Math.round(g(a+120)*255),Math.round(g(a)*255),Math.round(g(a-120)*255))}function y(a){function b(e){for(var c=[],f,h,i,k,j=0,o=a.length;j<o;j++){i=a[j];c.push(f=[]);f.parentNode=i.parentNode;f.parentData=i.parentData;
|
||||||
f,h,i,k=0,j=a.length;k<j;k++){h=a[k];for(var o=0,p=h.length;o<p;o++)if(i=h[o]){c.push(f=e(i));f.parentNode=i;f.parentData=i.__data__}}return y(c)}function g(e){for(var c=0,f=a.length;c<f;c++)for(var h=a[c],i=0,k=h.length;i<k;i++){var j=h[i];if(j)return e.call(j,j.__data__,i)}return null}a.select=function(e){return b(function(c){return D(e,c)})};a.selectAll=function(e){return d(function(c){return ha(e,c)})};a.filter=function(e){for(var c=[],f,h,i,k=0,j=a.length;k<j;k++){h=a[k];c.push(f=[]);f.parentNode=
|
for(var p=0,m=i.length;p<m;p++)if(k=i[p]){f.push(h=e(k));if(h&&"__data__"in k)h.__data__=k.__data__}else f.push(null)}return y(c)}function d(e){for(var c=[],f,h,i,k=0,j=a.length;k<j;k++){h=a[k];for(var o=0,p=h.length;o<p;o++)if(i=h[o]){c.push(f=e(i));f.parentNode=i;f.parentData=i.__data__}}return y(c)}function g(e){for(var c=0,f=a.length;c<f;c++)for(var h=a[c],i=0,k=h.length;i<k;i++){var j=h[i];if(j)return e.call(j,j.__data__,i)}return null}a.select=function(e){return b(function(c){return D(e,c)})};
|
||||||
h.parentNode;f.parentData=h.parentData;for(var o=0,p=h.length;o<p;o++)if((i=h[o])&&e.call(i,i.__data__,o))f.push(i)}return y(c)};a.map=function(e){for(var c,f,h=0,i=a.length;h<i;h++){c=a[h];for(var k=0,j=c.length;k<j;k++)if(f=c[k])f.__data__=e.call(f,f.__data__,k)}return a};a.data=function(e,c){function f(m,n){var l=0,q=m.length,r=n.length,t=Math.min(q,r),u=Math.max(q,r),s=[],z=[],w=[],x,A;if(c){t={};u=[];var E;A=n.length;for(l=0;l<q;l++){E=c.call(x=m[l],x.__data__,l);if(E in t)w[A++]=m[l];else{t[E]=
|
a.selectAll=function(e){return d(function(c){return ia(e,c)})};a.filter=function(e){for(var c=[],f,h,i,k=0,j=a.length;k<j;k++){h=a[k];c.push(f=[]);f.parentNode=h.parentNode;f.parentData=h.parentData;for(var o=0,p=h.length;o<p;o++)if((i=h[o])&&e.call(i,i.__data__,o))f.push(i)}return y(c)};a.map=function(e){for(var c,f,h=0,i=a.length;h<i;h++){c=a[h];for(var k=0,j=c.length;k<j;k++)if(f=c[k])f.__data__=e.call(f,f.__data__,k)}return a};a.data=function(e,c){function f(m,n){var l=0,q=m.length,r=n.length,
|
||||||
x;u.push(E)}}for(l=0;l<r;l++){if(x=t[E=c.call(n,A=n[l],l)]){x.__data__=A;s[l]=x;z[l]=w[l]=null}else{z[l]={__data__:A};s[l]=w[l]=null}delete t[E]}for(l=0;l<q;l++)if(u[l]in t)w[l]=m[l]}else{for(;l<t;l++){x=m[l];A=n[l];if(x){x.__data__=A;s[l]=x;z[l]=w[l]=null}else{z[l]={__data__:A};s[l]=w[l]=null}}for(;l<r;l++){z[l]={__data__:n[l]};s[l]=w[l]=null}for(;l<u;l++){w[l]=m[l];z[l]=s[l]=null}}z.parentNode=s.parentNode=w.parentNode=m.parentNode;z.parentData=s.parentData=w.parentData=m.parentData;h.push(z);i.push(s);
|
t=Math.min(q,r),u=Math.max(q,r),s=[],z=[],w=[],x,A;if(c){t={};u=[];var E;A=n.length;for(l=0;l<q;l++){E=c.call(x=m[l],x.__data__,l);if(E in t)w[A++]=m[l];else{t[E]=x;u.push(E)}}for(l=0;l<r;l++){if(x=t[E=c.call(n,A=n[l],l)]){x.__data__=A;s[l]=x;z[l]=w[l]=null}else{z[l]={__data__:A};s[l]=w[l]=null}delete t[E]}for(l=0;l<q;l++)if(u[l]in t)w[l]=m[l]}else{for(;l<t;l++){x=m[l];A=n[l];if(x){x.__data__=A;s[l]=x;z[l]=w[l]=null}else{z[l]={__data__:A};s[l]=w[l]=null}}for(;l<r;l++){z[l]={__data__:n[l]};s[l]=w[l]=
|
||||||
k.push(w)}var h=[],i=[],k=[],j=-1,o=a.length,p;if(typeof e=="function")for(;++j<o;)f(p=a[j],e.call(p,p.parentData,j));else for(;++j<o;)f(p=a[j],e);j=y(i);j.enter=function(){return Fa(h)};j.exit=function(){return y(k)};return j};a.each=function(e){for(var c=0,f=a.length;c<f;c++)for(var h=a[c],i=0,k=h.length;i<k;i++){var j=h[i];j&&e.call(j,j.__data__,i)}return a};a.empty=function(){return!g(function(){return true})};a.node=function(){return g(function(){return this})};a.attr=function(e,c){function f(){this.removeAttribute(e)}
|
null}for(;l<u;l++){w[l]=m[l];z[l]=s[l]=null}}z.parentNode=s.parentNode=w.parentNode=m.parentNode;z.parentData=s.parentData=w.parentData=m.parentData;h.push(z);i.push(s);k.push(w)}var h=[],i=[],k=[],j=-1,o=a.length,p;if(typeof e=="function")for(;++j<o;)f(p=a[j],e.call(p,p.parentData,j));else for(;++j<o;)f(p=a[j],e);j=y(i);j.enter=function(){return Fa(h)};j.exit=function(){return y(k)};return j};a.each=function(e){for(var c=0,f=a.length;c<f;c++)for(var h=a[c],i=0,k=h.length;i<k;i++){var j=h[i];j&&e.call(j,
|
||||||
function h(){this.removeAttributeNS(e.space,e.local)}function i(){this.setAttribute(e,c)}function k(){this.setAttributeNS(e.space,e.local,c)}function j(){var p=c.apply(this,arguments);p==null?this.removeAttribute(e):this.setAttribute(e,p)}function o(){var p=c.apply(this,arguments);p==null?this.removeAttributeNS(e.space,e.local):this.setAttributeNS(e.space,e.local,p)}e=d3.ns.qualify(e);if(arguments.length<2)return g(e.local?function(){return this.getAttributeNS(e.space,e.local)}:function(){return this.getAttribute(e)});
|
j.__data__,i)}return a};a.empty=function(){return!g(function(){return true})};a.node=function(){return g(function(){return this})};a.attr=function(e,c){function f(){this.removeAttribute(e)}function h(){this.removeAttributeNS(e.space,e.local)}function i(){this.setAttribute(e,c)}function k(){this.setAttributeNS(e.space,e.local,c)}function j(){var p=c.apply(this,arguments);p==null?this.removeAttribute(e):this.setAttribute(e,p)}function o(){var p=c.apply(this,arguments);p==null?this.removeAttributeNS(e.space,
|
||||||
return a.each(c==null?e.local?h:f:typeof c=="function"?e.local?o:j:e.local?k:i)};a.classed=function(e,c){function f(){var j=this.className;k.lastIndex=0;if(!k.test(j))this.className=da(j+" "+e)}function h(){var j=da(this.className.replace(k," "));this.className=j.length?j:null}function i(){(c.apply(this,arguments)?f:h).call(this)}var k=RegExp("(^|\\s+)"+d3.requote(e)+"(\\s+|$)","g");if(arguments.length<2)return g(function(){k.lastIndex=0;return k.test(this.className)});return a.each(typeof c=="function"?
|
e.local):this.setAttributeNS(e.space,e.local,p)}e=d3.ns.qualify(e);if(arguments.length<2)return g(e.local?function(){return this.getAttributeNS(e.space,e.local)}:function(){return this.getAttribute(e)});return a.each(c==null?e.local?h:f:typeof c=="function"?e.local?o:j:e.local?k:i)};a.classed=function(e,c){function f(){var j=this.className;k.lastIndex=0;if(!k.test(j))this.className=da(j+" "+e)}function h(){var j=da(this.className.replace(k," "));this.className=j.length?j:null}function i(){(c.apply(this,
|
||||||
i:c?f:h)};a.style=function(e,c,f){function h(){this.style.removeProperty(e)}function i(){this.style.setProperty(e,c,f)}function k(){var j=c.apply(this,arguments);j==null?this.style.removeProperty(e):this.style.setProperty(e,j,f)}if(arguments.length<3)f=null;if(arguments.length<2)return g(function(){return window.getComputedStyle(this,null).getPropertyValue(e)});return a.each(c==null?h:typeof c=="function"?k:i)};a.property=function(e,c){function f(){delete this[e]}function h(){this[e]=c}function i(){var k=
|
arguments)?f:h).call(this)}var k=RegExp("(^|\\s+)"+d3.requote(e)+"(\\s+|$)","g");if(arguments.length<2)return g(function(){k.lastIndex=0;return k.test(this.className)});return a.each(typeof c=="function"?i:c?f:h)};a.style=function(e,c,f){function h(){this.style.removeProperty(e)}function i(){this.style.setProperty(e,c,f)}function k(){var j=c.apply(this,arguments);j==null?this.style.removeProperty(e):this.style.setProperty(e,j,f)}if(arguments.length<3)f=null;if(arguments.length<2)return g(function(){return window.getComputedStyle(this,
|
||||||
c.apply(this,arguments);if(k==null)delete this[e];else this[e]=k}e=d3.ns.qualify(e);if(arguments.length<2)return g(function(){return this[e]});return a.each(c==null?f:typeof c=="function"?i:h)};a.text=function(e){function c(){this.appendChild(document.createTextNode(e))}function f(){var h=e.apply(this,arguments);h!=null&&this.appendChild(document.createTextNode(h))}if(arguments.length<1)return g(function(){return this.textContent});a.each(function(){for(;this.lastChild;)this.removeChild(this.lastChild)});
|
null).getPropertyValue(e)});return a.each(c==null?h:typeof c=="function"?k:i)};a.property=function(e,c){function f(){delete this[e]}function h(){this[e]=c}function i(){var k=c.apply(this,arguments);if(k==null)delete this[e];else this[e]=k}e=d3.ns.qualify(e);if(arguments.length<2)return g(function(){return this[e]});return a.each(c==null?f:typeof c=="function"?i:h)};a.text=function(e){function c(){this.appendChild(document.createTextNode(e))}function f(){var h=e.apply(this,arguments);h!=null&&this.appendChild(document.createTextNode(h))}
|
||||||
return e==null?a:a.each(typeof e=="function"?f:c)};a.html=function(e){function c(){this.innerHTML=e}function f(){this.innerHTML=e.apply(this,arguments)}if(arguments.length<1)return g(function(){return this.innerHTML});return a.each(typeof e=="function"?f:c)};a.append=function(e){function c(h){return h.appendChild(document.createElement(e))}function f(h){return h.appendChild(document.createElementNS(e.space,e.local))}e=d3.ns.qualify(e);return b(e.local?f:c)};a.insert=function(e,c){function f(i){return i.insertBefore(document.createElement(e),
|
if(arguments.length<1)return g(function(){return this.textContent});a.each(function(){for(;this.lastChild;)this.removeChild(this.lastChild)});return e==null?a:a.each(typeof e=="function"?f:c)};a.html=function(e){function c(){this.innerHTML=e}function f(){this.innerHTML=e.apply(this,arguments)}if(arguments.length<1)return g(function(){return this.innerHTML});return a.each(typeof e=="function"?f:c)};a.append=function(e){function c(h){return h.appendChild(document.createElement(e))}function f(h){return h.appendChild(document.createElementNS(e.space,
|
||||||
D(c,i))}function h(i){return i.insertBefore(document.createElementNS(e.space,e.local),D(c,i))}e=d3.ns.qualify(e);return b(e.local?h:f)};a.remove=function(){return b(function(e){var c=e.parentNode;c.removeChild(e);return c})};a.sort=function(e){e=Ga.apply(this,arguments);for(var c=0,f=a.length;c<f;c++){var h=a[c];h.sort(e);for(var i=1,k=h.length,j=h[0];i<k;i++){var o=h[i];if(o){j&&j.parentNode.insertBefore(o,j.nextSibling);j=o}}}return a};a.on=function(e,c){var f=e.indexOf("."),h=f==-1?e:e.substring(0,
|
e.local))}e=d3.ns.qualify(e);return b(e.local?f:c)};a.insert=function(e,c){function f(i){return i.insertBefore(document.createElement(e),D(c,i))}function h(i){return i.insertBefore(document.createElementNS(e.space,e.local),D(c,i))}e=d3.ns.qualify(e);return b(e.local?h:f)};a.remove=function(){return b(function(e){var c=e.parentNode;c.removeChild(e);return c})};a.sort=function(e){e=Ga.apply(this,arguments);for(var c=0,f=a.length;c<f;c++){var h=a[c];h.sort(e);for(var i=1,k=h.length,j=h[0];i<k;i++){var o=
|
||||||
f),i="__on"+e;return a.each(function(k,j){function o(p){var m=d3.event;d3.event=p;try{c.call(this,k,j)}finally{d3.event=m}}this[i]&&this.removeEventListener(h,this[i],false);if(c)this.addEventListener(h,this[i]=o,false)})};a.transition=function(){return X(a)};a.call=ea;return a}function Fa(a){function b(d){for(var g=[],e,c,f,h,i=0,k=a.length;i<k;i++){f=a[i];g.push(e=[]);e.parentNode=f.parentNode;e.parentData=f.parentData;for(var j=0,o=f.length;j<o;j++)if(h=f[j]){e.push(c=d(f.parentNode));c.__data__=
|
h[i];if(o){j&&j.parentNode.insertBefore(o,j.nextSibling);j=o}}}return a};a.on=function(e,c){var f=e.indexOf("."),h=f==-1?e:e.substring(0,f),i="__on"+e;return a.each(function(k,j){function o(p){var m=d3.event;d3.event=p;try{c.call(this,k,j)}finally{d3.event=m}}this[i]&&this.removeEventListener(h,this[i],false);if(c)this.addEventListener(h,this[i]=o,false)})};a.transition=function(){return X(a)};a.call=ea;return a}function Fa(a){function b(d){for(var g=[],e,c,f,h,i=0,k=a.length;i<k;i++){f=a[i];g.push(e=
|
||||||
h.__data__}else e.push(null)}return y(g)}a.append=function(d){function g(c){return c.appendChild(document.createElement(d))}function e(c){return c.appendChild(document.createElementNS(d.space,d.local))}d=d3.ns.qualify(d);return b(d.local?e:g)};a.insert=function(d,g){function e(f){return f.insertBefore(document.createElement(d),D(g,f))}function c(f){return f.insertBefore(document.createElementNS(d.space,d.local),D(g,f))}d=d3.ns.qualify(d);return b(d.local?c:e)};return a}function Ga(a){if(!arguments.length)a=
|
[]);e.parentNode=f.parentNode;e.parentData=f.parentData;for(var j=0,o=f.length;j<o;j++)if(h=f[j]){e.push(c=d(f.parentNode));c.__data__=h.__data__}else e.push(null)}return y(g)}a.append=function(d){function g(c){return c.appendChild(document.createElement(d))}function e(c){return c.appendChild(document.createElementNS(d.space,d.local))}d=d3.ns.qualify(d);return b(d.local?e:g)};a.insert=function(d,g){function e(f){return f.insertBefore(document.createElement(d),D(g,f))}function c(f){return f.insertBefore(document.createElementNS(d.space,
|
||||||
d3.ascending;return function(b,d){return a(b&&b.__data__,d&&d.__data__)}}function X(a){function b(m){var n=true,l=-1;a.each(function(){if(i[++l]!=2){var q=(m-k[l])/j[l],r=this.__transition__,t,u,s=c[l];if(q<1){n=false;if(q<0)return}else q=1;if(i[l]){if(!r||r.active!=g){i[l]=2;return}}else if(!r||r.active>g){i[l]=2;return}else{i[l]=1;h.start.dispatch.apply(this,arguments);s=c[l]={};r.active=g;for(u in e)s[u]=e[u].apply(this,arguments)}t=p(q);for(u in e)s[u].call(this,t);if(q==1){i[l]=2;if(r.active==
|
d.local),D(g,f))}d=d3.ns.qualify(d);return b(d.local?c:e)};return a}function Ga(a){if(!arguments.length)a=d3.ascending;return function(b,d){return a(b&&b.__data__,d&&d.__data__)}}function X(a){function b(m){var n=true,l=-1;a.each(function(){if(i[++l]!=2){var q=(m-k[l])/j[l],r=this.__transition__,t,u,s=c[l];if(q<1){n=false;if(q<0)return}else q=1;if(i[l]){if(!r||r.active!=g){i[l]=2;return}}else if(!r||r.active>g){i[l]=2;return}else{i[l]=1;h.start.dispatch.apply(this,arguments);s=c[l]={};r.active=g;
|
||||||
g){q=r.owner;if(q==g){delete this.__transition__;f&&this.parentNode.removeChild(this)}Y=g;h.end.dispatch.apply(this,arguments);Y=0;r.owner=q}}}});return n}var d={},g=Y||++Ha,e={},c=[],f=false,h=d3.dispatch("start","end"),i=[],k=[],j=[],o,p=d3.ease("cubic-in-out");a.each(function(){(this.__transition__||(this.__transition__={})).owner=g});d.delay=function(m){var n=Infinity,l=-1;if(typeof m=="function")a.each(function(){var q=k[++l]=+m.apply(this,arguments);if(q<n)n=q});else{n=+m;a.each(function(){k[++l]=
|
for(u in e)s[u]=e[u].apply(this,arguments)}t=p(q);for(u in e)s[u].call(this,t);if(q==1){i[l]=2;if(r.active==g){q=r.owner;if(q==g){delete this.__transition__;f&&this.parentNode.removeChild(this)}Y=g;h.end.dispatch.apply(this,arguments);Y=0;r.owner=q}}}});return n}var d={},g=Y||++Ha,e={},c=[],f=false,h=d3.dispatch("start","end"),i=[],k=[],j=[],o,p=d3.ease("cubic-in-out");a.each(function(){(this.__transition__||(this.__transition__={})).owner=g});d.delay=function(m){var n=Infinity,l=-1;if(typeof m==
|
||||||
n})}Ia(b,n);return d};d.duration=function(m){var n=-1;if(typeof m=="function"){o=0;a.each(function(){var l=j[++n]=+m.apply(this,arguments);if(l>o)o=l})}else{o=+m;a.each(function(){j[++n]=o})}return d};d.ease=function(m){p=typeof m=="string"?d3.ease(m):m;return d};d.attrTween=function(m,n){function l(r,t){var u=n.call(this,r,t,this.getAttribute(m));return function(s){this.setAttribute(m,u(s))}}function q(r,t){var u=n.call(this,r,t,this.getAttributeNS(m.space,m.local));return function(s){this.setAttributeNS(m.space,
|
"function")a.each(function(){var q=k[++l]=+m.apply(this,arguments);if(q<n)n=q});else{n=+m;a.each(function(){k[++l]=n})}Ia(b,n);return d};d.duration=function(m){var n=-1;if(typeof m=="function"){o=0;a.each(function(){var l=j[++n]=+m.apply(this,arguments);if(l>o)o=l})}else{o=+m;a.each(function(){j[++n]=o})}return d};d.ease=function(m){p=typeof m=="string"?d3.ease(m):m;return d};d.attrTween=function(m,n){function l(r,t){var u=n.call(this,r,t,this.getAttribute(m));return function(s){this.setAttribute(m,
|
||||||
m.local,u(s))}}e["attr."+m]=m.local?q:l;return d};d.attr=function(m,n){return d.attrTween(m,ia(n))};d.styleTween=function(m,n,l){if(arguments.length<3)l=null;e["style."+m]=function(q,r){var t=n.call(this,q,r,window.getComputedStyle(this,null).getPropertyValue(m));return function(u){this.style.setProperty(m,t(u),l)}};return d};d.style=function(m,n,l){if(arguments.length<3)l=null;return d.styleTween(m,ia(n),l)};d.select=function(m){var n;m=X(a.select(m)).ease(p);n=-1;m.delay(function(){return k[++n]});
|
u(s))}}function q(r,t){var u=n.call(this,r,t,this.getAttributeNS(m.space,m.local));return function(s){this.setAttributeNS(m.space,m.local,u(s))}}e["attr."+m]=m.local?q:l;return d};d.attr=function(m,n){return d.attrTween(m,ja(n))};d.styleTween=function(m,n,l){if(arguments.length<3)l=null;e["style."+m]=function(q,r){var t=n.call(this,q,r,window.getComputedStyle(this,null).getPropertyValue(m));return function(u){this.style.setProperty(m,t(u),l)}};return d};d.style=function(m,n,l){if(arguments.length<
|
||||||
n=-1;m.duration(function(){return j[++n]});return m};d.selectAll=function(m){var n;m=X(a.selectAll(m)).ease(p);n=-1;m.delay(function(l,q){return k[q?n:++n]});n=-1;m.duration(function(l,q){return j[q?n:++n]});return m};d.remove=function(){f=true;return d};d.each=function(m,n){h[m].add(n);return d};d.call=ea;return d.delay(0).duration(250)}function ia(a){return typeof a=="function"?function(b,d,g){return d3.interpolate(g,String(a.call(this,b,d)))}:(a=String(a),function(b,d,g){return d3.interpolate(g,
|
3)l=null;return d.styleTween(m,ja(n),l)};d.select=function(m){var n;m=X(a.select(m)).ease(p);n=-1;m.delay(function(){return k[++n]});n=-1;m.duration(function(){return j[++n]});return m};d.selectAll=function(m){var n;m=X(a.selectAll(m)).ease(p);n=-1;m.delay(function(l,q){return k[q?n:++n]});n=-1;m.duration(function(l,q){return j[q?n:++n]});return m};d.remove=function(){f=true;return d};d.each=function(m,n){h[m].add(n);return d};d.call=ea;return d.delay(0).duration(250)}function ja(a){return typeof a==
|
||||||
a)})}function Ia(a,b){var d=Date.now(),g=false,e=d+b,c=F;if(isFinite(b)){for(;c;){if(c.callback==a){c.then=d;c.delay=b;g=true}else{var f=c.then+c.delay;if(f<e)e=f}c=c.next}g||(F={callback:a,then:d,delay:b,next:F});if(!K){clearTimeout(Z);Z=setTimeout(Ja,Math.max(24,e-d))}}}function Ja(){K=setInterval(Ka,24);Z=0}function Ka(){for(var a,b=Date.now(),d=F;d;){a=b-d.then;if(a>d.delay)d.flush=d.callback(a);d=d.next}a=null;for(b=F;b;)b=b.flush?a?a.next=b.next:F=b.next:(a=b).next;a||(K=clearInterval(K))}function La(a){return a.innerRadius}
|
"function"?function(b,d,g){return d3.interpolate(g,String(a.call(this,b,d)))}:(a=String(a),function(b,d,g){return d3.interpolate(g,a)})}function Ia(a,b){var d=Date.now(),g=false,e=d+b,c=F;if(isFinite(b)){for(;c;){if(c.callback==a){c.then=d;c.delay=b;g=true}else{var f=c.then+c.delay;if(f<e)e=f}c=c.next}g||(F={callback:a,then:d,delay:b,next:F});if(!K){clearTimeout(Z);Z=setTimeout(Ja,Math.max(24,e-d))}}}function Ja(){K=setInterval(Ka,24);Z=0}function Ka(){for(var a,b=Date.now(),d=F;d;){a=b-d.then;if(a>
|
||||||
function Ma(a){return a.outerRadius}function ja(a){return a.startAngle}function ka(a){return a.endAngle}function $(a,b,d,g){var e=[],c=-1,f=b.length,h=typeof d=="function",i=typeof g=="function",k;if(h&&i)for(;++c<f;)e.push([d.call(a,k=b[c],c),g.call(a,k,c)]);else if(h)for(;++c<f;)e.push([d.call(a,b[c],c),g]);else if(i)for(;++c<f;)e.push([d,g.call(a,b[c],c)]);else for(;++c<f;)e.push([d,g]);return e}function la(a){return a[0]}function ma(a){return a[1]}function H(a){var b=[],d=0,g=a.length,e=a[0];
|
d.delay)d.flush=d.callback(a);d=d.next}a=null;for(b=F;b;)b=b.flush?a?a.next=b.next:F=b.next:(a=b).next;a||(K=clearInterval(K))}function La(a){return a.innerRadius}function Ma(a){return a.outerRadius}function ka(a){return a.startAngle}function la(a){return a.endAngle}function $(a,b,d,g){var e=[],c=-1,f=b.length,h=typeof d=="function",i=typeof g=="function",k;if(h&&i)for(;++c<f;)e.push([d.call(a,k=b[c],c),g.call(a,k,c)]);else if(h)for(;++c<f;)e.push([d.call(a,b[c],c),g]);else if(i)for(;++c<f;)e.push([d,
|
||||||
for(b.push(e[0],",",e[1]);++d<g;)b.push("L",(e=a[d])[0],",",e[1]);return b.join("")}function na(a,b){if(b.length<1||a.length!=b.length&&a.length!=b.length+2)return H(a);var d=a.length!=b.length,g="",e=a[0],c=a[1],f=b[0],h=f,i=1;if(d){g+="Q"+(c[0]-f[0]*2/3)+","+(c[1]-f[1]*2/3)+","+c[0]+","+c[1];e=a[1];i=2}if(b.length>1){h=b[1];c=a[i];i++;g+="C"+(e[0]+f[0])+","+(e[1]+f[1])+","+(c[0]-h[0])+","+(c[1]-h[1])+","+c[0]+","+c[1];for(e=2;e<b.length;e++,i++){c=a[i];h=b[e];g+="S"+(c[0]-h[0])+","+(c[1]-h[1])+
|
g.call(a,b[c],c)]);else for(;++c<f;)e.push([d,g]);return e}function ma(a){return a[0]}function na(a){return a[1]}function H(a){var b=[],d=0,g=a.length,e=a[0];for(b.push(e[0],",",e[1]);++d<g;)b.push("L",(e=a[d])[0],",",e[1]);return b.join("")}function oa(a,b){if(b.length<1||a.length!=b.length&&a.length!=b.length+2)return H(a);var d=a.length!=b.length,g="",e=a[0],c=a[1],f=b[0],h=f,i=1;if(d){g+="Q"+(c[0]-f[0]*2/3)+","+(c[1]-f[1]*2/3)+","+c[0]+","+c[1];e=a[1];i=2}if(b.length>1){h=b[1];c=a[i];i++;g+="C"+
|
||||||
","+c[0]+","+c[1]}}if(d){d=a[i];g+="Q"+(c[0]+h[0]*2/3)+","+(c[1]+h[1]*2/3)+","+d[0]+","+d[1]}return g}function oa(a,b){for(var d=[],g=(1-b)/2,e=a[0],c=a[1],f=a[2],h=2,i=a.length;++h<i;){d.push([g*(f[0]-e[0]),g*(f[1]-e[1])]);e=c;c=f;f=a[h]}d.push([g*(f[0]-e[0]),g*(f[1]-e[1])]);return d}function B(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]}function L(a,b,d){a.push("C",B(pa,b),",",B(pa,d),",",B(qa,b),",",B(qa,d),",",B(M,b),",",B(M,d))}function Na(){return 0}function Oa(a){return a.source}function Pa(a){return a.target}
|
(e[0]+f[0])+","+(e[1]+f[1])+","+(c[0]-h[0])+","+(c[1]-h[1])+","+c[0]+","+c[1];for(e=2;e<b.length;e++,i++){c=a[i];h=b[e];g+="S"+(c[0]-h[0])+","+(c[1]-h[1])+","+c[0]+","+c[1]}}if(d){d=a[i];g+="Q"+(c[0]+h[0]*2/3)+","+(c[1]+h[1]*2/3)+","+d[0]+","+d[1]}return g}function pa(a,b){for(var d=[],g=(1-b)/2,e=a[0],c=a[1],f=a[2],h=2,i=a.length;++h<i;){d.push([g*(f[0]-e[0]),g*(f[1]-e[1])]);e=c;c=f;f=a[h]}d.push([g*(f[0]-e[0]),g*(f[1]-e[1])]);return d}function B(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]}
|
||||||
function Qa(a){return a.radius}function Ra(){return 64}function Sa(){return"circle"}d3={version:"1.4.0"};if(!Date.now)Date.now=function(){return+new Date};if(!Object.create)Object.create=function(a){function b(){}b.prototype=a;return new b};var N=function(a){return Array.prototype.slice.call(a)};try{N(document.documentElement.childNodes)}catch(eb){N=ua}d3.ascending=function(a,b){return a<b?-1:a>b?1:0};d3.descending=function(a,b){return b<a?-1:b>a?1:0};d3.min=function(a,b){var d=0,g=a.length,e=a[0],
|
function L(a,b,d){a.push("C",B(qa,b),",",B(qa,d),",",B(ra,b),",",B(ra,d),",",B(M,b),",",B(M,d))}function Na(){return 0}function Oa(a){return a.source}function Pa(a){return a.target}function Qa(a){return a.radius}function Ra(){return 64}function Sa(){return"circle"}d3={version:"1.5.1"};if(!Date.now)Date.now=function(){return+new Date};if(!Object.create)Object.create=function(a){function b(){}b.prototype=a;return new b};var N=function(a){return Array.prototype.slice.call(a)};try{N(document.documentElement.childNodes)}catch(eb){N=
|
||||||
c;if(arguments.length==1)for(;++d<g;){if(e>(c=a[d]))e=c}else for(e=b(a[0]);++d<g;)if(e>(c=b(a[d])))e=c;return e};d3.max=function(a,b){var d=0,g=a.length,e=a[0],c;if(arguments.length==1)for(;++d<g;){if(e<(c=a[d]))e=c}else for(e=b(e);++d<g;)if(e<(c=b(a[d])))e=c;return e};d3.nest=function(){function a(h,i){if(i>=g.length)return f?f.call(d,h):c?h.sort(c):h;for(var k=-1,j=h.length,o=g[i++],p,m,n={};++k<j;)if((p=o(m=h[k]))in n)n[p].push(m);else n[p]=[m];for(p in n)n[p]=a(n[p],i);return n}function b(h,i){if(i>=
|
ua}d3.ascending=function(a,b){return a<b?-1:a>b?1:0};d3.descending=function(a,b){return b<a?-1:b>a?1:0};d3.min=function(a,b){var d=0,g=a.length,e=a[0],c;if(arguments.length==1)for(;++d<g;){if(e>(c=a[d]))e=c}else for(e=b(a[0]);++d<g;)if(e>(c=b(a[d])))e=c;return e};d3.max=function(a,b){var d=0,g=a.length,e=a[0],c;if(arguments.length==1)for(;++d<g;){if(e<(c=a[d]))e=c}else for(e=b(e);++d<g;)if(e<(c=b(a[d])))e=c;return e};d3.nest=function(){function a(h,i){if(i>=g.length)return f?f.call(d,h):c?h.sort(c):
|
||||||
g.length)return h;var k=[],j=e[i++],o;for(o in h)k.push({key:o,values:b(h[o],i)});j&&k.sort(function(p,m){return j(p.key,m.key)});return k}var d={},g=[],e=[],c,f;d.map=function(h){return a(h,0)};d.entries=function(h){return b(a(h,0),0)};d.key=function(h){g.push(h);return d};d.sortKeys=function(h){e[g.length-1]=h;return d};d.sortValues=function(h){c=h;return d};d.rollup=function(h){f=h;return d};return d};d3.keys=function(a){var b=[],d;for(d in a)b.push(d);return b};d3.values=function(a){var b=[],
|
h;for(var k=-1,j=h.length,o=g[i++],p,m,n={};++k<j;)if((p=o(m=h[k]))in n)n[p].push(m);else n[p]=[m];for(p in n)n[p]=a(n[p],i);return n}function b(h,i){if(i>=g.length)return h;var k=[],j=e[i++],o;for(o in h)k.push({key:o,values:b(h[o],i)});j&&k.sort(function(p,m){return j(p.key,m.key)});return k}var d={},g=[],e=[],c,f;d.map=function(h){return a(h,0)};d.entries=function(h){return b(a(h,0),0)};d.key=function(h){g.push(h);return d};d.sortKeys=function(h){e[g.length-1]=h;return d};d.sortValues=function(h){c=
|
||||||
d;for(d in a)b.push(a[d]);return b};d3.entries=function(a){var b=[],d;for(d in a)b.push({key:d,value:a[d]});return b};d3.merge=function(a){return Array.prototype.concat.apply([],a)};d3.split=function(a,b){var d=[],g=[],e,c=-1,f=a.length;if(arguments.length<2)b=va;for(;++c<f;)if(b.call(g,e=a[c],c))g=[];else{g.length||d.push(g);g.push(e)}return d};d3.range=function(a,b,d){if(arguments.length==1){b=a;a=0}if(d==null)d=1;if((b-a)/d==Infinity)throw Error("infinite range");var g=[],e=-1,c;if(d<0)for(;(c=
|
h;return d};d.rollup=function(h){f=h;return d};return d};d3.keys=function(a){var b=[],d;for(d in a)b.push(d);return b};d3.values=function(a){var b=[],d;for(d in a)b.push(a[d]);return b};d3.entries=function(a){var b=[],d;for(d in a)b.push({key:d,value:a[d]});return b};d3.merge=function(a){return Array.prototype.concat.apply([],a)};d3.split=function(a,b){var d=[],g=[],e,c=-1,f=a.length;if(arguments.length<2)b=va;for(;++c<f;)if(b.call(g,e=a[c],c))g=[];else{g.length||d.push(g);g.push(e)}return d};d3.range=
|
||||||
a+d*++e)>b;)g.push(c);else for(;(c=a+d*++e)<b;)g.push(c);return g};d3.requote=function(a){return a.replace(Ta,"\\$&")};var Ta=/[\\\^\$\*\+\?\[\]\(\)\.\{\}]/g;d3.xhr=function(a,b,d){var g=new XMLHttpRequest;if(arguments.length<3)d=b;else b&&g.overrideMimeType(b);g.open("GET",a,true);g.onreadystatechange=function(){if(g.readyState==4)d(g.status<300?g:null)};g.send(null)};d3.text=function(a,b,d){if(arguments.length<3){d=b;b=null}d3.xhr(a,b,function(g){d(g&&g.responseText)})};d3.json=function(a,b){d3.text(a,
|
function(a,b,d){if(arguments.length==1){b=a;a=0}if(d==null)d=1;if((b-a)/d==Infinity)throw Error("infinite range");var g=[],e=-1,c;if(d<0)for(;(c=a+d*++e)>b;)g.push(c);else for(;(c=a+d*++e)<b;)g.push(c);return g};d3.requote=function(a){return a.replace(Ta,"\\$&")};var Ta=/[\\\^\$\*\+\?\[\]\(\)\.\{\}]/g;d3.xhr=function(a,b,d){var g=new XMLHttpRequest;if(arguments.length<3)d=b;else b&&g.overrideMimeType(b);g.open("GET",a,true);g.onreadystatechange=function(){if(g.readyState==4)d(g.status<300?g:null)};
|
||||||
"application/json",function(d){b(d?JSON.parse(d):null)})};d3.html=function(a,b){d3.text(a,"text/html",function(d){if(d!=null){var g=document.createRange();g.selectNode(document.body);d=g.createContextualFragment(d)}b(d)})};d3.xml=function(a,b,d){if(arguments.length<3){d=b;b=null}d3.xhr(a,b,function(g){d(g&&g.responseXML)})};d3.ns={prefix:{svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},
|
g.send(null)};d3.text=function(a,b,d){if(arguments.length<3){d=b;b=null}d3.xhr(a,b,function(g){d(g&&g.responseText)})};d3.json=function(a,b){d3.text(a,"application/json",function(d){b(d?JSON.parse(d):null)})};d3.html=function(a,b){d3.text(a,"text/html",function(d){if(d!=null){var g=document.createRange();g.selectNode(document.body);d=g.createContextualFragment(d)}b(d)})};d3.xml=function(a,b,d){if(arguments.length<3){d=b;b=null}d3.xhr(a,b,function(g){d(g&&g.responseXML)})};d3.ns={prefix:{svg:"http://www.w3.org/2000/svg",
|
||||||
qualify:function(a){var b=a.indexOf(":");return b<0?a:{space:d3.ns.prefix[a.substring(0,b)],local:a.substring(b+1)}}};d3.dispatch=function(){for(var a={},b,d=0,g=arguments.length;d<g;d++){b=arguments[d];a[b]=wa(b)}return a};d3.format=function(a){a=Ua.exec(a);var b=a[1]||" ",d=ra[a[3]]||ra["-"],g=a[5],e=+a[6],c=a[7],f=a[8],h=a[9];if(f)f=f.substring(1);if(g)b="0";if(h=="d")f="0";return function(i){i=+i;var k=i<0&&(i=-i);if(h=="d"&&i%1)return"";i=f?i.toFixed(f):""+i;if(c){for(var j=i.lastIndexOf("."),
|
xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"},qualify:function(a){var b=a.indexOf(":");return b<0?a:{space:d3.ns.prefix[a.substring(0,b)],local:a.substring(b+1)}}};d3.dispatch=function(){for(var a={},b,d=0,g=arguments.length;d<g;d++){b=arguments[d];a[b]=wa(b)}return a};d3.format=function(a){a=Ua.exec(a);var b=a[1]||" ",d=a[3]||"",g=a[5],e=+a[6],c=a[7],f=a[8],h=a[9];if(f)f=f.substring(1);if(g){b=
|
||||||
o=j>=0?i.substring(j):(j=i.length,""),p=[];j>0;)p.push(i.substring(j-=3,j+3));i=p.reverse().join(",")+o}k=(i=d(k,i)).length;if(k<e)i=Array(e-k+1).join(b)+i;return i}};var Ua=/(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/,ra={"+":function(a,b){return(a?"−":"+")+b}," ":function(a,b){return(a?"−":" ")+b},"-":function(a,b){return a?"−"+b:b}},Va=R(2),Wa=R(3),Xa={linear:function(){return xa},poly:R,quad:function(){return Va},cubic:function(){return Wa},sin:function(){return ya},
|
"0";if(c)e-=Math.floor((e-1)/4)}if(h=="d")f="0";return function(i){i=+i;var k=i<0&&(i=-i)?"−":d;if(h=="d"&&i%1)return"";i=f?i.toFixed(f):""+i;if(g){var j=i.length+k.length;if(j<e)i=Array(e-j+1).join(b)+i;if(c)i=fa(i);i=k+i}else{if(c)i=fa(i);i=k+i;j=i.length;if(j<e)i=Array(e-j+1).join(b)+i}return i}};var Ua=/(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/,Va=R(2),Wa=R(3),Xa={linear:function(){return xa},poly:R,quad:function(){return Va},cubic:function(){return Wa},sin:function(){return ya},
|
||||||
exp:function(){return za},circle:function(){return Aa},elastic:function(a,b){var d;if(arguments.length<2)b=0.45;if(arguments.length<1){a=1;d=b/4}else d=b/(2*Math.PI)*Math.asin(1/a);return function(g){return 1+a*Math.pow(2,10*-g)*Math.sin((g-d)*2*Math.PI/b)}},back:function(a){a||(a=1.70158);return function(b){return b*b*((a+1)*b-a)}},bounce:function(){return Ba}},Ya={"in":function(a){return a},out:fa,"in-out":ga,"out-in":function(a){return ga(fa(a))}};d3.ease=function(a){var b=a.indexOf("-"),d=b>=
|
exp:function(){return za},circle:function(){return Aa},elastic:function(a,b){var d;if(arguments.length<2)b=0.45;if(arguments.length<1){a=1;d=b/4}else d=b/(2*Math.PI)*Math.asin(1/a);return function(g){return 1+a*Math.pow(2,10*-g)*Math.sin((g-d)*2*Math.PI/b)}},back:function(a){a||(a=1.70158);return function(b){return b*b*((a+1)*b-a)}},bounce:function(){return Ba}},Ya={"in":function(a){return a},out:ga,"in-out":ha,"out-in":function(a){return ha(ga(a))}};d3.ease=function(a){var b=a.indexOf("-"),d=b>=
|
||||||
0?a.substring(0,b):a;b=b>=0?a.substring(b+1):"in";return Ya[b](Xa[d].apply(null,Array.prototype.slice.call(arguments,1)))};d3.event=null;d3.interpolate=function(a,b){if(typeof b=="number")return d3.interpolateNumber(+a,b);if(typeof b=="string")return b in G||/^(#|rgb\(|hsl\()/.test(b)?d3.interpolateRgb(String(a),b):d3.interpolateString(String(a),b);if(b instanceof Array)return d3.interpolateArray(a,b);return d3.interpolateObject(a,b)};d3.interpolateNumber=function(a,b){b-=a;return function(d){return a+
|
0?a.substring(0,b):a;b=b>=0?a.substring(b+1):"in";return Ya[b](Xa[d].apply(null,Array.prototype.slice.call(arguments,1)))};d3.event=null;d3.interpolate=function(a,b){if(typeof b=="number")return d3.interpolateNumber(+a,b);if(typeof b=="string")return b in G||/^(#|rgb\(|hsl\()/.test(b)?d3.interpolateRgb(String(a),b):d3.interpolateString(String(a),b);if(b instanceof Array)return d3.interpolateArray(a,b);return d3.interpolateObject(a,b)};d3.interpolateNumber=function(a,b){b-=a;return function(d){return a+
|
||||||
b*d}};d3.interpolateRound=function(a,b){b-=a;return function(d){return Math.round(a+b*d)}};d3.interpolateString=function(a,b){var d,g,e=0,c=[],f=[],h,i;for(g=0;d=aa.exec(b);++g){d.index&&c.push(b.substring(e,d.index));f.push({i:c.length,x:d[0]});c.push(null);e=aa.lastIndex}e<b.length&&c.push(b.substring(e));g=0;for(h=f.length;(d=aa.exec(a))&&g<h;++g){i=f[g];if(i.x==d[0]){if(i.i)if(c[i.i+1]==null){c[i.i-1]+=i.x;c.splice(i.i,1);for(d=g+1;d<h;++d)f[d].i--}else{c[i.i-1]+=i.x+c[i.i+1];c.splice(i.i,2);
|
b*d}};d3.interpolateRound=function(a,b){b-=a;return function(d){return Math.round(a+b*d)}};d3.interpolateString=function(a,b){var d,g,e=0,c=[],f=[],h,i;for(g=0;d=aa.exec(b);++g){d.index&&c.push(b.substring(e,d.index));f.push({i:c.length,x:d[0]});c.push(null);e=aa.lastIndex}e<b.length&&c.push(b.substring(e));g=0;for(h=f.length;(d=aa.exec(a))&&g<h;++g){i=f[g];if(i.x==d[0]){if(i.i)if(c[i.i+1]==null){c[i.i-1]+=i.x;c.splice(i.i,1);for(d=g+1;d<h;++d)f[d].i--}else{c[i.i-1]+=i.x+c[i.i+1];c.splice(i.i,2);
|
||||||
for(d=g+1;d<h;++d)f[d].i-=2}else if(c[i.i+1]==null)c[i.i]=i.x;else{c[i.i]=i.x+c[i.i+1];c.splice(i.i+1,1);for(d=g+1;d<h;++d)f[d].i--}f.splice(g,1);h--;g--}else i.x=d3.interpolateNumber(parseFloat(d[0]),parseFloat(i.x))}for(;g<h;){i=f.pop();if(c[i.i+1]==null)c[i.i]=i.x;else{c[i.i]=i.x+c[i.i+1];c.splice(i.i+1,1)}h--}if(c.length==1)return c[0]==null?f[0].x:function(){return b};return function(k){for(g=0;g<h;++g)c[(i=f[g]).i]=i.x(k);return c.join("")}};d3.interpolateRgb=function(a,b){a=d3.rgb(a);b=d3.rgb(b);
|
for(d=g+1;d<h;++d)f[d].i-=2}else if(c[i.i+1]==null)c[i.i]=i.x;else{c[i.i]=i.x+c[i.i+1];c.splice(i.i+1,1);for(d=g+1;d<h;++d)f[d].i--}f.splice(g,1);h--;g--}else i.x=d3.interpolateNumber(parseFloat(d[0]),parseFloat(i.x))}for(;g<h;){i=f.pop();if(c[i.i+1]==null)c[i.i]=i.x;else{c[i.i]=i.x+c[i.i+1];c.splice(i.i+1,1)}h--}if(c.length==1)return c[0]==null?f[0].x:function(){return b};return function(k){for(g=0;g<h;++g)c[(i=f[g]).i]=i.x(k);return c.join("")}};d3.interpolateRgb=function(a,b){a=d3.rgb(a);b=d3.rgb(b);
|
||||||
|
@ -45,7 +45,7 @@ goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#
|
||||||
lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",
|
lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead",
|
||||||
navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",
|
navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d",
|
||||||
silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},ba;for(ba in G)G[ba]=T(G[ba],J,W);d3.hsl=function(a,b,d){return arguments.length==1?T(""+a,Da,V):V(+a,+b,+d)};var D=function(a,b){return b.querySelector(a)},
|
silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"},ba;for(ba in G)G[ba]=T(G[ba],J,W);d3.hsl=function(a,b,d){return arguments.length==1?T(""+a,Da,V):V(+a,+b,+d)};var D=function(a,b){return b.querySelector(a)},
|
||||||
ha=function(a,b){return N(b.querySelectorAll(a))};if(typeof Sizzle=="function"){D=function(a,b){return Sizzle(a,b)[0]};ha=Sizzle}var O=y([[document]]);O[0].parentNode=document.documentElement;d3.select=function(a){return typeof a=="string"?O.select(a):y([[a]])};d3.selectAll=function(a){return typeof a=="string"?O.selectAll(a):y([N(a)])};d3.transition=O.transition;var Ha=0,Y=0,F=null,Z=0,K;d3.scale={};d3.scale.linear=function(){function a(j){return k((j-d)*f)}function b(j){var o=Math.min(d,g),p=Math.max(d,
|
ia=function(a,b){return N(b.querySelectorAll(a))};if(typeof Sizzle=="function"){D=function(a,b){return Sizzle(a,b)[0]};ia=Sizzle}var O=y([[document]]);O[0].parentNode=document.documentElement;d3.select=function(a){return typeof a=="string"?O.select(a):y([[a]])};d3.selectAll=function(a){return typeof a=="string"?O.selectAll(a):y([N(a)])};d3.transition=O.transition;var Ha=0,Y=0,F=null,Z=0,K;d3.scale={};d3.scale.linear=function(){function a(j){return k((j-d)*f)}function b(j){var o=Math.min(d,g),p=Math.max(d,
|
||||||
g),m=p-o,n=Math.pow(10,Math.floor(Math.log(m/j)/Math.LN10));j=j/(m/n);if(j<=0.15)n*=10;else if(j<=0.35)n*=5;else if(j<=0.75)n*=2;return{start:Math.ceil(o/n)*n,stop:Math.floor(p/n)*n+n*0.5,step:n}}var d=0,g=1,e=0,c=1,f=1/(g-d),h=(g-d)/(c-e),i=d3.interpolate,k=i(e,c);a.invert=function(j){return(j-e)*h+d};a.domain=function(j){if(!arguments.length)return[d,g];d=j[0];g=j[1];f=1/(g-d);h=(g-d)/(c-e);return a};a.range=function(j){if(!arguments.length)return[e,c];e=j[0];c=j[1];h=(g-d)/(c-e);k=i(e,c);return a};
|
g),m=p-o,n=Math.pow(10,Math.floor(Math.log(m/j)/Math.LN10));j=j/(m/n);if(j<=0.15)n*=10;else if(j<=0.35)n*=5;else if(j<=0.75)n*=2;return{start:Math.ceil(o/n)*n,stop:Math.floor(p/n)*n+n*0.5,step:n}}var d=0,g=1,e=0,c=1,f=1/(g-d),h=(g-d)/(c-e),i=d3.interpolate,k=i(e,c);a.invert=function(j){return(j-e)*h+d};a.domain=function(j){if(!arguments.length)return[d,g];d=j[0];g=j[1];f=1/(g-d);h=(g-d)/(c-e);return a};a.range=function(j){if(!arguments.length)return[e,c];e=j[0];c=j[1];h=(g-d)/(c-e);k=i(e,c);return a};
|
||||||
a.rangeRound=function(j){return a.range(j).interpolate(d3.interpolateRound)};a.interpolate=function(j){if(!arguments.length)return i;k=(i=j)(e,c);return a};a.ticks=function(j){j=b(j);return d3.range(j.start,j.stop,j.step)};a.tickFormat=function(j){j=Math.max(0,-Math.floor(Math.log(b(j).step)/Math.LN10+0.01));return d3.format(",."+j+"f")};return a};d3.scale.log=function(){function a(c){return(e?-Math.log(-c):Math.log(c))/Math.LN10}function b(c){return e?-Math.pow(10,-c):Math.pow(10,c)}function d(c){return g(a(c))}
|
a.rangeRound=function(j){return a.range(j).interpolate(d3.interpolateRound)};a.interpolate=function(j){if(!arguments.length)return i;k=(i=j)(e,c);return a};a.ticks=function(j){j=b(j);return d3.range(j.start,j.stop,j.step)};a.tickFormat=function(j){j=Math.max(0,-Math.floor(Math.log(b(j).step)/Math.LN10+0.01));return d3.format(",."+j+"f")};return a};d3.scale.log=function(){function a(c){return(e?-Math.log(-c):Math.log(c))/Math.LN10}function b(c){return e?-Math.pow(10,-c):Math.pow(10,c)}function d(c){return g(a(c))}
|
||||||
var g=d3.scale.linear(),e=false;d.invert=function(c){return b(g.invert(c))};d.domain=function(c){if(!arguments.length)return g.domain().map(b);e=(c[0]||c[1])<0;g.domain(c.map(a));return d};d.range=C(d,g.range);d.rangeRound=C(d,g.rangeRound);d.interpolate=C(d,g.interpolate);d.ticks=function(){var c=g.domain(),f=[];if(c.every(isFinite)){var h=Math.floor(c[0]),i=Math.ceil(c[1]),k=b(c[0]);c=b(c[1]);if(e)for(f.push(b(h));h++<i;)for(var j=9;j>0;j--)f.push(b(h)*j);else{for(;h<i;h++)for(j=1;j<10;j++)f.push(b(h)*
|
var g=d3.scale.linear(),e=false;d.invert=function(c){return b(g.invert(c))};d.domain=function(c){if(!arguments.length)return g.domain().map(b);e=(c[0]||c[1])<0;g.domain(c.map(a));return d};d.range=C(d,g.range);d.rangeRound=C(d,g.rangeRound);d.interpolate=C(d,g.interpolate);d.ticks=function(){var c=g.domain(),f=[];if(c.every(isFinite)){var h=Math.floor(c[0]),i=Math.ceil(c[1]),k=b(c[0]);c=b(c[1]);if(e)for(f.push(b(h));h++<i;)for(var j=9;j>0;j--)f.push(b(h)*j);else{for(;h<i;h++)for(j=1;j<10;j++)f.push(b(h)*
|
||||||
|
@ -57,12 +57,12 @@ c[0],i=c[1],k=i-h,j=Math.floor(k/(b.length+f));g=d3.range(h+Math.round((k-(b.len
|
||||||
"#e6550d","#fd8d3c","#fdae6b","#fdd0a2","#31a354","#74c476","#a1d99b","#c7e9c0","#756bb1","#9e9ac8","#bcbddc","#dadaeb","#636363","#969696","#bdbdbd","#d9d9d9"];d3.scale.quantile=function(){function a(){for(var f=-1,h=c.length=e.length,i=g.length/h;++f<h;)c[f]=g[~~(f*i)]}function b(f){if(isNaN(f=+f))return NaN;for(var h=0,i=c.length-1;h<=i;){var k=h+i>>1,j=c[k];if(j<f)h=k+1;else if(j>f)i=k-1;else return k}return i<0?0:i}function d(f){return e[b(f)]}var g=[],e=[],c=[];d.domain=function(f){if(!arguments.length)return g;
|
"#e6550d","#fd8d3c","#fdae6b","#fdd0a2","#31a354","#74c476","#a1d99b","#c7e9c0","#756bb1","#9e9ac8","#bcbddc","#dadaeb","#636363","#969696","#bdbdbd","#d9d9d9"];d3.scale.quantile=function(){function a(){for(var f=-1,h=c.length=e.length,i=g.length/h;++f<h;)c[f]=g[~~(f*i)]}function b(f){if(isNaN(f=+f))return NaN;for(var h=0,i=c.length-1;h<=i;){var k=h+i>>1,j=c[k];if(j<f)h=k+1;else if(j>f)i=k-1;else return k}return i<0?0:i}function d(f){return e[b(f)]}var g=[],e=[],c=[];d.domain=function(f){if(!arguments.length)return g;
|
||||||
g=f.filter(function(h){return!isNaN(h)}).sort(d3.ascending);a();return d};d.range=function(f){if(!arguments.length)return e;e=f;a();return d};d.quantiles=function(){return c};return d};d3.scale.quantize=function(){function a(f){return c[Math.max(0,Math.min(e,Math.floor(g*(f-b))))]}var b=0,d=1,g=2,e=1,c=[0,1];a.domain=function(f){if(!arguments.length)return[b,d];b=f[0];d=f[1];g=c.length/(d-b);return a};a.range=function(f){if(!arguments.length)return c;c=f;g=c.length/(d-b);e=c.length-1;return a};return a};
|
g=f.filter(function(h){return!isNaN(h)}).sort(d3.ascending);a();return d};d.range=function(f){if(!arguments.length)return e;e=f;a();return d};d.quantiles=function(){return c};return d};d3.scale.quantize=function(){function a(f){return c[Math.max(0,Math.min(e,Math.floor(g*(f-b))))]}var b=0,d=1,g=2,e=1,c=[0,1];a.domain=function(f){if(!arguments.length)return[b,d];b=f[0];d=f[1];g=c.length/(d-b);return a};a.range=function(f){if(!arguments.length)return c;c=f;g=c.length/(d-b);e=c.length-1;return a};return a};
|
||||||
d3.svg={};d3.svg.arc=function(){function a(){var c=b.apply(this,arguments),f=d.apply(this,arguments),h=g.apply(this,arguments)+I,i=e.apply(this,arguments)+I,k=i-h,j=k<Math.PI?"0":"1",o=Math.cos(h);h=Math.sin(h);var p=Math.cos(i);i=Math.sin(i);return k>=db?c?"M0,"+f+"A"+f+","+f+" 0 1,1 0,"+-f+"A"+f+","+f+" 0 1,1 0,"+f+"M0,"+c+"A"+c+","+c+" 0 1,1 0,"+-c+"A"+c+","+c+" 0 1,1 0,"+c+"Z":"M0,"+f+"A"+f+","+f+" 0 1,1 0,"+-f+"A"+f+","+f+" 0 1,1 0,"+f+"Z":c?"M"+f*o+","+f*h+"A"+f+","+f+" 0 "+j+",1 "+f*p+","+
|
d3.svg={};d3.svg.arc=function(){function a(){var c=b.apply(this,arguments),f=d.apply(this,arguments),h=g.apply(this,arguments)+I,i=e.apply(this,arguments)+I,k=i-h,j=k<Math.PI?"0":"1",o=Math.cos(h);h=Math.sin(h);var p=Math.cos(i);i=Math.sin(i);return k>=db?c?"M0,"+f+"A"+f+","+f+" 0 1,1 0,"+-f+"A"+f+","+f+" 0 1,1 0,"+f+"M0,"+c+"A"+c+","+c+" 0 1,1 0,"+-c+"A"+c+","+c+" 0 1,1 0,"+c+"Z":"M0,"+f+"A"+f+","+f+" 0 1,1 0,"+-f+"A"+f+","+f+" 0 1,1 0,"+f+"Z":c?"M"+f*o+","+f*h+"A"+f+","+f+" 0 "+j+",1 "+f*p+","+
|
||||||
f*i+"L"+c*p+","+c*i+"A"+c+","+c+" 0 "+j+",0 "+c*o+","+c*h+"Z":"M"+f*o+","+f*h+"A"+f+","+f+" 0 "+j+",1 "+f*p+","+f*i+"L0,0Z"}var b=La,d=Ma,g=ja,e=ka;a.innerRadius=function(c){if(!arguments.length)return b;b=v(c);return a};a.outerRadius=function(c){if(!arguments.length)return d;d=v(c);return a};a.startAngle=function(c){if(!arguments.length)return g;g=v(c);return a};a.endAngle=function(c){if(!arguments.length)return e;e=v(c);return a};a.centroid=function(){var c=(b.apply(this,arguments)+d.apply(this,
|
f*i+"L"+c*p+","+c*i+"A"+c+","+c+" 0 "+j+",0 "+c*o+","+c*h+"Z":"M"+f*o+","+f*h+"A"+f+","+f+" 0 "+j+",1 "+f*p+","+f*i+"L0,0Z"}var b=La,d=Ma,g=ka,e=la;a.innerRadius=function(c){if(!arguments.length)return b;b=v(c);return a};a.outerRadius=function(c){if(!arguments.length)return d;d=v(c);return a};a.startAngle=function(c){if(!arguments.length)return g;g=v(c);return a};a.endAngle=function(c){if(!arguments.length)return e;e=v(c);return a};a.centroid=function(){var c=(b.apply(this,arguments)+d.apply(this,
|
||||||
arguments))/2,f=(g.apply(this,arguments)+e.apply(this,arguments))/2+I;return[Math.cos(f)*c,Math.sin(f)*c]};return a};var I=-Math.PI/2,db=2*Math.PI-1.0E-6;d3.svg.line=function(){function a(f){return f.length<1?null:"M"+e($(this,f,b,d),c)}var b=la,d=ma,g="linear",e=P[g],c=0.7;a.x=function(f){if(!arguments.length)return b;b=f;return a};a.y=function(f){if(!arguments.length)return d;d=f;return a};a.interpolate=function(f){if(!arguments.length)return g;e=P[g=f];return a};a.tension=function(f){if(!arguments.length)return c;
|
arguments))/2,f=(g.apply(this,arguments)+e.apply(this,arguments))/2+I;return[Math.cos(f)*c,Math.sin(f)*c]};return a};var I=-Math.PI/2,db=2*Math.PI-1.0E-6;d3.svg.line=function(){function a(f){return f.length<1?null:"M"+e($(this,f,b,d),c)}var b=ma,d=na,g="linear",e=P[g],c=0.7;a.x=function(f){if(!arguments.length)return b;b=f;return a};a.y=function(f){if(!arguments.length)return d;d=f;return a};a.interpolate=function(f){if(!arguments.length)return g;e=P[g=f];return a};a.tension=function(f){if(!arguments.length)return c;
|
||||||
c=f;return a};return a};var P={linear:H,basis:function(a){if(a.length<3)return H(a);var b=[],d=1,g=a.length,e=a[0],c=e[0],f=e[1],h=[c,c,c,(e=a[1])[0]],i=[f,f,f,e[1]];b.push(c,",",f);for(L(b,h,i);++d<g;){e=a[d];h.shift();h.push(e[0]);i.shift();i.push(e[1]);L(b,h,i)}for(d=-1;++d<2;){h.shift();h.push(e[0]);i.shift();i.push(e[1]);L(b,h,i)}return b.join("")},"basis-closed":function(a){for(var b,d=-1,g=a.length,e=g+4,c,f=[],h=[];++d<4;){c=a[d%g];f.push(c[0]);h.push(c[1])}b=[B(M,f),",",B(M,h)];for(--d;++d<
|
c=f;return a};return a};var P={linear:H,basis:function(a){if(a.length<3)return H(a);var b=[],d=1,g=a.length,e=a[0],c=e[0],f=e[1],h=[c,c,c,(e=a[1])[0]],i=[f,f,f,e[1]];b.push(c,",",f);for(L(b,h,i);++d<g;){e=a[d];h.shift();h.push(e[0]);i.shift();i.push(e[1]);L(b,h,i)}for(d=-1;++d<2;){h.shift();h.push(e[0]);i.shift();i.push(e[1]);L(b,h,i)}return b.join("")},"basis-closed":function(a){for(var b,d=-1,g=a.length,e=g+4,c,f=[],h=[];++d<4;){c=a[d%g];f.push(c[0]);h.push(c[1])}b=[B(M,f),",",B(M,h)];for(--d;++d<
|
||||||
e;){c=a[d%g];f.shift();f.push(c[0]);h.shift();h.push(c[1]);L(b,f,h)}return b.join("")},cardinal:function(a,b){if(a.length<3)return H(a);return a[0]+na(a,oa(a,b))},"cardinal-closed":function(a,b){if(a.length<3)return H(a);return a[0]+na(a,oa([a[a.length-2]].concat(a,[a[1]]),b))}},pa=[0,2/3,1/3,0],qa=[0,1/3,2/3,0],M=[0,1/6,2/3,1/6];d3.svg.area=function(){function a(h){return h.length<1?null:"M"+c($(this,h,b,g),f)+"L"+c($(this,h,b,d).reverse(),f)+"Z"}var b=la,d=Na,g=ma,e="linear",c=P[e],f=0.7;a.x=function(h){if(!arguments.length)return b;
|
e;){c=a[d%g];f.shift();f.push(c[0]);h.shift();h.push(c[1]);L(b,f,h)}return b.join("")},cardinal:function(a,b){if(a.length<3)return H(a);return a[0]+oa(a,pa(a,b))},"cardinal-closed":function(a,b){if(a.length<3)return H(a);return a[0]+oa(a,pa([a[a.length-2]].concat(a,[a[1]]),b))}},qa=[0,2/3,1/3,0],ra=[0,1/3,2/3,0],M=[0,1/6,2/3,1/6];d3.svg.area=function(){function a(h){return h.length<1?null:"M"+c($(this,h,b,g),f)+"L"+c($(this,h,b,d).reverse(),f)+"Z"}var b=ma,d=Na,g=na,e="linear",c=P[e],f=0.7;a.x=function(h){if(!arguments.length)return b;
|
||||||
b=h;return a};a.y0=function(h){if(!arguments.length)return d;d=h;return a};a.y1=function(h){if(!arguments.length)return g;g=h;return a};a.interpolate=function(h){if(!arguments.length)return e;c=P[e=h];return a};a.tension=function(h){if(!arguments.length)return f;f=h;return a};return a};d3.svg.chord=function(){function a(h,i){var k=b(this,d,h,i),j=b(this,g,h,i);return"M"+k.p0+("A"+k.r+","+k.r+" 0 0,1 "+k.p1)+(k.a0==j.a0&&k.a1==j.a1?"Q 0,0 "+k.p0:"Q 0,0 "+j.p0+("A"+j.r+","+j.r+" 0 0,1 "+j.p1)+("Q 0,0 "+
|
b=h;return a};a.y0=function(h){if(!arguments.length)return d;d=h;return a};a.y1=function(h){if(!arguments.length)return g;g=h;return a};a.interpolate=function(h){if(!arguments.length)return e;c=P[e=h];return a};a.tension=function(h){if(!arguments.length)return f;f=h;return a};return a};d3.svg.chord=function(){function a(h,i){var k=b(this,d,h,i),j=b(this,g,h,i);return"M"+k.p0+("A"+k.r+","+k.r+" 0 0,1 "+k.p1)+(k.a0==j.a0&&k.a1==j.a1?"Q 0,0 "+k.p0:"Q 0,0 "+j.p0+("A"+j.r+","+j.r+" 0 0,1 "+j.p1)+("Q 0,0 "+
|
||||||
k.p0))+"Z"}function b(h,i,k,j){var o=i.call(h,k,j);i=e.call(h,o,j);k=c.call(h,o,j)+I;h=f.call(h,o,j)+I;return{r:i,a0:k,a1:h,p0:[i*Math.cos(k),i*Math.sin(k)],p1:[i*Math.cos(h),i*Math.sin(h)]}}var d=Oa,g=Pa,e=Qa,c=ja,f=ka;a.radius=function(h){if(!arguments.length)return e;e=v(h);return a};a.source=function(h){if(!arguments.length)return d;d=v(h);return a};a.target=function(h){if(!arguments.length)return g;g=v(h);return a};a.startAngle=function(h){if(!arguments.length)return c;c=v(h);return a};a.endAngle=
|
k.p0))+"Z"}function b(h,i,k,j){var o=i.call(h,k,j);i=e.call(h,o,j);k=c.call(h,o,j)+I;h=f.call(h,o,j)+I;return{r:i,a0:k,a1:h,p0:[i*Math.cos(k),i*Math.sin(k)],p1:[i*Math.cos(h),i*Math.sin(h)]}}var d=Oa,g=Pa,e=Qa,c=ka,f=la;a.radius=function(h){if(!arguments.length)return e;e=v(h);return a};a.source=function(h){if(!arguments.length)return d;d=v(h);return a};a.target=function(h){if(!arguments.length)return g;g=v(h);return a};a.startAngle=function(h){if(!arguments.length)return c;c=v(h);return a};a.endAngle=
|
||||||
function(h){if(!arguments.length)return f;f=v(h);return a};return a};d3.svg.mouse=function(a){var b=(a.ownerSVGElement||a).createSVGPoint();if(ca<0&&(window.scrollX||window.scrollY)){var d=d3.select(document.body).append("svg:svg").style("position","absolute").style("top",0).style("left",0),g=d[0][0].getScreenCTM();ca=!(g.f||g.e);d.remove()}if(ca){b.x=d3.event.pageX;b.y=d3.event.pageY}else{b.x=d3.event.clientX;b.y=d3.event.clientY}b=b.matrixTransform(a.getScreenCTM().inverse());return[b.x,b.y]};var ca=
|
function(h){if(!arguments.length)return f;f=v(h);return a};return a};d3.svg.mouse=function(a){var b=(a.ownerSVGElement||a).createSVGPoint();if(ca<0&&(window.scrollX||window.scrollY)){var d=d3.select(document.body).append("svg:svg").style("position","absolute").style("top",0).style("left",0),g=d[0][0].getScreenCTM();ca=!(g.f||g.e);d.remove()}if(ca){b.x=d3.event.pageX;b.y=d3.event.pageY}else{b.x=d3.event.clientX;b.y=d3.event.clientY}b=b.matrixTransform(a.getScreenCTM().inverse());return[b.x,b.y]};var ca=
|
||||||
/WebKit/.test(navigator.userAgent)?-1:0;d3.svg.symbol=function(){function a(g,e){return(sa[b.call(this,g,e)]||sa.circle)(d.call(this,g,e))}var b=Sa,d=Ra;a.type=function(g){if(!arguments.length)return b;b=v(g);return a};a.size=function(g){if(!arguments.length)return d;d=v(g);return a};return a};d3.svg.symbolTypes=["circle","cross","diamond","square","triangle-down","triangle-up"];var sa={circle:function(a){a=Math.sqrt(a/Math.PI);return"M0,"+a+"A"+a+","+a+" 0 1,1 0,"+-a+"A"+a+","+a+" 0 1,1 0,"+a+"Z"},
|
/WebKit/.test(navigator.userAgent)?-1:0;d3.svg.symbol=function(){function a(g,e){return(sa[b.call(this,g,e)]||sa.circle)(d.call(this,g,e))}var b=Sa,d=Ra;a.type=function(g){if(!arguments.length)return b;b=v(g);return a};a.size=function(g){if(!arguments.length)return d;d=v(g);return a};return a};d3.svg.symbolTypes=["circle","cross","diamond","square","triangle-down","triangle-up"];var sa={circle:function(a){a=Math.sqrt(a/Math.PI);return"M0,"+a+"A"+a+","+a+" 0 1,1 0,"+-a+"A"+a+","+a+" 0 1,1 0,"+a+"Z"},
|
||||||
cross:function(a){a=Math.sqrt(a/5)/2;return"M"+-3*a+","+-a+"H"+-a+"V"+-3*a+"H"+a+"V"+-a+"H"+3*a+"V"+a+"H"+a+"V"+3*a+"H"+-a+"V"+a+"H"+-3*a+"Z"},diamond:function(a){a=Math.sqrt(a/(2*ta));var b=a*ta;return"M0,"+-a+"L"+b+",0 0,"+a+" "+-b+",0Z"},square:function(a){a=Math.sqrt(a)/2;return"M"+-a+","+-a+"L"+a+","+-a+" "+a+","+a+" "+-a+","+a+"Z"},"triangle-down":function(a){a=Math.sqrt(a/Q);var b=a*Q/2;return"M0,"+b+"L"+a+","+-b+" "+-a+","+-b+"Z"},"triangle-up":function(a){a=Math.sqrt(a/Q);var b=a*Q/2;return"M0,"+
|
cross:function(a){a=Math.sqrt(a/5)/2;return"M"+-3*a+","+-a+"H"+-a+"V"+-3*a+"H"+a+"V"+-a+"H"+3*a+"V"+a+"H"+a+"V"+3*a+"H"+-a+"V"+a+"H"+-3*a+"Z"},diamond:function(a){a=Math.sqrt(a/(2*ta));var b=a*ta;return"M0,"+-a+"L"+b+",0 0,"+a+" "+-b+",0Z"},square:function(a){a=Math.sqrt(a)/2;return"M"+-a+","+-a+"L"+a+","+-a+" "+a+","+a+" "+-a+","+a+"Z"},"triangle-down":function(a){a=Math.sqrt(a/Q);var b=a*Q/2;return"M0,"+b+"L"+a+","+-b+" "+-a+","+-b+"Z"},"triangle-up":function(a){a=Math.sqrt(a/Q);var b=a*Q/2;return"M0,"+
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<title>Clustered Network</title>
|
<title>Clustered Network</title>
|
||||||
<script type="text/javascript" src="../../d3.js"></script>
|
<script type="text/javascript" src="../../d3.js"></script>
|
||||||
<script type="text/javascript" src="../../d3.geom.js"></script>
|
<script type="text/javascript" src="../../d3.geom.js"></script>
|
||||||
<script type="text/javascript" src="layout.js"></script>
|
<script type="text/javascript" src="../../d3.layout.js"></script>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
svg {
|
svg {
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
|
@ -190,10 +190,10 @@ function init() {
|
||||||
|
|
||||||
net = network(data, net, getGroup, expand);
|
net = network(data, net, getGroup, expand);
|
||||||
|
|
||||||
force = layout_force()
|
force = d3.layout.force()
|
||||||
.nodes(net.nodes)
|
.nodes(net.nodes)
|
||||||
.links(net.links)
|
.links(net.links)
|
||||||
.size({x: w, y: h})
|
.size([w, h])
|
||||||
.distance(60)
|
.distance(60)
|
||||||
.start();
|
.start();
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<head>
|
<head>
|
||||||
<title>Force-Directed Layout</title>
|
<title>Force-Directed Layout</title>
|
||||||
<script type="text/javascript" src="../../d3.js"></script>
|
<script type="text/javascript" src="../../d3.js"></script>
|
||||||
<script type="text/javascript" src="layout.js"></script>
|
<script type="text/javascript" src="../../d3.layout.js"></script>
|
||||||
<link type="text/css" rel="stylesheet" href="force.css"/>
|
<link type="text/css" rel="stylesheet" href="force.css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
|
@ -8,10 +8,10 @@ var vis = d3.select("#chart")
|
||||||
.attr("height", h);
|
.attr("height", h);
|
||||||
|
|
||||||
d3.json("miserables.json", function(json) {
|
d3.json("miserables.json", function(json) {
|
||||||
var force = layout_force()
|
var force = d3.layout.force()
|
||||||
.nodes(json.nodes)
|
.nodes(json.nodes)
|
||||||
.links(json.links)
|
.links(json.links)
|
||||||
.size({x: w, y: h})
|
.size([w, h])
|
||||||
.start();
|
.start();
|
||||||
|
|
||||||
var link = vis.selectAll("line.link")
|
var link = vis.selectAll("line.link")
|
||||||
|
|
|
@ -1,284 +1,286 @@
|
||||||
{
|
{
|
||||||
"analytics": {
|
"flare": {
|
||||||
"cluster": {
|
"analytics": {
|
||||||
"AgglomerativeCluster": 3938,
|
"cluster": {
|
||||||
"CommunityStructure": 3812,
|
"AgglomerativeCluster": 3938,
|
||||||
"HierarchicalCluster": 6714,
|
"CommunityStructure": 3812,
|
||||||
"MergeEdge": 743
|
"HierarchicalCluster": 6714,
|
||||||
|
"MergeEdge": 743
|
||||||
|
},
|
||||||
|
"graph": {
|
||||||
|
"BetweennessCentrality": 3534,
|
||||||
|
"LinkDistance": 5731,
|
||||||
|
"MaxFlowMinCut": 7840,
|
||||||
|
"ShortestPaths": 5914,
|
||||||
|
"SpanningTree": 3416
|
||||||
|
},
|
||||||
|
"optimization": {
|
||||||
|
"AspectRatioBanker": 7074
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"graph": {
|
"animate": {
|
||||||
"BetweennessCentrality": 3534,
|
"Easing": 17010,
|
||||||
"LinkDistance": 5731,
|
"FunctionSequence": 5842,
|
||||||
"MaxFlowMinCut": 7840,
|
"interpolate": {
|
||||||
"ShortestPaths": 5914,
|
"ArrayInterpolator": 1983,
|
||||||
"SpanningTree": 3416
|
"ColorInterpolator": 2047,
|
||||||
},
|
"DateInterpolator": 1375,
|
||||||
"optimization": {
|
"Interpolator": 8746,
|
||||||
"AspectRatioBanker": 7074
|
"MatrixInterpolator": 2202,
|
||||||
}
|
"NumberInterpolator": 1382,
|
||||||
},
|
"ObjectInterpolator": 1629,
|
||||||
"animate": {
|
"PointInterpolator": 1675,
|
||||||
"Easing": 17010,
|
"RectangleInterpolator": 2042
|
||||||
"FunctionSequence": 5842,
|
},
|
||||||
"interpolate": {
|
"ISchedulable": 1041,
|
||||||
"ArrayInterpolator": 1983,
|
"Parallel": 5176,
|
||||||
"ColorInterpolator": 2047,
|
"Pause": 449,
|
||||||
"DateInterpolator": 1375,
|
"Scheduler": 5593,
|
||||||
"Interpolator": 8746,
|
"Sequence": 5534,
|
||||||
"MatrixInterpolator": 2202,
|
"Transition": 9201,
|
||||||
"NumberInterpolator": 1382,
|
"Transitioner": 19975,
|
||||||
"ObjectInterpolator": 1629,
|
"TransitionEvent": 1116,
|
||||||
"PointInterpolator": 1675,
|
"Tween": 6006
|
||||||
"RectangleInterpolator": 2042
|
|
||||||
},
|
|
||||||
"ISchedulable": 1041,
|
|
||||||
"Parallel": 5176,
|
|
||||||
"Pause": 449,
|
|
||||||
"Scheduler": 5593,
|
|
||||||
"Sequence": 5534,
|
|
||||||
"Transition": 9201,
|
|
||||||
"Transitioner": 19975,
|
|
||||||
"TransitionEvent": 1116,
|
|
||||||
"Tween": 6006
|
|
||||||
},
|
|
||||||
"data": {
|
|
||||||
"converters": {
|
|
||||||
"Converters": 721,
|
|
||||||
"DelimitedTextConverter": 4294,
|
|
||||||
"GraphMLConverter": 9800,
|
|
||||||
"IDataConverter": 1314,
|
|
||||||
"JSONConverter": 2220
|
|
||||||
},
|
|
||||||
"DataField": 1759,
|
|
||||||
"DataSchema": 2165,
|
|
||||||
"DataSet": 586,
|
|
||||||
"DataSource": 3331,
|
|
||||||
"DataTable": 772,
|
|
||||||
"DataUtil": 3322
|
|
||||||
},
|
|
||||||
"display": {
|
|
||||||
"DirtySprite": 8833,
|
|
||||||
"LineSprite": 1732,
|
|
||||||
"RectSprite": 3623,
|
|
||||||
"TextSprite": 10066
|
|
||||||
},
|
|
||||||
"flex": {
|
|
||||||
"FlareVis": 4116
|
|
||||||
},
|
|
||||||
"physics": {
|
|
||||||
"DragForce": 1082,
|
|
||||||
"GravityForce": 1336,
|
|
||||||
"IForce": 319,
|
|
||||||
"NBodyForce": 10498,
|
|
||||||
"Particle": 2822,
|
|
||||||
"Simulation": 9983,
|
|
||||||
"Spring": 2213,
|
|
||||||
"SpringForce": 1681
|
|
||||||
},
|
|
||||||
"query": {
|
|
||||||
"AggregateExpression": 1616,
|
|
||||||
"And": 1027,
|
|
||||||
"Arithmetic": 3891,
|
|
||||||
"Average": 891,
|
|
||||||
"BinaryExpression": 2893,
|
|
||||||
"Comparison": 5103,
|
|
||||||
"CompositeExpression": 3677,
|
|
||||||
"Count": 781,
|
|
||||||
"DateUtil": 4141,
|
|
||||||
"Distinct": 933,
|
|
||||||
"Expression": 5130,
|
|
||||||
"ExpressionIterator": 3617,
|
|
||||||
"Fn": 3240,
|
|
||||||
"If": 2732,
|
|
||||||
"IsA": 2039,
|
|
||||||
"Literal": 1214,
|
|
||||||
"Match": 3748,
|
|
||||||
"Maximum": 843,
|
|
||||||
"methods": {
|
|
||||||
"add": 593,
|
|
||||||
"and": 330,
|
|
||||||
"average": 287,
|
|
||||||
"count": 277,
|
|
||||||
"distinct": 292,
|
|
||||||
"div": 595,
|
|
||||||
"eq": 594,
|
|
||||||
"fn": 460,
|
|
||||||
"gt": 603,
|
|
||||||
"gte": 625,
|
|
||||||
"iff": 748,
|
|
||||||
"isa": 461,
|
|
||||||
"lt": 597,
|
|
||||||
"lte": 619,
|
|
||||||
"max": 283,
|
|
||||||
"min": 283,
|
|
||||||
"mod": 591,
|
|
||||||
"mul": 603,
|
|
||||||
"neq": 599,
|
|
||||||
"not": 386,
|
|
||||||
"or": 323,
|
|
||||||
"orderby": 307,
|
|
||||||
"range": 772,
|
|
||||||
"select": 296,
|
|
||||||
"stddev": 363,
|
|
||||||
"sub": 600,
|
|
||||||
"sum": 280,
|
|
||||||
"update": 307,
|
|
||||||
"variance": 335,
|
|
||||||
"where": 299,
|
|
||||||
"xor": 354,
|
|
||||||
"_": 264
|
|
||||||
},
|
|
||||||
"Minimum": 843,
|
|
||||||
"Not": 1554,
|
|
||||||
"Or": 970,
|
|
||||||
"Query": 13896,
|
|
||||||
"Range": 1594,
|
|
||||||
"StringUtil": 4130,
|
|
||||||
"Sum": 791,
|
|
||||||
"Variable": 1124,
|
|
||||||
"Variance": 1876,
|
|
||||||
"Xor": 1101
|
|
||||||
},
|
|
||||||
"scale": {
|
|
||||||
"IScaleMap": 2105,
|
|
||||||
"LinearScale": 1316,
|
|
||||||
"LogScale": 3151,
|
|
||||||
"OrdinalScale": 3770,
|
|
||||||
"QuantileScale": 2435,
|
|
||||||
"QuantitativeScale": 4839,
|
|
||||||
"RootScale": 1756,
|
|
||||||
"Scale": 4268,
|
|
||||||
"ScaleType": 1821,
|
|
||||||
"TimeScale": 5833
|
|
||||||
},
|
|
||||||
"util": {
|
|
||||||
"Arrays": 8258,
|
|
||||||
"Colors": 10001,
|
|
||||||
"Dates": 8217,
|
|
||||||
"Displays": 12555,
|
|
||||||
"Filter": 2324,
|
|
||||||
"Geometry": 10993,
|
|
||||||
"heap": {
|
|
||||||
"FibonacciHeap": 9354,
|
|
||||||
"HeapNode": 1233
|
|
||||||
},
|
|
||||||
"IEvaluable": 335,
|
|
||||||
"IPredicate": 383,
|
|
||||||
"IValueProxy": 874,
|
|
||||||
"math": {
|
|
||||||
"DenseMatrix": 3165,
|
|
||||||
"IMatrix": 2815,
|
|
||||||
"SparseMatrix": 3366
|
|
||||||
},
|
|
||||||
"Maths": 17705,
|
|
||||||
"Orientation": 1486,
|
|
||||||
"palette": {
|
|
||||||
"ColorPalette": 6367,
|
|
||||||
"Palette": 1229,
|
|
||||||
"ShapePalette": 2059,
|
|
||||||
"SizePalette": 2291
|
|
||||||
},
|
|
||||||
"Property": 5559,
|
|
||||||
"Shapes": 19118,
|
|
||||||
"Sort": 6887,
|
|
||||||
"Stats": 6557,
|
|
||||||
"Strings": 22026
|
|
||||||
},
|
|
||||||
"vis": {
|
|
||||||
"axis": {
|
|
||||||
"Axes": 1302,
|
|
||||||
"Axis": 24593,
|
|
||||||
"AxisGridLine": 652,
|
|
||||||
"AxisLabel": 636,
|
|
||||||
"CartesianAxes": 6703
|
|
||||||
},
|
|
||||||
"controls": {
|
|
||||||
"AnchorControl": 2138,
|
|
||||||
"ClickControl": 3824,
|
|
||||||
"Control": 1353,
|
|
||||||
"ControlList": 4665,
|
|
||||||
"DragControl": 2649,
|
|
||||||
"ExpandControl": 2832,
|
|
||||||
"HoverControl": 4896,
|
|
||||||
"IControl": 763,
|
|
||||||
"PanZoomControl": 5222,
|
|
||||||
"SelectionControl": 7862,
|
|
||||||
"TooltipControl": 8435
|
|
||||||
},
|
},
|
||||||
"data": {
|
"data": {
|
||||||
"Data": 20544,
|
"converters": {
|
||||||
"DataList": 19788,
|
"Converters": 721,
|
||||||
"DataSprite": 10349,
|
"DelimitedTextConverter": 4294,
|
||||||
"EdgeSprite": 3301,
|
"GraphMLConverter": 9800,
|
||||||
"NodeSprite": 19382,
|
"IDataConverter": 1314,
|
||||||
"render": {
|
"JSONConverter": 2220
|
||||||
"ArrowType": 698,
|
|
||||||
"EdgeRenderer": 5569,
|
|
||||||
"IRenderer": 353,
|
|
||||||
"ShapeRenderer": 2247
|
|
||||||
},
|
},
|
||||||
"ScaleBinding": 11275,
|
"DataField": 1759,
|
||||||
"Tree": 7147,
|
"DataSchema": 2165,
|
||||||
"TreeBuilder": 9930
|
"DataSet": 586,
|
||||||
|
"DataSource": 3331,
|
||||||
|
"DataTable": 772,
|
||||||
|
"DataUtil": 3322
|
||||||
},
|
},
|
||||||
"events": {
|
"display": {
|
||||||
"DataEvent": 2313,
|
"DirtySprite": 8833,
|
||||||
"SelectionEvent": 1880,
|
"LineSprite": 1732,
|
||||||
"TooltipEvent": 1701,
|
"RectSprite": 3623,
|
||||||
"VisualizationEvent": 1117
|
"TextSprite": 10066
|
||||||
},
|
},
|
||||||
"legend": {
|
"flex": {
|
||||||
"Legend": 20859,
|
"FlareVis": 4116
|
||||||
"LegendItem": 4614,
|
|
||||||
"LegendRange": 10530
|
|
||||||
},
|
},
|
||||||
"operator": {
|
"physics": {
|
||||||
"distortion": {
|
"DragForce": 1082,
|
||||||
"BifocalDistortion": 4461,
|
"GravityForce": 1336,
|
||||||
"Distortion": 6314,
|
"IForce": 319,
|
||||||
"FisheyeDistortion": 3444
|
"NBodyForce": 10498,
|
||||||
},
|
"Particle": 2822,
|
||||||
"encoder": {
|
"Simulation": 9983,
|
||||||
"ColorEncoder": 3179,
|
"Spring": 2213,
|
||||||
"Encoder": 4060,
|
"SpringForce": 1681
|
||||||
"PropertyEncoder": 4138,
|
|
||||||
"ShapeEncoder": 1690,
|
|
||||||
"SizeEncoder": 1830
|
|
||||||
},
|
|
||||||
"filter": {
|
|
||||||
"FisheyeTreeFilter": 5219,
|
|
||||||
"GraphDistanceFilter": 3165,
|
|
||||||
"VisibilityFilter": 3509
|
|
||||||
},
|
|
||||||
"IOperator": 1286,
|
|
||||||
"label": {
|
|
||||||
"Labeler": 9956,
|
|
||||||
"RadialLabeler": 3899,
|
|
||||||
"StackedAreaLabeler": 3202
|
|
||||||
},
|
|
||||||
"layout": {
|
|
||||||
"AxisLayout": 6725,
|
|
||||||
"BundledEdgeRouter": 3727,
|
|
||||||
"CircleLayout": 9317,
|
|
||||||
"CirclePackingLayout": 12003,
|
|
||||||
"DendrogramLayout": 4853,
|
|
||||||
"ForceDirectedLayout": 8411,
|
|
||||||
"IcicleTreeLayout": 4864,
|
|
||||||
"IndentedTreeLayout": 3174,
|
|
||||||
"Layout": 7881,
|
|
||||||
"NodeLinkTreeLayout": 12870,
|
|
||||||
"PieLayout": 2728,
|
|
||||||
"RadialTreeLayout": 12348,
|
|
||||||
"RandomLayout": 870,
|
|
||||||
"StackedAreaLayout": 9121,
|
|
||||||
"TreeMapLayout": 9191
|
|
||||||
},
|
|
||||||
"Operator": 2490,
|
|
||||||
"OperatorList": 5248,
|
|
||||||
"OperatorSequence": 4190,
|
|
||||||
"OperatorSwitch": 2581,
|
|
||||||
"SortOperator": 2023
|
|
||||||
},
|
},
|
||||||
"Visualization": 16540
|
"query": {
|
||||||
|
"AggregateExpression": 1616,
|
||||||
|
"And": 1027,
|
||||||
|
"Arithmetic": 3891,
|
||||||
|
"Average": 891,
|
||||||
|
"BinaryExpression": 2893,
|
||||||
|
"Comparison": 5103,
|
||||||
|
"CompositeExpression": 3677,
|
||||||
|
"Count": 781,
|
||||||
|
"DateUtil": 4141,
|
||||||
|
"Distinct": 933,
|
||||||
|
"Expression": 5130,
|
||||||
|
"ExpressionIterator": 3617,
|
||||||
|
"Fn": 3240,
|
||||||
|
"If": 2732,
|
||||||
|
"IsA": 2039,
|
||||||
|
"Literal": 1214,
|
||||||
|
"Match": 3748,
|
||||||
|
"Maximum": 843,
|
||||||
|
"methods": {
|
||||||
|
"add": 593,
|
||||||
|
"and": 330,
|
||||||
|
"average": 287,
|
||||||
|
"count": 277,
|
||||||
|
"distinct": 292,
|
||||||
|
"div": 595,
|
||||||
|
"eq": 594,
|
||||||
|
"fn": 460,
|
||||||
|
"gt": 603,
|
||||||
|
"gte": 625,
|
||||||
|
"iff": 748,
|
||||||
|
"isa": 461,
|
||||||
|
"lt": 597,
|
||||||
|
"lte": 619,
|
||||||
|
"max": 283,
|
||||||
|
"min": 283,
|
||||||
|
"mod": 591,
|
||||||
|
"mul": 603,
|
||||||
|
"neq": 599,
|
||||||
|
"not": 386,
|
||||||
|
"or": 323,
|
||||||
|
"orderby": 307,
|
||||||
|
"range": 772,
|
||||||
|
"select": 296,
|
||||||
|
"stddev": 363,
|
||||||
|
"sub": 600,
|
||||||
|
"sum": 280,
|
||||||
|
"update": 307,
|
||||||
|
"variance": 335,
|
||||||
|
"where": 299,
|
||||||
|
"xor": 354,
|
||||||
|
"_": 264
|
||||||
|
},
|
||||||
|
"Minimum": 843,
|
||||||
|
"Not": 1554,
|
||||||
|
"Or": 970,
|
||||||
|
"Query": 13896,
|
||||||
|
"Range": 1594,
|
||||||
|
"StringUtil": 4130,
|
||||||
|
"Sum": 791,
|
||||||
|
"Variable": 1124,
|
||||||
|
"Variance": 1876,
|
||||||
|
"Xor": 1101
|
||||||
|
},
|
||||||
|
"scale": {
|
||||||
|
"IScaleMap": 2105,
|
||||||
|
"LinearScale": 1316,
|
||||||
|
"LogScale": 3151,
|
||||||
|
"OrdinalScale": 3770,
|
||||||
|
"QuantileScale": 2435,
|
||||||
|
"QuantitativeScale": 4839,
|
||||||
|
"RootScale": 1756,
|
||||||
|
"Scale": 4268,
|
||||||
|
"ScaleType": 1821,
|
||||||
|
"TimeScale": 5833
|
||||||
|
},
|
||||||
|
"util": {
|
||||||
|
"Arrays": 8258,
|
||||||
|
"Colors": 10001,
|
||||||
|
"Dates": 8217,
|
||||||
|
"Displays": 12555,
|
||||||
|
"Filter": 2324,
|
||||||
|
"Geometry": 10993,
|
||||||
|
"heap": {
|
||||||
|
"FibonacciHeap": 9354,
|
||||||
|
"HeapNode": 1233
|
||||||
|
},
|
||||||
|
"IEvaluable": 335,
|
||||||
|
"IPredicate": 383,
|
||||||
|
"IValueProxy": 874,
|
||||||
|
"math": {
|
||||||
|
"DenseMatrix": 3165,
|
||||||
|
"IMatrix": 2815,
|
||||||
|
"SparseMatrix": 3366
|
||||||
|
},
|
||||||
|
"Maths": 17705,
|
||||||
|
"Orientation": 1486,
|
||||||
|
"palette": {
|
||||||
|
"ColorPalette": 6367,
|
||||||
|
"Palette": 1229,
|
||||||
|
"ShapePalette": 2059,
|
||||||
|
"SizePalette": 2291
|
||||||
|
},
|
||||||
|
"Property": 5559,
|
||||||
|
"Shapes": 19118,
|
||||||
|
"Sort": 6887,
|
||||||
|
"Stats": 6557,
|
||||||
|
"Strings": 22026
|
||||||
|
},
|
||||||
|
"vis": {
|
||||||
|
"axis": {
|
||||||
|
"Axes": 1302,
|
||||||
|
"Axis": 24593,
|
||||||
|
"AxisGridLine": 652,
|
||||||
|
"AxisLabel": 636,
|
||||||
|
"CartesianAxes": 6703
|
||||||
|
},
|
||||||
|
"controls": {
|
||||||
|
"AnchorControl": 2138,
|
||||||
|
"ClickControl": 3824,
|
||||||
|
"Control": 1353,
|
||||||
|
"ControlList": 4665,
|
||||||
|
"DragControl": 2649,
|
||||||
|
"ExpandControl": 2832,
|
||||||
|
"HoverControl": 4896,
|
||||||
|
"IControl": 763,
|
||||||
|
"PanZoomControl": 5222,
|
||||||
|
"SelectionControl": 7862,
|
||||||
|
"TooltipControl": 8435
|
||||||
|
},
|
||||||
|
"data": {
|
||||||
|
"Data": 20544,
|
||||||
|
"DataList": 19788,
|
||||||
|
"DataSprite": 10349,
|
||||||
|
"EdgeSprite": 3301,
|
||||||
|
"NodeSprite": 19382,
|
||||||
|
"render": {
|
||||||
|
"ArrowType": 698,
|
||||||
|
"EdgeRenderer": 5569,
|
||||||
|
"IRenderer": 353,
|
||||||
|
"ShapeRenderer": 2247
|
||||||
|
},
|
||||||
|
"ScaleBinding": 11275,
|
||||||
|
"Tree": 7147,
|
||||||
|
"TreeBuilder": 9930
|
||||||
|
},
|
||||||
|
"events": {
|
||||||
|
"DataEvent": 2313,
|
||||||
|
"SelectionEvent": 1880,
|
||||||
|
"TooltipEvent": 1701,
|
||||||
|
"VisualizationEvent": 1117
|
||||||
|
},
|
||||||
|
"legend": {
|
||||||
|
"Legend": 20859,
|
||||||
|
"LegendItem": 4614,
|
||||||
|
"LegendRange": 10530
|
||||||
|
},
|
||||||
|
"operator": {
|
||||||
|
"distortion": {
|
||||||
|
"BifocalDistortion": 4461,
|
||||||
|
"Distortion": 6314,
|
||||||
|
"FisheyeDistortion": 3444
|
||||||
|
},
|
||||||
|
"encoder": {
|
||||||
|
"ColorEncoder": 3179,
|
||||||
|
"Encoder": 4060,
|
||||||
|
"PropertyEncoder": 4138,
|
||||||
|
"ShapeEncoder": 1690,
|
||||||
|
"SizeEncoder": 1830
|
||||||
|
},
|
||||||
|
"filter": {
|
||||||
|
"FisheyeTreeFilter": 5219,
|
||||||
|
"GraphDistanceFilter": 3165,
|
||||||
|
"VisibilityFilter": 3509
|
||||||
|
},
|
||||||
|
"IOperator": 1286,
|
||||||
|
"label": {
|
||||||
|
"Labeler": 9956,
|
||||||
|
"RadialLabeler": 3899,
|
||||||
|
"StackedAreaLabeler": 3202
|
||||||
|
},
|
||||||
|
"layout": {
|
||||||
|
"AxisLayout": 6725,
|
||||||
|
"BundledEdgeRouter": 3727,
|
||||||
|
"CircleLayout": 9317,
|
||||||
|
"CirclePackingLayout": 12003,
|
||||||
|
"DendrogramLayout": 4853,
|
||||||
|
"ForceDirectedLayout": 8411,
|
||||||
|
"IcicleTreeLayout": 4864,
|
||||||
|
"IndentedTreeLayout": 3174,
|
||||||
|
"Layout": 7881,
|
||||||
|
"NodeLinkTreeLayout": 12870,
|
||||||
|
"PieLayout": 2728,
|
||||||
|
"RadialTreeLayout": 12348,
|
||||||
|
"RandomLayout": 870,
|
||||||
|
"StackedAreaLayout": 9121,
|
||||||
|
"TreeMapLayout": 9191
|
||||||
|
},
|
||||||
|
"Operator": 2490,
|
||||||
|
"OperatorList": 5248,
|
||||||
|
"OperatorSequence": 4190,
|
||||||
|
"OperatorSwitch": 2581,
|
||||||
|
"SortOperator": 2023
|
||||||
|
},
|
||||||
|
"Visualization": 16540
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
.cell {
|
||||||
|
border: solid 1px white;
|
||||||
|
font: 10px sans-serif;
|
||||||
|
line-height: 12px;
|
||||||
|
overflow: hidden;
|
||||||
|
position: absolute;
|
||||||
|
text-indent: 2px;
|
||||||
|
}
|
|
@ -4,49 +4,11 @@
|
||||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||||
<title>Treemap</title>
|
<title>Treemap</title>
|
||||||
<script type="text/javascript" src="../../d3.js"></script>
|
<script type="text/javascript" src="../../d3.js"></script>
|
||||||
<script type="text/javascript" src="layout.js"></script>
|
<script type="text/javascript" src="../../d3.layout.js"></script>
|
||||||
<style type="text/css">
|
<link type="text/css" rel="stylesheet" href="treemap.css"></script>
|
||||||
|
|
||||||
body {
|
|
||||||
font: 10px sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cell {
|
|
||||||
position: absolute;
|
|
||||||
background: lightsteelblue;
|
|
||||||
border: solid 1px white;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script type="text/javascript">
|
<div id="chart"></div>
|
||||||
|
<script type="text/javascript" src="treemap.js"></script>
|
||||||
var w = 960,
|
|
||||||
h = 500;
|
|
||||||
|
|
||||||
var div = d3.select("body").append("div")
|
|
||||||
.style("position", "relative");
|
|
||||||
|
|
||||||
var treemap = layout_treemap()
|
|
||||||
.size([w, h])
|
|
||||||
.children(function(d, i) { return typeof d.value == "object" && d3.entries(d.value); })
|
|
||||||
.value(function(d) { return d.value; });
|
|
||||||
|
|
||||||
d3.json("flare.json", function(json) {
|
|
||||||
div.data([{key: "flare", value: json}]).selectAll("div")
|
|
||||||
.data(treemap)
|
|
||||||
.enter().append("div")
|
|
||||||
.attr("class", "cell")
|
|
||||||
.style("left", function(d) { return d.x + "px"; })
|
|
||||||
.style("top", function(d) { return d.y + "px"; })
|
|
||||||
.style("width", function(d) { return d.dx + "px"; })
|
|
||||||
.style("height", function(d) { return d.dy + "px"; })
|
|
||||||
.text(function(d) { return d.data.key; });
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
var w = 960,
|
||||||
|
h = 500,
|
||||||
|
color = d3.scale.category20c();
|
||||||
|
|
||||||
|
var treemap = d3.layout.treemap()
|
||||||
|
.size([w, h])
|
||||||
|
.children(function(d) { return typeof d.value == "object" && d3.entries(d.value); })
|
||||||
|
.value(function(d) { return d.value; });
|
||||||
|
|
||||||
|
var div = d3.select("#chart").append("div")
|
||||||
|
.style("position", "relative")
|
||||||
|
.style("width", w + "px")
|
||||||
|
.style("height", h + "px");
|
||||||
|
|
||||||
|
d3.json("flare.json", function(json) {
|
||||||
|
div.data(d3.entries(json)).selectAll("div")
|
||||||
|
.data(treemap)
|
||||||
|
.enter().append("div")
|
||||||
|
.attr("class", "cell")
|
||||||
|
.style("background", function(d) { return d.children ? color(d.data.key) : null; })
|
||||||
|
.style("left", function(d) { return d.x + "px"; })
|
||||||
|
.style("top", function(d) { return d.y + "px"; })
|
||||||
|
.style("width", function(d) { return d.dx - 1 + "px"; })
|
||||||
|
.style("height", function(d) { return d.dy - 1 + "px"; })
|
||||||
|
.text(function(d) { return d.children ? null : d.data.key; });
|
||||||
|
});
|
|
@ -0,0 +1,20 @@
|
||||||
|
Copyright (c) 2009 John Resig, http://jquery.com/
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
|
a copy of this software and associated documentation files (the
|
||||||
|
"Software"), to deal in the Software without restriction, including
|
||||||
|
without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
distribute, sublicense, and/or sell copies of the Software, and to
|
||||||
|
permit persons to whom the Software is furnished to do so, subject to
|
||||||
|
the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be
|
||||||
|
included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||||
|
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||||
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
@ -0,0 +1,39 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Usage: envjs <platorm> file.js [file2.js ...]
|
||||||
|
###########################################################################
|
||||||
|
ENVJS_PLATFORM='node'
|
||||||
|
|
||||||
|
# first arguments ($1)
|
||||||
|
# may be a platform or is a file and the default platorm is used
|
||||||
|
if [ -n "$1" ]; then
|
||||||
|
if [ -n "$1" ]; then ENVJS_PLATFORM="$1"; shift; fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Run envjs with the given platform
|
||||||
|
###########################################################################
|
||||||
|
case "$ENVJS_PLATFORM" in
|
||||||
|
|
||||||
|
"node")
|
||||||
|
node envjs/node.js $@
|
||||||
|
;;
|
||||||
|
"rhino")
|
||||||
|
java -Xmx512M -jar rhino/js.jar -opt -1 envjs/rhino.js $@
|
||||||
|
;;
|
||||||
|
"rhino-debug")
|
||||||
|
java -cp rhino/js.jar org.mozilla.javascript.tools.debugger.Main envjs/rhino.js $@
|
||||||
|
;;
|
||||||
|
"spyd")
|
||||||
|
python envjs/spydermonkey.py envjs/spydermonkey.js $@
|
||||||
|
;;
|
||||||
|
"rubyracer")
|
||||||
|
ruby -rrubygems envjs/rubyracer.rb envjs/rubyracer.js $@
|
||||||
|
;;
|
||||||
|
"johnson")
|
||||||
|
ruby -rrubygems envjs/johnson.rb envjs/johnson.js $@
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# platform default means $1 was actually a file
|
||||||
|
node envjs/node.js $ENVJS_PLATFORM $@
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
|
@ -0,0 +1,278 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author envjs team
|
||||||
|
* @Console
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Envjs = Envjs || require('./platform/core').Envjs;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Envjs console.1.3.pre03
|
||||||
|
* Pure JavaScript Browser Environment
|
||||||
|
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||||
|
* Copyright 2008-2010 John Resig, under the MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
//CLOSURE_START
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author envjs team
|
||||||
|
* borrowed 99%-ish with love from firebug-lite
|
||||||
|
*/
|
||||||
|
|
||||||
|
//leaked globally on purpose;
|
||||||
|
try{
|
||||||
|
console.log();
|
||||||
|
}catch(e){
|
||||||
|
|
||||||
|
|
||||||
|
function escapeHTML(value)
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function objectToString(object)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return object+"";
|
||||||
|
}
|
||||||
|
catch (exc)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ********************************************************************************************
|
||||||
|
|
||||||
|
function appendText(object, html)
|
||||||
|
{
|
||||||
|
html.push(escapeHTML(objectToString(object)));
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendNull(object, html)
|
||||||
|
{
|
||||||
|
html.push(escapeHTML(objectToString(object)));
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendString(object, html)
|
||||||
|
{
|
||||||
|
html.push(escapeHTML(objectToString(object)));
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendInteger(object, html)
|
||||||
|
{
|
||||||
|
html.push(escapeHTML(objectToString(object)));
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendFloat(object, html)
|
||||||
|
{
|
||||||
|
html.push(escapeHTML(objectToString(object)));
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendFunction(object, html)
|
||||||
|
{
|
||||||
|
var reName = /function ?(.*?)\(/;
|
||||||
|
var m = reName.exec(objectToString(object));
|
||||||
|
var name = m ? m[1] : "function";
|
||||||
|
html.push(escapeHTML(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendObjectFormatted(object, html)
|
||||||
|
{
|
||||||
|
var text = objectToString(object);
|
||||||
|
var reObject = /\[object (.*?)\]/;
|
||||||
|
|
||||||
|
var m = reObject.exec(text);
|
||||||
|
html.push( m ? m[1] : text);
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendSelector(object, html)
|
||||||
|
{
|
||||||
|
|
||||||
|
html.push(escapeHTML(object.nodeName.toLowerCase()));
|
||||||
|
if (object.id) {
|
||||||
|
html.push(escapeHTML(object.id));
|
||||||
|
}
|
||||||
|
if (object.className) {
|
||||||
|
html.push(escapeHTML(object.className));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendNode(node, html)
|
||||||
|
{
|
||||||
|
if (node.nodeType == 1)
|
||||||
|
{
|
||||||
|
html.push( node.nodeName.toLowerCase());
|
||||||
|
|
||||||
|
for (var i = 0; i < node.attributes.length; ++i)
|
||||||
|
{
|
||||||
|
var attr = node.attributes[i];
|
||||||
|
if (!attr.specified) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.push( attr.nodeName.toLowerCase(),escapeHTML(attr.nodeValue));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node.firstChild)
|
||||||
|
{
|
||||||
|
for (var child = node.firstChild; child; child = child.nextSibling) {
|
||||||
|
appendNode(child, html);
|
||||||
|
}
|
||||||
|
|
||||||
|
html.push( node.nodeName.toLowerCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (node.nodeType === 3)
|
||||||
|
{
|
||||||
|
html.push(escapeHTML(node.nodeValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function appendObject(object, html)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (object === undefined) {
|
||||||
|
appendNull("undefined", html);
|
||||||
|
} else if (object === null) {
|
||||||
|
appendNull("null", html);
|
||||||
|
} else if (typeof object == "string") {
|
||||||
|
appendString(object, html);
|
||||||
|
} else if (typeof object == "number") {
|
||||||
|
appendInteger(object, html);
|
||||||
|
} else if (typeof object == "function") {
|
||||||
|
appendFunction(object, html);
|
||||||
|
} else if (object.nodeType == 1) {
|
||||||
|
appendSelector(object, html);
|
||||||
|
} else if (typeof object == "object") {
|
||||||
|
appendObjectFormatted(object, html);
|
||||||
|
} else {
|
||||||
|
appendText(object, html);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (exc)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function parseFormat(format)
|
||||||
|
{
|
||||||
|
var parts = [];
|
||||||
|
|
||||||
|
var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
|
||||||
|
var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat};
|
||||||
|
|
||||||
|
for (var m = reg.exec(format); m; m = reg.exec(format))
|
||||||
|
{
|
||||||
|
var type = m[8] ? m[8] : m[5];
|
||||||
|
var appender = type in appenderMap ? appenderMap[type] : appendObject;
|
||||||
|
var precision = m[3] ? parseInt(m[3], 10) : (m[4] == "." ? -1 : 0);
|
||||||
|
|
||||||
|
parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
|
||||||
|
parts.push({appender: appender, precision: precision});
|
||||||
|
|
||||||
|
format = format.substr(m.index+m[0].length);
|
||||||
|
}
|
||||||
|
|
||||||
|
parts.push(format);
|
||||||
|
|
||||||
|
return parts;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function logFormatted(objects, className)
|
||||||
|
{
|
||||||
|
var html = [],
|
||||||
|
i= 0,
|
||||||
|
object;
|
||||||
|
|
||||||
|
var format = objects[0];
|
||||||
|
var objIndex = 0;
|
||||||
|
|
||||||
|
if (typeof(format) != "string")
|
||||||
|
{
|
||||||
|
format = "";
|
||||||
|
objIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
var parts = parseFormat(format);
|
||||||
|
for (i = 0; i < parts.length; ++i)
|
||||||
|
{
|
||||||
|
var part = parts[i];
|
||||||
|
if (part && typeof(part) == "object")
|
||||||
|
{
|
||||||
|
object = objects[++objIndex];
|
||||||
|
part.appender(object, html);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
appendText(part, html);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = objIndex+1; i < objects.length; ++i)
|
||||||
|
{
|
||||||
|
appendText(" ", html);
|
||||||
|
|
||||||
|
object = objects[i];
|
||||||
|
if (typeof(object) == "string") {
|
||||||
|
appendText(object, html);
|
||||||
|
} else {
|
||||||
|
appendObject(object, html);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Envjs.log(html.join(' '));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Console = function(module){
|
||||||
|
var $level,
|
||||||
|
$logger,
|
||||||
|
$null = function(){};
|
||||||
|
$logger = {
|
||||||
|
log: function(level){
|
||||||
|
logFormatted(arguments, "");
|
||||||
|
},
|
||||||
|
debug: function(level){
|
||||||
|
logFormatted(arguments, "DEBUG");
|
||||||
|
},
|
||||||
|
info: function(level){
|
||||||
|
logFormatted(arguments, "INFO");
|
||||||
|
},
|
||||||
|
warn: function(level){
|
||||||
|
logFormatted(arguments, "WARN");
|
||||||
|
},
|
||||||
|
error: function(level){
|
||||||
|
logFormatted(arguments, "ERROR");
|
||||||
|
},
|
||||||
|
trace: function(){
|
||||||
|
Envjs.trace();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return $logger;
|
||||||
|
};
|
||||||
|
|
||||||
|
console = new Console();
|
||||||
|
exports.console = console;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author john resig & the envjs team
|
||||||
|
* @uri http://www.envjs.com/
|
||||||
|
* @copyright 2008-2010
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
//CLOSURE_END
|
||||||
|
}());
|
|
@ -0,0 +1,695 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DOM Style Level 2
|
||||||
|
|
||||||
|
Leaked globally
|
||||||
|
|
||||||
|
var CSS2Properties,
|
||||||
|
CSSRule,
|
||||||
|
CSSStyleRule,
|
||||||
|
CSSImportRule,
|
||||||
|
CSSMediaRule,
|
||||||
|
CSSFontFaceRule,
|
||||||
|
CSSPageRule,
|
||||||
|
CSSRuleList,
|
||||||
|
CSSStyleSheet,
|
||||||
|
StyleSheet,
|
||||||
|
StyleSheetList;
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Envjs = Envjs || require('./platform/core').Envjs,
|
||||||
|
Document = require('./dom').Document,
|
||||||
|
HTMLElement = require('./html').HTMLElement;
|
||||||
|
/*
|
||||||
|
* Envjs css.1.3.pre03
|
||||||
|
* Pure JavaScript Browser Environment
|
||||||
|
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||||
|
* Copyright 2008-2010 John Resig, under the MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
//CLOSURE_START
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author john resig
|
||||||
|
*/
|
||||||
|
// Helper method for extending one object with another.
|
||||||
|
function __extend__(a,b) {
|
||||||
|
for ( var i in b ) {
|
||||||
|
if(b.hasOwnProperty(i)){
|
||||||
|
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
|
||||||
|
if ( g || s ) {
|
||||||
|
if ( g ) { a.__defineGetter__(i, g); }
|
||||||
|
if ( s ) { a.__defineSetter__(i, s); }
|
||||||
|
} else {
|
||||||
|
a[i] = b[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author john resig
|
||||||
|
*/
|
||||||
|
//from jQuery
|
||||||
|
function __setArray__( target, array ) {
|
||||||
|
// Resetting the length to 0, then using the native Array push
|
||||||
|
// is a super-fast way to populate an object with array-like properties
|
||||||
|
target.length = 0;
|
||||||
|
Array.prototype.push.apply( target, array );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ariel flesler
|
||||||
|
* http://flesler.blogspot.com/2008/11/fast-trim-function-for-javascript.html
|
||||||
|
* @param {Object} str
|
||||||
|
*/
|
||||||
|
function __trim__( str ){
|
||||||
|
return (str || "").replace( /^\s+|\s+$/g, "" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.DOM.Document').debug('available');
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface DocumentStyle (introduced in DOM Level 2)
|
||||||
|
* http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113/stylesheets.html#StyleSheets-StyleSheet-DocumentStyle
|
||||||
|
*
|
||||||
|
* interface DocumentStyle {
|
||||||
|
* readonly attribute StyleSheetList styleSheets;
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
__extend__(Document.prototype, {
|
||||||
|
get styleSheets() {
|
||||||
|
if (! this._styleSheets) {
|
||||||
|
this._styleSheets = new StyleSheetList();
|
||||||
|
}
|
||||||
|
return this._styleSheets;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}(/*Envjs.DOM.Document*/));
|
||||||
|
/*
|
||||||
|
* CSS2Properties - DOM Level 2 CSS
|
||||||
|
* Renamed to CSSStyleDeclaration??
|
||||||
|
*/
|
||||||
|
|
||||||
|
var __toCamelCase__ = function(name) {
|
||||||
|
if (name) {
|
||||||
|
return name.replace(/\-(\w)/g, function(all, letter) {
|
||||||
|
return letter.toUpperCase();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
};
|
||||||
|
|
||||||
|
var __toDashed__ = function(camelCaseName) {
|
||||||
|
if (camelCaseName) {
|
||||||
|
return camelCaseName.replace(/[A-Z]/g, function(all) {
|
||||||
|
return '-' + all.toLowerCase();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return camelCaseName;
|
||||||
|
};
|
||||||
|
|
||||||
|
var __cssTextToStyles__,
|
||||||
|
__supportedStyles__;
|
||||||
|
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.CSS.CSS2Properties').debug('available');
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.CSS2Properties = CSS2Properties = function(element){
|
||||||
|
//console.log('css2properties %s', __cssproperties__++);
|
||||||
|
this.styleIndex = __supportedStyles__;//non-standard
|
||||||
|
this.type = element.tagName;//non-standard
|
||||||
|
__setArray__(this, []);
|
||||||
|
__cssTextToStyles__(this, element.cssText || '');
|
||||||
|
};
|
||||||
|
__extend__(CSS2Properties.prototype, {
|
||||||
|
get cssText() {
|
||||||
|
var i, css = [];
|
||||||
|
for (i = 0; i < this.length; ++i) {
|
||||||
|
css.push(this[i] + ': ' + this.getPropertyValue(this[i]) + ';');
|
||||||
|
}
|
||||||
|
return css.join(' ');
|
||||||
|
},
|
||||||
|
set cssText(cssText) {
|
||||||
|
__cssTextToStyles__(this, cssText);
|
||||||
|
},
|
||||||
|
getPropertyCSSValue: function(name) {
|
||||||
|
//?
|
||||||
|
},
|
||||||
|
getPropertyPriority: function() {
|
||||||
|
|
||||||
|
},
|
||||||
|
getPropertyValue: function(name) {
|
||||||
|
var index, cname = __toCamelCase__(name);
|
||||||
|
if (cname in this.styleIndex) {
|
||||||
|
return this[cname];
|
||||||
|
} else {
|
||||||
|
index = Array.prototype.indexOf.apply(this, [name]);
|
||||||
|
if (index > -1) {
|
||||||
|
return this[index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
item: function(index) {
|
||||||
|
return this[index];
|
||||||
|
},
|
||||||
|
removeProperty: function(name) {
|
||||||
|
this.styleIndex[name] = null;
|
||||||
|
name = __toDashed__(name);
|
||||||
|
var index = Array.prototype.indexOf.apply(this, [name]);
|
||||||
|
if (index > -1) {
|
||||||
|
Array.prototype.splice.apply(this, [1,index]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setProperty: function(name, value, priority) {
|
||||||
|
var nval;
|
||||||
|
name = __toCamelCase__(name);
|
||||||
|
if (value !== undefined && name in this.styleIndex) {
|
||||||
|
// NOTE: parseFloat('300px') ==> 300 no
|
||||||
|
// NOTE: Number('300px') ==> Nan yes
|
||||||
|
nval = Number(value);
|
||||||
|
this.styleIndex[name] = isNaN(nval) ? value : nval;
|
||||||
|
name = __toDashed__(name);
|
||||||
|
if (Array.prototype.indexOf.apply(this, [name]) === -1 ){
|
||||||
|
Array.prototype.push.apply(this,[name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toString: function() {
|
||||||
|
return '[object CSS2Properties]';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
__cssTextToStyles__ = function(css2props, cssText) {
|
||||||
|
//console.log('__cssTextToStyles__ %s %s', css2props, cssText);
|
||||||
|
var i, style, styles = cssText.split(';');
|
||||||
|
for (i = 0; i < styles.length; ++i) {
|
||||||
|
style = styles[i].split(':');
|
||||||
|
if (style.length === 2) {
|
||||||
|
css2props.setProperty(
|
||||||
|
style[0].replace(' ', '', 'g'),
|
||||||
|
style[1].replace(' ', '', 'g')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//Obviously these arent all supported but by commenting out various
|
||||||
|
//sections this provides a single location to configure what is
|
||||||
|
//exposed as supported.
|
||||||
|
__supportedStyles__ = {
|
||||||
|
azimuth: null,
|
||||||
|
background: null,
|
||||||
|
backgroundAttachment: null,
|
||||||
|
backgroundColor: 'rgb(0,0,0)',
|
||||||
|
backgroundImage: null,
|
||||||
|
backgroundPosition: null,
|
||||||
|
backgroundRepeat: null,
|
||||||
|
border: null,
|
||||||
|
borderBottom: null,
|
||||||
|
borderBottomColor: null,
|
||||||
|
borderBottomStyle: null,
|
||||||
|
borderBottomWidth: null,
|
||||||
|
borderCollapse: null,
|
||||||
|
borderColor: null,
|
||||||
|
borderLeft: null,
|
||||||
|
borderLeftColor: null,
|
||||||
|
borderLeftStyle: null,
|
||||||
|
borderLeftWidth: null,
|
||||||
|
borderRight: null,
|
||||||
|
borderRightColor: null,
|
||||||
|
borderRightStyle: null,
|
||||||
|
borderRightWidth: null,
|
||||||
|
borderSpacing: null,
|
||||||
|
borderStyle: null,
|
||||||
|
borderTop: null,
|
||||||
|
borderTopColor: null,
|
||||||
|
borderTopStyle: null,
|
||||||
|
borderTopWidth: null,
|
||||||
|
borderWidth: null,
|
||||||
|
bottom: null,
|
||||||
|
captionSide: null,
|
||||||
|
clear: null,
|
||||||
|
clip: null,
|
||||||
|
color: null,
|
||||||
|
content: null,
|
||||||
|
counterIncrement: null,
|
||||||
|
counterReset: null,
|
||||||
|
cssFloat: null,
|
||||||
|
cue: null,
|
||||||
|
cueAfter: null,
|
||||||
|
cueBefore: null,
|
||||||
|
cursor: null,
|
||||||
|
direction: 'ltr',
|
||||||
|
display: null,
|
||||||
|
elevation: null,
|
||||||
|
emptyCells: null,
|
||||||
|
font: null,
|
||||||
|
fontFamily: null,
|
||||||
|
fontSize: '1em',
|
||||||
|
fontSizeAdjust: null,
|
||||||
|
fontStretch: null,
|
||||||
|
fontStyle: null,
|
||||||
|
fontVariant: null,
|
||||||
|
fontWeight: null,
|
||||||
|
height: '',
|
||||||
|
left: null,
|
||||||
|
letterSpacing: null,
|
||||||
|
lineHeight: null,
|
||||||
|
listStyle: null,
|
||||||
|
listStyleImage: null,
|
||||||
|
listStylePosition: null,
|
||||||
|
listStyleType: null,
|
||||||
|
margin: null,
|
||||||
|
marginBottom: '0px',
|
||||||
|
marginLeft: '0px',
|
||||||
|
marginRight: '0px',
|
||||||
|
marginTop: '0px',
|
||||||
|
markerOffset: null,
|
||||||
|
marks: null,
|
||||||
|
maxHeight: null,
|
||||||
|
maxWidth: null,
|
||||||
|
minHeight: null,
|
||||||
|
minWidth: null,
|
||||||
|
opacity: 1,
|
||||||
|
orphans: null,
|
||||||
|
outline: null,
|
||||||
|
outlineColor: null,
|
||||||
|
outlineOffset: null,
|
||||||
|
outlineStyle: null,
|
||||||
|
outlineWidth: null,
|
||||||
|
overflow: null,
|
||||||
|
overflowX: null,
|
||||||
|
overflowY: null,
|
||||||
|
padding: null,
|
||||||
|
paddingBottom: '0px',
|
||||||
|
paddingLeft: '0px',
|
||||||
|
paddingRight: '0px',
|
||||||
|
paddingTop: '0px',
|
||||||
|
page: null,
|
||||||
|
pageBreakAfter: null,
|
||||||
|
pageBreakBefore: null,
|
||||||
|
pageBreakInside: null,
|
||||||
|
pause: null,
|
||||||
|
pauseAfter: null,
|
||||||
|
pauseBefore: null,
|
||||||
|
pitch: null,
|
||||||
|
pitchRange: null,
|
||||||
|
position: null,
|
||||||
|
quotes: null,
|
||||||
|
richness: null,
|
||||||
|
right: null,
|
||||||
|
size: null,
|
||||||
|
speak: null,
|
||||||
|
speakHeader: null,
|
||||||
|
speakNumeral: null,
|
||||||
|
speakPunctuation: null,
|
||||||
|
speechRate: null,
|
||||||
|
stress: null,
|
||||||
|
tableLayout: null,
|
||||||
|
textAlign: null,
|
||||||
|
textDecoration: null,
|
||||||
|
textIndent: null,
|
||||||
|
textShadow: null,
|
||||||
|
textTransform: null,
|
||||||
|
top: null,
|
||||||
|
unicodeBidi: null,
|
||||||
|
verticalAlign: null,
|
||||||
|
visibility: '',
|
||||||
|
voiceFamily: null,
|
||||||
|
volume: null,
|
||||||
|
whiteSpace: null,
|
||||||
|
widows: null,
|
||||||
|
width: '1px',
|
||||||
|
wordSpacing: null,
|
||||||
|
zIndex: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
var __displayMap__ = {
|
||||||
|
DIV : 'block',
|
||||||
|
P : 'block',
|
||||||
|
A : 'inline',
|
||||||
|
CODE : 'inline',
|
||||||
|
PRE : 'block',
|
||||||
|
SPAN : 'inline',
|
||||||
|
TABLE : 'table',
|
||||||
|
THEAD : 'table-header-group',
|
||||||
|
TBODY : 'table-row-group',
|
||||||
|
TR : 'table-row',
|
||||||
|
TH : 'table-cell',
|
||||||
|
TD : 'table-cell',
|
||||||
|
UL : 'block',
|
||||||
|
LI : 'list-item'
|
||||||
|
};
|
||||||
|
|
||||||
|
var __addStyleAccessor__ = function(name){
|
||||||
|
if (name === 'width' || name === 'height') {
|
||||||
|
CSS2Properties.prototype.__defineGetter__(name, function() {
|
||||||
|
if (this.display === 'none'){
|
||||||
|
return '0px';
|
||||||
|
}
|
||||||
|
return this.styleIndex[name];
|
||||||
|
});
|
||||||
|
} else if (name === 'display') {
|
||||||
|
//display will be set to a tagName specific value if ''
|
||||||
|
CSS2Properties.prototype.__defineGetter__(name, function() {
|
||||||
|
var val = this.styleIndex[name];
|
||||||
|
val = val ? val :__displayMap__[this.type];
|
||||||
|
return val;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
CSS2Properties.prototype.__defineGetter__(name, function() {
|
||||||
|
return this.styleIndex[name];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
CSS2Properties.prototype.__defineSetter__(name, function(value) {
|
||||||
|
this.setProperty(name, value);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var style in __supportedStyles__) {
|
||||||
|
if (__supportedStyles__.hasOwnProperty(style)) {
|
||||||
|
__addStyleAccessor__(style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}(/*Envjs.CSS.CSS2Properties*/));
|
||||||
|
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.CSS.CSSRule').debug('available');
|
||||||
|
});
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CSSRule - DOM Level 2
|
||||||
|
*/
|
||||||
|
exports.CSSRule = CSSRule = function(options) {
|
||||||
|
|
||||||
|
var $style,
|
||||||
|
$selectorText = options.selectorText ? options.selectorText : '';
|
||||||
|
$style = new CSS2Properties({
|
||||||
|
cssText: options.cssText ? options.cssText : null
|
||||||
|
});
|
||||||
|
|
||||||
|
return __extend__(this, {
|
||||||
|
get style(){
|
||||||
|
return $style;
|
||||||
|
},
|
||||||
|
get selectorText(){
|
||||||
|
return $selectorText;
|
||||||
|
},
|
||||||
|
set selectorText(selectorText){
|
||||||
|
$selectorText = selectorText;
|
||||||
|
},
|
||||||
|
toString : function(){
|
||||||
|
return "[object CSSRule]";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
CSSRule.STYLE_RULE = 1;
|
||||||
|
CSSRule.IMPORT_RULE = 3;
|
||||||
|
CSSRule.MEDIA_RULE = 4;
|
||||||
|
CSSRule.FONT_FACE_RULE = 5;
|
||||||
|
CSSRule.PAGE_RULE = 6;
|
||||||
|
//CSSRule.NAMESPACE_RULE = 10;
|
||||||
|
|
||||||
|
|
||||||
|
CSSStyleRule = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
CSSImportRule = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
CSSMediaRule = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
CSSFontFaceRule = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
CSSPageRule = function() {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
CSSRuleList = function(data) {
|
||||||
|
this.length = 0;
|
||||||
|
__setArray__(this, data);
|
||||||
|
};
|
||||||
|
|
||||||
|
__extend__(CSSRuleList.prototype, {
|
||||||
|
item : function(index) {
|
||||||
|
if ((index >= 0) && (index < this.length)) {
|
||||||
|
// bounds check
|
||||||
|
return this[index];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
toString: function() {
|
||||||
|
return '[object CSSRuleList]';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}(/*Envjs.CSS.CSSRuleList*/));
|
||||||
|
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.CSS.CSSStyleSheet').debug('available');
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StyleSheet
|
||||||
|
* http://dev.w3.org/csswg/cssom/#stylesheet
|
||||||
|
*
|
||||||
|
* interface StyleSheet {
|
||||||
|
* readonly attribute DOMString type;
|
||||||
|
* readonly attribute DOMString href;
|
||||||
|
* readonly attribute Node ownerNode;
|
||||||
|
* readonly attribute StyleSheet parentStyleSheet;
|
||||||
|
* readonly attribute DOMString title;
|
||||||
|
* [PutForwards=mediaText] readonly attribute MediaList media;
|
||||||
|
* attribute boolean disabled;
|
||||||
|
* };
|
||||||
|
*/
|
||||||
|
StyleSheet = function() {};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CSSStyleSheet
|
||||||
|
* http://dev.w3.org/csswg/cssom/#cssstylesheet
|
||||||
|
*
|
||||||
|
* interface CSSStyleSheet : StyleSheet {
|
||||||
|
* readonly attribute CSSRule ownerRule;
|
||||||
|
* readonly attribute CSSRuleList cssRules;
|
||||||
|
* unsigned long insertRule(DOMString rule, unsigned long index);
|
||||||
|
* void deleteRule(unsigned long index);
|
||||||
|
* };
|
||||||
|
*/
|
||||||
|
exports.CSSStyleSheets = CSSStyleSheet = function(options){
|
||||||
|
var $cssRules,
|
||||||
|
$disabled = options.disabled ? options.disabled : false,
|
||||||
|
$href = options.href ? options.href : null,
|
||||||
|
$parentStyleSheet = options.parentStyleSheet ? options.parentStyleSheet : null,
|
||||||
|
$title = options.title ? options.title : "",
|
||||||
|
$type = "text/css";
|
||||||
|
|
||||||
|
function parseStyleSheet(text){
|
||||||
|
//$debug("parsing css");
|
||||||
|
//this is pretty ugly, but text is the entire text of a stylesheet
|
||||||
|
var cssRules = [];
|
||||||
|
if (!text) {
|
||||||
|
text = '';
|
||||||
|
}
|
||||||
|
text = __trim__(text.replace(/\/\*(\r|\n|.)*\*\//g,""));
|
||||||
|
// TODO: @import
|
||||||
|
var blocks = text.split("}");
|
||||||
|
blocks.pop();
|
||||||
|
var i, j, len = blocks.length;
|
||||||
|
var definition_block, properties, selectors;
|
||||||
|
for (i=0; i<len; i++) {
|
||||||
|
definition_block = blocks[i].split("{");
|
||||||
|
if (definition_block.length === 2) {
|
||||||
|
selectors = definition_block[0].split(",");
|
||||||
|
for (j=0; j<selectors.length; j++) {
|
||||||
|
cssRules.push(new CSSRule({
|
||||||
|
selectorText : __trim__(selectors[j]),
|
||||||
|
cssText : definition_block[1]
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cssRules;
|
||||||
|
}
|
||||||
|
|
||||||
|
$cssRules = new CSSRuleList(parseStyleSheet(options.textContent));
|
||||||
|
|
||||||
|
return __extend__(this, {
|
||||||
|
get cssRules(){
|
||||||
|
return $cssRules;
|
||||||
|
},
|
||||||
|
get rule(){
|
||||||
|
return $cssRules;
|
||||||
|
},//IE - may be deprecated
|
||||||
|
get href(){
|
||||||
|
return $href;
|
||||||
|
},
|
||||||
|
get parentStyleSheet(){
|
||||||
|
return $parentStyleSheet;
|
||||||
|
},
|
||||||
|
get title(){
|
||||||
|
return $title;
|
||||||
|
},
|
||||||
|
get type(){
|
||||||
|
return $type;
|
||||||
|
},
|
||||||
|
addRule: function(selector, style, index){/*TODO*/},
|
||||||
|
deleteRule: function(index){/*TODO*/},
|
||||||
|
insertRule: function(rule, index){/*TODO*/},
|
||||||
|
//IE - may be deprecated
|
||||||
|
removeRule: function(index){
|
||||||
|
this.deleteRule(index);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.StyleSheetList = StyleSheetList = function() {};
|
||||||
|
|
||||||
|
StyleSheetList.prototype = [];
|
||||||
|
|
||||||
|
__extend__(StyleSheetList.prototype, {
|
||||||
|
item : function(index) {
|
||||||
|
if ((index >= 0) && (index < this.length)) {
|
||||||
|
// bounds check
|
||||||
|
return this[index];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
toString: function() {
|
||||||
|
return '[object StyleSheetList]';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}(/*Envjs.CSS.CSSStyleSheet*/));
|
||||||
|
/**
|
||||||
|
* This extends HTMLElement to handle CSS-specific interfaces.
|
||||||
|
*
|
||||||
|
* More work / research would be needed to extend just (DOM) Element
|
||||||
|
* for xml use and additional changes for just HTMLElement.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.HTML.HTMLElement').debug('available');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace or add the getter for 'style'
|
||||||
|
*
|
||||||
|
* This could be wrapped in a closure
|
||||||
|
*/
|
||||||
|
var $css2properties = [{}];
|
||||||
|
|
||||||
|
__extend__(HTMLElement.prototype, {
|
||||||
|
get style(){
|
||||||
|
if ( !this.css2uuid ) {
|
||||||
|
this.css2uuid = $css2properties.length;
|
||||||
|
$css2properties[this.css2uuid] = new CSS2Properties(this);
|
||||||
|
}
|
||||||
|
return $css2properties[this.css2uuid];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Change for how 'setAttribute("style", ...)' works
|
||||||
|
*
|
||||||
|
* We are truly adding functionality to HtmlElement.setAttribute, not
|
||||||
|
* replacing it. So we need to save the old one first, call it, then
|
||||||
|
* do our stuff. If we need to do more hacks like this, HTMLElement
|
||||||
|
* (or regular Element) needs to have a hooks array or dispatch table
|
||||||
|
* for global changes.
|
||||||
|
*
|
||||||
|
* This could be wrapped in a closure if desired.
|
||||||
|
*/
|
||||||
|
var updateCss2Props = function(elem, values) {
|
||||||
|
//console.log('__updateCss2Props__ %s %s', elem, values);
|
||||||
|
if ( !elem.css2uuid ) {
|
||||||
|
elem.css2uuid = $css2properties.length;
|
||||||
|
$css2properties[elem.css2uuid] = new CSS2Properties(elem);
|
||||||
|
}
|
||||||
|
__cssTextToStyles__($css2properties[elem.css2uuid], values);
|
||||||
|
};
|
||||||
|
|
||||||
|
var origSetAttribute = HTMLElement.prototype.setAttribute;
|
||||||
|
|
||||||
|
HTMLElement.prototype.setAttribute = function(name, value) {
|
||||||
|
//console.log("CSS set attribute: " + name + ", " + value);
|
||||||
|
origSetAttribute.apply(this, arguments);
|
||||||
|
if (name === "style") {
|
||||||
|
updateCss2Props(this, value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var origGetAttribute = HTMLElement.prototype.getAttribute;
|
||||||
|
|
||||||
|
HTMLElement.prototype.getAttribute = function(name) {
|
||||||
|
//console.log("CSS set attribute: " + name + ", " + value);
|
||||||
|
var style;
|
||||||
|
if (name === "style") {
|
||||||
|
style = this.style.cssText;
|
||||||
|
return style===""?null:style;
|
||||||
|
}else{
|
||||||
|
return origGetAttribute.apply(this, arguments);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}(/*Envjs.HTML.HTMLElement*/));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author john resig & the envjs team
|
||||||
|
* @uri http://www.envjs.com/
|
||||||
|
* @copyright 2008-2010
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
//CLOSURE_END
|
||||||
|
}());
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,720 @@
|
||||||
|
/*
|
||||||
|
* Envjs event.1.3.pre03
|
||||||
|
* Pure JavaScript Browser Environment
|
||||||
|
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||||
|
* Copyright 2008-2010 John Resig, under the MIT License
|
||||||
|
*
|
||||||
|
* This file simply provides the global definitions we need to
|
||||||
|
* be able to correctly implement to core browser DOM Event interfaces.
|
||||||
|
|
||||||
|
- leaked globally -
|
||||||
|
|
||||||
|
var Event,
|
||||||
|
MouseEvent,
|
||||||
|
UIEvent,
|
||||||
|
KeyboardEvent,
|
||||||
|
MutationEvent,
|
||||||
|
DocumentEvent,
|
||||||
|
EventTarget,
|
||||||
|
EventException;
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Envjs = Envjs || require('./platform/core').Envjs,
|
||||||
|
After = After || require('./platform/core').After,
|
||||||
|
Document = Document || require('./dom').Document;
|
||||||
|
/*
|
||||||
|
* Envjs event.1.3.pre03
|
||||||
|
* Pure JavaScript Browser Environment
|
||||||
|
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||||
|
* Copyright 2008-2010 John Resig, under the MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
//CLOSURE_START
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author john resig
|
||||||
|
*/
|
||||||
|
// Helper method for extending one object with another.
|
||||||
|
function __extend__(a,b) {
|
||||||
|
for ( var i in b ) {
|
||||||
|
if(b.hasOwnProperty(i)){
|
||||||
|
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
|
||||||
|
if ( g || s ) {
|
||||||
|
if ( g ) { a.__defineGetter__(i, g); }
|
||||||
|
if ( s ) { a.__defineSetter__(i, s); }
|
||||||
|
} else {
|
||||||
|
a[i] = b[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author john resig
|
||||||
|
*/
|
||||||
|
//from jQuery
|
||||||
|
function __setArray__( target, array ) {
|
||||||
|
// Resetting the length to 0, then using the native Array push
|
||||||
|
// is a super-fast way to populate an object with array-like properties
|
||||||
|
target.length = 0;
|
||||||
|
Array.prototype.push.apply( target, array );
|
||||||
|
}
|
||||||
|
var __addEventListener__,
|
||||||
|
__removeEventListener__,
|
||||||
|
__dispatchEvent__,
|
||||||
|
__captureEvent__,
|
||||||
|
__bubbleEvent__;
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.DOM.EventTarget').debug('available');
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name EventTarget
|
||||||
|
* @w3c:domlevel 2
|
||||||
|
* @uri -//TODO: paste dom event level 2 w3c spc uri here
|
||||||
|
*/
|
||||||
|
exports.EventTarget = EventTarget = function(){};
|
||||||
|
EventTarget.prototype.addEventListener = function(type, fn, phase){
|
||||||
|
__addEventListener__(this, type, fn, phase);
|
||||||
|
};
|
||||||
|
EventTarget.prototype.removeEventListener = function(type, fn, phase){
|
||||||
|
__removeEventListener__(this, type, fn, phase);
|
||||||
|
};
|
||||||
|
EventTarget.prototype.dispatchEvent = function(event, bubbles){
|
||||||
|
__dispatchEvent__(this, event, bubbles);
|
||||||
|
};
|
||||||
|
|
||||||
|
__extend__(Node.prototype, EventTarget.prototype);
|
||||||
|
|
||||||
|
var $events = [{}];
|
||||||
|
|
||||||
|
__addEventListener__ = function(target, type, fn, phase){
|
||||||
|
phase = !!phase?"CAPTURING":"BUBBLING";
|
||||||
|
if ( !target.uuid ) {
|
||||||
|
target.uuid = $events.length+'';
|
||||||
|
log.debug('add event uuid for %s %s', target, target.uuid);
|
||||||
|
}
|
||||||
|
if ( !$events[target.uuid] ) {
|
||||||
|
log.debug('creating listener for target: %s %s', target, target.uuid);
|
||||||
|
$events[target.uuid] = {};
|
||||||
|
}
|
||||||
|
if ( !$events[target.uuid][type] ){
|
||||||
|
log.debug('creating listener for type: %s %s %s', target, target.uuid, type);
|
||||||
|
$events[target.uuid][type] = {
|
||||||
|
CAPTURING:[],
|
||||||
|
BUBBLING:[]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if ( $events[target.uuid][type][phase].indexOf( fn ) < 0 ){
|
||||||
|
log.debug( 'adding event listener %s %s %s %s', target, target.uuid, type, phase);
|
||||||
|
$events[target.uuid][type][phase].push( fn );
|
||||||
|
}
|
||||||
|
log.debug('registered event listeners %s', $events.length);
|
||||||
|
};
|
||||||
|
|
||||||
|
__removeEventListener__ = function(target, type, fn, phase){
|
||||||
|
phase = !!phase?"CAPTURING":"BUBBLING";
|
||||||
|
if ( !target.uuid ) {
|
||||||
|
log.debug('target has never had registered events %s', target);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ( !$events[target.uuid] ) {
|
||||||
|
log.debug('target has no registered events to remove %s %s', target, target.uuid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(type == '*'){
|
||||||
|
//used to clean all event listeners for a given node
|
||||||
|
log.debug('cleaning all event listeners for node %s %s',target, target.uuid);
|
||||||
|
delete $events[target.uuid];
|
||||||
|
return;
|
||||||
|
}else if ( !$events[target.uuid][type] ){
|
||||||
|
log.debug('target has no registered events of type %s to remove %s %s', type, target, target.uuid);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$events[target.uuid][type][phase] =
|
||||||
|
$events[target.uuid][type][phase].filter(function(f){
|
||||||
|
log.debug('removing event listener %s %s %s %s', target, type, phase );
|
||||||
|
return f != fn;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var __eventuuid__ = 0;
|
||||||
|
|
||||||
|
__dispatchEvent__ = function(target, event, bubbles){
|
||||||
|
|
||||||
|
if (!event.uuid) {
|
||||||
|
event.uuid = __eventuuid__++;
|
||||||
|
}
|
||||||
|
//the window scope defines the $event object, for IE(^^^) compatibility;
|
||||||
|
//$event = event;
|
||||||
|
|
||||||
|
if (bubbles === undefined || bubbles === null) {
|
||||||
|
bubbles = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!event.target) {
|
||||||
|
event.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug('dispatching %s %s %s %s', event.uuid, target, event.type, bubbles);
|
||||||
|
if ( event.type && (target.nodeType || target === window )) {
|
||||||
|
|
||||||
|
__captureEvent__(target, event);
|
||||||
|
|
||||||
|
event.eventPhase = Event.AT_TARGET;
|
||||||
|
if ( target.uuid && $events[target.uuid] && $events[target.uuid][event.type] ) {
|
||||||
|
event.currentTarget = target;
|
||||||
|
|
||||||
|
log.debug('begin dispatching capturing phase %s %s', target, event.type);
|
||||||
|
$events[target.uuid][event.type].CAPTURING.forEach(function(fn){
|
||||||
|
log.debug('capturing event %s', target);
|
||||||
|
var returnValue = fn.apply(target, [event]);
|
||||||
|
if(returnValue === false){
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
log.debug('begin dispatching bubbling phase %s %s', target, event.type);
|
||||||
|
$events[target.uuid][event.type].BUBBLING.forEach(function(fn){
|
||||||
|
log.debug('bubbling event %s', target);
|
||||||
|
var returnValue = fn.apply(target, [event] );
|
||||||
|
if(returnValue === false){
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (target["on" + event.type]) {
|
||||||
|
target["on" + event.type](event);
|
||||||
|
}
|
||||||
|
if (bubbles && !event.cancelled){
|
||||||
|
__bubbleEvent__(target, event);
|
||||||
|
}
|
||||||
|
if(!event._preventDefault){
|
||||||
|
//At this point I'm guessing that just HTMLEvents are concerned
|
||||||
|
//with default behavior being executed in a browser but I could be
|
||||||
|
//wrong as usual. The goal is much more to filter at this point
|
||||||
|
//what events have no need to be handled
|
||||||
|
//console.log('triggering default behavior for %s', event.type);
|
||||||
|
if(event.type in Envjs.defaultEventBehaviors){
|
||||||
|
Envjs.defaultEventBehaviors[event.type](event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log.debug('deleting event %s', event.uuid);
|
||||||
|
event.target = null;
|
||||||
|
event = null;
|
||||||
|
}else{
|
||||||
|
throw new EventException(EventException.UNSPECIFIED_EVENT_TYPE_ERR);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
__captureEvent__ = function(target, event){
|
||||||
|
var ancestorStack = [],
|
||||||
|
parent = target.parentNode,
|
||||||
|
stopevent = function(fn){
|
||||||
|
var returnValue = fn( event );
|
||||||
|
if(returnValue === false){
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
event.eventPhase = Event.CAPTURING_PHASE;
|
||||||
|
while(parent){
|
||||||
|
if(parent.uuid && $events[parent.uuid] && $events[parent.uuid][event.type]){
|
||||||
|
ancestorStack.push(parent);
|
||||||
|
}
|
||||||
|
parent = parent.parentNode;
|
||||||
|
}
|
||||||
|
while(ancestorStack.length && !event.cancelled){
|
||||||
|
event.currentTarget = ancestorStack.pop();
|
||||||
|
if($events[event.currentTarget.uuid] && $events[event.currentTarget.uuid][event.type]){
|
||||||
|
$events[event.currentTarget.uuid][event.type].CAPTURING.forEach(stopevent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
__bubbleEvent__ = function(target, event){
|
||||||
|
var parent = target.parentNode,
|
||||||
|
stopevent = function(fn){
|
||||||
|
var returnValue = fn( event );
|
||||||
|
if(returnValue === false){
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
event.eventPhase = Event.BUBBLING_PHASE;
|
||||||
|
while(parent){
|
||||||
|
if(parent.uuid && $events[parent.uuid] && $events[parent.uuid][event.type] ){
|
||||||
|
event.currentTarget = parent;
|
||||||
|
$events[event.currentTarget.uuid][event.type].BUBBLING.forEach(stopevent);
|
||||||
|
}
|
||||||
|
parent = parent.parentNode;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}(/*Envjs.DOM2.EventTarget*/));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.DOM.Event').debug('available');
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class Event
|
||||||
|
*/
|
||||||
|
exports.Event = Event = function(options){
|
||||||
|
// event state is kept read-only by forcing
|
||||||
|
// a new object for each event. This may not
|
||||||
|
// be appropriate in the long run and we'll
|
||||||
|
// have to decide if we simply dont adhere to
|
||||||
|
// the read-only restriction of the specification
|
||||||
|
this._bubbles = true;
|
||||||
|
this._cancelable = true;
|
||||||
|
this._cancelled = false;
|
||||||
|
this._currentTarget = null;
|
||||||
|
this._target = null;
|
||||||
|
this._eventPhase = Event.AT_TARGET;
|
||||||
|
this._timeStamp = new Date().getTime();
|
||||||
|
this._preventDefault = false;
|
||||||
|
this._stopPropogation = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
__extend__(Event.prototype,{
|
||||||
|
get bubbles(){return this._bubbles;},
|
||||||
|
get cancelable(){return this._cancelable;},
|
||||||
|
get currentTarget(){return this._currentTarget;},
|
||||||
|
set currentTarget(currentTarget){ this._currentTarget = currentTarget; },
|
||||||
|
get eventPhase(){return this._eventPhase;},
|
||||||
|
set eventPhase(eventPhase){this._eventPhase = eventPhase;},
|
||||||
|
get target(){return this._target;},
|
||||||
|
set target(target){ this._target = target;},
|
||||||
|
get timeStamp(){return this._timeStamp;},
|
||||||
|
get type(){return this._type;},
|
||||||
|
initEvent: function(type, bubbles, cancelable){
|
||||||
|
this._type=type?type:'';
|
||||||
|
this._bubbles=!!bubbles;
|
||||||
|
this._cancelable=!!cancelable;
|
||||||
|
},
|
||||||
|
preventDefault: function(){
|
||||||
|
this._preventDefault = true;
|
||||||
|
},
|
||||||
|
stopPropagation: function(){
|
||||||
|
if(this._cancelable){
|
||||||
|
this._cancelled = true;
|
||||||
|
this._bubbles = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get cancelled(){
|
||||||
|
return this._cancelled;
|
||||||
|
},
|
||||||
|
toString: function(){
|
||||||
|
return '[object Event]';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
__extend__(Event,{
|
||||||
|
CAPTURING_PHASE : 1,
|
||||||
|
AT_TARGET : 2,
|
||||||
|
BUBBLING_PHASE : 3
|
||||||
|
});
|
||||||
|
|
||||||
|
}(/*Envjs.DOM.Event*/));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.DOM.UIEvent').debug('available');
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name UIEvent
|
||||||
|
* @param {Object} options
|
||||||
|
*/
|
||||||
|
exports.UIEvent = UIEvent = function(options) {
|
||||||
|
this._view = null;
|
||||||
|
this._detail = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
UIEvent.prototype = new Event();
|
||||||
|
__extend__(UIEvent.prototype,{
|
||||||
|
get view(){
|
||||||
|
return this._view;
|
||||||
|
},
|
||||||
|
get detail(){
|
||||||
|
return this._detail;
|
||||||
|
},
|
||||||
|
initUIEvent: function(type, bubbles, cancelable, windowObject, detail){
|
||||||
|
this.initEvent(type, bubbles, cancelable);
|
||||||
|
this._detail = 0;
|
||||||
|
this._view = windowObject;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}(/*Envjs.DOM.UIEvent*/));
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.DOM.MouseEvent').debug('available');
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name MouseEvent
|
||||||
|
* @w3c:domlevel 2
|
||||||
|
* @uri http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html
|
||||||
|
*/
|
||||||
|
exports.MouseEvent = MouseEvent = function(options) {
|
||||||
|
this._screenX= 0;
|
||||||
|
this._screenY= 0;
|
||||||
|
this._clientX= 0;
|
||||||
|
this._clientY= 0;
|
||||||
|
this._ctrlKey= false;
|
||||||
|
this._metaKey= false;
|
||||||
|
this._altKey= false;
|
||||||
|
this._button= null;
|
||||||
|
this._relatedTarget= null;
|
||||||
|
};
|
||||||
|
MouseEvent.prototype = new UIEvent();
|
||||||
|
__extend__(MouseEvent.prototype,{
|
||||||
|
get screenX(){
|
||||||
|
return this._screenX;
|
||||||
|
},
|
||||||
|
get screenY(){
|
||||||
|
return this._screenY;
|
||||||
|
},
|
||||||
|
get clientX(){
|
||||||
|
return this._clientX;
|
||||||
|
},
|
||||||
|
get clientY(){
|
||||||
|
return this._clientY;
|
||||||
|
},
|
||||||
|
get ctrlKey(){
|
||||||
|
return this._ctrlKey;
|
||||||
|
},
|
||||||
|
get altKey(){
|
||||||
|
return this._altKey;
|
||||||
|
},
|
||||||
|
get shiftKey(){
|
||||||
|
return this._shiftKey;
|
||||||
|
},
|
||||||
|
get metaKey(){
|
||||||
|
return this._metaKey;
|
||||||
|
},
|
||||||
|
get button(){
|
||||||
|
return this._button;
|
||||||
|
},
|
||||||
|
get relatedTarget(){
|
||||||
|
return this._relatedTarget;
|
||||||
|
},
|
||||||
|
initMouseEvent: function(type, bubbles, cancelable, windowObject, detail,
|
||||||
|
screenX, screenY, clientX, clientY, ctrlKey, altKey, shiftKey,
|
||||||
|
metaKey, button, relatedTarget){
|
||||||
|
this.initUIEvent(type, bubbles, cancelable, windowObject, detail);
|
||||||
|
this._screenX = screenX;
|
||||||
|
this._screenY = screenY;
|
||||||
|
this._clientX = clientX;
|
||||||
|
this._clientY = clientY;
|
||||||
|
this._ctrlKey = ctrlKey;
|
||||||
|
this._altKey = altKey;
|
||||||
|
this._shiftKey = shiftKey;
|
||||||
|
this._metaKey = metaKey;
|
||||||
|
this._button = button;
|
||||||
|
this._relatedTarget = relatedTarget;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}(/*Envjs.DOM2.MouseEvent*/));
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.DOM.KeyboardEvent').
|
||||||
|
debug('KeyboardEvent available');
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface KeyboardEvent (introduced in DOM Level 3)
|
||||||
|
*/
|
||||||
|
exports.KeyboardEvent = KeyboardEvent = function(options) {
|
||||||
|
this._keyIdentifier = 0;
|
||||||
|
this._keyLocation = 0;
|
||||||
|
this._ctrlKey = false;
|
||||||
|
this._metaKey = false;
|
||||||
|
this._altKey = false;
|
||||||
|
this._metaKey = false;
|
||||||
|
};
|
||||||
|
KeyboardEvent.prototype = new UIEvent();
|
||||||
|
|
||||||
|
__extend__(KeyboardEvent.prototype,{
|
||||||
|
|
||||||
|
get ctrlKey(){
|
||||||
|
return this._ctrlKey;
|
||||||
|
},
|
||||||
|
get altKey(){
|
||||||
|
return this._altKey;
|
||||||
|
},
|
||||||
|
get shiftKey(){
|
||||||
|
return this._shiftKey;
|
||||||
|
},
|
||||||
|
get metaKey(){
|
||||||
|
return this._metaKey;
|
||||||
|
},
|
||||||
|
get button(){
|
||||||
|
return this._button;
|
||||||
|
},
|
||||||
|
get relatedTarget(){
|
||||||
|
return this._relatedTarget;
|
||||||
|
},
|
||||||
|
getModifiersState: function(keyIdentifier){
|
||||||
|
|
||||||
|
},
|
||||||
|
initMouseEvent: function(type, bubbles, cancelable, windowObject,
|
||||||
|
keyIdentifier, keyLocation, modifiersList, repeat){
|
||||||
|
this.initUIEvent(type, bubbles, cancelable, windowObject, 0);
|
||||||
|
this._keyIdentifier = keyIdentifier;
|
||||||
|
this._keyLocation = keyLocation;
|
||||||
|
this._modifiersList = modifiersList;
|
||||||
|
this._repeat = repeat;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
KeyboardEvent.DOM_KEY_LOCATION_STANDARD = 0;
|
||||||
|
KeyboardEvent.DOM_KEY_LOCATION_LEFT = 1;
|
||||||
|
KeyboardEvent.DOM_KEY_LOCATION_RIGHT = 2;
|
||||||
|
KeyboardEvent.DOM_KEY_LOCATION_NUMPAD = 3;
|
||||||
|
KeyboardEvent.DOM_KEY_LOCATION_MOBILE = 4;
|
||||||
|
KeyboardEvent.DOM_KEY_LOCATION_JOYSTICK = 5;
|
||||||
|
|
||||||
|
}(/*Envjs.DOM3.KeyboardEvent*/));
|
||||||
|
|
||||||
|
|
||||||
|
//We dont fire mutation events until someone has registered for them
|
||||||
|
var __supportedMutations__ = /DOMSubtreeModified|DOMNodeInserted|DOMNodeRemoved|DOMAttrModified|DOMCharacterDataModified/;
|
||||||
|
|
||||||
|
var __fireMutationEvents__ = Aspect.before({
|
||||||
|
target: EventTarget,
|
||||||
|
method: 'addEventListener'
|
||||||
|
}, function(target, type){
|
||||||
|
if(type && type.match(__supportedMutations__)){
|
||||||
|
//unweaving removes the __addEventListener__ aspect
|
||||||
|
__fireMutationEvents__.unweave();
|
||||||
|
// These two methods are enough to cover all dom 2 manipulations
|
||||||
|
Aspect.around({
|
||||||
|
target: Node,
|
||||||
|
method:"removeChild"
|
||||||
|
}, function(invocation){
|
||||||
|
var event,
|
||||||
|
node = invocation['arguments'][0];
|
||||||
|
event = node.ownerDocument.createEvent('MutationEvents');
|
||||||
|
event.initEvent('DOMNodeRemoved', true, false, node.parentNode, null, null, null, null);
|
||||||
|
node.dispatchEvent(event, false);
|
||||||
|
return invocation.proceed();
|
||||||
|
|
||||||
|
});
|
||||||
|
Aspect.around({
|
||||||
|
target: Node,
|
||||||
|
method:"appendChild"
|
||||||
|
}, function(invocation) {
|
||||||
|
var event,
|
||||||
|
node = invocation.proceed();
|
||||||
|
event = node.ownerDocument.createEvent('MutationEvents');
|
||||||
|
event.initEvent('DOMNodeInserted', true, false, node.parentNode, null, null, null, null);
|
||||||
|
node.dispatchEvent(event, false);
|
||||||
|
return node;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.DOM.MutationEvent').debug('available');
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name MutationEvent
|
||||||
|
* @param {Object} options
|
||||||
|
*/
|
||||||
|
exports.MutationEvent = MutationEvent = function(options) {
|
||||||
|
this._cancelable = false;
|
||||||
|
this._timeStamp = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
MutationEvent.prototype = new Event();
|
||||||
|
__extend__(MutationEvent.prototype,{
|
||||||
|
get relatedNode(){
|
||||||
|
return this._relatedNode;
|
||||||
|
},
|
||||||
|
get prevValue(){
|
||||||
|
return this._prevValue;
|
||||||
|
},
|
||||||
|
get newValue(){
|
||||||
|
return this._newValue;
|
||||||
|
},
|
||||||
|
get attrName(){
|
||||||
|
return this._attrName;
|
||||||
|
},
|
||||||
|
get attrChange(){
|
||||||
|
return this._attrChange;
|
||||||
|
},
|
||||||
|
initMutationEvent: function( type, bubbles, cancelable,
|
||||||
|
relatedNode, prevValue, newValue, attrName, attrChange ){
|
||||||
|
this._relatedNode = relatedNode;
|
||||||
|
this._prevValue = prevValue;
|
||||||
|
this._newValue = newValue;
|
||||||
|
this._attrName = attrName;
|
||||||
|
this._attrChange = attrChange;
|
||||||
|
switch(type){
|
||||||
|
case "DOMSubtreeModified":
|
||||||
|
this.initEvent(type, true, false);
|
||||||
|
break;
|
||||||
|
case "DOMNodeInserted":
|
||||||
|
this.initEvent(type, true, false);
|
||||||
|
break;
|
||||||
|
case "DOMNodeRemoved":
|
||||||
|
this.initEvent(type, true, false);
|
||||||
|
break;
|
||||||
|
case "DOMNodeRemovedFromDocument":
|
||||||
|
this.initEvent(type, false, false);
|
||||||
|
break;
|
||||||
|
case "DOMNodeInsertedIntoDocument":
|
||||||
|
this.initEvent(type, false, false);
|
||||||
|
break;
|
||||||
|
case "DOMAttrModified":
|
||||||
|
this.initEvent(type, true, false);
|
||||||
|
break;
|
||||||
|
case "DOMCharacterDataModified":
|
||||||
|
this.initEvent(type, true, false);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.initEvent(type, bubbles, cancelable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// constants
|
||||||
|
MutationEvent.ADDITION = 0;
|
||||||
|
MutationEvent.MODIFICATION = 1;
|
||||||
|
MutationEvent.REMOVAL = 2;
|
||||||
|
|
||||||
|
}(/*Envjs.DOM.MutationEvent*/));
|
||||||
|
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.DOM.EventException').debug('available');
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name EventException
|
||||||
|
*/
|
||||||
|
exports.EventException = EventException = function(code) {
|
||||||
|
this.code = code;
|
||||||
|
};
|
||||||
|
EventException.UNSPECIFIED_EVENT_TYPE_ERR = 0;
|
||||||
|
|
||||||
|
}(/*Envjs.DOM2.EventException*/));
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* DOM Level 2: http://www.w3.org/TR/DOM-Level-2-Events/events.html
|
||||||
|
* DOM Level 3: http://www.w3.org/TR/DOM-Level-3-Events/
|
||||||
|
*
|
||||||
|
* interface DocumentEvent {
|
||||||
|
* Event createEvent (in DOMString eventType)
|
||||||
|
* raises (DOMException);
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* Firefox (3.6) exposes DocumentEvent
|
||||||
|
* Safari (4) does NOT.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.DOM.DocumentEvent').debug('available');
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Not sure we need a full prototype. We not just an regular object?
|
||||||
|
*/
|
||||||
|
exports.DocumentEvent = DocumentEvent = function(){};
|
||||||
|
DocumentEvent.prototype.__EventMap__ = {
|
||||||
|
// Safari4: singular and plural forms accepted
|
||||||
|
// Firefox3.6: singular and plural forms accepted
|
||||||
|
'Event' : Event,
|
||||||
|
'Events' : Event,
|
||||||
|
'UIEvent' : UIEvent,
|
||||||
|
'UIEvents' : UIEvent,
|
||||||
|
'MouseEvent' : MouseEvent,
|
||||||
|
'MouseEvents' : MouseEvent,
|
||||||
|
'MutationEvent' : MutationEvent,
|
||||||
|
'MutationEvents' : MutationEvent,
|
||||||
|
|
||||||
|
// Safari4: accepts HTMLEvents, but not HTMLEvent
|
||||||
|
// Firefox3.6: accepts HTMLEvents, but not HTMLEvent
|
||||||
|
'HTMLEvent' : Event,
|
||||||
|
'HTMLEvents' : Event,
|
||||||
|
|
||||||
|
// Safari4: both not accepted
|
||||||
|
// Firefox3.6, only KeyEvents is accepted
|
||||||
|
'KeyEvent' : KeyboardEvent,
|
||||||
|
'KeyEvents' : KeyboardEvent,
|
||||||
|
|
||||||
|
// Safari4: both accepted
|
||||||
|
// Firefox3.6: none accepted
|
||||||
|
'KeyboardEvent' : KeyboardEvent,
|
||||||
|
'KeyboardEvents' : KeyboardEvent
|
||||||
|
};
|
||||||
|
|
||||||
|
DocumentEvent.prototype.createEvent = function(eventType) {
|
||||||
|
var Clazz = this.__EventMap__[eventType];
|
||||||
|
if (Clazz) {
|
||||||
|
return new Clazz();
|
||||||
|
}
|
||||||
|
throw(new DOMException(DOMException.NOT_SUPPORTED_ERR));
|
||||||
|
};
|
||||||
|
|
||||||
|
__extend__(Document.prototype, DocumentEvent.prototype);
|
||||||
|
|
||||||
|
|
||||||
|
}(/*Envjs.DOM.DocumentEvent*/));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author john resig & the envjs team
|
||||||
|
* @uri http://www.envjs.com/
|
||||||
|
* @copyright 2008-2010
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
//CLOSURE_END
|
||||||
|
}());
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,66 @@
|
||||||
|
// This file must be executed automatically on startup for ruby/v8 rubyracer support.
|
||||||
|
var __this__ = this;
|
||||||
|
|
||||||
|
var require = (function() {
|
||||||
|
var cached = {};
|
||||||
|
var currentPath = Ruby.ENV['PWD'];
|
||||||
|
var paths = [currentPath];
|
||||||
|
|
||||||
|
function normalize(id) {
|
||||||
|
var file;
|
||||||
|
id = id + '.js';
|
||||||
|
if (/^\.\.?/.test(id)) {
|
||||||
|
// relative path
|
||||||
|
try{ return Ruby.File.open(id, 'r') }catch(e){}
|
||||||
|
} else {
|
||||||
|
for (var i = 0, len = paths.length; i < len; ++i) {
|
||||||
|
try{ return Ruby.File.open(paths[i]+'/'+id, 'r') }catch(e){}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function require(id) {
|
||||||
|
//print('require :'+ id);
|
||||||
|
var file = normalize(id);
|
||||||
|
if (!file) {
|
||||||
|
throw new Error("couldn't find module \"" + id + "\"");
|
||||||
|
}
|
||||||
|
if (!cached.hasOwnProperty(id)) {
|
||||||
|
//print('loading '+id);
|
||||||
|
var source = file.read();
|
||||||
|
source = source.replace(/^\#\!.*/, '');
|
||||||
|
source = "(function (require, exports, module) { "+source+"\n});";
|
||||||
|
cached[id] = {
|
||||||
|
exports: {},
|
||||||
|
module: {
|
||||||
|
id: id,
|
||||||
|
uri: id
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var previousPath = currentPath;
|
||||||
|
try {
|
||||||
|
currentPath = id.substr(0, id.lastIndexOf('/')) || '.';
|
||||||
|
var func = global.evaluate( source, id );
|
||||||
|
func(require, cached[id].exports, cached[id].module);
|
||||||
|
} finally {
|
||||||
|
currentPath = previousPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
print('returning exports for id: '+id+' '+cached[id].exports);
|
||||||
|
for(var prop in cached[id].exports){
|
||||||
|
print('export: '+prop);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return cached[id].exports;
|
||||||
|
};
|
||||||
|
|
||||||
|
require.paths = paths;
|
||||||
|
|
||||||
|
return require;
|
||||||
|
})();
|
||||||
|
|
||||||
|
require('./platform/johnson');
|
||||||
|
require('./window');
|
|
@ -0,0 +1,31 @@
|
||||||
|
require 'johnson'
|
||||||
|
require 'net/http'
|
||||||
|
require 'uri'
|
||||||
|
require 'thread'
|
||||||
|
|
||||||
|
include Config
|
||||||
|
|
||||||
|
def configure_context(context)
|
||||||
|
context['global'] = context
|
||||||
|
context['HTTPConnection'] = HTTPConnection.new
|
||||||
|
end
|
||||||
|
|
||||||
|
class HTTPConnection
|
||||||
|
def go(connection, request, headers, data)
|
||||||
|
headers.each{|key,value| request.add_field(key,value)}
|
||||||
|
response, body = connection.request(request, data)
|
||||||
|
respheaders = Hash.new
|
||||||
|
response.each_header do |name, value|
|
||||||
|
respheaders.store(name, value)
|
||||||
|
end
|
||||||
|
response['body'] = body
|
||||||
|
[response, respheaders]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
global = Johnson::Runtime.new
|
||||||
|
configure_context(global)
|
||||||
|
envjs = ARGV[0]
|
||||||
|
global.load(envjs)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
require('./platform/node');
|
||||||
|
Envjs.eventLoop = function() {}; // disabled for clean shutdown
|
||||||
|
|
||||||
|
require('./window');
|
||||||
|
new Window(__this__); // initialize a blank window
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,363 @@
|
||||||
|
var __context__ = __this__;
|
||||||
|
|
||||||
|
var Envjs = Envjs ||
|
||||||
|
require('./core').Envjs;
|
||||||
|
require('local_settings');
|
||||||
|
|
||||||
|
Envjs.platform = "Johnson SpiderMonkey";
|
||||||
|
Envjs.revision = Ruby.CONFIG.ruby_version;
|
||||||
|
|
||||||
|
Ruby.ARGV.shift();
|
||||||
|
Envjs.argv = Ruby.ARGV;
|
||||||
|
|
||||||
|
Envjs.exit = function(){ Ruby['exit!'](); };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Envjs johnson-env.1.3.pre03
|
||||||
|
* Pure JavaScript Browser Environment
|
||||||
|
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||||
|
* Copyright 2008-2010 John Resig, under the MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
//CLOSURE_START
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author john resig
|
||||||
|
*/
|
||||||
|
// Helper method for extending one object with another.
|
||||||
|
function __extend__(a,b) {
|
||||||
|
for ( var i in b ) {
|
||||||
|
if(b.hasOwnProperty(i)){
|
||||||
|
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
|
||||||
|
if ( g || s ) {
|
||||||
|
if ( g ) { a.__defineGetter__(i, g); }
|
||||||
|
if ( s ) { a.__defineSetter__(i, s); }
|
||||||
|
} else {
|
||||||
|
a[i] = b[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
Envjs.log = function(msg){
|
||||||
|
Ruby.puts(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
Envjs.lineSource = function(e){
|
||||||
|
return "(line ?)";
|
||||||
|
};
|
||||||
|
|
||||||
|
Envjs.readConsole = function(){
|
||||||
|
return Ruby.$stdin.gets();
|
||||||
|
};
|
||||||
|
|
||||||
|
Envjs.prompt = function(){
|
||||||
|
Ruby.$stdout.write(Envjs.CURSOR+' ');
|
||||||
|
Ruby.$stdout.flush;
|
||||||
|
};
|
||||||
|
|
||||||
|
//No REPL for
|
||||||
|
Envjs.repl = function(){
|
||||||
|
console.log('Envjs REPL Not Available');
|
||||||
|
};
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger('Envjs.Platform.Johnson');
|
||||||
|
|
||||||
|
Envjs.eval = function(context, source, name){
|
||||||
|
if(context == __this__){
|
||||||
|
return global.evaluate( source, name );
|
||||||
|
}else{
|
||||||
|
var abc = new Ruby.Johnson.Runtime()
|
||||||
|
log.debug('evaluating in framed context %s %s', context, abc);
|
||||||
|
return context.evaluate( source, name );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
|
/**
|
||||||
|
* synchronizes thread modifications
|
||||||
|
* @param {Function} fn
|
||||||
|
*/
|
||||||
|
var lock = new Ruby.Mutex();
|
||||||
|
|
||||||
|
//NOTES:
|
||||||
|
//context['sync'] = lambda{|wrapper|
|
||||||
|
// Proc.new{|*args|lock.synchronize {wrapper['fn'].call(*args)}}
|
||||||
|
//}
|
||||||
|
//context['sync'] = lambda{|fn| Proc.new{|*args| fn.call(*args) }}
|
||||||
|
Envjs.sync = function(fn){
|
||||||
|
//console.log('syncing js fn %s', fn);
|
||||||
|
var wrapper = {fn:fn};
|
||||||
|
//return lock.synchronize(fn)
|
||||||
|
return fn;
|
||||||
|
};
|
||||||
|
|
||||||
|
//NOTES:
|
||||||
|
//context['spawn'] = lambda{|wrapper| Thread.new {wrapper['fn'].call} }
|
||||||
|
//context['spawn'] = lambda{|wrapper| wrapper['fn'].call }
|
||||||
|
Envjs.spawn = function(fn){
|
||||||
|
//console.log('spawning js fn %s', fn);
|
||||||
|
var wrapper = {fn:fn};
|
||||||
|
return fn();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sleep thread for specified duration
|
||||||
|
* @param {Object} milliseconds
|
||||||
|
*/
|
||||||
|
Envjs.sleep = function(milliseconds){
|
||||||
|
return Ruby.sleep(1.0*milliseconds/1000.0);
|
||||||
|
};
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger('Envjs.Platform.Johnson');
|
||||||
|
|
||||||
|
//Since we're running in spydermonkey I guess we can safely assume
|
||||||
|
//java is not 'enabled'. I'm sure this requires more thought
|
||||||
|
//than I've given it here
|
||||||
|
Envjs.javaEnabled = false;
|
||||||
|
|
||||||
|
Envjs.homedir = Ruby.ENV.HOME
|
||||||
|
Envjs.tmpdir = Ruby.ENV.TMPDIR;
|
||||||
|
Envjs.os_name = Ruby.CONFIG.host_os;
|
||||||
|
Envjs.os_arch = Ruby.CONFIG.host_cpu;
|
||||||
|
Envjs.os_version = "";//part of os_arch
|
||||||
|
Envjs.lang = Ruby.ENV.LANG;
|
||||||
|
|
||||||
|
Envjs.gc = function(){ Ruby.Johnson.Runtime.gc(); };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes an object window-like by proxying object accessors
|
||||||
|
* @param {Object} scope
|
||||||
|
* @param {Object} parent
|
||||||
|
*/
|
||||||
|
Envjs.proxy = function(scope, parent) {
|
||||||
|
try{
|
||||||
|
if(scope == __this__){
|
||||||
|
return scope;
|
||||||
|
}else{
|
||||||
|
return new Ruby.Johnson.Runtime();
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
console.log('failed to init standard objects %s %s \n%s', scope, parent, e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
})();(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger('Envjs.XMLHttpRequest.Johnson');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get 'Current Working Directory'
|
||||||
|
*/
|
||||||
|
Envjs.getcwd = function() {
|
||||||
|
return Ruby.ENV['PWD'];
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to read the contents of a local file
|
||||||
|
* @param {Object} url
|
||||||
|
*/
|
||||||
|
Envjs.readFromFile = function( url ){
|
||||||
|
if(/^file\:\/\//.test(url))
|
||||||
|
url = url.substring(7,url.length);
|
||||||
|
log.debug('reading file %s', url);
|
||||||
|
var file = Ruby.File.open(url, 'r'),
|
||||||
|
data = file.read();
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Envjs.writeToFile = function(text, url){
|
||||||
|
var file = Ruby.File.open(url, 'w');
|
||||||
|
log.debug('writing to file %s', url);
|
||||||
|
file.write(text);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to write to a local file
|
||||||
|
* @param {Object} text
|
||||||
|
* @param {Object} suffix
|
||||||
|
*/
|
||||||
|
Envjs.writeToTempFile = function(text, suffix){
|
||||||
|
// Create temp file.
|
||||||
|
var temp = Envjs.tmpdir+"."+(new Date().getTime())+(suffix||'.js');
|
||||||
|
log.debug("writing text to temp url : %s ", temp);
|
||||||
|
Envjs.writeToFile(text, temp);
|
||||||
|
return temp;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to read the contents of a local file
|
||||||
|
* @param {Object} url
|
||||||
|
*/
|
||||||
|
Envjs.readFromFile = function( url ){
|
||||||
|
if(/^file\:\/\//.test(url))
|
||||||
|
url = url.substring(7,url.length);
|
||||||
|
log.debug('reading file %s', url);
|
||||||
|
var file = Ruby.File.open(url, 'r'),
|
||||||
|
data = file.read();
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to delete a local file
|
||||||
|
* @param {Object} url
|
||||||
|
*/
|
||||||
|
Envjs.deleteFile = function(url){
|
||||||
|
return ;//TODO
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* establishes connection and calls responsehandler
|
||||||
|
* @param {Object} xhr
|
||||||
|
* @param {Object} responseHandler
|
||||||
|
* @param {Object} data
|
||||||
|
*/
|
||||||
|
Envjs.connection = function(xhr, responseHandler, data){
|
||||||
|
var url = xhr.url,
|
||||||
|
urlparts = Envjs.urlsplit(xhr.url),
|
||||||
|
connection,
|
||||||
|
request,
|
||||||
|
headers,
|
||||||
|
header,
|
||||||
|
length,
|
||||||
|
binary = false,
|
||||||
|
name, value,
|
||||||
|
contentEncoding,
|
||||||
|
responseXML,
|
||||||
|
i;
|
||||||
|
|
||||||
|
if ( /^file\:/.test(url) ) {
|
||||||
|
//console.log('establishing file connection');
|
||||||
|
Envjs.localXHR(url, xhr, connection, data);
|
||||||
|
} else {
|
||||||
|
log.debug('establishing http connection %s', xhr.url);
|
||||||
|
try{
|
||||||
|
|
||||||
|
connection = Ruby.Net.HTTP.start(
|
||||||
|
urlparts.hostname,
|
||||||
|
Number(urlparts.port||80)
|
||||||
|
);
|
||||||
|
log.debug('connection established %s', connection);
|
||||||
|
|
||||||
|
path = urlparts.path+(urlparts.query?'?'+urlparts.query:'');
|
||||||
|
switch( xhr.method.toUpperCase() ){
|
||||||
|
case "GET":
|
||||||
|
request = new Ruby.Net.HTTP.Get(path);break;
|
||||||
|
case "PUT":
|
||||||
|
request = new Ruby.Net.HTTP.Put(path);break;
|
||||||
|
case "POST" :
|
||||||
|
request = new Ruby.Net.HTTP.Post(path);break;
|
||||||
|
case "HEAD":
|
||||||
|
request = new Ruby.Net.HTTP.Head(path);break;
|
||||||
|
case "DELETE":
|
||||||
|
request = new Ruby.Net.HTTP.Delete(path);break;
|
||||||
|
default:
|
||||||
|
request = null;
|
||||||
|
}
|
||||||
|
log.debug('request query string %s', urlparts.query);
|
||||||
|
log.debug('formulated %s request %s %s', xhr.method, urlparts.path, request);
|
||||||
|
//TODO: add gzip support
|
||||||
|
//connection.putheader("Accept-Encoding", 'gzip');
|
||||||
|
//connection.endheaders();
|
||||||
|
|
||||||
|
//write data to output stream if required
|
||||||
|
//TODO: if they have set the request header for a chunked
|
||||||
|
//request body, implement a chunked output stream
|
||||||
|
if(data){
|
||||||
|
if(data instanceof Document){
|
||||||
|
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||||
|
connection.send((new XMLSerializer()).serializeToString(data));
|
||||||
|
}
|
||||||
|
}else if(data.length&&data.length>0){
|
||||||
|
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||||
|
connection.send(data+'');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
log.error("connection failed %s",e);
|
||||||
|
if (connection)
|
||||||
|
connection.finish();
|
||||||
|
connection = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(connection){
|
||||||
|
[response, headers] = HTTPConnection.go(connection, request, xhr.headers, null);
|
||||||
|
|
||||||
|
try{
|
||||||
|
// Stick the response headers into responseHeaders
|
||||||
|
var keys = headers.keys();
|
||||||
|
for (var i = 0;i<keys.length;i++) {
|
||||||
|
header = keys[i];
|
||||||
|
log.debug('response header [%s] = %s', header, headers[header]);
|
||||||
|
xhr.responseHeaders[header] = headers[header];
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
log.error('failed to load response headers \n%s',e);
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.readyState = 4;
|
||||||
|
xhr.status = parseInt(response.code,10) || undefined;
|
||||||
|
xhr.statusText = response.message || "";
|
||||||
|
log.info('%s %s %s %s', xhr.method, xhr.status, xhr.url, xhr.statusText);
|
||||||
|
contentEncoding = xhr.getResponseHeader('content-encoding') || "utf-8";
|
||||||
|
responseXML = null;
|
||||||
|
|
||||||
|
try{
|
||||||
|
//console.log('contentEncoding %s', contentEncoding);
|
||||||
|
if( contentEncoding.toLowerCase() == "gzip" ||
|
||||||
|
contentEncoding.toLowerCase() == "decompress"){
|
||||||
|
//zipped content
|
||||||
|
binary = true;
|
||||||
|
//TODO
|
||||||
|
log.debug('TODO: handle gzip compression');
|
||||||
|
xhr.responseText = response.body;
|
||||||
|
}else{
|
||||||
|
//this is a text file
|
||||||
|
xhr.responseText = response.body+'';
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
log.warn('failed to open connection stream \n%s, %s %s %s',
|
||||||
|
xhr.status, xhr.url, e.toString(), e
|
||||||
|
);
|
||||||
|
}finally{
|
||||||
|
if(connection)
|
||||||
|
connection.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(responseHandler){
|
||||||
|
log.debug('calling ajax response handler');
|
||||||
|
if(!xhr.async){
|
||||||
|
log.debug('calling sync response handler directly');
|
||||||
|
responseHandler();
|
||||||
|
}else{
|
||||||
|
log.debug('using setTimeout for async response handler');
|
||||||
|
setTimeout(responseHandler, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
})(/*Envjs.XMLHttpRequest.Johnson*/);
|
||||||
|
/**
|
||||||
|
* @author john resig & the envjs team
|
||||||
|
* @uri http://www.envjs.com/
|
||||||
|
* @copyright 2008-2010
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
//CLOSURE_END
|
||||||
|
}());
|
|
@ -0,0 +1,343 @@
|
||||||
|
var __context__ = __this__ = global;
|
||||||
|
|
||||||
|
var Envjs = Envjs ||
|
||||||
|
require('./core').Envjs;
|
||||||
|
require('./../../local_settings');
|
||||||
|
|
||||||
|
Envjs.platform = "Node";
|
||||||
|
Envjs.revision = process.version;
|
||||||
|
|
||||||
|
/*process.on('uncaughtException', function (err) {
|
||||||
|
console.log('Envjs Caught exception: %s \n %s', err);
|
||||||
|
});*/
|
||||||
|
|
||||||
|
Envjs.argv = process.argv;
|
||||||
|
Envjs.argv.shift();
|
||||||
|
Envjs.argv.shift();//node is argv[0] but we want to start at argv[1]
|
||||||
|
|
||||||
|
Envjs.exit = function(){
|
||||||
|
/*setTimeout(function () {
|
||||||
|
if(!Envjs.timers.length){
|
||||||
|
//console.log('no timers remaining %s', Envjs.timers.length);
|
||||||
|
process.exit();
|
||||||
|
}else{
|
||||||
|
Envjs.exit();
|
||||||
|
}
|
||||||
|
}, 13);*/
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Envjs node-env.1.3.pre03
|
||||||
|
* Pure JavaScript Browser Environment
|
||||||
|
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||||
|
* Copyright 2008-2010 John Resig, under the MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
//CLOSURE_START
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author john resig
|
||||||
|
*/
|
||||||
|
// Helper method for extending one object with another.
|
||||||
|
function __extend__(a,b) {
|
||||||
|
for ( var i in b ) {
|
||||||
|
if(b.hasOwnProperty(i)){
|
||||||
|
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
|
||||||
|
if ( g || s ) {
|
||||||
|
if ( g ) { a.__defineGetter__(i, g); }
|
||||||
|
if ( s ) { a.__defineSetter__(i, s); }
|
||||||
|
} else {
|
||||||
|
a[i] = b[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
var $print = require('sys').print;
|
||||||
|
|
||||||
|
Envjs.log = function(msg){
|
||||||
|
console.log(msg+'\n\n');
|
||||||
|
};
|
||||||
|
|
||||||
|
Envjs.lineSource = function(e){
|
||||||
|
return "(line ?)";
|
||||||
|
};
|
||||||
|
|
||||||
|
Envjs.readConsole = function(){
|
||||||
|
return $stdin.gets();
|
||||||
|
};
|
||||||
|
|
||||||
|
Envjs.prompt = function(){
|
||||||
|
$stdout.write(Envjs.CURSOR+' ');
|
||||||
|
$stdout.flush;
|
||||||
|
};
|
||||||
|
|
||||||
|
//No REPL for
|
||||||
|
Envjs.repl = function(){
|
||||||
|
//require('repl').start(Envjs.CURSOR+' ');
|
||||||
|
console.log('Envjs REPL Not Available');
|
||||||
|
};
|
||||||
|
var Script = process.binding('evals').Script;
|
||||||
|
|
||||||
|
Envjs.eval = function(context, source, name, warming){
|
||||||
|
if(context === global){
|
||||||
|
return warming ?
|
||||||
|
eval(source) :
|
||||||
|
Script.runInThisContext(source, name);
|
||||||
|
}else{
|
||||||
|
return Script.runInNewContext(source, context, name);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Envjs.wait = function(){ return; }
|
||||||
|
|
||||||
|
var $tick = function(){
|
||||||
|
process.nextTick(function () {
|
||||||
|
//console.log('node tick');
|
||||||
|
Envjs.tick();
|
||||||
|
$tick();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Envjs.eventLoop = function(){
|
||||||
|
//console.log('event loop');
|
||||||
|
$tick();
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* provides callback hook for when the system exits
|
||||||
|
*/
|
||||||
|
Envjs.onExit = function(callback){
|
||||||
|
process.on('exit', callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* synchronizes thread modifications
|
||||||
|
* @param {Function} fn
|
||||||
|
*/
|
||||||
|
Envjs.sync = function(fn){
|
||||||
|
//console.log('syncing js fn %s', fn);
|
||||||
|
return fn;
|
||||||
|
};
|
||||||
|
|
||||||
|
Envjs.spawn = function(fn){
|
||||||
|
return fn();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sleep thread for specified duration
|
||||||
|
* @param {Object} milliseconds
|
||||||
|
*/
|
||||||
|
Envjs.sleep = function(milliseconds){
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//Since we're running in v8 I guess we can safely assume
|
||||||
|
//java is not 'enabled'. I'm sure this requires more thought
|
||||||
|
//than I've given it here
|
||||||
|
Envjs.javaEnabled = false;
|
||||||
|
|
||||||
|
Envjs.homedir = process.env["HOME"];
|
||||||
|
Envjs.tmpdir = process.env["TMPDIR"];
|
||||||
|
Envjs.os_name = process.platform;
|
||||||
|
Envjs.os_arch = "os arch";
|
||||||
|
Envjs.os_version = "os version";
|
||||||
|
Envjs.lang = process.env["LANG"];
|
||||||
|
|
||||||
|
|
||||||
|
Envjs.gc = function(){ return; };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes an object window-like by proxying object accessors
|
||||||
|
* @param {Object} scope
|
||||||
|
* @param {Object} parent
|
||||||
|
*/
|
||||||
|
Envjs.proxy = function(scope, parent) {
|
||||||
|
try{
|
||||||
|
if(scope.toString() == global){
|
||||||
|
return __this__;
|
||||||
|
}else{
|
||||||
|
return scope;
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
console.log('failed to init standard objects %s %s \n%s', scope, parent, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
};var filesystem = require('fs');
|
||||||
|
/**
|
||||||
|
* Get 'Current Working Directory'
|
||||||
|
*/
|
||||||
|
Envjs.getcwd = function() {
|
||||||
|
return process.cwd();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to write to a local file
|
||||||
|
* @param {Object} text
|
||||||
|
* @param {Object} url
|
||||||
|
*/
|
||||||
|
Envjs.writeToFile = function(text, url){
|
||||||
|
if(/^file\:\/\//.test(url))
|
||||||
|
url = url.substring(7,url.length);
|
||||||
|
filesystem.writeFileSync(url, text, 'utf8');
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to write to a local file
|
||||||
|
* @param {Object} text
|
||||||
|
* @param {Object} suffix
|
||||||
|
*/
|
||||||
|
Envjs.writeToTempFile = function(text, suffix){
|
||||||
|
var url = Envjs.tmpdir+'envjs-'+(new Date().getTime())+'.'+suffix;
|
||||||
|
if(/^file\:\/\//.test(url))
|
||||||
|
url = url.substring(7,url.length);
|
||||||
|
filesystem.writeFileSync(tmpfile, text, 'utf8');
|
||||||
|
return tmpfile;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to read the contents of a local file
|
||||||
|
* @param {Object} url
|
||||||
|
*/
|
||||||
|
Envjs.readFromFile = function( url ){
|
||||||
|
if(/^file\:\/\//.test(url))
|
||||||
|
url = url.substring(7,url.length);
|
||||||
|
return filesystem.readFileSync(url, 'utf8');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to delete a local file
|
||||||
|
* @param {Object} url
|
||||||
|
*/
|
||||||
|
Envjs.deleteFile = function(url){
|
||||||
|
if(/^file\:\/\//.test(url))
|
||||||
|
url = url.substring(7,url.length);
|
||||||
|
filesystem.unlink(url);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* establishes connection and calls responsehandler
|
||||||
|
* @param {Object} xhr
|
||||||
|
* @param {Object} responseHandler
|
||||||
|
* @param {Object} data
|
||||||
|
*/
|
||||||
|
Envjs.connection = function(xhr, responseHandler, data){
|
||||||
|
var url = xhr.url,
|
||||||
|
connection,
|
||||||
|
request,
|
||||||
|
binary = false,
|
||||||
|
contentEncoding,
|
||||||
|
responseXML = null,
|
||||||
|
http = require('http'),
|
||||||
|
urlparts = Envjs.urlsplit(url),
|
||||||
|
i;
|
||||||
|
|
||||||
|
|
||||||
|
if ( /^file\:/.test(url) ) {
|
||||||
|
Envjs.localXHR(url, xhr, connection, data);
|
||||||
|
} else {
|
||||||
|
//console.log('connecting to %s \n\t port(%s) host(%s) path(%s) query(%s)',
|
||||||
|
// url, urlparts.port, urlparts.hostname, urlparts.path, urlparts.query);
|
||||||
|
connection = http.createClient(urlparts.port||'80', urlparts.hostname);
|
||||||
|
request = connection.request(
|
||||||
|
xhr.method,
|
||||||
|
urlparts.path+(urlparts.query?"?"+urlparts.query:''),
|
||||||
|
__extend__(xhr.headers,{
|
||||||
|
"Host": urlparts.hostname,
|
||||||
|
//"Connection":"Keep-Alive"
|
||||||
|
//"Accept-Encoding", 'gzip'
|
||||||
|
})
|
||||||
|
);
|
||||||
|
xhr.statusText = "";
|
||||||
|
|
||||||
|
if(connection&&request){
|
||||||
|
request.on('response', function (response) {
|
||||||
|
//console.log('response begin');
|
||||||
|
xhr.readyState = 3;
|
||||||
|
response.on('end', function (chunk) {
|
||||||
|
//console.log('connection complete');
|
||||||
|
xhr.readyState = 4;
|
||||||
|
if(responseHandler){
|
||||||
|
//console.log('calling ajax response handler');
|
||||||
|
if(!xhr.async){
|
||||||
|
responseHandler();
|
||||||
|
}else{
|
||||||
|
setTimeout(responseHandler, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(xhr.onreadystatechange){
|
||||||
|
xhr.onreadystatechange();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
xhr.responseHeaders = __extend__({},response.headers);
|
||||||
|
xhr.statusText = "OK";
|
||||||
|
xhr.status = response.statusCode;
|
||||||
|
//console.log('response headers : %s', JSON.stringify(xhr.responseHeaders));
|
||||||
|
contentEncoding = xhr.getResponseHeader('Content-Encoding') || "utf-8";
|
||||||
|
response.setEncoding(contentEncoding);
|
||||||
|
//console.log('contentEncoding %s', contentEncoding);
|
||||||
|
|
||||||
|
response.on('data', function (chunk) {
|
||||||
|
//console.log('\nBODY: %s', chunk);
|
||||||
|
if( contentEncoding.match("gzip") ||
|
||||||
|
contentEncoding.match("decompress")){
|
||||||
|
//zipped content
|
||||||
|
binary = true;
|
||||||
|
//Not supported yet
|
||||||
|
xhr.responseText += (chunk+'');
|
||||||
|
}else{
|
||||||
|
//this is a text file
|
||||||
|
xhr.responseText += (chunk+'');
|
||||||
|
}
|
||||||
|
if(xhr.onreadystatechange){
|
||||||
|
xhr.onreadystatechange();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if(xhr.onreadystatechange){
|
||||||
|
xhr.onreadystatechange();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
//write data to output stream if required
|
||||||
|
//TODO: if they have set the request header for a chunked
|
||||||
|
//request body, implement a chunked output stream
|
||||||
|
|
||||||
|
//console.log('sending request %s\n', xhr.url);
|
||||||
|
if(data){
|
||||||
|
if(data instanceof Document){
|
||||||
|
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||||
|
xml = (new XMLSerializer()).serializeToString(data);
|
||||||
|
request.write(xml);
|
||||||
|
}
|
||||||
|
}else if(data.length&&data.length>0){
|
||||||
|
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||||
|
request.write(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
request.end();
|
||||||
|
}else{
|
||||||
|
request.end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author john resig & the envjs team
|
||||||
|
* @uri http://www.envjs.com/
|
||||||
|
* @copyright 2008-2010
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
//CLOSURE_END
|
||||||
|
}());
|
|
@ -0,0 +1,461 @@
|
||||||
|
/*
|
||||||
|
* Envjs rhino-env.1.3.pre03
|
||||||
|
* Pure JavaScript Browser Environment
|
||||||
|
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||||
|
* Copyright 2008-2010 John Resig, under the MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Envjs = Envjs ||
|
||||||
|
require('./core').Envjs;
|
||||||
|
require('local_settings');
|
||||||
|
|
||||||
|
var __context__ = Packages.org.mozilla.javascript.Context.getCurrentContext();
|
||||||
|
|
||||||
|
Envjs.platform = "Rhino";
|
||||||
|
Envjs.revision = "1.7.0.rc2";
|
||||||
|
Envjs.argv = [];
|
||||||
|
if(__argv__ && __argv__.length){
|
||||||
|
for(var i = 0; i < __argv__.length; i++){
|
||||||
|
Envjs.argv[i] = __argv__[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Envjs.exit = function(){
|
||||||
|
java.lang.System.exit(0);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Envjs rhino-env.1.3.pre03
|
||||||
|
* Pure JavaScript Browser Environment
|
||||||
|
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||||
|
* Copyright 2008-2010 John Resig, under the MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
//CLOSURE_START
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author john resig
|
||||||
|
*/
|
||||||
|
// Helper method for extending one object with another.
|
||||||
|
function __extend__(a,b) {
|
||||||
|
for ( var i in b ) {
|
||||||
|
if(b.hasOwnProperty(i)){
|
||||||
|
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
|
||||||
|
if ( g || s ) {
|
||||||
|
if ( g ) { a.__defineGetter__(i, g); }
|
||||||
|
if ( s ) { a.__defineSetter__(i, s); }
|
||||||
|
} else {
|
||||||
|
a[i] = b[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes message to system out.
|
||||||
|
*
|
||||||
|
* @param {Object} message
|
||||||
|
*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
Envjs.log = print;
|
||||||
|
|
||||||
|
Envjs.lineSource = function(e){
|
||||||
|
return e&&e.rhinoException?e.rhinoException.lineSource():"(line ?)";
|
||||||
|
};
|
||||||
|
|
||||||
|
var $in, log;
|
||||||
|
Envjs.readConsole = function(){
|
||||||
|
log = log||Envjs.logger('Envjs.Rhino');
|
||||||
|
$in = $in||new java.io.BufferedReader(
|
||||||
|
new java.io.InputStreamReader(java.lang.System['in'])
|
||||||
|
);
|
||||||
|
return $in.readLine()+'';
|
||||||
|
};
|
||||||
|
Envjs.prompt = function(){
|
||||||
|
java.lang.System.out.print(Envjs.CURSOR+' ');
|
||||||
|
java.lang.System.out.flush();
|
||||||
|
};
|
||||||
|
|
||||||
|
}());
|
||||||
|
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger('Envjs.HTML.Rhino');
|
||||||
|
|
||||||
|
Envjs.eval = function(context, source, name){
|
||||||
|
//console.log('evaluating javascript source %s', source.substring(0,64));
|
||||||
|
return __context__.evaluateString(
|
||||||
|
context,
|
||||||
|
source,
|
||||||
|
name,
|
||||||
|
0,
|
||||||
|
null
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
}());Envjs.renderSVG = function(svgstring, url){
|
||||||
|
//console.log("svg template url %s", templateSVG);
|
||||||
|
// Create a JPEG transcoder
|
||||||
|
var t = new Packages.org.apache.batik.transcoder.image.JPEGTranscoder();
|
||||||
|
|
||||||
|
// Set the transcoding hints.
|
||||||
|
t.addTranscodingHint(
|
||||||
|
Packages.org.apache.batik.transcoder.image.JPEGTranscoder.KEY_QUALITY,
|
||||||
|
new java.lang.Float(1.0));
|
||||||
|
// Create the transcoder input.
|
||||||
|
var input = new Packages.org.apache.batik.transcoder.TranscoderInput(
|
||||||
|
new java.io.StringReader(svgstring));
|
||||||
|
|
||||||
|
// Create the transcoder output.
|
||||||
|
var ostream = new java.io.ByteArrayOutputStream();
|
||||||
|
var output = new Packages.org.apache.batik.transcoder.TranscoderOutput(ostream);
|
||||||
|
|
||||||
|
// Save the image.
|
||||||
|
t.transcode(input, output);
|
||||||
|
|
||||||
|
// Flush and close the stream.
|
||||||
|
ostream.flush();
|
||||||
|
ostream.close();
|
||||||
|
|
||||||
|
var out = new java.io.FileOutputStream(new java.io.File(new java.net.URI(url.toString())));
|
||||||
|
try{
|
||||||
|
out.write( ostream.toByteArray() );
|
||||||
|
}catch(e){
|
||||||
|
|
||||||
|
}finally{
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger('Envjs.Timer.Rhino');
|
||||||
|
/**
|
||||||
|
* Rhino provides a very succinct 'sync'
|
||||||
|
* @param {Function} fn
|
||||||
|
*/
|
||||||
|
try{
|
||||||
|
Envjs.sync = sync;
|
||||||
|
Envjs.spawn = spawn;
|
||||||
|
//print('sync and spawn are available');
|
||||||
|
} catch(e){
|
||||||
|
//print('sync and spawn are not available : ' + e);
|
||||||
|
//sync unavailable on AppEngine
|
||||||
|
Envjs.sync = function(fn){
|
||||||
|
console.log('Threadless platform, sync is safe');
|
||||||
|
return fn;
|
||||||
|
};
|
||||||
|
|
||||||
|
Envjs.spawn = function(fn){
|
||||||
|
console.log('Threadless platform, spawn shares main thread.');
|
||||||
|
return fn();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sleep thread for specified duration
|
||||||
|
* @param {Object} milliseconds
|
||||||
|
*/
|
||||||
|
Envjs.sleep = function(milliseconds){
|
||||||
|
try{
|
||||||
|
return java.lang.Thread.currentThread().sleep(milliseconds);
|
||||||
|
}catch(e){
|
||||||
|
console.log('Threadless platform, cannot sleep.');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* provides callback hook for when the system exits
|
||||||
|
*/
|
||||||
|
Envjs.onExit = function(callback){
|
||||||
|
var rhino = Packages.org.mozilla.javascript,
|
||||||
|
contextFactory = __context__.getFactory(),
|
||||||
|
listener = new rhino.ContextFactory.Listener({
|
||||||
|
contextReleased: function(context){
|
||||||
|
if(context === __context__)
|
||||||
|
console.log('context released', context);
|
||||||
|
contextFactory.removeListener(this);
|
||||||
|
if(callback)
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
contextFactory.addListener(listener);
|
||||||
|
};
|
||||||
|
|
||||||
|
}());
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger('Envjs.XMLHttpRequest.Rhino');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get 'Current Working Directory'
|
||||||
|
*/
|
||||||
|
Envjs.getcwd = function() {
|
||||||
|
return java.lang.System.getProperty('user.dir');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to write to a local file
|
||||||
|
* @param {Object} text
|
||||||
|
* @param {Object} url
|
||||||
|
*/
|
||||||
|
Envjs.writeToFile = function(text, url){
|
||||||
|
//Envjs.debug("writing text to url : " + url);
|
||||||
|
var out = new java.io.FileWriter(
|
||||||
|
new java.io.File(
|
||||||
|
new java.net.URI(url.toString())));
|
||||||
|
out.write( text, 0, text.length );
|
||||||
|
out.flush();
|
||||||
|
out.close();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to write to a local file
|
||||||
|
* @param {Object} text
|
||||||
|
* @param {Object} suffix
|
||||||
|
*/
|
||||||
|
Envjs.writeToTempFile = function(text, suffix){
|
||||||
|
//console.log("writing text to temp url : %s");
|
||||||
|
// Create temp file.
|
||||||
|
var temp = java.io.File.createTempFile("envjs-tmp", suffix);
|
||||||
|
|
||||||
|
// Delete temp file when program exits.
|
||||||
|
temp.deleteOnExit();
|
||||||
|
|
||||||
|
// Write to temp file
|
||||||
|
var out = new java.io.FileWriter(temp);
|
||||||
|
out.write(text, 0, text.length);
|
||||||
|
out.close();
|
||||||
|
return temp.getAbsolutePath().toString()+'';
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to read the contents of a local file
|
||||||
|
* @param {Object} url
|
||||||
|
*/
|
||||||
|
Envjs.readFromFile = function( url ){
|
||||||
|
if(typeof url == 'string')
|
||||||
|
url = Envjs.uri(url);
|
||||||
|
//console.log("reading from url : %s", url);
|
||||||
|
var fileReader = new java.io.FileReader(
|
||||||
|
new java.io.File(
|
||||||
|
new java.net.URI( url )));
|
||||||
|
|
||||||
|
var stringwriter = new java.io.StringWriter(),
|
||||||
|
buffer = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 1024),
|
||||||
|
length;
|
||||||
|
|
||||||
|
while ((length = fileReader.read(buffer, 0, 1024)) != -1) {
|
||||||
|
stringwriter.write(buffer, 0, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
stringwriter.close();
|
||||||
|
return stringwriter.toString()+"";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to delete a local file
|
||||||
|
* @param {Object} url
|
||||||
|
*/
|
||||||
|
Envjs.deleteFile = function(url){
|
||||||
|
var file = new java.io.File( new java.net.URI( url ) );
|
||||||
|
file["delete"]();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* establishes connection and calls responsehandler
|
||||||
|
* @param {Object} xhr
|
||||||
|
* @param {Object} responseHandler
|
||||||
|
* @param {Object} data
|
||||||
|
*/
|
||||||
|
Envjs.connection = function(xhr, responseHandler, data){
|
||||||
|
var url = java.net.URL(xhr.url),
|
||||||
|
connection,
|
||||||
|
header,
|
||||||
|
outstream,
|
||||||
|
buffer,
|
||||||
|
length,
|
||||||
|
binary = false,
|
||||||
|
name, value,
|
||||||
|
contentEncoding,
|
||||||
|
instream,
|
||||||
|
responseXML,
|
||||||
|
i;
|
||||||
|
|
||||||
|
|
||||||
|
if ( /^file\:/.test(url) ) {
|
||||||
|
Envjs.localXHR(url, xhr, connection, data);
|
||||||
|
} else {
|
||||||
|
connection = url.openConnection();
|
||||||
|
//handle redirects manually since cookie support sucks out of the box
|
||||||
|
connection.setFollowRedirects(false);
|
||||||
|
connection.setRequestMethod( xhr.method );
|
||||||
|
|
||||||
|
// Add headers to Java connection
|
||||||
|
for (header in xhr.headers){
|
||||||
|
connection.addRequestProperty(header+'', xhr.headers[header]+'');
|
||||||
|
}
|
||||||
|
connection.addRequestProperty("Accept-Encoding", 'gzip');
|
||||||
|
|
||||||
|
//write data to output stream if required
|
||||||
|
//TODO: if they have set the request header for a chunked
|
||||||
|
//request body, implement a chunked output stream
|
||||||
|
if(data){
|
||||||
|
if(data instanceof Document){
|
||||||
|
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||||
|
connection.setDoOutput(true);
|
||||||
|
outstream = connection.getOutputStream(),
|
||||||
|
xml = (new XMLSerializer()).serializeToString(data);
|
||||||
|
buffer = new java.lang.String(xml).getBytes('UTF-8');
|
||||||
|
outstream.write(buffer, 0, buffer.length);
|
||||||
|
outstream.close();
|
||||||
|
}
|
||||||
|
}else if(data.length&&data.length>0){
|
||||||
|
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||||
|
connection.setDoOutput(true);
|
||||||
|
outstream = connection.getOutputStream();
|
||||||
|
buffer = new java.lang.String(data).getBytes('UTF-8');
|
||||||
|
outstream.write(buffer, 0, buffer.length);
|
||||||
|
outstream.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
connection.connect();
|
||||||
|
}else{
|
||||||
|
connection.connect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(connection){
|
||||||
|
try{
|
||||||
|
length = connection.getHeaderFields().size();
|
||||||
|
// Stick the response headers into responseHeaders
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
name = connection.getHeaderFieldKey(i);
|
||||||
|
value = connection.getHeaderField(i);
|
||||||
|
if (name)
|
||||||
|
xhr.responseHeaders[name+''] = value+'';
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
console.log('failed to load response headers \n%s',e);
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.readyState = 4;
|
||||||
|
xhr.status = parseInt(connection.responseCode,10) || undefined;
|
||||||
|
xhr.statusText = connection.responseMessage || "";
|
||||||
|
|
||||||
|
contentEncoding = connection.getContentEncoding() || "utf-8";
|
||||||
|
instream = null;
|
||||||
|
responseXML = null;
|
||||||
|
|
||||||
|
try{
|
||||||
|
//console.log('contentEncoding %s', contentEncoding);
|
||||||
|
if( contentEncoding.equalsIgnoreCase("gzip") ||
|
||||||
|
contentEncoding.equalsIgnoreCase("decompress")){
|
||||||
|
//zipped content
|
||||||
|
binary = true;
|
||||||
|
outstream = new java.io.ByteArrayOutputStream();
|
||||||
|
buffer = java.lang.reflect.Array.newInstance(java.lang.Byte.TYPE, 1024);
|
||||||
|
instream = new java.util.zip.GZIPInputStream(connection.getInputStream())
|
||||||
|
}else{
|
||||||
|
//this is a text file
|
||||||
|
outstream = new java.io.StringWriter();
|
||||||
|
buffer = java.lang.reflect.Array.newInstance(java.lang.Character.TYPE, 1024);
|
||||||
|
instream = new java.io.InputStreamReader(connection.getInputStream());
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
if (connection.getResponseCode() == 404){
|
||||||
|
console.log('failed to open connection stream \n %s %s',
|
||||||
|
e.toString(), e);
|
||||||
|
}else{
|
||||||
|
console.log('failed to open connection stream \n %s %s',
|
||||||
|
e.toString(), e);
|
||||||
|
}
|
||||||
|
instream = connection.getErrorStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
while ((length = instream.read(buffer, 0, 1024)) != -1) {
|
||||||
|
outstream.write(buffer, 0, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
outstream.close();
|
||||||
|
instream.close();
|
||||||
|
|
||||||
|
if(binary){
|
||||||
|
xhr.responseText = new java.lang.String(outstream.toByteArray(), 'UTF-8')+'';
|
||||||
|
}else{
|
||||||
|
xhr.responseText = outstream.toString()+'';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if(responseHandler){
|
||||||
|
//console.log('calling ajax response handler');
|
||||||
|
if(!xhr.async){
|
||||||
|
responseHandler();
|
||||||
|
}else{
|
||||||
|
//console.log('synchronizing ajax response handler via setTimeout');
|
||||||
|
setTimeout(responseHandler, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}());
|
||||||
|
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger('Envjs.Window.Rhino');
|
||||||
|
|
||||||
|
//Since we're running in rhino I guess we can safely assume
|
||||||
|
//java is 'enabled'. I'm sure this requires more thought
|
||||||
|
//than I've given it here
|
||||||
|
Envjs.javaEnabled = true;
|
||||||
|
|
||||||
|
Envjs.homedir = java.lang.System.getProperty("user.home");
|
||||||
|
Envjs.tmpdir = java.lang.System.getProperty("java.io.tmpdir");
|
||||||
|
Envjs.os_name = java.lang.System.getProperty("os.name");
|
||||||
|
Envjs.os_arch = java.lang.System.getProperty("os.arch");
|
||||||
|
Envjs.os_version = java.lang.System.getProperty("os.version");
|
||||||
|
Envjs.lang = java.lang.System.getProperty("user.lang");
|
||||||
|
|
||||||
|
|
||||||
|
Envjs.gc = function(){ gc(); };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes an object window-like by proxying object accessors
|
||||||
|
* @param {Object} scope
|
||||||
|
* @param {Object} parent
|
||||||
|
*/
|
||||||
|
Envjs.proxy = function(scope, parent) {
|
||||||
|
try{
|
||||||
|
if(scope+'' == '[object global]'){
|
||||||
|
return scope;
|
||||||
|
}else{
|
||||||
|
return __context__.initStandardObjects();
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
console.log('failed to init standard objects %s %s \n%s', scope, parent, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}());
|
||||||
|
/**
|
||||||
|
* @author john resig & the envjs team
|
||||||
|
* @uri http://www.envjs.com/
|
||||||
|
* @copyright 2008-2010
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
//CLOSURE_END
|
||||||
|
}());
|
|
@ -0,0 +1,340 @@
|
||||||
|
var __context__ = __this__;
|
||||||
|
|
||||||
|
var Envjs = Envjs ||
|
||||||
|
require('./core').Envjs;
|
||||||
|
require('local_settings');
|
||||||
|
|
||||||
|
Envjs.platform = "V8 RubyRacer";
|
||||||
|
Envjs.revision = Ruby.CONFIG.ruby_version;
|
||||||
|
|
||||||
|
Ruby.ARGV.shift();
|
||||||
|
Envjs.argv = Ruby.ARGV;
|
||||||
|
|
||||||
|
Envjs.exit = function(){ Ruby.Process['exit!'](); };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Envjs rubyracer-env.1.3.pre03
|
||||||
|
* Pure JavaScript Browser Environment
|
||||||
|
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||||
|
* Copyright 2008-2010 John Resig, under the MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
//CLOSURE_START
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author john resig
|
||||||
|
*/
|
||||||
|
// Helper method for extending one object with another.
|
||||||
|
function __extend__(a,b) {
|
||||||
|
for ( var i in b ) {
|
||||||
|
if(b.hasOwnProperty(i)){
|
||||||
|
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
|
||||||
|
if ( g || s ) {
|
||||||
|
if ( g ) { a.__defineGetter__(i, g); }
|
||||||
|
if ( s ) { a.__defineSetter__(i, s); }
|
||||||
|
} else {
|
||||||
|
a[i] = b[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
Envjs.log = function(msg){
|
||||||
|
Ruby.puts(msg);
|
||||||
|
};
|
||||||
|
|
||||||
|
Envjs.lineSource = function(e){
|
||||||
|
return "(line ?)";
|
||||||
|
};
|
||||||
|
|
||||||
|
var line = "";
|
||||||
|
Envjs.readConsole = function(){
|
||||||
|
try{
|
||||||
|
line = Ruby.$stdin.gets();
|
||||||
|
}catch(e){
|
||||||
|
console.log('ERROR : %s', e);
|
||||||
|
}
|
||||||
|
return line;
|
||||||
|
};
|
||||||
|
|
||||||
|
Envjs.prompt = function(){
|
||||||
|
Ruby.$stdout.write(Envjs.CURSOR+' ');
|
||||||
|
Ruby.$stdout.flush;
|
||||||
|
};
|
||||||
|
|
||||||
|
//No REPL for
|
||||||
|
Envjs.repl = function(){
|
||||||
|
console.log('Envjs REPL Not Available');
|
||||||
|
};
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger('Envjs.Platform.RubyRacer');
|
||||||
|
|
||||||
|
Envjs.eval = function(context, source, name){
|
||||||
|
if(context == __this__){
|
||||||
|
return __this__.eval( source );
|
||||||
|
}else{
|
||||||
|
log.debug('evaluating in proxy scope %s', context);
|
||||||
|
return context.eval( source );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
})();
|
||||||
|
/**
|
||||||
|
* synchronizes thread modifications
|
||||||
|
* @param {Function} fn
|
||||||
|
*/
|
||||||
|
Envjs.sync = function(fn){
|
||||||
|
//console.log('Threadless platform, sync is safe');
|
||||||
|
return sync(fn);
|
||||||
|
};
|
||||||
|
|
||||||
|
Envjs.spawn = function(fn){
|
||||||
|
return spawn(fn);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sleep thread for specified duration
|
||||||
|
* @param {Object} milliseconds
|
||||||
|
*/
|
||||||
|
Envjs.sleep = function(milliseconds){
|
||||||
|
return Ruby.sleep(1.0*milliseconds/1000.0);
|
||||||
|
};
|
||||||
|
//Since we're running in spydermonkey I guess we can safely assume
|
||||||
|
//java is not 'enabled'. I'm sure this requires more thought
|
||||||
|
//than I've given it here
|
||||||
|
Envjs.javaEnabled = false;
|
||||||
|
|
||||||
|
Envjs.homedir = Ruby.ENV.HOME
|
||||||
|
Envjs.tmpdir = Ruby.ENV.TMPDIR;
|
||||||
|
Envjs.os_name = Ruby.CONFIG.host_os;
|
||||||
|
Envjs.os_arch = Ruby.CONFIG.host_cpu;
|
||||||
|
Envjs.os_version = "";//part of os_arch
|
||||||
|
Envjs.lang = Ruby.ENV.LANG;
|
||||||
|
|
||||||
|
Envjs.gc = function(){ Ruby.gc(); };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes an object window-like by proxying object accessors
|
||||||
|
* @param {Object} scope
|
||||||
|
* @param {Object} parent
|
||||||
|
*/
|
||||||
|
Envjs.proxy = function(scope, parent) {
|
||||||
|
try{
|
||||||
|
if(scope == __this__){
|
||||||
|
return scope;
|
||||||
|
}else{
|
||||||
|
return new_context();
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
console.log('failed to init standard objects %s %s \n%s', scope, parent, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger('Envjs.XMLHttpRequest.RubyRacer');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get 'Current Working Directory'
|
||||||
|
*/
|
||||||
|
Envjs.getcwd = function() {
|
||||||
|
return Ruby.ENV.PWD;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to read the contents of a local file
|
||||||
|
* @param {Object} url
|
||||||
|
*/
|
||||||
|
Envjs.readFromFile = function( url ){
|
||||||
|
if(/^file\:\/\//.test(url))
|
||||||
|
url = url.substring(7,url.length);
|
||||||
|
log.debug('reading file %s', url);
|
||||||
|
var file = fopen(url, 'r'),
|
||||||
|
data = file.read();
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
Envjs.writeToFile = function(text, url){
|
||||||
|
var file = fopen(url, 'w');
|
||||||
|
log.debug('writing to file %s', url);
|
||||||
|
file.write(text);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to write to a local file
|
||||||
|
* @param {Object} text
|
||||||
|
* @param {Object} suffix
|
||||||
|
*/
|
||||||
|
Envjs.writeToTempFile = function(text, suffix){
|
||||||
|
// Create temp file.
|
||||||
|
var temp = Envjs.tmpdir+"."+(new Date().getTime())+(suffix||'.js');
|
||||||
|
log.debug("writing text to temp url : %s ", temp);
|
||||||
|
Envjs.writeToFile(text, temp);
|
||||||
|
return temp;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to read the contents of a local file
|
||||||
|
* @param {Object} url
|
||||||
|
*/
|
||||||
|
Envjs.readFromFile = function( url ){
|
||||||
|
if(/^file\:\/\//.test(url))
|
||||||
|
url = url.substring(7,url.length);
|
||||||
|
log.debug('reading file %s', url);
|
||||||
|
var file = fopen(url, 'r'),
|
||||||
|
data = file.read();
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to delete a local file
|
||||||
|
* @param {Object} url
|
||||||
|
*/
|
||||||
|
Envjs.deleteFile = function(url){
|
||||||
|
return ;//TODO
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* establishes connection and calls responsehandler
|
||||||
|
* @param {Object} xhr
|
||||||
|
* @param {Object} responseHandler
|
||||||
|
* @param {Object} data
|
||||||
|
*/
|
||||||
|
Envjs.connection = function(xhr, responseHandler, data){
|
||||||
|
var url = xhr.url,
|
||||||
|
urlparts = Envjs.urlsplit(xhr.url),
|
||||||
|
connection,
|
||||||
|
request,
|
||||||
|
headers,
|
||||||
|
header,
|
||||||
|
length,
|
||||||
|
binary = false,
|
||||||
|
name, value,
|
||||||
|
contentEncoding,
|
||||||
|
responseXML,
|
||||||
|
i;
|
||||||
|
|
||||||
|
if ( /^file\:/.test(url) ) {
|
||||||
|
log.debug('establishing file connection');
|
||||||
|
Envjs.localXHR(url, xhr, connection, data);
|
||||||
|
} else {
|
||||||
|
log.debug('establishing http native ruby connection %s', xhr.url);
|
||||||
|
try{
|
||||||
|
|
||||||
|
connection = HTTPConnection.connect(
|
||||||
|
urlparts.hostname,
|
||||||
|
Number(urlparts.port||80)
|
||||||
|
);
|
||||||
|
log.debug('native ruby connection established %s', connection);
|
||||||
|
|
||||||
|
path = urlparts.path+(urlparts.query?'?'+urlparts.query:'');
|
||||||
|
request = HTTPConnection.request(xhr.method.toUpperCase(), path);
|
||||||
|
log.debug('request query string %s', urlparts.query);
|
||||||
|
log.debug('formulated %s request %s %s', xhr.method, urlparts.path, request);
|
||||||
|
//TODO: add gzip support
|
||||||
|
//connection.putheader("Accept-Encoding", 'gzip');
|
||||||
|
//connection.endheaders();
|
||||||
|
|
||||||
|
//write data to output stream if required
|
||||||
|
//TODO: if they have set the request header for a chunked
|
||||||
|
//request body, implement a chunked output stream
|
||||||
|
if(data){
|
||||||
|
if(data instanceof Document){
|
||||||
|
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||||
|
connection.send((new XMLSerializer()).serializeToString(data));
|
||||||
|
}
|
||||||
|
}else if(data.length&&data.length>0){
|
||||||
|
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||||
|
connection.send(data+'');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
log.error("connection failed %s",e);
|
||||||
|
if (connection){
|
||||||
|
HTTPConnection.finish(connection);
|
||||||
|
}
|
||||||
|
connection = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(connection){
|
||||||
|
log.debug('loading response from native ruby connection');
|
||||||
|
response = HTTPConnection.go(connection, request, xhr.headers, null);
|
||||||
|
log.debug('got response from native ruby connection');
|
||||||
|
headers = response[1];
|
||||||
|
response = response[0];
|
||||||
|
try{
|
||||||
|
// Stick the response headers into responseHeaders
|
||||||
|
for (var header in headers) {
|
||||||
|
log.debug('response header [%s] = %s', header, headers[header]);
|
||||||
|
xhr.responseHeaders[header] = headers[header];
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
log.error('failed to load response headers \n%s',e);
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.readyState = 4;
|
||||||
|
xhr.status = parseInt(response.code,10) || undefined;
|
||||||
|
xhr.statusText = response.message || "";
|
||||||
|
log.info('%s %s %s %s', xhr.method, xhr.status, xhr.url, xhr.statusText);
|
||||||
|
contentEncoding = xhr.getResponseHeader('content-encoding') || "utf-8";
|
||||||
|
responseXML = null;
|
||||||
|
|
||||||
|
try{
|
||||||
|
//console.log('contentEncoding %s', contentEncoding);
|
||||||
|
if( contentEncoding.toLowerCase() == "gzip" ||
|
||||||
|
contentEncoding.toLowerCase() == "decompress"){
|
||||||
|
//zipped content
|
||||||
|
binary = true;
|
||||||
|
//TODO
|
||||||
|
log.debug('TODO: handle gzip compression');
|
||||||
|
xhr.responseText = response.body;
|
||||||
|
}else{
|
||||||
|
//this is a text file
|
||||||
|
xhr.responseText = response.body+'';
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
log.warn('failed to open connection stream \n%s, %s %s %s',
|
||||||
|
xhr.status, xhr.url, e.toString(), e
|
||||||
|
);
|
||||||
|
}finally{
|
||||||
|
if(connection){
|
||||||
|
HTTPConnection.finish(connection);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(responseHandler){
|
||||||
|
log.debug('calling ajax response handler');
|
||||||
|
if(!xhr.async){
|
||||||
|
log.debug('calling sync response handler directly');
|
||||||
|
responseHandler();
|
||||||
|
}else{
|
||||||
|
log.debug('using setTimeout for async response handler');
|
||||||
|
setTimeout(responseHandler, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
})(/*Envjs.XMLHttpRequest.Johnson*/);
|
||||||
|
/**
|
||||||
|
* @author john resig & the envjs team
|
||||||
|
* @uri http://www.envjs.com/
|
||||||
|
* @copyright 2008-2010
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
//CLOSURE_END
|
||||||
|
}());
|
|
@ -0,0 +1,352 @@
|
||||||
|
var __context__ = __this__;
|
||||||
|
|
||||||
|
var Envjs = Envjs ||
|
||||||
|
require('./core').Envjs;
|
||||||
|
require('local_settings');
|
||||||
|
|
||||||
|
Envjs.platform = "SpyderMonkey";
|
||||||
|
Envjs.revision = sys.version.substring(0,5);
|
||||||
|
|
||||||
|
Envjs.argv = []
|
||||||
|
for(var i in sys.argv){
|
||||||
|
Envjs.argv.push(sys.argv[i]);
|
||||||
|
}
|
||||||
|
Envjs.argv.shift();
|
||||||
|
Envjs.argv.shift();
|
||||||
|
|
||||||
|
Envjs.exit = function(){
|
||||||
|
exit();
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Envjs node-env.1.3.pre03
|
||||||
|
* Pure JavaScript Browser Environment
|
||||||
|
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||||
|
* Copyright 2008-2010 John Resig, under the MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
//CLOSURE_START
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author john resig
|
||||||
|
*/
|
||||||
|
// Helper method for extending one object with another.
|
||||||
|
function __extend__(a,b) {
|
||||||
|
for ( var i in b ) {
|
||||||
|
if(b.hasOwnProperty(i)){
|
||||||
|
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
|
||||||
|
if ( g || s ) {
|
||||||
|
if ( g ) { a.__defineGetter__(i, g); }
|
||||||
|
if ( s ) { a.__defineSetter__(i, s); }
|
||||||
|
} else {
|
||||||
|
a[i] = b[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
Envjs.log = print;
|
||||||
|
|
||||||
|
Envjs.lineSource = function(e){
|
||||||
|
return "(line ?)";
|
||||||
|
};
|
||||||
|
|
||||||
|
Envjs.readConsole = function(){
|
||||||
|
return sys.stdin.readline();
|
||||||
|
};
|
||||||
|
|
||||||
|
Envjs.prompt = function(){
|
||||||
|
sys.stdout.write(Envjs.CURSOR+' ');
|
||||||
|
sys.stdout.flush();
|
||||||
|
};
|
||||||
|
|
||||||
|
//No REPL for
|
||||||
|
Envjs.repl = function(){
|
||||||
|
console.log('Envjs REPL Not Available');
|
||||||
|
};
|
||||||
|
|
||||||
|
Envjs.eval = function(context, source, name){
|
||||||
|
if(context == __this__){
|
||||||
|
return global.execute( source );
|
||||||
|
}else{
|
||||||
|
return context.execute( source );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* synchronizes thread modifications
|
||||||
|
* @param {Function} fn
|
||||||
|
*/
|
||||||
|
Envjs.sync = function(fn){
|
||||||
|
/*return function(){
|
||||||
|
try{
|
||||||
|
//console.log('locking');
|
||||||
|
$lock.acquire();
|
||||||
|
fn.apply(fn, arguments);
|
||||||
|
}catch(e){
|
||||||
|
console.log('error in sync: %s',e);
|
||||||
|
}finally{
|
||||||
|
//console.log('unlocking');
|
||||||
|
$lock.release();
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
return fn;
|
||||||
|
};
|
||||||
|
|
||||||
|
Envjs.spawn = function(fn){
|
||||||
|
/*var t = threading.Thread();
|
||||||
|
t.run = function(){
|
||||||
|
try{
|
||||||
|
console.log('spawned');
|
||||||
|
fn.apply(fn, arguments);
|
||||||
|
}catch(e){
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return t.start();*/
|
||||||
|
fn();
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sleep thread for specified duration
|
||||||
|
* @param {Number} milliseconds
|
||||||
|
*/
|
||||||
|
Envjs.sleep = function(milliseconds){
|
||||||
|
return time.sleep(1.0*milliseconds/1000.0);
|
||||||
|
};
|
||||||
|
|
||||||
|
//Since we're running in spydermonkey I guess we can safely assume
|
||||||
|
//java is not 'enabled'. I'm sure this requires more thought
|
||||||
|
//than I've given it here
|
||||||
|
Envjs.javaEnabled = false;
|
||||||
|
|
||||||
|
Envjs.homedir = os.environ['HOME']
|
||||||
|
Envjs.tmpdir = os.environ['TMPDIR'];
|
||||||
|
Envjs.os_name = platform.system();
|
||||||
|
Envjs.os_arch = platform.processor();
|
||||||
|
Envjs.os_version = platform.release();
|
||||||
|
Envjs.lang = os.environ['LANG'];
|
||||||
|
|
||||||
|
|
||||||
|
Envjs.gc = function(){ global.gc(); };
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes an object window-like by proxying object accessors
|
||||||
|
* @param {Object} scope
|
||||||
|
* @param {Object} parent
|
||||||
|
*/
|
||||||
|
Envjs.proxy = function(scope, parent) {
|
||||||
|
try{
|
||||||
|
if(scope == __this__){
|
||||||
|
return scope;
|
||||||
|
}else{
|
||||||
|
return new_global();
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
console.log('failed to init standard objects %s %s \n%s', scope, parent, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger('Envjs.XMLHttpRequest.SpyderMonkey');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get 'Current Working Directory'
|
||||||
|
*/
|
||||||
|
Envjs.getcwd = function() {
|
||||||
|
return os.getcwd();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to write to a local file
|
||||||
|
* @param {Object} text
|
||||||
|
* @param {Object} url
|
||||||
|
*/
|
||||||
|
Envjs.writeToFile = function(text, url){
|
||||||
|
var file = fopen(url, 'w');
|
||||||
|
file.write(text);
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to write to a local file
|
||||||
|
* @param {Object} text
|
||||||
|
* @param {Object} suffix
|
||||||
|
*/
|
||||||
|
Envjs.writeToTempFile = function(text, suffix){
|
||||||
|
// Create temp file.
|
||||||
|
var temp = Envjs.tmpdir+"."+(new Date().getTime())+(suffix||'.js');
|
||||||
|
log.debug("writing text to temp url : %s ", temp);
|
||||||
|
Envjs.writeToFile(text, temp);
|
||||||
|
return temp;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to read the contents of a local file
|
||||||
|
* @param {Object} url
|
||||||
|
*/
|
||||||
|
Envjs.readFromFile = function( url ){
|
||||||
|
if(/^file\:\/\//.test(url))
|
||||||
|
url = url.substring(7,url.length);
|
||||||
|
log.debug('reading file %s', url);
|
||||||
|
var file = fopen(url, 'r'),
|
||||||
|
data = file.read();
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to delete a local file
|
||||||
|
* @param {Object} url
|
||||||
|
*/
|
||||||
|
Envjs.deleteFile = function(url){
|
||||||
|
if(/^file\:\/\//.test(url))
|
||||||
|
url = url.substring(7,url.length);
|
||||||
|
log.debug('deleting file %s', url);
|
||||||
|
return os.delete(url);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* establishes connection and calls responsehandler
|
||||||
|
* @param {Object} xhr
|
||||||
|
* @param {Object} responseHandler
|
||||||
|
* @param {Object} data
|
||||||
|
*/
|
||||||
|
Envjs.connection = function(xhr, responseHandler, data){
|
||||||
|
var url = xhr.url,
|
||||||
|
urlparts = Envjs.urlsplit(xhr.url),
|
||||||
|
connection,
|
||||||
|
request,
|
||||||
|
header,
|
||||||
|
length,
|
||||||
|
binary = false,
|
||||||
|
name, value,
|
||||||
|
contentEncoding,
|
||||||
|
responseXML,
|
||||||
|
i;
|
||||||
|
|
||||||
|
if ( /^file\:/.test(url) ) {
|
||||||
|
log.debug('establishing platform file connection');
|
||||||
|
Envjs.localXHR(url, xhr, connection, data);
|
||||||
|
} else {
|
||||||
|
log.debug('establishing python platform network connection');
|
||||||
|
try{
|
||||||
|
log.debug('connecting to %s \n\t port(%s) hostname(%s) path(%s) query(%s)',
|
||||||
|
url, urlparts.port, urlparts.hostname, urlparts.path, urlparts.query);
|
||||||
|
connection = httplib.HTTPConnection(urlparts.hostname, urlparts.port || 80);
|
||||||
|
connection.connect();
|
||||||
|
request = connection.putrequest(
|
||||||
|
xhr.method,
|
||||||
|
urlparts.path+(urlparts.query?'?'+urlparts.query:'')
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add headers to connection
|
||||||
|
for (header in xhr.headers){
|
||||||
|
log.debug('adding request header %s %s',header+'', xhr.headers[header]+'')
|
||||||
|
connection.putheader(header+'', xhr.headers[header]+'');
|
||||||
|
}
|
||||||
|
//TODO: add gzip support
|
||||||
|
//connection.putheader("Accept-Encoding", 'gzip');
|
||||||
|
connection.endheaders();
|
||||||
|
|
||||||
|
//write data to output stream if required
|
||||||
|
//TODO: if they have set the request header for a chunked
|
||||||
|
//request body, implement a chunked output stream
|
||||||
|
if(data){
|
||||||
|
if(data instanceof Document){
|
||||||
|
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||||
|
connection.send((new XMLSerializer()).serializeToString(data));
|
||||||
|
}
|
||||||
|
}else if(data.length&&data.length>0){
|
||||||
|
if ( xhr.method == "PUT" || xhr.method == "POST" ) {
|
||||||
|
connection.send(data+'');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
log.error('error making python native connection %s', e);
|
||||||
|
connection.close();
|
||||||
|
connection = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(connection){
|
||||||
|
try{
|
||||||
|
response = connection.getresponse();
|
||||||
|
log.debug('got native platform connection response');
|
||||||
|
length = response.getheaders().length;
|
||||||
|
// Stick the response headers into responseHeaders
|
||||||
|
for (i = 0; i < length; i++) {
|
||||||
|
header = response.getheaders()[i];
|
||||||
|
name = header[0];
|
||||||
|
value = header[1];
|
||||||
|
if (name){
|
||||||
|
log.debug('response header %s %s', name, value);
|
||||||
|
xhr.responseHeaders[name+''] = value+'';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
console.log('failed to load response headers \n%s',e);
|
||||||
|
}
|
||||||
|
|
||||||
|
xhr.readyState = 4;
|
||||||
|
xhr.status = parseInt(response.status,10) || undefined;
|
||||||
|
xhr.statusText = response.reason || "";
|
||||||
|
log.info('%s %s %s %s', xhr.method, xhr.status, xhr.url, xhr.statusText);
|
||||||
|
contentEncoding = xhr.getResponseHeader('content-encoding') || "utf-8";
|
||||||
|
responseXML = null;
|
||||||
|
|
||||||
|
try{
|
||||||
|
//console.log('contentEncoding %s', contentEncoding);
|
||||||
|
if( contentEncoding.toLowerCase() == "gzip" ||
|
||||||
|
contentEncoding.toLowerCase() == "decompress"){
|
||||||
|
//zipped content
|
||||||
|
binary = true;
|
||||||
|
//TODO
|
||||||
|
console.log('TODO: handle gzip compression');
|
||||||
|
xhr.responseText = response.read();
|
||||||
|
}else{
|
||||||
|
//this is a text file
|
||||||
|
xhr.responseText = response.read();
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
if (xhr.status == 404){
|
||||||
|
console.log('failed to open connection stream \n %s %s',
|
||||||
|
e.toString(), e);
|
||||||
|
}else{
|
||||||
|
console.log('failed to open connection stream \n %s %s',
|
||||||
|
e.toString(), e);
|
||||||
|
}
|
||||||
|
}finally{
|
||||||
|
connection.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(responseHandler){
|
||||||
|
log.debug('calling ajax response handler');
|
||||||
|
if(!xhr.async){
|
||||||
|
responseHandler();
|
||||||
|
}else{
|
||||||
|
setTimeout(responseHandler, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
})(/*Envjs.Platform.SpyderMonkey*/);
|
||||||
|
/**
|
||||||
|
* @author john resig & the envjs team
|
||||||
|
* @uri http://www.envjs.com/
|
||||||
|
* @copyright 2008-2010
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
//CLOSURE_END
|
||||||
|
}());
|
|
@ -0,0 +1,91 @@
|
||||||
|
// This file is compiled into the jar and executed automatically on startup.
|
||||||
|
var __this__ = this;
|
||||||
|
var require = (function() {
|
||||||
|
var cached = {};
|
||||||
|
var currentPath = java.lang.System.getProperty('user.dir');
|
||||||
|
var paths = [currentPath];
|
||||||
|
|
||||||
|
function normalize(id) {
|
||||||
|
var file;
|
||||||
|
id = id + '.js';
|
||||||
|
if (/^\.\.?/.test(id)) {
|
||||||
|
// relative path
|
||||||
|
file = new java.io.File(currentPath, id);
|
||||||
|
if (file.isFile()) {
|
||||||
|
return file.toURL();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (var i = 0, len = paths.length; i < len; ++i) {
|
||||||
|
file = new java.io.File(paths[i], id);
|
||||||
|
if (file.isFile()) {
|
||||||
|
return file.toURL();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// try to get it from the jar as a last resort
|
||||||
|
/*var url = rhoop.getClass().getResource('/' + id);
|
||||||
|
if (url !== null) {
|
||||||
|
return url;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
function read(connection) {
|
||||||
|
var stream = connection.getInputStream();
|
||||||
|
var bytes = java.lang.reflect.Array.newInstance(
|
||||||
|
java.lang.Byte.TYPE, 4096);
|
||||||
|
var bytesStream = new java.io.ByteArrayOutputStream();
|
||||||
|
var bytesRead;
|
||||||
|
while ((bytesRead = stream.read(bytes)) >= 0) {
|
||||||
|
if (bytesRead > 0) {
|
||||||
|
bytesStream.write(bytes, 0, bytesRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return String(bytesStream.toString());
|
||||||
|
};
|
||||||
|
|
||||||
|
function require(id) {
|
||||||
|
//print('require :'+ id);
|
||||||
|
var url = normalize(id);
|
||||||
|
if (!url) {
|
||||||
|
throw new Error("couldn't find module \"" + id + "\"");
|
||||||
|
}
|
||||||
|
id = String(url.toString());
|
||||||
|
if (!cached.hasOwnProperty(id)) {
|
||||||
|
var source = read(url.openConnection());
|
||||||
|
source = source.replace(/^\#\!.*/, '');
|
||||||
|
source = (
|
||||||
|
"(function (require, exports, module) { " + source + "\n});");
|
||||||
|
cached[id] = {
|
||||||
|
exports: {},
|
||||||
|
module: {
|
||||||
|
id: id,
|
||||||
|
uri: id
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var previousPath = currentPath;
|
||||||
|
try {
|
||||||
|
currentPath = id.substr(0, id.lastIndexOf('/')) || '.';
|
||||||
|
var ctx = org.mozilla.javascript.Context.getCurrentContext();
|
||||||
|
var func = ctx.evaluateString({}, source, id, 1, null);
|
||||||
|
func(require, cached[id].exports, cached[id].module);
|
||||||
|
} finally {
|
||||||
|
currentPath = previousPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
print('returning exports for id: '+id+' '+cached[id].exports);
|
||||||
|
for(var prop in cached[id].exports){
|
||||||
|
print('export: '+prop);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return cached[id].exports;
|
||||||
|
};
|
||||||
|
|
||||||
|
require.paths = paths;
|
||||||
|
|
||||||
|
return require;
|
||||||
|
}());
|
||||||
|
var __argv__ = arguments;
|
||||||
|
require('./platform/rhino');
|
||||||
|
require('./window');
|
|
@ -0,0 +1,72 @@
|
||||||
|
// This file must be executed automatically on startup for ruby/v8 rubyracer support.
|
||||||
|
var __this__ = this;
|
||||||
|
var require = (function() {
|
||||||
|
var cached = {};
|
||||||
|
var currentPath = Ruby.ENV.PWD;
|
||||||
|
var paths = [currentPath];
|
||||||
|
|
||||||
|
/*Ruby.puts("$PROGRAM_NAME " + Ruby.$PROGRAM_NAME)
|
||||||
|
Ruby.puts("Ruby.Config.ruby_version " + Ruby.Config.ruby_version)
|
||||||
|
Ruby.puts("Ruby.File " + Ruby.File)
|
||||||
|
Ruby.puts("Ruby.File.open " + Ruby.File.open)
|
||||||
|
Ruby.puts("Ruby.File equality " + (File === Ruby.File))
|
||||||
|
Ruby.puts("Ruby.File.open() " + Ruby.File.open('/tmp/t.tmp','r').read())*/
|
||||||
|
|
||||||
|
function normalize(id) {
|
||||||
|
var file;
|
||||||
|
id = id + '.js';
|
||||||
|
if (/^\.\.?/.test(id)) {
|
||||||
|
// relative path
|
||||||
|
try{ return fopen(id, 'r') }catch(e){}
|
||||||
|
} else {
|
||||||
|
for (var i = 0, len = paths.length; i < len; ++i) {
|
||||||
|
try{ return fopen(paths[i]+'/'+id, 'r') }catch(e){}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function require(id) {
|
||||||
|
//print('require :'+ id);
|
||||||
|
var file = normalize(id);
|
||||||
|
if (!file) {
|
||||||
|
throw new Error("couldn't find module \"" + id + "\"");
|
||||||
|
}
|
||||||
|
if (!cached.hasOwnProperty(id)) {
|
||||||
|
//print('loading '+id);
|
||||||
|
var source = file.read();
|
||||||
|
source = source.replace(/^\#\!.*/, '');
|
||||||
|
source = "(function (require, exports, module) { "+source+"\n});";
|
||||||
|
cached[id] = {
|
||||||
|
exports: {},
|
||||||
|
module: {
|
||||||
|
id: id,
|
||||||
|
uri: id
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var previousPath = currentPath;
|
||||||
|
try {
|
||||||
|
currentPath = id.substr(0, id.lastIndexOf('/')) || '.';
|
||||||
|
var func = __this__.eval(source);
|
||||||
|
func(require, cached[id].exports, cached[id].module);
|
||||||
|
} finally {
|
||||||
|
currentPath = previousPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
print('returning exports for id: '+id+' '+cached[id].exports);
|
||||||
|
for(var prop in cached[id].exports){
|
||||||
|
print('export: '+prop);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return cached[id].exports;
|
||||||
|
};
|
||||||
|
|
||||||
|
require.paths = paths;
|
||||||
|
|
||||||
|
return require;
|
||||||
|
})();
|
||||||
|
var __argv__ = Ruby.ARGV;
|
||||||
|
require('./platform/rubyracer');
|
||||||
|
require('./window');
|
|
@ -0,0 +1,90 @@
|
||||||
|
require 'v8'
|
||||||
|
require 'net/http'
|
||||||
|
require 'uri'
|
||||||
|
require 'thread'
|
||||||
|
|
||||||
|
include Config
|
||||||
|
|
||||||
|
lock = Mutex.new
|
||||||
|
class Runtime
|
||||||
|
def new_context()
|
||||||
|
V8::Context.new
|
||||||
|
end
|
||||||
|
def configure_context(runtime, context)
|
||||||
|
ruby = {}
|
||||||
|
Module.included_modules.each{|m|
|
||||||
|
#puts "adding module #{m}"
|
||||||
|
ruby[m.to_s] = m
|
||||||
|
}
|
||||||
|
Module.constants.each{|c|
|
||||||
|
#puts "adding constant #{c}"
|
||||||
|
ruby[c.to_s] = Kernel.eval(c)
|
||||||
|
}
|
||||||
|
Kernel.global_variables.each{|g|
|
||||||
|
#puts "adding global variable #{g}"
|
||||||
|
ruby[g.to_s] = Kernel.eval(g)
|
||||||
|
}
|
||||||
|
Kernel.methods.each{|m|
|
||||||
|
#puts "adding global method #{m}"
|
||||||
|
ruby[m.to_s] = Kernel.method(m)
|
||||||
|
}
|
||||||
|
ruby['CONFIG'] = CONFIG
|
||||||
|
ruby['gc'] = lambda{ GC.start() }
|
||||||
|
context['Ruby'] = ruby
|
||||||
|
|
||||||
|
context['__this__'] = context
|
||||||
|
context['File'] = File
|
||||||
|
#context['sync'] = lambda{|fn| Proc.new{|*args|lock.synchronize {fn.call(*args)}} }
|
||||||
|
context['sync'] = lambda{|fn| Proc.new{|*args| fn.call(*args) }}
|
||||||
|
#context['spawn'] = lambda{|fn| Thread.new {fn.call}}
|
||||||
|
context['spawn'] = lambda{|fn| fn.call}
|
||||||
|
context['print'] = lambda{|msg| puts msg}
|
||||||
|
context['fopen'] = lambda{|name, mode| File.open(name, mode)}
|
||||||
|
context['runtime'] = runtime
|
||||||
|
context['new_context'] = lambda{
|
||||||
|
rt = Runtime.new
|
||||||
|
ct = rt.new_context()
|
||||||
|
rt.configure_context(rt, ct)
|
||||||
|
ct['_eval'] = lambda{|script| ct.eval(script)}
|
||||||
|
ct.eval('var t = new Function(); t._eval = __this__._eval;t;')
|
||||||
|
}
|
||||||
|
context['HTTPConnection'] = HTTPConnection.new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class HTTPConnection
|
||||||
|
def connect(host, port)
|
||||||
|
Net::HTTP.start(host, port)
|
||||||
|
end
|
||||||
|
def request(httpMethod, path)
|
||||||
|
case httpMethod
|
||||||
|
when "GET" then return Net::HTTP::Get.new(path)
|
||||||
|
when "PUT" then return Net::HTTP::Put.new(path)
|
||||||
|
when "POST" then return Net::HTTP::Post.new(path)
|
||||||
|
when "HEAD" then return Net::HTTP::Head.new(path)
|
||||||
|
when "DELETE" then return Net::HTTP::Delete.new(path)
|
||||||
|
else return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def go(connection, request, headers, data)
|
||||||
|
headers.each{|key,value| request.add_field(key,value)}
|
||||||
|
response, body = connection.request(request, data)
|
||||||
|
respheaders = Hash.new
|
||||||
|
response.each_header do |name, value|
|
||||||
|
respheaders.store(name, value)
|
||||||
|
end
|
||||||
|
response['body'] = body
|
||||||
|
[response, respheaders]
|
||||||
|
end
|
||||||
|
def finish(connection)
|
||||||
|
connection.finish if connection.started?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
runtime = Runtime.new
|
||||||
|
global = runtime.new_context()
|
||||||
|
runtime.configure_context(runtime, global)
|
||||||
|
envjs = ARGV[0]
|
||||||
|
global.load(envjs)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
// This file must be executed automatically on startup for ruby/v8 rubyracer support.
|
||||||
|
var __this__ = this;
|
||||||
|
var require = (function() {
|
||||||
|
var cached = {};
|
||||||
|
var currentPath = os.getcwd();
|
||||||
|
var paths = [currentPath];
|
||||||
|
|
||||||
|
function normalize(id) {
|
||||||
|
var file;
|
||||||
|
id = id + '.js';
|
||||||
|
if (/^\.\.?/.test(id)) {
|
||||||
|
// relative path
|
||||||
|
try{ return fopen(id, 'r') }catch(e){}
|
||||||
|
} else {
|
||||||
|
for (var i = 0, len = paths.length; i < len; ++i) {
|
||||||
|
try{ return fopen(paths[i]+'/'+id, 'r') }catch(e){}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
function require(id) {
|
||||||
|
//print('require :'+ id);
|
||||||
|
var file = normalize(id);
|
||||||
|
if (!file) {
|
||||||
|
throw new Error("couldn't find module \"" + id + "\"");
|
||||||
|
}
|
||||||
|
if (!cached.hasOwnProperty(id)) {
|
||||||
|
//print('loading '+id);
|
||||||
|
var source = file.read();
|
||||||
|
source = source.replace(/^\#\!.*/, '');
|
||||||
|
source = "(function (require, exports, module) { "+source+"\n});";
|
||||||
|
cached[id] = {
|
||||||
|
exports: {},
|
||||||
|
module: {
|
||||||
|
id: id,
|
||||||
|
uri: id
|
||||||
|
}
|
||||||
|
};
|
||||||
|
var previousPath = currentPath;
|
||||||
|
try {
|
||||||
|
currentPath = id.substr(0, id.lastIndexOf('/')) || '.';
|
||||||
|
var func = global.execute( source );
|
||||||
|
func(require, cached[id].exports, cached[id].module);
|
||||||
|
} finally {
|
||||||
|
currentPath = previousPath;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
print('returning exports for id: '+id+' '+cached[id].exports);
|
||||||
|
for(var prop in cached[id].exports){
|
||||||
|
print('export: '+prop);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
return cached[id].exports;
|
||||||
|
};
|
||||||
|
|
||||||
|
require.paths = paths;
|
||||||
|
|
||||||
|
return require;
|
||||||
|
})();
|
||||||
|
require('./platform/spydermonkey');
|
||||||
|
require('./window');
|
|
@ -0,0 +1,56 @@
|
||||||
|
import spidermonkey
|
||||||
|
import threading
|
||||||
|
import platform
|
||||||
|
import httplib
|
||||||
|
import time
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
runtime = spidermonkey.Runtime()
|
||||||
|
context = runtime.new_context()
|
||||||
|
lock = threading.Lock()
|
||||||
|
|
||||||
|
def load(filename):
|
||||||
|
script = ''
|
||||||
|
f = open(filename, 'r')
|
||||||
|
script = f.read()
|
||||||
|
context.execute(script)
|
||||||
|
|
||||||
|
def _print(string):
|
||||||
|
print string
|
||||||
|
|
||||||
|
def _open(url, mode):
|
||||||
|
return open(url, mode)
|
||||||
|
|
||||||
|
def _exit():
|
||||||
|
return os._exit(1)
|
||||||
|
|
||||||
|
def new_global():
|
||||||
|
nc = runtime.new_context()
|
||||||
|
configure_context(nc)
|
||||||
|
return nc.execute('''
|
||||||
|
this.execute = global.execute;
|
||||||
|
this;
|
||||||
|
''')
|
||||||
|
|
||||||
|
def configure_context(context):
|
||||||
|
context.add_global('os', os)
|
||||||
|
context.add_global('sys', sys)
|
||||||
|
context.add_global('time', time)
|
||||||
|
context.add_global('$lock', lock);
|
||||||
|
context.add_global('exit', _exit)
|
||||||
|
context.add_global('fopen', _open)
|
||||||
|
context.add_global('print', _print)
|
||||||
|
context.add_global('httplib', httplib)
|
||||||
|
context.add_global('platform', platform)
|
||||||
|
context.add_global('threading', threading)
|
||||||
|
context.add_global('global', context)
|
||||||
|
context.add_global('runtime', runtime)
|
||||||
|
context.add_global('new_global', new_global)
|
||||||
|
|
||||||
|
configure_context(context)
|
||||||
|
|
||||||
|
if __name__=='__main__':
|
||||||
|
argv = sys.argv
|
||||||
|
if os.path.isfile( argv[1] ):
|
||||||
|
load(argv[1])
|
|
@ -0,0 +1,94 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Envjs timer.1.3.pre03
|
||||||
|
* Pure JavaScript Browser Environment
|
||||||
|
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||||
|
* Copyright 2008-2010 John Resig, under the MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
//CLOSURE_START
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Envjs timer.1.3.pre03
|
||||||
|
* Pure JavaScript Browser Environment
|
||||||
|
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||||
|
* Copyright 2008-2010 John Resig, under the MIT License
|
||||||
|
*
|
||||||
|
* Parts of the implementation were originally written by:\
|
||||||
|
* Steven Parkes
|
||||||
|
*
|
||||||
|
* requires Envjs.wait, Envjs.sleep, Envjs.WAIT_INTERVAL
|
||||||
|
|
||||||
|
This module leaks the following global definitions.
|
||||||
|
|
||||||
|
var setTimeout,
|
||||||
|
clearTimeout,
|
||||||
|
setInterval,
|
||||||
|
clearInterval;
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Envjs = require('./platform/core').Envjs;
|
||||||
|
/*
|
||||||
|
* - timer.js
|
||||||
|
*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.Timer').
|
||||||
|
debug('timer logger available');
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function setTimeout
|
||||||
|
* @param {Object} fn
|
||||||
|
* @param {Object} time
|
||||||
|
*/
|
||||||
|
exports.setTimeout = setTimeout = function(fn, time){
|
||||||
|
log.debug('setTimeout %s', time);
|
||||||
|
return Envjs.timers.addTimerOrInterval(fn, time, 'timeout');
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clearTimeout
|
||||||
|
* @param {Object} id
|
||||||
|
*/
|
||||||
|
exports.clearTimeout = clearTimeout = function(id){
|
||||||
|
log.debug('clearTimeout %s', id);
|
||||||
|
return Envjs.timers.removeTimerOrInterval(id, 'timeout');
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @function setInterval
|
||||||
|
* @param {Object} fn
|
||||||
|
* @param {Object} time
|
||||||
|
*/
|
||||||
|
exports.setInterval = setInterval = function(fn, time){
|
||||||
|
log.debug('setInterval %s', time);
|
||||||
|
return Envjs.timers.addTimerOrInterval(fn, time, 'interval');
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* clearInterval
|
||||||
|
* @param {Object} id
|
||||||
|
*/
|
||||||
|
exports.clearInterval = clearInterval = function(id){
|
||||||
|
log.debug('clearInterval %s', id);
|
||||||
|
return Envjs.timers.removeTimerOrInterval(id, 'interval');
|
||||||
|
};
|
||||||
|
|
||||||
|
}(/*Timer*/));
|
||||||
|
/**
|
||||||
|
* @author john resig & the envjs team
|
||||||
|
* @uri http://www.envjs.com/
|
||||||
|
* @copyright 2008-2010
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
//CLOSURE_END
|
||||||
|
}());
|
|
@ -0,0 +1,864 @@
|
||||||
|
/*
|
||||||
|
* Envjs window.1.3.pre03
|
||||||
|
* Pure JavaScript Browser Environment
|
||||||
|
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||||
|
* Copyright 2008-2010 John Resig, under the MIT License
|
||||||
|
|
||||||
|
This module leaks the following global definitions.
|
||||||
|
|
||||||
|
var Window,
|
||||||
|
Screen,
|
||||||
|
History,
|
||||||
|
Navigator;
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Envjs = Envjs || require('./platform/core').Envjs,
|
||||||
|
DOMImplementation = DOMImplementation || require('./dom').DOMImplementation,
|
||||||
|
HTMLDocument = HTMLDocument || require('./html').HTMLDocument,
|
||||||
|
HTMLFrameElement = HTMLFrameElement || require('./html').HTMLFrameElement,
|
||||||
|
HTMLIFrameElement = HTMLIFrameElement || require('./html').HTMLIFrameElement,
|
||||||
|
HTMLParser = HTMLParser || require('./parser').HTMLParser,
|
||||||
|
Location = Location || require('./xhr').Location,
|
||||||
|
CSSRule = CSSRule || require('./css').CSSRule;
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Envjs window.1.3.pre03
|
||||||
|
* Pure JavaScript Browser Environment
|
||||||
|
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||||
|
* Copyright 2008-2010 John Resig, under the MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
//CLOSURE_START
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author john resig
|
||||||
|
*/
|
||||||
|
// Helper method for extending one object with another.
|
||||||
|
function __extend__(a,b) {
|
||||||
|
for ( var i in b ) {
|
||||||
|
if(b.hasOwnProperty(i)){
|
||||||
|
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
|
||||||
|
if ( g || s ) {
|
||||||
|
if ( g ) { a.__defineGetter__(i, g); }
|
||||||
|
if ( s ) { a.__defineSetter__(i, s); }
|
||||||
|
} else {
|
||||||
|
a[i] = b[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Frame/Window Mixin
|
||||||
|
*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.HTML.Frame').
|
||||||
|
debug('html frame logger available');
|
||||||
|
});
|
||||||
|
|
||||||
|
__extend__(HTMLFrameElement.prototype,{
|
||||||
|
|
||||||
|
set src(value){
|
||||||
|
var event;
|
||||||
|
this.setAttribute('src', value);
|
||||||
|
//only load if we are already appended to the dom
|
||||||
|
if (this.parentNode && value && value.length > 0){
|
||||||
|
log.debug('loading frame via set src %s', value);
|
||||||
|
Envjs.loadFrame(this, Envjs.uri(value, this.ownerDocument?this.ownerDocument.location+'':null));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
__extend__(HTMLIFrameElement.prototype, HTMLFrameElement.prototype);
|
||||||
|
|
||||||
|
}(/*Frame/Window Mixin*/));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: Document the History object via HTML5 spec
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.Window.History').
|
||||||
|
debug('history logger available');
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.History = History = function(owner) {
|
||||||
|
var $current = 0,
|
||||||
|
$history = [null],
|
||||||
|
$owner = owner;
|
||||||
|
|
||||||
|
return {
|
||||||
|
go : function(target) {
|
||||||
|
if (typeof target === "number") {
|
||||||
|
target = $current + target;
|
||||||
|
if (target > -1 && target < $history.length){
|
||||||
|
if ($history[target].type === "hash") {
|
||||||
|
if ($owner.location) {
|
||||||
|
$owner.location.hash = $history[target].value;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($owner.location) {
|
||||||
|
$owner.location = $history[target].value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$current = target;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//TODO: walk through the history and find the 'best match'?
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
get length() {
|
||||||
|
return $history.length;
|
||||||
|
},
|
||||||
|
|
||||||
|
back : function(count) {
|
||||||
|
if (count) {
|
||||||
|
this.go(-count);
|
||||||
|
} else {
|
||||||
|
this.go(-1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
get current() {
|
||||||
|
return this.item($current);
|
||||||
|
},
|
||||||
|
|
||||||
|
get previous() {
|
||||||
|
return this.item($current-1);
|
||||||
|
},
|
||||||
|
|
||||||
|
forward : function(count) {
|
||||||
|
if (count) {
|
||||||
|
this.go(count);
|
||||||
|
} else {
|
||||||
|
this.go(1);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
item: function(idx) {
|
||||||
|
if (idx >= 0 && idx < $history.length) {
|
||||||
|
return $history[idx];
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
add: function(newLocation, type) {
|
||||||
|
//not a standard interface, we expose it to simplify
|
||||||
|
//history state modifications
|
||||||
|
if (newLocation !== $history[$current]) {
|
||||||
|
$history.slice(0, $current);
|
||||||
|
$history.push({
|
||||||
|
type: type || 'href',
|
||||||
|
value: newLocation
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}(/*History*/));
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* navigator.js
|
||||||
|
* Browser Navigator
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.Window.Navigator').
|
||||||
|
debug('window navigator logger available');
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.Navigator = Navigator = function(){
|
||||||
|
var $userAgent;
|
||||||
|
return {
|
||||||
|
get appCodeName(){
|
||||||
|
return Envjs.appCodeName;
|
||||||
|
},
|
||||||
|
get appName(){
|
||||||
|
return Envjs.appName;
|
||||||
|
},
|
||||||
|
get appVersion(){
|
||||||
|
return Envjs.version +" ("+
|
||||||
|
this.platform +"; "+
|
||||||
|
"U; "+//?
|
||||||
|
Envjs.os_name+" "+Envjs.os_arch+" "+Envjs.os_version+"; "+
|
||||||
|
(Envjs.lang?Envjs.lang:"en-US")+"; "+
|
||||||
|
"rv:"+Envjs.revision+
|
||||||
|
")";
|
||||||
|
},
|
||||||
|
get cookieEnabled(){
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
get mimeTypes(){
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
get platform(){
|
||||||
|
return Envjs.platform;
|
||||||
|
},
|
||||||
|
get plugins(){
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
get userAgent(){
|
||||||
|
return $userAgent||(this.appCodeName + "/" + this.appVersion + " Resig/20070309 PilotFish/1.3.pre03");
|
||||||
|
},
|
||||||
|
set userAgent(agent){
|
||||||
|
if(agent){
|
||||||
|
$userAgent = agent;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
javaEnabled : function(){
|
||||||
|
return Envjs.javaEnabled;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}());
|
||||||
|
/**
|
||||||
|
* Screen
|
||||||
|
* @param {Object} __window__
|
||||||
|
*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.Window.Screen').
|
||||||
|
debug('window screen logger available');
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.Screen = Screen = function(__window__){
|
||||||
|
|
||||||
|
var $availHeight = 600,
|
||||||
|
$availWidth = 800,
|
||||||
|
$colorDepth = 16,
|
||||||
|
$pixelDepth = 24,
|
||||||
|
$height = 600,
|
||||||
|
$width = 800,
|
||||||
|
$top = 0,
|
||||||
|
$left = 0,
|
||||||
|
$availTop = 0,
|
||||||
|
$availLeft = 0;
|
||||||
|
|
||||||
|
log.debug('extending window with screen properties');
|
||||||
|
__extend__( __window__, {
|
||||||
|
moveBy : function(dx,dy){
|
||||||
|
//TODO - modify $locals to reflect change
|
||||||
|
},
|
||||||
|
moveTo : function(x,y) {
|
||||||
|
//TODO - modify $locals to reflect change
|
||||||
|
},
|
||||||
|
/*print : function(){
|
||||||
|
//TODO - good global to modify to ensure print is not misused
|
||||||
|
};*/
|
||||||
|
resizeBy : function(dw, dh){
|
||||||
|
__window__.resizeTo($width + dw, $height + dh);
|
||||||
|
},
|
||||||
|
resizeTo : function(width, height){
|
||||||
|
$width = (width <= $availWidth) ? width : $availWidth;
|
||||||
|
$height = (height <= $availHeight) ? height : $availHeight;
|
||||||
|
},
|
||||||
|
scroll : function(x,y){
|
||||||
|
//TODO - modify $locals to reflect change
|
||||||
|
},
|
||||||
|
scrollBy : function(dx, dy){
|
||||||
|
//TODO - modify $locals to reflect change
|
||||||
|
},
|
||||||
|
scrollTo : function(x,y){
|
||||||
|
//TODO - modify $locals to reflect change
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
log.debug('creating screen');
|
||||||
|
return {
|
||||||
|
get top(){
|
||||||
|
return $top;
|
||||||
|
},
|
||||||
|
get left(){
|
||||||
|
return $left;
|
||||||
|
},
|
||||||
|
get availTop(){
|
||||||
|
return $availTop;
|
||||||
|
},
|
||||||
|
get availLeft(){
|
||||||
|
return $availLeft;
|
||||||
|
},
|
||||||
|
get availHeight(){
|
||||||
|
return $availHeight;
|
||||||
|
},
|
||||||
|
get availWidth(){
|
||||||
|
return $availWidth;
|
||||||
|
},
|
||||||
|
get colorDepth(){
|
||||||
|
return $colorDepth;
|
||||||
|
},
|
||||||
|
get pixelDepth(){
|
||||||
|
return $pixelDepth;
|
||||||
|
},
|
||||||
|
get height(){
|
||||||
|
return $height;
|
||||||
|
},
|
||||||
|
get width(){
|
||||||
|
return $width;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}(/*Screen*/));
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010 Nick Galbreath
|
||||||
|
* http://code.google.com/p/stringencoders/source/browse/#svn/trunk/javascript
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following
|
||||||
|
* conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* base64 encode/decode compatible with window.btoa/atob
|
||||||
|
*
|
||||||
|
* window.atob/btoa is a Firefox extension to convert binary data (the "b")
|
||||||
|
* to base64 (ascii, the "a").
|
||||||
|
*
|
||||||
|
* It is also found in Safari and Chrome. It is not available in IE.
|
||||||
|
*
|
||||||
|
* if (!window.btoa) window.btoa = base64.encode
|
||||||
|
* if (!window.atob) window.atob = base64.decode
|
||||||
|
*
|
||||||
|
* The original spec's for atob/btoa are a bit lacking
|
||||||
|
* https://developer.mozilla.org/en/DOM/window.atob
|
||||||
|
* https://developer.mozilla.org/en/DOM/window.btoa
|
||||||
|
*
|
||||||
|
* window.btoa and base64.encode takes a string where charCodeAt is [0,255]
|
||||||
|
* If any character is not [0,255], then an DOMException(5) is thrown.
|
||||||
|
*
|
||||||
|
* window.atob and base64.decode take a base64-encoded string
|
||||||
|
* If the input length is not a multiple of 4, or contains invalid characters
|
||||||
|
* then an DOMException(5) is thrown.
|
||||||
|
*/
|
||||||
|
var base64 = {};
|
||||||
|
base64.PADCHAR = '=';
|
||||||
|
base64.ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||||
|
|
||||||
|
base64.makeDOMException = function() {
|
||||||
|
// sadly in FF,Safari,Chrome you can't make a DOMException
|
||||||
|
var e;
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new DOMException(DOMException.INVALID_CHARACTER_ERR);
|
||||||
|
} catch (tmp) {
|
||||||
|
// not available, just passback a duck-typed equiv
|
||||||
|
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error
|
||||||
|
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Error/prototype
|
||||||
|
var ex = new Error("DOM Exception 5");
|
||||||
|
|
||||||
|
// ex.number and ex.description is IE-specific.
|
||||||
|
ex.code = ex.number = 5;
|
||||||
|
ex.name = ex.description = "INVALID_CHARACTER_ERR";
|
||||||
|
|
||||||
|
// Safari/Chrome output format
|
||||||
|
ex.toString = function() { return 'Error: ' + ex.name + ': ' + ex.message; };
|
||||||
|
return ex;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
base64.getbyte64 = function(s,i) {
|
||||||
|
// This is oddly fast, except on Chrome/V8.
|
||||||
|
// Minimal or no improvement in performance by using a
|
||||||
|
// object with properties mapping chars to value (eg. 'A': 0)
|
||||||
|
var idx = base64.ALPHA.indexOf(s.charAt(i));
|
||||||
|
if (idx === -1) {
|
||||||
|
throw base64.makeDOMException();
|
||||||
|
}
|
||||||
|
return idx;
|
||||||
|
};
|
||||||
|
|
||||||
|
base64.decode = function(s) {
|
||||||
|
// convert to string
|
||||||
|
s = '' + s;
|
||||||
|
var getbyte64 = base64.getbyte64;
|
||||||
|
var pads, i, b10;
|
||||||
|
var imax = s.length;
|
||||||
|
if (imax === 0) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imax % 4 !== 0) {
|
||||||
|
throw base64.makeDOMException();
|
||||||
|
}
|
||||||
|
|
||||||
|
pads = 0;
|
||||||
|
if (s.charAt(imax - 1) === base64.PADCHAR) {
|
||||||
|
pads = 1;
|
||||||
|
if (s.charAt(imax - 2) === base64.PADCHAR) {
|
||||||
|
pads = 2;
|
||||||
|
}
|
||||||
|
// either way, we want to ignore this last block
|
||||||
|
imax -= 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
var x = [];
|
||||||
|
for (i = 0; i < imax; i += 4) {
|
||||||
|
b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) |
|
||||||
|
(getbyte64(s,i+2) << 6) | getbyte64(s,i+3);
|
||||||
|
x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff, b10 & 0xff));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (pads) {
|
||||||
|
case 1:
|
||||||
|
b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12) | (getbyte64(s,i+2) << 6);
|
||||||
|
x.push(String.fromCharCode(b10 >> 16, (b10 >> 8) & 0xff));
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
b10 = (getbyte64(s,i) << 18) | (getbyte64(s,i+1) << 12);
|
||||||
|
x.push(String.fromCharCode(b10 >> 16));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return x.join('');
|
||||||
|
};
|
||||||
|
|
||||||
|
base64.getbyte = function(s,i) {
|
||||||
|
var x = s.charCodeAt(i);
|
||||||
|
if (x > 255) {
|
||||||
|
throw base64.makeDOMException();
|
||||||
|
}
|
||||||
|
return x;
|
||||||
|
};
|
||||||
|
|
||||||
|
base64.encode = function(s) {
|
||||||
|
if (arguments.length !== 1) {
|
||||||
|
throw new SyntaxError("Not enough arguments");
|
||||||
|
}
|
||||||
|
var padchar = base64.PADCHAR;
|
||||||
|
var alpha = base64.ALPHA;
|
||||||
|
var getbyte = base64.getbyte;
|
||||||
|
|
||||||
|
var i, b10;
|
||||||
|
var x = [];
|
||||||
|
|
||||||
|
// convert to string
|
||||||
|
s = '' + s;
|
||||||
|
|
||||||
|
var imax = s.length - s.length % 3;
|
||||||
|
|
||||||
|
if (s.length === 0) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
for (i = 0; i < imax; i += 3) {
|
||||||
|
b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8) | getbyte(s,i+2);
|
||||||
|
x.push(alpha.charAt(b10 >> 18));
|
||||||
|
x.push(alpha.charAt((b10 >> 12) & 0x3F));
|
||||||
|
x.push(alpha.charAt((b10 >> 6) & 0x3f));
|
||||||
|
x.push(alpha.charAt(b10 & 0x3f));
|
||||||
|
}
|
||||||
|
switch (s.length - imax) {
|
||||||
|
case 1:
|
||||||
|
b10 = getbyte(s,i) << 16;
|
||||||
|
x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) +
|
||||||
|
padchar + padchar);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
b10 = (getbyte(s,i) << 16) | (getbyte(s,i+1) << 8);
|
||||||
|
x.push(alpha.charAt(b10 >> 18) + alpha.charAt((b10 >> 12) & 0x3F) +
|
||||||
|
alpha.charAt((b10 >> 6) & 0x3f) + padchar);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return x.join('');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger('Envjs.Window');
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.Window').
|
||||||
|
debug('window logger available');
|
||||||
|
});
|
||||||
|
|
||||||
|
//These descriptions of window properties are taken loosely David Flanagan's
|
||||||
|
//'JavaScript - The Definitive Guide' (O'Reilly)
|
||||||
|
|
||||||
|
var __top__ = function(_scope){
|
||||||
|
var _parent = _scope.parent;
|
||||||
|
while (_scope && _parent && _scope !== _parent) {
|
||||||
|
if (_parent === _parent.parent) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
_parent = _parent.parent;
|
||||||
|
//console.log('scope %s _parent %s', scope, _parent);
|
||||||
|
}
|
||||||
|
return _parent || null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Window
|
||||||
|
* @param {Object} scope
|
||||||
|
* @param {Object} parent
|
||||||
|
* @param {Object} opener
|
||||||
|
*/
|
||||||
|
exports.Window = Window = function(scope, parent, opener){
|
||||||
|
|
||||||
|
if(!scope){
|
||||||
|
scope = __this__;
|
||||||
|
}
|
||||||
|
if(!parent){
|
||||||
|
parent = scope;
|
||||||
|
}
|
||||||
|
// the window property is identical to the self property and to this obj
|
||||||
|
scope.__defineGetter__('window', function(){
|
||||||
|
return scope;
|
||||||
|
});
|
||||||
|
|
||||||
|
var $uuid = new Date().getTime()+'-'+Math.floor(Math.random()*1000000000000000);
|
||||||
|
Envjs.windows($uuid, scope);
|
||||||
|
//log.debug('opening window %s', $uuid);
|
||||||
|
|
||||||
|
// every window has one-and-only-one .document property which is always
|
||||||
|
// an [object HTMLDocument]. also, only window.document objects are
|
||||||
|
// html documents, all other documents created by the window.document are
|
||||||
|
// [object XMLDocument]
|
||||||
|
var $htmlImplementation = new DOMImplementation();
|
||||||
|
$htmlImplementation.namespaceAware = true;
|
||||||
|
$htmlImplementation.errorChecking = false;
|
||||||
|
|
||||||
|
// read only reference to the Document object
|
||||||
|
var $document = new HTMLDocument($htmlImplementation, scope);
|
||||||
|
|
||||||
|
// A read-only reference to the Window object that contains this window
|
||||||
|
// or frame. If the window is a top-level window, parent refers to
|
||||||
|
// the window itself. If this window is a frame, this property refers
|
||||||
|
// to the window or frame that contains it.
|
||||||
|
var $parent = parent;
|
||||||
|
|
||||||
|
/**> $cookies - see cookie.js <*/
|
||||||
|
// read only boolean specifies whether the window has been closed
|
||||||
|
var $closed = false;
|
||||||
|
|
||||||
|
// a read/write string that specifies the default message that
|
||||||
|
// appears in the status line
|
||||||
|
var $defaultStatus = "Done";
|
||||||
|
|
||||||
|
// IE only, refers to the most recent event object - this maybe be
|
||||||
|
// removed after review
|
||||||
|
var $event = null;
|
||||||
|
|
||||||
|
// a read-only reference to the History object
|
||||||
|
var $history = new History();
|
||||||
|
|
||||||
|
// a read-only reference to the Location object. the location object does
|
||||||
|
// expose read/write properties
|
||||||
|
var $location = new Location('about:blank', $document, $history);
|
||||||
|
|
||||||
|
// The name of window/frame. Set directly, when using open(), or in frameset.
|
||||||
|
// May be used when specifying the target attribute of links
|
||||||
|
var $name = null;
|
||||||
|
|
||||||
|
// a read-only reference to the Navigator object
|
||||||
|
var $navigator = new Navigator();
|
||||||
|
|
||||||
|
// a read/write reference to the Window object that contained the script
|
||||||
|
// that called open() to open this browser window. This property is valid
|
||||||
|
// only for top-level window objects.
|
||||||
|
var $opener = opener?opener:null;
|
||||||
|
|
||||||
|
// read-only properties that specify the height and width, in pixels
|
||||||
|
var $innerHeight = 600, $innerWidth = 800;
|
||||||
|
|
||||||
|
// Read-only properties that specify the total height and width, in pixels,
|
||||||
|
// of the browser window. These dimensions include the height and width of
|
||||||
|
// the menu bar, toolbars, scrollbars, window borders and so on. These
|
||||||
|
// properties are not supported by IE and IE offers no alternative
|
||||||
|
// properties;
|
||||||
|
var $outerHeight = $innerHeight,
|
||||||
|
$outerWidth = $innerWidth;
|
||||||
|
|
||||||
|
// Read-only properties that specify the number of pixels that the current
|
||||||
|
// document has been scrolled to the right and down. These are not
|
||||||
|
// supported by IE.
|
||||||
|
var $pageXOffset = 0, $pageYOffset = 0;
|
||||||
|
|
||||||
|
// a read-only reference to the Screen object that specifies information
|
||||||
|
// about the screen: the number of available pixels and the number of
|
||||||
|
// available colors.
|
||||||
|
var $screen = new Screen(scope);
|
||||||
|
|
||||||
|
// read only properties that specify the coordinates of the upper-left
|
||||||
|
// corner of the screen.
|
||||||
|
var $screenX = 1,
|
||||||
|
$screenY = 1;
|
||||||
|
var $screenLeft = $screenX,
|
||||||
|
$screenTop = $screenY;
|
||||||
|
|
||||||
|
// a read/write string that specifies the current status line.
|
||||||
|
var $status = '';
|
||||||
|
__extend__(scope, EventTarget.prototype);
|
||||||
|
|
||||||
|
return __extend__( scope, {
|
||||||
|
get closed(){
|
||||||
|
return $closed;
|
||||||
|
},
|
||||||
|
get defaultStatus(){
|
||||||
|
return $defaultStatus;
|
||||||
|
},
|
||||||
|
set defaultStatus(defaultStatus){
|
||||||
|
$defaultStatus = defaultStatus;
|
||||||
|
},
|
||||||
|
get document(){
|
||||||
|
return $document;
|
||||||
|
},
|
||||||
|
set document(doc){
|
||||||
|
$document = doc;
|
||||||
|
},
|
||||||
|
/*
|
||||||
|
deprecated ie specific property probably not good to support
|
||||||
|
get event(){
|
||||||
|
return $event;
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
get frames(){
|
||||||
|
return $document.getElementsByTagName('frame');
|
||||||
|
},
|
||||||
|
get length(){
|
||||||
|
// should be frames.length,
|
||||||
|
return this.frames.length;
|
||||||
|
},
|
||||||
|
get history(){
|
||||||
|
return $history;
|
||||||
|
},
|
||||||
|
get innerHeight(){
|
||||||
|
return $innerHeight;
|
||||||
|
},
|
||||||
|
get innerWidth(){
|
||||||
|
return $innerWidth;
|
||||||
|
},
|
||||||
|
get clientHeight(){
|
||||||
|
return $innerHeight;
|
||||||
|
},
|
||||||
|
get clientWidth(){
|
||||||
|
return $innerWidth;
|
||||||
|
},
|
||||||
|
get location(){
|
||||||
|
return $location;
|
||||||
|
},
|
||||||
|
set location(url){
|
||||||
|
//very important or you will go into an infinite
|
||||||
|
//loop when creating a xml document
|
||||||
|
log.debug('setting window location %s', url);
|
||||||
|
if(url) {
|
||||||
|
$location.assign(Envjs.uri(url, $location+''));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get name(){
|
||||||
|
return $name;
|
||||||
|
},
|
||||||
|
set name(newName){
|
||||||
|
$name = newName;
|
||||||
|
},
|
||||||
|
get navigator(){
|
||||||
|
return $navigator;
|
||||||
|
},
|
||||||
|
get opener(){
|
||||||
|
return $opener;
|
||||||
|
},
|
||||||
|
get outerHeight(){
|
||||||
|
return $outerHeight;
|
||||||
|
},
|
||||||
|
get outerWidth(){
|
||||||
|
return $outerWidth;
|
||||||
|
},
|
||||||
|
get pageXOffest(){
|
||||||
|
return $pageXOffset;
|
||||||
|
},
|
||||||
|
get pageYOffset(){
|
||||||
|
return $pageYOffset;
|
||||||
|
},
|
||||||
|
get parent(){
|
||||||
|
return $parent;
|
||||||
|
},
|
||||||
|
get screen(){
|
||||||
|
return $screen;
|
||||||
|
},
|
||||||
|
get screenLeft(){
|
||||||
|
return $screenLeft;
|
||||||
|
},
|
||||||
|
get screenTop(){
|
||||||
|
return $screenTop;
|
||||||
|
},
|
||||||
|
get screenX(){
|
||||||
|
return $screenX;
|
||||||
|
},
|
||||||
|
get screenY(){
|
||||||
|
return $screenY;
|
||||||
|
},
|
||||||
|
get self(){
|
||||||
|
return scope;
|
||||||
|
},
|
||||||
|
get status(){
|
||||||
|
return $status;
|
||||||
|
},
|
||||||
|
set status(status){
|
||||||
|
$status = status;
|
||||||
|
},
|
||||||
|
// a read-only reference to the top-level window that contains this window.
|
||||||
|
// If this window is a top-level window it is simply a reference to itself.
|
||||||
|
// If this window is a frame, the top property refers to the top-level
|
||||||
|
// window that contains the frame.
|
||||||
|
get top(){
|
||||||
|
return __top__(scope);
|
||||||
|
},
|
||||||
|
get window(){
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
toString : function(){
|
||||||
|
return '[Window]';
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getComputedStyle
|
||||||
|
*
|
||||||
|
* Firefox 3.6:
|
||||||
|
* - Requires both elements to be present else an
|
||||||
|
* exception is thrown.
|
||||||
|
* - Returns a 'ComputedCSSStyleDeclaration' object.
|
||||||
|
* while a raw element.style returns a 'CSSStyleDeclaration' object.
|
||||||
|
* - Bogus input also throws exception
|
||||||
|
*
|
||||||
|
* Safari 4:
|
||||||
|
* - Requires one argument (second can be MIA)
|
||||||
|
* - Returns a CSSStyleDeclaration object
|
||||||
|
* - if bad imput, returns null
|
||||||
|
*
|
||||||
|
* getComputedStyle should really be an "add on" from the css
|
||||||
|
* modules. Unfortunately, 'window' comes way after the 'css'
|
||||||
|
* so css can't add it.
|
||||||
|
*/
|
||||||
|
getComputedStyle: function(element, pseudoElement) {
|
||||||
|
return element.style;
|
||||||
|
},
|
||||||
|
|
||||||
|
open: function(url, name, features, replace){
|
||||||
|
if (features) {
|
||||||
|
console.log("'features argument not yet implemented");
|
||||||
|
}
|
||||||
|
var _window = Envjs.proxy({}),
|
||||||
|
open;
|
||||||
|
if(replace && name){
|
||||||
|
for(open in Envjs.windows()){
|
||||||
|
if(open.name === name) {
|
||||||
|
_window = open;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var w = new Window(_window, _window, this);
|
||||||
|
if(name) {
|
||||||
|
_window.name = name;
|
||||||
|
}
|
||||||
|
_window.document.async = false;
|
||||||
|
_window.document.location.assign(Envjs.uri(url));
|
||||||
|
return _window;
|
||||||
|
},
|
||||||
|
close: function(){
|
||||||
|
log.debug('closing window %s', $uuid);
|
||||||
|
var frames = $document.getElementsByTagName('frame'),
|
||||||
|
iframes = $document.getElementsByTagName('iframe'),
|
||||||
|
i;
|
||||||
|
for(i=0;i<frames.length;i++){
|
||||||
|
Envjs.unloadFrame(frames[i]);
|
||||||
|
}
|
||||||
|
for(i=0;i<iframes.length;i++){
|
||||||
|
Envjs.unloadFrame(iframes[i]);
|
||||||
|
}
|
||||||
|
try{
|
||||||
|
Envjs.windows($uuid, null);
|
||||||
|
}catch(e){
|
||||||
|
log.error('%s',e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
alert : function(message){
|
||||||
|
Envjs.alert(message);
|
||||||
|
},
|
||||||
|
confirm : function(question){
|
||||||
|
Envjs.confirm(question);
|
||||||
|
},
|
||||||
|
prompt : function(message, defaultMsg){
|
||||||
|
Envjs.prompt(message, defaultMsg);
|
||||||
|
},
|
||||||
|
btoa: function(binary){
|
||||||
|
return base64.encode(binary);
|
||||||
|
},
|
||||||
|
atob: function(ascii){
|
||||||
|
return base64.decode(ascii);
|
||||||
|
},
|
||||||
|
//these should be undefined on instantiation
|
||||||
|
//onload: function(){},
|
||||||
|
//onunload: function(){},
|
||||||
|
focus: function(){},
|
||||||
|
blur: function(){},
|
||||||
|
get guid(){
|
||||||
|
return $uuid;
|
||||||
|
},
|
||||||
|
set guid(_guid){
|
||||||
|
$uuid = _guid;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
//console.log('scheduling default window creation');
|
||||||
|
setTimeout(function(){
|
||||||
|
var w = new Window(__this__);
|
||||||
|
log.info('[ %s ]', window.navigator.userAgent);
|
||||||
|
},1);
|
||||||
|
|
||||||
|
}(/*Window*/));
|
||||||
|
|
||||||
|
|
||||||
|
//console.log('starting Envjs.eventLoop');
|
||||||
|
Envjs.eventLoop();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author john resig & the envjs team
|
||||||
|
* @uri http://www.envjs.com/
|
||||||
|
* @copyright 2008-2010
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
//CLOSURE_END
|
||||||
|
}());
|
|
@ -0,0 +1,566 @@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Envjs xhr.1.3.pre03
|
||||||
|
* Pure JavaScript Browser Environment
|
||||||
|
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||||
|
* Copyright 2008-2010 John Resig, under the MIT License
|
||||||
|
*/
|
||||||
|
|
||||||
|
//CLOSURE_START
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Envjs xhr.1.3.pre03
|
||||||
|
* Pure JavaScript Browser Environment
|
||||||
|
* By John Resig <http://ejohn.org/> and the Envjs Team
|
||||||
|
* Copyright 2008-2010 John Resig, under the MIT License
|
||||||
|
*
|
||||||
|
* Parts of the implementation originally written by Yehuda Katz.
|
||||||
|
*
|
||||||
|
* This file simply provides the global definitions we need to
|
||||||
|
* be able to correctly implement to core browser (XML)HTTPRequest
|
||||||
|
* interfaces.
|
||||||
|
|
||||||
|
This module leaks the following global definitions.
|
||||||
|
|
||||||
|
var Location,
|
||||||
|
XMLHttpRequest;
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
var Envjs = Envjs || require('./platform/core').Envjs,
|
||||||
|
Document = Document || require('./dom').Document;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author john resig
|
||||||
|
*/
|
||||||
|
// Helper method for extending one object with another.
|
||||||
|
function __extend__(a,b) {
|
||||||
|
for ( var i in b ) {
|
||||||
|
if(b.hasOwnProperty(i)){
|
||||||
|
var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
|
||||||
|
if ( g || s ) {
|
||||||
|
if ( g ) { a.__defineGetter__(i, g); }
|
||||||
|
if ( s ) { a.__defineSetter__(i, s); }
|
||||||
|
} else {
|
||||||
|
a[i] = b[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* These functions require network IO provided by XMLHttpRequest
|
||||||
|
*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.DOM.Document').
|
||||||
|
info('doc logger available');
|
||||||
|
});
|
||||||
|
|
||||||
|
__extend__(Document.prototype,{
|
||||||
|
load: function(url){
|
||||||
|
if(this.documentURI == 'about:html'){
|
||||||
|
this.location.assign(url);
|
||||||
|
}else if(this.documentURI == url){
|
||||||
|
this.location.reload(false);
|
||||||
|
}else{
|
||||||
|
this.location.replace(url);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
get location(){
|
||||||
|
return this.ownerWindow.location;
|
||||||
|
},
|
||||||
|
set location(url){
|
||||||
|
//very important or you will go into an infinite
|
||||||
|
//loop when creating a xml document
|
||||||
|
this.ownerWindow.location = url;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}(/*Document/Location Mixin*/));
|
||||||
|
/**
|
||||||
|
* Location
|
||||||
|
*
|
||||||
|
* Mozilla MDC:
|
||||||
|
* https://developer.mozilla.org/En/DOM/Window.location
|
||||||
|
* https://developer.mozilla.org/en/DOM/document.location
|
||||||
|
*
|
||||||
|
* HTML5: 6.10.4 The Location interface
|
||||||
|
* http://dev.w3.org/html5/spec/Overview.html#location
|
||||||
|
*
|
||||||
|
* HTML5: 2.5.3 Interfaces for URL manipulation
|
||||||
|
* http://dev.w3.org/html5/spec/Overview.html#url-decomposition-idl-attributes
|
||||||
|
* All of section 2.5 is worth reading, but 2.5.3 contains very
|
||||||
|
* detailed information on how getters/setter should work
|
||||||
|
*
|
||||||
|
* NOT IMPLEMENTED:
|
||||||
|
* HTML5: Section 6.10.4.1 Security -- prevents scripts from another domain
|
||||||
|
* from accessing most of the 'Location'
|
||||||
|
* Not sure if anyone implements this in HTML4
|
||||||
|
*/
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
var log = Envjs.logger();
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.Location').
|
||||||
|
debug('location logger available');
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.Location = Location = function(url, doc, history) {
|
||||||
|
log = log||Envjs.logger('Envjs.Location');
|
||||||
|
log.debug('Location url %s', url);
|
||||||
|
var $url = url,
|
||||||
|
$document = doc ? doc : null,
|
||||||
|
$history = history ? history : null;
|
||||||
|
|
||||||
|
var parts = Envjs.urlsplit($url);
|
||||||
|
|
||||||
|
return {
|
||||||
|
get hash() {
|
||||||
|
return parts.fragment ? '#' + parts.fragment : parts.fragment;
|
||||||
|
},
|
||||||
|
set hash(s) {
|
||||||
|
if (s[0] === '#') {
|
||||||
|
parts.fragment = s.substr(1);
|
||||||
|
} else {
|
||||||
|
parts.fragment = s;
|
||||||
|
}
|
||||||
|
$url = Envjs.urlunsplit(parts);
|
||||||
|
if ($history) {
|
||||||
|
$history.add($url, 'hash');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
get host() {
|
||||||
|
return parts.netloc;
|
||||||
|
},
|
||||||
|
set host(s) {
|
||||||
|
if (!s || s === '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
parts.netloc = s;
|
||||||
|
$url = Envjs.urlunsplit(parts);
|
||||||
|
|
||||||
|
// this regenerates hostname & port
|
||||||
|
parts = Envjs.urlsplit($url);
|
||||||
|
|
||||||
|
if ($history) {
|
||||||
|
$history.add( $url, 'host');
|
||||||
|
}
|
||||||
|
this.assign($url);
|
||||||
|
},
|
||||||
|
|
||||||
|
get hostname() {
|
||||||
|
return parts.hostname;
|
||||||
|
},
|
||||||
|
set hostname(s) {
|
||||||
|
if (!s || s === '') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
parts.netloc = s;
|
||||||
|
if (parts.port != '') {
|
||||||
|
parts.netloc += ':' + parts.port;
|
||||||
|
}
|
||||||
|
parts.hostname = s;
|
||||||
|
$url = Envjs.urlunsplit(parts);
|
||||||
|
if ($history) {
|
||||||
|
$history.add( $url, 'hostname');
|
||||||
|
}
|
||||||
|
this.assign($url);
|
||||||
|
},
|
||||||
|
|
||||||
|
get href() {
|
||||||
|
return $url;
|
||||||
|
},
|
||||||
|
set href(url) {
|
||||||
|
$url = url;
|
||||||
|
if ($history) {
|
||||||
|
$history.add($url, 'href');
|
||||||
|
}
|
||||||
|
this.assign($url);
|
||||||
|
},
|
||||||
|
|
||||||
|
get pathname() {
|
||||||
|
return parts.path;
|
||||||
|
},
|
||||||
|
set pathname(s) {
|
||||||
|
if (s[0] === '/') {
|
||||||
|
parts.path = s;
|
||||||
|
} else {
|
||||||
|
parts.path = '/' + s;
|
||||||
|
}
|
||||||
|
$url = Envjs.urlunsplit(parts);
|
||||||
|
|
||||||
|
if ($history) {
|
||||||
|
$history.add($url, 'pathname');
|
||||||
|
}
|
||||||
|
this.assign($url);
|
||||||
|
},
|
||||||
|
|
||||||
|
get port() {
|
||||||
|
// make sure it's a string
|
||||||
|
return '' + parts.port;
|
||||||
|
},
|
||||||
|
set port(p) {
|
||||||
|
// make a string
|
||||||
|
var s = '' + p;
|
||||||
|
parts.port = s;
|
||||||
|
parts.netloc = parts.hostname + ':' + parts.port;
|
||||||
|
$url = Envjs.urlunsplit(parts);
|
||||||
|
if ($history) {
|
||||||
|
$history.add( $url, 'port');
|
||||||
|
}
|
||||||
|
this.assign($url);
|
||||||
|
},
|
||||||
|
|
||||||
|
get protocol() {
|
||||||
|
return parts.scheme + ':';
|
||||||
|
},
|
||||||
|
set protocol(s) {
|
||||||
|
var i = s.indexOf(':');
|
||||||
|
if (i != -1) {
|
||||||
|
s = s.substr(0,i);
|
||||||
|
}
|
||||||
|
parts.scheme = s;
|
||||||
|
$url = Envjs.urlunsplit(parts);
|
||||||
|
if ($history) {
|
||||||
|
$history.add($url, 'protocol');
|
||||||
|
}
|
||||||
|
this.assign($url);
|
||||||
|
},
|
||||||
|
|
||||||
|
get search() {
|
||||||
|
return (parts.query) ? '?' + parts.query : parts.query;
|
||||||
|
},
|
||||||
|
set search(s) {
|
||||||
|
if (s[0] == '?') {
|
||||||
|
s = s.substr(1);
|
||||||
|
}
|
||||||
|
parts.query = s;
|
||||||
|
$url = Envjs.urlunsplit(parts);
|
||||||
|
if ($history) {
|
||||||
|
$history.add($url, 'search');
|
||||||
|
}
|
||||||
|
this.assign($url);
|
||||||
|
},
|
||||||
|
|
||||||
|
toString: function() {
|
||||||
|
return $url;
|
||||||
|
},
|
||||||
|
|
||||||
|
assign: function(url, /*non-standard*/ method, data) {
|
||||||
|
var _this = this,
|
||||||
|
xhr,
|
||||||
|
event;
|
||||||
|
method = method||"GET";
|
||||||
|
data = data||null;
|
||||||
|
log.debug('assigning %s',url);
|
||||||
|
|
||||||
|
//we can only assign if this Location is associated with a document
|
||||||
|
if ($document) {
|
||||||
|
log.debug('fetching %s (async? %s)', url, $document.async);
|
||||||
|
xhr = new XMLHttpRequest();
|
||||||
|
|
||||||
|
xhr.setRequestHeader('Referer', $document.location);
|
||||||
|
log.debug("REFERER: %s", $document.location);
|
||||||
|
// TODO: make async flag a Envjs paramter
|
||||||
|
xhr.open(method, url, false);//$document.async);
|
||||||
|
|
||||||
|
// TODO: is there a better way to test if a node is an HTMLDocument?
|
||||||
|
if ($document.toString() === '[object HTMLDocument]') {
|
||||||
|
//tell the xhr to not parse the document as XML
|
||||||
|
log.debug('loading html document');
|
||||||
|
xhr.onreadystatechange = function() {
|
||||||
|
log.debug('readyState %s', xhr.readyState);
|
||||||
|
if (xhr.readyState === 4) {
|
||||||
|
switch(xhr.status){
|
||||||
|
case 301:
|
||||||
|
case 302:
|
||||||
|
case 303:
|
||||||
|
case 305:
|
||||||
|
case 307:
|
||||||
|
log.debug('status is not good for assignment %s', xhr.status);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log.debug('status is good for assignment %s', xhr.status);
|
||||||
|
$url = xhr.url;
|
||||||
|
parts = Envjs.urlsplit($url);
|
||||||
|
log.debug('new document location %s', xhr.url);
|
||||||
|
Envjs.exchangeHTMLDocument($document, xhr.responseText, xhr.url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
try{
|
||||||
|
xhr.send(data, false);//dont parse html
|
||||||
|
}catch(e){
|
||||||
|
log.debug('failed to load content %s', e);
|
||||||
|
Envjs.exchangeHTMLDocument(
|
||||||
|
$document,
|
||||||
|
"<html><head><title>Error Loading</title></head><body>"+e+"</body></html>",
|
||||||
|
xhr.url
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//Treat as an XMLDocument
|
||||||
|
xhr.onreadystatechange = function() {
|
||||||
|
if (xhr.readyState === 4) {
|
||||||
|
log.debug('exchanging xml content %s', e);
|
||||||
|
$document = xhr.responseXML;
|
||||||
|
$document.baseURI = xhr.url;
|
||||||
|
if ($document.createEvent) {
|
||||||
|
event = $document.createEvent('Event');
|
||||||
|
event.initEvent('DOMContentLoaded');
|
||||||
|
$document.dispatchEvent( event, false );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
}//end if($document)
|
||||||
|
},
|
||||||
|
reload: function(forceget) {
|
||||||
|
//for now we have no caching so just proxy to assign
|
||||||
|
log.debug('reloading %s',$url);
|
||||||
|
this.assign($url);
|
||||||
|
},
|
||||||
|
replace: function(url, /*non-standard*/ method, data) {
|
||||||
|
this.assign(url, method, data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}(/*Location*/));
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @class XMLHttpRequest
|
||||||
|
* @author Originally implemented by Yehuda Katz
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
|
||||||
|
// this implementation can be used without requiring a DOMParser
|
||||||
|
// assuming you dont try to use it to get xml/html documents
|
||||||
|
var domparser,
|
||||||
|
log = Envjs.logger();
|
||||||
|
|
||||||
|
Envjs.once('tick', function(){
|
||||||
|
log = Envjs.logger('Envjs.XMLHttpRequest').
|
||||||
|
debug('xhr logger available');
|
||||||
|
});
|
||||||
|
|
||||||
|
exports.XMLHttpRequest = XMLHttpRequest = function(){
|
||||||
|
this.headers = {};
|
||||||
|
this.responseHeaders = {};
|
||||||
|
this.aborted = false;//non-standard
|
||||||
|
};
|
||||||
|
|
||||||
|
// defined by the standard: http://www.w3.org/TR/XMLHttpRequest/#xmlhttprequest
|
||||||
|
// but not provided by Firefox. Safari and others do define it.
|
||||||
|
XMLHttpRequest.UNSENT = 0;
|
||||||
|
XMLHttpRequest.OPEN = 1;
|
||||||
|
XMLHttpRequest.HEADERS_RECEIVED = 2;
|
||||||
|
XMLHttpRequest.LOADING = 3;
|
||||||
|
XMLHttpRequest.DONE = 4;
|
||||||
|
|
||||||
|
XMLHttpRequest.prototype = {
|
||||||
|
open: function(method, url, async, user, password){
|
||||||
|
log.debug('opening xhr %s %s %s', method, url, async);
|
||||||
|
this.readyState = 1;
|
||||||
|
this.async = (async === false)?false:true;
|
||||||
|
this.method = method || "GET";
|
||||||
|
this.url = Envjs.uri(url);
|
||||||
|
this.onreadystatechange();
|
||||||
|
},
|
||||||
|
setRequestHeader: function(header, value){
|
||||||
|
this.headers[header] = value;
|
||||||
|
},
|
||||||
|
send: function(data, parsedoc/*non-standard*/, redirect_count){
|
||||||
|
var _this = this;
|
||||||
|
log.debug('sending request for url %s', this.url);
|
||||||
|
parsedoc = (parsedoc === undefined)?true:!!parsedoc;
|
||||||
|
redirect_count = (redirect_count === undefined) ? 0 : redirect_count;
|
||||||
|
function makeRequest(){
|
||||||
|
var cookie = Envjs.getCookies(_this.url),
|
||||||
|
redirecting = false;
|
||||||
|
if(cookie){
|
||||||
|
_this.setRequestHeader('COOKIE', cookie);
|
||||||
|
}
|
||||||
|
if(window&&window.navigator&&window.navigator.userAgent){
|
||||||
|
_this.setRequestHeader('User-Agent', window.navigator.userAgent);
|
||||||
|
}
|
||||||
|
|
||||||
|
log.debug('establishing platform native connection %s', _this.url);
|
||||||
|
Envjs.connection(_this, function(){
|
||||||
|
log.debug('callback remove xhr from network queue');
|
||||||
|
Envjs.connections.removeConnection(_this);
|
||||||
|
if (!_this.aborted){
|
||||||
|
var doc = null,
|
||||||
|
domparser,
|
||||||
|
cookie,
|
||||||
|
contentType,
|
||||||
|
location;
|
||||||
|
|
||||||
|
try{
|
||||||
|
cookie = _this.getResponseHeader('SET-COOKIE');
|
||||||
|
if(cookie){
|
||||||
|
Envjs.setCookie(_this.url, cookie);
|
||||||
|
}
|
||||||
|
}catch(e){
|
||||||
|
log.warn("Failed to set cookie");
|
||||||
|
}
|
||||||
|
//console.log('status : %s', _this.status);
|
||||||
|
switch(_this.status){
|
||||||
|
case 301:
|
||||||
|
case 302:
|
||||||
|
case 303:
|
||||||
|
case 305:
|
||||||
|
case 307:
|
||||||
|
if(_this.getResponseHeader('Location') && redirect_count < 20){
|
||||||
|
//follow redirect and copy headers
|
||||||
|
redirecting = true;
|
||||||
|
location = _this.getResponseHeader('Location');
|
||||||
|
log.debug('following %s redirect %s from %s url %s',
|
||||||
|
redirect_count,
|
||||||
|
_this.status,
|
||||||
|
_this.url,
|
||||||
|
location);
|
||||||
|
_this.url = Envjs.uri(location);
|
||||||
|
//remove current cookie headers to allow the redirect to determine
|
||||||
|
//the currect cookie based on the new location
|
||||||
|
if('Cookie' in _this.headers ){
|
||||||
|
delete _this.headers.Cookie;
|
||||||
|
}
|
||||||
|
if('Cookie2' in _this.headers ){
|
||||||
|
delete _this.headers.Cookie2;
|
||||||
|
}
|
||||||
|
redirect_count++;
|
||||||
|
if (_this.async){
|
||||||
|
//TODO: see TODO notes below
|
||||||
|
Envjs.runAsync(makeRequest);
|
||||||
|
}else{
|
||||||
|
makeRequest();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}break;
|
||||||
|
default:
|
||||||
|
// try to parse the document if we havent explicitly set a
|
||||||
|
// flag saying not to and if we can assure the text at least
|
||||||
|
// starts with valid xml
|
||||||
|
contentType = _this.getResponseHeader('Content-Type');
|
||||||
|
log.debug("response content-type : %s", contentType);
|
||||||
|
if ( parsedoc &&
|
||||||
|
contentType &&
|
||||||
|
contentType.indexOf('xml') > -1 &&
|
||||||
|
_this.responseText.match(/^\s*</) ) {
|
||||||
|
|
||||||
|
domparser = domparser||new DOMParser();
|
||||||
|
try {
|
||||||
|
log.debug("parsing response text into xml document");
|
||||||
|
doc = domparser.parseFromString(_this.responseText+"", 'text/xml');
|
||||||
|
} catch(ee) {
|
||||||
|
//Envjs.error('response XML does not appear to be well formed xml', e);
|
||||||
|
log.error('parseerror \n%s', ee);
|
||||||
|
doc = document.implementation.createDocument('','error',null);
|
||||||
|
doc.appendChild(doc.createTextNode(ee+''));
|
||||||
|
}
|
||||||
|
|
||||||
|
}else{
|
||||||
|
log.debug('response XML does not appear to be xml');
|
||||||
|
}
|
||||||
|
|
||||||
|
_this.__defineGetter__("responseXML", function(){
|
||||||
|
return doc;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, data);
|
||||||
|
|
||||||
|
if (!_this.aborted && !redirecting){
|
||||||
|
log.debug('did not abort and not redirecting so calling onreadystatechange');
|
||||||
|
_this.onreadystatechange();
|
||||||
|
}
|
||||||
|
|
||||||
|
}//end makeRequest
|
||||||
|
|
||||||
|
log.debug('requesting async: %s', this.url);
|
||||||
|
Envjs.connections.addConnection(this);
|
||||||
|
if (this.async){
|
||||||
|
//DONE: what we really need to do here is rejoin the
|
||||||
|
// current thread and call onreadystatechange via
|
||||||
|
// setTimeout so the callback is essentially applied
|
||||||
|
// at the end of the current callstack
|
||||||
|
Envjs.runAsync(makeRequest);
|
||||||
|
}else{
|
||||||
|
log.debug('requesting sync: %s', this.url);
|
||||||
|
makeRequest();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
abort: function(){
|
||||||
|
this.aborted = true;
|
||||||
|
},
|
||||||
|
onreadystatechange: function(){
|
||||||
|
//Instance specific
|
||||||
|
},
|
||||||
|
getResponseHeader: function(header){
|
||||||
|
log.debug('getting response header %s', header);
|
||||||
|
var rHeader, returnedHeaders;
|
||||||
|
if (this.readyState < 3){
|
||||||
|
throw new Error("INVALID_STATE_ERR");
|
||||||
|
} else {
|
||||||
|
returnedHeaders = [];
|
||||||
|
log.debug('searching response headers for %s ', header);
|
||||||
|
for (rHeader in this.responseHeaders) {
|
||||||
|
if ((rHeader+'').match(new RegExp(header, "i"))) {
|
||||||
|
log.debug('found response header, %s is %s', rHeader, header);
|
||||||
|
returnedHeaders.push(this.responseHeaders[rHeader]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (returnedHeaders.length){
|
||||||
|
returnedHeaders = returnedHeaders.join(", ");
|
||||||
|
log.debug('got response header %s', returnedHeaders);
|
||||||
|
return returnedHeaders;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
getAllResponseHeaders: function(){
|
||||||
|
var header, returnedHeaders = [];
|
||||||
|
if (this.readyState < 3){
|
||||||
|
throw new Error("INVALID_STATE_ERR");
|
||||||
|
} else {
|
||||||
|
for (header in this.responseHeaders) {
|
||||||
|
if(this.responseHeader.hasOwnProperty(header)){
|
||||||
|
returnedHeaders.push( header + ": " + this.responseHeaders[header] );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return returnedHeaders.join("\r\n");
|
||||||
|
},
|
||||||
|
async: true,
|
||||||
|
readyState: 0,
|
||||||
|
responseText: "",
|
||||||
|
status: 0,
|
||||||
|
statusText: ""
|
||||||
|
};
|
||||||
|
|
||||||
|
}(/*XMLHttpREquest*/));
|
||||||
|
/**
|
||||||
|
* @author john resig & the envjs team
|
||||||
|
* @uri http://www.envjs.com/
|
||||||
|
* @copyright 2008-2010
|
||||||
|
* @license MIT
|
||||||
|
*/
|
||||||
|
//CLOSURE_END
|
||||||
|
}());
|
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file provides local settings you'll need to modify to make sure
|
||||||
|
* envjs platform tests can function properly. Dont modify this
|
||||||
|
* file directly, copy it to local_settings.js and then modify it so
|
||||||
|
* as not to commit your local settings back to the repo.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var SETTINGS = {
|
||||||
|
BASE_URI : 'file:///mnt/repos/thatcher/env-js/',
|
||||||
|
AJAX_BASE: 'http://github.com/thatcher/env-js/raw/master/',
|
||||||
|
LOCAL_PORT: '8080',
|
||||||
|
APP_CONTEXT: '/env-js/'
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Envjs.config('logging',[
|
||||||
|
{category:'Envjs.Core', level:'WARN'},
|
||||||
|
{category:'Envjs.Core.REPL', level:'WARN'},
|
||||||
|
{category:'Envjs.DOM', level:'WARN'},
|
||||||
|
{category:'Envjs.DOM.Node', level:'WARN'},
|
||||||
|
{category:'Envjs.DOM.NodeList', level:'WARN'},
|
||||||
|
{category:'Envjs.DOM.NamedNodeMap', level:'WARN'},
|
||||||
|
{category:'Envjs.DOM.NamespacedNodeMap',level:'WARN'},
|
||||||
|
{category:'Envjs.DOM.Element', level:'WARN'},
|
||||||
|
{category:'Envjs.DOM.Document', level:'WARN'},
|
||||||
|
{category:'Envjs.DOM.EventTarget', level:'WARN'},
|
||||||
|
{category:'Envjs.Timer', level:'WARN'},
|
||||||
|
{category:'Envjs.Location', level:'WARN'},
|
||||||
|
{category:'Envjs.XMLHttpRequest', level:'INFO'},
|
||||||
|
{category:'Envjs.Parser', level:'WARN'},
|
||||||
|
{category:'Envjs.Parser.HTMLParser', level:'WARN'},
|
||||||
|
{category:'Envjs.Parser.XMLParser', level:'WARN'},
|
||||||
|
{category:'Envjs.HTML.Frame', level:'WARN'},
|
||||||
|
{category:'Envjs.Window', level:'WARN'},
|
||||||
|
{category:'Envjs.Platform', level:'WARN'},
|
||||||
|
{category:'Envjs.Platform.Johnson', level:'WARN'},
|
||||||
|
{category:'root', level:'WARN'}
|
||||||
|
]);
|
|
@ -1 +1 @@
|
||||||
d3 = {version: "1.4.0"}; // semver
|
d3 = {version: "1.5.1"}; // semver
|
||||||
|
|
|
@ -2,30 +2,45 @@
|
||||||
d3.format = function(specifier) {
|
d3.format = function(specifier) {
|
||||||
var match = d3_format_re.exec(specifier),
|
var match = d3_format_re.exec(specifier),
|
||||||
fill = match[1] || " ",
|
fill = match[1] || " ",
|
||||||
sign = d3_format_signs[match[3]] || d3_format_signs["-"],
|
sign = match[3] || "",
|
||||||
zfill = match[5],
|
zfill = match[5],
|
||||||
width = +match[6],
|
width = +match[6],
|
||||||
comma = match[7],
|
comma = match[7],
|
||||||
precision = match[8],
|
precision = match[8],
|
||||||
type = match[9];
|
type = match[9];
|
||||||
if (precision) precision = precision.substring(1);
|
if (precision) precision = precision.substring(1);
|
||||||
if (zfill) fill = "0"; // TODO align = "=";
|
if (zfill) {
|
||||||
|
fill = "0"; // TODO align = "=";
|
||||||
|
if (comma) width -= Math.floor((width - 1) / 4);
|
||||||
|
}
|
||||||
if (type == "d") precision = "0";
|
if (type == "d") precision = "0";
|
||||||
return function(value) {
|
return function(value) {
|
||||||
var number = +value,
|
var number = +value,
|
||||||
negative = (number < 0) && (number = -number);
|
negative = (number < 0) && (number = -number) ? "\u2212" : sign;
|
||||||
|
|
||||||
|
// Return the empty string for floats formatted as ints.
|
||||||
if ((type == "d") && (number % 1)) return "";
|
if ((type == "d") && (number % 1)) return "";
|
||||||
|
|
||||||
|
// Convert the input value to the desired precision.
|
||||||
if (precision) value = number.toFixed(precision);
|
if (precision) value = number.toFixed(precision);
|
||||||
else value = "" + number;
|
else value = "" + number;
|
||||||
if (comma) {
|
|
||||||
var i = value.lastIndexOf("."),
|
// If the fill character is 0, the sign and group is applied after the fill.
|
||||||
f = i >= 0 ? value.substring(i) : (i = value.length, ""),
|
if (zfill) {
|
||||||
t = [];
|
var length = value.length + negative.length;
|
||||||
while (i > 0) t.push(value.substring(i -= 3, i + 3));
|
if (length < width) value = new Array(width - length + 1).join(fill) + value;
|
||||||
value = t.reverse().join(",") + f;
|
if (comma) value = d3_format_group(value);
|
||||||
|
value = negative + value;
|
||||||
}
|
}
|
||||||
var length = (value = sign(negative, value)).length;
|
|
||||||
if (length < width) value = new Array(width - length + 1).join(fill) + value;
|
// Otherwise (e.g., space-filling), the sign and group is applied before.
|
||||||
|
else {
|
||||||
|
if (comma) value = d3_format_group(value);
|
||||||
|
value = negative + value;
|
||||||
|
var length = value.length;
|
||||||
|
if (length < width) value = new Array(width - length + 1).join(fill) + value;
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -33,8 +48,11 @@ d3.format = function(specifier) {
|
||||||
// [[fill]align][sign][#][0][width][,][.precision][type]
|
// [[fill]align][sign][#][0][width][,][.precision][type]
|
||||||
var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/;
|
var d3_format_re = /(?:([^{])?([<>=^]))?([+\- ])?(#)?(0)?([0-9]+)?(,)?(\.[0-9]+)?([a-zA-Z%])?/;
|
||||||
|
|
||||||
var d3_format_signs = {
|
// Apply comma grouping for thousands.
|
||||||
"+": function(negative, value) { return (negative ? "\u2212" : "+") + value; },
|
function d3_format_group(value) {
|
||||||
" ": function(negative, value) { return (negative ? "\u2212" : " ") + value; },
|
var i = value.lastIndexOf("."),
|
||||||
"-": function(negative, value) { return negative ? "\u2212" + value : value; }
|
f = i >= 0 ? value.substring(i) : (i = value.length, ""),
|
||||||
};
|
t = [];
|
||||||
|
while (i > 0) t.push(value.substring(i -= 3, i + 3));
|
||||||
|
return t.reverse().join(",") + f;
|
||||||
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
// A rudimentary force layout using Gauss-Seidel.
|
// A rudimentary force layout using Gauss-Seidel.
|
||||||
function layout_force() {
|
d3.layout.force = function() {
|
||||||
var force = {},
|
var force = {},
|
||||||
event = d3.dispatch("tick"),
|
event = d3.dispatch("tick"),
|
||||||
size = {x: 1, y: 1},
|
size = [1, 1],
|
||||||
alpha = .5,
|
alpha = .5,
|
||||||
distance = 30,
|
distance = 30,
|
||||||
interval,
|
interval,
|
||||||
|
@ -88,8 +88,8 @@ function layout_force() {
|
||||||
k,
|
k,
|
||||||
n = nodes.length,
|
n = nodes.length,
|
||||||
m = links.length,
|
m = links.length,
|
||||||
w = size.x,
|
w = size[0],
|
||||||
h = size.y,
|
h = size[1],
|
||||||
o;
|
o;
|
||||||
|
|
||||||
var paths = [];
|
var paths = [];
|
||||||
|
@ -183,6 +183,7 @@ function layout_force() {
|
||||||
function mouseup() {
|
function mouseup() {
|
||||||
if (!node) return;
|
if (!node) return;
|
||||||
mousemove();
|
mousemove();
|
||||||
|
node.fixed = false;
|
||||||
node = element = null;
|
node = element = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,4 +191,4 @@ function layout_force() {
|
||||||
};
|
};
|
||||||
|
|
||||||
return force;
|
return force;
|
||||||
}
|
};
|
|
@ -1,7 +1,8 @@
|
||||||
// Squarified Treemaps by Mark Bruls, Kees Huizing, and Jarke J. van Wijk
|
// Squarified Treemaps by Mark Bruls, Kees Huizing, and Jarke J. van Wijk
|
||||||
function layout_treemap() {
|
d3.layout.treemap = function() {
|
||||||
var children = layout_treemapChildren,
|
var children = d3_layout_treemapChildren,
|
||||||
value = layout_treemapValue,
|
value = d3_layout_treemapValue,
|
||||||
|
round = Math.round,
|
||||||
size = [1, 1]; // width, height
|
size = [1, 1]; // width, height
|
||||||
|
|
||||||
// Recursively compute the node depth and value.
|
// Recursively compute the node depth and value.
|
||||||
|
@ -43,17 +44,17 @@ function layout_treemap() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Arranges the specified children into squarified rows.
|
// Recursively arranges the specified node's children into squarified rows.
|
||||||
function squarify(children, node) {
|
function squarify(node) {
|
||||||
|
if (!node.children) return;
|
||||||
var rect = {x: node.x, y: node.y, dx: node.dx, dy: node.dy},
|
var rect = {x: node.x, y: node.y, dx: node.dx, dy: node.dy},
|
||||||
row = [],
|
row = [],
|
||||||
|
children = node.children.slice().sort(d3_layout_treemapSort),
|
||||||
child,
|
child,
|
||||||
best = Infinity, // the best row score so far
|
best = Infinity, // the best row score so far
|
||||||
score, // the current row score
|
score, // the current row score
|
||||||
u = Math.min(rect.dx, rect.dy), // initial orientation
|
u = Math.min(rect.dx, rect.dy), // initial orientation
|
||||||
n;
|
n;
|
||||||
children = children.slice(); // copy-on-write
|
|
||||||
children.sort(function(a, b) { return b.area - a.area; });
|
|
||||||
row.area = 0;
|
row.area = 0;
|
||||||
while ((n = children.length) > 0) {
|
while ((n = children.length) > 0) {
|
||||||
row.push(child = children[n - 1]);
|
row.push(child = children[n - 1]);
|
||||||
|
@ -63,16 +64,17 @@ function layout_treemap() {
|
||||||
best = score;
|
best = score;
|
||||||
} else { // abort, and try a different orientation
|
} else { // abort, and try a different orientation
|
||||||
row.area -= row.pop().area;
|
row.area -= row.pop().area;
|
||||||
position(row, u, rect);
|
position(row, u, rect, false);
|
||||||
u = Math.min(rect.dx, rect.dy);
|
u = Math.min(rect.dx, rect.dy);
|
||||||
row.length = row.area = 0;
|
row.length = row.area = 0;
|
||||||
best = Infinity;
|
best = Infinity;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (row.length) {
|
if (row.length) {
|
||||||
position(row, u, rect);
|
position(row, u, rect, true);
|
||||||
row.length = row.area = 0;
|
row.length = row.area = 0;
|
||||||
}
|
}
|
||||||
|
node.children.forEach(squarify);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Computes the score for the specified row, as the worst aspect ratio.
|
// Computes the score for the specified row, as the worst aspect ratio.
|
||||||
|
@ -94,45 +96,40 @@ function layout_treemap() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Positions the specified row of nodes. Modifies `rect`.
|
// Positions the specified row of nodes. Modifies `rect`.
|
||||||
function position(row, u, rect) {
|
function position(row, u, rect, flush) {
|
||||||
var i = -1,
|
var i = -1,
|
||||||
n = row.length,
|
n = row.length,
|
||||||
x = rect.x,
|
x = rect.x,
|
||||||
y = rect.y,
|
y = rect.y,
|
||||||
v = u ? row.area / u : 0,
|
v = u ? round(row.area / u) : 0,
|
||||||
o;
|
o;
|
||||||
if (u == rect.dx) { // horizontal subdivision
|
if (u == rect.dx) { // horizontal subdivision
|
||||||
|
if (flush || v > rect.dy) v = rect.dy; // over+underflow
|
||||||
while (++i < n) {
|
while (++i < n) {
|
||||||
o = row[i];
|
o = row[i];
|
||||||
o.x = x;
|
o.x = x;
|
||||||
o.y = y;
|
o.y = y;
|
||||||
o.dy = v;
|
o.dy = v;
|
||||||
x += o.dx = o.area / v;
|
x += o.dx = round(o.area / v);
|
||||||
}
|
}
|
||||||
|
o.dx += rect.x + rect.dx - x; // rounding error
|
||||||
rect.y += v;
|
rect.y += v;
|
||||||
rect.dy -= v;
|
rect.dy -= v;
|
||||||
} else { // vertical subdivision
|
} else { // vertical subdivision
|
||||||
|
if (flush || v > rect.dx) v = rect.dx; // over+underflow
|
||||||
while (++i < n) {
|
while (++i < n) {
|
||||||
o = row[i];
|
o = row[i];
|
||||||
o.x = x;
|
o.x = x;
|
||||||
o.y = y;
|
o.y = y;
|
||||||
o.dx = v;
|
o.dx = v;
|
||||||
y += o.dy = o.area / v;
|
y += o.dy = round(o.area / v);
|
||||||
}
|
}
|
||||||
|
o.dy += rect.y + rect.dy - y; // rounding error
|
||||||
rect.x += v;
|
rect.x += v;
|
||||||
rect.dx -= v;
|
rect.dx -= v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursively computes the treemap layout for the node and its children.
|
|
||||||
function layout(node) {
|
|
||||||
var children = node.children;
|
|
||||||
if (children) {
|
|
||||||
squarify(children, node);
|
|
||||||
children.forEach(layout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function treemap(d) {
|
function treemap(d) {
|
||||||
var nodes = [],
|
var nodes = [],
|
||||||
root = sum(d, 0, nodes);
|
root = sum(d, 0, nodes);
|
||||||
|
@ -140,7 +137,7 @@ function layout_treemap() {
|
||||||
root.y = 0;
|
root.y = 0;
|
||||||
root.dx = size[0];
|
root.dx = size[0];
|
||||||
root.dy = size[1];
|
root.dy = size[1];
|
||||||
layout(root);
|
squarify(root);
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,13 +159,23 @@ function layout_treemap() {
|
||||||
return treemap;
|
return treemap;
|
||||||
};
|
};
|
||||||
|
|
||||||
return treemap;
|
treemap.round = function(x) {
|
||||||
}
|
if (!arguments.length) return round != Number;
|
||||||
|
round = x ? Math.round : Number;
|
||||||
|
return treemap;
|
||||||
|
};
|
||||||
|
|
||||||
function layout_treemapChildren(d) {
|
return treemap;
|
||||||
|
};
|
||||||
|
|
||||||
|
function d3_layout_treemapChildren(d) {
|
||||||
return d.children;
|
return d.children;
|
||||||
}
|
}
|
||||||
|
|
||||||
function layout_treemapValue(d) {
|
function d3_layout_treemapValue(d) {
|
||||||
return d.value;
|
return d.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function d3_layout_treemapSort(a, b) {
|
||||||
|
return b.area - a.area;
|
||||||
|
}
|
|
@ -0,0 +1,109 @@
|
||||||
|
require("./../lib/env-js/envjs/node");
|
||||||
|
require("./../d3");
|
||||||
|
|
||||||
|
console.log("zero fill:");
|
||||||
|
console.log(" ", d3.format("08d")(0));
|
||||||
|
console.log(" ", d3.format("08d")(42));
|
||||||
|
console.log(" ", d3.format("08d")(42000000));
|
||||||
|
console.log(" ", d3.format("08d")(420000000));
|
||||||
|
console.log(" ", d3.format("08d")(-4));
|
||||||
|
console.log(" ", d3.format("08d")(-42));
|
||||||
|
console.log(" ", d3.format("08d")(-4200000));
|
||||||
|
console.log(" ", d3.format("08d")(-42000000));
|
||||||
|
console.log("");
|
||||||
|
|
||||||
|
console.log("space fill:");
|
||||||
|
console.log(" ", d3.format("8d")(0));
|
||||||
|
console.log(" ", d3.format("8d")(42));
|
||||||
|
console.log(" ", d3.format("8d")(42000000));
|
||||||
|
console.log(" ", d3.format("8d")(420000000));
|
||||||
|
console.log(" ", d3.format("8d")(-4));
|
||||||
|
console.log(" ", d3.format("8d")(-42));
|
||||||
|
console.log(" ", d3.format("8d")(-4200000));
|
||||||
|
console.log(" ", d3.format("8d")(-42000000));
|
||||||
|
console.log("");
|
||||||
|
|
||||||
|
// TODO fill with other characters (requires align support)
|
||||||
|
|
||||||
|
console.log("grouping:");
|
||||||
|
console.log(" ", d3.format(",d")(0));
|
||||||
|
console.log(" ", d3.format(",d")(42));
|
||||||
|
console.log(" ", d3.format(",d")(42000000));
|
||||||
|
console.log(" ", d3.format(",d")(420000000));
|
||||||
|
console.log(" ", d3.format(",d")(-4));
|
||||||
|
console.log(" ", d3.format(",d")(-42));
|
||||||
|
console.log(" ", d3.format(",d")(-4200000));
|
||||||
|
console.log(" ", d3.format(",d")(-42000000));
|
||||||
|
console.log("");
|
||||||
|
|
||||||
|
console.log("grouping with zero fill:");
|
||||||
|
console.log(" ", d3.format("01,d")(0));
|
||||||
|
console.log(" ", d3.format("01,d")(0));
|
||||||
|
console.log(" ", d3.format("02,d")(0));
|
||||||
|
console.log(" ", d3.format("03,d")(0));
|
||||||
|
console.log(" ", d3.format("05,d")(0));
|
||||||
|
console.log(" ", d3.format("08,d")(0));
|
||||||
|
console.log(" ", d3.format("013,d")(0));
|
||||||
|
console.log(" ", d3.format("021,d")(0));
|
||||||
|
console.log("");
|
||||||
|
|
||||||
|
console.log("grouping with zero fill (overflow):");
|
||||||
|
console.log(" ", d3.format("01,d")(1));
|
||||||
|
console.log(" ", d3.format("01,d")(1));
|
||||||
|
console.log(" ", d3.format("02,d")(12));
|
||||||
|
console.log(" ", d3.format("03,d")(123));
|
||||||
|
console.log(" ", d3.format("05,d")(12345));
|
||||||
|
console.log(" ", d3.format("08,d")(12345678));
|
||||||
|
console.log(" ", d3.format("013,d")(1234567890123));
|
||||||
|
console.log("");
|
||||||
|
|
||||||
|
console.log("grouping with space fill:");
|
||||||
|
console.log(" ", d3.format("1,d")(0));
|
||||||
|
console.log(" ", d3.format("1,d")(0));
|
||||||
|
console.log(" ", d3.format("2,d")(0));
|
||||||
|
console.log(" ", d3.format("3,d")(0));
|
||||||
|
console.log(" ", d3.format("5,d")(0));
|
||||||
|
console.log(" ", d3.format("8,d")(0));
|
||||||
|
console.log(" ", d3.format("13,d")(0));
|
||||||
|
console.log(" ", d3.format("21,d")(0));
|
||||||
|
console.log("");
|
||||||
|
|
||||||
|
console.log("grouping with space fill (overflow):");
|
||||||
|
console.log(" ", d3.format("1,d")(1));
|
||||||
|
console.log(" ", d3.format("1,d")(1));
|
||||||
|
console.log(" ", d3.format("2,d")(12));
|
||||||
|
console.log(" ", d3.format("3,d")(123));
|
||||||
|
console.log(" ", d3.format("5,d")(12345));
|
||||||
|
console.log(" ", d3.format("8,d")(12345678));
|
||||||
|
console.log(" ", d3.format("13,d")(1234567890123));
|
||||||
|
console.log("");
|
||||||
|
|
||||||
|
console.log("precision:");
|
||||||
|
console.log(" ", d3.format(".1f")(0.49));
|
||||||
|
console.log(" ", d3.format(".2f")(0.449));
|
||||||
|
console.log(" ", d3.format(".3f")(0.4449));
|
||||||
|
console.log(" ", d3.format(".5f")(0.444449));
|
||||||
|
console.log(" ", d3.format(".1f")(100));
|
||||||
|
console.log(" ", d3.format(".2f")(100));
|
||||||
|
console.log(" ", d3.format(".3f")(100));
|
||||||
|
console.log(" ", d3.format(".5f")(100));
|
||||||
|
console.log("");
|
||||||
|
|
||||||
|
console.log("precision and grouping with space fill:");
|
||||||
|
console.log(" ", d3.format("10,.1f")(123456.49));
|
||||||
|
console.log(" ", d3.format("10,.2f")(1234567.449));
|
||||||
|
console.log(" ", d3.format("10,.3f")(12345678.4449));
|
||||||
|
console.log(" ", d3.format("10,.5f")(123456789.444449));
|
||||||
|
console.log(" ", d3.format("10,.1f")(123456));
|
||||||
|
console.log(" ", d3.format("10,.2f")(1234567));
|
||||||
|
console.log(" ", d3.format("10,.3f")(12345678));
|
||||||
|
console.log(" ", d3.format("10,.5f")(123456789));
|
||||||
|
console.log("");
|
||||||
|
|
||||||
|
console.log("float type passed int:");
|
||||||
|
console.log(" ", d3.format("f")(42));
|
||||||
|
console.log("");
|
||||||
|
|
||||||
|
console.log("int type passed float:");
|
||||||
|
console.log(" ", d3.format("d")(4.2));
|
||||||
|
console.log("");
|
|
@ -0,0 +1,94 @@
|
||||||
|
zero fill:
|
||||||
|
00000000
|
||||||
|
00000042
|
||||||
|
42000000
|
||||||
|
420000000
|
||||||
|
−0000004
|
||||||
|
−0000042
|
||||||
|
−4200000
|
||||||
|
−42000000
|
||||||
|
|
||||||
|
space fill:
|
||||||
|
0
|
||||||
|
42
|
||||||
|
42000000
|
||||||
|
420000000
|
||||||
|
−4
|
||||||
|
−42
|
||||||
|
−4200000
|
||||||
|
−42000000
|
||||||
|
|
||||||
|
grouping:
|
||||||
|
0
|
||||||
|
42
|
||||||
|
42,000,000
|
||||||
|
420,000,000
|
||||||
|
−4
|
||||||
|
−42
|
||||||
|
−4,200,000
|
||||||
|
−42,000,000
|
||||||
|
|
||||||
|
grouping with zero fill:
|
||||||
|
0
|
||||||
|
0
|
||||||
|
00
|
||||||
|
000
|
||||||
|
0,000
|
||||||
|
0,000,000
|
||||||
|
0,000,000,000
|
||||||
|
0,000,000,000,000,000
|
||||||
|
|
||||||
|
grouping with zero fill (overflow):
|
||||||
|
1
|
||||||
|
1
|
||||||
|
12
|
||||||
|
123
|
||||||
|
12,345
|
||||||
|
12,345,678
|
||||||
|
1,234,567,890,123
|
||||||
|
|
||||||
|
grouping with space fill:
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
|
||||||
|
grouping with space fill (overflow):
|
||||||
|
1
|
||||||
|
1
|
||||||
|
12
|
||||||
|
123
|
||||||
|
12,345
|
||||||
|
12,345,678
|
||||||
|
1,234,567,890,123
|
||||||
|
|
||||||
|
precision:
|
||||||
|
0.5
|
||||||
|
0.45
|
||||||
|
0.445
|
||||||
|
0.44445
|
||||||
|
100.0
|
||||||
|
100.00
|
||||||
|
100.000
|
||||||
|
100.00000
|
||||||
|
|
||||||
|
precision and grouping with space fill:
|
||||||
|
123,456.5
|
||||||
|
1,234,567.45
|
||||||
|
12,345,678.445
|
||||||
|
123,456,789.44445
|
||||||
|
123,456.0
|
||||||
|
1,234,567.00
|
||||||
|
12,345,678.000
|
||||||
|
123,456,789.00000
|
||||||
|
|
||||||
|
float type passed int:
|
||||||
|
42
|
||||||
|
|
||||||
|
int type passed float:
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче