From e802308a9eb5e94a3438172b274ef7b2495033ca Mon Sep 17 00:00:00 2001 From: Sergey Pimenov Date: Thu, 20 May 2021 21:03:30 +0300 Subject: [PATCH 01/22] init 1.0.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 077be69..6a62dbb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@olton/mina-monitor", - "version": "1.0.1", + "version": "1.0.2", "license": "MIT", "type": "module", "scripts": { From b40940e479d8aae150f3cb8e9f855246cfa9ca67 Mon Sep 17 00:00:00 2001 From: Sergey Pimenov Date: Thu, 20 May 2021 21:06:16 +0300 Subject: [PATCH 02/22] change md to mkdir in scripts commands --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 6a62dbb..cbac7da 100644 --- a/package.json +++ b/package.json @@ -4,12 +4,12 @@ "license": "MIT", "type": "module", "scripts": { - "serve": "rimraf -rf output & md output & xcopy client\\config.json output\\*.* /Y && parcel serve --open -d output -p 2222 client/index.html", - "serve_x": "rimraf -rf output & md output & cp -a client/config.json output && parcel serve --open -d output -p 2222 --no-cache client/index.html", + "serve": "rimraf -rf output & mkdir output & xcopy client\\config.json output\\*.* /Y && parcel serve --open -d output -p 2222 client/index.html", + "serve_x": "rimraf -rf output & mkdir output & cp -a client/config.json output && parcel serve --open -d output -p 2222 --no-cache client/index.html", "build_site": "xcopy client\\config.json dist\\*.* /Y /I && parcel build -d dist --public-url . --no-minify client/index.html", "build_site_x": "cp -a client/config.json dist && parcel build -d dist --public-url . --no-minify client/index.html", - "build": "rimraf -rf dist & md dist & npm run build_site", - "build_x": "rimraf -rf dist & md dist & npm run build_site_x" + "build": "rimraf -rf dist & mkdir dist & npm run build_site", + "build_x": "rimraf -rf dist & mkdir dist & npm run build_site_x" }, "devDependencies": { "@babel/cli": "^7.13.16", From 56216d360dfb4de42f63db98dfaa1fcae664e10e Mon Sep 17 00:00:00 2001 From: Sergey Pimenov Date: Thu, 20 May 2021 21:18:27 +0300 Subject: [PATCH 03/22] updated readme.en --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d017ca6..4f18edf 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@

# Mina Node Monitor -**Mina Node Monitor** is an extended graphical version of the` mina client status` command with additional indicators. +**Mina Monitor** is an extended graphical version of the` mina client status` command with additional indicators. This is a `client-server` application for visual monitoring of the validator node and alerts when the node has a problem. ## Key Features @@ -18,7 +18,7 @@ This is a `client-server` application for visual monitoring of the validator nod - client - JavaScript, HTML, CSS ### Credits -+ [x] [Mina Node Monitor]() by [Serhii Pimenov](https://github.com/olton) ++ [x] [Mina Monitor](https://github.com/olton/mina-node-monitor) by [Serhii Pimenov](https://github.com/olton) + [x] [Metro 4](https://github.com/olton/Metro-UI-CSS) by [Serhii Pimenov](https://github.com/olton) + [x] [ChartJS](https://github.com/olton/chartjs) by [Serhii Pimenov](https://github.com/olton) + [x] [SystemInformation](https://github.com/sebhildebrandt/systeminformation) by [Sebastian Hildebrandt](https://github.com/sebhildebrandt) @@ -52,7 +52,7 @@ Create file `config.json` in a `client` folder. Example below demonstrate witch ```json { "hosts": { - "node1": "192.168.1.2:3085" + "node1": "xxx.xxx.xxx.xxx:xxxx" }, "useHost": "node1", "intervals": { @@ -103,8 +103,8 @@ Create file `config.json` in a `server` folder. Example below demonstrate witch "canRestartNode": true, "restartAfter": 30, "restartCmd": "systemctl --user restart mina", - "host": "192.168.1.2:3085", - "graphql": "localhost:3085" + "host": "xxx.xxx.xxx.xxx:xxxx", + "graphql": "xxx.xxx.xxx.xxx:xxxx" } ``` @@ -118,7 +118,7 @@ where - `alertInterval` - the interval with which the server will check node state and send alerts in telegrams - `blockDiff` - difference in blocks with MinaExplorer at which an alert will be sent - `host` - IP and PORT on which the server will run -- `graphql` - Mina node GraphQL address +- `graphql` - Mina node GraphQL address (by default `localhost:3085`) - `canRestartNode` - if true, server can restart mina node - `restartAfter` - value in minutes, if node synced and height is lower from Mina Explorer within the specified time, node will restart after this interval - `restartCmd` - command for restart mina node From a3ddc5c733c774064b45b9455ec7258f3e506603 Mon Sep 17 00:00:00 2001 From: Sergey Pimenov Date: Thu, 20 May 2021 21:19:00 +0300 Subject: [PATCH 04/22] updated readme --- README.RU.md | 2 +- README.UA.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.RU.md b/README.RU.md index 61f8449..7b27f53 100644 --- a/README.RU.md +++ b/README.RU.md @@ -18,7 +18,7 @@ - клиент - JavaScript, HTML, CSS ### Использованы компоненты -+ [x] [Mina Node Monitor]() by [Serhii Pimenov](https://github.com/olton) ++ [x] [Mina Node Monitor](https://github.com/olton/mina-node-monitor) by [Serhii Pimenov](https://github.com/olton) + [x] [Metro 4](https://github.com/olton/Metro-UI-CSS) by [Serhii Pimenov](https://github.com/olton) + [x] [ChartJS](https://github.com/olton/chartjs) by [Serhii Pimenov](https://github.com/olton) + [x] [SystemInformation](https://github.com/sebhildebrandt/systeminformation) by [Sebastian Hildebrandt](https://github.com/sebhildebrandt) diff --git a/README.UA.md b/README.UA.md index 73dd52d..9fd313e 100644 --- a/README.UA.md +++ b/README.UA.md @@ -18,7 +18,7 @@ - кліент - JavaScript, HTML, CSS ### Використано компоненти -+ [x] [Mina Node Monitor]() by [Serhii Pimenov](https://github.com/olton) ++ [x] [Mina Node Monitor](https://github.com/olton/mina-node-monitor) by [Serhii Pimenov](https://github.com/olton) + [x] [Metro 4](https://github.com/olton/Metro-UI-CSS) by [Serhii Pimenov](https://github.com/olton) + [x] [ChartJS](https://github.com/olton/chartjs) by [Serhii Pimenov](https://github.com/olton) + [x] [SystemInformation](https://github.com/sebhildebrandt/systeminformation) by [Sebastian Hildebrandt](https://github.com/sebhildebrandt) From af797d222e200ecbdd77c318b6250c50eeb63140 Mon Sep 17 00:00:00 2001 From: Sergey Pimenov Date: Sun, 23 May 2021 21:14:34 +0300 Subject: [PATCH 05/22] added cpu threads chart --- .gitignore | 1 + CHANGELOG.md | 2 + client/index.html | 48 ++-- client/js/app.js | 3 +- client/js/cpu.js | 68 ++++-- client/js/mem.js | 8 +- client/js/net.js | 5 +- client/js/server-info.js | 2 +- client/vendor/chart/chart.js | 401 ++++++++++++++++++++++++------- client/vendor/chart/chart.min.js | 14 +- server/monitor.mjs | 1 + server/system.mjs | 22 +- 12 files changed, 427 insertions(+), 148 deletions(-) diff --git a/.gitignore b/.gitignore index 996ba6a..6344a36 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .idea output dist +private packages/**/lib packages/**/dist node_modules diff --git a/CHANGELOG.md b/CHANGELOG.md index 87d8edc..ce4b08f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +### 1.0.2 + ### 1.0.1 + [x] Added php proxy server + [x] Added uptime values from sidecar (parsed from http://uptime.minaprotocol.com) diff --git a/client/index.html b/client/index.html index 0b91699..cc96ab9 100644 --- a/client/index.html +++ b/client/index.html @@ -14,7 +14,7 @@
- MINAMONITOR v1.0.1 + MINAMONITOR v1.0.2
@@ -130,30 +130,42 @@
-
+
-
-
-
-
-
-
-
-
Free: GiB
+
+
+
+
+
+
+
+ FREE: GiB + USED: GiB +
+
-
-
-
-
-
Load average:
+ +
+
+
+
+
+
+
+
+
Load average:
+
-
-
-
+ +
+
+
+
 
+
diff --git a/client/js/app.js b/client/js/app.js index 3037dc7..03f4ebb 100644 --- a/client/js/app.js +++ b/client/js/app.js @@ -1,6 +1,6 @@ import {processSystemInfo} from "./server-info"; import {processServerTime} from "./server-time"; -import {processCPUData} from "./cpu"; +import {processCPUData, processCPUDataAll} from "./cpu"; import {processMemInfo} from "./mem"; import {processNetConnections, processNetInfo} from "./net"; import {processBlockchainInfo} from "./blockchain"; @@ -14,6 +14,7 @@ fetch("./config.json").then( (r) => r.ok ? r.json() : null ).then(config => { setTimeout(() => processSystemInfo(), 0) setTimeout(() => processServerTime(), 0) setTimeout(() => processCPUData(), 0) + setTimeout(() => processCPUDataAll(), 0) setTimeout(() => processMemInfo(), 0) setTimeout(() => processNetInfo(), 0) setTimeout(() => processNetConnections(), 0) diff --git a/client/js/cpu.js b/client/js/cpu.js index 68a3fe6..2cd7100 100644 --- a/client/js/cpu.js +++ b/client/js/cpu.js @@ -12,19 +12,7 @@ const cpuChart = chart.areaChart("#cpu-load", [ ], { ...defaultChartConfig, colors: [Metro.colors.toRGBA('#00AFF0', .5), Metro.colors.toRGBA('#aa00ff', .5)], - legend: { - position: 'top-left', - vertical: true, - background: "#22272e", - font: { - color: "#fff" - }, - margin: 0, - border: { - color: "#22272e" - }, - padding: 5 - }, + legend: false, padding: { left: 35, top: 5, @@ -43,7 +31,13 @@ const cpuChart = chart.areaChart("#cpu-load", [ } }); -let cpuGauge +let cpuGauge = chart.gauge('#cpu-use', [0], { + ...defaultGaugeConfig, + padding: 0, + onDrawValue: (v, p) => { + return +p.toFixed(0) + "%" + } +}) export const processCPUData = async () => { const elLog = $("#log-cpu") @@ -55,16 +49,6 @@ export const processCPUData = async () => { let {load = 0, user = 0, sys = 0, loadavg = [0, 0, 0]} = cpu - if (!cpuGauge) { - cpuGauge = chart.gauge('#cpu-use', [0], { - ...defaultGaugeConfig, - padding: 0, - onDrawValue: (v, p) => { - return +p.toFixed(0) + "%" - } - }) - } - cpuChart.addPoint(0, [datetime().time(), load]) cpuGauge.setData([load]) @@ -76,3 +60,39 @@ export const processCPUData = async () => { setTimeout( () => processCPUData(), globalThis.config.intervals.cpu ) } + +let cpuSegment + +export const processCPUDataAll = async () => { + let cpus = await getInfo('cpu-load-all') + let container = $("#cpu-load-all") + let height = 208 + + if (!container.children().length) { + cpuSegment = chart.segment("#cpu-load-all", cpus, { + padding: { + top: 0, + bottom: 0, + left: 0, + right: 0 + }, + segment: { + rowDistance: 6, + count: 40, + height: height / (cpus.length) - 6 + }, + border: { + color: "transparent" + }, + ghost: { + color: "rgba(125, 195, 123, .1)" + } + }) + } else { + cpus.forEach( (v, i) => { + cpuSegment.setData(v, i) + }) + } + + setTimeout( () => processCPUDataAll(), globalThis.config.intervals.cpu ) +} diff --git a/client/js/mem.js b/client/js/mem.js index 0f472dc..f8e8e0d 100644 --- a/client/js/mem.js +++ b/client/js/mem.js @@ -38,11 +38,14 @@ export const processMemInfo = async () => { font: { color: "#fff" }, - margin: 0, + margin: { + left:24, + top: 0 + }, border: { color: "#22272e" }, - padding: 5 + padding: 5, }, padding: { left: 30, @@ -77,6 +80,7 @@ export const processMemInfo = async () => { memoryGauge.setData([memUsage]) $("#free-ram").text(memFree.toFixed(0)) + $("#used-ram").text(memUsage.toFixed(0)) elLog.html(imgOk) // console.log("Mem (re)loaded!") diff --git a/client/js/net.js b/client/js/net.js index ff05bd6..a8099b4 100644 --- a/client/js/net.js +++ b/client/js/net.js @@ -23,7 +23,10 @@ let networkChart = chart.areaChart("#net-load", [ font: { color: "#fff" }, - margin: 0, + margin: { + left:24, + top: 0 + }, border: { color: "#22272e" }, diff --git a/client/js/server-info.js b/client/js/server-info.js index 62e27f3..f66f5c5 100644 --- a/client/js/server-info.js +++ b/client/js/server-info.js @@ -15,7 +15,7 @@ export const processSystemInfo = async () => { $("#cpu-info").text(cpuInfo.model) $("#ram-total").text(Math.round(memInfo.total / (1024 ** 3))) $("#os-distro").text(platformInfo.osVersion) - $("#hostname").text(platformInfo.hostname) + $("#hostname").text(platformInfo.hostname.split(".")[0]) $("#vcpu").text(cpuInfo.cores) $("title").text(platformInfo.hostname + " :: Mona Node Monitor") diff --git a/client/vendor/chart/chart.js b/client/vendor/chart/chart.js index ba4bd5d..d14d010 100644 --- a/client/vendor/chart/chart.js +++ b/client/vendor/chart/chart.js @@ -483,8 +483,8 @@ x = padding.left + legendPadding.left + legendMargin.left; for (var i = 0; i < items.length; i++) { - var [name] = items[i]; - offset += getTextBoxWidth(ctx, [[name]], { + var [name, _, value] = items[i]; + offset += getTextBoxWidth(ctx, [[legend.showValue ? "".concat(name, " - ").concat(value) : name]], { font: legend.font }) + box * 2 + magic; } @@ -492,8 +492,8 @@ offset = (this.viewWidth - offset) / 2; for (var _i = 0; _i < items.length; _i++) { - var [_name, color] = items[_i]; - var nameWidth = getTextBoxWidth(ctx, [[_name]], { + var [_name, color, _value] = items[_i]; + var nameWidth = getTextBoxWidth(ctx, [[legend.showValue ? "".concat(_name, " - ").concat(_value) : _name]], { font: legend.font }); @@ -506,7 +506,7 @@ color, fill: color }); - drawText(ctx, _name, [offset + x + box + magic, y + box / 2], { + drawText(ctx, legend.showValue ? "".concat(_name, " - ").concat(_value) : _name, [offset + x + box + magic, y + box / 2], { color: legend.font.color, stroke: legend.font.color, font: o.font @@ -541,17 +541,17 @@ textBoxHeight = items.length * lh + legendPadding.top + legendPadding.bottom + magic; if (legend.position === 'top-left') { - x = padding.left + legendMargin.left; - y = padding.top + legendMargin.top; + x = legendPadding.left + legendMargin.left; + y = legendPadding.top + legendMargin.top; } else if (legend.position === 'top-right') { x = this.dpiWidth - textBoxWidth - legendMargin.right - padding.right; - y = padding.top + legendMargin.top; + y = legendPadding.top + legendMargin.top; } else if (legend.position === 'bottom-left') { - x = padding.left + legendMargin.left; - y = this.dpiHeight - textBoxHeight - padding.bottom + legendMargin.bottom; + x = legendPadding.left + legendMargin.left; + y = this.dpiHeight - textBoxHeight - legendPadding.bottom + legendMargin.bottom; } else { - x = this.dpiWidth - textBoxWidth - legendMargin.right - padding.right; - y = this.dpiHeight - textBoxHeight - padding.bottom + legendMargin.bottom; + x = this.dpiWidth - textBoxWidth - legendMargin.right - legendPadding.right; + y = this.dpiHeight - textBoxHeight - legendPadding.bottom + legendMargin.bottom; } drawBox(ctx, [x, y, textBoxWidth, textBoxHeight], { @@ -564,12 +564,12 @@ y += box + magic + legendPadding.top; for (var i = 0; i < items.length; i++) { - var [name, color] = items[i]; + var [name, color, value] = items[i]; drawSquare(ctx, [x, y, box], { color, fill: color }); - drawText(ctx, name, [x + box + magic, y + 1], { + drawText(ctx, legend.showValue ? "".concat(name, " - ").concat(value) : name, [x + box + magic, y + 1], { color: legend.font.color, stroke: legend.font.color, font: legend.font @@ -688,8 +688,9 @@ height = o.height.toString().includes('%') ? elHeight / 100 * parseInt(o.height) : +o.height; this.width = width; this.height = height; - this.dpiHeight = o.dpi * height; - this.dpiWidth = o.dpi * width; + this.dpi = o.dpi; + this.dpiHeight = this.dpi * height; + this.dpiWidth = this.dpi * width; this.viewHeight = this.dpiHeight - (padding.top + padding.bottom); this.viewWidth = this.dpiWidth - (padding.left + padding.right); this.center = [this.dpiWidth / 2, this.dpiHeight / 2]; @@ -744,13 +745,31 @@ } setData(data, index) { + var redraw = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + if (typeof index !== "undefined") { this.data[index].data = data; } else { this.data = data; } - this.draw(); + if (redraw) this.resize(); + } + + setBoundaries(obj) { + var redraw = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var grantedKeys = ["minX", "minY", "minZ", "maxX", "maxY", "maxZ", "min", "max"]; + + for (var k in obj) { + if (grantedKeys.includes(k)) { + this[k] = obj[k]; + this.options.boundaries[k] = obj[k]; + } + } + + if (redraw) { + this.draw(); + } } mouseMove(e) { @@ -2265,10 +2284,7 @@ color: '#fff' }, showValue: false, - holeSize: 0, - legend: { - vertical: true - }, + padding: 0, onDrawValue: null }; @@ -2296,12 +2312,13 @@ class PieChart extends Chart { constructor(el, data, options) { super(el, data, merge({}, defaultPieChartOptions, options), 'pie'); - this.total = this.data.reduce((acc, curr) => acc + curr.data, 0); + this.total = this.data.reduce((acc, curr) => acc + curr, 0); this.legendItems = []; + var legend = this.options.legend; - if (this.options.legend && this.data.length) { - for (var i = 0; i < this.data.length; i++) { - this.legendItems.push([this.data[i].name, this.options.colors[i]]); + if (legend && legend.titles && legend.titles.length) { + for (var i = 0; i < legend.titles.length; i++) { + this.legendItems.push([legend.titles[i], this.options.colors[i], this.data[i]]); } } @@ -2311,21 +2328,19 @@ sectors() { var ctx = this.ctx, o = this.options; - expandPadding(o.padding); var [x, y] = this.center; var radius = this.radius; var startAngle = 0, endAngle = 360, offset = 0, - val = '', textVal = ''; var textX, textY; if (!this.data || !this.data.length) return; for (var i = 0; i < this.data.length; i++) { - var sector = this.data[i]; + var _val = this.data[i]; var color = o.colors[i]; - endAngle = 2 * Math.PI * sector.data / this.total; + endAngle = 2 * Math.PI * _val / this.total; drawSector(ctx, [x, y, radius, startAngle, startAngle + endAngle], { fill: color, color: color @@ -2333,29 +2348,26 @@ startAngle += endAngle; } - if (o.holeSize) { - drawCircle(ctx, [x, y, o.holeSize], { - color: '#fff' - }); - } - startAngle = 0; for (var _i = 0; _i < this.data.length; _i++) { - var _sector = this.data[_i], + var _ref; + + var _val2 = this.data[_i], percent = void 0; - endAngle = 2 * Math.PI * _sector.data / this.total; - offset = o.holeSize / 2; - percent = Math.round(_sector.data * 100 / this.total); - textVal = o.showValue ? _sector.data : percent + "%"; + var name = (_ref = this.legendItems[_i] && this.legendItems[_i][0]) !== null && _ref !== void 0 ? _ref : ""; + endAngle = 2 * Math.PI * _val2 / this.total; + offset = 0; + percent = Math.round(_val2 * 100 / this.total); + textVal = o.showValue ? _val2 : percent + "%"; if (typeof o.onDrawValue === 'function') { - textVal = o.onDrawValue.apply(null, [_sector.name, _sector.data, percent]); + textVal = o.onDrawValue.apply(null, [name, _val2, percent]); } textX = x + (radius / 2 + offset) * Math.cos(startAngle + endAngle / 2); textY = y + (radius / 2 + offset) * Math.sin(startAngle + endAngle / 2); - var textW = getTextBoxWidth(ctx, [val + "%"], { + var textW = getTextBoxWidth(ctx, [_val2 + "%"], { font: o.labels.font }); drawText(ctx, textVal, [textX - textW / 2, textY + o.labels.font.size / 2], { @@ -2656,26 +2668,28 @@ ctx.closePath(); }; - class Gauge extends Chart { - constructor(el, data, options) { - super(el, data, merge({}, defaultGaugeOptions, options), 'gauge'); - this.resize(); - } + var getFillColor = (p, colors) => { + var res = '#fff', + min = 0; - _getFillColor(p, colors) { - var res = '#fff', - min = 0; + for (var i = 0; i < colors.length; i++) { + var c = colors[i][0]; - for (var i = 0; i < colors.length; i++) { - var c = colors[i][0]; - - if (p > min && p <= c) { - res = colors[i][1]; - min = colors[i][0]; - } + if (p >= min && p <= c) { + res = colors[i][1]; + min = colors[i][0]; } + } - return res; + return res; + }; + + class Gauge extends Chart { + constructor(el, data, options) { + super(el, data, merge({}, defaultGaugeOptions, options), 'gauge'); + this.min = this.options.boundaries.min; + this.max = this.options.boundaries.max; + this.resize(); } gauge() { @@ -2690,7 +2704,7 @@ max = PI * (2 + o.endFactor); var r = o.radius * this.radius / 100 - o.backWidth; var v = this.data[0], - p = Math.round(Math.abs(100 * (v - o.boundaries.min) / (o.boundaries.max - o.boundaries.min))); + p = Math.round(Math.abs(100 * (v - this.min) / (this.max - this.min))); var val = min + (max - min) * p / 100; var textVal = p; var colors = []; @@ -2714,7 +2728,7 @@ drawArc(ctx, [x, y, r, min, val], { size: o.valueWidth, - stroke: this._getFillColor(p, colors) + stroke: getFillColor(p, colors) }); drawText(ctx, textVal, [0, 0], { align: "center", @@ -2759,49 +2773,93 @@ } var gauge = (el, data, options) => new Gauge(el, data, options); + var donutLabel = { + font: defaultFont, + fixed: false, + color: "#000", + angle: 0, + shift: { + x: 0, + y: 0 + } + }; + var defaultDonutOptions = { + backStyle: "#a7a7a7", + fillStyle: "#8f8", + backWidth: 100, + valueWidth: 100, + radius: 100, + boundaries: { + min: 0, + max: 100 + }, + label: donutLabel, + padding: 0 + }; + class Donut extends Chart { constructor(el, data, options) { - super(el, data, merge({}, defaultGaugeOptions, options), 'gauge'); + super(el, data, merge({}, defaultDonutOptions, options), 'donut'); + this.total = this.data.reduce((acc, curr) => acc + curr, 0); + this.min = this.options.boundaries.min; + this.max = this.options.boundaries.max; + this.legendItems = []; + var legend = this.options.legend; + + if (legend && legend.titles && legend.titles.length) { + for (var i = 0; i < legend.titles.length; i++) { + this.legendItems.push([legend.titles[i], this.options.colors[i], this.data[i]]); + } + } + this.resize(); } gauge() { var ctx = this.ctx, - o = this.options, - padding = expandPadding(o.padding); + o = this.options; var [x, y] = this.center; - x += padding.left; - y += padding.top; - var PI = Math.PI, - min = PI * o.startFactor, - max = PI * (2 + o.endFactor); - var r = o.radius * this.radius / 100 - o.backWidth; - var v = this.data[0], - p = Math.abs(100 * (v - o.boundaries.min) / (o.boundaries.max - o.boundaries.min)); - var val = min + (max - min) * p / 100; - var textVal = p.toFixed(0); - - if (typeof o.onDrawValue === 'function') { - textVal = o.onDrawValue.apply(null, [v, p]); - } - - drawArc(ctx, [x, y, r, 0, 2 * PI], { + var PI = Math.PI; + var radius = this.radius - o.backWidth / 2; + drawArc(ctx, [x, y, radius, 0, 2 * PI], { size: o.backWidth, stroke: o.backStyle }); - drawArc(ctx, [x, y, r, min, val], { - size: o.valueWidth, - stroke: o.fillStyle - }); - drawText(ctx, textVal, [0, 0], { - align: "center", - baseLine: "middle", - color: o.value.color, - stroke: o.value.color, - font: o.value.font || o.font, - translate: [x + o.value.shift.x, y + o.value.shift.y], - angle: o.value.angle - }); + var startAngle = 0, + endAngle = 0; + + for (var i = 0; i < this.data.length; i++) { + var color = o.colors[i]; + var val = this.data[i]; + endAngle = 2 * Math.PI * val / this.total; + drawArc(ctx, [x, y, radius, startAngle, startAngle + endAngle], { + size: o.valueWidth, + stroke: color + }); + + if (o.label) { + var _ref; + + var name = (_ref = this.legendItems[i] && this.legendItems[i][0]) !== null && _ref !== void 0 ? _ref : ""; + var percent = Math.round(val * 100 / this.total); + var textVal = o.showValue ? val : percent + "%"; + var textX = void 0, + textY = void 0; + + if (typeof o.onDrawValue === 'function') { + textVal = o.onDrawValue.apply(null, [name, val, percent]); + } + + textX = x + radius * Math.cos(startAngle + endAngle / 2); + textY = y + radius * Math.sin(startAngle + endAngle / 2); + drawText(ctx, textVal, [textX, textY], { + color: o.label.color, + font: o.label.font + }); + } + + startAngle += endAngle; + } } draw() { @@ -2810,9 +2868,165 @@ this.legend(); } + resize() { + super.resize(); + this.center = [this.dpiWidth / 2, this.dpiHeight / 2]; + } + } var donut = (el, data, options) => new Donut(el, data, options); + var defaultSegmentOptions = { + segment: { + count: 100, + distance: 4, + rowDistance: 4, + height: 10, + radius: 0 + }, + ghost: { + color: "#f1f1f1" + }, + colors: [[70, '#60a917'], [90, '#f0a30a'], [100, '#a20025']], + padding: 0, + margin: 0 + }; + + var drawRoundedRect = function drawRoundedRect(ctx, _ref) { + var [x, y, width, height] = _ref; + var { + color = '#000', + fill = '#fff', + size = 1, + dash = [], + radius = 4 + } = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; + + if (typeof radius === 'number') { + radius = { + tl: radius, + tr: radius, + br: radius, + bl: radius + }; + } else { + var defaultRadius = { + tl: 0, + tr: 0, + br: 0, + bl: 0 + }; + + for (var side in defaultRadius) { + radius[side] = radius[side] || defaultRadius[side]; + } + } + + ctx.beginPath(); + ctx.fillStyle = fill; + ctx.strokeStyle = color; + ctx.moveTo(x + radius.tl, y); + ctx.lineTo(x + width - radius.tr, y); + ctx.quadraticCurveTo(x + width, y, x + width, y + radius.tr); + ctx.lineTo(x + width, y + height - radius.br); + ctx.quadraticCurveTo(x + width, y + height, x + width - radius.br, y + height); + ctx.lineTo(x + radius.bl, y + height); + ctx.quadraticCurveTo(x, y + height, x, y + height - radius.bl); + ctx.lineTo(x, y + radius.tl); + ctx.quadraticCurveTo(x, y, x + radius.tl, y); + ctx.fill(); + ctx.stroke(); + ctx.closePath(); + }; + + class Segment extends Chart { + constructor(el, data, options) { + var values = Array.isArray(data) ? data : [data]; + var opt = merge({}, defaultOptions, defaultSegmentOptions, options); + var padding = expandPadding(opt.padding); + var { + height, + distance, + rowDistance + } = opt.segment; + var canvasHeight = ((height + rowDistance) * values.length - rowDistance + (padding.top + padding.bottom)) * opt.dpi + rowDistance; + super(el, data, _objectSpread2(_objectSpread2({}, opt), {}, { + height: canvasHeight + }), 'segment'); + this.min = 0; + this.max = 100; + this.values = values; + this.resize(); + } + + segments() { + var ctx = this.ctx, + o = this.options, + s = o.segment; + var count = s.count ? s.count : 20; + var distance = s.distance * o.dpi; + var rowDistance = s.rowDistance * o.dpi; + var width = this.viewWidth / count - distance; + var height = s.height; + var colors = []; + var padding = expandPadding(o.padding); + var x, + y = padding.top + distance; + + if (typeof o.colors === "string") { + colors.push([100, o.colors]); + } else if (Array.isArray(o.colors)) { + for (var c of o.colors) { + colors.push(c); + } + } + + for (var k = 0; k < this.values.length; k++) { + var value = this.values[k]; + var limit = count * value / 100; + x = padding.left - distance / 2; + + for (var i = 0; i < count; i++) { + var color = getFillColor(i * 100 / count, colors); + + if (i <= limit) { + drawRoundedRect(ctx, [x, y, width, height], { + color, + fill: color, + radius: s.radius + }); + } else { + if (o.ghost) { + drawRoundedRect(ctx, [x, y, width, height], { + color: o.ghost.color, + fill: o.ghost.color, + radius: s.radius + }); + } + } + + x += width + distance; + } + + y += height + rowDistance; + } + } + + setData(data) { + var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; + var redraw = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true; + this.values[index] = data; + if (redraw) this.resize(); + } + + draw() { + super.draw(); + this.segments(); + } + + } + var segment = (el, data, options) => new Segment(el, data, options); + globalThis.chart = { areaChart, barChart, @@ -2822,7 +3036,8 @@ pieChart, stackedBarChart, gauge, - donut + donut, + segment }; }()); diff --git a/client/vendor/chart/chart.min.js b/client/vendor/chart/chart.min.js index 2bbb65c..3b4dd51 100644 --- a/client/vendor/chart/chart.min.js +++ b/client/vendor/chart/chart.min.js @@ -18,15 +18,15 @@ function s(t){return t&&"object"==typeof t&&!Array.isArray(t)} * Deep merge two objects. * @param target * @param ...sources - */function o(t){for(var i=arguments.length,e=new Array(i>1?i-1:0),a=1;a3&&void 0!==arguments[3]?arguments[3]:{},{style:f="normal",weight:u="normal",size:p=12,lineHeight:g=1,family:m="sans-serif"}=h,v=0,b=0;"number"==typeof c?v=b=c:Array.isArray(c)&&([v,b]=c),t.save(),t.beginPath(),t.textAlign=o,t.fillStyle=n,t.strokeStyle=l,t.font="".concat(f," ").concat(u," ").concat(p,"px/").concat(g," ").concat(m),t.translate(v,b),t.rotate(d),t.textBaseline=r;var x=i.toString().split("\n");x.map(((i,e)=>{t.fillText(i,a,s+s*e*g)})),t.closePath(),t.restore()},n=(t,i,e)=>{var a,{font:s=null}=e,o=0;if(t.save(),s){var{style:r="normal",weight:n="normal",size:l=12,lineHeight:h=1.2,family:d="sans-serif"}=s;t.font="".concat(r," ").concat(n," ").concat(l,"px/").concat(h," ").concat(d)}for(var c=0;co&&(o=a);return t.restore(),o},l=function(t,i){var[e,a,s]=i,{color:o="#000",fill:r="#fff",size:n=1,dash:l=[]}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.save(),t.setLineDash(l),t.lineWidth=n,t.strokeStyle=o,t.fillStyle=r,t.rect(e-s,a-s,2*s,2*s),t.fill(),t.stroke(),t.restore(),t.closePath()},h=t=>"number"==typeof t?{top:t,left:t,right:t,bottom:t}:t,d=t=>"number"==typeof t?{top:t,left:t,right:t,bottom:t}:t,c={legend(){return!0===this.options.legend.vertical?this.legendVertical():this.legendHorizontal()},legendHorizontal(){var t,i,e,a,o=this.options,c=h(o.padding),f=o.legend,u=h(f.padding),p=d(f.margin),g=this.ctx,m=this.legendItems,v=0;if(f&&s(f)&&m&&Array.isArray(m)&&m.length){a=f.font.size/2,t=f.font.size*f.font.lineHeight,e=c.top+this.viewHeight+f.font.size+u.top+p.top,i=c.left+u.left+p.left;for(var b=0;bthis.viewWidth&&(i=c.left+u.left+p.left,e+=t),l(g,[v+i,e,a],{color:X,fill:X}),r(g,w,[v+i+a+5,e+a/2],{color:f.font.color,stroke:f.font.color,font:o.font}),i+=a+Y+20}}},legendVertical(){var t,i,e,a,o,c,f=this.options,u=f.legend,p=null!==(t=u.font)&&void 0!==t?t:f.font,g=p.size/2,m=this.ctx,v=this.legendItems,b=h(u.padding),x=d(u.margin),y=h(f.padding);if(u&&s(u)&&v&&Array.isArray(v)&&v.length){i=p.size*p.lineHeight,o=n(m,v,{font:p})+b.left+b.right+3*g+5,c=v.length*i+b.top+b.bottom+5,"top-left"===u.position?(e=y.left+x.left,a=y.top+x.top):"top-right"===u.position?(e=this.dpiWidth-o-x.right-y.right,a=y.top+x.top):"bottom-left"===u.position?(e=y.left+x.left,a=this.dpiHeight-c-y.bottom+x.bottom):(e=this.dpiWidth-o-x.right-y.right,a=this.dpiHeight-c-y.bottom+x.bottom),function(t,i){var[e,a,s,o]=i,{color:r="#fff",borderColor:n="#000",dash:l=[],size:h=1}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};t.save(),t.beginPath(),t.strokeStyle=n,t.fillStyle=r,t.setLineDash(l),t.lineWidth=h,t.clearRect(e,a,s,o),t.fillRect(e,a,s,o),h&&t.strokeRect(e,a,s,o),t.closePath(),t.restore()}(m,[e,a,o,c],{color:u.background,dash:u.dash,size:u.border.width,borderColor:u.border.color}),e+=g+5+b.left,a+=g+5+b.top;for(var w=0;w1&&void 0!==arguments[1]?arguments[1]:[],e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},s=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"unknown";if(this.el=document.querySelector(t),!this.el)throw new Error("You must define a selector for chart wrapper element!");this.options=o({},a,e),this.data=i,this.canvas=null,this.ctx=null,this.raf=null,this.tooltip=null,this.legendItems=[],this.chartType=s,this.rect=this.el.getBoundingClientRect(),this.canvasRect=null,this.static=!1;var r=this;this.proxy=new Proxy({},{set(){var t=Reflect.set(...arguments);return r.raf=requestAnimationFrame(r.draw.bind(r)),t}}),this.options.border&&(this.el.style.border="".concat(this.options.border.width,"px ").concat(this.options.border.lineType," ").concat(this.options.border.color)),this.calcInternalValues(),this.createCanvas(),this.addEvents()}createCanvas(){this.canvas=document.createElement("canvas"),this.el.innerHTML="",this.el.style.overflow="hidden",this.el.appendChild(this.canvas),this.ctx=this.canvas.getContext("2d"),this.setCanvasSize(),this.canvasRect=this.canvas.getBoundingClientRect()}setCanvasSize(){var t=this.options;this.canvas.style.height=this.height+"px",this.canvas.style.width=this.width+"px",this.canvas.width=t.dpi*this.width,this.canvas.height=t.dpi*this.height}calcInternalValues(){var t,i,e=this.options,a=h(e.padding),s=this.el.getBoundingClientRect(),{width:o,height:r}=s;t=e.width.toString().includes("%")?o/100*parseInt(e.width):+e.width,i=e.height.toString().includes("%")?r/100*parseInt(e.height):+e.height,this.width=t,this.height=i,this.dpiHeight=e.dpi*i,this.dpiWidth=e.dpi*t,this.viewHeight=this.dpiHeight-(a.top+a.bottom),this.viewWidth=this.dpiWidth-(a.left+a.right),this.center=[this.dpiWidth/2,this.dpiHeight/2],this.radius=Math.min(this.viewHeight,this.viewWidth)/2}title(){var t,i=this.options.title,e=this.ctx;if(i&&i.text){var{text:a,align:s,color:o,font:n}=i;switch(s){case"center":t=this.dpiWidth/2;break;case"right":t=this.dpiWidth-5;break;default:t=5}r(e,a,[t,n.size+5],{align:i.align,color:i.color,stroke:i.color,font:i.font})}}draw(){this.clear(),this.title()}clear(){this.ctx.clearRect(0,0,this.dpiWidth,this.dpiHeight)}setData(t,i){void 0!==i?this.data[i].data=t:this.data=t,this.draw()}mouseMove(t){var i=this.options.onHover,{clientX:e,clientY:a}=t.changedTouches?t.touches[0]:t;"function"==typeof i&&i.apply(null,[e,a]),this.proxy.mouse={x:e,y:a},t.cancelable&&t.preventDefault()}mouseLeave(){var t=this.options.onLeave;"function"==typeof t&&t.apply(null,[]),this.proxy.mouse=null}resize(){this.calcInternalValues(),this.setCanvasSize(),this.rect=this.el.getBoundingClientRect(),this.canvasRect=this.canvas.getBoundingClientRect(),this.draw()}addEvents(){var t=this.canvas;t.addEventListener("mousemove",this.mouseMove.bind(this)),t.addEventListener("touchmove",this.mouseMove.bind(this),{passive:!1}),t.addEventListener("mouseleave",this.mouseLeave.bind(this)),window.addEventListener("resize",this.resize.bind(this))}destroy(){var t=this.canvas;cancelAnimationFrame(this.raf),t.removeEventListener("mousemove",this.mouseMove.bind(this)),t.removeEventListener("mouseleave",this.mouseLeave.bind(this)),window.removeEventListener("resize",this.resize.bind(this))}}Object.assign(u.prototype,c),Object.assign(u.prototype,f);var p={arrow:{color:"#000",size:1,dash:[],factorX:5,factorY:5},line:{color:"#e3e3e3",size:1,dash:[],count:5,show:!0},label:{color:"#000",font:e,count:5, + */function o(t){for(var i=arguments.length,e=new Array(i>1?i-1:0),a=1;a3&&void 0!==arguments[3]?arguments[3]:{},{style:f="normal",weight:u="normal",size:p=12,lineHeight:g=1,family:m="sans-serif"}=h,v=0,b=0;"number"==typeof c?v=b=c:Array.isArray(c)&&([v,b]=c),t.save(),t.beginPath(),t.textAlign=o,t.fillStyle=n,t.strokeStyle=l,t.font="".concat(f," ").concat(u," ").concat(p,"px/").concat(g," ").concat(m),t.translate(v,b),t.rotate(d),t.textBaseline=r;var x=i.toString().split("\n");x.map(((i,e)=>{t.fillText(i,a,s+s*e*g)})),t.closePath(),t.restore()},n=(t,i,e)=>{var a,{font:s=null}=e,o=0;if(t.save(),s){var{style:r="normal",weight:n="normal",size:l=12,lineHeight:h=1.2,family:d="sans-serif"}=s;t.font="".concat(r," ").concat(n," ").concat(l,"px/").concat(h," ").concat(d)}for(var c=0;co&&(o=a);return t.restore(),o},l=function(t,i){var[e,a,s]=i,{color:o="#000",fill:r="#fff",size:n=1,dash:l=[]}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.save(),t.setLineDash(l),t.lineWidth=n,t.strokeStyle=o,t.fillStyle=r,t.rect(e-s,a-s,2*s,2*s),t.fill(),t.stroke(),t.restore(),t.closePath()},h=t=>"number"==typeof t?{top:t,left:t,right:t,bottom:t}:t,d=t=>"number"==typeof t?{top:t,left:t,right:t,bottom:t}:t,c={legend(){return!0===this.options.legend.vertical?this.legendVertical():this.legendHorizontal()},legendHorizontal(){var t,i,e,a,o=this.options,c=h(o.padding),f=o.legend,u=h(f.padding),p=d(f.margin),g=this.ctx,m=this.legendItems,v=0;if(f&&s(f)&&m&&Array.isArray(m)&&m.length){a=f.font.size/2,t=f.font.size*f.font.lineHeight,e=c.top+this.viewHeight+f.font.size+u.top+p.top,i=c.left+u.left+p.left;for(var b=0;bthis.viewWidth&&(i=c.left+u.left+p.left,e+=t),l(g,[v+i,e,a],{color:k,fill:k}),r(g,f.showValue?"".concat(Y," - ").concat(z):Y,[v+i+a+5,e+a/2],{color:f.font.color,stroke:f.font.color,font:o.font}),i+=a+W+20}}},legendVertical(){var t,i,e,a,o,c,f=this.options,u=f.legend,p=null!==(t=u.font)&&void 0!==t?t:f.font,g=p.size/2,m=this.ctx,v=this.legendItems,b=h(u.padding),x=d(u.margin),y=h(f.padding);if(u&&s(u)&&v&&Array.isArray(v)&&v.length){i=p.size*p.lineHeight,o=n(m,v,{font:p})+b.left+b.right+3*g+5,c=v.length*i+b.top+b.bottom+5,"top-left"===u.position?(e=b.left+x.left,a=b.top+x.top):"top-right"===u.position?(e=this.dpiWidth-o-x.right-y.right,a=b.top+x.top):"bottom-left"===u.position?(e=b.left+x.left,a=this.dpiHeight-c-b.bottom+x.bottom):(e=this.dpiWidth-o-x.right-b.right,a=this.dpiHeight-c-b.bottom+x.bottom),function(t,i){var[e,a,s,o]=i,{color:r="#fff",borderColor:n="#000",dash:l=[],size:h=1}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};t.save(),t.beginPath(),t.strokeStyle=n,t.fillStyle=r,t.setLineDash(l),t.lineWidth=h,t.clearRect(e,a,s,o),t.fillRect(e,a,s,o),h&&t.strokeRect(e,a,s,o),t.closePath(),t.restore()}(m,[e,a,o,c],{color:u.background,dash:u.dash,size:u.border.width,borderColor:u.border.color}),e+=g+5+b.left,a+=g+5+b.top;for(var w=0;w1&&void 0!==arguments[1]?arguments[1]:[],e=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},s=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"unknown";if(this.el=document.querySelector(t),!this.el)throw new Error("You must define a selector for chart wrapper element!");this.options=o({},a,e),this.data=i,this.canvas=null,this.ctx=null,this.raf=null,this.tooltip=null,this.legendItems=[],this.chartType=s,this.rect=this.el.getBoundingClientRect(),this.canvasRect=null,this.static=!1;var r=this;this.proxy=new Proxy({},{set(){var t=Reflect.set(...arguments);return r.raf=requestAnimationFrame(r.draw.bind(r)),t}}),this.options.border&&(this.el.style.border="".concat(this.options.border.width,"px ").concat(this.options.border.lineType," ").concat(this.options.border.color)),this.calcInternalValues(),this.createCanvas(),this.addEvents()}createCanvas(){this.canvas=document.createElement("canvas"),this.el.innerHTML="",this.el.style.overflow="hidden",this.el.appendChild(this.canvas),this.ctx=this.canvas.getContext("2d"),this.setCanvasSize(),this.canvasRect=this.canvas.getBoundingClientRect()}setCanvasSize(){var t=this.options;this.canvas.style.height=this.height+"px",this.canvas.style.width=this.width+"px",this.canvas.width=t.dpi*this.width,this.canvas.height=t.dpi*this.height}calcInternalValues(){var t,i,e=this.options,a=h(e.padding),s=this.el.getBoundingClientRect(),{width:o,height:r}=s;t=e.width.toString().includes("%")?o/100*parseInt(e.width):+e.width,i=e.height.toString().includes("%")?r/100*parseInt(e.height):+e.height,this.width=t,this.height=i,this.dpi=e.dpi,this.dpiHeight=this.dpi*i,this.dpiWidth=this.dpi*t,this.viewHeight=this.dpiHeight-(a.top+a.bottom),this.viewWidth=this.dpiWidth-(a.left+a.right),this.center=[this.dpiWidth/2,this.dpiHeight/2],this.radius=Math.min(this.viewHeight,this.viewWidth)/2}title(){var t,i=this.options.title,e=this.ctx;if(i&&i.text){var{text:a,align:s,color:o,font:n}=i;switch(s){case"center":t=this.dpiWidth/2;break;case"right":t=this.dpiWidth-5;break;default:t=5}r(e,a,[t,n.size+5],{align:i.align,color:i.color,stroke:i.color,font:i.font})}}draw(){this.clear(),this.title()}clear(){this.ctx.clearRect(0,0,this.dpiWidth,this.dpiHeight)}setData(t,i){var e=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];void 0!==i?this.data[i].data=t:this.data=t,e&&this.resize()}setBoundaries(t){var i=!(arguments.length>1&&void 0!==arguments[1])||arguments[1],e=["minX","minY","minZ","maxX","maxY","maxZ","min","max"];for(var a in t)e.includes(a)&&(this[a]=t[a],this.options.boundaries[a]=t[a]);i&&this.draw()}mouseMove(t){var i=this.options.onHover,{clientX:e,clientY:a}=t.changedTouches?t.touches[0]:t;"function"==typeof i&&i.apply(null,[e,a]),this.proxy.mouse={x:e,y:a},t.cancelable&&t.preventDefault()}mouseLeave(){var t=this.options.onLeave;"function"==typeof t&&t.apply(null,[]),this.proxy.mouse=null}resize(){this.calcInternalValues(),this.setCanvasSize(),this.rect=this.el.getBoundingClientRect(),this.canvasRect=this.canvas.getBoundingClientRect(),this.draw()}addEvents(){var t=this.canvas;t.addEventListener("mousemove",this.mouseMove.bind(this)),t.addEventListener("touchmove",this.mouseMove.bind(this),{passive:!1}),t.addEventListener("mouseleave",this.mouseLeave.bind(this)),window.addEventListener("resize",this.resize.bind(this))}destroy(){var t=this.canvas;cancelAnimationFrame(this.raf),t.removeEventListener("mousemove",this.mouseMove.bind(this)),t.removeEventListener("mouseleave",this.mouseLeave.bind(this)),window.removeEventListener("resize",this.resize.bind(this))}}Object.assign(u.prototype,c),Object.assign(u.prototype,f);var p={arrow:{color:"#000",size:1,dash:[],factorX:5,factorY:5},line:{color:"#e3e3e3",size:1,dash:[],count:5,show:!0},label:{color:"#000",font:e,count:5, // odd, even, num show:!0,first:!0,last:!0,fixed:!1}},g={x:p,y:p},m={size:1,color:"#bbb",dash:[5,3]},v={axis:g,cross:m,showDots:!0},b=function(){var t,i,e,a,s=arguments.length>0&&void 0!==arguments[0]?arguments[0]:[],o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"x";if("number"==typeof o)a=o;else switch(o.toString().toLowerCase()){case"y":a=1;break;case"z":a=2;break;default:a=0}for(var r of s)e=r[a],(isNaN(t)||t>e)&&(t=e),(isNaN(i)||i0&&void 0!==arguments[0]?arguments[0]:[];return[Math.min.apply(null,t),Math.max.apply(null,t)]},y=function(t,i){var[e,a,s]=i,{color:o="#000",fill:r="#fff",size:n=1}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.save(),t.setLineDash([]),t.lineWidth=n,t.strokeStyle=o,t.fillStyle=r,t.arc(e,a,s,0,2*Math.PI),t.fill(),t.stroke(),t.restore(),t.closePath()},w=function(t,i){var[e,a,s]=i,{color:o="#000",fill:r="#fff",size:n=1}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.save(),t.setLineDash([]),t.lineWidth=n,t.strokeStyle=o,t.fillStyle=r,t.moveTo(e,a-s),t.lineTo(e+s,a+s),t.lineTo(e-s,a+s),t.lineTo(e,a-s),t.fill(),t.stroke(),t.restore(),t.closePath()},X=function(t,i){var[e,a,s]=i,{color:o="#000",fill:r="#fff",size:n=1}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.save(),t.setLineDash([]),t.lineWidth=n,t.strokeStyle=o,t.fillStyle=r,t.moveTo(e,a-s),t.lineTo(e+s,a),t.lineTo(e,a+s),t.lineTo(e-s,a),t.lineTo(e,a-s),t.fill(),t.stroke(),t.restore(),t.closePath()},Y={cross(){var t=this.options,i=t.cross,e=h(t.padding),a=this.ctx,s=this.canvas.getBoundingClientRect();if(t.cross&&(!t.cross||this.proxy.mouse)){var{x:o,y:r}=this.proxy.mouse;o-=s.left,r-=s.top,o-e.left+1<0||o>this.viewWidth+e.left+1||r-e.top+1<0||r>this.viewHeight+e.top+1||(a.beginPath(),a.setLineDash(t.cross.dash),a.lineWidth=i.size,a.strokeStyle=i.color,// vertical line a.moveTo(o,e.top),a.lineTo(o,this.viewHeight+e.top),// Horizontal line a.moveTo(e.left,r),a.lineTo(this.viewWidth+e.left,r),a.arc(o,r,10,0,2*Math.PI),a.stroke(),a.closePath())}}},k=function(t,i){var[e,a,s,o]=i,{color:r="#000",size:n=1,dash:l=[]}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.save(),t.setLineDash(l),t.lineWidth=n,t.strokeStyle=r,t.moveTo(e,a),t.lineTo(s,o),t.stroke(),t.restore(),t.closePath()},z={arrowX(){var t=this.options,i=this.ctx,e=h(t.padding),a=e.left,s=this.viewHeight+e.top,o=a+this.viewWidth,r=s;if(t.axis.x.arrow){var n=t.axis.x.arrow;!function(t,i){var[e,a,s,o,r,n]=i,{color:l="#000",dash:h=[],size:d=1}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.strokeStyle=l,t.lineWidth=d,t.setLineDash(h),t.moveTo(e,a),t.lineTo(s,o),t.moveTo(s,o),t.lineTo(s-r,o-n),t.moveTo(s,o),t.lineTo(s-r,o+n),t.stroke(),t.closePath()}(i,[a,s,o,r,n.factorX,n.factorY],{color:n.color,size:n.size,dash:n.dash})}},axisX(){var t,i=this.ctx,e=this.options,a=h(e.padding);if(e.axis.x)for(var s=e.axis.x,o=null!==(t=s&&s.label&&s.label.font)&&void 0!==t?t:e.font,n=this.viewWidth/s.line.count,l=(this.maxX-this.minX)/s.line.count,d=Math.round(s.line.count/s.label.count),c=0;c<=s.line.count;c++){var f,u,p=n*c+a.left,g=this.minX+l*c;"number"==typeof s.label.fixed&&(g=g.toFixed(s.label.fixed)),s.line.show&&k(i,[p,a.top,p,this.viewHeight+a.top],{color:s.line.color,size:s.line.size,dash:s.line.dash}),s.label.show&&(d&&c&&c%d!=0||(s.label.first||0!==c)&&(s.label.last||c!==s.line.count)&&("function"==typeof e.onDrawLabelX&&(g=e.onDrawLabelX.apply(null,[g])),// if (x + ctx.measureText(labelXValue.toString()).width > this.viewWidth) continue -k(i,[p,this.viewHeight+a.top,p,this.viewHeight+a.top+5],{color:null!==(f=s.arrow&&s.arrow.color)&&void 0!==f?f:s.line.color}),r(i,g.toString(),[p,this.viewHeight+a.top+o.size+5],{color:null!==(u=s.label&&s.label.color)&&void 0!==u?u:e.color,align:"center",font:o})))}},arrowY(){var t=this.options,i=this.ctx,e=h(t.padding),a=e.left,s=this.viewHeight+e.top,o=a,r=e.top;if(t.axis.y.arrow){var n=t.axis.y.arrow;!function(t,i){var[e,a,s,o,r,n]=i,{color:l="#000",dash:h=[],size:d=1}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.strokeStyle=l,t.lineWidth=d,t.setLineDash(h),t.moveTo(e,a),t.lineTo(s,o),t.moveTo(s,o),t.lineTo(s-r,o+n),t.moveTo(s,o),t.lineTo(s+r,o+n),t.stroke(),t.closePath()}(i,[a,s,o,r,n.factorX,n.factorY],{color:n.color,size:n.size,dash:n.dash})}},axisY(){var t,i=this.ctx,e=this.options,a=h(e.padding);if(e.axis.y)for(var s=e.axis.y,o=null!==(t=s&&s.label&&s.label.font)&&void 0!==t?t:e.font,n=this.viewHeight/s.line.count,l=(this.maxY-this.minY)/s.line.count,d=Math.floor(s.line.count/s.label.count),c=0;c2&&void 0!==arguments[2])||arguments[2],r=this.options;this.data&&this.data.length&&(e=this.data[t].data,o&&(r.graphSize?e.length===r.graphSize&&(e=e.slice(1)):e=e.slice(1)),this.data[t].data=e,this.data[t].data.push([a,s]),this.calcMinMax(),this.calcRatio(),this.resize())}},W=function(t){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],{color:e="#000",size:a=1,dash:s=[]}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.save(),t.setLineDash(s),t.lineWidth=a,t.strokeStyle=e,i.map((i=>{var[e,a]=i;t.lineTo(e,a)})),t.stroke(),t.restore(),t.closePath()};class M extends u{constructor(t){if(super(t,arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],o({},v,arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}),"area"),this.coords={},this.minX=0,this.maxX=0,this.minY=0,this.maxY=0,this.legendItems=[],this.options.legend)for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:[],{color:e="#000",fill:a="#000",size:s=1,dash:o=[]}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.save(),t.setLineDash(o),t.lineWidth=s,t.strokeStyle=e,t.fillStyle=a,i.map((i=>{var[e,a]=i;t.lineTo(e,a)})),t.lineTo(i[0][0],i[0][1]),t.fill(),t.restore(),t.closePath()}(s,t,{color:u,fill:p,size:f.size});var x=f.dots?f.dots:{type:"dot"},Y={color:null!==(h=x.color)&&void 0!==h?h:u,fill:null!==(d=x.fill)&&void 0!==d?d:u,radius:null!==(c=x.size)&&void 0!==c?c:4},k=void 0;switch(x.type){case"square":k=l;break;case"triangle":k=w;break;case"diamond":k=X;break;default:k=y}f.dots&&!1!==e.showDots&&t.map((t=>{var[i,e]=t;k(s,[i,e,Y.radius],Y)})),i.coords[f.name]={graph:f,coords:t,drawPointFn:k,opt:Y},t.shift(),t.pop(),!1!==f.showLines&&W(s,t,{color:u,fill:p,size:f.size})},r=0;rv&&rv&&rx&&n2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.save(),t.setLineDash(h),t.lineWidth=l,t.strokeStyle=r,t.fillStyle=n,t.rect(e,a,s,o),t.fill(),t.stroke(),t.restore(),t.closePath()};class L extends u{constructor(t,i,e){super(t,i,o({},T,e),"bar"),this.groups=0,this.barWidth=0,this.maxY=0,this.maxX=0,this.minY=0,this.minX=0,this.viewAxis=this.options.dataAxisX?this.viewHeight:this.viewWidth,this.legendItems=[];var a=this.options.legend;if(a&&a.titles&&a.titles.length)for(var s=0;s0&&void 0!==arguments[0]&&arguments[0],o=this.options,n=h(o.padding),l=this.ctx,d=this.canvas.getBoundingClientRect(),c=!1;if(this.data&&this.data.length){this.proxy.mouse&&(e=this.proxy.mouse.x-d.left,a=this.proxy.mouse.y-d.top),t=s?n.left:n.left+o.groupDistance,i=s?n.top+o.groupDistance:this.viewHeight+n.top;for(var f=0;fY[0]&&ek[0]&&a2&&void 0!==arguments[2])||arguments[2],n=this.options;this.data&&this.data.length&&(e=this.data[t].data,r&&(e=(n.graphSize&&(e.length,n.graphSize),e.slice(1))),this.data[t].data=e,this.data[t].data.push([a,s,o]),this.calcMinMax(),this.calcRatio(),this.resize())}};class B extends u{constructor(t){if(super(t,arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],o({},A,arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}),"histogram"),this.coords={},this.minX=0,this.maxX=0,this.minY=0,this.maxY=0,this.legendItems=[],this.options.legend)for(var i=0;i2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.strokeStyle=l,t.lineWidth=d,t.setLineDash(h),t.moveTo(e,a),t.lineTo(s,o),t.moveTo(s,o),t.lineTo(s-r,o+n),t.moveTo(s,o),t.lineTo(s+r,o+n),t.stroke(),t.closePath()}(i,[a,s,o,r,n.factorX,n.factorY],{color:n.color,size:n.size,dash:n.dash})}},axisY(){var t,i=this.ctx,e=this.options,a=h(e.padding);if(e.axis.y)for(var s=e.axis.y,o=null!==(t=s&&s.label&&s.label.font)&&void 0!==t?t:e.font,n=this.viewHeight/s.line.count,l=(this.maxY-this.minY)/s.line.count,d=Math.floor(s.line.count/s.label.count),c=0;c2&&void 0!==arguments[2])||arguments[2],r=this.options;this.data&&this.data.length&&(e=this.data[t].data,o&&(r.graphSize?e.length===r.graphSize&&(e=e.slice(1)):e=e.slice(1)),this.data[t].data=e,this.data[t].data.push([a,s]),this.calcMinMax(),this.calcRatio(),this.resize())}},N=function(t){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],{color:e="#000",size:a=1,dash:s=[]}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.save(),t.setLineDash(s),t.lineWidth=a,t.strokeStyle=e,i.map((i=>{var[e,a]=i;t.lineTo(e,a)})),t.stroke(),t.restore(),t.closePath()};class M extends u{constructor(t){if(super(t,arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],o({},v,arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}),"area"),this.coords={},this.minX=0,this.maxX=0,this.minY=0,this.maxY=0,this.legendItems=[],this.options.legend)for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:[],{color:e="#000",fill:a="#000",size:s=1,dash:o=[]}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.save(),t.setLineDash(o),t.lineWidth=s,t.strokeStyle=e,t.fillStyle=a,i.map((i=>{var[e,a]=i;t.lineTo(e,a)})),t.lineTo(i[0][0],i[0][1]),t.fill(),t.restore(),t.closePath()}(s,t,{color:u,fill:p,size:f.size});var x=f.dots?f.dots:{type:"dot"},Y={color:null!==(h=x.color)&&void 0!==h?h:u,fill:null!==(d=x.fill)&&void 0!==d?d:u,radius:null!==(c=x.size)&&void 0!==c?c:4},k=void 0;switch(x.type){case"square":k=l;break;case"triangle":k=w;break;case"diamond":k=X;break;default:k=y}f.dots&&!1!==e.showDots&&t.map((t=>{var[i,e]=t;k(s,[i,e,Y.radius],Y)})),i.coords[f.name]={graph:f,coords:t,drawPointFn:k,opt:Y},t.shift(),t.pop(),!1!==f.showLines&&N(s,t,{color:u,fill:p,size:f.size})},r=0;rv&&rv&&rx&&n2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.save(),t.setLineDash(h),t.lineWidth=l,t.strokeStyle=r,t.fillStyle=n,t.rect(e,a,s,o),t.fill(),t.stroke(),t.restore(),t.closePath()};class L extends u{constructor(t,i,e){super(t,i,o({},T,e),"bar"),this.groups=0,this.barWidth=0,this.maxY=0,this.maxX=0,this.minY=0,this.minX=0,this.viewAxis=this.options.dataAxisX?this.viewHeight:this.viewWidth,this.legendItems=[];var a=this.options.legend;if(a&&a.titles&&a.titles.length)for(var s=0;s0&&void 0!==arguments[0]&&arguments[0],o=this.options,n=h(o.padding),l=this.ctx,d=this.canvas.getBoundingClientRect(),c=!1;if(this.data&&this.data.length){this.proxy.mouse&&(e=this.proxy.mouse.x-d.left,a=this.proxy.mouse.y-d.top),t=s?n.left:n.left+o.groupDistance,i=s?n.top+o.groupDistance:this.viewHeight+n.top;for(var f=0;fY[0]&&ek[0]&&a2&&void 0!==arguments[2])||arguments[2],n=this.options;this.data&&this.data.length&&(e=this.data[t].data,r&&(e=(n.graphSize&&(e.length,n.graphSize),e.slice(1))),this.data[t].data=e,this.data[t].data.push([a,s,o]),this.calcMinMax(),this.calcRatio(),this.resize())}};class B extends u{constructor(t){if(super(t,arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],o({},C,arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}),"histogram"),this.coords={},this.minX=0,this.maxX=0,this.minY=0,this.maxY=0,this.legendItems=[],this.options.legend)for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:[],o({},j,arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}),"line"),this.coords={},this.minX=0,this.maxX=0,this.minY=0,this.maxY=0,this.legendItems=[],this.options.legend)for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:[],{color:e="#000",size:a=1,dash:s=[],tension:o=.25}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.save(),t.setLineDash(s),t.lineWidth=a,t.strokeStyle=e,t.moveTo(i[0][0],i[0][1]);for(var r=0;r{i&&s(i)&&Object.assign(t,i)})),t}({type:"circle"},e.dots,c.dots),x={color:null!==(n=b.color)&&void 0!==n?n:f,fill:null!==(h=b.fill)&&void 0!==h?h:f,radius:null!==(d=b.size)&&void 0!==d?d:2},Y=void 0;switch(b.type){case"square":Y=l;break;case"triangle":Y=w;break;case"diamond":Y=X;break;default:Y=y}c.dots&&!1!==e.showDots&&t.map((t=>{var[i,e]=t;Y(o,[i,e,x.radius],x)})),i.coords[c.name]={graph:c,coords:t,drawPointFn:Y,opt:x}},n=0;nv&&rv&&rx&&n2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.save(),t.setLineDash([]),t.lineWidth=h,t.strokeStyle=n,t.fillStyle=l,t.arc(e,a,s,o,r),t.lineTo(e,a),t.fill(),t.stroke(),t.restore(),t.closePath()};class q extends u{constructor(t,i,e){if(super(t,i,o({},V,e),"pie"),this.total=this.data.reduce(((t,i)=>t+i.data),0),this.legendItems=[],this.options.legend&&this.data.length)for(var a=0;at+i),0))}var[,s]=x(i);this.maxX=this.maxY=t.boundaries&&!isNaN(t.boundaries.max)?t.boundaries.maxY:s,isNaN(this.maxX)&&(this.maxX=100),isNaN(this.maxY)&&(this.maxX=100)}calcRatio(){this.ratio=(this.options.dataAxisX?this.viewWidth:this.viewHeight)/(this.maxY===this.minY?this.maxY:this.maxY-this.minY)}calcBarWidth(){var t=this.options,i=this.data.length,e=(t.dataAxisX?this.viewHeight:this.viewWidth)-(this.data.length+1)*t.groupDistance;// space between groups -this.barWidth=e/i}barsX(){var t,i,e,a,s=this.options,o=h(s.padding),n=this.ctx,l=this.canvas.getBoundingClientRect(),d=!1;if(this.data&&this.data.length){this.proxy.mouse&&(e=this.proxy.mouse.x-l.left,a=this.proxy.mouse.y-l.top),t=o.left,i=o.top+s.groupDistance;var c=Array.isArray(s.colors)?s.colors:s.colors.split(",").map((t=>t.trim()));for(var f of this.data){for(var u=f.data,p=f.name,g=c.length>1?s.color:c[0],m=0,v=0;vt+m&&ei&&at.trim()));for(var f of this.data){for(var u=f.data,p=f.name,g=c.length>1?s.color:c[0],m=0,v=0;vt&&ei-b-m&&a2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.save(),t.setLineDash(d),t.lineWidth=h,t.strokeStyle=n,t.fillStyle=l,t.arc(e,a,s,o,r),t.stroke(),t.restore(),t.closePath()};class U extends u{constructor(t,i,e){super(t,i,o({},J,e),"gauge"),this.resize()}_getFillColor(t,i){for(var e="#fff",a=0,s=0;sa&&t<=o&&(e=i[s][1],a=i[s][0])}return e}gauge(){var t=this.ctx,i=this.options,e=h(i.padding),[a,s]=this.center;a+=e.left,s+=e.top;var o=Math.PI,n=o*i.startFactor,l=o*(2+i.endFactor),d=i.radius*this.radius/100-i.backWidth,c=this.data[0],f=Math.round(Math.abs(100*(c-i.boundaries.min)/(i.boundaries.max-i.boundaries.min))),u=n+(l-n)*f/100,p=f,g=[];if("function"==typeof i.onDrawValue&&(p=i.onDrawValue.apply(null,[c,f])),Q(t,[a,s,d,n,l],{size:i.backWidth,stroke:i.backStyle}),"string"==typeof i.fillStyle)g.push([100,i.fillStyle]);else if(Array.isArray(i.fillStyle))for(var m of i.fillStyle)g.push(m);Q(t,[a,s,d,n,u],{size:i.valueWidth,stroke:this._getFillColor(f,g)}),r(t,p,[0,0],{align:"center",baseLine:"middle",color:i.value.color,stroke:i.value.color,font:i.value.font||i.font,translate:[a+i.value.shift.x,s+i.value.shift.y],angle:i.value.angle}),i.label.min&&r(t,i.boundaries.min,[0,0],{align:"left",baseLine:"middle",color:i.label.min.color,stroke:i.label.min.color,font:i.label.min.font||i.font,translate:[a+d*Math.cos(n)+i.backWidth+i.label.min.shift.x,s+d*Math.sin(n)+i.label.min.shift.y],angle:0}),i.label.max&&r(t,i.boundaries.max,[0,0],{align:"right",baseLine:"middle",color:i.label.max.color,stroke:i.label.max.color,font:i.label.max.font||i.font,translate:[a+d*Math.cos(l)-i.backWidth+i.label.max.shift.x,s+d*Math.sin(l)+i.label.max.shift.y],angle:0})}draw(){super.draw(),this.gauge()}}class $ extends u{constructor(t,i,e){super(t,i,o({},J,e),"gauge"),this.resize()}gauge(){var t=this.ctx,i=this.options,e=h(i.padding),[a,s]=this.center;a+=e.left,s+=e.top;var o=Math.PI,n=o*i.startFactor,l=o*(2+i.endFactor),d=i.radius*this.radius/100-i.backWidth,c=this.data[0],f=Math.abs(100*(c-i.boundaries.min)/(i.boundaries.max-i.boundaries.min)),u=n+(l-n)*f/100,p=f.toFixed(0);"function"==typeof i.onDrawValue&&(p=i.onDrawValue.apply(null,[c,f])),Q(t,[a,s,d,0,2*o],{size:i.backWidth,stroke:i.backStyle}),Q(t,[a,s,d,n,u],{size:i.valueWidth,stroke:i.fillStyle}),r(t,p,[0,0],{align:"center",baseLine:"middle",color:i.value.color,stroke:i.value.color,font:i.value.font||i.font,translate:[a+i.value.shift.x,s+i.value.shift.y],angle:i.value.angle})}draw(){super.draw(),this.gauge(),this.legend()}}globalThis.chart={areaChart:(t,i,e)=>new M(t,i,e),barChart:(t,i,e)=>new L(t,i,e),bubbleChart:(t,i,e)=>new O(t,i,e),histogramChart:(t,i,e)=>new B(t,i,e),lineChart:(t,i,e)=>new F(t,i,e),pieChart:(t,i,e)=>new q(t,i,e),stackedBarChart:(t,i,e)=>new _(t,i,e),gauge:(t,i,e)=>new U(t,i,e),donut:(t,i,e)=>new $(t,i,e)}}(); +axis:g,cross:m,showDots:!0,type:"line"},j="line",G="default";class V extends u{constructor(t){if(super(t,arguments.length>1&&void 0!==arguments[1]?arguments[1]:[],o({},I,arguments.length>2&&void 0!==arguments[2]?arguments[2]:{}),"line"),this.coords={},this.minX=0,this.maxX=0,this.minY=0,this.maxY=0,this.legendItems=[],this.options.legend)for(var i=0;i1&&void 0!==arguments[1]?arguments[1]:[],{color:e="#000",size:a=1,dash:s=[],tension:o=.25}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.save(),t.setLineDash(s),t.lineWidth=a,t.strokeStyle=e,t.moveTo(i[0][0],i[0][1]);for(var r=0;r{i&&s(i)&&Object.assign(t,i)})),t}({type:"circle"},e.dots,c.dots),x={color:null!==(n=b.color)&&void 0!==n?n:f,fill:null!==(h=b.fill)&&void 0!==h?h:f,radius:null!==(d=b.size)&&void 0!==d?d:2},Y=void 0;switch(b.type){case"square":Y=l;break;case"triangle":Y=w;break;case"diamond":Y=X;break;default:Y=y}c.dots&&!1!==e.showDots&&t.map((t=>{var[i,e]=t;Y(o,[i,e,x.radius],x)})),i.coords[c.name]={graph:c,coords:t,drawPointFn:Y,opt:x}},n=0;nv&&rv&&rx&&n2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.save(),t.setLineDash([]),t.lineWidth=h,t.strokeStyle=n,t.fillStyle=l,t.arc(e,a,s,o,r),t.lineTo(e,a),t.fill(),t.stroke(),t.restore(),t.closePath()};class F extends u{constructor(t,i,e){super(t,i,o({},q,e),"pie"),this.total=this.data.reduce(((t,i)=>t+i),0),this.legendItems=[];var a=this.options.legend;if(a&&a.titles&&a.titles.length)for(var s=0;st+i),0))}var[,s]=x(i);this.maxX=this.maxY=t.boundaries&&!isNaN(t.boundaries.max)?t.boundaries.maxY:s,isNaN(this.maxX)&&(this.maxX=100),isNaN(this.maxY)&&(this.maxX=100)}calcRatio(){this.ratio=(this.options.dataAxisX?this.viewWidth:this.viewHeight)/(this.maxY===this.minY?this.maxY:this.maxY-this.minY)}calcBarWidth(){var t=this.options,i=this.data.length,e=(t.dataAxisX?this.viewHeight:this.viewWidth)-(this.data.length+1)*t.groupDistance;// space between groups +this.barWidth=e/i}barsX(){var t,i,e,a,s=this.options,o=h(s.padding),n=this.ctx,l=this.canvas.getBoundingClientRect(),d=!1;if(this.data&&this.data.length){this.proxy.mouse&&(e=this.proxy.mouse.x-l.left,a=this.proxy.mouse.y-l.top),t=o.left,i=o.top+s.groupDistance;var c=Array.isArray(s.colors)?s.colors:s.colors.split(",").map((t=>t.trim()));for(var f of this.data){for(var u=f.data,p=f.name,g=c.length>1?s.color:c[0],m=0,v=0;vt+m&&ei&&at.trim()));for(var f of this.data){for(var u=f.data,p=f.name,g=c.length>1?s.color:c[0],m=0,v=0;vt&&ei-b-m&&a2&&void 0!==arguments[2]?arguments[2]:{};t.beginPath(),t.save(),t.setLineDash(d),t.lineWidth=h,t.strokeStyle=n,t.fillStyle=l,t.arc(e,a,s,o,r),t.stroke(),t.restore(),t.closePath()},$=(t,i)=>{for(var e="#fff",a=0,s=0;s=a&&t<=o&&(e=i[s][1],a=i[s][0])}return e};class _ extends u{constructor(t,i,e){super(t,i,o({},Q,e),"gauge"),this.min=this.options.boundaries.min,this.max=this.options.boundaries.max,this.resize()}gauge(){var t=this.ctx,i=this.options,e=h(i.padding),[a,s]=this.center;a+=e.left,s+=e.top;var o=Math.PI,n=o*i.startFactor,l=o*(2+i.endFactor),d=i.radius*this.radius/100-i.backWidth,c=this.data[0],f=Math.round(Math.abs(100*(c-this.min)/(this.max-this.min))),u=n+(l-n)*f/100,p=f,g=[];if("function"==typeof i.onDrawValue&&(p=i.onDrawValue.apply(null,[c,f])),U(t,[a,s,d,n,l],{size:i.backWidth,stroke:i.backStyle}),"string"==typeof i.fillStyle)g.push([100,i.fillStyle]);else if(Array.isArray(i.fillStyle))for(var m of i.fillStyle)g.push(m);U(t,[a,s,d,n,u],{size:i.valueWidth,stroke:$(f,g)}),r(t,p,[0,0],{align:"center",baseLine:"middle",color:i.value.color,stroke:i.value.color,font:i.value.font||i.font,translate:[a+i.value.shift.x,s+i.value.shift.y],angle:i.value.angle}),i.label.min&&r(t,i.boundaries.min,[0,0],{align:"left",baseLine:"middle",color:i.label.min.color,stroke:i.label.min.color,font:i.label.min.font||i.font,translate:[a+d*Math.cos(n)+i.backWidth+i.label.min.shift.x,s+d*Math.sin(n)+i.label.min.shift.y],angle:0}),i.label.max&&r(t,i.boundaries.max,[0,0],{align:"right",baseLine:"middle",color:i.label.max.color,stroke:i.label.max.color,font:i.label.max.font||i.font,translate:[a+d*Math.cos(l)-i.backWidth+i.label.max.shift.x,s+d*Math.sin(l)+i.label.max.shift.y],angle:0})}draw(){super.draw(),this.gauge()}}var tt={backStyle:"#a7a7a7",fillStyle:"#8f8",backWidth:100,valueWidth:100,radius:100,boundaries:{min:0,max:100},label:{font:i,fixed:!1,color:"#000",angle:0,shift:{x:0,y:0}},padding:0};class it extends u{constructor(t,i,e){super(t,i,o({},tt,e),"donut"),this.total=this.data.reduce(((t,i)=>t+i),0),this.min=this.options.boundaries.min,this.max=this.options.boundaries.max,this.legendItems=[];var a=this.options.legend;if(a&&a.titles&&a.titles.length)for(var s=0;s2&&void 0!==arguments[2]?arguments[2]:{};if("number"==typeof d)d={tl:d,tr:d,br:d,bl:d};else{var c={tl:0,tr:0,br:0,bl:0};for(var f in c)d[f]=d[f]||c[f]}t.beginPath(),t.fillStyle=n,t.strokeStyle=r,t.moveTo(e+d.tl,a),t.lineTo(e+s-d.tr,a),t.quadraticCurveTo(e+s,a,e+s,a+d.tr),t.lineTo(e+s,a+o-d.br),t.quadraticCurveTo(e+s,a+o,e+s-d.br,a+o),t.lineTo(e+d.bl,a+o),t.quadraticCurveTo(e,a+o,e,a+o-d.bl),t.lineTo(e,a+d.tl),t.quadraticCurveTo(e,a,e+d.tl,a),t.fill(),t.stroke(),t.closePath()};class st extends u{constructor(t,i,e){var s=Array.isArray(i)?i:[i],r=o({},a,et,e),n=h(r.padding),{height:l,distance:d,rowDistance:c}=r.segment,f=((l+c)*s.length-c+(n.top+n.bottom))*r.dpi+c;super(t,i,P(P({},r),{},{height:f}),"segment"),this.min=0,this.max=100,this.values=s,this.resize()}segments(){var t,i=this.ctx,e=this.options,a=e.segment,s=a.count?a.count:20,o=a.distance*e.dpi,r=a.rowDistance*e.dpi,n=this.viewWidth/s-o,l=a.height,d=[],c=h(e.padding),f=c.top+o;if("string"==typeof e.colors)d.push([100,e.colors]);else if(Array.isArray(e.colors))for(var u of e.colors)d.push(u);for(var p=0;p1&&void 0!==arguments[1]?arguments[1]:0,e=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];this.values[i]=t,e&&this.resize()}draw(){super.draw(),this.segments()}}globalThis.chart={areaChart:(t,i,e)=>new M(t,i,e),barChart:(t,i,e)=>new L(t,i,e),bubbleChart:(t,i,e)=>new R(t,i,e),histogramChart:(t,i,e)=>new B(t,i,e),lineChart:(t,i,e)=>new V(t,i,e),pieChart:(t,i,e)=>new F(t,i,e),stackedBarChart:(t,i,e)=>new K(t,i,e),gauge:(t,i,e)=>new _(t,i,e),donut:(t,i,e)=>new it(t,i,e),segment:(t,i,e)=>new st(t,i,e)}}(); diff --git a/server/monitor.mjs b/server/monitor.mjs index 693e57b..3d96b16 100644 --- a/server/monitor.mjs +++ b/server/monitor.mjs @@ -39,6 +39,7 @@ const requestListener = async (req, res) => { case '/mem': response = await sysInfo('mem'); break; case '/cpu': response = await sysInfo('cpu'); break; case '/cpu-load': response = await sysInfo('cpu-load'); break; + case '/cpu-load-all': response = await sysInfo('cpu-load-all'); break; case '/consensus': response = await nodeInfo('consensus', config); break; case '/blockchain': response = await nodeInfo('blockchain', config); break; diff --git a/server/system.mjs b/server/system.mjs index 523c6c0..3507525 100644 --- a/server/system.mjs +++ b/server/system.mjs @@ -33,6 +33,26 @@ const getCpuAverage = () => { } } +const getCpuLoadAll = () => { + const startMeasure = os.cpus() + + return new Promise((resolve) => { + setTimeout( () => { + const endMeasure = os.cpus() + const result = [] + + endMeasure.forEach( (cpu, i) => { + let totalDiff = (cpu.times.user + cpu.times.nice + cpu.times.sys + cpu.times.irq + cpu.times.idle) - (startMeasure[i].times.user + startMeasure[i].times.nice + startMeasure[i].times.sys + startMeasure[i].times.irq + startMeasure[i].times.idle) + let idleDiff = cpu.times.idle - startMeasure[i].times.idle + + result.push(100 - ~~(100 * idleDiff / totalDiff)) + }) + + resolve(result) + }, 200) + }) +} + const getCpuLoad = () => { const startMeasure = getCpuAverage() @@ -101,8 +121,8 @@ export const sysInfo = async (obj) => { case 'platform': return getPlatform() case 'time': return getServerTime() case 'cpu-load': return await getCpuLoad() + case 'cpu-load-all': return await getCpuLoadAll() - // case 'cpu-load': return await si.currentLoad() case 'net-stat': return si.networkStats() case 'net-conn': return si.networkConnections() } From e4b754c87ec80e7304368d6294710966e95ef5e0 Mon Sep 17 00:00:00 2001 From: Sergey Pimenov Date: Sun, 23 May 2021 21:32:31 +0300 Subject: [PATCH 06/22] Added cpu threads load chart, Re-disposition RAM and CPU panels content --- CHANGELOG.md | 2 + client/css/index.css | 6 +- client/css/index.less | 8 +- client/index.html | 2 +- package-lock.json | 234 +++++++++++++++++++++++++++++++++++++++++- package.json | 1 + 6 files changed, 243 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce4b08f..430a95b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,6 @@ ### 1.0.2 ++ [x] Added cpu threads load chart ++ [x] Re-disposition RAM and CPU panels content ### 1.0.1 + [x] Added php proxy server diff --git a/client/css/index.css b/client/css/index.css index 0a7362d..aee1b2f 100644 --- a/client/css/index.css +++ b/client/css/index.css @@ -9,16 +9,16 @@ --chart-fill-color: rgba(125, 195, 123, 0.3); } .fg-normal { - color: var(--text-color) !important; + color: var(--text-color); } .fg-stroke { color: var(--chart-stroke-color); } .bd-system { - border-color: var(--border-color) !important; + border-color: var(--border-color); } .bg-system { - background: var(--body-background) !important; + background: var(--body-background); } body { background: var(--body-background); diff --git a/client/css/index.less b/client/css/index.less index 3bee008..0aa8116 100644 --- a/client/css/index.less +++ b/client/css/index.less @@ -10,7 +10,7 @@ } .fg-normal { - color: var(--text-color)!important; + color: var(--text-color); } .fg-stroke { @@ -18,11 +18,11 @@ } .bd-system { - border-color: var(--border-color)!important; + border-color: var(--border-color); } .bg-system { - background: var(--body-background)!important; + background: var(--body-background); } body { @@ -153,4 +153,4 @@ hr { canvas { max-width: 100%; -} \ No newline at end of file +} diff --git a/client/index.html b/client/index.html index cc96ab9..b38c947 100644 --- a/client/index.html +++ b/client/index.html @@ -8,7 +8,7 @@ - +
diff --git a/package-lock.json b/package-lock.json index 4873214..fb86ddb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@olton/mina-monitor", - "version": "1.0.1", + "version": "1.0.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@olton/mina-monitor", - "version": "1.0.1", + "version": "1.0.2", "license": "MIT", "dependencies": { "node-fetch": "^2.6.1", @@ -25,6 +25,7 @@ "eslint": "^7.26.0", "glob": "^7.1.7", "jest": "^26.6.3", + "less": "^4.1.1", "parcel-bundler": "^1.12.5", "rimraf": "^3.0.2" } @@ -4382,6 +4383,15 @@ "safe-buffer": "~5.1.1" } }, + "node_modules/copy-anything": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.3.tgz", + "integrity": "sha512-GK6QUtisv4fNS+XcI7shX0Gx9ORg7QqIznyfho79JTnX1XhLiyZHfftvGiziqzRiEi/Bjhgpi+D2o7HxJFPnDQ==", + "dev": true, + "dependencies": { + "is-what": "^3.12.0" + } + }, "node_modules/copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", @@ -5418,6 +5428,19 @@ "node": ">=4" } }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "optional": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -7772,6 +7795,19 @@ "node": ">= 4" } }, + "node_modules/image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", + "dev": true, + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -8246,6 +8282,12 @@ "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", "dev": true }, + "node_modules/is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true + }, "node_modules/is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -10422,6 +10464,42 @@ "node": ">=6" } }, + "node_modules/less": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/less/-/less-4.1.1.tgz", + "integrity": "sha512-w09o8tZFPThBscl5d0Ggp3RcrKIouBoQscnOMgFH3n5V3kN/CXGHNfCkRPtxJk6nKryDXaV9aHLK55RXuH4sAw==", + "dev": true, + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^1.10.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^2.5.2", + "source-map": "~0.6.0" + } + }, + "node_modules/less/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, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -10939,6 +11017,34 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "node_modules/needle": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz", + "integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==", + "dev": true, + "optional": true, + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "optional": true, + "dependencies": { + "ms": "^2.1.1" + } + }, "node_modules/neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -12325,6 +12431,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", @@ -13564,6 +13679,13 @@ "node": ">= 6" } }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true, + "optional": true + }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -16030,6 +16152,12 @@ "node": ">=6" } }, + "node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, "node_modules/tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", @@ -20811,6 +20939,15 @@ "safe-buffer": "~5.1.1" } }, + "copy-anything": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.3.tgz", + "integrity": "sha512-GK6QUtisv4fNS+XcI7shX0Gx9ORg7QqIznyfho79JTnX1XhLiyZHfftvGiziqzRiEi/Bjhgpi+D2o7HxJFPnDQ==", + "dev": true, + "requires": { + "is-what": "^3.12.0" + } + }, "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", @@ -21643,6 +21780,16 @@ "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", "dev": true }, + "errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "optional": true, + "requires": { + "prr": "~1.0.1" + } + }, "error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -23487,6 +23634,13 @@ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", "dev": true }, + "image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", + "dev": true, + "optional": true + }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -23828,6 +23982,12 @@ "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", "dev": true }, + "is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true + }, "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -25468,6 +25628,33 @@ "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, + "less": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/less/-/less-4.1.1.tgz", + "integrity": "sha512-w09o8tZFPThBscl5d0Ggp3RcrKIouBoQscnOMgFH3n5V3kN/CXGHNfCkRPtxJk6nKryDXaV9aHLK55RXuH4sAw==", + "dev": true, + "requires": { + "copy-anything": "^2.0.1", + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^2.5.2", + "parse-node-version": "^1.0.1", + "source-map": "~0.6.0", + "tslib": "^1.10.0" + }, + "dependencies": { + "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, + "optional": true + } + } + }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -25898,6 +26085,30 @@ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", "dev": true }, + "needle": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.6.0.tgz", + "integrity": "sha512-KKYdza4heMsEfSWD7VPUIz3zX2XDwOyX2d+geb4vrERZMT5RMU6ujjaD+I5Yr54uZxQ2w6XRTAhHBbSCyovZBg==", + "dev": true, + "optional": true, + "requires": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, "neo-async": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", @@ -27009,6 +27220,12 @@ "lines-and-columns": "^1.1.6" } }, + "parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true + }, "parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", @@ -27966,6 +28183,13 @@ "sisteransi": "^1.0.5" } }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true, + "optional": true + }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -29928,6 +30152,12 @@ } } }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", diff --git a/package.json b/package.json index cbac7da..ce62671 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "eslint": "^7.26.0", "glob": "^7.1.7", "jest": "^26.6.3", + "less": "^4.1.1", "parcel-bundler": "^1.12.5", "rimraf": "^3.0.2" }, From f6ce9fc20ab5db0198474f3163749efa521bd70a Mon Sep 17 00:00:00 2001 From: Sergey Pimenov Date: Sun, 23 May 2021 22:11:02 +0300 Subject: [PATCH 07/22] improved styles --- client/index.html | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/index.html b/client/index.html index b38c947..7e53745 100644 --- a/client/index.html +++ b/client/index.html @@ -133,10 +133,10 @@
-
+
-
+
FREE: GiB @@ -150,10 +150,10 @@
-
+
-
+
Load average:
From 5259b106fb0963c90363f6d76de02bd8dc31ebd6 Mon Sep 17 00:00:00 2001 From: Sergey Pimenov Date: Mon, 24 May 2021 11:00:53 +0300 Subject: [PATCH 08/22] optimized cpu loads --- client/js/app.js | 1 - client/js/cpu.js | 73 +++++++++++++++++++++------------------------- server/monitor.mjs | 1 - server/system.mjs | 37 +++++++++-------------- 4 files changed, 47 insertions(+), 65 deletions(-) diff --git a/client/js/app.js b/client/js/app.js index 03f4ebb..15ee391 100644 --- a/client/js/app.js +++ b/client/js/app.js @@ -14,7 +14,6 @@ fetch("./config.json").then( (r) => r.ok ? r.json() : null ).then(config => { setTimeout(() => processSystemInfo(), 0) setTimeout(() => processServerTime(), 0) setTimeout(() => processCPUData(), 0) - setTimeout(() => processCPUDataAll(), 0) setTimeout(() => processMemInfo(), 0) setTimeout(() => processNetInfo(), 0) setTimeout(() => processNetConnections(), 0) diff --git a/client/js/cpu.js b/client/js/cpu.js index 2cd7100..29a2e50 100644 --- a/client/js/cpu.js +++ b/client/js/cpu.js @@ -39,60 +39,53 @@ let cpuGauge = chart.gauge('#cpu-use', [0], { } }) +let cpuSegment + export const processCPUData = async () => { const elLog = $("#log-cpu") elLog.html(imgStop) - let cpu = await getInfo('cpu-load') + let container = $("#cpu-load-all") + let height = 208 + let cpuLoad = await getInfo('cpu-load') - if (cpu) { + if (cpuLoad) { - let {load = 0, user = 0, sys = 0, loadavg = [0, 0, 0]} = cpu + let {load = 0, user = 0, sys = 0, loadavg = [0, 0, 0], threads = []} = cpuLoad cpuChart.addPoint(0, [datetime().time(), load]) cpuGauge.setData([load]) $("#loadavg").html(`${loadavg[0]} ${loadavg[1]} ${loadavg[2]}`) - // console.log("CPU (re)loaded!") + if (!container.children().length) { + cpuSegment = chart.segment("#cpu-load-all", cpuLoad.threads, { + padding: { + top: 0, + bottom: 0, + left: 0, + right: 0 + }, + segment: { + rowDistance: 6, + count: 40, + height: height / (cpuLoad.threads.length) - 6 + }, + border: { + color: "transparent" + }, + ghost: { + color: "rgba(125, 195, 123, .1)" + } + }) + } else { + cpuLoad.threads.forEach( (v, i) => { + cpuSegment.setData(v, i) + }) + } + elLog.html(imgOk) } setTimeout( () => processCPUData(), globalThis.config.intervals.cpu ) } - -let cpuSegment - -export const processCPUDataAll = async () => { - let cpus = await getInfo('cpu-load-all') - let container = $("#cpu-load-all") - let height = 208 - - if (!container.children().length) { - cpuSegment = chart.segment("#cpu-load-all", cpus, { - padding: { - top: 0, - bottom: 0, - left: 0, - right: 0 - }, - segment: { - rowDistance: 6, - count: 40, - height: height / (cpus.length) - 6 - }, - border: { - color: "transparent" - }, - ghost: { - color: "rgba(125, 195, 123, .1)" - } - }) - } else { - cpus.forEach( (v, i) => { - cpuSegment.setData(v, i) - }) - } - - setTimeout( () => processCPUDataAll(), globalThis.config.intervals.cpu ) -} diff --git a/server/monitor.mjs b/server/monitor.mjs index 3d96b16..693e57b 100644 --- a/server/monitor.mjs +++ b/server/monitor.mjs @@ -39,7 +39,6 @@ const requestListener = async (req, res) => { case '/mem': response = await sysInfo('mem'); break; case '/cpu': response = await sysInfo('cpu'); break; case '/cpu-load': response = await sysInfo('cpu-load'); break; - case '/cpu-load-all': response = await sysInfo('cpu-load-all'); break; case '/consensus': response = await nodeInfo('consensus', config); break; case '/blockchain': response = await nodeInfo('blockchain', config); break; diff --git a/server/system.mjs b/server/system.mjs index 3507525..3bdf4bc 100644 --- a/server/system.mjs +++ b/server/system.mjs @@ -29,47 +29,39 @@ const getCpuAverage = () => { sys, user, idle, - total + total, + cpus } } -const getCpuLoadAll = () => { - const startMeasure = os.cpus() - - return new Promise((resolve) => { - setTimeout( () => { - const endMeasure = os.cpus() - const result = [] - - endMeasure.forEach( (cpu, i) => { - let totalDiff = (cpu.times.user + cpu.times.nice + cpu.times.sys + cpu.times.irq + cpu.times.idle) - (startMeasure[i].times.user + startMeasure[i].times.nice + startMeasure[i].times.sys + startMeasure[i].times.irq + startMeasure[i].times.idle) - let idleDiff = cpu.times.idle - startMeasure[i].times.idle - - result.push(100 - ~~(100 * idleDiff / totalDiff)) - }) - - resolve(result) - }, 200) - }) -} - const getCpuLoad = () => { const startMeasure = getCpuAverage() + const startCPU = startMeasure.cpus return new Promise((resolve) => { setTimeout( () => { const endMeasure = getCpuAverage() + const endCPU = endMeasure.cpus + const threads = [] let idleDiff = endMeasure.idle - startMeasure.idle let totalDiff = endMeasure.total - startMeasure.total let userDiff = endMeasure.user - startMeasure.user let sysDiff = endMeasure.sys - startMeasure.sys + endCPU.forEach( (cpu, i) => { + let totalDiff = (cpu.times.user + cpu.times.nice + cpu.times.sys + cpu.times.irq + cpu.times.idle) - (startCPU[i].times.user + startCPU[i].times.nice + startCPU[i].times.sys + startCPU[i].times.irq + startCPU[i].times.idle) + let idleDiff = cpu.times.idle - startCPU[i].times.idle + + threads.push(100 - ~~(100 * idleDiff / totalDiff)) + }) + resolve({ load: 100 - ~~(100 * idleDiff / totalDiff), user: 100 - (100 - ~~(100 * userDiff / totalDiff)), sys: 100 - (100 - ~~(100 * sysDiff / totalDiff)), - loadavg: os.loadavg() + loadavg: os.loadavg(), + threads }) }, 200) }) @@ -121,7 +113,6 @@ export const sysInfo = async (obj) => { case 'platform': return getPlatform() case 'time': return getServerTime() case 'cpu-load': return await getCpuLoad() - case 'cpu-load-all': return await getCpuLoadAll() case 'net-stat': return si.networkStats() case 'net-conn': return si.networkConnections() From 020bda11a767059ac4eaaf6d895b9dd129a4678c Mon Sep 17 00:00:00 2001 From: Sergey Pimenov Date: Mon, 24 May 2021 13:00:52 +0300 Subject: [PATCH 09/22] added dark, light modes support --- client/css/index.css | 195 +++++++++++-- client/css/index.css.map | 2 +- client/css/index.less | 78 ++++-- client/css/light.less | 131 +++++++++ client/index.html | 116 ++++---- client/js/app.js | 10 + client/js/cpu.js | 3 +- client/js/helpers/chart-config.js | 14 +- client/js/helpers/const.js | 4 +- client/js/mem.js | 9 +- client/js/net.js | 9 +- client/vendor/metro4/css/metro-all.css | 2 +- client/vendor/metro4/css/metro-colors.css | 2 +- client/vendor/metro4/css/metro-common.css | 2 +- client/vendor/metro4/css/metro-components.css | 2 +- client/vendor/metro4/css/metro-icons.css | 2 +- client/vendor/metro4/css/metro-reset.css | 2 +- client/vendor/metro4/css/metro.css | 2 +- client/vendor/metro4/css/schemes/darcula.css | 2 +- .../vendor/metro4/css/schemes/red-alert.css | 2 +- client/vendor/metro4/css/schemes/red-dark.css | 2 +- .../metro4/css/schemes/red-mirohost.css | 2 +- client/vendor/metro4/css/schemes/sky-net.css | 2 +- client/vendor/metro4/js/metro.js | 263 ++++++++++++------ client/vendor/metro4/js/metro.min.js | 4 +- client/vendor/metro4/js/metro.min.js.map | 2 +- 26 files changed, 646 insertions(+), 218 deletions(-) create mode 100644 client/css/light.less diff --git a/client/css/index.css b/client/css/index.css index aee1b2f..d0a0b5d 100644 --- a/client/css/index.css +++ b/client/css/index.css @@ -3,16 +3,40 @@ --text-color: #adbaa9; --border-color: #444c56; --panel-background: #22272e; + --accent-color: #fff; --alert-color: #ea0b0b; --warning-color: #ff8330; - --chart-stroke-color: #7dc37b; - --chart-fill-color: rgba(125, 195, 123, 0.3); + --info-color1: #7dc37b; + --info-color2: #1ba1e2; + --info-color3: #ffdb10; + --fill-color: rgba(125, 195, 123, 0.3); } .fg-normal { color: var(--text-color); } +.fg-accent { + color: var(--accent-color); +} +.fg-warning { + color: var(--warning-color); +} +.fg-alert { + color: var(--alert-color); +} .fg-stroke { - color: var(--chart-stroke-color); + color: var(--info-color1); +} +.fg-fill { + color: var(--fill-color); +} +.fg-info1 { + color: var(--info-color1); +} +.fg-info2 { + color: var(--info-color2); +} +.fg-info3 { + color: var(--info-color3); } .bd-system { border-color: var(--border-color); @@ -31,28 +55,30 @@ body { height: 36px; } hr { - background: var(--border-color) !important; + background: var(--border-color); } #max-block { - color: #fff000; + color: var(--info-color3); } #max-unvalidated { - color: #ff0000; + color: var(--alert-color); } #explorer-height { - color: #0b98da; + color: var(--info-color2); } .panel { height: 100%; background: var(--panel-background); color: var(--text-color); - border: 1px solid var(--border-color); + border-color: var(--border-color) !important; + border: 1px solid; padding: 0 10px; } .panel .panel-title { - border-bottom: 1px solid var(--border-color); + border-bottom: 1px solid; + border-color: var(--border-color); text-align: center; - color: darkorange; + color: var(--warning-color); font-size: 12px; font-weight: bold; } @@ -68,16 +94,16 @@ hr { .panel.alert, .panel.warning { background: var(--alert-color); - color: #fff !important; + color: var(--accent-color); } .panel.alert .panel-title, .panel.warning .panel-title { border: none; - color: #fff !important; + color: var(--accent-color); } .panel.alert #node-status, .panel.warning #node-status { - color: #fff !important; + color: var(--accent-color); } .panel.alert #max-block, .panel.warning #max-block, @@ -85,7 +111,7 @@ hr { .panel.warning #max-unvalidated, .panel.alert #explorer-height, .panel.warning #explorer-height { - color: #fff; + color: var(--accent-color); } .panel.warning { background: var(--warning-color); @@ -116,16 +142,18 @@ hr { margin-top: 8px; } .info-table tr:not(:last-child) { - border-bottom: 1px solid var(--border-color); + border-bottom: 1px solid; + border-color: var(--border-color); } .info-table tbody td { padding: 4px 0; } .info-table tbody td:nth-child(2) { - color: #fff; + color: var(--accent-color); } .progress { - border: 1px solid var(--border-color); + border: 1px solid; + border-color: var(--border-color); overflow: visible; } .progress .value { @@ -136,23 +164,150 @@ hr { background: var(--body-background); } .progress-bar { - background: var(--chart-stroke-color) !important; + background: var(--info-color1) !important; } #ip-address, #bind-ip, #p2p-port, #client-port { font-size: 18px; - color: #fff; + color: var(--accent-color); font-weight: 500; line-height: 1.2; } #sidecar-position, #sidecar-uptime, #sidecar-score { - color: #fff000; + color: var(--info-color3); } canvas { max-width: 100%; } +:root { + --body-background-light: #f6f8fa; + --text-color-light: #24292e; + --border-color-light: #e1e4e8; + --panel-background-light: #ffffff; + --accent-color-light: #444c56; + --alert-color-light: #ea0b0b; + --warning-color-light: #ff8330; + --info-color1-light: #7dc37b; + --info-color2-light: #1ba1e2; + --info-color3-light: #ffe725; + --fill-color-light: rgba(125, 195, 123, 0.3); +} +body.light-mode { + background: var(--body-background-light); + color: var(--text-color-light); +} +body.light-mode .fg-normal { + color: var(--text-color-light); +} +body.light-mode .fg-accent { + color: var(--accent-color-light); +} +body.light-mode .fg-warning { + color: var(--warning-color-light); +} +body.light-mode .fg-alert { + color: var(--alert-color-light); +} +body.light-mode .fg-stroke { + color: var(--info-color1-light); +} +body.light-mode .fg-fill { + color: var(--fill-color-light); +} +body.light-mode .fg-info1 { + color: var(--info-color1-light); +} +body.light-mode .fg-info2 { + color: var(--info-color2-light); +} +body.light-mode .fg-info3 { + color: var(--accent-color-light); +} +body.light-mode .bd-system { + border-color: var(--border-color-light); +} +body.light-mode .bg-system { + background: var(--body-background-light); +} +body.light-mode hr { + background: var(--border-color-light); +} +body.light-mode #max-block { + color: var(--accent-color-light); +} +body.light-mode #max-unvalidated { + color: var(--alert-color-light); +} +body.light-mode #explorer-height { + color: var(--info-color2-light); +} +body.light-mode .panel { + background: var(--panel-background-light); + color: var(--text-color-light); + border-color: var(--border-color-light) !important; +} +body.light-mode .panel .panel-title { + border-color: var(--border-color-light); + color: var(--accent-color-light); +} +body.light-mode .panel.alert, +body.light-mode .panel.warning { + background: var(--alert-color-light); + color: #fff; +} +body.light-mode .panel.alert .panel-title, +body.light-mode .panel.warning .panel-title { + color: #fff; +} +body.light-mode .panel.alert #node-status, +body.light-mode .panel.warning #node-status { + color: #fff; +} +body.light-mode .panel.alert #max-block, +body.light-mode .panel.warning #max-block, +body.light-mode .panel.alert #max-unvalidated, +body.light-mode .panel.warning #max-unvalidated, +body.light-mode .panel.alert #explorer-height, +body.light-mode .panel.warning #explorer-height, +body.light-mode .panel.alert .fg-stroke, +body.light-mode .panel.warning .fg-stroke, +body.light-mode .panel.alert .fg-normal, +body.light-mode .panel.warning .fg-normal, +body.light-mode .panel.alert .fg-accent, +body.light-mode .panel.warning .fg-accent { + color: #fff; +} +body.light-mode .panel.warning { + background: var(--warning-color-light); +} +body.light-mode .info-table tr:not(:last-child) { + border-color: var(--border-color-light); +} +body.light-mode .info-table tbody td:nth-child(2) { + color: var(--accent-color-light); +} +body.light-mode .progress { + border-color: var(--border-color-light); +} +body.light-mode .progress-back { + background: var(--body-background-light); +} +body.light-mode .progress-bar { + background: var(--info-color1-light); +} +body.light-mode #ip-address, +body.light-mode #bind-ip, +body.light-mode #p2p-port, +body.light-mode #client-port { + color: var(--accent-color-light); +} +body.light-mode #sidecar-position, +body.light-mode #sidecar-uptime, +body.light-mode #sidecar-score { + color: var(--accent-color-light); +} /*# sourceMappingURL=index.css.map */ \ No newline at end of file diff --git a/client/css/index.css.map b/client/css/index.css.map index 8f45373..461f17f 100644 --- a/client/css/index.css.map +++ b/client/css/index.css.map @@ -1 +1 @@ -{"version":3,"sources":["index.less"],"names":[],"mappings":"AAAA;EACE,0BAAA;EACA,qBAAA;EACA,uBAAA;EACA,2BAAA;EACA,sBAAA;EACA,wBAAA;EACA,6BAAA;EACA,4CAAA;;AAGF;EACE,OAAO,iBAAP;;AAGF;EACE,OAAO,yBAAP;;AAGF;EACE,cAAc,mBAAd;;AAGF;EACE,YAAY,sBAAZ;;AAGF;EACE,YAAY,sBAAZ;EACA,OAAO,iBAAP;;AAGF;EACE,sBAAA;;AAGF;EACE,YAAA;;AAGF;EACE,YAAY,mBAAZ;;AAGF;EAAY,cAAA;;AACZ;EAAkB,cAAA;;AAClB;EAAkB,cAAA;;AAElB;EACE,YAAA;EACA,YAAY,uBAAZ;EACA,OAAO,iBAAP;EACA,kBAAkB,mBAAlB;EACA,eAAA;;AALF,MAOE;EACE,yBAAyB,mBAAzB;EACA,kBAAA;EACA,iBAAA;EACA,eAAA;EACA,iBAAA;;AAZJ,MAeE;EACE,YAAA;EACA,aAAA;EACA,uBAAA;EACA,mBAAA;;AAEA,MANF,eAMI;EACA,WAAA;;AAIJ,MAAC;AAAQ,MAAC;EACR,YAAY,kBAAZ;EACA,WAAA;;AAFF,MAAC,MAIC;AAJO,MAAC,QAIR;EACE,YAAA;EACA,WAAA;;AANJ,MAAC,MAQC;AARO,MAAC,QAQR;EACE,WAAA;;AATJ,MAAC,MAWC;AAXO,MAAC,QAWR;AAXF,MAAC,MAWa;AAXL,MAAC,QAWI;AAXd,MAAC,MAW+B;AAXvB,MAAC,QAWsB;EAC5B,WAAA;;AAGJ,MAAC;EACC,YAAY,oBAAZ;;AAIJ;AAAW;AAAc;AAAe;AAAc;AAAe;AAAc;AAAgB;EACjG,eAAA;EACA,iBAAA;EACA,cAAA;;AAGF;EACE,mBAAA;;AAGF;EACE,eAAA;;AAGF;AAAsB;EACpB,gBAAA;;AAGF;EACE,eAAA;;AADF,WAEE,GAAE,IAAI;EACJ,yBAAyB,mBAAzB;;AAHJ,WAME,MAAM;EACJ,cAAA;;AACA,WAFF,MAAM,GAEH,UAAU;EACT,WAAA;;AAKN;EACE,kBAAkB,mBAAlB;EACA,iBAAA;;AAFF,SAIE;EACE,UAAA;EACA,eAAA;;AAGJ;EACE,YAAY,sBAAZ;;AAEF;EACE,YAAY,yBAAZ;;AAGF;AAAa;AAAU;AAAW;EAChC,eAAA;EACA,WAAA;EACA,gBAAA;EACA,gBAAA;;AAGF;AAAmB;AAAiB;EAClC,cAAA;;AAGF;EACE,eAAA","file":"index.css"} \ No newline at end of file +{"version":3,"sources":["index.less","light.less"],"names":[],"mappings":"AAAA;EACE,0BAAA;EACA,qBAAA;EACA,uBAAA;EACA,2BAAA;EACA,oBAAA;EACA,sBAAA;EACA,wBAAA;EACA,sBAAA;EACA,sBAAA;EACA,sBAAA;EACA,sCAAA;;AAGF;EACE,OAAO,iBAAP;;AAGF;EACE,OAAO,mBAAP;;AAGF;EACE,OAAO,oBAAP;;AAGF;EACE,OAAO,kBAAP;;AAGF;EACE,OAAO,kBAAP;;AAGF;EACE,OAAO,iBAAP;;AAGF;EACE,OAAO,kBAAP;;AAGF;EACE,OAAO,kBAAP;;AAGF;EACE,OAAO,kBAAP;;AAIF;EACE,cAAc,mBAAd;;AAGF;EACE,YAAY,sBAAZ;;AAGF;EACE,YAAY,sBAAZ;EACA,OAAO,iBAAP;;AAGF;EACE,sBAAA;;AAGF;EACE,YAAA;;AAGF;EACE,YAAY,mBAAZ;;AAGF;EAAY,OAAO,kBAAP;;AACZ;EAAkB,OAAO,kBAAP;;AAClB;EAAkB,OAAO,kBAAP;;AAElB;EACE,YAAA;EACA,YAAY,uBAAZ;EACA,OAAO,iBAAP;EACA,cAAc,mBAAd;EACA,iBAAA;EACA,eAAA;;AANF,MAQE;EACE,wBAAA;EACA,cAAc,mBAAd;EACA,kBAAA;EACA,OAAO,oBAAP;EACA,eAAA;EACA,iBAAA;;AAdJ,MAiBE;EACE,YAAA;EACA,aAAA;EACA,uBAAA;EACA,mBAAA;;AAEA,MANF,eAMI;EACA,WAAA;;AAIJ,MAAC;AAAQ,MAAC;EACR,YAAY,kBAAZ;EACA,OAAO,mBAAP;;AAFF,MAAC,MAIC;AAJO,MAAC,QAIR;EACE,YAAA;EACA,OAAO,mBAAP;;AANJ,MAAC,MAQC;AARO,MAAC,QAQR;EACE,OAAO,mBAAP;;AATJ,MAAC,MAWC;AAXO,MAAC,QAWR;AAXF,MAAC,MAWa;AAXL,MAAC,QAWI;AAXd,MAAC,MAW+B;AAXvB,MAAC,QAWsB;EAC5B,OAAO,mBAAP;;AAGJ,MAAC;EACC,YAAY,oBAAZ;;AAIJ;AAAW;AAAc;AAAe;AAAc;AAAe;AAAc;AAAgB;EACjG,eAAA;EACA,iBAAA;EACA,cAAA;;AAGF;EACE,mBAAA;;AAGF;EACE,eAAA;;AAGF;AAAsB;EACpB,gBAAA;;AAGF;EACE,eAAA;;AADF,WAEE,GAAE,IAAI;EACJ,wBAAA;EACA,cAAc,mBAAd;;AAJJ,WAOE,MAAM;EACJ,cAAA;;AACA,WAFF,MAAM,GAEH,UAAU;EACT,OAAO,mBAAP;;AAKN;EACE,iBAAA;EACA,cAAc,mBAAd;EACA,iBAAA;;AAHF,SAKE;EACE,UAAA;EACA,eAAA;;AAGJ;EACE,YAAY,sBAAZ;;AAEF;EACE,YAAY,kBAAZ;;AAGF;AAAa;AAAU;AAAW;EAChC,eAAA;EACA,OAAO,mBAAP;EACA,gBAAA;EACA,gBAAA;;AAGF;AAAmB;AAAiB;EAClC,OAAO,kBAAP;;AAGF;EACE,eAAA;;AC9LF;EACE,gCAAA;EACA,2BAAA;EACA,6BAAA;EACA,iCAAA;EACA,6BAAA;EACA,4BAAA;EACA,8BAAA;EACA,4BAAA;EACA,4BAAA;EACA,4BAAA;EACA,4CAAA;;AAGF,IAAI;EACF,YAAY,4BAAZ;EACA,OAAO,uBAAP;;AAFF,IAAI,WAIF;EACE,OAAO,uBAAP;;AALJ,IAAI,WAQF;EACE,OAAO,yBAAP;;AATJ,IAAI,WAYF;EACE,OAAO,0BAAP;;AAbJ,IAAI,WAgBF;EACE,OAAO,wBAAP;;AAjBJ,IAAI,WAoBF;EACE,OAAO,wBAAP;;AArBJ,IAAI,WAwBF;EACE,OAAO,uBAAP;;AAzBJ,IAAI,WA4BF;EACE,OAAO,wBAAP;;AA7BJ,IAAI,WAgCF;EACE,OAAO,wBAAP;;AAjCJ,IAAI,WAoCF;EACE,OAAO,yBAAP;;AArCJ,IAAI,WAyCF;EACE,cAAc,yBAAd;;AA1CJ,IAAI,WA6CF;EACE,YAAY,4BAAZ;;AA9CJ,IAAI,WAiDF;EACE,YAAY,yBAAZ;;AAlDJ,IAAI,WAqDF;EAAY,OAAO,yBAAP;;AArDd,IAAI,WAsDF;EAAkB,OAAO,wBAAP;;AAtDpB,IAAI,WAuDF;EAAkB,OAAO,wBAAP;;AAvDpB,IAAI,WAyDF;EACE,YAAY,6BAAZ;EACA,OAAO,uBAAP;EACA,cAAc,yBAAd;;AA5DJ,IAAI,WAyDF,OAKE;EACE,cAAc,yBAAd;EACA,OAAO,yBAAP;;AAGF,IAnEA,WAyDF,OAUG;AAAQ,IAnET,WAyDF,OAUY;EACR,YAAY,wBAAZ;EACA,WAAA;;AAFF,IAnEA,WAyDF,OAUG,MAIC;AAJO,IAnET,WAyDF,OAUY,QAIR;EACE,WAAA;;AALJ,IAnEA,WAyDF,OAUG,MAOC;AAPO,IAnET,WAyDF,OAUY,QAOR;EACE,WAAA;;AARJ,IAnEA,WAyDF,OAUG,MAUC;AAVO,IAnET,WAyDF,OAUY,QAUR;AAVF,IAnEA,WAyDF,OAUG,MAUa;AAVL,IAnET,WAyDF,OAUY,QAUI;AAVd,IAnEA,WAyDF,OAUG,MAU+B;AAVvB,IAnET,WAyDF,OAUY,QAUsB;AAVhC,IAnEA,WAyDF,OAUG,MAUiD;AAVzC,IAnET,WAyDF,OAUY,QAUwC;AAVlD,IAnEA,WAyDF,OAUG,MAU6D;AAVrD,IAnET,WAyDF,OAUY,QAUoD;AAV9D,IAnEA,WAyDF,OAUG,MAUyE;AAVjE,IAnET,WAyDF,OAUY,QAUgE;EACtE,WAAA;;AAGJ,IAjFA,WAyDF,OAwBG;EACC,YAAY,0BAAZ;;AAlFN,IAAI,WAsFF,YACE,GAAE,IAAI;EACJ,cAAc,yBAAd;;AAIA,IA5FF,WAsFF,YAKE,MAAM,GACH,UAAU;EACT,OAAO,yBAAP;;AA7FR,IAAI,WAkGF;EACE,cAAc,yBAAd;;AAnGJ,IAAI,WAqGF;EACE,YAAY,4BAAZ;;AAtGJ,IAAI,WAwGF;EACE,YAAY,wBAAZ;;AAzGJ,IAAI,WA4GF;AA5GF,IAAI,WA4GW;AA5Gf,IAAI,WA4GqB;AA5GzB,IAAI,WA4GgC;EAChC,OAAO,yBAAP;;AA7GJ,IAAI,WAgHF;AAhHF,IAAI,WAgHiB;AAhHrB,IAAI,WAgHkC;EAClC,OAAO,yBAAP","file":"index.css"} \ No newline at end of file diff --git a/client/css/index.less b/client/css/index.less index 0aa8116..a673624 100644 --- a/client/css/index.less +++ b/client/css/index.less @@ -3,20 +3,52 @@ --text-color: #adbaa9; --border-color: #444c56; --panel-background: #22272e; + --accent-color: #fff; --alert-color: #ea0b0b; --warning-color: #ff8330; - --chart-stroke-color: #7dc37b; - --chart-fill-color: rgba(125, 195, 123, .3); + --info-color1: #7dc37b; + --info-color2: #1ba1e2; + --info-color3: #ffdb10; + --fill-color: rgba(125, 195, 123, .3); } .fg-normal { color: var(--text-color); } +.fg-accent { + color: var(--accent-color); +} + +.fg-warning { + color: var(--warning-color); +} + +.fg-alert { + color: var(--alert-color); +} + .fg-stroke { - color: var(--chart-stroke-color); + color: var(--info-color1); +} + +.fg-fill { + color: var(--fill-color); } +.fg-info1 { + color: var(--info-color1); +} + +.fg-info2 { + color: var(--info-color2); +} + +.fg-info3 { + color: var(--info-color3); +} + + .bd-system { border-color: var(--border-color); } @@ -39,24 +71,26 @@ body { } hr { - background: var(--border-color)!important; + background: var(--border-color); } -#max-block {color: #fff000;} -#max-unvalidated {color: #ff0000;} -#explorer-height {color: #0b98da;} +#max-block {color: var(--info-color3);} +#max-unvalidated {color: var(--alert-color);} +#explorer-height {color: var(--info-color2);} .panel { height: 100%; background: var(--panel-background); color: var(--text-color); - border: 1px solid var(--border-color); + border-color: var(--border-color)!important; + border: 1px solid; padding: 0 10px; .panel-title { - border-bottom: 1px solid var(--border-color); + border-bottom: 1px solid; + border-color: var(--border-color); text-align: center; - color: darkorange; + color: var(--warning-color); font-size: 12px; font-weight: bold; } @@ -74,17 +108,17 @@ hr { &.alert, &.warning{ background: var(--alert-color); - color: #fff!important; + color: var(--accent-color); .panel-title { border: none; - color: #fff!important; + color: var(--accent-color); } #node-status { - color: #fff!important; + color: var(--accent-color); } #max-block, #max-unvalidated, #explorer-height { - color: #fff; + color: var(--accent-color); } } &.warning{ @@ -113,19 +147,21 @@ hr { .info-table { margin-top: 8px; tr:not(:last-child) { - border-bottom: 1px solid var(--border-color) + border-bottom: 1px solid; + border-color: var(--border-color); } tbody td { padding: 4px 0; &:nth-child(2) { - color: #fff; + color: var(--accent-color); } } } .progress { - border: 1px solid var(--border-color); + border: 1px solid; + border-color: var(--border-color); overflow: visible; .value { @@ -137,20 +173,22 @@ hr { background: var(--body-background); } .progress-bar { - background: var(--chart-stroke-color)!important; + background: var(--info-color1)!important; } #ip-address, #bind-ip, #p2p-port, #client-port { font-size: 18px; - color: #fff; + color: var(--accent-color); font-weight: 500; line-height: 1.2; } #sidecar-position, #sidecar-uptime, #sidecar-score { - color: #fff000; + color: var(--info-color3); } canvas { max-width: 100%; } + +@import "light"; \ No newline at end of file diff --git a/client/css/light.less b/client/css/light.less new file mode 100644 index 0000000..1e53fdb --- /dev/null +++ b/client/css/light.less @@ -0,0 +1,131 @@ +:root { + --body-background-light: #f6f8fa; + --text-color-light: #24292e; + --border-color-light: #e1e4e8; + --panel-background-light: #ffffff; + --accent-color-light: #444c56; + --alert-color-light: #ea0b0b; + --warning-color-light: #ff8330; + --info-color1-light: #7dc37b; + --info-color2-light: #1ba1e2; + --info-color3-light: #ffe725; + --fill-color-light: rgba(125, 195, 123, .3); +} + +body.light-mode { + background: var(--body-background-light); + color: var(--text-color-light); + + .fg-normal { + color: var(--text-color-light); + } + + .fg-accent { + color: var(--accent-color-light); + } + + .fg-warning { + color: var(--warning-color-light); + } + + .fg-alert { + color: var(--alert-color-light); + } + + .fg-stroke { + color: var(--info-color1-light); + } + + .fg-fill { + color: var(--fill-color-light); + } + + .fg-info1 { + color: var(--info-color1-light); + } + + .fg-info2 { + color: var(--info-color2-light); + } + + .fg-info3 { + color: var(--accent-color-light); + } + + + .bd-system { + border-color: var(--border-color-light); + } + + .bg-system { + background: var(--body-background-light); + } + + hr { + background: var(--border-color-light); + } + + #max-block {color: var(--accent-color-light);} + #max-unvalidated {color: var(--alert-color-light);} + #explorer-height {color: var(--info-color2-light);} + + .panel { + background: var(--panel-background-light); + color: var(--text-color-light); + border-color: var(--border-color-light)!important; + + .panel-title { + border-color: var(--border-color-light); + color: var(--accent-color-light); + } + + &.alert, &.warning{ + background: var(--alert-color-light); + color: #fff; + + .panel-title { + color: #fff; + } + #node-status { + color: #fff; + } + #max-block, #max-unvalidated, #explorer-height, .fg-stroke, .fg-normal, .fg-accent { + color: #fff; + } + } + &.warning{ + background: var(--warning-color-light); + } + } + + .info-table { + tr:not(:last-child) { + border-color: var(--border-color-light); + } + + tbody td { + &:nth-child(2) { + color: var(--accent-color-light); + } + } + } + + .progress { + border-color: var(--border-color-light); + } + .progress-back { + background: var(--body-background-light); + } + .progress-bar { + background: var(--info-color1-light); + } + + #ip-address, #bind-ip, #p2p-port, #client-port { + color: var(--accent-color-light); + } + + #sidecar-position, #sidecar-uptime, #sidecar-score { + color: var(--accent-color-light); + } + +} \ No newline at end of file diff --git a/client/index.html b/client/index.html index 7e53745..0f5a096 100644 --- a/client/index.html +++ b/client/index.html @@ -8,38 +8,37 @@ - +
- MINAMONITOR v1.0.2 + MINAMONITOR v1.0.2
-
Next block will be produce at
- Calculating... -
-
calculating...
+
Next block will be produce at
+ Calculating... +
+
calculating...
- - +
- Server time: + Server time:
- Server uptime: + Server uptime:
- +
@@ -50,40 +49,40 @@
-
-
UNKNOWN
-
---.---.---.---
+
+
UNKNOWN
+
---.---.---.---
-
+
UNKNOWN
-
UNKNOWN
+
UNKNOWN
-
+
0
-
- max: 0 - unv: 0 - exp: 0 +
+ max: 0 + unv: 0 + exp: 0
-
+
0
-
- pos: 0 - score: 0 - rate: 0 +
+ pos: 0 + score: 0 + rate: 0
@@ -93,26 +92,27 @@
-
-
0
+
+
0
- liquid: 0 + liquid: + 0
-
-
0
+
+
0
-
-
0
-
time calculating... left
+
+
0
+
time calculating... left
@@ -121,9 +121,9 @@
-
-
0
-
0
+
+
0
+
0
@@ -139,8 +139,8 @@
- FREE: GiB - USED: GiB + FREE: GiB + USED: GiB
@@ -162,9 +162,9 @@
-
+
-
 
+
@@ -176,10 +176,10 @@
-
Network Traffic
+
Network Traffic
- 0 - MB/S + 0 + MB/S
@@ -190,8 +190,8 @@
-
Peers Connected
-
0
+
Peers Connected
+
0
@@ -219,8 +219,8 @@
-
Network Connections
-
0
+
Network Connections
+
0
@@ -231,35 +231,35 @@ - + - + - + - + - + - + - + - +
System info
System time
CPU info
RAM info
NET info
Mina GraphQL
Mina Explorer
Uptime
@@ -275,7 +275,7 @@
-
+
No data
No data
@@ -285,7 +285,7 @@
-
unknown
+
unknown
diff --git a/client/js/app.js b/client/js/app.js index 15ee391..b4c6af8 100644 --- a/client/js/app.js +++ b/client/js/app.js @@ -8,6 +8,14 @@ import {processNodeStatus} from "./node"; import {processConsensus} from "./consensus" import {processUptime} from "./uptime" +const body = $("body") + +if ($.dark) { + body.removeClass("light-mode") +} else { + body.addClass("light-mode") +} + fetch("./config.json").then( (r) => r.ok ? r.json() : null ).then(config => { globalThis.config = config @@ -24,3 +32,5 @@ fetch("./config.json").then( (r) => r.ok ? r.json() : null ).then(config => { }).catch( reason => { // }) + +console.log($.dark) \ No newline at end of file diff --git a/client/js/cpu.js b/client/js/cpu.js index 29a2e50..757adf7 100644 --- a/client/js/cpu.js +++ b/client/js/cpu.js @@ -71,11 +71,12 @@ export const processCPUData = async () => { count: 40, height: height / (cpuLoad.threads.length) - 6 }, + colors: [ [70, '#60a917'], [90, '#f0a30a'], [100, '#a20025'] ], border: { color: "transparent" }, ghost: { - color: "rgba(125, 195, 123, .1)" + color: $.dark ? "rgba(125, 195, 123, .1)" : "#f0f6fc" } }) } else { diff --git a/client/js/helpers/chart-config.js b/client/js/helpers/chart-config.js index 6e1129e..c0ff397 100644 --- a/client/js/helpers/chart-config.js +++ b/client/js/helpers/chart-config.js @@ -5,8 +5,8 @@ export const defaultChartConfig = { top: 25 }, font: { - color: '#fff' - } + color: $.dark ? "#fff" : "#000" + }, }, margin: 0, padding: { @@ -25,11 +25,11 @@ export const defaultChartConfig = { x: { line: { count: 10, - color: '#444c56' + color: $.dark ? '#444c56' : "#f0f6fc" }, label: { count: 3, - color: '#fff', + color: $.dark ? "#fff" : "#000", font: { size: 10 }, @@ -43,11 +43,11 @@ export const defaultChartConfig = { y: { line: { count: 10, - color: '#444c56' + color: $.dark ? '#444c56' : "#f0f6fc" }, label: { fixed: 0, - color: '#fff', + color: $.dark ? "#fff" : "#000", font: { size: 10 } @@ -62,7 +62,7 @@ export const defaultChartConfig = { export const defaultGaugeConfig = { border: false, - backStyle: '#1e2228', + backStyle: $.dark ? '#1e2228' : '#f0f6fc', fillStyle: [ [30, '#00fa9a'], [60, '#60a917'], diff --git a/client/js/helpers/const.js b/client/js/helpers/const.js index bdce8a1..4234121 100644 --- a/client/js/helpers/const.js +++ b/client/js/helpers/const.js @@ -1,2 +1,2 @@ -export const imgOk = "" -export const imgStop = "" \ No newline at end of file +export const imgOk = "" +export const imgStop = "" \ No newline at end of file diff --git a/client/js/mem.js b/client/js/mem.js index f8e8e0d..6f16b09 100644 --- a/client/js/mem.js +++ b/client/js/mem.js @@ -34,16 +34,13 @@ export const processMemInfo = async () => { legend: { position: 'top-left', vertical: true, - background: "#22272e", - font: { - color: "#fff" - }, + background: $.dark ? "#22272e" : "#fff", margin: { - left:24, + left: 32, top: 0 }, border: { - color: "#22272e" + color: $.dark ? "#22272e" : "#fafbfc" }, padding: 5, }, diff --git a/client/js/net.js b/client/js/net.js index a8099b4..6948ed1 100644 --- a/client/js/net.js +++ b/client/js/net.js @@ -19,17 +19,10 @@ let networkChart = chart.areaChart("#net-load", [ legend: { position: 'top-left', vertical: true, - background: "#22272e", - font: { - color: "#fff" - }, margin: { - left:24, + left:32, top: 0 }, - border: { - color: "#22272e" - }, padding: 5 }, padding: { diff --git a/client/vendor/metro4/css/metro-all.css b/client/vendor/metro4/css/metro-all.css index 2e07ee6..674aaa4 100644 --- a/client/vendor/metro4/css/metro-all.css +++ b/client/vendor/metro4/css/metro-all.css @@ -1,7 +1,7 @@ /* * Metro 4 Components Library v4.5.0 (https://metroui.org.ua) * Copyright 2012-2021 Sergey Pimenov - * Built at 08/04/2021 16:25:25 + * Built at 17/05/2021 12:24:52 * Licensed under MIT */ *, diff --git a/client/vendor/metro4/css/metro-colors.css b/client/vendor/metro4/css/metro-colors.css index 4f6fa88..5003fe2 100644 --- a/client/vendor/metro4/css/metro-colors.css +++ b/client/vendor/metro4/css/metro-colors.css @@ -1,7 +1,7 @@ /* * Metro 4 Components Library v4.5.0 (https://metroui.org.ua) * Copyright 2012-2021 Sergey Pimenov - * Built at 08/04/2021 16:25:25 + * Built at 17/05/2021 12:24:52 * Licensed under MIT */ .bg-transparent { diff --git a/client/vendor/metro4/css/metro-common.css b/client/vendor/metro4/css/metro-common.css index cdf254e..85c73cf 100644 --- a/client/vendor/metro4/css/metro-common.css +++ b/client/vendor/metro4/css/metro-common.css @@ -1,7 +1,7 @@ /* * Metro 4 Components Library v4.5.0 (https://metroui.org.ua) * Copyright 2012-2021 Sergey Pimenov - * Built at 08/04/2021 16:25:25 + * Built at 17/05/2021 12:24:52 * Licensed under MIT */ .button.primary, diff --git a/client/vendor/metro4/css/metro-components.css b/client/vendor/metro4/css/metro-components.css index 61c30b2..08d3400 100644 --- a/client/vendor/metro4/css/metro-components.css +++ b/client/vendor/metro4/css/metro-components.css @@ -1,7 +1,7 @@ /* * Metro 4 Components Library v4.5.0 (https://metroui.org.ua) * Copyright 2012-2021 Sergey Pimenov - * Built at 08/04/2021 16:25:25 + * Built at 17/05/2021 12:24:52 * Licensed under MIT */ .accordion { diff --git a/client/vendor/metro4/css/metro-icons.css b/client/vendor/metro4/css/metro-icons.css index b1a8f05..9324bc4 100644 --- a/client/vendor/metro4/css/metro-icons.css +++ b/client/vendor/metro4/css/metro-icons.css @@ -1,7 +1,7 @@ /* * Metro 4 Components Library v4.5.0 (https://metroui.org.ua) * Copyright 2012-2021 Sergey Pimenov - * Built at 08/04/2021 16:25:25 + * Built at 17/05/2021 12:24:52 * Licensed under MIT */ @font-face { diff --git a/client/vendor/metro4/css/metro-reset.css b/client/vendor/metro4/css/metro-reset.css index 2a1a391..7a353ba 100644 --- a/client/vendor/metro4/css/metro-reset.css +++ b/client/vendor/metro4/css/metro-reset.css @@ -1,7 +1,7 @@ /* * Metro 4 Components Library v4.5.0 (https://metroui.org.ua) * Copyright 2012-2021 Sergey Pimenov - * Built at 08/04/2021 16:25:25 + * Built at 17/05/2021 12:24:52 * Licensed under MIT */ *, diff --git a/client/vendor/metro4/css/metro.css b/client/vendor/metro4/css/metro.css index af900f3..5459a2d 100644 --- a/client/vendor/metro4/css/metro.css +++ b/client/vendor/metro4/css/metro.css @@ -1,7 +1,7 @@ /* * Metro 4 Components Library v4.5.0 (https://metroui.org.ua) * Copyright 2012-2021 Sergey Pimenov - * Built at 08/04/2021 16:25:25 + * Built at 17/05/2021 12:24:52 * Licensed under MIT */ *, diff --git a/client/vendor/metro4/css/schemes/darcula.css b/client/vendor/metro4/css/schemes/darcula.css index 62e8747..8433640 100644 --- a/client/vendor/metro4/css/schemes/darcula.css +++ b/client/vendor/metro4/css/schemes/darcula.css @@ -1,7 +1,7 @@ /* * Metro 4 Components Library v4.5.0 (https://metroui.org.ua) * Copyright 2012-2021 Sergey Pimenov - * Built at 08/04/2021 16:25:25 + * Built at 17/05/2021 12:24:52 * Licensed under MIT */ .bg-scheme { diff --git a/client/vendor/metro4/css/schemes/red-alert.css b/client/vendor/metro4/css/schemes/red-alert.css index d86f128..1eb4f93 100644 --- a/client/vendor/metro4/css/schemes/red-alert.css +++ b/client/vendor/metro4/css/schemes/red-alert.css @@ -1,7 +1,7 @@ /* * Metro 4 Components Library v4.5.0 (https://metroui.org.ua) * Copyright 2012-2021 Sergey Pimenov - * Built at 08/04/2021 16:25:25 + * Built at 17/05/2021 12:24:52 * Licensed under MIT */ .bg-scheme { diff --git a/client/vendor/metro4/css/schemes/red-dark.css b/client/vendor/metro4/css/schemes/red-dark.css index 293c4b5..cd40a9c 100644 --- a/client/vendor/metro4/css/schemes/red-dark.css +++ b/client/vendor/metro4/css/schemes/red-dark.css @@ -1,7 +1,7 @@ /* * Metro 4 Components Library v4.5.0 (https://metroui.org.ua) * Copyright 2012-2021 Sergey Pimenov - * Built at 08/04/2021 16:25:25 + * Built at 17/05/2021 12:24:52 * Licensed under MIT */ .bg-scheme { diff --git a/client/vendor/metro4/css/schemes/red-mirohost.css b/client/vendor/metro4/css/schemes/red-mirohost.css index c5eaa59..e7352d1 100644 --- a/client/vendor/metro4/css/schemes/red-mirohost.css +++ b/client/vendor/metro4/css/schemes/red-mirohost.css @@ -1,7 +1,7 @@ /* * Metro 4 Components Library v4.5.0 (https://metroui.org.ua) * Copyright 2012-2021 Sergey Pimenov - * Built at 08/04/2021 16:25:25 + * Built at 17/05/2021 12:24:52 * Licensed under MIT */ .bg-scheme { diff --git a/client/vendor/metro4/css/schemes/sky-net.css b/client/vendor/metro4/css/schemes/sky-net.css index 4953034..821b1ce 100644 --- a/client/vendor/metro4/css/schemes/sky-net.css +++ b/client/vendor/metro4/css/schemes/sky-net.css @@ -1,7 +1,7 @@ /* * Metro 4 Components Library v4.5.0 (https://metroui.org.ua) * Copyright 2012-2021 Sergey Pimenov - * Built at 08/04/2021 16:25:25 + * Built at 17/05/2021 12:24:52 * Licensed under MIT */ .bg-scheme { diff --git a/client/vendor/metro4/js/metro.js b/client/vendor/metro4/js/metro.js index f7dcc7b..3290a3b 100644 --- a/client/vendor/metro4/js/metro.js +++ b/client/vendor/metro4/js/metro.js @@ -1,7 +1,7 @@ /* * Metro 4 Components Library v4.5.0 (https://metroui.org.ua) * Copyright 2012-2021 Sergey Pimenov - * Built at 08/04/2021 16:25:25 + * Built at 17/05/2021 12:24:52 * Licensed under MIT */ /*! @@ -2818,7 +2818,7 @@ // Source: src/func.js /* global dataSet */ -/* exported isTouch, isSimple, isHidden, isPlainObject, isEmptyObject, isArrayLike, str2arr, parseUnit, getUnit, setStyleProp, acceptData, dataAttr, normName, strip, dashedName, isLocalhost */ +/* exported isDark, isTouch, isSimple, isHidden, isPlainObject, isEmptyObject, isArrayLike, str2arr, parseUnit, getUnit, setStyleProp, acceptData, dataAttr, normName, strip, dashedName, isLocalhost */ var numProps = ['opacity', 'zIndex', "order", "zoom"]; @@ -2960,6 +2960,11 @@ function isTouch() { return (('ontouchstart' in window) || (navigator.maxTouchPoints > 0) || (navigator.msMaxTouchPoints > 0)); +} + +function isDark(){ + var prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)") + return prefersDarkScheme.matches } // Source: src/setimmediate.js @@ -3104,7 +3109,7 @@ function isTouch() { /* global hasProp */ -var m4qVersion = "v1.1.0. Built at 27/03/2021 21:47:36"; +var m4qVersion = "v1.1.0. Built at 05/05/2021 22:47:56"; /* eslint-disable-next-line */ var matches = Element.prototype.matches @@ -4042,7 +4047,7 @@ $.fn.extend({ // Source: src/utils.js -/* global $, not, camelCase, dashedName, isPlainObject, isEmptyObject, isArrayLike, acceptData, parseUnit, getUnit, isVisible, isHidden, matches, strip, normName, hasProp, isLocalhost, isTouch */ +/* global $, not, isDark, camelCase, dashedName, isPlainObject, isEmptyObject, isArrayLike, acceptData, parseUnit, getUnit, isVisible, isHidden, matches, strip, normName, hasProp, isLocalhost, isTouch */ $.extend({ @@ -4050,6 +4055,7 @@ $.extend({ localhost: isLocalhost(), isLocalhost: isLocalhost, touchable: isTouch(), + dark: isDark(), uniqueId: function (prefix) { var d = new Date().getTime(); @@ -7191,7 +7197,7 @@ $.noConflict = function() { var Metro = { version: "4.5.0", - compileTime: "08/04/2021 16:25:25", + compileTime: "17/05/2021 12:24:52", buildNumber: "@@build", isTouchable: isTouch, fullScreenEnabled: document.fullscreenEnabled, @@ -7955,6 +7961,10 @@ $.noConflict = function() { "colorSelector": { addUserColorButton: "ADD TO SWATCHES", userColorsTitle: "USER COLORS" + }, + "switch": { + on: "on", + off: "off" } } }); @@ -8009,6 +8019,10 @@ $.noConflict = function() { "colorSelector": { addUserColorButton: "ADD TO SWATCHES", userColorsTitle: "USER COLORS" + }, + "switch": { + on: "on", + off: "off" } } }); @@ -8066,6 +8080,10 @@ $.noConflict = function() { "colorSelector": { addUserColorButton: "ADD TO SWATCHES", userColorsTitle: "USER COLORS" + }, + "switch": { + on: "on", + off: "off" } } }); @@ -8123,6 +8141,10 @@ $.noConflict = function() { "colorSelector": { addUserColorButton: "ADD TO SWATCHES", userColorsTitle: "USER COLORS" + }, + "switch": { + on: "on", + off: "off" } } }); @@ -8180,6 +8202,10 @@ $.noConflict = function() { "colorSelector": { addUserColorButton: "ADD TO SWATCHES", userColorsTitle: "USER COLORS" + }, + "switch": { + on: "on", + off: "off" } } }); @@ -8237,6 +8263,10 @@ $.noConflict = function() { "colorSelector": { addUserColorButton: "Dodaj uzorcima", userColorsTitle: "Korisničke boje" + }, + "switch": { + on: "on", + off: "off" } } }); @@ -8292,6 +8322,10 @@ $.noConflict = function() { "colorSelector": { addUserColorButton: "ADD TO SWATCHES", userColorsTitle: "USER COLORS" + }, + "switch": { + on: "on", + off: "off" } } }); @@ -8349,6 +8383,10 @@ $.noConflict = function() { "colorSelector": { addUserColorButton: "ADD TO SWATCHES", userColorsTitle: "USER COLORS" + }, + "switch": { + on: "on", + off: "off" } } }); @@ -8406,6 +8444,10 @@ $.noConflict = function() { "colorSelector": { addUserColorButton: "ADD TO SWATCHES", userColorsTitle: "USER COLORS" + }, + "switch": { + on: "on", + off: "off" } } }); @@ -8463,6 +8505,10 @@ $.noConflict = function() { "colorSelector": { addUserColorButton: "ДОБАВИТЬ В ОБРАЗЦЫ", userColorsTitle: "ЦВЕТА ПОЛЬЗОВАТЕЛЯ" + }, + "switch": { + on: "вкл", + off: "выкл" } } }); @@ -8520,6 +8566,10 @@ $.noConflict = function() { "colorSelector": { addUserColorButton: "ADD TO SWATCHES", userColorsTitle: "USER COLORS" + }, + "switch": { + on: "on", + off: "off" } } }); @@ -8577,6 +8627,10 @@ $.noConflict = function() { "colorSelector": { addUserColorButton: "ДОДАТИ В ЗРАЗКИ", userColorsTitle: "КОЛІРИ КОРИСТУВАЧА" + }, + "switch": { + on: "увм", + off: "вім" } } }); @@ -8634,6 +8688,10 @@ $.noConflict = function() { "colorSelector": { addUserColorButton: "ADD TO SWATCHES", userColorsTitle: "USER COLORS" + }, + "switch": { + on: "on", + off: "off" } } }); @@ -8691,6 +8749,10 @@ $.noConflict = function() { "colorSelector": { addUserColorButton: "ADD TO SWATCHES", userColorsTitle: "USER COLORS" + }, + "switch": { + on: "on", + off: "off" } } }); @@ -9102,7 +9164,8 @@ $.noConflict = function() { }, arrayDelete: function(arr, val){ - if (arr.indexOf(val) > -1) arr.splice(arr.indexOf(val), 1); + var i = arr.indexOf(val); + if (i > -1) arr.splice(i, 1); }, arrayDeleteByKey: function(arr, key){ @@ -9509,6 +9572,13 @@ $.noConflict = function() { activeFrameClass: "", activeHeadingClass: "", activeContentClass: "", + clsFrame: "", + clsHeading: "", + clsContent: "", + clsAccordion: "", + clsActiveFrame: "", + clsActiveFrameHeading: "", + clsActiveFrameContent: "", onFrameOpen: Metro.noop, onFrameBeforeOpen: Metro.noop_true, onFrameClose: Metro.noop, @@ -9547,7 +9617,19 @@ $.noConflict = function() { var active = element.children(".frame.active"); var frame_to_open; - element.addClass("accordion"); + element + .addClass("accordion") + .addClass(o.clsAccordion) + ; + + frames + .addClass(o.clsFrame) + .each(function(){ + var $el = $(this); + $el.children(".heading").addClass(o.clsHeading); + $el.children(".content").addClass(o.clsContent); + }) + ; if (o.showMarker === true) { element.addClass("marker-on"); @@ -9613,9 +9695,9 @@ $.noConflict = function() { this._closeAll(frame[0]); } - frame.addClass("active " + o.activeFrameClass); - frame.children(".heading").addClass(o.activeHeadingClass); - frame.children(".content").addClass(o.activeContentClass).slideDown(o.duration); + frame.addClass("active " + o.activeFrameClass).addClass(o.clsActiveFrame); + frame.children(".heading").addClass(o.activeHeadingClass).addClass(o.clsActiveFrameHeading); + frame.children(".content").addClass(o.activeContentClass).addClass(o.clsActiveFrameContent).slideDown(o.duration); this._fireEvent("frameOpen", { frame: frame[0] @@ -9634,9 +9716,9 @@ $.noConflict = function() { return ; } - frame.removeClass("active " + o.activeFrameClass); - frame.children(".heading").removeClass(o.activeHeadingClass); - frame.children(".content").removeClass(o.activeContentClass).slideUp(o.duration); + frame.removeClass("active " + o.activeFrameClass).removeClass(o.clsActiveFrame); + frame.children(".heading").removeClass(o.activeHeadingClass).removeClass(o.clsActiveFrameHeading); + frame.children(".content").removeClass(o.activeContentClass).removeClass(o.clsActiveFrameContent).slideUp(o.duration); this._fireEvent("frameClose", { frame: frame[0] @@ -9671,8 +9753,13 @@ $.noConflict = function() { }); }, + open: function(i){ + var frame = this.element.children(".frame").eq(i); + this._openFrame(frame); + }, + /* eslint-disable-next-line */ - changeAttribute: function(attributeName){ + changeAttribute: function(attr, newVal){ }, destroy: function(){ @@ -32224,6 +32311,10 @@ $.noConflict = function() { clsSwitch: "", clsCheck: "", clsCaption: "", + textOn: "", + textOff: "", + locale: METRO_LOCALE, + showOnOff: false, onSwitchCreate: Metro.noop }; @@ -32237,7 +32328,9 @@ $.noConflict = function() { Metro.Component('switch', { init: function( options, elem ) { - this._super(elem, options, SwitchDefaultConfig); + this._super(elem, options, SwitchDefaultConfig, { + locale: null + }); return this; }, @@ -32263,9 +32356,6 @@ $.noConflict = function() { check.appendTo(container); caption.appendTo(container); - if (element.attr("data-on")) check.attr("data-on", element.attr("data-on")); - if (element.attr("data-off")) check.attr("data-off", element.attr("data-off")); - if (o.transition === true) { container.addClass("transition-on"); } @@ -32286,6 +32376,7 @@ $.noConflict = function() { this.enable(); } + this.i18n(o.locale); this._fireEvent("switch-create"); }, @@ -32319,9 +32410,42 @@ $.noConflict = function() { return this; }, - changeAttribute: function(attributeName){ - switch (attributeName) { + changeLocale: function(where, val){ + var element = this.element, o = this.options; + var check = element.siblings(".check"); + + o["text"+Cake.capitalize(where)] = val + + check.attr("data-"+where, val); + }, + + i18n: function(locale){ + var element = this.element, o = this.options; + var check = element.siblings(".check"); + var on, off; + + o.locale = locale; + this.locale = Metro.locales[o.locale] !== undefined ? Metro.locales[o.locale] : Metro.locales["en-US"]; + + if (o.showOnOff) { + on = element.attr("data-on") || o.textOn || this.locale.switch.on; + off = element.attr("data-off") || o.textOff || this.locale.switch.off; + + check.attr("data-on", on); + check.attr("data-off", off); + } else { + check.removeAttr("data-on"); + check.removeAttr("data-off"); + } + }, + + changeAttribute: function(attr, newVal){ + switch (attr) { case 'disabled': this.toggleState(); break; + case 'data-on': + case 'data-text-on': this.changeLocale('on', newVal); break; + case 'data-off': + case 'data-text-off': this.changeLocale('off', newVal); break; } }, @@ -32336,6 +32460,7 @@ $.noConflict = function() { var Utils = Metro.utils; var TableDefaultConfig = { + useCurrentSlice: false, showInspectorButton: false, inspectorButtonIcon: "", tableDeferred: 0, @@ -32515,6 +32640,7 @@ $.noConflict = function() { items: [], foots: [], filteredItems: [], + currentSlice: [], index: {} }); @@ -33377,18 +33503,38 @@ $.noConflict = function() { }); element.on(Metro.events.click, ".table-service-check-all input", function(){ - var status = $(this).is(":checked"); + var checked = $(this).is(":checked"); var store_key = o.checkStoreKey.replace("$1", id); - var data = []; var storage = Metro.storage; + var data, stored_keys; - if (status) { - $.each(that.filteredItems, function(){ - if (data.indexOf(this[o.checkColIndex]) !== -1) return ; - data.push(""+this[o.checkColIndex]); - }); + if (o.useCurrentSlice === true) { + stored_keys = storage.getItem(store_key, []); + + if (checked) { + $.each(that.currentSlice, function(){ + if (stored_keys.indexOf(""+this[o.checkColIndex]) === -1) { + stored_keys.push(""+this[o.checkColIndex]) + } + }); + } else { + $.each(that.currentSlice, function(){ + var key = ""+this[o.checkColIndex]; + if (stored_keys.indexOf(key) !== -1) { + Metro.utils.arrayDelete(stored_keys, key) + } + }); + } + data = stored_keys } else { - data = []; + if (checked) { + $.each(that.filteredItems, function () { + if (data.indexOf(this[o.checkColIndex]) !== -1) return; + data.push("" + this[o.checkColIndex]); + }); + } else { + data = []; + } } storage.setItem(store_key, data); @@ -33397,7 +33543,7 @@ $.noConflict = function() { that._fireEvent("check-click-all", { check: this, - status: status, + status: checked, data: data }); }); @@ -33645,27 +33791,6 @@ $.noConflict = function() { post_data: post_data }); }); - // - // $.post(viewPath, post_data) - // .then(function(data){ - // - // that._fireEvent("view-save", { - // target: "server", - // path: o.viewSavePath, - // view: view, - // post_data: post_data, - // response: data - // }); - // - // }, function(xhr){ - // - // that._fireEvent("data-save-error", { - // source: o.viewSavePath, - // xhr: xhr, - // post_data: post_data - // }); - // - // }); } }, @@ -33783,7 +33908,7 @@ $.noConflict = function() { var i, j, tr, td, check, cells, tds, is_even_row; var start = parseInt(o.rows) === -1 ? 0 : o.rows * (this.currentPage - 1), stop = parseInt(o.rows) === -1 ? this.items.length - 1 : start + o.rows - 1; - var items; + var items, checkedItems = []; var stored_keys = Metro.storage.getItem(o.checkStoreKey.replace("$1", element.attr('id'))); var view = o.staticView ? this.viewDefault : this.view; @@ -33797,6 +33922,9 @@ $.noConflict = function() { items = this._filter(); + this.currentSlice = items.slice(start, stop + 1); + checkedItems = []; + if (items.length > 0) { for (i = start; i <= stop; i++) { cells = items[i]; @@ -33825,6 +33953,7 @@ $.noConflict = function() { if (Utils.isValue(stored_keys) && Array.isArray(stored_keys) && stored_keys.indexOf(""+items[i][o.checkColIndex]) > -1) { check.prop("checked", true); + checkedItems.push(cells) } check.addClass("table-service-check"); @@ -33838,6 +33967,7 @@ $.noConflict = function() { td.addClass(that.service[1].clsColumn); } td.appendTo(tr); + // End of check for (j = 0; j < cells.length; j++){ tds[j] = null; @@ -33908,6 +34038,7 @@ $.noConflict = function() { }); } + $(this.component).find(".table-service-check-all input").prop("checked", checkedItems.length); } else { j = 0; $.each(view, function(){ @@ -33954,7 +34085,7 @@ $.noConflict = function() { switch (format) { case "date": result = formatMask ? Datetime.from(result, formatMask, o.locale) : datetime(result); break; - case "number": result = Number(result); break; + case "number": result = +result; break; case "int": result = parseInt(result); break; case "float": result = parseFloat(result); break; case "money": result = Utils.parseMoney(result); break; @@ -34250,34 +34381,6 @@ $.noConflict = function() { error: error }); }) - // $.json(o.source).then(function(data){ - // that.activity.hide(); - // that.items = []; - // that.heads = []; - // that.foots = []; - // - // that._fireEvent("data-loaded", { - // source: o.source, - // data: data - // }); - // - // if (Array.isArray(o.head)) { - // that.heads = o.head; - // } - // - // if (Array.isArray(o.body)) { - // that.items = o.body; - // } - // - // that._createItemsFromJSON(data); - // that._rebuild(review); - // }, function(xhr){ - // that.activity.hide(); - // that._fireEvent("data-load-error", { - // source: o.source, - // xhr: xhr - // }); - // }); }); } diff --git a/client/vendor/metro4/js/metro.min.js b/client/vendor/metro4/js/metro.min.js index 8a556f8..0e369b6 100644 --- a/client/vendor/metro4/js/metro.min.js +++ b/client/vendor/metro4/js/metro.min.js @@ -1,9 +1,9 @@ /* * Metro 4 Components Library v4.5.0 (https://metroui.org.ua) * Copyright 2012-2021 Sergey Pimenov - * Built at 08/04/2021 16:25:25 + * Built at 17/05/2021 12:24:52 * Licensed under MIT */ -!function(n){"use strict";var h="YYYY-MM-DDTHH:mm:ss.sss",t="Invalid date",p=/\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|m{1,2}|s{1,3}/g;n.DATETIME_LOCALES={en:{months:"January February March April May June July August September October November December".split(" "),monthsShort:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),weekdays:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),weekdaysShort:"Sun Mon Tue Wed Thu Fri Sat".split(" "),weekdaysMin:"Su Mo Tu We Th Fr Sa".split(" "),weekStart:0}};function f(e,t,n){return e=""+e,n&&n<=e.length?e:Array(n+1-e.length).join(t)+e}function i(e){return null==e}var s={ms:"Milliseconds",s:"Seconds",m:"Minutes",h:"Hours",D:"Date",d:"Day",M:"Month",Y:"FullYear",y:"Year",t:"Time"},a="ms",o="second",r="minute",l="hour",c="day",d="week",u="month",m="year",v=function(){var e;return arguments[0]instanceof g?v(arguments[0].value):(e=[].slice.call(Array.isArray(arguments[0])?arguments[0]:arguments),new(Function.prototype.bind.apply(g,[this].concat(e))))},g=function(){var e=[].slice.call(arguments);if(this.value=new(Function.prototype.bind.apply(Date,[this].concat(e))),this.locale="en",this.weekStart=n.DATETIME_LOCALES.en.weekStart,this.utcMode=!1,this.mutable=!0,isNaN(this.value.getTime()))throw new Error(t)};g.DEFAULT_FORMAT=h,g.REGEX_FORMAT=p,g.INVALID_DATE=t,g.lpad=f,g.not=i,g.isDatetime=function(e){return e instanceof g},g.now=function(e){return v()[e?"val":"time"]()},g.locale=function(e,t){n.DATETIME_LOCALES[e]=t},g.getLocale=function(e){return n.DATETIME_LOCALES[e||"en"]||n.DATETIME_LOCALES.en},g.parse=function(e){return v(Date.parse(e))},g.align=function(e,t){var n,i,s=e instanceof g?e:v(e);switch(t){case o:n=s.ms(0);break;case r:n=g.align(s,o)[o](0);break;case l:n=g.align(s,r)[r](0);break;case c:n=g.align(s,l)[l](0);break;case u:n=g.align(s,c)[c](1);break;case m:n=g.align(s,u)[u](0);break;case d:i=s.weekDay(),n=g.align(s,c).addDay(-i);break;default:n=s}return n},g.alignEnd=function(e,t){var n,i,s=e instanceof g?e:v(e);switch(t){case a:n=s.ms(999);break;case o:n=g.alignEnd(s,a);break;case r:n=g.alignEnd(s,o)[o](59);break;case l:n=g.alignEnd(s,r)[r](59);break;case c:n=g.alignEnd(s,l)[l](23);break;case u:n=g.alignEnd(s,c)[c](1).add(1,u).add(-1,c);break;case m:n=g.alignEnd(s,c)[u](11)[c](31);break;case d:i=s.weekDay(),n=g.alignEnd(s,"day").addDay(6-i);break;default:n=s}return n},g.extend=function(e){for(var t,n,i=arguments.length,s=1;s",">=","<=","=","!="].indexOf(n=n||"=")&&(n="="),t=(t||"ms").toLowerCase(),i=e.align(t).time(),s=a.align(t).time(),n){case"<":return i":return s=":return s<=i;case"=":return i===s;case"!=":return i!==s}},between:function(e,t){return this.younger(e)&&this.older(t)},older:function(e,t){return this.compare(e,t,"<")},olderOrEqual:function(e,t){return this.compare(e,t,"<=")},younger:function(e,t){return this.compare(e,t,">")},youngerOrEqual:function(e,t){return this.compare(e,t,">=")},equal:function(e,t){return this.compare(e,t,"=")},notEqual:function(e,t){return this.compare(e,t,"!=")},diff:function(e){var t=datetime(e),e=Math.abs(this.time()-t.time()),t=Math.abs(this.month()-t.month()+12*(this.year()-t.year()));return{ms:e,second:Math.ceil(e/1e3),minute:Math.ceil(e/6e4),hour:Math.ceil(e/36e5),day:Math.ceil(e/864e5),month:t,year:Math.floor(t/12)}},distance:function(e,t){return this.diff(e)[t]}})}(),function(){"use strict";Datetime.use({dayOfYear:function(){var e=this.month(),t=this.day();return[0,31,59,90,120,151,181,212,243,273,304,334][e]+t+(1&"'`]/g,c=/(<([^>]+)>)/gi,d=new RegExp("(?:["+i+"]["+t+"]*)?(?:["+n+"]["+t+"]*)+|(?:["+i+"]["+t+"]*)+(?!["+n+"])|[\\d]+|[\\u2700-\\u27BF]|[^\\x00-\\x2F\\x3A-\\x40\\x5B-\\x60\\x7b-\\xBF\\xD7\\xF7\\u2000-\\u206F"+e+"]+","g"),u=/[A-Z\xC0-\xD6\xD8-\xDE]?[a-z\xDF-\xF6\xF8-\xFF]+|[A-Z\xC0-\xD6\xD8-\xDE]+(?![a-z\xDF-\xF6\xF8-\xFF])|\d+/g,h=new RegExp("^(?:["+n+i+"]["+t+"]*)+$"),p=new RegExp("^((?:["+n+i+"]["+t+"]*)|[\\d])+$"),f=/^[\x01-\xFF]*$/;function m(e,t){return o(e)?t:e}function v(e,t){t=1e.length)&&(t=e.length);for(var n=0,i=new Array(t);n":">","&":"&",'"':""","'":"'","`":"`"};function I(e){return E[e]}var A={"<":/(<)|(�*3c;)|(�*60;)/gi,">":/(>)|(�*3e;)|(�*62;)/gi,"&":/(&)|(�*26;)|(�*38;)/gi,'"':/(")|(�*22;)|(�*34;)/gi,"'":/(�*27;)|(�*39;)/gi,"`":/(�*60;)|(�*96;)/gi},M=Object.keys(A);function D(e,t){return e.replace(A[t],t)}function O(e,t,n){return v(e).substr(t,n)}var P=9007199254740991;function L(e,t,n){n=2>>0).toString(8);break;case"s":n=String(n),n=i.precision?n.substring(0,i.precision):n;break;case"t":n=String(!!n),n=i.precision?n.substring(0,i.precision):n;break;case"T":n=Object.prototype.toString.call(n).slice(8,-1).toLowerCase(),n=i.precision?n.substring(0,i.precision):n;break;case"u":n=parseInt(n,10)>>>0;break;case"v":n=n.valueOf(),n=i.precision?n.substring(0,i.precision):n;break;case"x":n=(parseInt(n,10)>>>0).toString(16);break;case"X":n=(parseInt(n,10)>>>0).toString(16).toUpperCase()}q.json.test(i.type)?d+=n:(!q.number.test(i.type)||o&&!i.sign?r="":(r=o?"+":"-",n=n.toString().replace(q.sign,"")),s=i.pad_char?"0"===i.pad_char?"0":i.pad_char.charAt(1):" ",a=i.width-(r+n).length,a=i.width&&0").concat(v(e),"")},escapeHtml:function(e){return v(e).replace(l,I)},unescapeHtml:function(e){return M.reduce(D,v(e))},unique:function(e,t){return x(w(e,t)).join("")},uniqueWords:function(e,t,n){return x(g(e,t,n)).join("")},substr:O,first:function(e,t){return(e=v(e))?O(e,0,t):""},last:function(e,t){return(e=v(e))?O(e,e.length-t):""},truncate:function(e,t){var n=2]*>/gi,function(e,t){return n.includes(t)?e:""})},stripTagsAll:function(e){return v(e).replace(c,"")},sprintf:Y,vsprintf:function(e,t){return Y.apply(null,[e].concat(t||[]))},includes:function(e,t,n){return v(e).includes(t,n)}},$=null;G=Symbol.toPrimitive,K=Symbol.toStringTag;var X=function(){function s(){var e,t,n,i=0=e.interval)&&(e.fn(),e.lastTime=M())})},this.intervalTicking=!0,n()),this.intervalId},clearInterval:function(e){for(var t=0;t:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i.exec(e))s.push(document.createElement(n[1]));else{i.innerHTML=e;for(var a=0;aA.animation.elements[y].loop?setTimeout(function(){S()},p):_()):"alternate"!==f||w?_():(b="normal"===b?"reverse":"normal",w=!0,S()))}};0
M4Q - "+m4q.version+"
";h.infobox.create(e)},info:function(){console.info("Metro 4 - v"+h.version+". "+h.showCompileTime()),console.info("m4q - "+m4q.version)},showCompileTime:function(){return"Built at: "+h.compileTime},aboutDlg:function(){alert("Metro 4 - v"+h.version+". "+h.showCompileTime())},ver:function(){return h.version},build:function(){return h.build},compile:function(){return h.compileTime},observe:function(){new MutationObserver(function(e){e.map(function(e){var t,n,i,s,a;if("attributes"===e.type&&"data-role"!==e.attributeName)"data-hotkey"===e.attributeName?h.initHotkeys([e.target],!0):(n=(t=u(e.target)).data("metroComponent"),i=e.attributeName,s=t.attr(i),a=e.oldValue,void 0!==n&&(t.fire("attr-change",{attr:i,newValue:s,oldValue:a,__this:t[0]}),u.each(n,function(){var e=h.getPlugin(t,this);e&&"function"==typeof e.changeAttribute&&e.changeAttribute(i,s,a)})));else if("childList"===e.type&&0/gi.test(e)},isEmbedObject:function(e){var t=!1;return o.each(["iframe","object","embed","video"],function(){("string"==typeof e&&e.toLowerCase()===this||void 0!==e.nodeType&&e.tagName.toLowerCase()===this)&&(t=!0)}),t},isVideoUrl:function(e){return/youtu\.be|youtube|twitch|vimeo/gi.test(e)},isDate:function(e,t,n){var i;if(this.isDateObject(e))return!0;try{return i=t?Datetime.from(e,t,n||"en-US"):datetime(e),Datetime.isDatetime(i)}catch(e){return!1}},isDateObject:function(e){return"object"==typeof e&&void 0!==e.getMonth},isInt:function(e){return!isNaN(e)&&+e%1==0},isFloat:function(e){return!isNaN(e)&&+e%1!=0||/^\d*\.\d+$/.test(e)},isFunc:function(e){return this.isType(e,"function")},isObject:function(e){return this.isType(e,"object")},isObject2:function(e){return"object"==typeof e&&!Array.isArray(e)},isType:function(e,t){if(!this.isValue(e))return!1;if(typeof e===t)return e;if("tag"===(""+t).toLowerCase()&&this.isTag(e))return e;if("url"===(""+t).toLowerCase()&&this.isUrl(e))return e;if("array"===(""+t).toLowerCase()&&Array.isArray(e))return e;if(this.isTag(e)||this.isUrl(e))return!1;if(typeof window[e]===t)return window[e];if("string"==typeof e&&-1===e.indexOf("."))return!1;if("string"==typeof e&&/[/\s([]+/gm.test(e))return!1;if("number"==typeof e&&"number"!==t.toLowerCase())return!1;for(var n=e.split("."),i=window,s=0;s
"},elementId:function(e){return e+"-"+(new Date).getTime()+o.random(1,1e3)},secondsToTime:function(e){return{d:Math.floor(e%31536e3/86400),h:Math.floor(e%31536e3%86400/3600),m:Math.floor(e%31536e3%86400%3600/60),s:Math.round(e%31536e3%86400%3600%60)}},secondsToFormattedString:function(e){var t=parseInt(e,10),n=Math.floor(t/3600),e=Math.floor((t-3600*n)/60),t=t-3600*n-60*e;return[Cake.lpad(n,2,"0"),Cake.lpad(e,2,"0"),Cake.lpad(t,2,"0")].join(":")},func:function(e){return new Function("a",e)},exec:function(e,t,n){var i;if(null==e)return!1;var s=this.isFunc(e);!1===s&&(s=this.func(e));try{i=s.apply(n,t)}catch(e){if(!(i=null)===window.METRO_THROWS)throw e}return i},isOutsider:function(e){var t=o(e),e=t.clone();return e.removeAttr("data-role").css({visibility:"hidden",position:"absolute",display:"block"}),t.parent().append(e),t=this.inViewport(e[0]),e.remove(),!t},inViewport:function(e){e=this.rect(e);return 0<=e.top&&0<=e.left&&e.bottom<=(window.innerHeight||document.documentElement.clientHeight)&&e.right<=(window.innerWidth||document.documentElement.clientWidth)},rect:function(e){return e.getBoundingClientRect()},getCursorPosition:function(e,t){e=this.rect(e);return{x:this.pageXY(t).x-e.left-window.pageXOffset,y:this.pageXY(t).y-e.top-window.pageYOffset}},getCursorPositionX:function(e,t){return this.getCursorPosition(e,t).x},getCursorPositionY:function(e,t){return this.getCursorPosition(e,t).y},objectLength:function(e){return Object.keys(e).length},percent:function(e,t,n){if(0===e)return 0;e=100*t/e;return!0===n?Math.round(e):Math.round(100*e)/100},objectShift:function(e){var t=0;return o.each(e,function(e){(0===t||e").addClass("circle").appendTo(n)}();break;case"square":!function(){for(e=0;e<4;e++)s("
").addClass("square").appendTo(n)}();break;case"cycle":s("
").addClass("cycle").appendTo(n);break;case"simple":s('').appendTo(n);break;case"atom":!function(){for(e=0;e<3;e++)s("").addClass("electron").appendTo(n)}();break;case"bars":!function(){for(e=0;e<6;e++)s("").addClass("bar").appendTo(n)}();break;default:!function(){for(e=0;e<5;e++)t=s("
").addClass("wrap").appendTo(n),s("
").addClass("circle").appendTo(t)}()}this._fireEvent("activity-create",{element:n})},changeAttribute:function(e){},destroy:function(){return this.element}}),i.activity={open:function(e){var t=e||{},n='
',e=t.text?'
'+t.text+"
":"";return i.dialog.create({content:n+e,defaultAction:!1,clsContent:"d-flex flex-column flex-justify-center flex-align-center bg-transparent no-shadow w-auto",clsDialog:"no-border no-shadow bg-transparent global-dialog",autoHide:t.autoHide||0,overlayClickClose:!0===t.overlayClickClose,overlayColor:t.overlayColor||"#000000",overlayAlpha:t.overlayAlpha||.5,clsOverlay:"global-overlay"})},close:function(e){i.dialog.close(e)}}}(Metro,m4q),function(e,r){"use strict";var l=e.utils,t={adblockDeferred:0,checkInterval:1e3,fireOnce:!0,checkStop:10,localhost:!1,onAlert:e.noop,onFishingStart:e.noop,onFishingDone:e.noop};e.adblockSetup=function(e){t=r.extend({},t,e)},window.metroAdblockSetup,e.adblockSetup(window.metroAdblockSetup);var c={bite:function(){r("
").addClass("adblock-bite adsense google-adsense dblclick advert topad top_ads topAds textads sponsoredtextlink_container show_ads right-banner rekl mpu module-ad mid_ad mediaget horizontal_ad headerAd contentAd brand-link bottombanner bottom_ad_block block_ad bannertop banner-right banner-body b-banner b-article-aside__banner b-advert adwrapper adverts advertisment advertisement:not(body) advertise advert_list adtable adsense adpic adlist adleft adinfo adi adholder adframe addiv ad_text ad_space ad_right ad_links ad_body ad_block ad_Right adTitle adText".split(" ").shuffle().join(" ")).css({position:"fixed",height:1,width:1,overflow:"hidden",visibility:"visible",top:0,left:0}).append(r("").html("dblclick.net")).appendTo("body"),c.options.adblockDeferred?setTimeout(function(){c.fishing()},c.options.adblockDeferred):this.fishing()},fishing:function(){function e(){function e(){clearInterval(o),l.exec(i.onFishingDone),r(window).fire("fishing-done"),t.remove()}var t=r(".adsense.google-adsense.dblclick.advert.adblock-bite"),n=t.find("a");i.localhost||!r.localhost?!t.length||!n.length||-1").attr("type","button").addClass("hamburger menu-down");for(var s=0;s<3;s++)o("").addClass("line").appendTo(e);"rgba(0, 0, 0, 0)"!==i&&!0!==a.colors.isLight(i)||e.addClass("dark")}t.prepend(e),0===(i=t.find(".app-bar-menu")).length?e.css("display","none"):r.addCssRule(a.sheet,".app-bar-menu li","list-style: none!important;"),"block"===e.css("display")?(i.hide().addClass("collapsed"),e.removeClass("hidden")):e.addClass("hidden"),(!0===n.expand||r.isValue(n.expandPoint)&&r.mediaExist(n.expandPoint))&&(t.addClass("app-bar-expand"),e.addClass("hidden"))},_createEvents:function(){var e=this,t=this.element,n=this.options,i=t.find(".app-bar-menu"),s=t.find(".hamburger");t.on(a.events.click,".hamburger",function(){0!==i.length&&(i.hasClass("collapsed")?e.open():e.close())}),o(window).on(a.events.resize,function(){!0!==n.expand&&(r.isValue(n.expandPoint)&&r.mediaExist(n.expandPoint)?(t.addClass("app-bar-expand"),e._fireEvent("menu-expand")):(t.removeClass("app-bar-expand"),e._fireEvent("menu-collapse"))),0!==i.length&&("block"!==s.css("display")?(i.show(function(){o(this).removeStyleProperty("display")}),s.addClass("hidden")):(s.removeClass("hidden"),s.hasClass("active")?i.show().removeClass("collapsed"):i.hide().addClass("collapsed")))},{ns:this.id})},close:function(){var e=this,t=this.element,n=this.options,i=t.find(".app-bar-menu"),s=t.find(".hamburger");e._fireEvent("before-menu-close",{menu:i[0]}),i.slideUp(n.duration,function(){i.addClass("collapsed").removeClass("opened"),s.removeClass("active"),e._fireEvent("menu-close",{menu:i[0]})})},open:function(){var e=this,t=this.element,n=this.options,i=t.find(".app-bar-menu"),s=t.find(".hamburger");e._fireEvent("before-menu-open",{menu:i[0]}),i.slideDown(n.duration,function(){i.removeClass("collapsed").addClass("opened"),s.addClass("active"),e._fireEvent("menu-open",{menu:i[0]})})},changeAttribute:function(e){},destroy:function(){var e=this.element;return e.off(a.events.click,".hamburger"),o(window).off(a.events.resize,{ns:this.id}),e}})}(Metro,m4q),function(s,t){"use strict";var a=s.utils,n={audioVolume:.5,audioSrc:"",onAudioStart:s.noop,onAudioEnd:s.noop,onAudioButtonCreate:s.noop};s.audioButtonSetup=function(e){n=t.extend({},n,e)},window.metroAudioButtonSetup,s.audioButtonSetup(window.metroAudioButtonSetup),s.Component("audio-button",{init:function(e,t){return this._super(t,e,n,{audio:null,canPlay:null,id:a.elementId("audioButton")}),this},_create:function(){var e=this.element;this._createStructure(),this._createEvents(),this._fireEvent("audioButtonCreate",{element:e})},_createStructure:function(){var e=this.options;this.audio=new Audio(e.audioSrc),this.audio.volume=e.audioVolume},_createEvents:function(){var e=this,t=this.element,n=this.options,i=this.audio;i.addEventListener("loadeddata",function(){e.canPlay=!0}),i.addEventListener("ended",function(){e._fireEvent("audioEnd",{src:n.audioSrc,audio:i})}),t.on(s.events.click,function(){e.play()},{ns:this.id})},play:function(e){var t=this.element,n=this.options,i=this.audio;""!==n.audioSrc&&this.audio.duration&&this.canPlay&&(this._fireEvent("audioStart",{src:n.audioSrc,audio:i}),i.pause(),i.currentTime=0,i.play(),a.exec(e,[i],t[0]))},stop:function(e){var t=this.element,n=this.options,i=this.audio;i.pause(),i.currentTime=0,this._fireEvent("audioEnd",{src:n.audioSrc,audio:i}),a.exec(e,[i],t[0])},changeAttribute:function(e){var t,n,i=this.element,s=this.options,a=this.audio;"data-audio-src"===e&&(t=i.attr("data-audio-src"))&&""!==t.trim()&&(s.audioSrc=t,a.src=t),"data-audio-volume"===e&&(n=parseFloat(i.attr("data-audio-volume")),isNaN(n)||(s.audioVolume=n,a.volume=n))},destroy:function(){this.element.off(s.events.click,{ns:this.id})}}),s.playSound=function(e){var t,n="string"==typeof e?e:e.audioSrc,i=e&&e.audioVolume?e.audioVolume:.5;n&&((t=new Audio(n)).volume=parseFloat(i),t.addEventListener("loadeddata",function(){e&&e.onAudioStart&&a.exec(e.onAudioStart,[n],this),this.play()}),t.addEventListener("ended",function(){e&&e.onAudioEnd&&a.exec(e.onAudioEnd,[null],this)}))}}(Metro,m4q),function(h,p){"use strict";var o=h.utils,n={audioDeferred:0,playlist:null,src:null,volume:.5,loop:!1,autoplay:!1,showLoop:!0,showPlay:!0,showStop:!0,showMute:!0,showFull:!0,showStream:!0,showVolume:!0,showInfo:!0,showPlaylist:!0,showNext:!0,showPrev:!0,showFirst:!0,showLast:!0,showForward:!0,showBackward:!0,showShuffle:!0,showRandom:!0,loopIcon:"",stopIcon:"",playIcon:"",pauseIcon:"",muteIcon:"",volumeLowIcon:"",volumeMediumIcon:"",volumeHighIcon:"",playlistIcon:"",nextIcon:"",prevIcon:"",firstIcon:"",lastIcon:"",forwardIcon:"",backwardIcon:"",shuffleIcon:"",randomIcon:"",onPlay:h.noop,onPause:h.noop,onStop:h.noop,onEnd:h.noop,onMetadata:h.noop,onTime:h.noop,onAudioPlayerCreate:h.noop};h.audioPlayerSetup=function(e){n=p.extend({},n,e)},window.metroAudioPlayerSetup,h.audioPlayerSetup(window.metroAudioPlayerSetup),h.Component("audio-player",{init:function(e,t){return this._super(t,e,n,{preloader:null,player:null,audio:t,stream:null,volume:null,volumeBackup:0,muted:!1}),this},_create:function(){var e=this.element,t=this.options;this._createPlayer(),this._createControls(),this._createEvents(),!0===t.autoplay&&this.play(),this._fireEvent("audio-player-create",{element:e,player:this.player})},_createPlayer:function(){var e=this.element,t=this.options,n=this.audio,i=e.prev(),s=e.parent(),a=p("
").addClass("media-player audio-player "+e[0].className);0===i.length?s.prepend(a):a.insertAfter(i),e.appendTo(a),p.each(["muted","autoplay","controls","height","width","loop","poster","preload"],function(){e.removeAttr(this)}),e.attr("preload","auto"),n.volume=t.volume,null!==t.src&&this._setSource(t.src),e[0].className="",this.player=a},_setSource:function(e){var t=this.element;t.find("source").remove(),t.removeAttr("src"),Array.isArray(e)?p.each(e,function(){void 0!==this.src&&p("").attr("src",this.src).attr("type",void 0!==this.type?this.type:"").appendTo(t)}):t.attr("src",e)},_createControls:function(){var e,t=this,n=this.element,i=this.options,s=this.elem,a=p("
").addClass("controls").addClass(i.clsControls).insertAfter(n),o=p("
").addClass("stream").appendTo(a),r=p("").addClass("stream-slider ultra-thin cycle-marker").appendTo(o),l=p("
").addClass("load-audio").appendTo(o),c=p("
").addClass("volume").appendTo(a),d=p("").addClass("volume-slider ultra-thin cycle-marker").appendTo(c),u=p("
").addClass("info-box").appendTo(a);!0!==i.showInfo&&u.hide(),l.activity({type:"metro",style:"color"}),l.hide(0),this.preloader=l,h.makePlugin(r,"slider",{clsMarker:"bg-red",clsHint:"bg-cyan fg-white",clsComplete:"bg-cyan",hint:!0,onStart:function(){s.paused||s.pause()},onStop:function(e){0").attr("type","button").addClass("button square loop").html(i.loopIcon).appendTo(a)),!0===i.showPlay&&p("").appendTo(n),a[i.view[e]["index-view"]]=n}),t=0;t").addClass("table-inspector");i.attr("for",this.element.attr("id")),w("
"+(n.inspectorTitle||this.locale.table.inspector)+"
").appendTo(i),e=w("
").addClass("table-wrap").appendTo(i),t=w("").addClass("table subcompact"),n=w("").appendTo(t),t.appendTo(e),this._createInspectorItems(n),n=w("
").appendTo(i),w("
").addClass(a.clsHeadRow).appendTo(o),w.each(this.service,function(){var e=[];i=w("").appendTo(n)),s.clear().addClass(i.clsFooter),0!==this.foots.length&&(e=w("").addClass(i.clsHeadRow).appendTo(s),w.each(this.foots,function(){t=w("").addClass(h.clsBodyRow)).data("original",o),l=t%2==0,s=w("").appendTo(m),C=[];if("function"==typeof h.tableToCSV){for(t=y.isValue(t)?t.toLowerCase():"all-filtered",n=y.isValue(n)?n:y.elementId("table")+"-export.csv",l=w(""),o=this.heads,a=0;a"),y.isValue(this.title)&&c.html(this.title),C[p.view[e]["index-view"]]=c)}),a=0;a"),o=r[s],a=0;a").html(this),C[p.view[e]["index-view"]]=c)}),a=0;a").addClass("tabs-material-wrapper").addClass(t.clsComponent).insertBefore(e);!0===t.appBar&&s.addClass("app-bar-present"),"more"===t.appBar&&s.addClass("app-bar-present-more"),e.appendTo(s),e.addClass("tabs-material").addClass(t.clsTabs),n.addClass(t.clsTab),!0===t.deep&&e.addClass("deep"),!0===t.fixedTabs&&e.addClass("fixed-tabs"),this.marker=e.find(".tab-marker"),0===this.marker.length&&(this.marker=d("").addClass("tab-marker").addClass(t.clsMarker).appendTo(e)),this.openTab((0===i.length?n:i)[0])},_createEvents:function(){var s=this,a=this.element,o=this.options;a.on(t.events.click,"li",function(e){var t=d(this),n=a.find("li.active"),i=t.index()>n.index(),n=t.children("a").attr("href");u.isValue(n)&&"#"===n[0]&&(t.hasClass("active")||t.hasClass("disabled")||!1!==u.exec(o.onBeforeTabOpen,[t,n,i],this)&&(s.openTab(t,i),e.preventDefault()))}),a.on(t.events.scroll,function(){var e=s.scroll;s.scrollDir=s.scrolln.index(t);this.openTab(e,t)},changeAttribute:function(){},destroy:function(){var e=this.element;return e.off(t.events.click,"li"),e.off(t.events.scroll),e}})}(Metro,m4q),function(r,l){"use strict";var c=r.utils,n={tabsDeferred:0,expand:!1,expandPoint:null,tabsPosition:"top",tabsType:"default",clsTabs:"",clsTabsList:"",clsTabsListItem:"",clsTabsListItemActive:"",onTab:r.noop,onBeforeTab:r.noop_true,onTabsCreate:r.noop};r.tabsSetup=function(e){n=l.extend({},n,e)},window.metroTabsSetup,r.tabsSetup(window.metroTabsSetup),r.Component("tabs",{init:function(e,t){return this._super(t,e,n,{_targets:[],id:c.elementId("tabs")}),this},_create:function(){var e=this.element,t=0").addClass("tabs tabs-wrapper");if(i.addClass(n.tabsPosition.replace(["-","_","+"]," ")),t.addClass("tabs-list"),"default"!==n.tabsType&&t.addClass("tabs-"+n.tabsType),s||(i.insertBefore(t),t.appendTo(i)),t.data("expanded",!1),s=l("
").addClass("expand-title"),i.prepend(s),0===(e=i.find(".hamburger")).length){e=l("
").appendTo(t),y.isValue(this.title)&&i.html(this.title),y.isValue(this.size)&&i.css({width:this.size}),y.isValue(this.cls)&&e.push(this.cls),e.push(a.clsHeadCell),i.addClass(e.join(" "))}),n=this.heads,e=0;e")).data("index",e),y.isValue(t.title)&&i.html(t.title),y.isValue(t.format)&&i.attr("data-format",t.format),y.isValue(t.name)&&i.attr("data-name",t.name),y.isValue(t.colspan)&&i.attr("colspan",t.colspan),y.isValue(l[e].size)&&i.css({width:l[e].size}),!0===t.sortable&&(n.push("sortable-column"),y.isValue(t.sortDir)&&n.push("sort-"+t.sortDir)),y.isValue(t.cls)&&w.each(t.cls.toArray(),function(){n.push(this)}),!1===y.bool(l[e].show)&&-1===n.indexOf("hidden")&&n.push("hidden"),n.push(a.clsHeadCell),y.bool(l[e].show)&&y.arrayDelete(n,"hidden"),i.addClass(n.join(" ")),r[l[e]["index-view"]]=i}),e=0;e").addClass(this.options.clsBody),0!==t.length?n.insertAfter(t):e.append(n)),n.clear()},_createTableFooter:function(){var e,t,n=this.element,i=this.options,s=n.find("tfoot");0===s.length&&(s=w("
").appendTo(e),void 0!==this.title&&t.html(this.title),void 0!==this.name&&t.addClass("foot-column-name-"+this.name),void 0!==this.cls&&t.addClass(this.cls),y.isValue(this.colspan)&&t.attr("colspan",this.colspan),t.appendTo(e)}))},_createTopBlock:function(){var n,i=this,e=this.element,s=this.options,t=w("
").addClass("table-top").addClass(s.clsTableTop).insertBefore(e.parent()),a=y.isValue(this.wrapperSearch)?this.wrapperSearch:w("
").addClass("table-search-block").addClass(s.clsSearch).appendTo(t);return a.addClass(s.clsSearch),e=w("").attr("type","text").appendTo(a),b.makePlugin(e,"input",{prepend:s.tableSearchTitle||i.locale.table.search}),!0!==s.showSearch&&a.hide(),(a=y.isValue(this.wrapperRows)?this.wrapperRows:w("
").addClass("table-rows-block").appendTo(t)).addClass(s.clsRowsCount),n=w("").addClass("input table-skip-input").addClass(t.clsTableSkipInput).appendTo(e),w("
").html(t+1),void 0!==d.service[0].clsColumn&&s.addClass(d.service[0].clsColumn),s.appendTo(i),s=w(""),a="checkbox"===h.checkType?w(""):w(""),y.isValue(v)&&Array.isArray(v)&&-1");y.isValue(d.heads[e].template)&&(t=d.heads[e].template.replace(/%VAL%/g,t)),n.html(t),n.addClass(h.clsBodyCell),y.isValue(d.heads[e].clsColumn)&&n.addClass(d.heads[e].clsColumn),!1===y.bool(g[e].show)&&n.addClass("hidden"),y.bool(g[e].show)&&n.removeClass("hidden"),n.data("original",this),r[g[e]["index-view"]]=n,d._fireEvent("draw-cell",{td:n,val:t,cellIndex:e,head:d.heads[e],items:o}),!0===h.cellWrapper&&(t=w("
").addClass("data-wrapper").addClass(h.clsCellWrapper).html(n.html()),n.html("").append(t))}),n=0;n").addClass(h.clsBodyRow).appendTo(p),(s=w("
").attr("colspan",n).addClass("text-center").html(w("").addClass(h.clsEmptyTableTitle).html(h.emptyTableTitle||d.locale.table.empty))).appendTo(i);this._info(1+f,1+m,c.length),this._paging(c.length),this.activity&&this.activity.hide(),this._fireEvent("draw"),void 0!==e&&y.exec(e,null,u[0])}else console.warn("Heads is not defined for table ID "+u.attr("id"))},_getItemContent:function(e){var t=this.options,n=e[this.sort.colIndex],i=this.heads[this.sort.colIndex].format,s=y.isNull(this.heads)||y.isNull(this.heads[this.sort.colIndex])||!y.isValue(this.heads[this.sort.colIndex].formatMask)?"%Y-%m-%d":this.heads[this.sort.colIndex].formatMask,a=(this.heads&&this.heads[this.sort.colIndex]&&this.heads[this.sort.colIndex].thousandSeparator?this.heads[this.sort.colIndex]:t).thousandSeparator,e=(this.heads&&this.heads[this.sort.colIndex]&&this.heads[this.sort.colIndex].decimalSeparator?this.heads[this.sort.colIndex]:t).decimalSeparator,o=(""+n).toLowerCase().replace(/[\n\r]+|[\s]{2,}/g," ").trim();if(y.isValue(o)&&y.isValue(i))switch(-1!==["number","int","float","money"].indexOf(i)&&(o=y.parseNumber(o,a,e)),i){case"date":o=s?Datetime.from(o,s,t.locale):datetime(o);break;case"number":o=Number(o);break;case"int":o=parseInt(o);break;case"float":o=parseFloat(o);break;case"money":o=y.parseMoney(o);break;case"card":o=y.parseCard(o);break;case"phone":o=y.parsePhone(o)}return o},addItem:function(e,t){if(!Array.isArray(e))return console.warn("Item is not an array and can't be added"),this;this.items.push(e),!1!==t&&this.draw()},addItems:function(e,t){if(!Array.isArray(e))return console.warn("Items is not an array and can't be added"),this;e.forEach(function(e){Array.isArray(e)&&this.items.push(e,!1)}),this.draw(),!1!==t&&this.draw()},updateItem:function(e,n,t){var i=this.items[this.index[e]],s=null;return y.isNull(i)?(console.warn("Item is undefined for update"),this):(isNaN(n)&&this.heads.forEach(function(e,t){e.name===n&&(s=t)}),y.isNull(s)?console.warn("Item is undefined for update. Field "+n+" not found in data structure"):(i[s]=t,this.items[this.index[e]]=i),this)},getItem:function(e){return this.items[this.index[e]]},deleteItem:function(e,t){for(var n=[],i=y.isFunc(t),s=0;sthis.pagesCount))return this._draw(),this;this.currentPage=this.pagesCount}},prev:function(){if(0!==this.items.length){if(this.currentPage--,0!==this.currentPage)return this._draw(),this;this.currentPage=1}},first:function(){if(0!==this.items.length)return this.currentPage=1,this._draw(),this},last:function(){if(0!==this.items.length)return this.currentPage=this.pagesCount,this._draw(),this},page:function(e){return e<=0&&(e=1),e>this.pagesCount&&(e=this.pagesCount),this.currentPage=e,this._draw(),this},addFilter:function(e,t){var n,i=null,s=y.isFunc(e);if(!1!==s){for(n=0;n").appendTo(m),g=w("