diff --git a/README.md b/README.md
index 76ac24a..b319237 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,6 @@ So the API is minimal and easy to understand. The library is tiny, fast and rend
* Fast and lightweight graphics command queue builder.
* Addressing HTML canvas 2D context as the default renderer.
-* Generating SVG output using an [addon library](https://github.com/goessner/g2-svg).
* Method chaining.
* Support of cartesian coordinates.
* Viewport pan and zoom transformations.
diff --git a/changelog.md b/changelog.md
index 46e9696..c176083 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,4 +1,27 @@
# CHANGELOG
+## [3.1.0]() on May 2021
+
+### `g2.core.js`
+* Styles `(fs|ls|lw|lc|lj|ld|ldoff|ml|sh|lsh|font|thal|tval)` can be numbered now from `0-9` as in `{ls2:'red'}`.
+This helps to hand over multiple fill styles (for example) to sub- structures (`beg`, `use`).
+
+### `g2.ext.js`
+* Handles `hdl` now have new default fill color `fs:'limegreen'` for better recognition.
+
+## [3.0.0]() on December 2020
+
+### `g2.core.js`
+* `g2.mixin` is replaced with `g2.mix`.
+
+### `g2.ext.js`
+* Symbols like `nod`, `origin` etc. are moved from `g2.mec` to `g2.ext`.
+* Commands `vec`, `avec`, `dim`, `adim` are also moved.
+* `label` is no command anymore, but a property on respective `g2` commands.
+* `mark` is no command anymore, but a property on respective `g2` commands.
+
+### `g2.chart.html.js`
+* A new custom HTML element used for easy rendering of `g2.chart` commands.
+
## [2.6.0]() on May 2020
### `g2.core.js`
@@ -19,17 +42,3 @@
### `g2.selector.js` / `canvasinteractor.js`
* `interactor.on('pan')`, `interactor.on('drag')` and `interactor.on('wheel')` handling is moved out of the library and is now in the responsibility of the application (s. `g2.drag.html`).
* `hdl` elements can be used elegantly to interactively modify geometry.
-
-## [3.0.0]() on December 2020
-
-### `g2.core.js`
-* `g2.mixin` is replaced with `g2.mix`.
-
-### `g2.ext.js`
-* Symbols like `nod`, `origin` etc. are moved from `g2.mec` to `g2.ext`.
-* Commands `vec`, `avec`, `dim`, `adim` are also moved.
-* `label` is no command anymore, but a property on respective `g2` commands.
-* `mark` is no command anymore, but a property on respective `g2` commands.
-
-### `g2.chart.html.js`
-* A new custom HTML element used for easy rendering of `g2.chart` commands.
diff --git a/dist/g2.chart.html.js b/dist/g2.chart.html.js
index 49c964d..37750d3 100644
--- a/dist/g2.chart.html.js
+++ b/dist/g2.chart.html.js
@@ -2,7 +2,7 @@
"use strict"
/**
- * g2.core (c) 2013-20 Stefan Goessner
+ * g2.core (c) 2013-21 Stefan Goessner
* @author Stefan Goessner
* @license MIT License
* @link https://github.com/goessner/g2
@@ -538,6 +538,8 @@ g2.prototype = {
// statics
g2.defaultStyle = { fs: 'transparent', ls: '#000', lw: 1, lc: "butt", lj: "miter", ld: [], ml: 10, sh: [0, 0], lsh: false, font: '14px serif', thal: 'start', tval: 'alphabetic' };
+g2.styleRex = /^(fs|ls|lw|lc|lj|ld|ldoff|ml|sh|lsh|font|thal|tval)([-0-9].*)?$/,
+
g2.symbol = {
unknown: g2().cir({ r: 12, fs: 'orange' }).txt({ str: '?', thal: 'center', tval: 'middle', font: 'bold 20pt serif' })
};
@@ -955,13 +957,16 @@ g2.canvasHdl.prototype = {
let q, prv = {};
for (const key in style) {
if (this.get[key]) { // style keys only ...
+ let keyval = style[key];
if (typeof style[key] === 'string' && style[key][0] === '@') {
- let ref = style[key].substr(1);
- style[key] = g2.symbol[ref] || this.get[ref] && this.get[ref](this.ctx);
+ // also check inherited styles ...
+ const ref = style[key].substr(1);
+ keyval = g2.symbol[ref] || ref in this.get && this.get[ref](this.ctx)
+ || ref in this.cur && this.cur[ref];
}
- if ((q = this.get[key](this.ctx)) !== style[key]) {
+ if ((q = this.get[key](this.ctx)) !== keyval) {
prv[key] = q;
- this.set[key](this.ctx, style[key]);
+ this.set[key](this.ctx, keyval);
}
}
}
@@ -973,14 +978,17 @@ g2.canvasHdl.prototype = {
},
pushStyle(style) {
let cur = {}; // hold changed properties ...
- for (const key in style)
- if (this.get[key]) { // style keys only ...
+ for (const key in style) // allow extended style syntax ('fs-2', ...)
+ if (g2.styleRex.test(key)) { // (extended) style keys only ...
if (typeof style[key] === 'string' && style[key][0] === '@') {
let ref = style[key].substr(1);
style[key] = g2.symbol[ref] || this.get[ref] && this.get[ref](this.ctx);
}
- if (this.cur[key] !== style[key])
- this.set[key](this.ctx, (cur[key] = style[key]));
+ if (this.cur[key] !== style[key]) {
+ if (key in this.set)
+ this.set[key](this.ctx, style[key]);
+ cur[key] = style[key];
+ }
}
this.stack.push(this.cur = Object.assign({}, this.cur, cur));
},
@@ -1052,8 +1060,6 @@ g2.canvasHdl.prototype = {
}
}
-// use it with node.js ... ?
-if (typeof module !== 'undefined') module.exports = g2;
/**
* g2.io (c) 2017-18 Stefan Goessner
* @license MIT License
@@ -1321,7 +1327,7 @@ g2 = Object.assign(g2, {
"use strict"
/**
- * g2.ext (c) 2015-20 Stefan Goessner
+ * g2.ext (c) 2015-21 Stefan Goessner
* @author Stefan Goessner
* @license MIT License
* @requires g2.core.js
@@ -1346,7 +1352,7 @@ g2.NONE = 0x0; g2.OVER = 0x1; g2.DRAG = 0x2; g2.EDIT = 0x4;
* @property {object} [symbol.sqr] Predefined symbol: a little square
* @property {string} [symbol.nodcolor=#333] node color.
* @property {string} [symbol.nodfill=#dedede] node fill color.
- * @property {string} [symbol.nodfill2=#aeaeae] alternate node fill color, somewhat darker.
+ * @property {string} [symbol.nodfill2=#aeaeae] alternate node fill color, somewhat darker.
* @property {string} [symbol.linkcolor=#666] link color.
* @property {string} [symbol.linkfill=rgba(225,225,225,0.75)] link fill color, semi-transparent.
* @property {string} [symbol.dimcolor=darkslategray] dimension color.
@@ -1472,7 +1478,7 @@ g2.markIfc = {
}
}
-g2.prototype.cir.prototype = g2.mix(g2.pointIfc, g2.labelIfc, g2.markIfc, {
+g2.prototype.cir.prototype = g2.mix(g2.labelIfc, g2.markIfc, {
w: 0, // default start angle (used for dash-dot orgin and editing)
lbloc: 'c',
get isSolid() { return this.fs && this.fs !== 'transparent' },
@@ -1682,8 +1688,8 @@ g2.prototype.nod.prototype = g2.mix(g2.prototype.cir.prototype, {
*/
g2.prototype.dblnod = function ({ x = 0, y = 0 }) { return this.addCommand({ c: 'dblnod', a: arguments[0] }); }
g2.prototype.dblnod.prototype = g2.mix(g2.prototype.cir.prototype, {
- get r() { return 6; },
- get isSolid() { return true; },
+ r: 6,
+ isSolid: true,
g2() {
return g2()
.beg({ x: this.x, y: this.y })
@@ -1709,7 +1715,7 @@ g2.prototype.pol.prototype = g2.mix(g2.prototype.nod.prototype, {
g2() {
return g2()
.beg(g2.flatten(this))
- .cir({ r: 6, fs: g2.symbol.nodfill })
+ .cir({ r: 6, fs: '@fs2' })
.cir({ r: 2.5, fs: '@ls', ls: 'transparent' })
.end()
.ins((g) => this.label && this.drawLabel(g));
@@ -2188,10 +2194,10 @@ g2.prototype.chart.prototype = {
];
funcs.forEach(f => this.initFunc(f, ...tmp));
}
- // if (this.xaxis)
- this.xAxis = this.autoAxis(this.get('xmin'), this.get('xmax'), 0, this.b);
- // if (this.yaxis)
- this.yAxis = this.autoAxis(this.get('ymin'), this.get('ymax'), 0, this.h);
+ if (this.xaxis)
+ this.xAxis = this.autoAxis(this.get('xmin'), this.get('xmax'), 0, this.b);
+ if (this.yaxis)
+ this.yAxis = this.autoAxis(this.get('ymin'), this.get('ymax'), 0, this.h);
// draw background & border ...
g.rec({
@@ -2271,15 +2277,14 @@ g2.prototype.chart.prototype = {
}
},
autoAxis(zmin, zmax, tmin, tmax) {
- let base = 2, exp = 1, eps = Math.sqrt(Number.EPSILON),
+ let base = 1, exp = 1, eps = Math.sqrt(Number.EPSILON),
Dz = zmax - zmin || 1, // value range
Dt = tmax - tmin || 1, // area range
scl = Dz > eps ? Dt / Dz : 1, // scale [usr]->[pix]
dz = base * Math.pow(10, exp), // tick size [usr]
dt = Math.floor(scl * dz), // tick size [pix]
N, // # segments
- dt01, // reminder segment
- i0, j0, jth, t0, res;
+ i0, j0, jth, t0;
while (dt < 14 || dt > 35) {
if (dt < 14) {
@@ -2300,8 +2305,6 @@ g2.prototype.chart.prototype = {
: Math.floor(zmin / dz) + 1;
let z0 = i0 * dz;
t0 = Math.round(scl * (z0 - zmin));
- // console.log("Dt="+Dt+",N="+(Dt - t0)/ dt)
- // console.log("DT="+Dt+",N="+(Dt - t0)/ dt)
N = Math.floor((Dt - t0) / dt) + 1;
j0 = base % 2 && i0 % 2 ? i0 + 1 : i0;
jth = exp === 0 && N < 11 ? 1 : base === 2 && N > 9 ? 5 : 2;
@@ -2345,8 +2348,6 @@ g2.prototype.chart.prototype = {
ticklen = showticks ? this.get("xaxis", "ticks", "len") : 0,
showorigin = showaxis && this.get("xaxis", "origin"),
title = this.xaxis && (this.get("xaxis", "title", "text") || this.xaxis.title) || '';
- // console.log(this.xAxis)
- // draw tick/grid lines
g.beg(axisstyle);
for (let i = 0; i < this.xAxis.N; i++) {
tick = this.xAxis.itr(i);
@@ -2950,6 +2951,12 @@ class G2ChartElement extends HTMLElement {
'ymin',
'ymax',
'title',
+ 'xlabels',
+ 'ylabels',
+ 'xticks',
+ 'yticks',
+ 'xtitle',
+ 'ytitle'
];
}
@@ -2972,33 +2979,52 @@ class G2ChartElement extends HTMLElement {
set ymax(q) { return q && +this.setAttribute('ymax', q) }
get title() { return this.getAttribute('title') || ''; }
set title(q) { return q && this.setAttribute('title', q) }
+ get xlabels() { return this.getAttribute('xlabels') !== 'false'; }
+ get ylabels() { return this.getAttribute('ylabels') !== 'false'; }
+ get xticks() { return this.getAttribute('xticks') !== 'false'; }
+ get yticks() { return this.getAttribute('yticks') !== 'false'; }
+ get xtitle() { return this.getAttribute('xtitle'); }
+ get ytitle() { return this.getAttribute('ytitle'); }
connectedCallback() {
this._root.innerHTML = G2ChartElement.template({
width: this.width, height: this.height
});
- this._ctx = this._root.getElementById('cnv').getContext('2d');
+ const xmargin = (this.yticks && 5) + (this.ylabels && 15) + (this.ytitle && 15);
+ const ymargin = (this.xticks && 5) + (this.xlabels && 15) + (this.xtitle && 15);
- const t = 35;
this._chart = {
- x: t,
- y: t,
+ x: xmargin,
+ y: ymargin,
xmin: this.xmin,
xmax: this.xmax,
ymin: this.ymin,
ymax: this.ymax,
title: this.title,
- b: this.width - t * 2,
- h: this.height - t * 2,
- xaxis: () => this.xaxis || {},
- yaxis: () => this.yaxis || {},
+ b: this.width - 5 - xmargin,
+ h: this.height - 5 - ymargin - (this.title && 15),
+ xaxis: () => this.xaxis || { ticks: this.xticks, labels: this.xlabels, title: this.xtitle },
+ yaxis: () => this.yaxis || { ticks: this.yticks, labels: this.ylabels, title: this.ytitle },
title: () => this.title || "",
- funcs: () => this.funcs
+ funcs: []
};
- this._g = g2().del().clr().view({ cartesian: true }).chart(this._chart);
+ if (this.innerHTML) {
+ let res;
+
+ try { res = JSON.parse(this.innerHTML); }
+ catch (e) {
+ console.error(e);
+ this._g.txt({ str: e, y: 5 });
+ }
+
+ this._chart.funcs.push(...G2ChartElement.validateFunc(res));
+ }
+ this._ctx = this._root.getElementById('cnv').getContext('2d');
+ this._g = g2().del().clr().view({ cartesian: true }).chart(this._chart);
+/*
try {
// If not true, the element should be referenced by another module.
if (this.innerHTML !== '') {
@@ -3028,24 +3054,41 @@ class G2ChartElement extends HTMLElement {
});
this.render();
}
+*/
+ this.render();
}
render() {
this._g.exe(this._ctx);
}
-
+/*
setFuncs(funcs) {
this.funcs = funcs;
return this;
}
-
+*/
disconnectedCallback() {
// TODO
}
+ static validateFunc(obj, funcs) {
+ funcs = funcs || [];
+ if (Array.isArray(obj)) // array of functions ...
+ for (const o of obj)
+ G2ChartElement.validateFunc(o, funcs);
+ else if (typeof obj === 'object') { // single function ...
+ if ('fn' in obj) {
+ const fnc = Function('"use strict";return (' + obj['fn'] + ')')();
+ obj.fn = typeof fnc === 'function' ? fnc : undefined; // todo: error message ...
+ }
+ if ('fn' in obj || 'data' in obj)
+ funcs.push(obj);
+ }
+ return funcs;
+ }
+
static template({ width, height }) {
- return ``
+ return ``
}
}
customElements.define('g2-chart', G2ChartElement);
diff --git a/dist/g2.full.js b/dist/g2.full.js
index 7245306..fa2ef73 100644
--- a/dist/g2.full.js
+++ b/dist/g2.full.js
@@ -2,7 +2,7 @@
"use strict"
/**
- * g2.core (c) 2013-20 Stefan Goessner
+ * g2.core (c) 2013-21 Stefan Goessner
* @author Stefan Goessner
* @license MIT License
* @link https://github.com/goessner/g2
@@ -538,6 +538,8 @@ g2.prototype = {
// statics
g2.defaultStyle = { fs: 'transparent', ls: '#000', lw: 1, lc: "butt", lj: "miter", ld: [], ml: 10, sh: [0, 0], lsh: false, font: '14px serif', thal: 'start', tval: 'alphabetic' };
+g2.styleRex = /^(fs|ls|lw|lc|lj|ld|ldoff|ml|sh|lsh|font|thal|tval)([-0-9].*)?$/,
+
g2.symbol = {
unknown: g2().cir({ r: 12, fs: 'orange' }).txt({ str: '?', thal: 'center', tval: 'middle', font: 'bold 20pt serif' })
};
@@ -955,13 +957,16 @@ g2.canvasHdl.prototype = {
let q, prv = {};
for (const key in style) {
if (this.get[key]) { // style keys only ...
+ let keyval = style[key];
if (typeof style[key] === 'string' && style[key][0] === '@') {
- let ref = style[key].substr(1);
- style[key] = g2.symbol[ref] || this.get[ref] && this.get[ref](this.ctx);
+ // also check inherited styles ...
+ const ref = style[key].substr(1);
+ keyval = g2.symbol[ref] || ref in this.get && this.get[ref](this.ctx)
+ || ref in this.cur && this.cur[ref];
}
- if ((q = this.get[key](this.ctx)) !== style[key]) {
+ if ((q = this.get[key](this.ctx)) !== keyval) {
prv[key] = q;
- this.set[key](this.ctx, style[key]);
+ this.set[key](this.ctx, keyval);
}
}
}
@@ -973,14 +978,17 @@ g2.canvasHdl.prototype = {
},
pushStyle(style) {
let cur = {}; // hold changed properties ...
- for (const key in style)
- if (this.get[key]) { // style keys only ...
+ for (const key in style) // allow extended style syntax ('fs-2', ...)
+ if (g2.styleRex.test(key)) { // (extended) style keys only ...
if (typeof style[key] === 'string' && style[key][0] === '@') {
let ref = style[key].substr(1);
style[key] = g2.symbol[ref] || this.get[ref] && this.get[ref](this.ctx);
}
- if (this.cur[key] !== style[key])
- this.set[key](this.ctx, (cur[key] = style[key]));
+ if (this.cur[key] !== style[key]) {
+ if (key in this.set)
+ this.set[key](this.ctx, style[key]);
+ cur[key] = style[key];
+ }
}
this.stack.push(this.cur = Object.assign({}, this.cur, cur));
},
@@ -1052,8 +1060,6 @@ g2.canvasHdl.prototype = {
}
}
-// use it with node.js ... ?
-if (typeof module !== 'undefined') module.exports = g2;
/**
* g2.lib (c) 2013-17 Stefan Goessner
* geometric constants and higher functions
@@ -1230,7 +1236,7 @@ g2 = Object.assign(g2, {
"use strict"
/**
- * g2.ext (c) 2015-20 Stefan Goessner
+ * g2.ext (c) 2015-21 Stefan Goessner
* @author Stefan Goessner
* @license MIT License
* @requires g2.core.js
@@ -1255,7 +1261,7 @@ g2.NONE = 0x0; g2.OVER = 0x1; g2.DRAG = 0x2; g2.EDIT = 0x4;
* @property {object} [symbol.sqr] Predefined symbol: a little square
* @property {string} [symbol.nodcolor=#333] node color.
* @property {string} [symbol.nodfill=#dedede] node fill color.
- * @property {string} [symbol.nodfill2=#aeaeae] alternate node fill color, somewhat darker.
+ * @property {string} [symbol.nodfill2=#aeaeae] alternate node fill color, somewhat darker.
* @property {string} [symbol.linkcolor=#666] link color.
* @property {string} [symbol.linkfill=rgba(225,225,225,0.75)] link fill color, semi-transparent.
* @property {string} [symbol.dimcolor=darkslategray] dimension color.
@@ -1381,7 +1387,7 @@ g2.markIfc = {
}
}
-g2.prototype.cir.prototype = g2.mix(g2.pointIfc, g2.labelIfc, g2.markIfc, {
+g2.prototype.cir.prototype = g2.mix(g2.labelIfc, g2.markIfc, {
w: 0, // default start angle (used for dash-dot orgin and editing)
lbloc: 'c',
get isSolid() { return this.fs && this.fs !== 'transparent' },
@@ -1591,8 +1597,8 @@ g2.prototype.nod.prototype = g2.mix(g2.prototype.cir.prototype, {
*/
g2.prototype.dblnod = function ({ x = 0, y = 0 }) { return this.addCommand({ c: 'dblnod', a: arguments[0] }); }
g2.prototype.dblnod.prototype = g2.mix(g2.prototype.cir.prototype, {
- get r() { return 6; },
- get isSolid() { return true; },
+ r: 6,
+ isSolid: true,
g2() {
return g2()
.beg({ x: this.x, y: this.y })
@@ -1618,7 +1624,7 @@ g2.prototype.pol.prototype = g2.mix(g2.prototype.nod.prototype, {
g2() {
return g2()
.beg(g2.flatten(this))
- .cir({ r: 6, fs: g2.symbol.nodfill })
+ .cir({ r: 6, fs: '@fs2' })
.cir({ r: 2.5, fs: '@ls', ls: 'transparent' })
.end()
.ins((g) => this.label && this.drawLabel(g));
@@ -2588,10 +2594,10 @@ g2.prototype.chart.prototype = {
];
funcs.forEach(f => this.initFunc(f, ...tmp));
}
- // if (this.xaxis)
- this.xAxis = this.autoAxis(this.get('xmin'), this.get('xmax'), 0, this.b);
- // if (this.yaxis)
- this.yAxis = this.autoAxis(this.get('ymin'), this.get('ymax'), 0, this.h);
+ if (this.xaxis)
+ this.xAxis = this.autoAxis(this.get('xmin'), this.get('xmax'), 0, this.b);
+ if (this.yaxis)
+ this.yAxis = this.autoAxis(this.get('ymin'), this.get('ymax'), 0, this.h);
// draw background & border ...
g.rec({
@@ -2671,15 +2677,14 @@ g2.prototype.chart.prototype = {
}
},
autoAxis(zmin, zmax, tmin, tmax) {
- let base = 2, exp = 1, eps = Math.sqrt(Number.EPSILON),
+ let base = 1, exp = 1, eps = Math.sqrt(Number.EPSILON),
Dz = zmax - zmin || 1, // value range
Dt = tmax - tmin || 1, // area range
scl = Dz > eps ? Dt / Dz : 1, // scale [usr]->[pix]
dz = base * Math.pow(10, exp), // tick size [usr]
dt = Math.floor(scl * dz), // tick size [pix]
N, // # segments
- dt01, // reminder segment
- i0, j0, jth, t0, res;
+ i0, j0, jth, t0;
while (dt < 14 || dt > 35) {
if (dt < 14) {
@@ -2700,8 +2705,6 @@ g2.prototype.chart.prototype = {
: Math.floor(zmin / dz) + 1;
let z0 = i0 * dz;
t0 = Math.round(scl * (z0 - zmin));
- // console.log("Dt="+Dt+",N="+(Dt - t0)/ dt)
- // console.log("DT="+Dt+",N="+(Dt - t0)/ dt)
N = Math.floor((Dt - t0) / dt) + 1;
j0 = base % 2 && i0 % 2 ? i0 + 1 : i0;
jth = exp === 0 && N < 11 ? 1 : base === 2 && N > 9 ? 5 : 2;
@@ -2745,8 +2748,6 @@ g2.prototype.chart.prototype = {
ticklen = showticks ? this.get("xaxis", "ticks", "len") : 0,
showorigin = showaxis && this.get("xaxis", "origin"),
title = this.xaxis && (this.get("xaxis", "title", "text") || this.xaxis.title) || '';
- // console.log(this.xAxis)
- // draw tick/grid lines
g.beg(axisstyle);
for (let i = 0; i < this.xAxis.N; i++) {
tick = this.xAxis.itr(i);
diff --git a/dist/g2.html.js b/dist/g2.html.js
index 0b8ca60..1175774 100644
--- a/dist/g2.html.js
+++ b/dist/g2.html.js
@@ -2,7 +2,7 @@
"use strict"
/**
- * g2.core (c) 2013-20 Stefan Goessner
+ * g2.core (c) 2013-21 Stefan Goessner
* @author Stefan Goessner
* @license MIT License
* @link https://github.com/goessner/g2
@@ -538,6 +538,8 @@ g2.prototype = {
// statics
g2.defaultStyle = { fs: 'transparent', ls: '#000', lw: 1, lc: "butt", lj: "miter", ld: [], ml: 10, sh: [0, 0], lsh: false, font: '14px serif', thal: 'start', tval: 'alphabetic' };
+g2.styleRex = /^(fs|ls|lw|lc|lj|ld|ldoff|ml|sh|lsh|font|thal|tval)([-0-9].*)?$/,
+
g2.symbol = {
unknown: g2().cir({ r: 12, fs: 'orange' }).txt({ str: '?', thal: 'center', tval: 'middle', font: 'bold 20pt serif' })
};
@@ -607,6 +609,457 @@ g2.mix = function mix(...protos) {
*/
g2.cpyProp = function (from, fromKey, to, toKey) { Object.defineProperty(to, toKey, Object.getOwnPropertyDescriptor(from, fromKey)); }
+// Html canvas handler
+g2.canvasHdl = function (ctx) {
+ if (this instanceof g2.canvasHdl) {
+ if (ctx instanceof CanvasRenderingContext2D) {
+ this.ctx = ctx;
+ this.cur = g2.defaultStyle;
+ this.stack = [this.cur];
+ this.matrix = [[1, 0, 0, 1, 0.5, 0.5]];
+ this.gridBase = 2;
+ this.gridExp = 1;
+ return this;
+ }
+ else
+ return null;
+ }
+ return g2.canvasHdl.apply(Object.create(g2.canvasHdl.prototype), arguments);
+};
+g2.handler.factory.push((ctx) => ctx instanceof g2.canvasHdl ? ctx
+ : ctx instanceof CanvasRenderingContext2D ? g2.canvasHdl(ctx) : false);
+
+g2.canvasHdl.prototype = {
+ init(grp, style) {
+ this.stack.length = 1;
+ this.matrix.length = 1;
+ this.initStyle(style ? Object.assign({}, this.cur, style) : this.cur);
+ return true;
+ },
+ async exe(commands) {
+ for (let cmd of commands) {
+ // cmd.a is an object offering a `g2` method, so call it and execute its returned commands array.
+ if (cmd.a && cmd.a.g2) {
+ const cmds = cmd.a.g2().commands;
+ // If false, ext was not applied to this cmd. But the command still renders
+ if (cmds) {
+ this.exe(cmds);
+ continue;
+ }
+ }
+ // cmd.a is a `g2` object, so directly execute its commands array.
+ else if (cmd.a && cmd.a.commands) {
+ this.exe(cmd.a.commands);
+ continue;
+ }
+ if (cmd.c && this[cmd.c]) { // explicit command name .. !
+ const rx = this[cmd.c](cmd.a);
+ if (rx && rx instanceof Promise) {
+ await rx;
+ }
+ }
+ }
+ },
+ view({ x = 0, y = 0, scl = 1, cartesian = false }) {
+ this.pushTrf(cartesian ? [scl, 0, 0, -scl, x, this.ctx.canvas.height - 1 - y]
+ : [scl, 0, 0, scl, x, y]);
+ },
+ grid({ color = '#ccc', size } = {}) {
+ let ctx = this.ctx, b = ctx.canvas.width, h = ctx.canvas.height,
+ { x, y, scl } = this.uniTrf,
+ sz = size || this.gridSize(scl),
+ xoff = x % sz, yoff = y % sz;
+ ctx.save();
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
+ ctx.strokeStyle = color;
+ ctx.lineWidth = 1;
+ ctx.beginPath();
+ for (let x = xoff, nx = b + 1; x < nx; x += sz) { ctx.moveTo(x, 0); ctx.lineTo(x, h); }
+ for (let y = yoff, ny = h + 1; y < ny; y += sz) { ctx.moveTo(0, y); ctx.lineTo(b, y); }
+ ctx.stroke();
+ ctx.restore();
+ },
+ clr({ b, h } = {}) {
+ let ctx = this.ctx;
+ ctx.save();
+ ctx.setTransform(1, 0, 0, 1, 0, 0);
+ ctx.clearRect(0, 0, b || ctx.canvas.width, h || ctx.canvas.height);
+ ctx.restore();
+ },
+ cir({ r }) {
+ const { x = 0, y = 0 } = arguments[0].p !== undefined ? arguments[0].p : arguments[0];
+ this.ctx.beginPath();
+ this.ctx.arc(x || 0, y || 0, Math.abs(r), 0, 2 * Math.PI, true);
+ this.drw(arguments[0]);
+ },
+ arc({ r, w = 0, dw = 2 * Math.PI }) {
+ const { x = 0, y = 0 } = arguments[0].p !== undefined ? arguments[0].p : arguments[0];
+ if (Math.abs(dw) > Number.EPSILON && Math.abs(r) > Number.EPSILON) {
+ this.ctx.beginPath();
+ this.ctx.arc(x, y, Math.abs(r), w, w + dw, dw < 0);
+ this.drw(arguments[0]);
+ }
+ else if (Math.abs(dw) < Number.EPSILON && Math.abs(r) > Number.EPSILON) {
+ const cw = Math.cos(w), sw = Math.sin(w);
+ this.ctx.beginPath();
+ this.ctx.moveTo(x - r * cw, y - r * sw);
+ this.ctx.lineTo(x + r * cw, y + r * sw);
+ }
+ // else // nothing to draw with r === 0
+ },
+ ell({ rx, ry, w = 0, dw = 2 * Math.PI, rot = 0 }) {
+ const { x = 0, y = 0 } = arguments[0].p !== undefined ? arguments[0].p : arguments[0];
+ this.ctx.beginPath();
+ this.ctx.ellipse(x, y, Math.abs(rx), Math.abs(ry), rot, w, w + dw, dw < 0);
+ this.drw(arguments[0]);
+ },
+ rec({ b, h }) {
+ const { x = 0, y = 0 } = arguments[0].p !== undefined ? arguments[0].p : arguments[0];
+ const tmp = this.setStyle(arguments[0]);
+ this.ctx.fillRect(x, y, b, h);
+ this.ctx.strokeRect(x, y, b, h);
+ this.resetStyle(tmp);
+ },
+ lin(args) {
+ this.ctx.beginPath();
+ this.ctx.moveTo(args.p1 && args.p1.x || args.x1 || 0, args.p1 && args.p1.y || args.y1 || 0);
+ this.ctx.lineTo(args.p2 && args.p2.x || args.x2 || 0, args.p2 && args.p2.y || args.y2 || 0);
+ this.stroke(args);
+ },
+ ply({ pts, closed, w = 0, _itr }) {
+ if (_itr && _itr.len) {
+ const { x = 0, y = 0 } = arguments[0].p !== undefined ? arguments[0].p : arguments[0];
+ let p, i, len = _itr.len, istrf = !!(x || y || w), cw, sw;
+ if (istrf) this.setTrf([cw = (w ? Math.cos(w) : 1), sw = (w ? Math.sin(w) : 0), -sw, cw, x, y]);
+ this.ctx.beginPath();
+ this.ctx.moveTo((p = _itr(0)).x, p.y);
+ for (i = 1; i < len; i++)
+ this.ctx.lineTo((p = _itr(i)).x, p.y);
+ if (closed) // closed then ..
+ this.ctx.closePath();
+ this.drw(arguments[0]);
+ if (istrf) this.resetTrf();
+ return i - 1; // number of points ..
+ }
+ return 0;
+ },
+ txt({ str, w = 0/*,unsizable*/ }) {
+ const { x = 0, y = 0 } = arguments[0].p !== undefined ? arguments[0].p : arguments[0];
+ const tmp = this.setStyle(arguments[0]),
+ sw = w ? Math.sin(w) : 0,
+ cw = w ? Math.cos(w) : 1,
+ trf = this.isCartesian ? [cw, sw, sw, -cw, x, y]
+ : [cw, sw, -sw, cw, x, y];
+ this.setTrf(trf); // this.setTrf(unsizable ? this.concatTrf(this.unscaleTrf({x,y}),trf) : trf);
+ if (this.ctx.fillStyle === 'rgba(0, 0, 0, 0)') {
+ this.ctx.fillStyle = this.ctx.strokeStyle;
+ tmp.fs = 'transparent';
+ }
+ this.ctx.fillText(str, 0, 0);
+ this.resetTrf();
+ this.resetStyle(tmp);
+ },
+ errorImageStr: "data:image/gif;base64,R0lGODlhHgAeAKIAAAAAmWZmmZnM/////8zMzGZmZgAAAAAAACwAAAAAHgAeAEADimi63P5ryAmEqHfqPRWfRQF+nEeeqImum0oJQxUThGaQ7hSs95ezvB4Q+BvihBSAclk6fgKiAkE0kE6RNqwkUBtMa1OpVlI0lsbmFjrdWbMH5Tdcu6wbf7J8YM9H4y0YAE0+dHVKIV0Efm5VGiEpY1A0UVMSBYtPGl1eNZhnEBGEck6jZ6WfoKmgCQA7",
+ images: Object.create(null),
+ async loadImage(uri) {
+ const download = async (xuri) => {
+ const pimg = new Promise((resolve, reject) => {
+ let img = new Image();
+ img.src = xuri;
+ function error(err) {
+ img.removeEventListener('load', load);
+ img = undefined;
+ reject(err);
+ };
+ function load() {
+ img.removeEventListener('error', error);
+ resolve(img);
+ img = undefined;
+ };
+ img.addEventListener('error', error, { once: true });
+ img.addEventListener('load', load, { once: true });
+ });
+
+ try {
+ return await pimg;
+ } catch (err) {
+ // console.warn(`failed to (pre-)load image; '${xuri}'`, err);
+ if (xuri === this.errorImageStr) {
+ throw err;
+ } else {
+ return await download(this.errorImageStr);
+ }
+ }
+ }
+
+ let img = this.images[uri];
+ if (img !== undefined) {
+ return img instanceof Promise ? await img : img;
+ }
+ img = download(uri);
+ this.images[uri] = img;
+ try {
+ img = await img;
+ } finally {
+ this.images[uri] = img;
+ }
+ return img;
+ },
+ async img({ uri, x = 0, y = 0, b, h, sx = 0, sy = 0, sb, sh, xoff = 0, yoff = 0, w = 0, scl = 1 }) {
+ const img_ = await this.loadImage(uri);
+ this.ctx.save();
+ const cart = this.isCartesian ? -1 : 1;
+ sb = sb || img_.width;
+ b = b || img_.width;
+ sh = (sh || img_.height);
+ h = (h || img_.height) * cart;
+ yoff *= cart;
+ w *= cart;
+ y = this.isCartesian ? -(y / scl) + sy : y / scl;
+ const [cw, sw] = [Math.cos(w), Math.sin(w)];
+ this.ctx.scale(scl, scl * cart);
+ this.ctx.transform(cw, sw, -sw, cw, x / scl, y);
+ this.ctx.drawImage(img_, sx, sy, sb, sh, xoff, yoff, b, h);
+ this.ctx.restore();
+ },
+ use({ grp }) {
+ this.beg(arguments[0]);
+ this.exe(grp.commands);
+ this.end();
+ },
+ beg({ w = 0, scl = 1, matrix/*,unsizable*/ } = {}) {
+ const { x = 0, y = 0 } = arguments[0].p !== undefined ? arguments[0].p : arguments[0];
+ let trf = matrix;
+ if (!trf) {
+ let ssw, scw;
+ ssw = w ? Math.sin(w) * scl : 0;
+ scw = w ? Math.cos(w) * scl : scl;
+ trf = [scw, ssw, -ssw, scw, x, y];
+ }
+ this.pushStyle(arguments[0]);
+ this.pushTrf(trf); // this.pushTrf(unsizable ? this.concatTrf(this.unscaleTrf({x,y}),trf) : trf);
+ },
+ end() {
+ this.popTrf();
+ this.popStyle();
+ },
+ p() { this.ctx.beginPath(); },
+ z() { this.ctx.closePath(); },
+ m({ x, y }) { this.ctx.moveTo(x, y); },
+ l({ x, y }) { this.ctx.lineTo(x, y); },
+ q({ x, y, x1, y1 }) { this.ctx.quadraticCurveTo(x1, y1, x, y); },
+ c({ x, y, x1, y1, x2, y2 }) { this.ctx.bezierCurveTo(x1, y1, x2, y2, x, y); },
+ a({ dw, k, phi, _xp, _yp }) { // todo: fix elliptical arc bug ...
+ const { x = 0, y = 0 } = arguments[0].p !== undefined ? arguments[0].p : arguments[0];
+ if (k === undefined) k = 1; // ratio r1/r2
+ if (Math.abs(dw) > Number.EPSILON) {
+ if (k === 1) { // circular arc ...
+ let x12 = x - _xp, y12 = y - _yp;
+ let tdw_2 = Math.tan(dw / 2),
+ rx = (x12 - y12 / tdw_2) / 2, ry = (y12 + x12 / tdw_2) / 2,
+ R = Math.hypot(rx, ry),
+ w = Math.atan2(-ry, -rx);
+ this.ctx.ellipse(_xp + rx, _yp + ry, R, R, 0, w, w + dw, this.cartesian ? dw > 0 : dw < 0);
+ }
+ else { // elliptical arc .. still buggy .. !
+ if (phi === undefined) phi = 0;
+ let x1 = dw > 0 ? _xp : x,
+ y1 = dw > 0 ? _yp : y,
+ x2 = dw > 0 ? x : _xp,
+ y2 = dw > 0 ? y : _yp;
+ let x12 = x2 - x1, y12 = y2 - y1,
+ _dw = (dw < 0) ? dw : -dw;
+ // if (dw < 0) dw = -dw; // test for bugs .. !
+ let cp = phi ? Math.cos(phi) : 1, sp = phi ? Math.sin(phi) : 0,
+ dx = -x12 * cp - y12 * sp, dy = -x12 * sp - y12 * cp,
+ sdw_2 = Math.sin(_dw / 2),
+ R = Math.sqrt((dx * dx + dy * dy / (k * k)) / (4 * sdw_2 * sdw_2)),
+ w = Math.atan2(k * dx, dy) - _dw / 2,
+ x0 = x1 - R * Math.cos(w),
+ y0 = y1 - R * k * Math.sin(w);
+ this.ctx.ellipse(x0, y0, R, R * k, phi, w, w + dw, this.cartesian ? dw > 0 : dw < 0);
+ }
+ }
+ else
+ this.ctx.lineTo(x, y);
+ },
+
+ stroke({ d } = {}) {
+ let tmp = this.setStyle(arguments[0]);
+ d ? this.ctx.stroke(new Path2D(d)) : this.ctx.stroke(); // SVG path syntax
+ this.resetStyle(tmp);
+ },
+ fill({ d } = {}) {
+ let tmp = this.setStyle(arguments[0]);
+ d ? this.ctx.fill(new Path2D(d)) : this.ctx.fill(); // SVG path syntax
+ this.resetStyle(tmp);
+ },
+ drw({ d, lsh } = {}) {
+ let ctx = this.ctx,
+ tmp = this.setStyle(arguments[0]),
+ p = d && new Path2D(d); // SVG path syntax
+ d ? ctx.fill(p) : ctx.fill();
+ if (ctx.shadowColor !== 'rgba(0, 0, 0, 0)' && ctx.fillStyle !== 'rgba(0, 0, 0, 0)' && !lsh) {
+ let shc = ctx.shadowColor; // usually avoid stroke shadow when filling ...
+ ctx.shadowColor = 'rgba(0, 0, 0, 0)';
+ d ? ctx.stroke(p) : ctx.stroke();
+ ctx.shadowColor = shc;
+ }
+ else
+ d ? ctx.stroke(p) : ctx.stroke();
+ this.resetStyle(tmp);
+ },
+
+ // State management (transform & style)
+ // getters & setters
+ get: {
+ fs: (ctx) => ctx.fillStyle,
+ ls: (ctx) => ctx.strokeStyle,
+ lw: (ctx) => ctx.lineWidth,
+ lc: (ctx) => ctx.lineCap,
+ lj: (ctx) => ctx.lineJoin,
+ ld: (ctx) => ctx.getLineDash(),
+ ldoff: (ctx) => ctx.lineDashOffset,
+ ml: (ctx) => ctx.miterLimit,
+ sh: (ctx) => [ctx.shadowOffsetX || 0, ctx.shadowOffsetY || 0,
+ ctx.shadowBlur || 0, ctx.shadowColor || 'black'],
+ font: (ctx) => ctx.font,
+ thal: (ctx) => ctx.textAlign,
+ tval: (ctx) => ctx.textBaseline,
+ },
+ set: {
+ fs: (ctx, q) => { ctx.fillStyle = q; },
+ ls: (ctx, q) => { ctx.strokeStyle = q; },
+ lw: (ctx, q) => { ctx.lineWidth = q; },
+ lc: (ctx, q) => { ctx.lineCap = q; },
+ lj: (ctx, q) => { ctx.lineJoin = q; },
+ ld: (ctx, q) => { ctx.setLineDash(q); },
+ ldoff: (ctx, q) => { ctx.lineDashOffset = q; },
+ ml: (ctx, q) => { ctx.miterLimit = q; },
+ sh: (ctx, q) => {
+ if (q) {
+ ctx.shadowOffsetX = q[0] || 0;
+ ctx.shadowOffsetY = q[1] || 0;
+ ctx.shadowBlur = q[2] || 0;
+ ctx.shadowColor = q[3] || 'black';
+ }
+ },
+ font: (ctx, q) => { ctx.font = q; },
+ thal: (ctx, q) => { ctx.textAlign = q; },
+ tval: (ctx, q) => { ctx.textBaseline = q; }
+ },
+ initStyle(style) {
+ for (const key in style)
+ if (this.get[key] && this.get[key](this.ctx) !== style[key])
+ this.set[key](this.ctx, style[key]);
+ },
+ setStyle(style) { // short circuit style setting
+ let q, prv = {};
+ for (const key in style) {
+ if (this.get[key]) { // style keys only ...
+ let keyval = style[key];
+ if (typeof style[key] === 'string' && style[key][0] === '@') {
+ // also check inherited styles ...
+ const ref = style[key].substr(1);
+ keyval = g2.symbol[ref] || ref in this.get && this.get[ref](this.ctx)
+ || ref in this.cur && this.cur[ref];
+ }
+ if ((q = this.get[key](this.ctx)) !== keyval) {
+ prv[key] = q;
+ this.set[key](this.ctx, keyval);
+ }
+ }
+ }
+ return prv;
+ },
+ resetStyle(style) { // short circuit style reset
+ for (const key in style)
+ this.set[key](this.ctx, style[key]);
+ },
+ pushStyle(style) {
+ let cur = {}; // hold changed properties ...
+ for (const key in style) // allow extended style syntax ('fs-2', ...)
+ if (g2.styleRex.test(key)) { // (extended) style keys only ...
+ if (typeof style[key] === 'string' && style[key][0] === '@') {
+ let ref = style[key].substr(1);
+ style[key] = g2.symbol[ref] || this.get[ref] && this.get[ref](this.ctx);
+ }
+ if (this.cur[key] !== style[key]) {
+ if (key in this.set)
+ this.set[key](this.ctx, style[key]);
+ cur[key] = style[key];
+ }
+ }
+ this.stack.push(this.cur = Object.assign({}, this.cur, cur));
+ },
+ popStyle() {
+ let cur = this.stack.pop();
+ this.cur = this.stack[this.stack.length - 1];
+ for (const key in this.cur)
+ if (this.get[key] && this.cur[key] !== cur[key])
+ this.set[key](this.ctx, this.cur[key]);
+ },
+ concatTrf(q, t) {
+ return [
+ q[0] * t[0] + q[2] * t[1],
+ q[1] * t[0] + q[3] * t[1],
+ q[0] * t[2] + q[2] * t[3],
+ q[1] * t[2] + q[3] * t[3],
+ q[0] * t[4] + q[2] * t[5] + q[4],
+ q[1] * t[4] + q[3] * t[5] + q[5]
+ ];
+ },
+ initTrf() {
+ this.ctx.setTransform(...this.matrix[0]);
+ },
+ setTrf(t) {
+ this.ctx.setTransform(...this.concatTrf(this.matrix[this.matrix.length - 1], t));
+ },
+ resetTrf() {
+ this.ctx.setTransform(...this.matrix[this.matrix.length - 1]);
+ },
+ pushTrf(t) {
+ let q_t = this.concatTrf(this.matrix[this.matrix.length - 1], t);
+ this.matrix.push(q_t);
+ this.ctx.setTransform(...q_t);
+ },
+ popTrf() {
+ this.matrix.pop();
+ this.ctx.setTransform(...this.matrix[this.matrix.length - 1]);
+ },
+ get isCartesian() { // det of mat2x2 < 0 !
+ let m = this.matrix[this.matrix.length - 1];
+ return m[0] * m[3] - m[1] * m[2] < 0;
+ },
+ get uniTrf() {
+ let m = this.matrix[this.matrix.length - 1];
+ return { x: m[4], y: m[5], scl: Math.hypot(m[0], m[1]), cartesian: m[0] * m[3] - m[1] * m[2] < 0 };
+ },
+ unscaleTrf({ x, y }) { // remove scaling effect (make unzoomable with respect to (x,y))
+ let m = this.matrix[this.matrix.length - 1],
+ invscl = 1 / Math.hypot(m[0], m[1]);
+ return [invscl, 0, 0, invscl, (1 - invscl) * x, (1 - invscl) * y];
+ },
+ gridSize(scl) {
+ let base = this.gridBase, exp = this.gridExp, sz;
+ while ((sz = scl * base * Math.pow(10, exp)) < 14 || sz > 35) {
+ if (sz < 14) {
+ if (base == 1) base = 2;
+ else if (base == 2) base = 5;
+ else if (base == 5) { base = 1; exp++; }
+ }
+ else {
+ if (base == 1) { base = 5; exp--; }
+ else if (base == 2) base = 1;
+ else if (base == 5) base = 2;
+ }
+ }
+ this.gridBase = base;
+ this.gridExp = exp;
+ return sz;
+ }
+}
+
/**
* g2.io (c) 2017-18 Stefan Goessner
* @license MIT License
@@ -874,7 +1327,7 @@ g2 = Object.assign(g2, {
"use strict"
/**
- * g2.ext (c) 2015-20 Stefan Goessner
+ * g2.ext (c) 2015-21 Stefan Goessner
* @author Stefan Goessner
* @license MIT License
* @requires g2.core.js
@@ -899,7 +1352,7 @@ g2.NONE = 0x0; g2.OVER = 0x1; g2.DRAG = 0x2; g2.EDIT = 0x4;
* @property {object} [symbol.sqr] Predefined symbol: a little square
* @property {string} [symbol.nodcolor=#333] node color.
* @property {string} [symbol.nodfill=#dedede] node fill color.
- * @property {string} [symbol.nodfill2=#aeaeae] alternate node fill color, somewhat darker.
+ * @property {string} [symbol.nodfill2=#aeaeae] alternate node fill color, somewhat darker.
* @property {string} [symbol.linkcolor=#666] link color.
* @property {string} [symbol.linkfill=rgba(225,225,225,0.75)] link fill color, semi-transparent.
* @property {string} [symbol.dimcolor=darkslategray] dimension color.
@@ -972,7 +1425,8 @@ g2.labelIfc = {
const font = lbl.font || g2.defaultStyle.font;
const h = parseInt(font); // font height (px assumed !)
const str = this.getLabelString();
- const rx = (str.length || 1) * 0.75 * h / 2, ry = 1.25 * h / 2; // ellipse semi-axes length
+ const rx = (str.length || 1) * 0.65 * h / 2,
+ ry = 1.25 * h / 2; // ellipse semi-axes length
const pos = this.pointAt(lbl.loc || this.lbloc || 'se');
const off = this.getLabelOffset();
const p = {
@@ -1193,9 +1647,9 @@ g2.prototype.hdl.prototype = g2.mix(g2.prototype.cir.prototype, {
get lsh() { return this.state & g2.OVER; },
get sh() { return this.state & g2.OVER ? [0, 0, 5, "black"] : false },
g2() {
- const { x, y, r, b = 4, shape = 'cir', ls = 'black', fs = '#ccc', sh } = this;
- return shape === 'cir' ? g2().cir({ x, y, r, ls, fs, sh }).ins((g) => this.label && this.drawLabel(g))
- : g2().rec({ x: x - b, y: y - b, b: 2 * b, h: 2 * b, ls, fs, sh }).ins((g) => this.label && this.drawLabel(g));
+ const { x, y, r, b = 4, ls = 'black', fs = 'palegreen', sh } = this;
+
+ return g2().cir({ x, y, r, ls, fs, sh }).ins((g) => this.label && this.drawLabel(g));
}
});
@@ -1235,8 +1689,8 @@ g2.prototype.nod.prototype = g2.mix(g2.prototype.cir.prototype, {
*/
g2.prototype.dblnod = function ({ x = 0, y = 0 }) { return this.addCommand({ c: 'dblnod', a: arguments[0] }); }
g2.prototype.dblnod.prototype = g2.mix(g2.prototype.cir.prototype, {
- get r() { return 6; },
- get isSolid() { return true; },
+ r: 6,
+ isSolid: true,
g2() {
return g2()
.beg({ x: this.x, y: this.y })
@@ -1262,7 +1716,7 @@ g2.prototype.pol.prototype = g2.mix(g2.prototype.nod.prototype, {
g2() {
return g2()
.beg(g2.flatten(this))
- .cir({ r: 6, fs: g2.symbol.nodfill })
+ .cir({ r: 6, fs: '@fs2' })
.cir({ r: 2.5, fs: '@ls', ls: 'transparent' })
.end()
.ins((g) => this.label && this.drawLabel(g));
@@ -2457,7 +2911,7 @@ const canvasInteractor = {
};
/**
- * g2.element.js (c) 2019-20 Stefan Goessner
+ * g2.element.js (c) 2019-21 Stefan Goessner
* @license MIT License
*/
"use strict";
diff --git a/dist/g2.js b/dist/g2.js
index 91f63c5..ac5e5eb 100644
--- a/dist/g2.js
+++ b/dist/g2.js
@@ -1,6 +1,6 @@
"use strict";
/**
- * g2.core (c) 2013-20 Stefan Goessner
+ * g2.core (c) 2013-21 Stefan Goessner
* @author Stefan Goessner
* @license MIT License
* @link https://github.com/goessner/g2
@@ -14,7 +14,7 @@
* .lin({x1:50,y1:50,x2:100,y2:100}) // Append ...
* .lin({x1:100,y1:100,x2:200,y2:50}) // ... commands.
* .exe(ctx); // Execute commands addressing canvas context.
- */function g2(opts){let o=Object.create(g2.prototype);o.commands=[];if(opts)Object.assign(o,opts);return o}g2.prototype={clr(){return this.addCommand({c:"clr"})},view({scl:scl,x:x,y:y,cartesian:cartesian}){return this.addCommand({c:"view",a:arguments[0]})},grid({color:color,size:size}={}){return this.addCommand({c:"grid",a:arguments[0]})},cir({x:x,y:y,r:r,w:w}){return this.addCommand({c:"cir",a:arguments[0]})},ell({x:x,y:y,rx:rx,ry:ry,w:w,dw:dw,rot:rot}){return this.addCommand({c:"ell",a:arguments[0]})},arc({x:x,y:y,r:r,w:w,dw:dw}){return this.addCommand({c:"arc",a:arguments[0]})},rec({x:x,y:y,b:b,h:h}){return this.addCommand({c:"rec",a:arguments[0]})},lin({x1:x1,y1:y1,x2:x2,y2:y2}){return this.addCommand({c:"lin",a:arguments[0]})},ply({pts:pts,format:format,closed:closed,x:x,y:y,w:w}){arguments[0]._itr=format&&g2.pntIterator[format](pts)||g2.pntItrOf(pts);return this.addCommand({c:"ply",a:arguments[0]})},txt({str:str,x:x,y:y,w:w}){return this.addCommand({c:"txt",a:arguments[0]})},use({grp:grp,x:x,y:y,w:w,scl:scl}){if(grp&&grp!==this){if(typeof grp==="string")arguments[0].grp=g2.symbol[grp in g2.symbol?grp:"unknown"];this.addCommand({c:"use",a:arguments[0]})}return this},img({uri:uri,x:x,y:y,b:b,h:h,sx:sx,sy:sy,sb:sb,sh:sh,xoff:xoff,yoff:yoff,w:w,scl:scl}){return this.addCommand({c:"img",a:arguments[0]})},beg({x:x,y:y,w:w,scl:scl,matrix:matrix}={}){return this.addCommand({c:"beg",a:arguments[0]})},end(){let myBeg=1,findMyBeg=cmd=>{if(cmd.c==="beg")myBeg--;else if(cmd.c==="end")myBeg++;return myBeg===0};return g2.cmdIdxBy(this.commands,findMyBeg)!==false?this.addCommand({c:"end"}):this},p(){return this.addCommand({c:"p"})},z(){return this.addCommand({c:"z"})},m({x:x,y:y}){return this.addCommand({c:"m",a:arguments[0]})},l({x:x,y:y}){return this.addCommand({c:"l",a:arguments[0]})},q({x1:x1,y1:y1,x:x,y:y}){return this.addCommand({c:"q",a:arguments[0]})},c({x1:x1,y1:y1,x2:x2,y2:y2,x:x,y:y}){return this.addCommand({c:"c",a:arguments[0]})},a({dw:dw,x:x,y:y}){let prvcmd=this.commands[this.commands.length-1];g2.cpyProp(prvcmd.a,"x",arguments[0],"_xp");g2.cpyProp(prvcmd.a,"y",arguments[0],"_yp");return this.addCommand({c:"a",a:arguments[0]})},stroke({d:d}={}){return this.addCommand({c:"stroke",a:arguments[0]})},fill({d:d}={}){return this.addCommand({c:"fill",a:arguments[0]})},drw({d:d,lsh:lsh}={}){return this.addCommand({c:"drw",a:arguments[0]})},del(idx){this.commands.length=idx||0;return this},ins(arg){return typeof arg==="function"?arg(this)||this:typeof arg==="object"?(this.commands.push({a:arg}),this):this},exe(ctx){let handler=g2.handler(ctx);if(handler&&handler.init(this))handler.exe(this.commands);return this},addCommand({c:c,a:a}){if(a&&Object.getPrototypeOf(a)===Object.prototype){for(const key in a){if(!Object.getOwnPropertyDescriptor(a,key).get&&key[0]!=="_"&&typeof a[key]==="function"){Object.defineProperty(a,key,{get:a[key],enumerable:true,configurable:true,writabel:false})}if(typeof a[key]==="string"&&a[key][0]==="@"){const refidIdx=a[key].indexOf(".");const refid=refidIdx>0?a[key].substr(1,refidIdx-1):"";const refkey=refid?a[key].substr(refidIdx+1):"";const refcmd=refid?()=>this.commands.find(cmd=>cmd.a&&cmd.a.id===refid):undefined;if(refcmd)Object.defineProperty(a,key,{get:function(){const rc=refcmd();return rc&&refkey in rc.a?rc.a[refkey]:0},enumerable:true,configurable:true,writabel:false})}}if(g2.prototype[c].prototype)Object.setPrototypeOf(a,g2.prototype[c].prototype)}this.commands.push(arguments[0]);return this}};g2.defaultStyle={fs:"transparent",ls:"#000",lw:1,lc:"butt",lj:"miter",ld:[],ml:10,sh:[0,0],lsh:false,font:"14px serif",thal:"start",tval:"alphabetic"};g2.symbol={unknown:g2().cir({r:12,fs:"orange"}).txt({str:"?",thal:"center",tval:"middle",font:"bold 20pt serif"})};g2.handler=function(ctx){let hdl;for(let h of g2.handler.factory)if((hdl=h(ctx))!==false)return hdl;return false};g2.handler.factory=[];g2.pntIterator={"x,y":function(pts){function pitr(i){return{x:pts[2*i],y:pts[2*i+1]}}Object.defineProperty(pitr,"len",{get:()=>pts.length/2,enumerable:true,configurable:true,writabel:false});return pitr},"[x,y]":function(pts){function pitr(i){return pts[i]?{x:pts[i][0],y:pts[i][1]}:undefined}Object.defineProperty(pitr,"len",{get:()=>pts.length,enumerable:true,configurable:true,writabel:false});return pitr},"{x,y}":function(pts){function pitr(i){return pts[i]}Object.defineProperty(pitr,"len",{get:()=>pts.length,enumerable:true,configurable:true,writabel:false});return pitr}};g2.pntItrOf=function(pts){return!(pts&&pts.length)?undefined:typeof pts[0]==="number"?g2.pntIterator["x,y"](pts):Array.isArray(pts[0])&&pts[0].length>=2?g2.pntIterator["[x,y]"](pts):typeof pts[0]==="object"&&"x"in pts[0]&&"y"in pts[0]?g2.pntIterator["{x,y}"](pts):undefined};g2.cmdIdxBy=function(cmds,callbk){for(let i=cmds.length-1;i>=0;i--)if(callbk(cmds[i],i,cmds))return i;return false};g2.mix=function mix(...protos){let mixture={};for(const p of protos)mixture=Object.defineProperties(mixture,Object.getOwnPropertyDescriptors(p));return mixture};g2.cpyProp=function(from,fromKey,to,toKey){Object.defineProperty(to,toKey,Object.getOwnPropertyDescriptor(from,fromKey))};g2.canvasHdl=function(ctx){if(this instanceof g2.canvasHdl){if(ctx instanceof CanvasRenderingContext2D){this.ctx=ctx;this.cur=g2.defaultStyle;this.stack=[this.cur];this.matrix=[[1,0,0,1,.5,.5]];this.gridBase=2;this.gridExp=1;return this}else return null}return g2.canvasHdl.apply(Object.create(g2.canvasHdl.prototype),arguments)};g2.handler.factory.push(ctx=>ctx instanceof g2.canvasHdl?ctx:ctx instanceof CanvasRenderingContext2D?g2.canvasHdl(ctx):false);g2.canvasHdl.prototype={init(grp,style){this.stack.length=1;this.matrix.length=1;this.initStyle(style?Object.assign({},this.cur,style):this.cur);return true},async exe(commands){for(let cmd of commands){if(cmd.a&&cmd.a.g2){const cmds=cmd.a.g2().commands;if(cmds){this.exe(cmds);continue}}else if(cmd.a&&cmd.a.commands){this.exe(cmd.a.commands);continue}if(cmd.c&&this[cmd.c]){const rx=this[cmd.c](cmd.a);if(rx&&rx instanceof Promise){await rx}}}},view({x:x=0,y:y=0,scl:scl=1,cartesian:cartesian=false}){this.pushTrf(cartesian?[scl,0,0,-scl,x,this.ctx.canvas.height-1-y]:[scl,0,0,scl,x,y])},grid({color:color="#ccc",size:size}={}){let ctx=this.ctx,b=ctx.canvas.width,h=ctx.canvas.height,{x:x,y:y,scl:scl}=this.uniTrf,sz=size||this.gridSize(scl),xoff=x%sz,yoff=y%sz;ctx.save();ctx.setTransform(1,0,0,1,0,0);ctx.strokeStyle=color;ctx.lineWidth=1;ctx.beginPath();for(let x=xoff,nx=b+1;xNumber.EPSILON&&Math.abs(r)>Number.EPSILON){this.ctx.beginPath();this.ctx.arc(x,y,Math.abs(r),w,w+dw,dw<0);this.drw(arguments[0])}else if(Math.abs(dw)Number.EPSILON){const cw=Math.cos(w),sw=Math.sin(w);this.ctx.beginPath();this.ctx.moveTo(x-r*cw,y-r*sw);this.ctx.lineTo(x+r*cw,y+r*sw)}},ell({rx:rx,ry:ry,w:w=0,dw:dw=2*Math.PI,rot:rot=0}){const{x:x=0,y:y=0}=arguments[0].p!==undefined?arguments[0].p:arguments[0];this.ctx.beginPath();this.ctx.ellipse(x,y,Math.abs(rx),Math.abs(ry),rot,w,w+dw,dw<0);this.drw(arguments[0])},rec({b:b,h:h}){const{x:x=0,y:y=0}=arguments[0].p!==undefined?arguments[0].p:arguments[0];const tmp=this.setStyle(arguments[0]);this.ctx.fillRect(x,y,b,h);this.ctx.strokeRect(x,y,b,h);this.resetStyle(tmp)},lin(args){this.ctx.beginPath();this.ctx.moveTo(args.p1&&args.p1.x||args.x1||0,args.p1&&args.p1.y||args.y1||0);this.ctx.lineTo(args.p2&&args.p2.x||args.x2||0,args.p2&&args.p2.y||args.y2||0);this.stroke(args)},ply({pts:pts,closed:closed,w:w=0,_itr:_itr}){if(_itr&&_itr.len){const{x:x=0,y:y=0}=arguments[0].p!==undefined?arguments[0].p:arguments[0];let p,i,len=_itr.len,istrf=!!(x||y||w),cw,sw;if(istrf)this.setTrf([cw=w?Math.cos(w):1,sw=w?Math.sin(w):0,-sw,cw,x,y]);this.ctx.beginPath();this.ctx.moveTo((p=_itr(0)).x,p.y);for(i=1;i{const pimg=new Promise((resolve,reject)=>{let img=new Image;img.src=xuri;function error(err){img.removeEventListener("load",load);img=undefined;reject(err)}function load(){img.removeEventListener("error",error);resolve(img);img=undefined}img.addEventListener("error",error,{once:true});img.addEventListener("load",load,{once:true})});try{return await pimg}catch(err){if(xuri===this.errorImageStr){throw err}else{return await download(this.errorImageStr)}}};let img=this.images[uri];if(img!==undefined){return img instanceof Promise?await img:img}img=download(uri);this.images[uri]=img;try{img=await img}finally{this.images[uri]=img}return img},async img({uri:uri,x:x=0,y:y=0,b:b,h:h,sx:sx=0,sy:sy=0,sb:sb,sh:sh,xoff:xoff=0,yoff:yoff=0,w:w=0,scl:scl=1}){const img_=await this.loadImage(uri);this.ctx.save();const cart=this.isCartesian?-1:1;sb=sb||img_.width;b=b||img_.width;sh=sh||img_.height;h=(h||img_.height)*cart;yoff*=cart;w*=cart;y=this.isCartesian?-(y/scl)+sy:y/scl;const[cw,sw]=[Math.cos(w),Math.sin(w)];this.ctx.scale(scl,scl*cart);this.ctx.transform(cw,sw,-sw,cw,x/scl,y);this.ctx.drawImage(img_,sx,sy,sb,sh,xoff,yoff,b,h);this.ctx.restore()},use({grp:grp}){this.beg(arguments[0]);this.exe(grp.commands);this.end()},beg({w:w=0,scl:scl=1,matrix:matrix}={}){const{x:x=0,y:y=0}=arguments[0].p!==undefined?arguments[0].p:arguments[0];let trf=matrix;if(!trf){let ssw,scw;ssw=w?Math.sin(w)*scl:0;scw=w?Math.cos(w)*scl:scl;trf=[scw,ssw,-ssw,scw,x,y]}this.pushStyle(arguments[0]);this.pushTrf(trf)},end(){this.popTrf();this.popStyle()},p(){this.ctx.beginPath()},z(){this.ctx.closePath()},m({x:x,y:y}){this.ctx.moveTo(x,y)},l({x:x,y:y}){this.ctx.lineTo(x,y)},q({x:x,y:y,x1:x1,y1:y1}){this.ctx.quadraticCurveTo(x1,y1,x,y)},c({x:x,y:y,x1:x1,y1:y1,x2:x2,y2:y2}){this.ctx.bezierCurveTo(x1,y1,x2,y2,x,y)},a({dw:dw,k:k,phi:phi,_xp:_xp,_yp:_yp}){const{x:x=0,y:y=0}=arguments[0].p!==undefined?arguments[0].p:arguments[0];if(k===undefined)k=1;if(Math.abs(dw)>Number.EPSILON){if(k===1){let x12=x-_xp,y12=y-_yp;let tdw_2=Math.tan(dw/2),rx=(x12-y12/tdw_2)/2,ry=(y12+x12/tdw_2)/2,R=Math.hypot(rx,ry),w=Math.atan2(-ry,-rx);this.ctx.ellipse(_xp+rx,_yp+ry,R,R,0,w,w+dw,this.cartesian?dw>0:dw<0)}else{if(phi===undefined)phi=0;let x1=dw>0?_xp:x,y1=dw>0?_yp:y,x2=dw>0?x:_xp,y2=dw>0?y:_yp;let x12=x2-x1,y12=y2-y1,_dw=dw<0?dw:-dw;let cp=phi?Math.cos(phi):1,sp=phi?Math.sin(phi):0,dx=-x12*cp-y12*sp,dy=-x12*sp-y12*cp,sdw_2=Math.sin(_dw/2),R=Math.sqrt((dx*dx+dy*dy/(k*k))/(4*sdw_2*sdw_2)),w=Math.atan2(k*dx,dy)-_dw/2,x0=x1-R*Math.cos(w),y0=y1-R*k*Math.sin(w);this.ctx.ellipse(x0,y0,R,R*k,phi,w,w+dw,this.cartesian?dw>0:dw<0)}}else this.ctx.lineTo(x,y)},stroke({d:d}={}){let tmp=this.setStyle(arguments[0]);d?this.ctx.stroke(new Path2D(d)):this.ctx.stroke();this.resetStyle(tmp)},fill({d:d}={}){let tmp=this.setStyle(arguments[0]);d?this.ctx.fill(new Path2D(d)):this.ctx.fill();this.resetStyle(tmp)},drw({d:d,lsh:lsh}={}){let ctx=this.ctx,tmp=this.setStyle(arguments[0]),p=d&&new Path2D(d);d?ctx.fill(p):ctx.fill();if(ctx.shadowColor!=="rgba(0, 0, 0, 0)"&&ctx.fillStyle!=="rgba(0, 0, 0, 0)"&&!lsh){let shc=ctx.shadowColor;ctx.shadowColor="rgba(0, 0, 0, 0)";d?ctx.stroke(p):ctx.stroke();ctx.shadowColor=shc}else d?ctx.stroke(p):ctx.stroke();this.resetStyle(tmp)},get:{fs:ctx=>ctx.fillStyle,ls:ctx=>ctx.strokeStyle,lw:ctx=>ctx.lineWidth,lc:ctx=>ctx.lineCap,lj:ctx=>ctx.lineJoin,ld:ctx=>ctx.getLineDash(),ldoff:ctx=>ctx.lineDashOffset,ml:ctx=>ctx.miterLimit,sh:ctx=>[ctx.shadowOffsetX||0,ctx.shadowOffsetY||0,ctx.shadowBlur||0,ctx.shadowColor||"black"],font:ctx=>ctx.font,thal:ctx=>ctx.textAlign,tval:ctx=>ctx.textBaseline},set:{fs:(ctx,q)=>{ctx.fillStyle=q},ls:(ctx,q)=>{ctx.strokeStyle=q},lw:(ctx,q)=>{ctx.lineWidth=q},lc:(ctx,q)=>{ctx.lineCap=q},lj:(ctx,q)=>{ctx.lineJoin=q},ld:(ctx,q)=>{ctx.setLineDash(q)},ldoff:(ctx,q)=>{ctx.lineDashOffset=q},ml:(ctx,q)=>{ctx.miterLimit=q},sh:(ctx,q)=>{if(q){ctx.shadowOffsetX=q[0]||0;ctx.shadowOffsetY=q[1]||0;ctx.shadowBlur=q[2]||0;ctx.shadowColor=q[3]||"black"}},font:(ctx,q)=>{ctx.font=q},thal:(ctx,q)=>{ctx.textAlign=q},tval:(ctx,q)=>{ctx.textBaseline=q}},initStyle(style){for(const key in style)if(this.get[key]&&this.get[key](this.ctx)!==style[key])this.set[key](this.ctx,style[key])},setStyle(style){let q,prv={};for(const key in style){if(this.get[key]){if(typeof style[key]==="string"&&style[key][0]==="@"){let ref=style[key].substr(1);style[key]=g2.symbol[ref]||this.get[ref]&&this.get[ref](this.ctx)}if((q=this.get[key](this.ctx))!==style[key]){prv[key]=q;this.set[key](this.ctx,style[key])}}}return prv},resetStyle(style){for(const key in style)this.set[key](this.ctx,style[key])},pushStyle(style){let cur={};for(const key in style)if(this.get[key]){if(typeof style[key]==="string"&&style[key][0]==="@"){let ref=style[key].substr(1);style[key]=g2.symbol[ref]||this.get[ref]&&this.get[ref](this.ctx)}if(this.cur[key]!==style[key])this.set[key](this.ctx,cur[key]=style[key])}this.stack.push(this.cur=Object.assign({},this.cur,cur))},popStyle(){let cur=this.stack.pop();this.cur=this.stack[this.stack.length-1];for(const key in this.cur)if(this.get[key]&&this.cur[key]!==cur[key])this.set[key](this.ctx,this.cur[key])},concatTrf(q,t){return[q[0]*t[0]+q[2]*t[1],q[1]*t[0]+q[3]*t[1],q[0]*t[2]+q[2]*t[3],q[1]*t[2]+q[3]*t[3],q[0]*t[4]+q[2]*t[5]+q[4],q[1]*t[4]+q[3]*t[5]+q[5]]},initTrf(){this.ctx.setTransform(...this.matrix[0])},setTrf(t){this.ctx.setTransform(...this.concatTrf(this.matrix[this.matrix.length-1],t))},resetTrf(){this.ctx.setTransform(...this.matrix[this.matrix.length-1])},pushTrf(t){let q_t=this.concatTrf(this.matrix[this.matrix.length-1],t);this.matrix.push(q_t);this.ctx.setTransform(...q_t)},popTrf(){this.matrix.pop();this.ctx.setTransform(...this.matrix[this.matrix.length-1])},get isCartesian(){let m=this.matrix[this.matrix.length-1];return m[0]*m[3]-m[1]*m[2]<0},get uniTrf(){let m=this.matrix[this.matrix.length-1];return{x:m[4],y:m[5],scl:Math.hypot(m[0],m[1]),cartesian:m[0]*m[3]-m[1]*m[2]<0}},unscaleTrf({x:x,y:y}){let m=this.matrix[this.matrix.length-1],invscl=1/Math.hypot(m[0],m[1]);return[invscl,0,0,invscl,(1-invscl)*x,(1-invscl)*y]},gridSize(scl){let base=this.gridBase,exp=this.gridExp,sz;while((sz=scl*base*Math.pow(10,exp))<14||sz>35){if(sz<14){if(base==1)base=2;else if(base==2)base=5;else if(base==5){base=1;exp++}}else{if(base==1){base=5;exp--}else if(base==2)base=1;else if(base==5)base=2}}this.gridBase=base;this.gridExp=exp;return sz}};if(typeof module!=="undefined")module.exports=g2;
+ */function g2(opts){let o=Object.create(g2.prototype);o.commands=[];if(opts)Object.assign(o,opts);return o}g2.prototype={clr(){return this.addCommand({c:"clr"})},view({scl:scl,x:x,y:y,cartesian:cartesian}){return this.addCommand({c:"view",a:arguments[0]})},grid({color:color,size:size}={}){return this.addCommand({c:"grid",a:arguments[0]})},cir({x:x,y:y,r:r,w:w}){return this.addCommand({c:"cir",a:arguments[0]})},ell({x:x,y:y,rx:rx,ry:ry,w:w,dw:dw,rot:rot}){return this.addCommand({c:"ell",a:arguments[0]})},arc({x:x,y:y,r:r,w:w,dw:dw}){return this.addCommand({c:"arc",a:arguments[0]})},rec({x:x,y:y,b:b,h:h}){return this.addCommand({c:"rec",a:arguments[0]})},lin({x1:x1,y1:y1,x2:x2,y2:y2}){return this.addCommand({c:"lin",a:arguments[0]})},ply({pts:pts,format:format,closed:closed,x:x,y:y,w:w}){arguments[0]._itr=format&&g2.pntIterator[format](pts)||g2.pntItrOf(pts);return this.addCommand({c:"ply",a:arguments[0]})},txt({str:str,x:x,y:y,w:w}){return this.addCommand({c:"txt",a:arguments[0]})},use({grp:grp,x:x,y:y,w:w,scl:scl}){if(grp&&grp!==this){if(typeof grp==="string")arguments[0].grp=g2.symbol[grp in g2.symbol?grp:"unknown"];this.addCommand({c:"use",a:arguments[0]})}return this},img({uri:uri,x:x,y:y,b:b,h:h,sx:sx,sy:sy,sb:sb,sh:sh,xoff:xoff,yoff:yoff,w:w,scl:scl}){return this.addCommand({c:"img",a:arguments[0]})},beg({x:x,y:y,w:w,scl:scl,matrix:matrix}={}){return this.addCommand({c:"beg",a:arguments[0]})},end(){let myBeg=1,findMyBeg=cmd=>{if(cmd.c==="beg")myBeg--;else if(cmd.c==="end")myBeg++;return myBeg===0};return g2.cmdIdxBy(this.commands,findMyBeg)!==false?this.addCommand({c:"end"}):this},p(){return this.addCommand({c:"p"})},z(){return this.addCommand({c:"z"})},m({x:x,y:y}){return this.addCommand({c:"m",a:arguments[0]})},l({x:x,y:y}){return this.addCommand({c:"l",a:arguments[0]})},q({x1:x1,y1:y1,x:x,y:y}){return this.addCommand({c:"q",a:arguments[0]})},c({x1:x1,y1:y1,x2:x2,y2:y2,x:x,y:y}){return this.addCommand({c:"c",a:arguments[0]})},a({dw:dw,x:x,y:y}){let prvcmd=this.commands[this.commands.length-1];g2.cpyProp(prvcmd.a,"x",arguments[0],"_xp");g2.cpyProp(prvcmd.a,"y",arguments[0],"_yp");return this.addCommand({c:"a",a:arguments[0]})},stroke({d:d}={}){return this.addCommand({c:"stroke",a:arguments[0]})},fill({d:d}={}){return this.addCommand({c:"fill",a:arguments[0]})},drw({d:d,lsh:lsh}={}){return this.addCommand({c:"drw",a:arguments[0]})},del(idx){this.commands.length=idx||0;return this},ins(arg){return typeof arg==="function"?arg(this)||this:typeof arg==="object"?(this.commands.push({a:arg}),this):this},exe(ctx){let handler=g2.handler(ctx);if(handler&&handler.init(this))handler.exe(this.commands);return this},addCommand({c:c,a:a}){if(a&&Object.getPrototypeOf(a)===Object.prototype){for(const key in a){if(!Object.getOwnPropertyDescriptor(a,key).get&&key[0]!=="_"&&typeof a[key]==="function"){Object.defineProperty(a,key,{get:a[key],enumerable:true,configurable:true,writabel:false})}if(typeof a[key]==="string"&&a[key][0]==="@"){const refidIdx=a[key].indexOf(".");const refid=refidIdx>0?a[key].substr(1,refidIdx-1):"";const refkey=refid?a[key].substr(refidIdx+1):"";const refcmd=refid?()=>this.commands.find(cmd=>cmd.a&&cmd.a.id===refid):undefined;if(refcmd)Object.defineProperty(a,key,{get:function(){const rc=refcmd();return rc&&refkey in rc.a?rc.a[refkey]:0},enumerable:true,configurable:true,writabel:false})}}if(g2.prototype[c].prototype)Object.setPrototypeOf(a,g2.prototype[c].prototype)}this.commands.push(arguments[0]);return this}};g2.defaultStyle={fs:"transparent",ls:"#000",lw:1,lc:"butt",lj:"miter",ld:[],ml:10,sh:[0,0],lsh:false,font:"14px serif",thal:"start",tval:"alphabetic"};g2.styleRex=/^(fs|ls|lw|lc|lj|ld|ldoff|ml|sh|lsh|font|thal|tval)([-0-9].*)?$/,g2.symbol={unknown:g2().cir({r:12,fs:"orange"}).txt({str:"?",thal:"center",tval:"middle",font:"bold 20pt serif"})};g2.handler=function(ctx){let hdl;for(let h of g2.handler.factory)if((hdl=h(ctx))!==false)return hdl;return false};g2.handler.factory=[];g2.pntIterator={"x,y":function(pts){function pitr(i){return{x:pts[2*i],y:pts[2*i+1]}}Object.defineProperty(pitr,"len",{get:()=>pts.length/2,enumerable:true,configurable:true,writabel:false});return pitr},"[x,y]":function(pts){function pitr(i){return pts[i]?{x:pts[i][0],y:pts[i][1]}:undefined}Object.defineProperty(pitr,"len",{get:()=>pts.length,enumerable:true,configurable:true,writabel:false});return pitr},"{x,y}":function(pts){function pitr(i){return pts[i]}Object.defineProperty(pitr,"len",{get:()=>pts.length,enumerable:true,configurable:true,writabel:false});return pitr}};g2.pntItrOf=function(pts){return!(pts&&pts.length)?undefined:typeof pts[0]==="number"?g2.pntIterator["x,y"](pts):Array.isArray(pts[0])&&pts[0].length>=2?g2.pntIterator["[x,y]"](pts):typeof pts[0]==="object"&&"x"in pts[0]&&"y"in pts[0]?g2.pntIterator["{x,y}"](pts):undefined};g2.cmdIdxBy=function(cmds,callbk){for(let i=cmds.length-1;i>=0;i--)if(callbk(cmds[i],i,cmds))return i;return false};g2.mix=function mix(...protos){let mixture={};for(const p of protos)mixture=Object.defineProperties(mixture,Object.getOwnPropertyDescriptors(p));return mixture};g2.cpyProp=function(from,fromKey,to,toKey){Object.defineProperty(to,toKey,Object.getOwnPropertyDescriptor(from,fromKey))};g2.canvasHdl=function(ctx){if(this instanceof g2.canvasHdl){if(ctx instanceof CanvasRenderingContext2D){this.ctx=ctx;this.cur=g2.defaultStyle;this.stack=[this.cur];this.matrix=[[1,0,0,1,.5,.5]];this.gridBase=2;this.gridExp=1;return this}else return null}return g2.canvasHdl.apply(Object.create(g2.canvasHdl.prototype),arguments)};g2.handler.factory.push(ctx=>ctx instanceof g2.canvasHdl?ctx:ctx instanceof CanvasRenderingContext2D?g2.canvasHdl(ctx):false);g2.canvasHdl.prototype={init(grp,style){this.stack.length=1;this.matrix.length=1;this.initStyle(style?Object.assign({},this.cur,style):this.cur);return true},async exe(commands){for(let cmd of commands){if(cmd.a&&cmd.a.g2){const cmds=cmd.a.g2().commands;if(cmds){this.exe(cmds);continue}}else if(cmd.a&&cmd.a.commands){this.exe(cmd.a.commands);continue}if(cmd.c&&this[cmd.c]){const rx=this[cmd.c](cmd.a);if(rx&&rx instanceof Promise){await rx}}}},view({x:x=0,y:y=0,scl:scl=1,cartesian:cartesian=false}){this.pushTrf(cartesian?[scl,0,0,-scl,x,this.ctx.canvas.height-1-y]:[scl,0,0,scl,x,y])},grid({color:color="#ccc",size:size}={}){let ctx=this.ctx,b=ctx.canvas.width,h=ctx.canvas.height,{x:x,y:y,scl:scl}=this.uniTrf,sz=size||this.gridSize(scl),xoff=x%sz,yoff=y%sz;ctx.save();ctx.setTransform(1,0,0,1,0,0);ctx.strokeStyle=color;ctx.lineWidth=1;ctx.beginPath();for(let x=xoff,nx=b+1;xNumber.EPSILON&&Math.abs(r)>Number.EPSILON){this.ctx.beginPath();this.ctx.arc(x,y,Math.abs(r),w,w+dw,dw<0);this.drw(arguments[0])}else if(Math.abs(dw)Number.EPSILON){const cw=Math.cos(w),sw=Math.sin(w);this.ctx.beginPath();this.ctx.moveTo(x-r*cw,y-r*sw);this.ctx.lineTo(x+r*cw,y+r*sw)}},ell({rx:rx,ry:ry,w:w=0,dw:dw=2*Math.PI,rot:rot=0}){const{x:x=0,y:y=0}=arguments[0].p!==undefined?arguments[0].p:arguments[0];this.ctx.beginPath();this.ctx.ellipse(x,y,Math.abs(rx),Math.abs(ry),rot,w,w+dw,dw<0);this.drw(arguments[0])},rec({b:b,h:h}){const{x:x=0,y:y=0}=arguments[0].p!==undefined?arguments[0].p:arguments[0];const tmp=this.setStyle(arguments[0]);this.ctx.fillRect(x,y,b,h);this.ctx.strokeRect(x,y,b,h);this.resetStyle(tmp)},lin(args){this.ctx.beginPath();this.ctx.moveTo(args.p1&&args.p1.x||args.x1||0,args.p1&&args.p1.y||args.y1||0);this.ctx.lineTo(args.p2&&args.p2.x||args.x2||0,args.p2&&args.p2.y||args.y2||0);this.stroke(args)},ply({pts:pts,closed:closed,w:w=0,_itr:_itr}){if(_itr&&_itr.len){const{x:x=0,y:y=0}=arguments[0].p!==undefined?arguments[0].p:arguments[0];let p,i,len=_itr.len,istrf=!!(x||y||w),cw,sw;if(istrf)this.setTrf([cw=w?Math.cos(w):1,sw=w?Math.sin(w):0,-sw,cw,x,y]);this.ctx.beginPath();this.ctx.moveTo((p=_itr(0)).x,p.y);for(i=1;i{const pimg=new Promise((resolve,reject)=>{let img=new Image;img.src=xuri;function error(err){img.removeEventListener("load",load);img=undefined;reject(err)}function load(){img.removeEventListener("error",error);resolve(img);img=undefined}img.addEventListener("error",error,{once:true});img.addEventListener("load",load,{once:true})});try{return await pimg}catch(err){if(xuri===this.errorImageStr){throw err}else{return await download(this.errorImageStr)}}};let img=this.images[uri];if(img!==undefined){return img instanceof Promise?await img:img}img=download(uri);this.images[uri]=img;try{img=await img}finally{this.images[uri]=img}return img},async img({uri:uri,x:x=0,y:y=0,b:b,h:h,sx:sx=0,sy:sy=0,sb:sb,sh:sh,xoff:xoff=0,yoff:yoff=0,w:w=0,scl:scl=1}){const img_=await this.loadImage(uri);this.ctx.save();const cart=this.isCartesian?-1:1;sb=sb||img_.width;b=b||img_.width;sh=sh||img_.height;h=(h||img_.height)*cart;yoff*=cart;w*=cart;y=this.isCartesian?-(y/scl)+sy:y/scl;const[cw,sw]=[Math.cos(w),Math.sin(w)];this.ctx.scale(scl,scl*cart);this.ctx.transform(cw,sw,-sw,cw,x/scl,y);this.ctx.drawImage(img_,sx,sy,sb,sh,xoff,yoff,b,h);this.ctx.restore()},use({grp:grp}){this.beg(arguments[0]);this.exe(grp.commands);this.end()},beg({w:w=0,scl:scl=1,matrix:matrix}={}){const{x:x=0,y:y=0}=arguments[0].p!==undefined?arguments[0].p:arguments[0];let trf=matrix;if(!trf){let ssw,scw;ssw=w?Math.sin(w)*scl:0;scw=w?Math.cos(w)*scl:scl;trf=[scw,ssw,-ssw,scw,x,y]}this.pushStyle(arguments[0]);this.pushTrf(trf)},end(){this.popTrf();this.popStyle()},p(){this.ctx.beginPath()},z(){this.ctx.closePath()},m({x:x,y:y}){this.ctx.moveTo(x,y)},l({x:x,y:y}){this.ctx.lineTo(x,y)},q({x:x,y:y,x1:x1,y1:y1}){this.ctx.quadraticCurveTo(x1,y1,x,y)},c({x:x,y:y,x1:x1,y1:y1,x2:x2,y2:y2}){this.ctx.bezierCurveTo(x1,y1,x2,y2,x,y)},a({dw:dw,k:k,phi:phi,_xp:_xp,_yp:_yp}){const{x:x=0,y:y=0}=arguments[0].p!==undefined?arguments[0].p:arguments[0];if(k===undefined)k=1;if(Math.abs(dw)>Number.EPSILON){if(k===1){let x12=x-_xp,y12=y-_yp;let tdw_2=Math.tan(dw/2),rx=(x12-y12/tdw_2)/2,ry=(y12+x12/tdw_2)/2,R=Math.hypot(rx,ry),w=Math.atan2(-ry,-rx);this.ctx.ellipse(_xp+rx,_yp+ry,R,R,0,w,w+dw,this.cartesian?dw>0:dw<0)}else{if(phi===undefined)phi=0;let x1=dw>0?_xp:x,y1=dw>0?_yp:y,x2=dw>0?x:_xp,y2=dw>0?y:_yp;let x12=x2-x1,y12=y2-y1,_dw=dw<0?dw:-dw;let cp=phi?Math.cos(phi):1,sp=phi?Math.sin(phi):0,dx=-x12*cp-y12*sp,dy=-x12*sp-y12*cp,sdw_2=Math.sin(_dw/2),R=Math.sqrt((dx*dx+dy*dy/(k*k))/(4*sdw_2*sdw_2)),w=Math.atan2(k*dx,dy)-_dw/2,x0=x1-R*Math.cos(w),y0=y1-R*k*Math.sin(w);this.ctx.ellipse(x0,y0,R,R*k,phi,w,w+dw,this.cartesian?dw>0:dw<0)}}else this.ctx.lineTo(x,y)},stroke({d:d}={}){let tmp=this.setStyle(arguments[0]);d?this.ctx.stroke(new Path2D(d)):this.ctx.stroke();this.resetStyle(tmp)},fill({d:d}={}){let tmp=this.setStyle(arguments[0]);d?this.ctx.fill(new Path2D(d)):this.ctx.fill();this.resetStyle(tmp)},drw({d:d,lsh:lsh}={}){let ctx=this.ctx,tmp=this.setStyle(arguments[0]),p=d&&new Path2D(d);d?ctx.fill(p):ctx.fill();if(ctx.shadowColor!=="rgba(0, 0, 0, 0)"&&ctx.fillStyle!=="rgba(0, 0, 0, 0)"&&!lsh){let shc=ctx.shadowColor;ctx.shadowColor="rgba(0, 0, 0, 0)";d?ctx.stroke(p):ctx.stroke();ctx.shadowColor=shc}else d?ctx.stroke(p):ctx.stroke();this.resetStyle(tmp)},get:{fs:ctx=>ctx.fillStyle,ls:ctx=>ctx.strokeStyle,lw:ctx=>ctx.lineWidth,lc:ctx=>ctx.lineCap,lj:ctx=>ctx.lineJoin,ld:ctx=>ctx.getLineDash(),ldoff:ctx=>ctx.lineDashOffset,ml:ctx=>ctx.miterLimit,sh:ctx=>[ctx.shadowOffsetX||0,ctx.shadowOffsetY||0,ctx.shadowBlur||0,ctx.shadowColor||"black"],font:ctx=>ctx.font,thal:ctx=>ctx.textAlign,tval:ctx=>ctx.textBaseline},set:{fs:(ctx,q)=>{ctx.fillStyle=q},ls:(ctx,q)=>{ctx.strokeStyle=q},lw:(ctx,q)=>{ctx.lineWidth=q},lc:(ctx,q)=>{ctx.lineCap=q},lj:(ctx,q)=>{ctx.lineJoin=q},ld:(ctx,q)=>{ctx.setLineDash(q)},ldoff:(ctx,q)=>{ctx.lineDashOffset=q},ml:(ctx,q)=>{ctx.miterLimit=q},sh:(ctx,q)=>{if(q){ctx.shadowOffsetX=q[0]||0;ctx.shadowOffsetY=q[1]||0;ctx.shadowBlur=q[2]||0;ctx.shadowColor=q[3]||"black"}},font:(ctx,q)=>{ctx.font=q},thal:(ctx,q)=>{ctx.textAlign=q},tval:(ctx,q)=>{ctx.textBaseline=q}},initStyle(style){for(const key in style)if(this.get[key]&&this.get[key](this.ctx)!==style[key])this.set[key](this.ctx,style[key])},setStyle(style){let q,prv={};for(const key in style){if(this.get[key]){let keyval=style[key];if(typeof style[key]==="string"&&style[key][0]==="@"){const ref=style[key].substr(1);keyval=g2.symbol[ref]||ref in this.get&&this.get[ref](this.ctx)||ref in this.cur&&this.cur[ref]}if((q=this.get[key](this.ctx))!==keyval){prv[key]=q;this.set[key](this.ctx,keyval)}}}return prv},resetStyle(style){for(const key in style)this.set[key](this.ctx,style[key])},pushStyle(style){let cur={};for(const key in style)if(g2.styleRex.test(key)){if(typeof style[key]==="string"&&style[key][0]==="@"){let ref=style[key].substr(1);style[key]=g2.symbol[ref]||this.get[ref]&&this.get[ref](this.ctx)}if(this.cur[key]!==style[key]){if(key in this.set)this.set[key](this.ctx,style[key]);cur[key]=style[key]}}this.stack.push(this.cur=Object.assign({},this.cur,cur))},popStyle(){let cur=this.stack.pop();this.cur=this.stack[this.stack.length-1];for(const key in this.cur)if(this.get[key]&&this.cur[key]!==cur[key])this.set[key](this.ctx,this.cur[key])},concatTrf(q,t){return[q[0]*t[0]+q[2]*t[1],q[1]*t[0]+q[3]*t[1],q[0]*t[2]+q[2]*t[3],q[1]*t[2]+q[3]*t[3],q[0]*t[4]+q[2]*t[5]+q[4],q[1]*t[4]+q[3]*t[5]+q[5]]},initTrf(){this.ctx.setTransform(...this.matrix[0])},setTrf(t){this.ctx.setTransform(...this.concatTrf(this.matrix[this.matrix.length-1],t))},resetTrf(){this.ctx.setTransform(...this.matrix[this.matrix.length-1])},pushTrf(t){let q_t=this.concatTrf(this.matrix[this.matrix.length-1],t);this.matrix.push(q_t);this.ctx.setTransform(...q_t)},popTrf(){this.matrix.pop();this.ctx.setTransform(...this.matrix[this.matrix.length-1])},get isCartesian(){let m=this.matrix[this.matrix.length-1];return m[0]*m[3]-m[1]*m[2]<0},get uniTrf(){let m=this.matrix[this.matrix.length-1];return{x:m[4],y:m[5],scl:Math.hypot(m[0],m[1]),cartesian:m[0]*m[3]-m[1]*m[2]<0}},unscaleTrf({x:x,y:y}){let m=this.matrix[this.matrix.length-1],invscl=1/Math.hypot(m[0],m[1]);return[invscl,0,0,invscl,(1-invscl)*x,(1-invscl)*y]},gridSize(scl){let base=this.gridBase,exp=this.gridExp,sz;while((sz=scl*base*Math.pow(10,exp))<14||sz>35){if(sz<14){if(base==1)base=2;else if(base==2)base=5;else if(base==5){base=1;exp++}}else{if(base==1){base=5;exp--}else if(base==2)base=1;else if(base==5)base=2}}this.gridBase=base;this.gridExp=exp;return sz}};
/**
* g2.lib (c) 2013-17 Stefan Goessner
* geometric constants and higher functions
@@ -23,14 +23,14 @@
*/
"use strict";var g2=g2||{};g2=Object.assign(g2,{EPS:Number.EPSILON,PI:Math.PI,PI2:2*Math.PI,SQRT2:Math.SQRT2,SQRT2_2:Math.SQRT2/2,toPi2(w){return(w%g2.PI2+g2.PI2)%g2.PI2},toPi(w){return(w=(w%g2.PI2+g2.PI2)%g2.PI2)>g2.PI?w-g2.PI2:w},toArc:function(w,w0,dw){if(dw>g2.EPS||dw<-g2.EPS){if(w0>w&&w0+dw>g2.PI2)w0-=g2.PI2;else if(w0eps&&Math.abs(dist-r)=0&&mu<=1},isPntOnPly({x:x,y:y},{pts:pts,closed:closed},eps=Number.EPSILON){for(var i=0,n=pts.length;i<(closed?n:n-1);i++)if(g2.isPntOnLin({x:x,y:y},pts[i],pts[(i+1)%n],eps))return true;return false},isPntOnBox({x:xp,y:yp},{x:x,y:y,b:b,h:h},eps=Number.EPSILON){var dx=x.p-x,dy=yp-y;return dx>=b-eps&&dx<=b+eps&&dy<=h+eps&&dy>=-h-eps||dx>=-b-eps&&dx<=b+eps&&dy<=h+eps&&dy>=h-eps||dx>=-b-eps&&dx<=-b+eps&&dy<=h+eps&&dy>=-h-eps||dx>=-b-eps&&dx<=b+eps&&dy<=-h+eps&&dy>=-h-eps},isPntInCir({x:xp,y:yp},{x:x,y:y,r:r}){return(x-xp)**2+(y-yp)**2pi.y||y>pj.y)&&(y<=pi.y||y<=pj.y)&&(x<=pi.x||x<=pj.x)&&pi.y!==pj.y&&(pi.x===pj.x||x<=pj.x+(y-pj.y)*(pi.x-pj.x)/(pi.y-pj.y)))match++;return match%2!=0},isPntInBox({x:xp,y:yp},{x:x,y:y,b:b,h:h}){var dx=xp-x,dy=yp-y;return dx>=-b&&dx<=b&&dy>=-h&&dy<=h},arc3pts(x1,y1,x2,y2,x3,y3){const dx1=x2-x1,dy1=y2-y1;const dx2=x3-x2,dy2=y3-y2;const den=dx1*dy2-dy1*dx2;const lam=Math.abs(den)>Number.EPSILON?.5*((dx1+dx2)*dx2+(dy1+dy2)*dy2)/den:0;const x0=lam?x1+.5*dx1-lam*dy1:x1+.5*(dx1+dx2);const y0=lam?y1+.5*dy1+lam*dx1:y1+.5*(dy1+dy2);const dx01=x1-x0,dy01=y1-y0;const dx03=x3-x0,dy03=y3-y0;const dw=lam?Math.atan2(dx01*dy03-dy01*dx03,dx01*dx03+dy01*dy03):0;const r=dw?Math.hypot(dy01,dx01):.5*Math.hypot(dy1+dy2,dx1+dx2);return{x:x0,y:y0,r:r,w:Math.atan2(dy01,dx01),dw:dw}}});"use strict";
/**
- * g2.ext (c) 2015-20 Stefan Goessner
+ * g2.ext (c) 2015-21 Stefan Goessner
* @author Stefan Goessner
* @license MIT License
* @requires g2.core.js
* @typedef {g2}
* @description Additional methods for g2.
* @returns {g2}
- */var g2=g2||{prototype:{}};g2.NONE=0;g2.OVER=1;g2.DRAG=2;g2.EDIT=4;g2.symbol=g2.symbol||{};g2.symbol.tick=g2().p().m({x:0,y:-2}).l({x:0,y:2}).stroke({lc:"round",lwnosc:true});g2.symbol.dot=g2().cir({x:0,y:0,r:2,ls:"transparent"});g2.symbol.sqr=g2().rec({x:-1.5,y:-1.5,b:3,h:3,ls:"transparent"});g2.symbol.nodcolor="#333";g2.symbol.nodfill="#dedede";g2.symbol.nodfill2="#aeaeae";g2.symbol.linkcolor="#666";g2.symbol.linkfill="rgba(225,225,225,0.75)";g2.symbol.dimcolor="darkslategray";g2.symbol.solid=[];g2.symbol.dash=[15,10];g2.symbol.dot=[4,4];g2.symbol.dashdot=[25,6.5,2,6.5];g2.symbol.labelSignificantDigits=3;g2.flatten=function(obj){const args=Object.create(null);for(let p in obj)if(typeof obj[p]!=="function")args[p]=obj[p];return args};g2.pointIfc={get p(){return{x:this.x,y:this.y}},get x(){return Object.getOwnPropertyDescriptor(this,"p")?this.p.x:0},get y(){return Object.getOwnPropertyDescriptor(this,"p")?this.p.y:0},set x(q){if(Object.getOwnPropertyDescriptor(this,"p"))this.p.x=q},set y(q){if(Object.getOwnPropertyDescriptor(this,"p"))this.p.y=q}};g2.labelIfc={getLabelOffset(){const off=this.label.off!==undefined?+this.label.off:1;return off+Math.sign(off)*(this.lw||2)/2},getLabelString(){let s=typeof this.label==="object"?this.label.str:typeof this.label==="string"?this.label:"?";if(s&&s[0]==="@"&&this[s.substr(1)]){s=s.substr(1);let val=this[s];val=Number.isInteger(val)?val:Number(val).toFixed(Math.max(g2.symbol.labelSignificantDigits-Math.log10(val),0));s=`${val}${s==="angle"?"°":""}`}return s},drawLabel(g){const lbl=this.label;const font=lbl.font||g2.defaultStyle.font;const h=parseInt(font);const str=this.getLabelString();const rx=(str.length||1)*.75*h/2,ry=1.25*h/2;const pos=this.pointAt(lbl.loc||this.lbloc||"se");const off=this.getLabelOffset();const p={x:pos.x+pos.nx*(off+Math.sign(off)*rx),y:pos.y+pos.ny*(off+Math.sign(off)*ry)};if(lbl.border)g.ell({x:p.x,y:p.y,rx:rx,ry:ry,ls:lbl.fs||"black",fs:lbl.fs2||"#ffc"});g.txt({str:str,x:p.x,y:p.y,thal:"center",tval:"middle",fs:lbl.fs||"black",font:lbl.font});return g}};g2.markIfc={markAt(loc){const p=this.pointAt(loc);const w=Math.atan2(p.ny,p.nx)+Math.PI/2;return{grp:this.getMarkSymbol(),x:p.x,y:p.y,w:w,scl:this.lw||1,ls:this.ls||"#000",fs:this.fs||this.ls||"#000"}},getMarkSymbol(){const mrk=this.mark;if(typeof mrk==="number"||!mrk)return g2.symbol.tick;if(typeof mrk.symbol==="object")return mrk.symbol;if(typeof mrk.symbol==="string")return g2.symbol[mrk.symbol]},drawMark(g,closed=false){let loc;if(Array.isArray(this.mark)){loc=this.mark}else{const count=typeof this.mark==="object"?this.mark.count:this.mark;loc=count?Array.from(Array(count)).map((_,i)=>i/(count-!closed)):this.mark.loc}for(let l of loc){g.use(this.markAt(l))}return g}};g2.prototype.cir.prototype=g2.mix(g2.pointIfc,g2.labelIfc,g2.markIfc,{w:0,lbloc:"c",get isSolid(){return this.fs&&this.fs!=="transparent"},get len(){return 2*Math.PI*this.r},get lsh(){return this.state&g2.OVER},get sh(){return this.state&g2.OVER?[0,0,5,"black"]:false},get g2(){const e=g2();this.label&&e.ins(g=>this.drawLabel(g));this.mark&&e.ins(g=>this.drawMark(g,true));return()=>g2().cir(g2.flatten(this)).ins(e)},pointAt(loc){const Q=Math.SQRT2/2;const LOC={c:[0,0],e:[1,0],ne:[Q,Q],n:[0,1],nw:[-Q,Q],w:[-1,0],sw:[-Q,-Q],s:[0,-1],se:[Q,-Q]};const q=loc+0===loc?[Math.cos(loc*2*Math.PI),Math.sin(loc*2*Math.PI)]:LOC[loc||"c"]||[0,0];return{x:this.x+q[0]*this.r,y:this.y+q[1]*this.r,nx:q[0],ny:q[1]}},hit({x:x,y:y,eps:eps}){return this.isSolid?g2.isPntInCir({x:x,y:y},this,eps):g2.isPntOnCir({x:x,y:y},this,eps)},drag({dx:dx,dy:dy}){this.x+=dx;this.y+=dy}});g2.prototype.lin.prototype=g2.mix(g2.labelIfc,g2.markIfc,{get p1(){return{x1:this.x1,y1:this.y1}},get x1(){return Object.getOwnPropertyDescriptor(this,"p1")?this.p1.x:0},get y1(){return Object.getOwnPropertyDescriptor(this,"p1")?this.p1.y:0},set x1(q){if(Object.getOwnPropertyDescriptor(this,"p1"))this.p1.x=q},set y1(q){if(Object.getOwnPropertyDescriptor(this,"p1"))this.p1.y=q},get p2(){return{x2:this.x2,y2:this.y2}},get x2(){return Object.getOwnPropertyDescriptor(this,"p2")?this.p2.x:0},get y2(){return Object.getOwnPropertyDescriptor(this,"p2")?this.p2.y:0},set x2(q){if(Object.getOwnPropertyDescriptor(this,"p2"))this.p2.x=q},set y2(q){if(Object.getOwnPropertyDescriptor(this,"p2"))this.p2.y=q},isSolid:false,get len(){return Math.hypot(this.x2-this.x1,this.y2-this.y1)},get sh(){return this.state&g2.OVER?[0,0,5,"black"]:false},get g2(){const e=g2();this.label&&e.ins(e=>this.drawLabel(e));this.mark&&e.ins(e=>this.drawMark(e));return()=>g2().lin(g2.flatten(this)).ins(e)},pointAt(loc){let t=loc==="beg"?0:loc==="end"?1:loc+0===loc?loc:.5,dx=this.x2-this.x1,dy=this.y2-this.y1,len=Math.hypot(dx,dy);return{x:this.x1+dx*t,y:this.y1+dy*t,nx:len?dy/len:0,ny:len?-dx/len:-1}},hit({x:x,y:y,eps:eps}){return g2.isPntOnLin({x:x,y:y},{x:this.x1,y:this.y1},{x:this.x2,y:this.y2},eps)},drag({dx:dx,dy:dy}){this.x1+=dx;this.x2+=dx;this.y1+=dy;this.y2+=dy}});g2.prototype.rec.prototype=g2.mix(g2.pointIfc,g2.labelIfc,g2.markIfc,{get len(){return 2*(this.b+this.h)},get isSolid(){return this.fs&&this.fs!=="transparent"},get lsh(){return this.state&g2.OVER},get sh(){return this.state&g2.OVER?[0,0,5,"black"]:false},get g2(){const e=g2();this.label&&e.ins(e=>this.drawLabel(e));this.mark&&e.ins(e=>this.drawMark(e,true));return()=>g2().rec(g2.flatten(this)).ins(e)},lbloc:"c",pointAt(loc){const locAt=loc=>{const o={c:[0,0],e:[1,0],ne:[.95,.95],n:[0,1],nw:[-.95,.95],w:[-1,0],sw:[-.95,-.95],s:[0,-1],se:[.95,-.95]};if(o[loc])return o[loc];const w=2*Math.PI*loc+pi/4;if(loc<=.25)return[1/Math.tan(w),1];if(loc<=.5)return[-1,-Math.tan(w)];if(loc<=.75)return[-1/Math.tan(w),-1];if(loc<=1)return[1,Math.tan(w)]};const q=locAt(loc);return{x:this.x+(1+q[0])*this.b/2,y:this.y+(1+q[1])*this.h/2,nx:1-Math.abs(q[0])<.01?q[0]:0,ny:1-Math.abs(q[1])<.01?q[1]:0}},hit({x:x,y:y,eps:eps}){return this.isSolid?g2.isPntInBox({x:x,y:y},{x:this.x+this.b/2,y:this.y+this.h/2,b:this.b/2,h:this.h/2},eps):g2.isPntOnBox({x:x,y:y},{x:this.x+this.b/2,y:this.y+this.h/2,b:this.b/2,h:this.h/2},eps)},drag({dx:dx,dy:dy}){this.x+=dx;this.y+=dy}});g2.prototype.arc.prototype=g2.mix(g2.pointIfc,g2.labelIfc,g2.markIfc,{get len(){return Math.abs(this.r*this.dw)},isSolid:false,get angle(){return this.dw/Math.PI*180},get sh(){return this.state&g2.OVER?[0,0,5,"black"]:false},get g2(){const e=g2();this.label&&e.ins(e=>this.drawLabel(e));this.mark&&e.ins(e=>this.drawMark(e));return()=>g2().arc(g2.flatten(this)).ins(e)},lbloc:"mid",pointAt(loc){let t=loc==="beg"?0:loc==="end"?1:loc==="mid"?.5:loc+0===loc?loc:.5,ang=(this.w||0)+t*(this.dw||Math.PI*2),cang=Math.cos(ang),sang=Math.sin(ang),r=loc==="c"?0:this.r;return{x:this.x+r*cang,y:this.y+r*sang,nx:cang,ny:sang}},hit({x:x,y:y,eps:eps}){return g2.isPntOnArc({x:x,y:y},this,eps)},drag({dx:dx,dy:dy}){this.x+=dx;this.y+=dy}});g2.prototype.hdl=function(args){return this.addCommand({c:"hdl",a:args})};g2.prototype.hdl.prototype=g2.mix(g2.prototype.cir.prototype,{r:5,isSolid:true,draggable:true,lbloc:"se",get lsh(){return this.state&g2.OVER},get sh(){return this.state&g2.OVER?[0,0,5,"black"]:false},g2(){const{x:x,y:y,r:r,b:b=4,shape:shape="cir",ls:ls="black",fs:fs="#ccc",sh:sh}=this;return shape==="cir"?g2().cir({x:x,y:y,r:r,ls:ls,fs:fs,sh:sh}).ins(g=>this.label&&this.drawLabel(g)):g2().rec({x:x-b,y:y-b,b:2*b,h:2*b,ls:ls,fs:fs,sh:sh}).ins(g=>this.label&&this.drawLabel(g))}});g2.prototype.nod=function(args={}){return this.addCommand({c:"nod",a:args})};g2.prototype.nod.prototype=g2.mix(g2.prototype.cir.prototype,{r:5,ls:"@nodcolor",fs:g2.symbol.nodfill,isSolid:true,lbloc:"se",g2(){return g2().cir({...g2.flatten(this),r:this.r*(this.scl!==undefined?this.scl:1)}).ins(g=>this.label&&this.drawLabel(g))}});g2.prototype.dblnod=function({x:x=0,y:y=0}){return this.addCommand({c:"dblnod",a:arguments[0]})};g2.prototype.dblnod.prototype=g2.mix(g2.prototype.cir.prototype,{get r(){return 6},get isSolid(){return true},g2(){return g2().beg({x:this.x,y:this.y}).cir({r:6,ls:"@nodcolor",fs:"@nodfill",sh:this.sh}).cir({r:3,ls:"@nodcolor",fs:"@nodfill2"}).end().ins(g=>this.label&&this.drawLabel(g))}});g2.prototype.pol=function(args={}){return this.addCommand({c:"pol",a:args})};g2.prototype.pol.prototype=g2.mix(g2.prototype.nod.prototype,{g2(){return g2().beg(g2.flatten(this)).cir({r:6,fs:g2.symbol.nodfill}).cir({r:2.5,fs:"@ls",ls:"transparent"}).end().ins(g=>this.label&&this.drawLabel(g))}});g2.prototype.gnd=function(args={}){return this.addCommand({c:"gnd",a:args})};g2.prototype.gnd.prototype=g2.mix(g2.prototype.nod.prototype,{g2(){return g2().beg(g2.flatten(this)).cir({x:0,y:0,r:6}).p().m({x:0,y:6}).a({dw:Math.PI/2,x:-6,y:0}).l({x:6,y:0}).a({dw:-Math.PI/2,x:0,y:-6}).z().fill({fs:g2.symbol.nodcolor}).end().ins(g=>this.label&&this.drawLabel(g))}});g2.prototype.nodfix=function(args={}){return this.addCommand({c:"nodfix",a:args})};g2.prototype.nodfix.prototype=g2.mix(g2.prototype.nod.prototype,{g2(){return g2().beg(g2.flatten(this)).p().m({x:-8,y:-12}).l({x:0,y:0}).l({x:8,y:-12}).drw({fs:g2.symbol.nodfill2}).cir({x:0,y:0,r:this.r}).end().ins(g=>this.label&&this.drawLabel(g))}});g2.prototype.nodflt=function(args={}){return this.addCommand({c:"nodflt",a:args})};g2.prototype.nodflt.prototype=g2.mix(g2.prototype.nod.prototype,{g2(){return g2().beg(g2.flatten(this)).p().m({x:-8,y:-12}).l({x:0,y:0}).l({x:8,y:-12}).drw({ls:g2.symbol.nodcolor,fs:g2.symbol.nodfill2}).cir({x:0,y:0,r:this.r,ls:g2.symbol.nodcolor,fs:g2.symbol.nodfill}).lin({x1:-9,y1:-19,x2:9,y2:-19,ls:g2.symbol.nodfill2,lw:5}).lin({x1:-9,y1:-15.5,x2:9,y2:-15.5,ls:g2.symbol.nodcolor,lw:2}).end().ins(g=>this.label&&this.drawLabel(g))}});g2.prototype.vec=function vec(args){return this.addCommand({c:"vec",a:args})};g2.prototype.vec.prototype=g2.mix(g2.prototype.lin.prototype,{g2(){const{x1:x1,y1:y1,x2:x2,y2:y2,lw:lw=1,ls:ls="#000",ld:ld=[],fs:fs=ls||"#000",lc:lc="round",lj:lj="round"}=this;const dx=x2-x1,dy=y2-y1,r=Math.hypot(dx,dy);const b=3*(1+lw)>r?r/3:1+lw;const arrowHead=()=>g2().p().m({x:0,y:0}).l({x:-5*b,y:b}).a({dw:-Math.PI/3,x:-5*b,y:-b}).z().drw({ls:ls,fs:fs,lc:lc,lj:lj});return g2().beg({x:x1,y:y1,w:Math.atan2(dy,dx),lc:lc,lj:lj}).p().m({x:0,y:0}).l({x:r-3*b,y:0}).stroke({ls:ls,lw:lw,ld:ld}).use({grp:arrowHead,x:r,y:0}).end().ins(g=>this.label&&this.drawLabel(g))}});g2.prototype.avec=function avec(args){return this.addCommand({c:"avec",a:args})};g2.prototype.avec.prototype=g2.mix(g2.prototype.arc.prototype,{g2(){const{x:x,y:y,r:r,w:w,dw:dw=0,lw:lw=1,lc:lc="round",lj:lj="round",ls:ls,fs:fs=ls||"#000",label:label}=this;const b=3*(1+lw)>r?r/3:1+lw,bw=5*b/r;const arrowHead=()=>g2().p().m({x:0,y:2*b}).l({x:0,y:-2*b}).m({x:0,y:0}).l({x:-5*b,y:b}).a({dw:-Math.PI/3,x:-5*b,y:-b}).z().drw({ls:ls,fs:fs});return g2().beg({x:x,y:y,w:w,ls:ls,lw:lw,lc:lc,lj:lj}).arc({r:r,w:0,dw:dw}).use({grp:arrowHead,x:r*Math.cos(dw),y:r*Math.sin(dw),w:dw>=0?dw+Math.PI/2-bw/2:dw-Math.PI/2+bw/2}).end().ins(g=>label&&this.drawLabel(g))}});g2.prototype.dim=function dim(args){return this.addCommand({c:"dim",a:args})};g2.prototype.dim.prototype=g2.mix(g2.prototype.lin.prototype,{pointAt(loc){const pnt=g2.prototype.lin.prototype.pointAt.call(this,loc);if(this.off){pnt.x+=this.off*pnt.nx;pnt.y+=this.off*pnt.ny}return pnt},g2(){const{x1:x1,y1:y1,x2:x2,y2:y2,lw:lw=1,lc:lc="round",lj:lj="round",off:off=0,inside:inside=true,ls:ls,fs:fs=ls||"#000",label:label}=this;const dx=x2-x1,dy=y2-y1,r=Math.hypot(dx,dy);const b=3*(1+lw)>r?r/3:1+lw;const arrowHead=()=>g2().p().m({x:0,y:2*b}).l({x:0,y:-2*b}).m({x:0,y:0}).l({x:-5*b,y:b}).a({dw:-Math.PI/3,x:-5*b,y:-b}).z().drw({ls:ls,fs:fs});return g2().beg({x:x1+off/r*dy,y:y1-off/r*dx,w:Math.atan2(dy,dx),ls:ls,fs:fs,lw:lw,lc:lc,lj:lj}).lin({x1:inside?4*b:0,y1:0,x2:inside?r-4*b:r,y2:0}).use({grp:arrowHead,x:r,y:0,w:inside?0:Math.PI}).use({grp:arrowHead,x:0,y:0,w:inside?Math.PI:0}).lin({x1:0,y1:off,x2:0,y2:0}).lin({x1:r,y1:off,x2:r,y2:0}).end().ins(g=>label&&this.drawLabel(g))}});g2.prototype.adim=function adim(args){return this.addCommand({c:"adim",a:args})};g2.prototype.adim.prototype=g2.mix(g2.prototype.arc.prototype,{g2(){const{x:x,y:y,r:r,w:w,dw:dw,lw:lw=1,lc:lc="round",lj:lj="round",ls:ls,fs:fs=ls||"#000",label:label}=this;const b=3*(1+lw)>r?r/3:1+lw,bw=5*b/r;const arrowHead=()=>g2().p().m({x:0,y:2*b}).l({x:0,y:-2*b}).m({x:0,y:0}).l({x:-5*b,y:b}).a({dw:-Math.PI/3,x:-5*b,y:-b}).z().drw({ls:ls,fs:fs});const outside=this.inside!==undefined&&this.outside===undefined?!this.inside:!!this.outside;return g2().beg({x:x,y:y,w:w,ls:ls,lw:lw,lc:lc,lj:lj}).arc({r:r,w:0,dw:dw}).use({grp:arrowHead,x:r,y:0,w:!outside&&dw>0||outside&&dw<0?-Math.PI/2+bw/2:Math.PI/2-bw/2}).use({grp:arrowHead,x:r*Math.cos(dw),y:r*Math.sin(dw),w:!outside&&dw>0||outside&&dw<0?dw+Math.PI/2-bw/2:dw-Math.PI/2+bw/2}).end().ins(g=>label&&this.drawLabel(g))}});g2.prototype.origin=function(args={}){return this.addCommand({c:"origin",a:args})};g2.prototype.origin.prototype=g2.mix(g2.prototype.nod.prototype,{lbloc:"sw",g2(){const{x:x,y:y,w:w,ls:ls="#000",lw:lw=1}=this;return g2().beg({x:x,y:y,w:w,ls:ls}).vec({x1:0,y1:0,x2:40,y2:0,lw:lw,fs:"#ccc"}).vec({x1:0,y1:0,x2:0,y2:40,lw:lw,fs:"#ccc"}).cir({x:0,y:0,r:lw+1,fs:"#ccc"}).end().ins(g=>this.label&&this.drawLabel(g))}});g2.prototype.ply.prototype=g2.mix(g2.labelIfc,g2.markIfc,{get isSolid(){return this.closed&&this.fs&&this.fs!=="transparent"},get sh(){return this.state&g2.OVER?[0,0,5,"black"]:false},pointAt(loc){const t=loc==="beg"?0:loc==="end"?1:loc+0===loc?loc:.5,pitr=g2.pntItrOf(this.pts),pts=[],len=[];for(let itr=0;itr{const target=t*len.reduce((a,b)=>a+b);for(let itr=0,tmp=0;itr=target){return{t2:1-(tmp-target)/len[itr],x:pts[itr].x,y:pts[itr].y,dx:next.x-pts[itr].x,dy:next.y-pts[itr].y}}}})();const len2=Math.hypot(dx,dy);return{x:(this.x||0)+x+dx*t2,y:(this.y||0)+y+dy*t2,nx:len2?dy/len2:1,ny:len2?dx/len2:0}},hit({x:x,y:y,eps:eps}){return this.isSolid?g2.isPntInPly({x:x-this.x,y:y-this.y},this,eps):g2.isPntOnPly({x:x-this.x,y:y-this.y},this,eps)},drag({dx:dx,dy:dy}){this.x+=dx;this.y+=dy},get g2(){const e=g2();this.label&&e.ins(e=>this.drawLabel(e));this.mark&&e.ins(e=>this.drawMark(e,this.closed));return()=>g2().ply(g2.flatten(this)).ins(e)}});g2.prototype.use.prototype={get p(){return{x:this.x,y:this.y}},get x(){return Object.getOwnPropertyDescriptor(this,"p")?this.p.x:0},get y(){return Object.getOwnPropertyDescriptor(this,"p")?this.p.y:0},set x(q){if(Object.getOwnPropertyDescriptor(this,"p"))this.p.x=q},set y(q){if(Object.getOwnPropertyDescriptor(this,"p"))this.p.y=q},isSolid:false};g2.prototype.spline=function spline({pts:pts,closed:closed,x:x,y:y,w:w}){arguments[0]._itr=g2.pntItrOf(pts);return this.addCommand({c:"spline",a:arguments[0]})};g2.prototype.spline.prototype=g2.mix(g2.prototype.ply.prototype,{g2:function(){let{pts:pts,closed:closed,x:x,y:y,w:w,ls:ls,lw:lw,fs:fs,sh:sh}=this,itr=this._itr,gbez;if(itr){let b=[],i,n=itr.len,p1,p2,p3,p4,d1,d2,d3,d1d2,d2d3,scl2,scl3,den2,den3,istrf=x||y||w;gbez=g2();if(istrf)gbez.beg({x:x,y:y,w:w});gbez.p().m(itr(0));for(let i=0;i<(closed?n:n-1);i++){if(i===0){p1=closed?itr(n-1):{x:2*itr(0).x-itr(1).x,y:2*itr(0).y-itr(1).y};p2=itr(0);p3=itr(1);p4=n===2?closed?itr(0):{x:2*itr(1).x-itr(0).x,y:2*itr(1).y-itr(0).y}:itr(2);d1=Math.max(Math.hypot(p2.x-p1.x,p2.y-p1.y),Number.EPSILON);d2=Math.max(Math.hypot(p3.x-p2.x,p3.y-p2.y),Number.EPSILON)}else{p1=p2;p2=p3;p3=p4;p4=i===n-2?closed?itr(0):{x:2*itr(n-1).x-itr(n-2).x,y:2*itr(n-1).y-itr(n-2).y}:i===n-1?itr(1):itr(i+2);d1=d2;d2=d3}d3=Math.max(Math.hypot(p4.x-p3.x,p4.y-p3.y),Number.EPSILON);d1d2=Math.sqrt(d1*d2),d2d3=Math.sqrt(d2*d3),scl2=2*d1+3*d1d2+d2,scl3=2*d3+3*d2d3+d2,den2=3*(d1+d1d2),den3=3*(d3+d2d3);gbez.c({x:p3.x,y:p3.y,x1:(-d2*p1.x+scl2*p2.x+d1*p3.x)/den2,y1:(-d2*p1.y+scl2*p2.y+d1*p3.y)/den2,x2:(-d2*p4.x+scl3*p3.x+d3*p2.x)/den3,y2:(-d2*p4.y+scl3*p3.y+d3*p2.y)/den3})}gbez.c(closed?{x:itr(0).x,y:itr(0).y}:{x:itr(n-1).x,y:itr(n-1).y});if(closed)gbez.z();gbez.drw({ls:ls,lw:lw,fs:fs,sh:sh});if(istrf)gbez.end()}return gbez}});"use strict";
+ */var g2=g2||{prototype:{}};g2.NONE=0;g2.OVER=1;g2.DRAG=2;g2.EDIT=4;g2.symbol=g2.symbol||{};g2.symbol.tick=g2().p().m({x:0,y:-2}).l({x:0,y:2}).stroke({lc:"round",lwnosc:true});g2.symbol.dot=g2().cir({x:0,y:0,r:2,ls:"transparent"});g2.symbol.sqr=g2().rec({x:-1.5,y:-1.5,b:3,h:3,ls:"transparent"});g2.symbol.nodcolor="#333";g2.symbol.nodfill="#dedede";g2.symbol.nodfill2="#aeaeae";g2.symbol.linkcolor="#666";g2.symbol.linkfill="rgba(225,225,225,0.75)";g2.symbol.dimcolor="darkslategray";g2.symbol.solid=[];g2.symbol.dash=[15,10];g2.symbol.dot=[4,4];g2.symbol.dashdot=[25,6.5,2,6.5];g2.symbol.labelSignificantDigits=3;g2.flatten=function(obj){const args=Object.create(null);for(let p in obj)if(typeof obj[p]!=="function")args[p]=obj[p];return args};g2.pointIfc={get p(){return{x:this.x,y:this.y}},get x(){return Object.getOwnPropertyDescriptor(this,"p")?this.p.x:0},get y(){return Object.getOwnPropertyDescriptor(this,"p")?this.p.y:0},set x(q){if(Object.getOwnPropertyDescriptor(this,"p"))this.p.x=q},set y(q){if(Object.getOwnPropertyDescriptor(this,"p"))this.p.y=q}};g2.labelIfc={getLabelOffset(){const off=this.label.off!==undefined?+this.label.off:1;return off+Math.sign(off)*(this.lw||2)/2},getLabelString(){let s=typeof this.label==="object"?this.label.str:typeof this.label==="string"?this.label:"?";if(s&&s[0]==="@"&&this[s.substr(1)]){s=s.substr(1);let val=this[s];val=Number.isInteger(val)?val:Number(val).toFixed(Math.max(g2.symbol.labelSignificantDigits-Math.log10(val),0));s=`${val}${s==="angle"?"°":""}`}return s},drawLabel(g){const lbl=this.label;const font=lbl.font||g2.defaultStyle.font;const h=parseInt(font);const str=this.getLabelString();const rx=(str.length||1)*.75*h/2,ry=1.25*h/2;const pos=this.pointAt(lbl.loc||this.lbloc||"se");const off=this.getLabelOffset();const p={x:pos.x+pos.nx*(off+Math.sign(off)*rx),y:pos.y+pos.ny*(off+Math.sign(off)*ry)};if(lbl.border)g.ell({x:p.x,y:p.y,rx:rx,ry:ry,ls:lbl.fs||"black",fs:lbl.fs2||"#ffc"});g.txt({str:str,x:p.x,y:p.y,thal:"center",tval:"middle",fs:lbl.fs||"black",font:lbl.font});return g}};g2.markIfc={markAt(loc){const p=this.pointAt(loc);const w=Math.atan2(p.ny,p.nx)+Math.PI/2;return{grp:this.getMarkSymbol(),x:p.x,y:p.y,w:w,scl:this.lw||1,ls:this.ls||"#000",fs:this.fs||this.ls||"#000"}},getMarkSymbol(){const mrk=this.mark;if(typeof mrk==="number"||!mrk)return g2.symbol.tick;if(typeof mrk.symbol==="object")return mrk.symbol;if(typeof mrk.symbol==="string")return g2.symbol[mrk.symbol]},drawMark(g,closed=false){let loc;if(Array.isArray(this.mark)){loc=this.mark}else{const count=typeof this.mark==="object"?this.mark.count:this.mark;loc=count?Array.from(Array(count)).map((_,i)=>i/(count-!closed)):this.mark.loc}for(let l of loc){g.use(this.markAt(l))}return g}};g2.prototype.cir.prototype=g2.mix(g2.pointIfc,g2.labelIfc,g2.markIfc,{w:0,lbloc:"c",get isSolid(){return this.fs&&this.fs!=="transparent"},get len(){return 2*Math.PI*this.r},get lsh(){return this.state&g2.OVER},get sh(){return this.state&g2.OVER?[0,0,5,"black"]:false},get g2(){const e=g2();this.label&&e.ins(g=>this.drawLabel(g));this.mark&&e.ins(g=>this.drawMark(g,true));return()=>g2().cir(g2.flatten(this)).ins(e)},pointAt(loc){const Q=Math.SQRT2/2;const LOC={c:[0,0],e:[1,0],ne:[Q,Q],n:[0,1],nw:[-Q,Q],w:[-1,0],sw:[-Q,-Q],s:[0,-1],se:[Q,-Q]};const q=loc+0===loc?[Math.cos(loc*2*Math.PI),Math.sin(loc*2*Math.PI)]:LOC[loc||"c"]||[0,0];return{x:this.x+q[0]*this.r,y:this.y+q[1]*this.r,nx:q[0],ny:q[1]}},hit({x:x,y:y,eps:eps}){return this.isSolid?g2.isPntInCir({x:x,y:y},this,eps):g2.isPntOnCir({x:x,y:y},this,eps)},drag({dx:dx,dy:dy}){this.x+=dx;this.y+=dy}});g2.prototype.lin.prototype=g2.mix(g2.labelIfc,g2.markIfc,{get p1(){return{x1:this.x1,y1:this.y1}},get x1(){return Object.getOwnPropertyDescriptor(this,"p1")?this.p1.x:0},get y1(){return Object.getOwnPropertyDescriptor(this,"p1")?this.p1.y:0},set x1(q){if(Object.getOwnPropertyDescriptor(this,"p1"))this.p1.x=q},set y1(q){if(Object.getOwnPropertyDescriptor(this,"p1"))this.p1.y=q},get p2(){return{x2:this.x2,y2:this.y2}},get x2(){return Object.getOwnPropertyDescriptor(this,"p2")?this.p2.x:0},get y2(){return Object.getOwnPropertyDescriptor(this,"p2")?this.p2.y:0},set x2(q){if(Object.getOwnPropertyDescriptor(this,"p2"))this.p2.x=q},set y2(q){if(Object.getOwnPropertyDescriptor(this,"p2"))this.p2.y=q},isSolid:false,get len(){return Math.hypot(this.x2-this.x1,this.y2-this.y1)},get sh(){return this.state&g2.OVER?[0,0,5,"black"]:false},get g2(){const e=g2();this.label&&e.ins(e=>this.drawLabel(e));this.mark&&e.ins(e=>this.drawMark(e));return()=>g2().lin(g2.flatten(this)).ins(e)},pointAt(loc){let t=loc==="beg"?0:loc==="end"?1:loc+0===loc?loc:.5,dx=this.x2-this.x1,dy=this.y2-this.y1,len=Math.hypot(dx,dy);return{x:this.x1+dx*t,y:this.y1+dy*t,nx:len?dy/len:0,ny:len?-dx/len:-1}},hit({x:x,y:y,eps:eps}){return g2.isPntOnLin({x:x,y:y},{x:this.x1,y:this.y1},{x:this.x2,y:this.y2},eps)},drag({dx:dx,dy:dy}){this.x1+=dx;this.x2+=dx;this.y1+=dy;this.y2+=dy}});g2.prototype.rec.prototype=g2.mix(g2.pointIfc,g2.labelIfc,g2.markIfc,{get len(){return 2*(this.b+this.h)},get isSolid(){return this.fs&&this.fs!=="transparent"},get lsh(){return this.state&g2.OVER},get sh(){return this.state&g2.OVER?[0,0,5,"black"]:false},get g2(){const e=g2();this.label&&e.ins(e=>this.drawLabel(e));this.mark&&e.ins(e=>this.drawMark(e,true));return()=>g2().rec(g2.flatten(this)).ins(e)},lbloc:"c",pointAt(loc){const locAt=loc=>{const o={c:[0,0],e:[1,0],ne:[.95,.95],n:[0,1],nw:[-.95,.95],w:[-1,0],sw:[-.95,-.95],s:[0,-1],se:[.95,-.95]};if(o[loc])return o[loc];const w=2*Math.PI*loc+pi/4;if(loc<=.25)return[1/Math.tan(w),1];if(loc<=.5)return[-1,-Math.tan(w)];if(loc<=.75)return[-1/Math.tan(w),-1];if(loc<=1)return[1,Math.tan(w)]};const q=locAt(loc);return{x:this.x+(1+q[0])*this.b/2,y:this.y+(1+q[1])*this.h/2,nx:1-Math.abs(q[0])<.01?q[0]:0,ny:1-Math.abs(q[1])<.01?q[1]:0}},hit({x:x,y:y,eps:eps}){return this.isSolid?g2.isPntInBox({x:x,y:y},{x:this.x+this.b/2,y:this.y+this.h/2,b:this.b/2,h:this.h/2},eps):g2.isPntOnBox({x:x,y:y},{x:this.x+this.b/2,y:this.y+this.h/2,b:this.b/2,h:this.h/2},eps)},drag({dx:dx,dy:dy}){this.x+=dx;this.y+=dy}});g2.prototype.arc.prototype=g2.mix(g2.pointIfc,g2.labelIfc,g2.markIfc,{get len(){return Math.abs(this.r*this.dw)},isSolid:false,get angle(){return this.dw/Math.PI*180},get sh(){return this.state&g2.OVER?[0,0,5,"black"]:false},get g2(){const e=g2();this.label&&e.ins(e=>this.drawLabel(e));this.mark&&e.ins(e=>this.drawMark(e));return()=>g2().arc(g2.flatten(this)).ins(e)},lbloc:"mid",pointAt(loc){let t=loc==="beg"?0:loc==="end"?1:loc==="mid"?.5:loc+0===loc?loc:.5,ang=(this.w||0)+t*(this.dw||Math.PI*2),cang=Math.cos(ang),sang=Math.sin(ang),r=loc==="c"?0:this.r;return{x:this.x+r*cang,y:this.y+r*sang,nx:cang,ny:sang}},hit({x:x,y:y,eps:eps}){return g2.isPntOnArc({x:x,y:y},this,eps)},drag({dx:dx,dy:dy}){this.x+=dx;this.y+=dy}});g2.prototype.hdl=function(args){return this.addCommand({c:"hdl",a:args})};g2.prototype.hdl.prototype=g2.mix(g2.prototype.cir.prototype,{r:5,isSolid:true,draggable:true,lbloc:"se",get lsh(){return this.state&g2.OVER},get sh(){return this.state&g2.OVER?[0,0,5,"black"]:false},g2(){const{x:x,y:y,r:r,b:b=4,shape:shape="cir",ls:ls="black",fs:fs="#ccc",sh:sh}=this;return shape==="cir"?g2().cir({x:x,y:y,r:r,ls:ls,fs:fs,sh:sh}).ins(g=>this.label&&this.drawLabel(g)):g2().rec({x:x-b,y:y-b,b:2*b,h:2*b,ls:ls,fs:fs,sh:sh}).ins(g=>this.label&&this.drawLabel(g))}});g2.prototype.nod=function(args={}){return this.addCommand({c:"nod",a:args})};g2.prototype.nod.prototype=g2.mix(g2.prototype.cir.prototype,{r:5,ls:"@nodcolor",fs:g2.symbol.nodfill,isSolid:true,lbloc:"se",g2(){return g2().cir({...g2.flatten(this),r:this.r*(this.scl!==undefined?this.scl:1)}).ins(g=>this.label&&this.drawLabel(g))}});g2.prototype.dblnod=function({x:x=0,y:y=0}){return this.addCommand({c:"dblnod",a:arguments[0]})};g2.prototype.dblnod.prototype=g2.mix(g2.prototype.cir.prototype,{r:6,isSolid:true,g2(){return g2().beg({x:this.x,y:this.y}).cir({r:6,ls:"@nodcolor",fs:"@nodfill",sh:this.sh}).cir({r:3,ls:"@nodcolor",fs:"@nodfill2"}).end().ins(g=>this.label&&this.drawLabel(g))}});g2.prototype.pol=function(args={}){return this.addCommand({c:"pol",a:args})};g2.prototype.pol.prototype=g2.mix(g2.prototype.nod.prototype,{g2(){return g2().beg(g2.flatten(this)).cir({r:6,fs:"@fs2"}).cir({r:2.5,fs:"@ls",ls:"transparent"}).end().ins(g=>this.label&&this.drawLabel(g))}});g2.prototype.gnd=function(args={}){return this.addCommand({c:"gnd",a:args})};g2.prototype.gnd.prototype=g2.mix(g2.prototype.nod.prototype,{g2(){return g2().beg(g2.flatten(this)).cir({x:0,y:0,r:6}).p().m({x:0,y:6}).a({dw:Math.PI/2,x:-6,y:0}).l({x:6,y:0}).a({dw:-Math.PI/2,x:0,y:-6}).z().fill({fs:g2.symbol.nodcolor}).end().ins(g=>this.label&&this.drawLabel(g))}});g2.prototype.nodfix=function(args={}){return this.addCommand({c:"nodfix",a:args})};g2.prototype.nodfix.prototype=g2.mix(g2.prototype.nod.prototype,{g2(){return g2().beg(g2.flatten(this)).p().m({x:-8,y:-12}).l({x:0,y:0}).l({x:8,y:-12}).drw({fs:g2.symbol.nodfill2}).cir({x:0,y:0,r:this.r}).end().ins(g=>this.label&&this.drawLabel(g))}});g2.prototype.nodflt=function(args={}){return this.addCommand({c:"nodflt",a:args})};g2.prototype.nodflt.prototype=g2.mix(g2.prototype.nod.prototype,{g2(){return g2().beg(g2.flatten(this)).p().m({x:-8,y:-12}).l({x:0,y:0}).l({x:8,y:-12}).drw({ls:g2.symbol.nodcolor,fs:g2.symbol.nodfill2}).cir({x:0,y:0,r:this.r,ls:g2.symbol.nodcolor,fs:g2.symbol.nodfill}).lin({x1:-9,y1:-19,x2:9,y2:-19,ls:g2.symbol.nodfill2,lw:5}).lin({x1:-9,y1:-15.5,x2:9,y2:-15.5,ls:g2.symbol.nodcolor,lw:2}).end().ins(g=>this.label&&this.drawLabel(g))}});g2.prototype.vec=function vec(args){return this.addCommand({c:"vec",a:args})};g2.prototype.vec.prototype=g2.mix(g2.prototype.lin.prototype,{g2(){const{x1:x1,y1:y1,x2:x2,y2:y2,lw:lw=1,ls:ls="#000",ld:ld=[],fs:fs=ls||"#000",lc:lc="round",lj:lj="round"}=this;const dx=x2-x1,dy=y2-y1,r=Math.hypot(dx,dy);const b=3*(1+lw)>r?r/3:1+lw;const arrowHead=()=>g2().p().m({x:0,y:0}).l({x:-5*b,y:b}).a({dw:-Math.PI/3,x:-5*b,y:-b}).z().drw({ls:ls,fs:fs,lc:lc,lj:lj});return g2().beg({x:x1,y:y1,w:Math.atan2(dy,dx),lc:lc,lj:lj}).p().m({x:0,y:0}).l({x:r-3*b,y:0}).stroke({ls:ls,lw:lw,ld:ld}).use({grp:arrowHead,x:r,y:0}).end().ins(g=>this.label&&this.drawLabel(g))}});g2.prototype.avec=function avec(args){return this.addCommand({c:"avec",a:args})};g2.prototype.avec.prototype=g2.mix(g2.prototype.arc.prototype,{g2(){const{x:x,y:y,r:r,w:w,dw:dw=0,lw:lw=1,lc:lc="round",lj:lj="round",ls:ls,fs:fs=ls||"#000",label:label}=this;const b=3*(1+lw)>r?r/3:1+lw,bw=5*b/r;const arrowHead=()=>g2().p().m({x:0,y:2*b}).l({x:0,y:-2*b}).m({x:0,y:0}).l({x:-5*b,y:b}).a({dw:-Math.PI/3,x:-5*b,y:-b}).z().drw({ls:ls,fs:fs});return g2().beg({x:x,y:y,w:w,ls:ls,lw:lw,lc:lc,lj:lj}).arc({r:r,w:0,dw:dw}).use({grp:arrowHead,x:r*Math.cos(dw),y:r*Math.sin(dw),w:dw>=0?dw+Math.PI/2-bw/2:dw-Math.PI/2+bw/2}).end().ins(g=>label&&this.drawLabel(g))}});g2.prototype.dim=function dim(args){return this.addCommand({c:"dim",a:args})};g2.prototype.dim.prototype=g2.mix(g2.prototype.lin.prototype,{pointAt(loc){const pnt=g2.prototype.lin.prototype.pointAt.call(this,loc);if(this.off){pnt.x+=this.off*pnt.nx;pnt.y+=this.off*pnt.ny}return pnt},g2(){const{x1:x1,y1:y1,x2:x2,y2:y2,lw:lw=1,lc:lc="round",lj:lj="round",off:off=0,inside:inside=true,ls:ls,fs:fs=ls||"#000",label:label}=this;const dx=x2-x1,dy=y2-y1,r=Math.hypot(dx,dy);const b=3*(1+lw)>r?r/3:1+lw;const arrowHead=()=>g2().p().m({x:0,y:2*b}).l({x:0,y:-2*b}).m({x:0,y:0}).l({x:-5*b,y:b}).a({dw:-Math.PI/3,x:-5*b,y:-b}).z().drw({ls:ls,fs:fs});return g2().beg({x:x1+off/r*dy,y:y1-off/r*dx,w:Math.atan2(dy,dx),ls:ls,fs:fs,lw:lw,lc:lc,lj:lj}).lin({x1:inside?4*b:0,y1:0,x2:inside?r-4*b:r,y2:0}).use({grp:arrowHead,x:r,y:0,w:inside?0:Math.PI}).use({grp:arrowHead,x:0,y:0,w:inside?Math.PI:0}).lin({x1:0,y1:off,x2:0,y2:0}).lin({x1:r,y1:off,x2:r,y2:0}).end().ins(g=>label&&this.drawLabel(g))}});g2.prototype.adim=function adim(args){return this.addCommand({c:"adim",a:args})};g2.prototype.adim.prototype=g2.mix(g2.prototype.arc.prototype,{g2(){const{x:x,y:y,r:r,w:w,dw:dw,lw:lw=1,lc:lc="round",lj:lj="round",ls:ls,fs:fs=ls||"#000",label:label}=this;const b=3*(1+lw)>r?r/3:1+lw,bw=5*b/r;const arrowHead=()=>g2().p().m({x:0,y:2*b}).l({x:0,y:-2*b}).m({x:0,y:0}).l({x:-5*b,y:b}).a({dw:-Math.PI/3,x:-5*b,y:-b}).z().drw({ls:ls,fs:fs});const outside=this.inside!==undefined&&this.outside===undefined?!this.inside:!!this.outside;return g2().beg({x:x,y:y,w:w,ls:ls,lw:lw,lc:lc,lj:lj}).arc({r:r,w:0,dw:dw}).use({grp:arrowHead,x:r,y:0,w:!outside&&dw>0||outside&&dw<0?-Math.PI/2+bw/2:Math.PI/2-bw/2}).use({grp:arrowHead,x:r*Math.cos(dw),y:r*Math.sin(dw),w:!outside&&dw>0||outside&&dw<0?dw+Math.PI/2-bw/2:dw-Math.PI/2+bw/2}).end().ins(g=>label&&this.drawLabel(g))}});g2.prototype.origin=function(args={}){return this.addCommand({c:"origin",a:args})};g2.prototype.origin.prototype=g2.mix(g2.prototype.nod.prototype,{lbloc:"sw",g2(){const{x:x,y:y,w:w,ls:ls="#000",lw:lw=1}=this;return g2().beg({x:x,y:y,w:w,ls:ls}).vec({x1:0,y1:0,x2:40,y2:0,lw:lw,fs:"#ccc"}).vec({x1:0,y1:0,x2:0,y2:40,lw:lw,fs:"#ccc"}).cir({x:0,y:0,r:lw+1,fs:"#ccc"}).end().ins(g=>this.label&&this.drawLabel(g))}});g2.prototype.ply.prototype=g2.mix(g2.labelIfc,g2.markIfc,{get isSolid(){return this.closed&&this.fs&&this.fs!=="transparent"},get sh(){return this.state&g2.OVER?[0,0,5,"black"]:false},pointAt(loc){const t=loc==="beg"?0:loc==="end"?1:loc+0===loc?loc:.5,pitr=g2.pntItrOf(this.pts),pts=[],len=[];for(let itr=0;itr{const target=t*len.reduce((a,b)=>a+b);for(let itr=0,tmp=0;itr=target){return{t2:1-(tmp-target)/len[itr],x:pts[itr].x,y:pts[itr].y,dx:next.x-pts[itr].x,dy:next.y-pts[itr].y}}}})();const len2=Math.hypot(dx,dy);return{x:(this.x||0)+x+dx*t2,y:(this.y||0)+y+dy*t2,nx:len2?dy/len2:1,ny:len2?dx/len2:0}},hit({x:x,y:y,eps:eps}){return this.isSolid?g2.isPntInPly({x:x-this.x,y:y-this.y},this,eps):g2.isPntOnPly({x:x-this.x,y:y-this.y},this,eps)},drag({dx:dx,dy:dy}){this.x+=dx;this.y+=dy},get g2(){const e=g2();this.label&&e.ins(e=>this.drawLabel(e));this.mark&&e.ins(e=>this.drawMark(e,this.closed));return()=>g2().ply(g2.flatten(this)).ins(e)}});g2.prototype.use.prototype={get p(){return{x:this.x,y:this.y}},get x(){return Object.getOwnPropertyDescriptor(this,"p")?this.p.x:0},get y(){return Object.getOwnPropertyDescriptor(this,"p")?this.p.y:0},set x(q){if(Object.getOwnPropertyDescriptor(this,"p"))this.p.x=q},set y(q){if(Object.getOwnPropertyDescriptor(this,"p"))this.p.y=q},isSolid:false};g2.prototype.spline=function spline({pts:pts,closed:closed,x:x,y:y,w:w}){arguments[0]._itr=g2.pntItrOf(pts);return this.addCommand({c:"spline",a:arguments[0]})};g2.prototype.spline.prototype=g2.mix(g2.prototype.ply.prototype,{g2:function(){let{pts:pts,closed:closed,x:x,y:y,w:w,ls:ls,lw:lw,fs:fs,sh:sh}=this,itr=this._itr,gbez;if(itr){let b=[],i,n=itr.len,p1,p2,p3,p4,d1,d2,d3,d1d2,d2d3,scl2,scl3,den2,den3,istrf=x||y||w;gbez=g2();if(istrf)gbez.beg({x:x,y:y,w:w});gbez.p().m(itr(0));for(let i=0;i<(closed?n:n-1);i++){if(i===0){p1=closed?itr(n-1):{x:2*itr(0).x-itr(1).x,y:2*itr(0).y-itr(1).y};p2=itr(0);p3=itr(1);p4=n===2?closed?itr(0):{x:2*itr(1).x-itr(0).x,y:2*itr(1).y-itr(0).y}:itr(2);d1=Math.max(Math.hypot(p2.x-p1.x,p2.y-p1.y),Number.EPSILON);d2=Math.max(Math.hypot(p3.x-p2.x,p3.y-p2.y),Number.EPSILON)}else{p1=p2;p2=p3;p3=p4;p4=i===n-2?closed?itr(0):{x:2*itr(n-1).x-itr(n-2).x,y:2*itr(n-1).y-itr(n-2).y}:i===n-1?itr(1):itr(i+2);d1=d2;d2=d3}d3=Math.max(Math.hypot(p4.x-p3.x,p4.y-p3.y),Number.EPSILON);d1d2=Math.sqrt(d1*d2),d2d3=Math.sqrt(d2*d3),scl2=2*d1+3*d1d2+d2,scl3=2*d3+3*d2d3+d2,den2=3*(d1+d1d2),den3=3*(d3+d2d3);gbez.c({x:p3.x,y:p3.y,x1:(-d2*p1.x+scl2*p2.x+d1*p3.x)/den2,y1:(-d2*p1.y+scl2*p2.y+d1*p3.y)/den2,x2:(-d2*p4.x+scl3*p3.x+d3*p2.x)/den3,y2:(-d2*p4.y+scl3*p3.y+d3*p2.y)/den3})}gbez.c(closed?{x:itr(0).x,y:itr(0).y}:{x:itr(n-1).x,y:itr(n-1).y});if(closed)gbez.z();gbez.drw({ls:ls,lw:lw,fs:fs,sh:sh});if(istrf)gbez.end()}return gbez}});"use strict";
/**
* g2.mec (c) 2013-18 Stefan Goessner
* @author Stefan Goessner
@@ -88,4 +88,4 @@
* @property {float} [xmax] - maximal x-axis value. If not given it is calculated from chart data values.
* @property {float} [ymin] - minimal y-axis value. If not given it is calculated from chart data values.
* @property {float} [ymax] - maximal y-axis value. If not given it is calculated from chart data values.
- */g2.prototype.chart=function chart({x:x,y:y,b:b,h:h,style:style,title:title,funcs:funcs,xaxis:xaxis,xmin:xmin,xmax:xmax,yaxis:yaxis,ymin:ymin,ymax:ymax}){return this.addCommand({c:"chart",a:arguments[0]})};g2.prototype.chart.prototype={g2(){const g=g2(),funcs=this.get("funcs"),title=this.title&&this.get("title");if(!this.b)this.b=this.defaults.b;if(!this.h)this.h=this.defaults.h;if(funcs&&funcs.length){const tmp=[this.xmin===undefined,this.xmax===undefined,this.ymin===undefined,this.ymax===undefined];funcs.forEach(f=>this.initFunc(f,...tmp))}this.xAxis=this.autoAxis(this.get("xmin"),this.get("xmax"),0,this.b);this.yAxis=this.autoAxis(this.get("ymin"),this.get("ymax"),0,this.h);g.rec({x:this.x,y:this.y,b:this.b,h:this.h,fs:this.get("fs"),ls:this.get("ls")});g.beg(Object.assign({x:this.x,y:this.y,lw:1},this.defaults.style,this.style));if(title)g.txt(Object.assign({str:this.title&&this.title.text||this.title,x:this.get("b")/2,y:this.get("h")+this.get("title","offset"),w:0},this.defaults.title.style,this.title&&this.title.style||{}));if(this.xaxis)this.drawXAxis(g);if(this.yaxis)this.drawYAxis(g);g.end();if(funcs){funcs.forEach((fnc,i)=>{this.drawFunc(g,fnc,this.defaults.colors[i%this.defaults.colors.length])})}return g},initFunc(fn,setXmin,setXmax,setYmin,setYmax){let itr;if(fn.data&&fn.data.length){itr=fn.itr=g2.pntItrOf(fn.data)}else if(fn.fn&&fn.dx){const xmin=+this.xmin||this.defaults.xmin;const xmax=+this.xmax||this.defaults.xmax;itr=fn.itr=(i=>{let x=xmin+i*fn.dx;return{x:x,y:fn.fn(x)}});itr.len=(xmax-xmin)/fn.dx+1}if(itr&&(setXmin||setXmax||setYmin||setYmax)){const xarr=[];const yarr=[];for(let i=0;ithis.xmax)this.xmax=xmax}if(setYmin){const ymin=Math.min(...yarr);if(!this.ymin||yminthis.ymax)this.ymax=ymax}if(fn.color&&typeof fn.color==="number")fn.color=this.defaults.colors[fn.color%this.defaults.colors.length]}},autoAxis(zmin,zmax,tmin,tmax){let base=2,exp=1,eps=Math.sqrt(Number.EPSILON),Dz=zmax-zmin||1,Dt=tmax-tmin||1,scl=Dz>eps?Dt/Dz:1,dz=base*Math.pow(10,exp),dt=Math.floor(scl*dz),N,dt01,i0,j0,jth,t0,res;while(dt<14||dt>35){if(dt<14){if(base==1)base=2;else if(base==2)base=5;else if(base==5){base=1;exp++}}else{if(base==1){base=5;exp--}else if(base==2)base=1;else if(base==5)base=2}dz=base*Math.pow(10,exp);dt=scl*dz}i0=(scl*Math.abs(zmin)+eps/2)%dt9?5:2;return{zmin:zmin,zmax:zmax,base:base,exp:exp,scl:scl,dt:dt,dz:dz,N:N,t0:t0,z0:z0,i0:i0,j0:j0,jth:jth,itr(i){return{t:this.t0+i*this.dt,z:parseFloat((this.z0+i*this.dz).toFixed(Math.abs(this.exp))),maj:(this.j0-this.i0+i)%this.jth===0}}}},drawXAxis(g){let tick,showgrid=this.xaxis&&this.xaxis.grid,gridstyle=showgrid&&Object.assign({},this.defaults.xaxis.grid,this.xaxis.grid),showaxis=this.xaxis||this.xAxis,axisstyle=showaxis&&Object.assign({},this.defaults.xaxis.style,this.defaults.xaxis.labels.style,this.xaxis&&this.xaxis.style||{}),showline=showaxis&&this.get("xaxis","line"),showlabels=this.xAxis&&showaxis&&this.get("xaxis","labels"),showticks=this.xAxis&&showaxis&&this.get("xaxis","ticks"),ticklen=showticks?this.get("xaxis","ticks","len"):0,showorigin=showaxis&&this.get("xaxis","origin"),title=this.xaxis&&(this.get("xaxis","title","text")||this.xaxis.title)||"";g.beg(axisstyle);for(let i=0;i=0)g.lin({x1:-this.xAxis.zmin*this.xAxis.scl,y1:0,x2:-this.xAxis.zmin*this.xAxis.scl,y2:this.h});if(title)g.txt(Object.assign({str:title.text||title,x:this.b/2,y:-(this.get("xaxis","title","offset")+(showticks&&this.get("xaxis","ticks","len")||0)+(showlabels&&this.get("xaxis","labels","offset")||0)+(showlabels&&parseFloat(this.get("xaxis","labels","style","font"))||0)),w:0},this.get("xaxis","title","style")));g.end()},drawYAxis(g){let tick,showgrid=this.yaxis&&this.yaxis.grid,gridstyle=showgrid&&Object.assign({},this.defaults.yaxis.grid,this.yaxis.grid),showaxis=this.yaxis||this.yAxis,axisstyle=showaxis&&Object.assign({},this.defaults.yaxis.style,this.defaults.yaxis.labels.style,this.yaxis&&this.yaxis.style||{}),showline=showaxis&&this.get("yaxis","line"),showlabels=this.yAxis&&showaxis&&this.get("yaxis","labels"),showticks=this.yAxis&&showaxis&&this.get("yaxis","ticks"),ticklen=showticks?this.get("yaxis","ticks","len"):0,showorigin=showaxis&&this.get("yaxis","origin"),title=this.yaxis&&(this.get("yaxis","title","text")||this.yaxis.title)||"";g.beg(axisstyle);for(let i=0;i=0)g.lin({x1:0,y1:-this.yAxis.zmin*this.yAxis.scl,x2:this.b,y2:-this.yAxis.zmin*this.yAxis.scl});if(title)g.txt(Object.assign({str:title.text||title,x:-(this.get("yaxis","title","offset")+(showticks&&this.get("yaxis","ticks","len")||0)+(showlabels&&this.get("yaxis","labels","offset")||0)+(showlabels&&parseFloat(this.get("yaxis","labels","style","font"))||0)),y:this.h/2,w:Math.PI/2},this.get("yaxis","title","style")));g.end()},drawFunc(g,fn,defaultcolor){let itr=fn.itr;if(itr){let fill=fn.fill||fn.style&&fn.style.fs&&fn.style.fs!=="transparent",color=fn.color=fn.color||fn.style&&fn.style.ls||defaultcolor,plydata=[],args=Object.assign({pts:plydata,closed:false,ls:color,fs:fill?g2.color.rgbaStr(color,.125):"transparent",lw:1},fn.style);if(fill){plydata.push(this.pntOf({x:itr(0).x,y:0}))}const fence=({x:x,y:y})=>({x:Math.max(Math.min(this.xmax,x),this.xmin),y:Math.max(Math.min(this.ymax,y),this.ymin)});plydata.push(this.pntOf(fence(itr(0))));for(let i=1,n=itr.len;ithis.ymax||bfr.ythis.initFunc(f,...tmp))}if(this.xaxis)this.xAxis=this.autoAxis(this.get("xmin"),this.get("xmax"),0,this.b);if(this.yaxis)this.yAxis=this.autoAxis(this.get("ymin"),this.get("ymax"),0,this.h);g.rec({x:this.x,y:this.y,b:this.b,h:this.h,fs:this.get("fs"),ls:this.get("ls")});g.beg(Object.assign({x:this.x,y:this.y,lw:1},this.defaults.style,this.style));if(title)g.txt(Object.assign({str:this.title&&this.title.text||this.title,x:this.get("b")/2,y:this.get("h")+this.get("title","offset"),w:0},this.defaults.title.style,this.title&&this.title.style||{}));if(this.xaxis)this.drawXAxis(g);if(this.yaxis)this.drawYAxis(g);g.end();if(funcs){funcs.forEach((fnc,i)=>{this.drawFunc(g,fnc,this.defaults.colors[i%this.defaults.colors.length])})}return g},initFunc(fn,setXmin,setXmax,setYmin,setYmax){let itr;if(fn.data&&fn.data.length){itr=fn.itr=g2.pntItrOf(fn.data)}else if(fn.fn&&fn.dx){const xmin=+this.xmin||this.defaults.xmin;const xmax=+this.xmax||this.defaults.xmax;itr=fn.itr=(i=>{let x=xmin+i*fn.dx;return{x:x,y:fn.fn(x)}});itr.len=(xmax-xmin)/fn.dx+1}if(itr&&(setXmin||setXmax||setYmin||setYmax)){const xarr=[];const yarr=[];for(let i=0;ithis.xmax)this.xmax=xmax}if(setYmin){const ymin=Math.min(...yarr);if(!this.ymin||yminthis.ymax)this.ymax=ymax}if(fn.color&&typeof fn.color==="number")fn.color=this.defaults.colors[fn.color%this.defaults.colors.length]}},autoAxis(zmin,zmax,tmin,tmax){let base=1,exp=1,eps=Math.sqrt(Number.EPSILON),Dz=zmax-zmin||1,Dt=tmax-tmin||1,scl=Dz>eps?Dt/Dz:1,dz=base*Math.pow(10,exp),dt=Math.floor(scl*dz),N,i0,j0,jth,t0;while(dt<14||dt>35){if(dt<14){if(base==1)base=2;else if(base==2)base=5;else if(base==5){base=1;exp++}}else{if(base==1){base=5;exp--}else if(base==2)base=1;else if(base==5)base=2}dz=base*Math.pow(10,exp);dt=scl*dz}i0=(scl*Math.abs(zmin)+eps/2)%dt9?5:2;return{zmin:zmin,zmax:zmax,base:base,exp:exp,scl:scl,dt:dt,dz:dz,N:N,t0:t0,z0:z0,i0:i0,j0:j0,jth:jth,itr(i){return{t:this.t0+i*this.dt,z:parseFloat((this.z0+i*this.dz).toFixed(Math.abs(this.exp))),maj:(this.j0-this.i0+i)%this.jth===0}}}},drawXAxis(g){let tick,showgrid=this.xaxis&&this.xaxis.grid,gridstyle=showgrid&&Object.assign({},this.defaults.xaxis.grid,this.xaxis.grid),showaxis=this.xaxis||this.xAxis,axisstyle=showaxis&&Object.assign({},this.defaults.xaxis.style,this.defaults.xaxis.labels.style,this.xaxis&&this.xaxis.style||{}),showline=showaxis&&this.get("xaxis","line"),showlabels=this.xAxis&&showaxis&&this.get("xaxis","labels"),showticks=this.xAxis&&showaxis&&this.get("xaxis","ticks"),ticklen=showticks?this.get("xaxis","ticks","len"):0,showorigin=showaxis&&this.get("xaxis","origin"),title=this.xaxis&&(this.get("xaxis","title","text")||this.xaxis.title)||"";g.beg(axisstyle);for(let i=0;i=0)g.lin({x1:-this.xAxis.zmin*this.xAxis.scl,y1:0,x2:-this.xAxis.zmin*this.xAxis.scl,y2:this.h});if(title)g.txt(Object.assign({str:title.text||title,x:this.b/2,y:-(this.get("xaxis","title","offset")+(showticks&&this.get("xaxis","ticks","len")||0)+(showlabels&&this.get("xaxis","labels","offset")||0)+(showlabels&&parseFloat(this.get("xaxis","labels","style","font"))||0)),w:0},this.get("xaxis","title","style")));g.end()},drawYAxis(g){let tick,showgrid=this.yaxis&&this.yaxis.grid,gridstyle=showgrid&&Object.assign({},this.defaults.yaxis.grid,this.yaxis.grid),showaxis=this.yaxis||this.yAxis,axisstyle=showaxis&&Object.assign({},this.defaults.yaxis.style,this.defaults.yaxis.labels.style,this.yaxis&&this.yaxis.style||{}),showline=showaxis&&this.get("yaxis","line"),showlabels=this.yAxis&&showaxis&&this.get("yaxis","labels"),showticks=this.yAxis&&showaxis&&this.get("yaxis","ticks"),ticklen=showticks?this.get("yaxis","ticks","len"):0,showorigin=showaxis&&this.get("yaxis","origin"),title=this.yaxis&&(this.get("yaxis","title","text")||this.yaxis.title)||"";g.beg(axisstyle);for(let i=0;i=0)g.lin({x1:0,y1:-this.yAxis.zmin*this.yAxis.scl,x2:this.b,y2:-this.yAxis.zmin*this.yAxis.scl});if(title)g.txt(Object.assign({str:title.text||title,x:-(this.get("yaxis","title","offset")+(showticks&&this.get("yaxis","ticks","len")||0)+(showlabels&&this.get("yaxis","labels","offset")||0)+(showlabels&&parseFloat(this.get("yaxis","labels","style","font"))||0)),y:this.h/2,w:Math.PI/2},this.get("yaxis","title","style")));g.end()},drawFunc(g,fn,defaultcolor){let itr=fn.itr;if(itr){let fill=fn.fill||fn.style&&fn.style.fs&&fn.style.fs!=="transparent",color=fn.color=fn.color||fn.style&&fn.style.ls||defaultcolor,plydata=[],args=Object.assign({pts:plydata,closed:false,ls:color,fs:fill?g2.color.rgbaStr(color,.125):"transparent",lw:1},fn.style);if(fill){plydata.push(this.pntOf({x:itr(0).x,y:0}))}const fence=({x:x,y:y})=>({x:Math.max(Math.min(this.xmax,x),this.xmin),y:Math.max(Math.min(this.ymax,y),this.ymin)});plydata.push(this.pntOf(fence(itr(0))));for(let i=1,n=itr.len;ithis.ymax||bfr.y\u03f1 = ϱ |
+| Zeta | \u0396 = Ζ | \u03b6 = ζ | \| | Sigma | \u03a3 = Σ | \u03c3 = σ |
+| Eta | \u0397 = Η | \u03b7 = η | \| | Tau | \u03a4 = Τ | \u03c4 = τ |
+| Theta | \u0398 = Θ | \u03b8 = θ
\u03d1 = ϑ | \| | Upsilon | \u03a5 = Υ | \u03c5 = υ |
+| Iota | \u0399 = Ι | \u03b9 = ι | \| | Phi | \u03a6 = Φ | \u03c6 = φ
\u03d5 = ϕ |
+| Kappa | \u039a = Κ | \u03ba = κ | \| | Chi | \u03a7 = Χ | \u03c7 = χ |
+| Lambda | \u039b = Λ | \u03bb = λ | \| | Psi | \u03a8 = Ψ | \u03c8 = ψ |
+| Mu | \u039c = Μ | \u03bc = μ | \| | Omega | \u03a9 = Ω | \u03c9 = ω |
+
+
+
+
+| Combining Symbol | Unicode Character |
+|:------:|:------:|
+| Circumflex | x\u0302 = x̂ |
+| Tilde | u\u0303 = ũ |
+| Overline | r\u0305 = r̅ |
+| Dot | x\u0307 = ẋ |
+| Double dot | y\u0308 = ÿ |
+
+
+| Symbol | Subscript | Superscript | \| | Symbol | Subscript | Superscript |
+|:------:|:------:|:------:| --- |:------:|:------:|:------:|
+| 0 | \u2080 = ₀ | \u2070 = ⁰ | \| | α | –| \u1d45 = ᵅ |
+| 1 | \u2081 = ₁ | \u00B9 = ¹ | \| |β | \u1d66 = ᵦ |\u1d5d = ᵝ |
+| 2 | \u2082 = ₂ | \u00B2 = ² | \| |γ | \u1d67 = ᵧ | \u1d5e = ᵞ |
+| 3 | \u2083 = ₃ | \u00B3 = ³ | \| | δ | – | \u1d5f = ᵟ |
+| 4 | \u2084 = ₄ | \u2074 = ⁴ | \| | ε | – | \u1d4b = ᵋ |
+| 5 | \u2085 = ₅ | \u2075 = ⁵ | \| | θ | – | \u1dbf = ᶿ |
+| 6 | \u2086 = ₆ | \u2076 = ⁶ | \| | ι | – | \u1da5 = ᶥ |
+| 7 | \u2087 = ₇ | \u2077 = ⁷ | \| | ρ | \u1d68 = ᵨ | – |
+| 8 | \u2088 = ₈ | \u2078 = ⁸ | \| | ϕ | – | \u1db2 = ᶲ |
+| 9 | \u2089 = ₉ | \u2079 = ⁹ | \| | φ | \u1d69 = ᵩ | \u1d60 = ᵠ |
+| + | \u208A = ₊ | \u207A = ⁺ | \| | ψ | – | – |
+| - | \u208B = ₋ | \u207B = ⁻ | \| | χ | \u1d6a = ᵪ | \u1d61 = ᵡ |
+| = | \u208C = ₌ | \u207C = ⁼ | \| |
+| ( | \u208D = ₍ | \u207D = ⁽ | \| |
+| ) | \u208E = ₎ | \u207E = ⁾ | \| |
+
+| Symbol | Subscript | Superscript | \| | Symbol | Subscript | Superscript
+|:------:|:------:|:------:| --- |:------:|:------:|:------:|
+| a | \u2090 = ₐ | \u1d43 = ᵃ | \| | A | \u1D00 = ᴀ | \u1d2c = ᴬ |
+| b | – | \u1d47 = ᵇ | \| | B | \u0299 = ʙ | \u1d2e = ᴮ |
+| c | – | \u1d9c = ᶜ | \| | C |\u1D04 = ᴄ | – |
+| d | – | \u1d48 = ᵈ | \| | D | \u1D05 = ᴅ | \u1d30 = ᴰ |
+| e | \u2091 = ₑ | \u1d49 = ᵉ | \| | E | \u1D07 = ᴇ | \u1d31 = ᴱ |
+| f | – | \u1da0 = ᶠ | \| | F | \ua730 = ꜰ | – |
+| g | – | \u1d4d = ᵍ | \| | G | \u0262 = ɢ | \u1d33 = ᴳ |
+| h | \u2095 = ₕ | \u02b0 = ʰ | \| | H | \u029c = ʜ | \u1d34 = ᴴ |
+| i | \u1d62 = ᵢ | \u2071 = ⁱ | \| | I | \u026a = ɪ | \u1d35 = ᴵ |
+| j | \u2c7c = ⱼ | \u02b2 = ʲ | \| | J | \u1D0a = ᴊ | \u1d36 = ᴶ |
+| k | \u2096 = ₖ | \u1d4f = ᵏ | \| | K | \u1D0b = ᴋ | \u1d37 = ᴷ |
+| l | \u2c7c = ⱼ | \u02b2 = ʲ | \| | L | \u029f = ʟ | \u1d38 = ᴸ |
+| m | \u2098 = ₘ | \u1d50 = ᵐ | \| | M | \u1D0d = ᴍ | \u1d39 = ᴹ |
+| n | \u2099 = ₙ | \u207f = ⁿ | \| | N | \u0274 = ɴ | \u1d3a = ᴺ |
+| o | \u2092 = ₒ | \u1d52 = ᵒ | \| | O | \u1D0f = ᴏ | \u1d3c = ᴼ |
+| p | \u209a = ₚ | \u1d56 = ᵖ | \| | P | \u1D18 = ᴘ | \u1d3e = ᴾ |
+| q | – | – | \| | Q | \ua7af = ꞯ | – |
+| r | \u1d63 = ᵣ | \u02b3 = ʳ | \| | R | \u0280 = ʀ | \u1d3f = ᴿ |
+| s | \u209b = ₛ | \u02e2 = ˢ | \| | S | \ua731 = ꜱ | – |
+| t | \u209c = ₜ | \u1d57 = ᵗ | \| | T | \u1D1b = ᴛ | \u1d40 = ᵀ |
+| u | \u1d64 = ᵤ | \u1d58 = ᵘ | \| | U | \u1D1c = ᴜ | \u1d41 = ᵁ |
+| v | \u1d65 = ᵥ | \u1d5b = ᵛ | \| | V | \u1D20 = ᴠ | \u2c7d = ⱽ |
+| w | – | \u02b7 = ʷ | \| | W | \u1D21 = ᴡ | \u1d42 = ᵂ |
+| x | \u2093 = ₓ | \u02e3 = ˣ | \| | X | \u0078 = x | – |
+| y | – | \u02b8 = ʸ | \| | Y | \u028f = ʏ | – |
+| z | x\u0302 = x̂ | – | \| | Z | \u1D22 = ᴢ | – |
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..1955a76
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,1965 @@
+{
+ "name": "g2d",
+ "version": "3.0.1",
+ "lockfileVersion": 2,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "g2d",
+ "version": "3.0.1",
+ "license": "MIT",
+ "devDependencies": {
+ "concat": "^1.0.0",
+ "jsdoc-to-markdown": "^5.0.3",
+ "uglify-es": "^3.3.9"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.14.3",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.3.tgz",
+ "integrity": "sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==",
+ "dev": true,
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/ansi-escape-sequences": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.1.0.tgz",
+ "integrity": "sha512-dzW9kHxH011uBsidTXd14JXgzye/YLb2LzeKZ4bsgl/Knwx8AtbSFkkGxagdNOoh0DlqHCmfiEjWKBaqjOanVw==",
+ "dev": true,
+ "dependencies": {
+ "array-back": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/ansi-escape-sequences/node_modules/array-back": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
+ "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "dependencies": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "node_modules/array-back": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz",
+ "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "node_modules/bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+ "dev": true
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/cache-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/cache-point/-/cache-point-1.0.0.tgz",
+ "integrity": "sha512-ZqrZp9Hi5Uq7vfSGmNP2bUT/9DzZC2Y/GXjHB8rUJN1a+KLmbV05+vxHipNsg8+CSVgjcVVzLV8VZms6w8ZeRw==",
+ "dev": true,
+ "dependencies": {
+ "array-back": "^4.0.0",
+ "fs-then-native": "^2.0.0",
+ "mkdirp2": "^1.0.4"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/catharsis": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz",
+ "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==",
+ "dev": true,
+ "dependencies": {
+ "lodash": "^4.17.15"
+ },
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/collect-all": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/collect-all/-/collect-all-1.0.4.tgz",
+ "integrity": "sha512-RKZhRwJtJEP5FWul+gkSMEnaK6H3AGPTTWOiRimCcs+rc/OmQE3Yhy1Q7A7KsdkG3ZXVdZq68Y6ONSdvkeEcKA==",
+ "dev": true,
+ "dependencies": {
+ "stream-connect": "^1.0.2",
+ "stream-via": "^1.0.4"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/command-line-args": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.1.1.tgz",
+ "integrity": "sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg==",
+ "dev": true,
+ "dependencies": {
+ "array-back": "^3.0.1",
+ "find-replace": "^3.0.0",
+ "lodash.camelcase": "^4.3.0",
+ "typical": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/command-line-args/node_modules/array-back": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
+ "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/command-line-args/node_modules/typical": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz",
+ "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/command-line-tool": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/command-line-tool/-/command-line-tool-0.8.0.tgz",
+ "integrity": "sha512-Xw18HVx/QzQV3Sc5k1vy3kgtOeGmsKIqwtFFoyjI4bbcpSgnw2CWVULvtakyw4s6fhyAdI6soQQhXc2OzJy62g==",
+ "dev": true,
+ "dependencies": {
+ "ansi-escape-sequences": "^4.0.0",
+ "array-back": "^2.0.0",
+ "command-line-args": "^5.0.0",
+ "command-line-usage": "^4.1.0",
+ "typical": "^2.6.1"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/command-line-tool/node_modules/array-back": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
+ "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
+ "dev": true,
+ "dependencies": {
+ "typical": "^2.6.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/command-line-usage": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.1.0.tgz",
+ "integrity": "sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==",
+ "dev": true,
+ "dependencies": {
+ "ansi-escape-sequences": "^4.0.0",
+ "array-back": "^2.0.0",
+ "table-layout": "^0.4.2",
+ "typical": "^2.6.1"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/command-line-usage/node_modules/array-back": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
+ "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
+ "dev": true,
+ "dependencies": {
+ "typical": "^2.6.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "node_modules/common-sequence": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/common-sequence/-/common-sequence-2.0.2.tgz",
+ "integrity": "sha512-jAg09gkdkrDO9EWTdXfv80WWH3yeZl5oT69fGfedBNS9pXUKYInVJ1bJ+/ht2+Moeei48TmSbQDYMc8EOx9G0g==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/concat": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/concat/-/concat-1.0.3.tgz",
+ "integrity": "sha1-QPM1MInWVGdpXLGIa0Xt1jfYzKg=",
+ "dev": true,
+ "dependencies": {
+ "commander": "^2.9.0"
+ },
+ "bin": {
+ "concat": "bin/concat"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "node_modules/config-master": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/config-master/-/config-master-3.1.0.tgz",
+ "integrity": "sha1-ZnZjWQUFooO/JqSE1oSJ10xUhdo=",
+ "dev": true,
+ "dependencies": {
+ "walk-back": "^2.0.1"
+ }
+ },
+ "node_modules/config-master/node_modules/walk-back": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-2.0.1.tgz",
+ "integrity": "sha1-VU4qnYdPrEeoywBr9EwvDEmYoKQ=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/dmd": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/dmd/-/dmd-4.0.6.tgz",
+ "integrity": "sha512-7ZYAnFQ6jGm4SICArwqNPylJ83PaOdPTAkds3Z/s1ueFqSc5ilJ2F0b7uP+35W1PUbemH++gn5/VlC3KwEgiHQ==",
+ "dev": true,
+ "dependencies": {
+ "array-back": "^4.0.1",
+ "cache-point": "^1.0.0",
+ "common-sequence": "^2.0.0",
+ "file-set": "^3.0.0",
+ "handlebars": "^4.5.3",
+ "marked": "^0.7.0",
+ "object-get": "^2.1.0",
+ "reduce-flatten": "^3.0.0",
+ "reduce-unique": "^2.0.1",
+ "reduce-without": "^1.0.1",
+ "test-value": "^3.0.0",
+ "walk-back": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/entities": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz",
+ "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==",
+ "dev": true
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/file-set": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/file-set/-/file-set-3.0.0.tgz",
+ "integrity": "sha512-B/SdeSIeRv7VlOgIjtH3dkxMI+tEy5m+OeCXfAUsirBoVoY+bGtsmvmmTFPm/G23TBY4RiTtjpcgePCfwXRjqA==",
+ "dev": true,
+ "dependencies": {
+ "array-back": "^4.0.0",
+ "glob": "^7.1.5"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-replace": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz",
+ "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==",
+ "dev": true,
+ "dependencies": {
+ "array-back": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/find-replace/node_modules/array-back": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
+ "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/fs-then-native": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fs-then-native/-/fs-then-native-2.0.0.tgz",
+ "integrity": "sha1-GaEk2U2QwiyOBF8ujdbr6jbUjGc=",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "node_modules/glob": {
+ "version": "7.1.7",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+ "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ },
+ "engines": {
+ "node": "*"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.6",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
+ "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
+ "dev": true
+ },
+ "node_modules/handlebars": {
+ "version": "4.7.7",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
+ "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
+ "dev": true,
+ "dependencies": {
+ "minimist": "^1.2.5",
+ "neo-async": "^2.6.0",
+ "source-map": "^0.6.1",
+ "wordwrap": "^1.0.0"
+ },
+ "bin": {
+ "handlebars": "bin/handlebars"
+ },
+ "engines": {
+ "node": ">=0.4.7"
+ },
+ "optionalDependencies": {
+ "uglify-js": "^3.1.4"
+ }
+ },
+ "node_modules/inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "dependencies": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "node_modules/js2xmlparser": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.1.tgz",
+ "integrity": "sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw==",
+ "dev": true,
+ "dependencies": {
+ "xmlcreate": "^2.0.3"
+ }
+ },
+ "node_modules/jsdoc": {
+ "version": "3.6.7",
+ "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.7.tgz",
+ "integrity": "sha512-sxKt7h0vzCd+3Y81Ey2qinupL6DpRSZJclS04ugHDNmRUXGzqicMJ6iwayhSA0S0DwwX30c5ozyUthr1QKF6uw==",
+ "dev": true,
+ "dependencies": {
+ "@babel/parser": "^7.9.4",
+ "bluebird": "^3.7.2",
+ "catharsis": "^0.9.0",
+ "escape-string-regexp": "^2.0.0",
+ "js2xmlparser": "^4.0.1",
+ "klaw": "^3.0.0",
+ "markdown-it": "^10.0.0",
+ "markdown-it-anchor": "^5.2.7",
+ "marked": "^2.0.3",
+ "mkdirp": "^1.0.4",
+ "requizzle": "^0.2.3",
+ "strip-json-comments": "^3.1.0",
+ "taffydb": "2.6.2",
+ "underscore": "~1.13.1"
+ },
+ "bin": {
+ "jsdoc": "jsdoc.js"
+ },
+ "engines": {
+ "node": ">=8.15.0"
+ }
+ },
+ "node_modules/jsdoc-api": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/jsdoc-api/-/jsdoc-api-5.0.4.tgz",
+ "integrity": "sha512-1KMwLnfo0FyhF06TQKzqIm8BiY1yoMIGICxRdJHUjzskaHMzHMmpLlmNFgzoa4pAC8t1CDPK5jWuQTvv1pBsEQ==",
+ "dev": true,
+ "dependencies": {
+ "array-back": "^4.0.0",
+ "cache-point": "^1.0.0",
+ "collect-all": "^1.0.3",
+ "file-set": "^2.0.1",
+ "fs-then-native": "^2.0.0",
+ "jsdoc": "^3.6.3",
+ "object-to-spawn-args": "^1.1.1",
+ "temp-path": "^1.0.0",
+ "walk-back": "^3.0.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/jsdoc-api/node_modules/file-set": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/file-set/-/file-set-2.0.1.tgz",
+ "integrity": "sha512-XgOUUpgR6FbbfYcniLw0qm1Am7PnNYIAkd+eXxRt42LiYhjaso0WiuQ+VmrNdtwotyM+cLCfZ56AZrySP3QnKA==",
+ "dev": true,
+ "dependencies": {
+ "array-back": "^2.0.0",
+ "glob": "^7.1.3"
+ }
+ },
+ "node_modules/jsdoc-api/node_modules/file-set/node_modules/array-back": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
+ "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
+ "dev": true,
+ "dependencies": {
+ "typical": "^2.6.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/jsdoc-api/node_modules/walk-back": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-3.0.1.tgz",
+ "integrity": "sha512-umiNB2qLO731Sxbp6cfZ9pwURJzTnftxE4Gc7hq8n/ehkuXC//s9F65IEIJA2ZytQZ1ZOsm/Fju4IWx0bivkUQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/jsdoc-parse": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/jsdoc-parse/-/jsdoc-parse-4.0.1.tgz",
+ "integrity": "sha512-qIObw8yqYZjrP2qxWROB5eLQFLTUX2jRGLhW9hjo2CC2fQVlskidCIzjCoctwsDvauBp2a/lR31jkSleczSo8Q==",
+ "dev": true,
+ "dependencies": {
+ "array-back": "^4.0.0",
+ "lodash.omit": "^4.5.0",
+ "lodash.pick": "^4.4.0",
+ "reduce-extract": "^1.0.0",
+ "sort-array": "^2.0.0",
+ "test-value": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jsdoc-to-markdown": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/jsdoc-to-markdown/-/jsdoc-to-markdown-5.0.3.tgz",
+ "integrity": "sha512-tQv5tBV0fTYidRQtE60lJKxE98mmuLcYuITFDKQiDPE9hGccpeEGUNFcVkInq1vigyuPnZmt79bQ8wv2GKjY0Q==",
+ "dev": true,
+ "dependencies": {
+ "array-back": "^4.0.1",
+ "command-line-tool": "^0.8.0",
+ "config-master": "^3.1.0",
+ "dmd": "^4.0.5",
+ "jsdoc-api": "^5.0.4",
+ "jsdoc-parse": "^4.0.1",
+ "walk-back": "^4.0.0"
+ },
+ "bin": {
+ "jsdoc2md": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/jsdoc/node_modules/marked": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.5.tgz",
+ "integrity": "sha512-yfCEUXmKhBPLOzEC7c+tc4XZdIeTdGoRCZakFMkCxodr7wDXqoapIME4wjcpBPJLNyUnKJ3e8rb8wlAgnLnaDw==",
+ "dev": true,
+ "bin": {
+ "marked": "bin/marked"
+ },
+ "engines": {
+ "node": ">= 8.16.2"
+ }
+ },
+ "node_modules/klaw": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz",
+ "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.9"
+ }
+ },
+ "node_modules/linkify-it": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
+ "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
+ "dev": true,
+ "dependencies": {
+ "uc.micro": "^1.0.1"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true
+ },
+ "node_modules/lodash.camelcase": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
+ "dev": true
+ },
+ "node_modules/lodash.omit": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
+ "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=",
+ "dev": true
+ },
+ "node_modules/lodash.padend": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz",
+ "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=",
+ "dev": true
+ },
+ "node_modules/lodash.pick": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz",
+ "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=",
+ "dev": true
+ },
+ "node_modules/markdown-it": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz",
+ "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^1.0.7",
+ "entities": "~2.0.0",
+ "linkify-it": "^2.0.0",
+ "mdurl": "^1.0.1",
+ "uc.micro": "^1.0.5"
+ },
+ "bin": {
+ "markdown-it": "bin/markdown-it.js"
+ }
+ },
+ "node_modules/markdown-it-anchor": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz",
+ "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==",
+ "dev": true,
+ "peerDependencies": {
+ "markdown-it": "*"
+ }
+ },
+ "node_modules/marked": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz",
+ "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==",
+ "dev": true,
+ "bin": {
+ "marked": "bin/marked"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/mdurl": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+ "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
+ "dev": true
+ },
+ "node_modules/minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "dev": true
+ },
+ "node_modules/mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "dev": true,
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/mkdirp2": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp2/-/mkdirp2-1.0.4.tgz",
+ "integrity": "sha512-Q2PKB4ZR4UPtjLl76JfzlgSCUZhSV1AXQgAZa1qt5RiaALFjP/CDrGvFBrOz7Ck6McPcwMAxTsJvWOUjOU8XMw==",
+ "dev": true
+ },
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true
+ },
+ "node_modules/object-get": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/object-get/-/object-get-2.1.1.tgz",
+ "integrity": "sha512-7n4IpLMzGGcLEMiQKsNR7vCe+N5E9LORFrtNUVy4sO3dj9a3HedZCxEL2T7QuLhcHN1NBuBsMOKaOsAYI9IIvg==",
+ "dev": true
+ },
+ "node_modules/object-to-spawn-args": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-to-spawn-args/-/object-to-spawn-args-1.1.1.tgz",
+ "integrity": "sha1-d9qIJ/Bz0BHJ4bFz+JV4FHAkZ4U=",
+ "dev": true
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/reduce-extract": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/reduce-extract/-/reduce-extract-1.0.0.tgz",
+ "integrity": "sha1-Z/I4W+2mUGG19fQxJmLosIDKFSU=",
+ "dev": true,
+ "dependencies": {
+ "test-value": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/reduce-extract/node_modules/array-back": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+ "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+ "dev": true,
+ "dependencies": {
+ "typical": "^2.6.0"
+ },
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/reduce-extract/node_modules/test-value": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/test-value/-/test-value-1.1.0.tgz",
+ "integrity": "sha1-oJE29y7AQ9J8iTcHwrFZv6196T8=",
+ "dev": true,
+ "dependencies": {
+ "array-back": "^1.0.2",
+ "typical": "^2.4.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/reduce-flatten": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-3.0.1.tgz",
+ "integrity": "sha512-bYo+97BmUUOzg09XwfkwALt4PQH1M5L0wzKerBt6WLm3Fhdd43mMS89HiT1B9pJIqko/6lWx3OnV4J9f2Kqp5Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/reduce-unique": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/reduce-unique/-/reduce-unique-2.0.1.tgz",
+ "integrity": "sha512-x4jH/8L1eyZGR785WY+ePtyMNhycl1N2XOLxhCbzZFaqF4AXjLzqSxa2UHgJ2ZVR/HHyPOvl1L7xRnW8ye5MdA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/reduce-without": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/reduce-without/-/reduce-without-1.0.1.tgz",
+ "integrity": "sha1-aK0OrRGFXJo31OglbBW7+Hly/Iw=",
+ "dev": true,
+ "dependencies": {
+ "test-value": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/reduce-without/node_modules/array-back": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+ "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+ "dev": true,
+ "dependencies": {
+ "typical": "^2.6.0"
+ },
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/reduce-without/node_modules/test-value": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz",
+ "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=",
+ "dev": true,
+ "dependencies": {
+ "array-back": "^1.0.3",
+ "typical": "^2.6.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/requizzle": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz",
+ "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==",
+ "dev": true,
+ "dependencies": {
+ "lodash": "^4.17.14"
+ }
+ },
+ "node_modules/sort-array": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-2.0.0.tgz",
+ "integrity": "sha1-OKnG2if9fRR7QuYFVPKBGHtN9HI=",
+ "dev": true,
+ "dependencies": {
+ "array-back": "^1.0.4",
+ "object-get": "^2.1.0",
+ "typical": "^2.6.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/sort-array/node_modules/array-back": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+ "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+ "dev": true,
+ "dependencies": {
+ "typical": "^2.6.0"
+ },
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "node_modules/stream-connect": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/stream-connect/-/stream-connect-1.0.2.tgz",
+ "integrity": "sha1-GLyB8u2zW4tdmoAJIAqYUxRCipc=",
+ "dev": true,
+ "dependencies": {
+ "array-back": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/stream-connect/node_modules/array-back": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+ "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+ "dev": true,
+ "dependencies": {
+ "typical": "^2.6.0"
+ },
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/stream-via": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/stream-via/-/stream-via-1.0.4.tgz",
+ "integrity": "sha512-DBp0lSvX5G9KGRDTkR/R+a29H+Wk2xItOF+MpZLLNDWbEV9tGPnqLPxHEYjmiz8xGtJHRIqmI+hCjmNzqoA4nQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/table-layout": {
+ "version": "0.4.5",
+ "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz",
+ "integrity": "sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==",
+ "dev": true,
+ "dependencies": {
+ "array-back": "^2.0.0",
+ "deep-extend": "~0.6.0",
+ "lodash.padend": "^4.6.1",
+ "typical": "^2.6.1",
+ "wordwrapjs": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/table-layout/node_modules/array-back": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
+ "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
+ "dev": true,
+ "dependencies": {
+ "typical": "^2.6.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/taffydb": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz",
+ "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=",
+ "dev": true
+ },
+ "node_modules/temp-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/temp-path/-/temp-path-1.0.0.tgz",
+ "integrity": "sha1-JLFUOXOrRCiW2a02fdnL2/r+kYs=",
+ "dev": true
+ },
+ "node_modules/test-value": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/test-value/-/test-value-3.0.0.tgz",
+ "integrity": "sha512-sVACdAWcZkSU9x7AOmJo5TqE+GyNJknHaHsMrR6ZnhjVlVN9Yx6FjHrsKZ3BjIpPCT68zYesPWkakrNupwfOTQ==",
+ "dev": true,
+ "dependencies": {
+ "array-back": "^2.0.0",
+ "typical": "^2.6.1"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/test-value/node_modules/array-back": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
+ "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
+ "dev": true,
+ "dependencies": {
+ "typical": "^2.6.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/typical": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
+ "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=",
+ "dev": true
+ },
+ "node_modules/uc.micro": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
+ "dev": true
+ },
+ "node_modules/uglify-es": {
+ "version": "3.3.9",
+ "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz",
+ "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==",
+ "deprecated": "support for ECMAScript is superseded by `uglify-js` as of v3.13.0",
+ "dev": true,
+ "dependencies": {
+ "commander": "~2.13.0",
+ "source-map": "~0.6.1"
+ },
+ "bin": {
+ "uglifyjs": "bin/uglifyjs"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/uglify-es/node_modules/commander": {
+ "version": "2.13.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz",
+ "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==",
+ "dev": true
+ },
+ "node_modules/uglify-js": {
+ "version": "3.13.7",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.7.tgz",
+ "integrity": "sha512-1Psi2MmnZJbnEsgJJIlfnd7tFlJfitusmR7zDI8lXlFI0ACD4/Rm/xdrU8bh6zF0i74aiVoBtkRiFulkrmh3AA==",
+ "dev": true,
+ "optional": true,
+ "bin": {
+ "uglifyjs": "bin/uglifyjs"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/underscore": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz",
+ "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==",
+ "dev": true
+ },
+ "node_modules/walk-back": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-4.0.0.tgz",
+ "integrity": "sha512-kudCA8PXVQfrqv2mFTG72vDBRi8BKWxGgFLwPpzHcpZnSwZk93WMwUDVcLHWNsnm+Y0AC4Vb6MUNRgaHfyV2DQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+ "dev": true
+ },
+ "node_modules/wordwrapjs": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz",
+ "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==",
+ "dev": true,
+ "dependencies": {
+ "reduce-flatten": "^1.0.1",
+ "typical": "^2.6.1"
+ },
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/wordwrapjs/node_modules/reduce-flatten": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz",
+ "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "node_modules/xmlcreate": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz",
+ "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==",
+ "dev": true
+ }
+ },
+ "dependencies": {
+ "@babel/parser": {
+ "version": "7.14.3",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.3.tgz",
+ "integrity": "sha512-7MpZDIfI7sUC5zWo2+foJ50CSI5lcqDehZ0lVgIhSi4bFEk94fLAKlF3Q0nzSQQ+ca0lm+O6G9ztKVBeu8PMRQ==",
+ "dev": true
+ },
+ "ansi-escape-sequences": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-escape-sequences/-/ansi-escape-sequences-4.1.0.tgz",
+ "integrity": "sha512-dzW9kHxH011uBsidTXd14JXgzye/YLb2LzeKZ4bsgl/Knwx8AtbSFkkGxagdNOoh0DlqHCmfiEjWKBaqjOanVw==",
+ "dev": true,
+ "requires": {
+ "array-back": "^3.0.1"
+ },
+ "dependencies": {
+ "array-back": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
+ "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
+ "dev": true
+ }
+ }
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "array-back": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.2.tgz",
+ "integrity": "sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true
+ },
+ "bluebird": {
+ "version": "3.7.2",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
+ "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
+ "dev": true
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "cache-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/cache-point/-/cache-point-1.0.0.tgz",
+ "integrity": "sha512-ZqrZp9Hi5Uq7vfSGmNP2bUT/9DzZC2Y/GXjHB8rUJN1a+KLmbV05+vxHipNsg8+CSVgjcVVzLV8VZms6w8ZeRw==",
+ "dev": true,
+ "requires": {
+ "array-back": "^4.0.0",
+ "fs-then-native": "^2.0.0",
+ "mkdirp2": "^1.0.4"
+ }
+ },
+ "catharsis": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz",
+ "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.15"
+ }
+ },
+ "collect-all": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/collect-all/-/collect-all-1.0.4.tgz",
+ "integrity": "sha512-RKZhRwJtJEP5FWul+gkSMEnaK6H3AGPTTWOiRimCcs+rc/OmQE3Yhy1Q7A7KsdkG3ZXVdZq68Y6ONSdvkeEcKA==",
+ "dev": true,
+ "requires": {
+ "stream-connect": "^1.0.2",
+ "stream-via": "^1.0.4"
+ }
+ },
+ "command-line-args": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/command-line-args/-/command-line-args-5.1.1.tgz",
+ "integrity": "sha512-hL/eG8lrll1Qy1ezvkant+trihbGnaKaeEjj6Scyr3DN+RC7iQ5Rz84IeLERfAWDGo0HBSNAakczwgCilDXnWg==",
+ "dev": true,
+ "requires": {
+ "array-back": "^3.0.1",
+ "find-replace": "^3.0.0",
+ "lodash.camelcase": "^4.3.0",
+ "typical": "^4.0.0"
+ },
+ "dependencies": {
+ "array-back": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
+ "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
+ "dev": true
+ },
+ "typical": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/typical/-/typical-4.0.0.tgz",
+ "integrity": "sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==",
+ "dev": true
+ }
+ }
+ },
+ "command-line-tool": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/command-line-tool/-/command-line-tool-0.8.0.tgz",
+ "integrity": "sha512-Xw18HVx/QzQV3Sc5k1vy3kgtOeGmsKIqwtFFoyjI4bbcpSgnw2CWVULvtakyw4s6fhyAdI6soQQhXc2OzJy62g==",
+ "dev": true,
+ "requires": {
+ "ansi-escape-sequences": "^4.0.0",
+ "array-back": "^2.0.0",
+ "command-line-args": "^5.0.0",
+ "command-line-usage": "^4.1.0",
+ "typical": "^2.6.1"
+ },
+ "dependencies": {
+ "array-back": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
+ "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
+ "dev": true,
+ "requires": {
+ "typical": "^2.6.1"
+ }
+ }
+ }
+ },
+ "command-line-usage": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-4.1.0.tgz",
+ "integrity": "sha512-MxS8Ad995KpdAC0Jopo/ovGIroV/m0KHwzKfXxKag6FHOkGsH8/lv5yjgablcRxCJJC0oJeUMuO/gmaq+Wq46g==",
+ "dev": true,
+ "requires": {
+ "ansi-escape-sequences": "^4.0.0",
+ "array-back": "^2.0.0",
+ "table-layout": "^0.4.2",
+ "typical": "^2.6.1"
+ },
+ "dependencies": {
+ "array-back": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
+ "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
+ "dev": true,
+ "requires": {
+ "typical": "^2.6.1"
+ }
+ }
+ }
+ },
+ "commander": {
+ "version": "2.20.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
+ "dev": true
+ },
+ "common-sequence": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/common-sequence/-/common-sequence-2.0.2.tgz",
+ "integrity": "sha512-jAg09gkdkrDO9EWTdXfv80WWH3yeZl5oT69fGfedBNS9pXUKYInVJ1bJ+/ht2+Moeei48TmSbQDYMc8EOx9G0g==",
+ "dev": true
+ },
+ "concat": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/concat/-/concat-1.0.3.tgz",
+ "integrity": "sha1-QPM1MInWVGdpXLGIa0Xt1jfYzKg=",
+ "dev": true,
+ "requires": {
+ "commander": "^2.9.0"
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "config-master": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/config-master/-/config-master-3.1.0.tgz",
+ "integrity": "sha1-ZnZjWQUFooO/JqSE1oSJ10xUhdo=",
+ "dev": true,
+ "requires": {
+ "walk-back": "^2.0.1"
+ },
+ "dependencies": {
+ "walk-back": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-2.0.1.tgz",
+ "integrity": "sha1-VU4qnYdPrEeoywBr9EwvDEmYoKQ=",
+ "dev": true
+ }
+ }
+ },
+ "deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "dev": true
+ },
+ "dmd": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/dmd/-/dmd-4.0.6.tgz",
+ "integrity": "sha512-7ZYAnFQ6jGm4SICArwqNPylJ83PaOdPTAkds3Z/s1ueFqSc5ilJ2F0b7uP+35W1PUbemH++gn5/VlC3KwEgiHQ==",
+ "dev": true,
+ "requires": {
+ "array-back": "^4.0.1",
+ "cache-point": "^1.0.0",
+ "common-sequence": "^2.0.0",
+ "file-set": "^3.0.0",
+ "handlebars": "^4.5.3",
+ "marked": "^0.7.0",
+ "object-get": "^2.1.0",
+ "reduce-flatten": "^3.0.0",
+ "reduce-unique": "^2.0.1",
+ "reduce-without": "^1.0.1",
+ "test-value": "^3.0.0",
+ "walk-back": "^4.0.0"
+ }
+ },
+ "entities": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz",
+ "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==",
+ "dev": true
+ },
+ "escape-string-regexp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
+ "dev": true
+ },
+ "file-set": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/file-set/-/file-set-3.0.0.tgz",
+ "integrity": "sha512-B/SdeSIeRv7VlOgIjtH3dkxMI+tEy5m+OeCXfAUsirBoVoY+bGtsmvmmTFPm/G23TBY4RiTtjpcgePCfwXRjqA==",
+ "dev": true,
+ "requires": {
+ "array-back": "^4.0.0",
+ "glob": "^7.1.5"
+ }
+ },
+ "find-replace": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-replace/-/find-replace-3.0.0.tgz",
+ "integrity": "sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==",
+ "dev": true,
+ "requires": {
+ "array-back": "^3.0.1"
+ },
+ "dependencies": {
+ "array-back": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-3.1.0.tgz",
+ "integrity": "sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==",
+ "dev": true
+ }
+ }
+ },
+ "fs-then-native": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fs-then-native/-/fs-then-native-2.0.0.tgz",
+ "integrity": "sha1-GaEk2U2QwiyOBF8ujdbr6jbUjGc=",
+ "dev": true
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "glob": {
+ "version": "7.1.7",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
+ "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.6",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz",
+ "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==",
+ "dev": true
+ },
+ "handlebars": {
+ "version": "4.7.7",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
+ "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.5",
+ "neo-async": "^2.6.0",
+ "source-map": "^0.6.1",
+ "uglify-js": "^3.1.4",
+ "wordwrap": "^1.0.0"
+ }
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "js2xmlparser": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.1.tgz",
+ "integrity": "sha512-KrPTolcw6RocpYjdC7pL7v62e55q7qOMHvLX1UCLc5AAS8qeJ6nukarEJAF2KL2PZxlbGueEbINqZR2bDe/gUw==",
+ "dev": true,
+ "requires": {
+ "xmlcreate": "^2.0.3"
+ }
+ },
+ "jsdoc": {
+ "version": "3.6.7",
+ "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-3.6.7.tgz",
+ "integrity": "sha512-sxKt7h0vzCd+3Y81Ey2qinupL6DpRSZJclS04ugHDNmRUXGzqicMJ6iwayhSA0S0DwwX30c5ozyUthr1QKF6uw==",
+ "dev": true,
+ "requires": {
+ "@babel/parser": "^7.9.4",
+ "bluebird": "^3.7.2",
+ "catharsis": "^0.9.0",
+ "escape-string-regexp": "^2.0.0",
+ "js2xmlparser": "^4.0.1",
+ "klaw": "^3.0.0",
+ "markdown-it": "^10.0.0",
+ "markdown-it-anchor": "^5.2.7",
+ "marked": "^2.0.3",
+ "mkdirp": "^1.0.4",
+ "requizzle": "^0.2.3",
+ "strip-json-comments": "^3.1.0",
+ "taffydb": "2.6.2",
+ "underscore": "~1.13.1"
+ },
+ "dependencies": {
+ "marked": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-2.0.5.tgz",
+ "integrity": "sha512-yfCEUXmKhBPLOzEC7c+tc4XZdIeTdGoRCZakFMkCxodr7wDXqoapIME4wjcpBPJLNyUnKJ3e8rb8wlAgnLnaDw==",
+ "dev": true
+ }
+ }
+ },
+ "jsdoc-api": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/jsdoc-api/-/jsdoc-api-5.0.4.tgz",
+ "integrity": "sha512-1KMwLnfo0FyhF06TQKzqIm8BiY1yoMIGICxRdJHUjzskaHMzHMmpLlmNFgzoa4pAC8t1CDPK5jWuQTvv1pBsEQ==",
+ "dev": true,
+ "requires": {
+ "array-back": "^4.0.0",
+ "cache-point": "^1.0.0",
+ "collect-all": "^1.0.3",
+ "file-set": "^2.0.1",
+ "fs-then-native": "^2.0.0",
+ "jsdoc": "^3.6.3",
+ "object-to-spawn-args": "^1.1.1",
+ "temp-path": "^1.0.0",
+ "walk-back": "^3.0.1"
+ },
+ "dependencies": {
+ "file-set": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/file-set/-/file-set-2.0.1.tgz",
+ "integrity": "sha512-XgOUUpgR6FbbfYcniLw0qm1Am7PnNYIAkd+eXxRt42LiYhjaso0WiuQ+VmrNdtwotyM+cLCfZ56AZrySP3QnKA==",
+ "dev": true,
+ "requires": {
+ "array-back": "^2.0.0",
+ "glob": "^7.1.3"
+ },
+ "dependencies": {
+ "array-back": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
+ "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
+ "dev": true,
+ "requires": {
+ "typical": "^2.6.1"
+ }
+ }
+ }
+ },
+ "walk-back": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-3.0.1.tgz",
+ "integrity": "sha512-umiNB2qLO731Sxbp6cfZ9pwURJzTnftxE4Gc7hq8n/ehkuXC//s9F65IEIJA2ZytQZ1ZOsm/Fju4IWx0bivkUQ==",
+ "dev": true
+ }
+ }
+ },
+ "jsdoc-parse": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/jsdoc-parse/-/jsdoc-parse-4.0.1.tgz",
+ "integrity": "sha512-qIObw8yqYZjrP2qxWROB5eLQFLTUX2jRGLhW9hjo2CC2fQVlskidCIzjCoctwsDvauBp2a/lR31jkSleczSo8Q==",
+ "dev": true,
+ "requires": {
+ "array-back": "^4.0.0",
+ "lodash.omit": "^4.5.0",
+ "lodash.pick": "^4.4.0",
+ "reduce-extract": "^1.0.0",
+ "sort-array": "^2.0.0",
+ "test-value": "^3.0.0"
+ }
+ },
+ "jsdoc-to-markdown": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/jsdoc-to-markdown/-/jsdoc-to-markdown-5.0.3.tgz",
+ "integrity": "sha512-tQv5tBV0fTYidRQtE60lJKxE98mmuLcYuITFDKQiDPE9hGccpeEGUNFcVkInq1vigyuPnZmt79bQ8wv2GKjY0Q==",
+ "dev": true,
+ "requires": {
+ "array-back": "^4.0.1",
+ "command-line-tool": "^0.8.0",
+ "config-master": "^3.1.0",
+ "dmd": "^4.0.5",
+ "jsdoc-api": "^5.0.4",
+ "jsdoc-parse": "^4.0.1",
+ "walk-back": "^4.0.0"
+ }
+ },
+ "klaw": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz",
+ "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.9"
+ }
+ },
+ "linkify-it": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
+ "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
+ "dev": true,
+ "requires": {
+ "uc.micro": "^1.0.1"
+ }
+ },
+ "lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true
+ },
+ "lodash.camelcase": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
+ "dev": true
+ },
+ "lodash.omit": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
+ "integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA=",
+ "dev": true
+ },
+ "lodash.padend": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/lodash.padend/-/lodash.padend-4.6.1.tgz",
+ "integrity": "sha1-U8y6BH0G4VjTEfRdpiX05J5vFm4=",
+ "dev": true
+ },
+ "lodash.pick": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz",
+ "integrity": "sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM=",
+ "dev": true
+ },
+ "markdown-it": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz",
+ "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "entities": "~2.0.0",
+ "linkify-it": "^2.0.0",
+ "mdurl": "^1.0.1",
+ "uc.micro": "^1.0.5"
+ }
+ },
+ "markdown-it-anchor": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-5.3.0.tgz",
+ "integrity": "sha512-/V1MnLL/rgJ3jkMWo84UR+K+jF1cxNG1a+KwqeXqTIJ+jtA8aWSHuigx8lTzauiIjBDbwF3NcWQMotd0Dm39jA==",
+ "dev": true,
+ "requires": {}
+ },
+ "marked": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-0.7.0.tgz",
+ "integrity": "sha512-c+yYdCZJQrsRjTPhUx7VKkApw9bwDkNbHUKo1ovgcfDjb2kc8rLuRbIFyXL5WOEUwzSSKo3IXpph2K6DqB/KZg==",
+ "dev": true
+ },
+ "mdurl": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+ "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "dev": true
+ },
+ "mkdirp": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
+ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==",
+ "dev": true
+ },
+ "mkdirp2": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/mkdirp2/-/mkdirp2-1.0.4.tgz",
+ "integrity": "sha512-Q2PKB4ZR4UPtjLl76JfzlgSCUZhSV1AXQgAZa1qt5RiaALFjP/CDrGvFBrOz7Ck6McPcwMAxTsJvWOUjOU8XMw==",
+ "dev": true
+ },
+ "neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true
+ },
+ "object-get": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/object-get/-/object-get-2.1.1.tgz",
+ "integrity": "sha512-7n4IpLMzGGcLEMiQKsNR7vCe+N5E9LORFrtNUVy4sO3dj9a3HedZCxEL2T7QuLhcHN1NBuBsMOKaOsAYI9IIvg==",
+ "dev": true
+ },
+ "object-to-spawn-args": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/object-to-spawn-args/-/object-to-spawn-args-1.1.1.tgz",
+ "integrity": "sha1-d9qIJ/Bz0BHJ4bFz+JV4FHAkZ4U=",
+ "dev": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "reduce-extract": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/reduce-extract/-/reduce-extract-1.0.0.tgz",
+ "integrity": "sha1-Z/I4W+2mUGG19fQxJmLosIDKFSU=",
+ "dev": true,
+ "requires": {
+ "test-value": "^1.0.1"
+ },
+ "dependencies": {
+ "array-back": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+ "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+ "dev": true,
+ "requires": {
+ "typical": "^2.6.0"
+ }
+ },
+ "test-value": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/test-value/-/test-value-1.1.0.tgz",
+ "integrity": "sha1-oJE29y7AQ9J8iTcHwrFZv6196T8=",
+ "dev": true,
+ "requires": {
+ "array-back": "^1.0.2",
+ "typical": "^2.4.2"
+ }
+ }
+ }
+ },
+ "reduce-flatten": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-3.0.1.tgz",
+ "integrity": "sha512-bYo+97BmUUOzg09XwfkwALt4PQH1M5L0wzKerBt6WLm3Fhdd43mMS89HiT1B9pJIqko/6lWx3OnV4J9f2Kqp5Q==",
+ "dev": true
+ },
+ "reduce-unique": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/reduce-unique/-/reduce-unique-2.0.1.tgz",
+ "integrity": "sha512-x4jH/8L1eyZGR785WY+ePtyMNhycl1N2XOLxhCbzZFaqF4AXjLzqSxa2UHgJ2ZVR/HHyPOvl1L7xRnW8ye5MdA==",
+ "dev": true
+ },
+ "reduce-without": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/reduce-without/-/reduce-without-1.0.1.tgz",
+ "integrity": "sha1-aK0OrRGFXJo31OglbBW7+Hly/Iw=",
+ "dev": true,
+ "requires": {
+ "test-value": "^2.0.0"
+ },
+ "dependencies": {
+ "array-back": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+ "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+ "dev": true,
+ "requires": {
+ "typical": "^2.6.0"
+ }
+ },
+ "test-value": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz",
+ "integrity": "sha1-Edpv9nDzRxpztiXKTz/c97t0gpE=",
+ "dev": true,
+ "requires": {
+ "array-back": "^1.0.3",
+ "typical": "^2.6.0"
+ }
+ }
+ }
+ },
+ "requizzle": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.3.tgz",
+ "integrity": "sha512-YanoyJjykPxGHii0fZP0uUPEXpvqfBDxWV7s6GKAiiOsiqhX6vHNyW3Qzdmqp/iq/ExbhaGbVrjB4ruEVSM4GQ==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.14"
+ }
+ },
+ "sort-array": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/sort-array/-/sort-array-2.0.0.tgz",
+ "integrity": "sha1-OKnG2if9fRR7QuYFVPKBGHtN9HI=",
+ "dev": true,
+ "requires": {
+ "array-back": "^1.0.4",
+ "object-get": "^2.1.0",
+ "typical": "^2.6.0"
+ },
+ "dependencies": {
+ "array-back": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+ "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+ "dev": true,
+ "requires": {
+ "typical": "^2.6.0"
+ }
+ }
+ }
+ },
+ "source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "stream-connect": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/stream-connect/-/stream-connect-1.0.2.tgz",
+ "integrity": "sha1-GLyB8u2zW4tdmoAJIAqYUxRCipc=",
+ "dev": true,
+ "requires": {
+ "array-back": "^1.0.2"
+ },
+ "dependencies": {
+ "array-back": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-1.0.4.tgz",
+ "integrity": "sha1-ZEun8JX3/898Q7Xw3DnTwfA8Bjs=",
+ "dev": true,
+ "requires": {
+ "typical": "^2.6.0"
+ }
+ }
+ }
+ },
+ "stream-via": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/stream-via/-/stream-via-1.0.4.tgz",
+ "integrity": "sha512-DBp0lSvX5G9KGRDTkR/R+a29H+Wk2xItOF+MpZLLNDWbEV9tGPnqLPxHEYjmiz8xGtJHRIqmI+hCjmNzqoA4nQ==",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true
+ },
+ "table-layout": {
+ "version": "0.4.5",
+ "resolved": "https://registry.npmjs.org/table-layout/-/table-layout-0.4.5.tgz",
+ "integrity": "sha512-zTvf0mcggrGeTe/2jJ6ECkJHAQPIYEwDoqsiqBjI24mvRmQbInK5jq33fyypaCBxX08hMkfmdOqj6haT33EqWw==",
+ "dev": true,
+ "requires": {
+ "array-back": "^2.0.0",
+ "deep-extend": "~0.6.0",
+ "lodash.padend": "^4.6.1",
+ "typical": "^2.6.1",
+ "wordwrapjs": "^3.0.0"
+ },
+ "dependencies": {
+ "array-back": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
+ "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
+ "dev": true,
+ "requires": {
+ "typical": "^2.6.1"
+ }
+ }
+ }
+ },
+ "taffydb": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/taffydb/-/taffydb-2.6.2.tgz",
+ "integrity": "sha1-fLy2S1oUG2ou/CxdLGe04VCyomg=",
+ "dev": true
+ },
+ "temp-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/temp-path/-/temp-path-1.0.0.tgz",
+ "integrity": "sha1-JLFUOXOrRCiW2a02fdnL2/r+kYs=",
+ "dev": true
+ },
+ "test-value": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/test-value/-/test-value-3.0.0.tgz",
+ "integrity": "sha512-sVACdAWcZkSU9x7AOmJo5TqE+GyNJknHaHsMrR6ZnhjVlVN9Yx6FjHrsKZ3BjIpPCT68zYesPWkakrNupwfOTQ==",
+ "dev": true,
+ "requires": {
+ "array-back": "^2.0.0",
+ "typical": "^2.6.1"
+ },
+ "dependencies": {
+ "array-back": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/array-back/-/array-back-2.0.0.tgz",
+ "integrity": "sha512-eJv4pLLufP3g5kcZry0j6WXpIbzYw9GUB4mVJZno9wfwiBxbizTnHCw3VJb07cBihbFX48Y7oSrW9y+gt4glyw==",
+ "dev": true,
+ "requires": {
+ "typical": "^2.6.1"
+ }
+ }
+ }
+ },
+ "typical": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/typical/-/typical-2.6.1.tgz",
+ "integrity": "sha1-XAgOXWYcu+OCWdLnCjxyU+hziB0=",
+ "dev": true
+ },
+ "uc.micro": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
+ "dev": true
+ },
+ "uglify-es": {
+ "version": "3.3.9",
+ "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz",
+ "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==",
+ "dev": true,
+ "requires": {
+ "commander": "~2.13.0",
+ "source-map": "~0.6.1"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.13.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz",
+ "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==",
+ "dev": true
+ }
+ }
+ },
+ "uglify-js": {
+ "version": "3.13.7",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.13.7.tgz",
+ "integrity": "sha512-1Psi2MmnZJbnEsgJJIlfnd7tFlJfitusmR7zDI8lXlFI0ACD4/Rm/xdrU8bh6zF0i74aiVoBtkRiFulkrmh3AA==",
+ "dev": true,
+ "optional": true
+ },
+ "underscore": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz",
+ "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==",
+ "dev": true
+ },
+ "walk-back": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/walk-back/-/walk-back-4.0.0.tgz",
+ "integrity": "sha512-kudCA8PXVQfrqv2mFTG72vDBRi8BKWxGgFLwPpzHcpZnSwZk93WMwUDVcLHWNsnm+Y0AC4Vb6MUNRgaHfyV2DQ==",
+ "dev": true
+ },
+ "wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+ "dev": true
+ },
+ "wordwrapjs": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-3.0.0.tgz",
+ "integrity": "sha512-mO8XtqyPvykVCsrwj5MlOVWvSnCdT+C+QVbm6blradR7JExAhbkZ7hZ9A+9NUtwzSqrlUo9a67ws0EiILrvRpw==",
+ "dev": true,
+ "requires": {
+ "reduce-flatten": "^1.0.1",
+ "typical": "^2.6.1"
+ },
+ "dependencies": {
+ "reduce-flatten": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-1.0.1.tgz",
+ "integrity": "sha1-JYx479FT3fk8tWEjf2EYTzaW4yc=",
+ "dev": true
+ }
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "xmlcreate": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.3.tgz",
+ "integrity": "sha512-HgS+X6zAztGa9zIK3Y3LXuJes33Lz9x+YyTxgrkIdabu2vqcGOWwdfCpf1hWLRrd553wd4QCDf6BBO6FfdsRiQ==",
+ "dev": true
+ }
+ }
+}
diff --git a/package.json b/package.json
index ebf7aee..1cf1bea 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "g2d",
- "version": "3.0.1",
+ "version": "3.1.0",
"description": "g2 - a tiny 2d graphics command library",
"keywords": [
"vector",
@@ -12,7 +12,6 @@
"javascript"
],
"main": "g2.js",
- "microjam": {},
"scripts": {
"build": "npm run minify && npm run jsdoc && npm run 7z",
"minify": "uglifyjs ./src/g2.core.js ./src/g2.hdl.canvas.js ./src/g2.lib.js ./src/g2.ext.js ./src/g2.mec.js ./src/g2.chart.js -o ./dist/g2.js --comments",
diff --git a/sample/g2styleref.html b/sample/g2styleref.html
new file mode 100644
index 0000000..dff4215
--- /dev/null
+++ b/sample/g2styleref.html
@@ -0,0 +1,25 @@
+
+
+duck
+
+
+
+
+
+
+
+
+
diff --git a/src/g2.chart.element.js b/src/g2.chart.element.js
index 18a0bc5..6df8f3f 100644
--- a/src/g2.chart.element.js
+++ b/src/g2.chart.element.js
@@ -10,6 +10,12 @@ class G2ChartElement extends HTMLElement {
'ymin',
'ymax',
'title',
+ 'xlabels',
+ 'ylabels',
+ 'xticks',
+ 'yticks',
+ 'xtitle',
+ 'ytitle'
];
}
@@ -32,33 +38,52 @@ class G2ChartElement extends HTMLElement {
set ymax(q) { return q && +this.setAttribute('ymax', q) }
get title() { return this.getAttribute('title') || ''; }
set title(q) { return q && this.setAttribute('title', q) }
+ get xlabels() { return this.getAttribute('xlabels') !== 'false'; }
+ get ylabels() { return this.getAttribute('ylabels') !== 'false'; }
+ get xticks() { return this.getAttribute('xticks') !== 'false'; }
+ get yticks() { return this.getAttribute('yticks') !== 'false'; }
+ get xtitle() { return this.getAttribute('xtitle'); }
+ get ytitle() { return this.getAttribute('ytitle'); }
connectedCallback() {
this._root.innerHTML = G2ChartElement.template({
width: this.width, height: this.height
});
- this._ctx = this._root.getElementById('cnv').getContext('2d');
+ const xmargin = (this.yticks && 5) + (this.ylabels && 15) + (this.ytitle && 15);
+ const ymargin = (this.xticks && 5) + (this.xlabels && 15) + (this.xtitle && 15);
- const t = 35;
this._chart = {
- x: t,
- y: t,
+ x: xmargin,
+ y: ymargin,
xmin: this.xmin,
xmax: this.xmax,
ymin: this.ymin,
ymax: this.ymax,
title: this.title,
- b: this.width - t * 2,
- h: this.height - t * 2,
- xaxis: () => this.xaxis || {},
- yaxis: () => this.yaxis || {},
+ b: this.width - 5 - xmargin,
+ h: this.height - 5 - ymargin - (this.title && 15),
+ xaxis: () => this.xaxis || { ticks: this.xticks, labels: this.xlabels, title: this.xtitle },
+ yaxis: () => this.yaxis || { ticks: this.yticks, labels: this.ylabels, title: this.ytitle },
title: () => this.title || "",
- funcs: () => this.funcs
+ funcs: []
};
- this._g = g2().del().clr().view({ cartesian: true }).chart(this._chart);
+ if (this.innerHTML) {
+ let res;
+
+ try { res = JSON.parse(this.innerHTML); }
+ catch (e) {
+ console.error(e);
+ this._g.txt({ str: e, y: 5 });
+ }
+ this._chart.funcs.push(...G2ChartElement.validateFunc(res));
+ }
+
+ this._ctx = this._root.getElementById('cnv').getContext('2d');
+ this._g = g2().del().clr().view({ cartesian: true }).chart(this._chart);
+/*
try {
// If not true, the element should be referenced by another module.
if (this.innerHTML !== '') {
@@ -88,24 +113,41 @@ class G2ChartElement extends HTMLElement {
});
this.render();
}
+*/
+ this.render();
}
render() {
this._g.exe(this._ctx);
}
-
+/*
setFuncs(funcs) {
this.funcs = funcs;
return this;
}
-
+*/
disconnectedCallback() {
// TODO
}
+ static validateFunc(obj, funcs) {
+ funcs = funcs || [];
+ if (Array.isArray(obj)) // array of functions ...
+ for (const o of obj)
+ G2ChartElement.validateFunc(o, funcs);
+ else if (typeof obj === 'object') { // single function ...
+ if ('fn' in obj) {
+ const fnc = Function('"use strict";return (' + obj['fn'] + ')')();
+ obj.fn = typeof fnc === 'function' ? fnc : undefined; // todo: error message ...
+ }
+ if ('fn' in obj || 'data' in obj)
+ funcs.push(obj);
+ }
+ return funcs;
+ }
+
static template({ width, height }) {
- return ``
+ return ``
}
}
customElements.define('g2-chart', G2ChartElement);
diff --git a/src/g2.chart.js b/src/g2.chart.js
index ecba22b..63689ab 100644
--- a/src/g2.chart.js
+++ b/src/g2.chart.js
@@ -69,10 +69,10 @@ g2.prototype.chart.prototype = {
];
funcs.forEach(f => this.initFunc(f, ...tmp));
}
- // if (this.xaxis)
- this.xAxis = this.autoAxis(this.get('xmin'), this.get('xmax'), 0, this.b);
- // if (this.yaxis)
- this.yAxis = this.autoAxis(this.get('ymin'), this.get('ymax'), 0, this.h);
+ if (this.xaxis)
+ this.xAxis = this.autoAxis(this.get('xmin'), this.get('xmax'), 0, this.b);
+ if (this.yaxis)
+ this.yAxis = this.autoAxis(this.get('ymin'), this.get('ymax'), 0, this.h);
// draw background & border ...
g.rec({
@@ -152,15 +152,14 @@ g2.prototype.chart.prototype = {
}
},
autoAxis(zmin, zmax, tmin, tmax) {
- let base = 2, exp = 1, eps = Math.sqrt(Number.EPSILON),
+ let base = 1, exp = 1, eps = Math.sqrt(Number.EPSILON),
Dz = zmax - zmin || 1, // value range
Dt = tmax - tmin || 1, // area range
scl = Dz > eps ? Dt / Dz : 1, // scale [usr]->[pix]
dz = base * Math.pow(10, exp), // tick size [usr]
dt = Math.floor(scl * dz), // tick size [pix]
N, // # segments
- dt01, // reminder segment
- i0, j0, jth, t0, res;
+ i0, j0, jth, t0;
while (dt < 14 || dt > 35) {
if (dt < 14) {
@@ -181,8 +180,6 @@ g2.prototype.chart.prototype = {
: Math.floor(zmin / dz) + 1;
let z0 = i0 * dz;
t0 = Math.round(scl * (z0 - zmin));
- // console.log("Dt="+Dt+",N="+(Dt - t0)/ dt)
- // console.log("DT="+Dt+",N="+(Dt - t0)/ dt)
N = Math.floor((Dt - t0) / dt) + 1;
j0 = base % 2 && i0 % 2 ? i0 + 1 : i0;
jth = exp === 0 && N < 11 ? 1 : base === 2 && N > 9 ? 5 : 2;
@@ -226,8 +223,6 @@ g2.prototype.chart.prototype = {
ticklen = showticks ? this.get("xaxis", "ticks", "len") : 0,
showorigin = showaxis && this.get("xaxis", "origin"),
title = this.xaxis && (this.get("xaxis", "title", "text") || this.xaxis.title) || '';
- // console.log(this.xAxis)
- // draw tick/grid lines
g.beg(axisstyle);
for (let i = 0; i < this.xAxis.N; i++) {
tick = this.xAxis.itr(i);
diff --git a/src/g2.core.js b/src/g2.core.js
index e79b5f8..7620b83 100644
--- a/src/g2.core.js
+++ b/src/g2.core.js
@@ -2,7 +2,7 @@
"use strict"
/**
- * g2.core (c) 2013-20 Stefan Goessner
+ * g2.core (c) 2013-21 Stefan Goessner
* @author Stefan Goessner
* @license MIT License
* @link https://github.com/goessner/g2
@@ -538,6 +538,8 @@ g2.prototype = {
// statics
g2.defaultStyle = { fs: 'transparent', ls: '#000', lw: 1, lc: "butt", lj: "miter", ld: [], ml: 10, sh: [0, 0], lsh: false, font: '14px serif', thal: 'start', tval: 'alphabetic' };
+g2.styleRex = /^(fs|ls|lw|lc|lj|ld|ldoff|ml|sh|lsh|font|thal|tval)([-0-9].*)?$/,
+
g2.symbol = {
unknown: g2().cir({ r: 12, fs: 'orange' }).txt({ str: '?', thal: 'center', tval: 'middle', font: 'bold 20pt serif' })
};
diff --git a/src/g2.element.js b/src/g2.element.js
index 4ad0d26..33551a9 100644
--- a/src/g2.element.js
+++ b/src/g2.element.js
@@ -1,5 +1,5 @@
/**
- * g2.element.js (c) 2019-20 Stefan Goessner
+ * g2.element.js (c) 2019-21 Stefan Goessner
* @license MIT License
*/
"use strict";
diff --git a/src/g2.ext.js b/src/g2.ext.js
index 8a0fcad..5213760 100644
--- a/src/g2.ext.js
+++ b/src/g2.ext.js
@@ -2,7 +2,7 @@
"use strict"
/**
- * g2.ext (c) 2015-20 Stefan Goessner
+ * g2.ext (c) 2015-21 Stefan Goessner
* @author Stefan Goessner
* @license MIT License
* @requires g2.core.js
@@ -27,7 +27,7 @@ g2.NONE = 0x0; g2.OVER = 0x1; g2.DRAG = 0x2; g2.EDIT = 0x4;
* @property {object} [symbol.sqr] Predefined symbol: a little square
* @property {string} [symbol.nodcolor=#333] node color.
* @property {string} [symbol.nodfill=#dedede] node fill color.
- * @property {string} [symbol.nodfill2=#aeaeae] alternate node fill color, somewhat darker.
+ * @property {string} [symbol.nodfill2=#aeaeae] alternate node fill color, somewhat darker.
* @property {string} [symbol.linkcolor=#666] link color.
* @property {string} [symbol.linkfill=rgba(225,225,225,0.75)] link fill color, semi-transparent.
* @property {string} [symbol.dimcolor=darkslategray] dimension color.
@@ -100,7 +100,8 @@ g2.labelIfc = {
const font = lbl.font || g2.defaultStyle.font;
const h = parseInt(font); // font height (px assumed !)
const str = this.getLabelString();
- const rx = (str.length || 1) * 0.75 * h / 2, ry = 1.25 * h / 2; // ellipse semi-axes length
+ const rx = (str.length || 1) * 0.65 * h / 2,
+ ry = 1.25 * h / 2; // ellipse semi-axes length
const pos = this.pointAt(lbl.loc || this.lbloc || 'se');
const off = this.getLabelOffset();
const p = {
@@ -321,9 +322,9 @@ g2.prototype.hdl.prototype = g2.mix(g2.prototype.cir.prototype, {
get lsh() { return this.state & g2.OVER; },
get sh() { return this.state & g2.OVER ? [0, 0, 5, "black"] : false },
g2() {
- const { x, y, r, b = 4, shape = 'cir', ls = 'black', fs = '#ccc', sh } = this;
- return shape === 'cir' ? g2().cir({ x, y, r, ls, fs, sh }).ins((g) => this.label && this.drawLabel(g))
- : g2().rec({ x: x - b, y: y - b, b: 2 * b, h: 2 * b, ls, fs, sh }).ins((g) => this.label && this.drawLabel(g));
+ const { x, y, r, b = 4, ls = 'black', fs = 'palegreen', sh } = this;
+
+ return g2().cir({ x, y, r, ls, fs, sh }).ins((g) => this.label && this.drawLabel(g));
}
});
@@ -363,8 +364,8 @@ g2.prototype.nod.prototype = g2.mix(g2.prototype.cir.prototype, {
*/
g2.prototype.dblnod = function ({ x = 0, y = 0 }) { return this.addCommand({ c: 'dblnod', a: arguments[0] }); }
g2.prototype.dblnod.prototype = g2.mix(g2.prototype.cir.prototype, {
- get r() { return 6; },
- get isSolid() { return true; },
+ r: 6,
+ isSolid: true,
g2() {
return g2()
.beg({ x: this.x, y: this.y })
@@ -390,7 +391,7 @@ g2.prototype.pol.prototype = g2.mix(g2.prototype.nod.prototype, {
g2() {
return g2()
.beg(g2.flatten(this))
- .cir({ r: 6, fs: g2.symbol.nodfill })
+ .cir({ r: 6, fs: '@fs2' })
.cir({ r: 2.5, fs: '@ls', ls: 'transparent' })
.end()
.ins((g) => this.label && this.drawLabel(g));
diff --git a/src/g2.hdl.canvas.js b/src/g2.hdl.canvas.js
index b7f2dfd..b30751c 100644
--- a/src/g2.hdl.canvas.js
+++ b/src/g2.hdl.canvas.js
@@ -346,13 +346,16 @@ g2.canvasHdl.prototype = {
let q, prv = {};
for (const key in style) {
if (this.get[key]) { // style keys only ...
+ let keyval = style[key];
if (typeof style[key] === 'string' && style[key][0] === '@') {
- let ref = style[key].substr(1);
- style[key] = g2.symbol[ref] || this.get[ref] && this.get[ref](this.ctx);
+ // also check inherited styles ...
+ const ref = style[key].substr(1);
+ keyval = g2.symbol[ref] || ref in this.get && this.get[ref](this.ctx)
+ || ref in this.cur && this.cur[ref];
}
- if ((q = this.get[key](this.ctx)) !== style[key]) {
+ if ((q = this.get[key](this.ctx)) !== keyval) {
prv[key] = q;
- this.set[key](this.ctx, style[key]);
+ this.set[key](this.ctx, keyval);
}
}
}
@@ -364,14 +367,17 @@ g2.canvasHdl.prototype = {
},
pushStyle(style) {
let cur = {}; // hold changed properties ...
- for (const key in style)
- if (this.get[key]) { // style keys only ...
+ for (const key in style) // allow extended style syntax ('fs-2', ...)
+ if (g2.styleRex.test(key)) { // (extended) style keys only ...
if (typeof style[key] === 'string' && style[key][0] === '@') {
let ref = style[key].substr(1);
style[key] = g2.symbol[ref] || this.get[ref] && this.get[ref](this.ctx);
}
- if (this.cur[key] !== style[key])
- this.set[key](this.ctx, (cur[key] = style[key]));
+ if (this.cur[key] !== style[key]) {
+ if (key in this.set)
+ this.set[key](this.ctx, style[key]);
+ cur[key] = style[key];
+ }
}
this.stack.push(this.cur = Object.assign({}, this.cur, cur));
},