-
-## Installation
-Note: there is also an online version, which can be found at [my-mind.github.io](http://my-mind.github.io/)
-
-* Download the zip by clicking [here](archive/master.zip) and extract the archive, or clone the repository using git
-* Open index.html in your webbrowser
-* Done! If need be, you can find the manual [here](https://github.com/ondras/my-mind/wiki)
-
-## Contributing
-
-Do you want to participate?
-
-* Found a bug? [Open an issue.](https://github.com/ondras/my-mind/issues)
-* Not sure how to do stuff? [Check the docs.](https://github.com/ondras/my-mind/wiki)
-* Have a feature request? [Open an issue.](https://github.com/ondras/my-mind/issues)
-* Have an improvement? [Submit a pull request.](https://github.com/ondras/my-mind/pulls)
-
-## License
-[MIT](LICENSE.txt)
-
-## Links
-
-* [cdnjs](https://nobige.cn/post/20191116-qian_duan_cdn_zheng_li_he_ji/)
-
diff --git a/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/font.css b/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/font.css
deleted file mode 100644
index 53f5d7b6b..000000000
--- a/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/font.css
+++ /dev/null
@@ -1,6 +0,0 @@
-@font-face {
- font-family: source sans pro;
- src: url(data:application/font-woff;charset=utf-8;base64,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) format('woff');
- font-weight: normal;
- font-style: normal;
-}
diff --git a/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/item.css b/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/item.css
deleted file mode 100644
index 0fc1de53d..000000000
--- a/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/item.css
+++ /dev/null
@@ -1,121 +0,0 @@
-.item {
- position: absolute;
-}
-
-.item.cut {
- opacity: 0.5;
-}
-
-.item.collapsed .children {
- display: none;
-}
-
-.content {
- position: relative;
- display: inline-block;
- white-space: nowrap;
- cursor: pointer;
-}
-
-.content > * {
- vertical-align: middle;
-}
-
-.text {
- display: inline-block;
- text-align: center;
- min-width: 0.5em;
- min-height: 1.3em;
- line-height: 1.3em;
- outline: none;
-}
-
-.value, .status {
- margin-right: 0.2em;
-}
-
-.text ~ .value, .text ~ .status {
- margin-left: 0.2em;
- margin-right: 0;
-}
-
-.value {
- opacity: 0.7;
-}
-
-.value:not(:empty):before {
- content: "(";
-}
-
-.value:not(:empty):after {
- content: ")";
-}
-
-.status {
- font-size: 150%;
- line-height: 0.8;
-}
-
-.status.yes:after {
- content: "✔";
- color: #0f0;
-}
-
-.status.no:after {
- content: "✘";
- color: #f00;
-}
-
-canvas {
- position: absolute;
- left: 0;
- top: 0;
-}
-
-.notes-indicator {
- width: 16px;
- height: 100%;
- background: url("../icons/notes-indicator.png") right center no-repeat;
- position: absolute;
- top: -8px;
- right: 0;
- opacity: 0.4;
- display: none;
-}
-
-.notes-indicator-visible {
- display: block;
-}
-
-.toggle {
- position: absolute;
- width: 12px;
- height: 12px;
- line-height: 12px;
- cursor: pointer;
- border-radius: 50%;
- border: 1px solid #00f;
- background-color: #88f;
- text-align: center;
- font-weight: bold;
- font-family: sans-serif;
- color: #fff;
- opacity: 0.7;
-}
-
-.toggle:hover {
- opacity: 1;
-}
-
-.toggle:before {
- content: "−";
-}
-
-.collapsed > .toggle:before {
- content: "+";
-}
-
-:not(.current):not(.collapsed) > .toggle {
- /* NOT display:none - we need to have non-zero dimensions for layouting */
- visibility: hidden;
-}
diff --git a/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/menu.css b/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/menu.css
deleted file mode 100644
index 567aa55d3..000000000
--- a/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/menu.css
+++ /dev/null
@@ -1,33 +0,0 @@
-#menu {
- position: absolute;
- z-index: 1;
- border: 1px solid #666;
- background-color: #fff;
- box-shadow: 0 0 2px 1px #666;
-}
-
-#menu button {
- display: block;
- background-color: transparent;
- border: none;
- margin: 0;
- padding: 3px 6px;
- font-size: 15px;
- width: 130px;
- text-align: left;
-}
-
-#menu button:hover {
- font-weight: bold;
-}
-
-#menu span {
- display: block;
- border-top: 1px solid #666;
- margin-top: 4px;
- padding-top: 4px;
-}
-
-#menu .ui select.fa-select, .ui select.fa-select option {
- font-size: 13px;
-}
diff --git a/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/print.css b/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/print.css
deleted file mode 100644
index 9ddca3512..000000000
--- a/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/print.css
+++ /dev/null
@@ -1,7 +0,0 @@
-.ui, #toggle, #tip {
- display: none;
-}
-
-#port > .item {
- position: static;
-}
diff --git a/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/shape.css b/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/shape.css
deleted file mode 100644
index aa21a84fd..000000000
--- a/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/shape.css
+++ /dev/null
@@ -1,43 +0,0 @@
-.shape-box > .content {
- padding: 0.15em 0.4em;
- background-color: #fff;
- border: 1px solid #666;
- border-radius: 3px;
-}
-
-.shape-ellipse > .content {
- background-color: #fff;
- border: 1px solid #666;
- border-radius: 50%;
- padding: 0.5em 1em;
-}
-
-/* current */
-
-.current > .content {
- background-color: rgba(255, 255, 187, 0.9);
-}
-
-/* root */
-
-#port > .item > .content {
- font-weight: bold;
- border-width: 2px;
- font-size: 140%;
-}
-
-#port > .item > .toggle {
- display: none;
-}
-
-/* 1st children */
-
-#port > .item > .children > .item > .content {
- border-width: 2px;
- font-size: 120%;
-}
-
-.item .icon {
- margin: 0 0.5em 0 0;
- font-size: x-large;
-}
diff --git a/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/style.css b/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/style.css
deleted file mode 100644
index a5a32854c..000000000
--- a/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/style.css
+++ /dev/null
@@ -1,73 +0,0 @@
-@import url(ui.css);
-@import url(item.css);
-@import url(shape.css);
-@import url(menu.css);
-
-* {
- font-family: source sans pro, sans-serif;
-}
-
-html, body {
- margin: 0;
- overflow: hidden;
- height: 100%;
- background-color: #eed;
- -webkit-user-select: none; /* no magnifier on hold */
-}
-
-[contenteditable] { /* allow for editable items */
- -webkit-user-select: auto;
-}
-
-ul {
- margin: 0;
- padding: 0;
- list-style: none;
-}
-
-#port {
- overflow: hidden;
- font-size: 15px;
-}
-
-#throbber {
- position: absolute;
- top: 50px;
- left: -60px;
- width: 50px;
- height: 50px;
- background-image: url(throbber.gif);
-}
-
-#throbber:not(.visible) {
- opacity: 0;
-}
-
-.ghost {
- position: absolute !important; /* to prevent collision with .content */
- opacity: 0.5;
- z-index: 1;
-}
-
-#tip {
- position: fixed;
- z-index: 1;
- left: 10px;
- bottom: 5px;
- transition: all 500ms;
- font-size: 1rem; /* do not scale with map zoom */
-}
-
-#tip:before {
- content: "Tip: ";
-}
-
-#tip code {
- padding: 0 4px;
- border-radius: 4px;
- background-color: rgba(0, 0, 0, 0.1);
-}
-
-#tip.hidden {
- opacity: 0;
-}
diff --git a/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/throbber.gif b/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/throbber.gif
deleted file mode 100644
index ac8353239..000000000
Binary files a/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/throbber.gif and /dev/null differ
diff --git a/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/ui.css b/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/ui.css
deleted file mode 100644
index fb447ebe5..000000000
--- a/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/css/ui.css
+++ /dev/null
@@ -1,226 +0,0 @@
-button:not(:disabled) {
- cursor: pointer;
-}
-
-.ui {
- position: fixed;
- right: 0;
- top: 0;
- height: 100%;
- background-color: #fff;
- width: 200px;
- max-width: 600px;
- box-shadow: 0 0 2px 2px #666;
- -webkit-transition: -webkit-transform 500ms;
- transition: transform 500ms;
-}
-
-.ui:not(.visible) {
- -webkit-transform: translate(100%, 0);
- transform: translate(100%, 0);
-}
-
-.ui h3 {
- background-color: #34495e;
- color: #fff;
- padding: 0.2em 0;
- margin: 0;
- text-transform: capitalize;
- text-align: center;
-}
-
-.ui select, .ui input {
- background-color: transparent;
- border: 1px solid rgba(50, 70, 90, 0.5);
- font-size: 13px;
- border-radius: 4px;
- padding: 4px;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- -webkit-font-smoothing: subpixel-antialiased;
- transition: all 250ms linear;
-}
-
-.ui select:hover, .ui input:hover, .ui select:focus, .ui input:focus {
- border-color: rgba(50, 70, 90, 1);
-}
-
-.ui select, .ui input, .ui #color {
- width: 168px;
-}
-
-.ui .go {
- font-weight: bold;
-}
-
-.ui p {
- margin: 8px 16px;
-}
-
-.ui p.desc {
- font-size: 13px;
-}
-
-.ui:not([id]) button {
- border: none;
- padding: 0;
- margin: 0 4px;
- background-color: transparent;
- width: 32px;
-}
-
-.ui button:first-child {
- margin-left: 0 !important;
-}
-
-.ui button:last-child {
- margin-right: 0 !important;
-}
-
-.ui button[data-command=Help] {
- position: absolute;
- left: -50px;
- top: 5px;
-}
-
-.ui button[data-command=Notes] {
- position: absolute;
- left: -90px;
- top: 5px;
-}
-
-.ui table {
- width: 100%;
- border-collapse: collapse;
-}
-
-.ui table td:first-child {
- padding-left: 16px;
-}
-
-.ui table td:last-child {
- text-align: right;
- padding-right: 16px;
-}
-
-.ui span {
- text-transform: uppercase;
- font-size: 80%;
-}
-
-.ui #color {
- display: block;
-}
-
-.ui #color::after {
- clear: both;
- content: "";
- display: block;
-}
-
-.ui [data-color] {
- display: block;
- float: left;
- width: 14px;
- height: 14px;
- border-radius: 3px;
- margin-right: 2px;
- border: 1px solid transparent;
-}
-
-.ui [data-color]:hover, .ui [data-color]:first-child {
- border-color: #000;
-}
-
-#notes {
- width: 50%;
-}
-
-#notes-editor {
- border: 0;
- width: 100%;
- height: 100%;
-}
-
-.pell-content {
- height: calc(100% - 60px);
-}
-
-.ui #github {
- position: absolute;
- right: 8px;
- bottom: 6px;
-}
-
-.ui #github img {
- vertical-align: middle;
-}
-
-.ui #privacy {
- position: absolute;
- left: 8px;
- bottom: 6px;
-}
-
-.ui #toggle {
- z-index: 999;
- position: absolute;
- left: -23px;
- top: 48%;
- width: 35px;
- height: 35px;
- padding: 0 0 0 2px;
- text-align: left;
-
- border: none;
- background-color: #fff;
- box-shadow: -3px 0 2px 0px #666;
-
- line-height: 8px;
- border-radius: 50%;
-}
-
-.ui #toggle:after {
- content: "←";
- font-weight: bold;
- font-size: 22px;
-}
-
-.ui.visible #toggle:after {
- content: "→";
-}
-
-.ui#help {
- overflow-y: auto;
- right: auto;
- left: 0;
- background-color: rgba(255, 255, 255, 0.7);
- width: 250px;
-}
-
-.ui#help:not(.visible) {
- -webkit-transform: translate(-100%, 0);
- transform: translate(-100%, 0);
-}
-
-.ui#help table {
- font-size: 80%;
-}
-
-.ui#io button {
- width: 45%;
-}
-
-.ui#io button:nth-child(odd) {
- float: left;
-}
-
-.ui#io button:nth-child(even) {
- float: right;
-}
-
-.ui select.fa-select ,
-.ui select.fa-select option {
- font-family: fontAwesome;
- font-size: x-large;
-}
diff --git a/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/editor.html b/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/editor.html
deleted file mode 100644
index 9aa37bf28..000000000
--- a/openwrt-app-actions/applications/luci-app-mymind/root/www/luci-static/mymind/editor.html
+++ /dev/null
@@ -1,91 +0,0 @@
-
-
-
-
-
- :screenshot --selector .item in Firefox Console to save the Map as an image! For more tips/news, follow @my_mind_app.- - - - -
- -- Layout - -
-- Shape - -
-- Value - -
-- Status - -
-- Color - - - - - - - - - - - -
- -- Icons - -
- -
- Privacy policy
-
-
-
-
-
- - Storage - -
- -Local files are suitable for loading/saving files from other mindmapping applications.
-- Format - -
-- -
-Export your design as a PNG image.
-- -
-Your browser's localStorage can handle many mind maps and creates a permalink, but this URL cannot be shared.
-- Saved maps - -
-- -
-- -
-Firebase offers real-time synchronization for true multi-user collaboration.
-- Server - -
-- Auth - -
-- Saved maps - -
-- -
-- -
-Use this to access a generic DAV-like REST API.
-- URL - -
-- -
-Maps stored in Google Drive have a permalink URL and can be shared with other users, if you allow this by setting proper permissions (inside Google Drive itself).
-- Format - -
-- -
-Navigation
-Manipulation
-Editing
-Other
-")}},quote:{icon:"“ ”",title:"Quote",result:function(){return f(l,"
")}},olist:{icon:"#",title:"Ordered List",result:function(){return f("insertOrderedList")}},ulist:{icon:"•",title:"Unordered List",result:function(){return f("insertUnorderedList")}},code:{icon:"</>",title:"Code",result:function(){return f(l,"")}},line:{icon:"―",title:"Horizontal Line",result:function(){return f("insertHorizontalRule")}},link:{icon:"🔗",title:"Link",result:function(){var t=window.prompt("Enter the link URL");t&&f("createLink",t)}},image:{icon:"📷",title:"Image",result:function(){var t=window.prompt("Enter the image URL");t&&f("insertImage",t)}}},m={actionbar:"pell-actionbar",button:"pell-button",content:"pell-content",selected:"pell-button-selected"},r=function(n){var t=n.actions?n.actions.map(function(t){return"string"==typeof t?p[t]:p[t.name]?e({},p[t.name],t):t}):Object.keys(p).map(function(t){return p[t]}),r=e({},m,n.classes),i=n[c]||"div",o=d("div");o.className=r.actionbar,s(n.element,o);var u=n.element.content=d("div");return u.contentEditable=!0,u.className=r.content,u.oninput=function(t){var e=t.target.firstChild;e&&3===e.nodeType?f(l,"<"+i+">"):"
"===u.innerHTML&&(u.innerHTML=""),n.onChange(u.innerHTML)},u.onkeydown=function(t){var e;"Enter"===t.key&&"blockquote"===(e=l,document.queryCommandValue(e))&&setTimeout(function(){return f(l,"<"+i+">")},0)},s(n.element,u),t.forEach(function(t){var e=d("button");if(e.className=r.button,e.innerHTML=t.icon,e.title=t.title,e.setAttribute("type","button"),e.onclick=function(){return t.result()&&u.focus()},t.state){var n=function(){return e.classList[t.state()?"add":"remove"](r.selected)};a(u,"keyup",n),a(u,"mouseup",n),a(e,"click",n)}s(o,e)}),n.styleWithCSS&&f("styleWithCSS"),f(c,i),n.element},i={exec:f,init:r};t.exec=f,t.init=r,t.default=i,Object.defineProperty(t,"__esModule",{value:!0})});
diff --git a/openwrt-app-actions/applications/luci-app-nastools/Makefile b/openwrt-app-actions/applications/luci-app-nastools/Makefile
deleted file mode 100644
index 2c51c4086..000000000
--- a/openwrt-app-actions/applications/luci-app-nastools/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-include $(TOPDIR)/rules.mk
-
-PKG_VERSION:=1.1.2-20230108
-PKG_RELEASE:=
-
-LUCI_TITLE:=LuCI support for nastools
-LUCI_PKGARCH:=all
-LUCI_DEPENDS:=+docker +luci-lib-taskd
-
-define Package/luci-app-nastools/conffiles
-/etc/config/nastools
-endef
-
-include $(TOPDIR)/feeds/luci/luci.mk
-
-# call BuildPackage - OpenWrt buildroot signature
diff --git a/openwrt-app-actions/applications/luci-app-nastools/luasrc/controller/nastools.lua b/openwrt-app-actions/applications/luci-app-nastools/luasrc/controller/nastools.lua
deleted file mode 100755
index 9fe474450..000000000
--- a/openwrt-app-actions/applications/luci-app-nastools/luasrc/controller/nastools.lua
+++ /dev/null
@@ -1,7 +0,0 @@
-
-module("luci.controller.nastools", package.seeall)
-
-function index()
- entry({"admin", "services", "nastools"}, alias("admin", "services", "nastools", "config"), _("NasTools"), 30).dependent = true
- entry({"admin", "services", "nastools", "config"}, cbi("nastools"))
-end
diff --git a/openwrt-app-actions/applications/luci-app-nastools/luasrc/model/cbi/nastools.lua b/openwrt-app-actions/applications/luci-app-nastools/luasrc/model/cbi/nastools.lua
deleted file mode 100644
index c8e88da74..000000000
--- a/openwrt-app-actions/applications/luci-app-nastools/luasrc/model/cbi/nastools.lua
+++ /dev/null
@@ -1,43 +0,0 @@
---[[
-LuCI - Lua Configuration Interface
-]]--
-
-local taskd = require "luci.model.tasks"
-local nastools_model = require "luci.model.nastools"
-local m, s, o
-
-m = taskd.docker_map("nastools", "nastools", "/usr/libexec/istorec/nastools.sh",
- translate("NasTools"),
- translate("NasTools is a tools for resource aggregation running in NAS.")
- .. translate("Official website:") .. ' https://github.com/jxxghp/nas-tools')
-
-s = m:section(SimpleSection, translate("Service Status"), translate("NasTools status:"))
-s:append(Template("nastools/status"))
-
-s = m:section(TypedSection, "nastools", translate("Setup"), translate("The following parameters will only take effect during installation or upgrade:"))
-s.addremove=false
-s.anonymous=true
-
-o = s:option(Value, "http_port", translate("Port").."*")
-o.rmempty = false
-o.default = "3003"
-o.datatype = "port"
-
-local blocks = nastools_model.blocks()
-local home = nastools_model.home()
-
-o = s:option(Value, "config_path", translate("Config path").."*")
-o.rmempty = false
-o.datatype = "string"
-
-local paths, default_path = nastools_model.find_paths(blocks, home, "Configs")
-for _, val in pairs(paths) do
- o:value(val, val)
-end
-o.default = default_path
-
-o = s:option(Flag, "auto_upgrade", translate("Auto update"))
-o.default = 1
-o.rmempty = false
-
-return m
diff --git a/openwrt-app-actions/applications/luci-app-nastools/luasrc/model/nastools.lua b/openwrt-app-actions/applications/luci-app-nastools/luasrc/model/nastools.lua
deleted file mode 100644
index 98d98aeac..000000000
--- a/openwrt-app-actions/applications/luci-app-nastools/luasrc/model/nastools.lua
+++ /dev/null
@@ -1,55 +0,0 @@
-local util = require "luci.util"
-local jsonc = require "luci.jsonc"
-
-local nastools = {}
-
-nastools.blocks = function()
- local f = io.popen("lsblk -s -f -b -o NAME,FSSIZE,MOUNTPOINT --json", "r")
- local vals = {}
- if f then
- local ret = f:read("*all")
- f:close()
- local obj = jsonc.parse(ret)
- for _, val in pairs(obj["blockdevices"]) do
- local fsize = val["fssize"]
- if fsize ~= nil and string.len(fsize) > 10 and val["mountpoint"] then
- -- fsize > 1G
- vals[#vals+1] = val["mountpoint"]
- end
- end
- end
- return vals
-end
-
-nastools.home = function()
- local uci = require "luci.model.uci".cursor()
- local home_dirs = {}
- home_dirs["main_dir"] = uci:get_first("quickstart", "main", "main_dir", "/root")
- home_dirs["Configs"] = uci:get_first("quickstart", "main", "conf_dir", home_dirs["main_dir"].."/Configs")
- home_dirs["Public"] = uci:get_first("quickstart", "main", "pub_dir", home_dirs["main_dir"].."/Public")
- home_dirs["Downloads"] = uci:get_first("quickstart", "main", "dl_dir", home_dirs["Public"].."/Downloads")
- home_dirs["Caches"] = uci:get_first("quickstart", "main", "tmp_dir", home_dirs["main_dir"].."/Caches")
- return home_dirs
-end
-
-nastools.find_paths = function(blocks, home_dirs, path_name)
- local default_path = ''
- local configs = {}
-
- default_path = home_dirs[path_name] .. "/NasTools"
- if #blocks == 0 then
- table.insert(configs, default_path)
- else
- for _, val in pairs(blocks) do
- table.insert(configs, val .. "/" .. path_name .. "/NasTools")
- end
- local without_conf_dir = "/root/" .. path_name .. "/NasTools"
- if default_path == without_conf_dir then
- default_path = configs[1]
- end
- end
-
- return configs, default_path
-end
-
-return nastools
diff --git a/openwrt-app-actions/applications/luci-app-nastools/luasrc/view/nastools/status.htm b/openwrt-app-actions/applications/luci-app-nastools/luasrc/view/nastools/status.htm
deleted file mode 100644
index c8f1e929b..000000000
--- a/openwrt-app-actions/applications/luci-app-nastools/luasrc/view/nastools/status.htm
+++ /dev/null
@@ -1,32 +0,0 @@
-<%
-local util = require "luci.util"
-local container_status = util.trim(util.exec("/usr/libexec/istorec/nastools.sh status"))
-local container_install = (string.len(container_status) > 0)
-local container_running = container_status == "running"
--%>
-
-
-
- <% if container_running then %>
-
- <%:Default username: admin, password: password%>
- <% else %>
-
- <% end %>
-
-
-<%
-if container_running then
- local port=util.trim(util.exec("/usr/libexec/istorec/nastools.sh port"))
- if port == "" then
- port="3003"
- end
--%>
-
-
-
-
-
-
-
-<% end %>
\ No newline at end of file
diff --git a/openwrt-app-actions/applications/luci-app-nastools/po/zh-cn/nastools.po b/openwrt-app-actions/applications/luci-app-nastools/po/zh-cn/nastools.po
deleted file mode 100644
index 499d65616..000000000
--- a/openwrt-app-actions/applications/luci-app-nastools/po/zh-cn/nastools.po
+++ /dev/null
@@ -1,44 +0,0 @@
-msgid ""
-msgstr "Content-Type: text/plain; charset=UTF-8"
-
-msgid "Official website:"
-msgstr "官方网站:"
-
-msgid "NasTools is a tools for resource aggregation running in NAS."
-msgstr "NasTools 是汇聚了电影搜索,下载,订阅,观看等等 NAS 功能的工具集合。"
-
-msgid "Config path"
-msgstr "配置文件路径"
-
-msgid "Port"
-msgstr "端口"
-
-msgid "Auto update"
-msgstr "自动更新"
-
-msgid "Service Status"
-msgstr "服务状态"
-
-msgid "NasTools status:"
-msgstr "NasTools 的状态信息如下:"
-
-msgid "Setup"
-msgstr "安装配置"
-
-msgid "The following parameters will only take effect during installation or upgrade:"
-msgstr "以下参数只在安装或者升级时才会生效:"
-
-msgid "Status"
-msgstr "状态"
-
-msgid "NasTools is running"
-msgstr "NasTools 运行中"
-
-msgid "Default username: admin, password: password"
-msgstr "默认用户名:admin,密码:password"
-
-msgid "NasTools is not running"
-msgstr "NasTools 未运行"
-
-msgid "Open NasTools"
-msgstr "打开 NasTools"
diff --git a/openwrt-app-actions/applications/luci-app-nastools/root/etc/config/nastools b/openwrt-app-actions/applications/luci-app-nastools/root/etc/config/nastools
deleted file mode 100644
index 5e8c5e167..000000000
--- a/openwrt-app-actions/applications/luci-app-nastools/root/etc/config/nastools
+++ /dev/null
@@ -1,4 +0,0 @@
-config nastools
- option 'config_path' ''
- option 'http_port' '3003'
- option 'auto_upgrade' '0'
diff --git a/openwrt-app-actions/applications/luci-app-nastools/root/usr/libexec/istorec/nastools.sh b/openwrt-app-actions/applications/luci-app-nastools/root/usr/libexec/istorec/nastools.sh
deleted file mode 100755
index aeb705a5a..000000000
--- a/openwrt-app-actions/applications/luci-app-nastools/root/usr/libexec/istorec/nastools.sh
+++ /dev/null
@@ -1,92 +0,0 @@
-#!/bin/sh
-
-ACTION=${1}
-shift 1
-
-get_image() {
- IMAGE_NAME="jxxghp/nas-tools"
-}
-
-do_install() {
- get_image
- echo "docker pull ${IMAGE_NAME}"
- docker pull ${IMAGE_NAME}
- docker rm -f nastools
-
- do_install_detail
-}
-
-do_install_detail() {
- local config=`uci get nastools.@nastools[0].config_path 2>/dev/null`
- local port=`uci get nastools.@nastools[0].http_port 2>/dev/null`
- local auto_update=`uci get nastools.@nastools[0].auto_upgrade 2>/dev/null`
-
- if [ -z "$config" ]; then
- echo "config path is empty!"
- exit 1
- fi
-
- [ -z "$port" ] && port=3003
-
- local cmd="docker run --restart=unless-stopped -d \
- --hostname nastools \
- -v \"$config:/config\" \
- --dns=172.17.0.1 \
- -p $port:3000 \
- -e UMASK=000"
-
- local tz="`uci get system.@system[0].zonename`"
- [ -z "$tz" ] || cmd="$cmd -e TZ=$tz"
-
- if [ -n "$auto_update" ]; then
- if [ "$auto_update" = 1 ]; then
- cmd="$cmd -e NASTOOL_AUTO_UPDATE=true"
- else
- cmd="$cmd -e NASTOOL_AUTO_UPDATE=false"
- fi
- fi
-
- cmd="$cmd -v /mnt:/mnt"
- mountpoint -q /mnt && cmd="$cmd:rslave"
-
- cmd="$cmd --name nastools \"$IMAGE_NAME\""
-
- echo "$cmd"
- eval "$cmd"
-
-}
-
-usage() {
- echo "usage: $0 sub-command"
- echo "where sub-command is one of:"
- echo " install Install the nastools"
- echo " upgrade Upgrade the nastools"
- echo " rm/start/stop/restart Remove/Start/Stop/Restart the nastools"
- echo " status NasTools status"
- echo " port NasTools port"
-}
-
-case ${ACTION} in
- "install")
- do_install
- ;;
- "upgrade")
- do_install
- ;;
- "rm")
- docker rm -f nastools
- ;;
- "start" | "stop" | "restart")
- docker ${ACTION} nastools
- ;;
- "status")
- docker ps --all -f 'name=nastools' --format '{{.State}}'
- ;;
- "port")
- docker ps --all -f 'name=nastools' --format '{{.Ports}}' | grep -om1 '0.0.0.0:[0-9]*' | sed 's/0.0.0.0://'
- ;;
- *)
- usage
- exit 1
- ;;
-esac
diff --git a/openwrt-app-actions/applications/luci-app-navidrome/Makefile b/openwrt-app-actions/applications/luci-app-navidrome/Makefile
deleted file mode 100644
index 45cf1ca37..000000000
--- a/openwrt-app-actions/applications/luci-app-navidrome/Makefile
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-include $(TOPDIR)/rules.mk
-
-PKG_VERSION:=1.0.1-20230108
-PKG_RELEASE:=
-
-LUCI_TITLE:=LuCI support for Navidrome
-LUCI_PKGARCH:=all
-LUCI_DEPENDS:=+docker +luci-lib-taskd
-
-define Package/luci-app-navidrome/conffiles
-/etc/config/navidrome
-endef
-
-include $(TOPDIR)/feeds/luci/luci.mk
-
-# call BuildPackage - OpenWrt buildroot signature
diff --git a/openwrt-app-actions/applications/luci-app-navidrome/luasrc/controller/navidrome.lua b/openwrt-app-actions/applications/luci-app-navidrome/luasrc/controller/navidrome.lua
deleted file mode 100755
index da9e3aaf7..000000000
--- a/openwrt-app-actions/applications/luci-app-navidrome/luasrc/controller/navidrome.lua
+++ /dev/null
@@ -1,7 +0,0 @@
-
-module("luci.controller.navidrome", package.seeall)
-
-function index()
- entry({"admin", "services", "navidrome"}, alias("admin", "services", "navidrome", "config"), _("Navidrome"), 30).dependent = true
- entry({"admin", "services", "navidrome", "config"}, cbi("navidrome"))
-end
diff --git a/openwrt-app-actions/applications/luci-app-navidrome/luasrc/model/cbi/navidrome.lua b/openwrt-app-actions/applications/luci-app-navidrome/luasrc/model/cbi/navidrome.lua
deleted file mode 100644
index 3e408a9ae..000000000
--- a/openwrt-app-actions/applications/luci-app-navidrome/luasrc/model/cbi/navidrome.lua
+++ /dev/null
@@ -1,54 +0,0 @@
---[[
-LuCI - Lua Configuration Interface
-]]--
-
-local taskd = require "luci.model.tasks"
-local navidrome_model = require "luci.model.navidrome"
-local m, s, o
-
-m = taskd.docker_map("navidrome", "navidrome", "/usr/libexec/istorec/navidrome.sh",
- translate("Navidrome"),
- translate("Navidrome is an open source web-based music collection server and streamer.")
- .. translate("Official website:") .. ' https://github.com/Difegue/Navidrome')
-
-s = m:section(SimpleSection, translate("Service Status"), translate("Navidrome status:"))
-s:append(Template("navidrome/status"))
-
-s = m:section(TypedSection, "main", translate("Setup"), translate("The following parameters will only take effect during installation or upgrade:"))
-s.addremove=false
-s.anonymous=true
-
-o = s:option(Value, "http_port", translate("HTTP Port").."*")
-o.rmempty = false
-o.default = "3000"
-o.datatype = "string"
-
-o = s:option(Value, "image_name", translate("Image").."*")
-o.rmempty = false
-o.datatype = "string"
-o:value("difegue/navidrome", "difegue/navidrome")
-o.default = "difegue/navidrome"
-
-local blocks = navidrome_model.blocks()
-local home = navidrome_model.home()
-
-o = s:option(Value, "config_path", translate("Config path").."*")
-o.rmempty = false
-o.datatype = "string"
-
-local paths, default_path = navidrome_model.find_paths(blocks, home, "Configs")
-for _, val in pairs(paths) do
- o:value(val, val)
-end
-o.default = default_path
-
-o = s:option(Value, "music_path", translate("Music path").."*")
-o.rmempty = false
-o.datatype = "string"
-local paths, default_path = navidrome_model.find_paths(blocks, home, "Public")
-for _, val in pairs(paths) do
- o:value(val, val)
-end
-o.default = default_path
-
-return m
diff --git a/openwrt-app-actions/applications/luci-app-navidrome/luasrc/model/navidrome.lua b/openwrt-app-actions/applications/luci-app-navidrome/luasrc/model/navidrome.lua
deleted file mode 100644
index baaab3de0..000000000
--- a/openwrt-app-actions/applications/luci-app-navidrome/luasrc/model/navidrome.lua
+++ /dev/null
@@ -1,54 +0,0 @@
-local util = require "luci.util"
-local jsonc = require "luci.jsonc"
-
-local navidrome = {}
-
-navidrome.blocks = function()
- local f = io.popen("lsblk -s -f -b -o NAME,FSSIZE,MOUNTPOINT --json", "r")
- local vals = {}
- if f then
- local ret = f:read("*all")
- f:close()
- local obj = jsonc.parse(ret)
- for _, val in pairs(obj["blockdevices"]) do
- local fsize = val["fssize"]
- if fsize ~= nil and string.len(fsize) > 10 and val["mountpoint"] then
- -- fsize > 1G
- vals[#vals+1] = val["mountpoint"]
- end
- end
- end
- return vals
-end
-
-navidrome.home = function()
- local uci = require "luci.model.uci".cursor()
- local home_dirs = {}
- home_dirs["main_dir"] = uci:get_first("quickstart", "main", "main_dir", "/root")
- home_dirs["Configs"] = uci:get_first("quickstart", "main", "conf_dir", home_dirs["main_dir"].."/Configs")
- home_dirs["Public"] = uci:get_first("quickstart", "main", "pub_dir", home_dirs["main_dir"].."/Public")
- home_dirs["Caches"] = uci:get_first("quickstart", "main", "tmp_dir", home_dirs["main_dir"].."/Caches")
- return home_dirs
-end
-
-navidrome.find_paths = function(blocks, home_dirs, path_name)
- local appname = '/Navidrome'
- local default_path = ''
- local configs = {}
-
- if #blocks == 0 then
- return configs, default_path
- else
- if path_name == "Public" then
- appname = "/Music"
- end
- for _, val in pairs(blocks) do
- table.insert(configs, val .. "/" .. path_name .. appname)
- end
- default_path = configs[1]
- end
-
- return configs, default_path
-end
-
-return navidrome
diff --git a/openwrt-app-actions/applications/luci-app-navidrome/luasrc/view/navidrome/status.htm b/openwrt-app-actions/applications/luci-app-navidrome/luasrc/view/navidrome/status.htm
deleted file mode 100644
index 5b631352c..000000000
--- a/openwrt-app-actions/applications/luci-app-navidrome/luasrc/view/navidrome/status.htm
+++ /dev/null
@@ -1,31 +0,0 @@
-<%
-local util = require "luci.util"
-local container_status = util.trim(util.exec("/usr/libexec/istorec/navidrome.sh status"))
-local container_install = (string.len(container_status) > 0)
-local container_running = container_status == "running"
--%>
-
-
-
- <% if container_running then %>
-
- <% else %>
-
- <% end %>
-
-
-<%
-if container_running then
- local port=util.trim(util.exec("/usr/libexec/istorec/navidrome.sh port"))
- if port == "" then
- port="4533"
- end
--%>
-
-
-
-
-
-
-
-<% end %>
diff --git a/openwrt-app-actions/applications/luci-app-navidrome/po/zh-cn/navidrome.po b/openwrt-app-actions/applications/luci-app-navidrome/po/zh-cn/navidrome.po
deleted file mode 100644
index 4aeea8eb9..000000000
--- a/openwrt-app-actions/applications/luci-app-navidrome/po/zh-cn/navidrome.po
+++ /dev/null
@@ -1,41 +0,0 @@
-msgid ""
-msgstr "Content-Type: text/plain; charset=UTF-8"
-
-msgid "Official website:"
-msgstr "官方网站:"
-
-msgid "Navidrome is an open source web-based music collection server and streamer."
-msgstr "Navidrome 是一个开源的在线音乐播放软件。"
-
-msgid "Config path"
-msgstr "配置文件路径"
-
-msgid "Music path"
-msgstr "音乐路径"
-
-msgid "HTTP Port"
-msgstr "HTTP 端口"
-
-msgid "Service Status"
-msgstr "服务状态"
-
-msgid "Navidrome status:"
-msgstr "Navidrome 的状态信息如下:"
-
-msgid "Setup"
-msgstr "安装配置"
-
-msgid "The following parameters will only take effect during installation or upgrade:"
-msgstr "以下参数只在安装或者升级时才会生效:"
-
-msgid "Status"
-msgstr "状态"
-
-msgid "Navidrome is running"
-msgstr "Navidrome 运行中"
-
-msgid "Navidrome is not running"
-msgstr "Navidrome 未运行"
-
-msgid "Open Navidrome"
-msgstr "打开 Navidrome"
diff --git a/openwrt-app-actions/applications/luci-app-navidrome/root/etc/config/navidrome b/openwrt-app-actions/applications/luci-app-navidrome/root/etc/config/navidrome
deleted file mode 100644
index 8e0c715c5..000000000
--- a/openwrt-app-actions/applications/luci-app-navidrome/root/etc/config/navidrome
+++ /dev/null
@@ -1,6 +0,0 @@
-config main
- option 'http_port' '4533'
- option 'image_name' 'deluan/navidrome:latest'
- option 'config_path' ''
- option 'music_path' ''
-
diff --git a/openwrt-app-actions/applications/luci-app-navidrome/root/usr/libexec/istorec/navidrome.sh b/openwrt-app-actions/applications/luci-app-navidrome/root/usr/libexec/istorec/navidrome.sh
deleted file mode 100755
index 984ea8c5d..000000000
--- a/openwrt-app-actions/applications/luci-app-navidrome/root/usr/libexec/istorec/navidrome.sh
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/bin/sh
-# Author Xiaobao(xiaobao@linkease.com)
-
-ACTION=${1}
-shift 1
-
-do_install() {
- local http_port=`uci get navidrome.@main[0].http_port 2>/dev/null`
- local image_name=`uci get navidrome.@main[0].image_name 2>/dev/null`
- local config=`uci get navidrome.@main[0].config_path 2>/dev/null`
- local content=`uci get navidrome.@main[0].music_path 2>/dev/null`
-
- [ -z "$image_name" ] && image_name="difegue/navidrome"
- echo "docker pull ${image_name}"
- docker pull ${image_name}
- docker rm -f navidrome
-
- if [ -z "$config" ]; then
- echo "config path is empty!"
- exit 1
- fi
-
- [ -z "$http_port" ] && http_port=4533
-
- local cmd="docker run --restart=unless-stopped -d \
- -v \"$config:/data\" \
- -v \"$content:/music:ro\" \
- --dns=172.17.0.1 \
- -p $http_port:4533 "
-
- local tz="`uci get system.@system[0].zonename`"
- [ -z "$tz" ] || cmd="$cmd -e TZ=$tz"
-
- cmd="$cmd -v /mnt:/mnt"
- mountpoint -q /mnt && cmd="$cmd:rslave"
- cmd="$cmd --name navidrome \"$image_name\""
-
- echo "$cmd"
- eval "$cmd"
-}
-
-usage() {
- echo "usage: $0 sub-command"
- echo "where sub-command is one of:"
- echo " install Install the navidrome"
- echo " upgrade Upgrade the navidrome"
- echo " rm/start/stop/restart Remove/Start/Stop/Restart the navidrome"
- echo " status Navidrome status"
- echo " port Navidrome port"
-}
-
-case ${ACTION} in
- "install")
- do_install
- ;;
- "upgrade")
- do_install
- ;;
- "rm")
- docker rm -f navidrome
- ;;
- "start" | "stop" | "restart")
- docker ${ACTION} navidrome
- ;;
- "status")
- docker ps --all -f 'name=navidrome' --format '{{.State}}'
- ;;
- "port")
- docker ps --all -f 'name=navidrome' --format '{{.Ports}}' | grep -om1 '0.0.0.0:[0-9]*' | sed 's/0.0.0.0://'
- ;;
- *)
- usage
- exit 1
- ;;
-esac
diff --git a/openwrt-app-actions/applications/luci-app-netdata/Makefile b/openwrt-app-actions/applications/luci-app-netdata/Makefile
deleted file mode 100755
index 2666b69b6..000000000
--- a/openwrt-app-actions/applications/luci-app-netdata/Makefile
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2016 Openwrt.org
-# Copyright (C) 2020-2021 sirpdboy
-# https://github.com/sirpdboy/luci-app-netdata for v 1.30.1 cn
-# This is free software, licensed under the Apache License, Version 2.0 .
-#
-
-include $(TOPDIR)/rules.mk
-
-LUCI_TITLE:=LuCI support for Netdata
-LUCI_DEPENDS:=+netdata
-LUCI_PKGARCH:=all
-PKG_VERSION:=1.1-20210610
-PKG_RELEASE:=
-
-define Build/Compile
-endef
-
-
-include $(TOPDIR)/feeds/luci/luci.mk
-
-# call BuildPackage - OpenWrt buildroot signature
-
diff --git a/openwrt-app-actions/applications/luci-app-netdata/README.md b/openwrt-app-actions/applications/luci-app-netdata/README.md
deleted file mode 100755
index 06a486b43..000000000
--- a/openwrt-app-actions/applications/luci-app-netdata/README.md
+++ /dev/null
@@ -1,30 +0,0 @@
-luci-app-netdata for OpenWRT/Lede
-
-
-Install to OpenWRT/LEDE
-
-git clone https://github.com/sirpdboy/luci-app-netdata
-
-cp -r luci-app-netdata LEDE_DIR/package/luci-app-netdata
-
-cd LEDE_DIR
-
-./scripts/feeds update -a
-
-./scripts/feeds install -a
-
-make menuconfig
-
-LuCI --->
-
- 1. Collections --->
-
- <*> luci
-
- 3. Applications --->
-
- <*> luci-app-netdata.........................LuCI support for Netdata
-
-
-make package/new/luci-app-netdata/compile V=s
-
diff --git a/openwrt-app-actions/applications/luci-app-netdata/luasrc/controller/netdata.lua b/openwrt-app-actions/applications/luci-app-netdata/luasrc/controller/netdata.lua
deleted file mode 100755
index 29d81e918..000000000
--- a/openwrt-app-actions/applications/luci-app-netdata/luasrc/controller/netdata.lua
+++ /dev/null
@@ -1,12 +0,0 @@
-module("luci.controller.netdata", package.seeall)
-
-function index()
- if not (luci.sys.call("pidof netdata > /dev/null") == 0) then
- return
- end
- local fs = require "nixio.fs"
-
- entry({"admin","status","netdata"},template("netdata"),_("NetData"),10).leaf=true
-
-
-end
\ No newline at end of file
diff --git a/openwrt-app-actions/applications/luci-app-netdata/luasrc/model/cgi/netdate.lua b/openwrt-app-actions/applications/luci-app-netdata/luasrc/model/cgi/netdate.lua
deleted file mode 100755
index 134e2bea8..000000000
--- a/openwrt-app-actions/applications/luci-app-netdata/luasrc/model/cgi/netdate.lua
+++ /dev/null
@@ -1,25 +0,0 @@
--- Copyright 2018 Nick Peng (pymumu@gmail.com)
-
-function index()
-
-
-o = Map("netdate", "" .. translate("实时监控") .."", "" .. translate( "强大的实时监控数据,需要中文版请点击:【升级中文版】") .."")
-
-t = o:section(TypedSection, "netdate")
-t.anonymous = true
-t.description = translate(string.format("%s
", status))
-
-t:tab("base",translate("Basic Settings"))
-
-e = t:taboption("base", Button, "restart", translate("手动更新"))
-e.inputtitle = translate("升级中文版")
-e.inputstyle = "reload"
-e.write = function()
- luci.sys.call("/usr/share/netdata/netdatacn 2>&1 >/dev/null")
- luci.http.redirect(luci.dispatcher.build_url("admin","status","netdata"))
-end
-
-t=o:section(TypedSection,"rss_rules",translate("技术支持"))
-t.anonymous = true
-t:append(Template("feedback"))
-return o
diff --git a/openwrt-app-actions/applications/luci-app-netdata/luasrc/view/netdata.htm b/openwrt-app-actions/applications/luci-app-netdata/luasrc/view/netdata.htm
deleted file mode 100755
index 159f8dc28..000000000
--- a/openwrt-app-actions/applications/luci-app-netdata/luasrc/view/netdata.htm
+++ /dev/null
@@ -1,22 +0,0 @@
-<%#
- Copyright 2008-2020 sirpdboy Wich
- https://github.com/sirpdboy/luci-app-netdata
- Licensed to the public under the Apache License 2.0.
--%>
-
-<%+header%>
-
- <%=translate("NetData")%>
-
-
-
-
-
-<%+footer%>
diff --git a/openwrt-app-actions/applications/luci-app-netdata/po/zh-cn/netdata.po b/openwrt-app-actions/applications/luci-app-netdata/po/zh-cn/netdata.po
deleted file mode 100755
index e8966b815..000000000
--- a/openwrt-app-actions/applications/luci-app-netdata/po/zh-cn/netdata.po
+++ /dev/null
@@ -1,5 +0,0 @@
-msgid ""
-msgstr "Content-Type: text/plain; charset=UTF-8"
-
-msgid "NetData"
-msgstr "实时监控"
diff --git a/openwrt-app-actions/applications/luci-app-netdata/readme.txt b/openwrt-app-actions/applications/luci-app-netdata/readme.txt
deleted file mode 100755
index 72da42502..000000000
--- a/openwrt-app-actions/applications/luci-app-netdata/readme.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-luci-app-netdata for OpenWRT/Lede()
-
-
-Install to OpenWRT/LEDE
-
-git clone https://github.com/sirpdboy/luci-app-netdata
-cp -r luci-app-netdata LEDE_DIR/package/luci-app-netdata
-
-cd LEDE_DIR
-./scripts/feeds update -a
-./scripts/feeds install -a
-
-make menuconfig
-LuCI --->
- 1. Collections --->
- <*> luci
- 3. Applications --->
- <*> luci-app-netdata.........................LuCI support for Netdata
-
-
-make package/luci-app-netdata/compile V=s
\ No newline at end of file
diff --git a/openwrt-app-actions/applications/luci-app-netdata/root/etc/netdata/apps_groups.conf b/openwrt-app-actions/applications/luci-app-netdata/root/etc/netdata/apps_groups.conf
deleted file mode 100755
index d326be78f..000000000
--- a/openwrt-app-actions/applications/luci-app-netdata/root/etc/netdata/apps_groups.conf
+++ /dev/null
@@ -1,314 +0,0 @@
-#
-# apps.plugin process grouping
-#
-# The apps.plugin displays charts with information about the processes running.
-# This config allows grouping processes together, so that several processes
-# will be reported as one.
-#
-# Only groups in this file are reported. All other processes will be reported
-# as 'other'.
-#
-# For each process given, its whole process tree will be grouped, not just
-# the process matched. The plugin will include both parents and childs.
-#
-# The format is:
-#
-# group: process1 process2 process3 ...
-#
-# Each group can be given multiple times, to add more processes to it.
-#
-# The process names are the ones returned by:
-#
-# - ps -e or /proc/PID/stat
-# - in case of substring mode (see below): /proc/PID/cmdline
-#
-# To add process names with spaces, enclose them in quotes (single or double)
-# example: 'Plex Media Serv' "my other process".
-#
-# Wildcard support:
-# You can add an asterisk (*) at the beginning and/or the end of a process:
-#
-# *name suffix mode: will search for processes ending with 'name'
-# (/proc/PID/stat)
-#
-# name* prefix mode: will search for processes beginning with 'name'
-# (/proc/PID/stat)
-#
-# *name* substring mode: will search for 'name' in the whole command line
-# (/proc/PID/cmdline)
-#
-# If you enter even just one *name* (substring), apps.plugin will process
-# /proc/PID/cmdline for all processes, just once (when they are first seen).
-#
-# To add processes with single quotes, enclose them in double quotes
-# example: "process with this ' single quote"
-#
-# To add processes with double quotes, enclose them in single quotes:
-# example: 'process with this " double quote'
-#
-# If a group or process name starts with a -, the dimension will be hidden
-# (cpu chart only).
-#
-# If a process starts with a +, debugging will be enabled for it
-# (debugging produces a lot of output - do not enable it in production systems)
-#
-# You can add any number of groups you like. Only the ones found running will
-# affect the charts generated. However, producing charts with hundreds of
-# dimensions may slow down your web browser.
-#
-# The order of the entries in this list is important: the first that matches
-# a process is used, so put important ones at the top. Processes not matched
-# by any row, will inherit it from their parents or children.
-#
-# The order also controls the order of the dimensions on the generated charts
-# (although applications started after apps.plugin is started, will be appended
-# to the existing list of dimensions the netdata daemon maintains).
-
-# -----------------------------------------------------------------------------
-# NETDATA processes accounting
-
-# netdata main process
-netdata: netdata
-
-# netdata known plugins
-# plugins not defined here will be accumulated in netdata, above
-apps.plugin: apps.plugin
-freeipmi.plugin: freeipmi.plugin
-nfacct.plugin: nfacct.plugin
-cups.plugin: cups.plugin
-xenstat.plugin: xenstat.plugin
-perf.plugin: perf.plugin
-charts.d.plugin: *charts.d.plugin*
-node.d.plugin: *node.d.plugin*
-python.d.plugin: *python.d.plugin*
-tc-qos-helper: *tc-qos-helper.sh*
-fping: fping
-ioping: ioping
-go.d.plugin: *go.d.plugin*
-slabinfo.plugin: slabinfo.plugin
-ebpf.plugin: *ebpf.plugin*
-
-# agent-service-discovery
-agent_sd: agent_sd
-
-# -----------------------------------------------------------------------------
-# authentication/authorization related servers
-
-auth: radius* openldap* ldap* slapd authelia
-fail2ban: fail2ban*
-
-# -----------------------------------------------------------------------------
-# web/ftp servers
-
-httpd: apache* httpd nginx* lighttpd hiawatha
-proxy: squid* c-icap squidGuard varnish*
-php: php* lsphp*
-ftpd: proftpd in.tftpd vsftpd
-uwsgi: uwsgi
-unicorn: *unicorn*
-puma: *puma*
-
-# -----------------------------------------------------------------------------
-# database servers
-
-sql: mysqld* mariad* postgres* postmaster* oracle_* ora_* sqlservr
-nosql: mongod redis* memcached *couchdb*
-timedb: prometheus *carbon-cache.py* *carbon-aggregator.py* *graphite/manage.py* *net.opentsdb.tools.TSDMain* influxd*
-columndb: clickhouse-server*
-
-# -----------------------------------------------------------------------------
-# email servers
-
-email: dovecot imapd pop3d amavis* master zmstat* zmmailboxdmgr qmgr oqmgr saslauthd opendkim clamd freshclam tlsmgr postfwd2 postscreen postfix smtp* lmtp* sendmail
-
-# -----------------------------------------------------------------------------
-# network, routing, VPN
-
-ppp: ppp*
-vpn: openvpn pptp* cjdroute gvpe tincd
-wifi: hostapd wpa_supplicant NetworkManager
-routing: ospfd* ospf6d* bgpd bfdd fabricd isisd eigrpd sharpd staticd ripd ripngd pimd pbrd nhrpd ldpd zebra vrrpd vtysh bird*
-modem: ModemManager
-tor: tor
-
-# -----------------------------------------------------------------------------
-# high availability and balancers
-
-camo: *camo*
-balancer: ipvs_* haproxy
-ha: corosync hs_logd ha_logd stonithd pacemakerd lrmd crmd
-
-# -----------------------------------------------------------------------------
-# telephony
-
-pbx: asterisk safe_asterisk *vicidial*
-sip: opensips* stund
-
-# -----------------------------------------------------------------------------
-# chat
-
-chat: irssi *vines* *prosody* murmurd
-
-# -----------------------------------------------------------------------------
-# monitoring
-
-logs: ulogd* syslog* rsyslog* logrotate systemd-journald rotatelogs
-nms: snmpd vnstatd smokeping zabbix* monit munin* mon openhpid watchdog tailon nrpe
-splunk: splunkd
-azure: mdsd *waagent* *omiserver* *omiagent* hv_kvp_daemon hv_vss_daemon *auoms* *omsagent*
-
-# -----------------------------------------------------------------------------
-# storage, file systems and file servers
-
-ceph: ceph-* ceph_* radosgw* rbd-* cephfs-* osdmaptool crushtool
-samba: smbd nmbd winbindd ctdbd ctdb-* ctdb_*
-nfs: rpcbind rpc.* nfs*
-zfs: spl_* z_* txg_* zil_* arc_* l2arc*
-btrfs: btrfs*
-iscsi: iscsid iscsi_eh
-
-# -----------------------------------------------------------------------------
-# kubernetes
-
-kubelet: kubelet
-kube-dns: kube-dns
-kube-proxy: kube-proxy
-metrics-server: metrics-server
-heapster: heapster
-
-# -----------------------------------------------------------------------------
-# containers & virtual machines
-
-containers: lxc* docker* balena*
-VMs: vbox* VBox* qemu*
-
-# -----------------------------------------------------------------------------
-# ssh servers and clients
-
-ssh: ssh* scp dropbear
-
-# -----------------------------------------------------------------------------
-# print servers and clients
-
-print: cups* lpd lpq
-
-# -----------------------------------------------------------------------------
-# time servers and clients
-
-time: ntp* systemd-timesyn* chronyd
-
-# -----------------------------------------------------------------------------
-# dhcp servers and clients
-
-dhcp: *dhcp*
-
-# -----------------------------------------------------------------------------
-# name servers and clients
-
-dns: named unbound nsd pdns_server knotd gdnsd yadifad dnsmasq systemd-resolve*
-dnsdist: dnsdist
-
-# -----------------------------------------------------------------------------
-# installation / compilation / debugging
-
-build: cc1 cc1plus as gcc* cppcheck ld make cmake automake autoconf autoreconf
-build: git gdb valgrind*
-
-# -----------------------------------------------------------------------------
-# antivirus
-
-antivirus: clam* *clam imunify360*
-
-# -----------------------------------------------------------------------------
-# torrent clients
-
-torrents: *deluge* transmission* *SickBeard* *CouchPotato* *rtorrent*
-
-# -----------------------------------------------------------------------------
-# backup servers and clients
-
-backup: rsync lsyncd bacula* borg rclone
-
-# -----------------------------------------------------------------------------
-# cron
-
-cron: cron* atd anacron systemd-cron*
-
-# -----------------------------------------------------------------------------
-# UPS
-
-ups: upsmon upsd */nut/*
-
-# -----------------------------------------------------------------------------
-# media players, servers, clients
-
-media: mplayer vlc xine mediatomb omxplayer* kodi* xbmc* mediacenter eventlircd
-media: mpd minidlnad mt-daapd avahi* Plex* jellyfin squeeze* jackett Ombi
-
-# -----------------------------------------------------------------------------
-# java applications
-
-hdfsdatanode: *org.apache.hadoop.hdfs.server.datanode.DataNode*
-hdfsnamenode: *org.apache.hadoop.hdfs.server.namenode.NameNode*
-hdfsjournalnode: *org.apache.hadoop.hdfs.qjournal.server.JournalNode*
-hdfszkfc: *org.apache.hadoop.hdfs.tools.DFSZKFailoverController*
-
-yarnnode: *org.apache.hadoop.yarn.server.nodemanager.NodeManager*
-yarnmgr: *org.apache.hadoop.yarn.server.resourcemanager.ResourceManager*
-yarnproxy: *org.apache.hadoop.yarn.server.webproxy.WebAppProxyServer*
-
-sparkworker: *org.apache.spark.deploy.worker.Worker*
-sparkmaster: *org.apache.spark.deploy.master.Master*
-
-hbaseregion: *org.apache.hadoop.hbase.regionserver.HRegionServer*
-hbaserest: *org.apache.hadoop.hbase.rest.RESTServer*
-hbasethrift: *org.apache.hadoop.hbase.thrift.ThriftServer*
-hbasemaster: *org.apache.hadoop.hbase.master.HMaster*
-
-zookeeper: *org.apache.zookeeper.server.quorum.QuorumPeerMain*
-
-hive2: *org.apache.hive.service.server.HiveServer2*
-hivemetastore: *org.apache.hadoop.hive.metastore.HiveMetaStore*
-
-solr: *solr.install.dir*
-
-airflow: *airflow*
-
-# -----------------------------------------------------------------------------
-# X
-
-X: X Xorg xinit lightdm xdm pulseaudio gkrellm xfwm4 xfdesktop xfce* Thunar
-X: xfsettingsd xfconfd gnome-* gdm gconf* dconf* xfconf* *gvfs gvfs* slim
-X: kdeinit* kdm plasmashell
-X: evolution-* firefox chromium opera vivaldi-bin epiphany WebKit*
-X: '*systemd --user*' chrome *chrome-sandbox* *google-chrome* *chromium* *firefox*
-
-# -----------------------------------------------------------------------------
-# Kernel / System
-
-ksmd: ksmd
-
-system: systemd-* udisks* udevd* *udevd connmand ipv6_addrconf dbus-* rtkit*
-system: inetd xinetd mdadm polkitd acpid uuidd packagekitd upowerd colord
-system: accounts-daemon rngd haveged
-
-kernel: kthreadd kauditd lockd khelper kdevtmpfs khungtaskd rpciod
-kernel: fsnotify_mark kthrotld deferwq scsi_*
-
-# -----------------------------------------------------------------------------
-# other application servers
-
-kafka: *kafka.Kafka*
-
-rabbitmq: *rabbitmq*
-
-sidekiq: *sidekiq*
-java: java
-ipfs: ipfs
-
-node: node*
-factorio: factorio
-
-p4: p4*
-
-git-services: gitea gitlab-runner
diff --git a/openwrt-app-actions/applications/luci-app-netdata/root/etc/netdata/ebpf.conf b/openwrt-app-actions/applications/luci-app-netdata/root/etc/netdata/ebpf.conf
deleted file mode 100755
index d9b6b9393..000000000
--- a/openwrt-app-actions/applications/luci-app-netdata/root/etc/netdata/ebpf.conf
+++ /dev/null
@@ -1,7 +0,0 @@
-[global]
- ebpf load mode = entry
- disable apps = no
-
-[ebpf programs]
- process = yes
- network viewer = yes
diff --git a/openwrt-app-actions/applications/luci-app-netdata/root/etc/netdata/exporting.conf b/openwrt-app-actions/applications/luci-app-netdata/root/etc/netdata/exporting.conf
deleted file mode 100755
index 9c1e7ffb7..000000000
--- a/openwrt-app-actions/applications/luci-app-netdata/root/etc/netdata/exporting.conf
+++ /dev/null
@@ -1,88 +0,0 @@
-[exporting:global]
- enabled = no
- # send configured labels = yes
- # send automatic labels = no
- # update every = 10
-
-[prometheus:exporter]
- # send names instead of ids = yes
- # send configured labels = yes
- # send automatic labels = no
- # send charts matching = *
- # send hosts matching = localhost *
- # prefix = netdata
-
-# An example configuration for graphite, json, opentsdb exporting connectors
-# [graphite:my_graphite_instance]
- # enabled = no
- # destination = localhost
- # data source = average
- # prefix = netdata
- # hostname = my_hostname
- # update every = 10
- # buffer on failures = 10
- # timeout ms = 20000
- # send names instead of ids = yes
- # send charts matching = *
- # send hosts matching = localhost *
-
-# [prometheus_remote_write:my_prometheus_remote_write_instance]
- # enabled = no
- # destination = localhost
- # remote write URL path = /receive
- # data source = average
- # prefix = netdata
- # hostname = my_hostname
- # update every = 10
- # buffer on failures = 10
- # timeout ms = 20000
- # send names instead of ids = yes
- # send charts matching = *
- # send hosts matching = localhost *
-
-# [kinesis:my_kinesis_instance]
- # enabled = no
- # destination = us-east-1
- # stream name = netdata
- # aws_access_key_id = my_access_key_id
- # aws_secret_access_key = my_aws_secret_access_key
- # data source = average
- # prefix = netdata
- # hostname = my_hostname
- # update every = 10
- # buffer on failures = 10
- # timeout ms = 20000
- # send names instead of ids = yes
- # send charts matching = *
- # send hosts matching = localhost *
-
-# [pubsub:my_pubsub_instance]
- # enabled = no
- # destination = pubsub.googleapis.com
- # credentials file = /etc/netdata/pubsub_credentials.json
- # project id = my_project
- # topic id = my_topic
- # data source = average
- # prefix = netdata
- # hostname = my_hostname
- # update every = 10
- # buffer on failures = 10
- # timeout ms = 20000
- # send names instead of ids = yes
- # send charts matching = *
- # send hosts matching = localhost *
-
-# [mongodb:my_mongodb_instance]
- # enabled = no
- # destination = localhost
- # database = my_database
- # collection = my_collection
- # data source = average
- # prefix = netdata
- # hostname = my_hostname
- # update every = 10
- # buffer on failures = 10
- # timeout ms = 20000
- # send names instead of ids = yes
- # send charts matching = *
- # send hosts matching = localhost *
diff --git a/openwrt-app-actions/applications/luci-app-netdata/root/etc/netdata/netdata.conf b/openwrt-app-actions/applications/luci-app-netdata/root/etc/netdata/netdata.conf
deleted file mode 100755
index 4b0f5a38b..000000000
--- a/openwrt-app-actions/applications/luci-app-netdata/root/etc/netdata/netdata.conf
+++ /dev/null
@@ -1,43 +0,0 @@
-
-[global]
- update every = 2
- memory deduplication (ksm) = no
- debug log = syslog
- error log = syslog
- access log = none
- run as user = root
-
-[web]
- allow connections from = localhost 10.* 192.168.* 172.16.* 172.17.* 172.18.* 172.19.* 172.20.* 172.21.* 172.22.* 172.23.* 172.24.* 172.25.* 172.26.* 172.27.* 172.28.* 172.29.* 172.30.* 172.31.*
- allow dashboard from = localhost 10.* 192.168.* 172.16.* 172.17.* 172.18.* 172.19.* 172.20.* 172.21.* 172.22.* 172.23.* 172.24.* 172.25.* 172.26.* 172.27.* 172.28.* 172.29.* 172.30.* 172.31.*
-
-[plugins]
- cgroups = no
- apps = no
- charts.d = no
- fping = no
- node.d = no
- python.d = no
-
-
-[plugin:proc]
- ipc =no
- /proc/sysvipc/shm = no
- /sys/devices/system/edac/mc = no
- /sys/devices/system/node = no
- /proc/net/sockstat = no
- /proc/net/netstat = no
- /proc/net/snmp = no
- /proc/net/softnet_stat = no
- /proc/net/sctp/snmp = no
- /proc/net/ip_vs/stats = no
- /proc/net/stat/synproxy = no
- /sys/kernel/mm/ksm = no
- /dev/mapper = no
-
-[plugin:proc:/proc/diskstats]
- path to /dev/vx/dsk =
- path to /dev/disk/by-label =
-
-[health]
- enabled = no
diff --git a/openwrt-app-actions/applications/luci-app-netdata/root/etc/netdata/stream.conf b/openwrt-app-actions/applications/luci-app-netdata/root/etc/netdata/stream.conf
deleted file mode 100755
index b5142632d..000000000
--- a/openwrt-app-actions/applications/luci-app-netdata/root/etc/netdata/stream.conf
+++ /dev/null
@@ -1,205 +0,0 @@
-# netdata configuration for aggregating data from remote hosts
-#
-# API keys authorize a pair of sending-receiving netdata servers.
-# Once their communication is authorized, they can exchange metrics for any
-# number of hosts.
-#
-# You can generate API keys, with the linux command: uuidgen
-
-
-# -----------------------------------------------------------------------------
-# 1. ON CHILD NETDATA - THE ONE THAT WILL BE SENDING METRICS
-
-[stream]
- # Enable this on child nodes, to have them send metrics.
- enabled = no
-
- # Where is the receiving netdata?
- # A space separated list of:
- #
- # [PROTOCOL:]HOST[%INTERFACE][:PORT][:SSL]
- #
- # If many are given, the first available will get the metrics.
- #
- # PROTOCOL = tcp, udp, or unix (only tcp and unix are supported by parent nodes)
- # HOST = an IPv4, IPv6 IP, or a hostname, or a unix domain socket path.
- # IPv6 IPs should be given with brackets [ip:address]
- # INTERFACE = the network interface to use (only for IPv6)
- # PORT = the port number or service name (/etc/services)
- # SSL = when this word appear at the end of the destination string
- # the Netdata will encrypt the connection with the parent.
- #
- # This communication is not HTTP (it cannot be proxied by web proxies).
- destination =
-
- # Skip Certificate verification?
- #
- # The netdata child is configurated to avoid invalid SSL/TLS certificate,
- # so certificates that are self-signed or expired will stop the streaming.
- # Case the server certificate is not valid, you can enable the use of
- # 'bad' certificates setting the next option as 'yes'.
- #
- #ssl skip certificate verification = yes
-
- # Certificate Authority Path
- #
- # OpenSSL has a default directory where the known certificates are stored,
- # case it is necessary it is possible to change this rule using the variable
- # "CApath"
- #
- #CApath = /etc/ssl/certs/
-
- # Certificate Authority file
- #
- # When the Netdata parent has certificate, that is not recognized as valid,
- # we can add this certificate in the list of known certificates in CApath
- # and give for Netdata as argument.
- #
- #CAfile = /etc/ssl/certs/cert.pem
-
- # The API_KEY to use (as the sender)
- api key =
-
- # The timeout to connect and send metrics
- timeout seconds = 60
-
- # If the destination line above does not specify a port, use this
- default port = 19999
-
- # filter the charts to be streamed
- # netdata SIMPLE PATTERN:
- # - space separated list of patterns (use \ to include spaces in patterns)
- # - use * as wildcard, any number of times within each pattern
- # - prefix a pattern with ! for a negative match (ie not stream the charts it matches)
- # - the order of patterns is important (left to right)
- # To send all except a few, use: !this !that * (ie append a wildcard pattern)
- send charts matching = *
-
- # The buffer to use for sending metrics.
- # 1MB is good for 10-20 seconds of data, so increase this if you expect latencies.
- # The buffer is flushed on reconnects (this will not prevent gaps at the charts).
- buffer size bytes = 1048576
-
- # If the connection fails, or it disconnects,
- # retry after that many seconds.
- reconnect delay seconds = 5
-
- # Sync the clock of the charts for that many iterations, when starting.
- initial clock resync iterations = 60
-
-# -----------------------------------------------------------------------------
-# 2. ON PARENT NETDATA - THE ONE THAT WILL BE RECEIVING METRICS
-
-# You can have one API key per child,
-# or the same API key for all child nodes.
-#
-# netdata searches for options in this order:
-#
-# a) parent netdata settings (netdata.conf)
-# b) [stream] section (above)
-# c) [API_KEY] section (below, settings for the API key)
-# d) [MACHINE_GUID] section (below, settings for each machine)
-#
-# You can combine the above (the more specific setting will be used).
-
-# API key authentication
-# If the key is not listed here, it will not be able to push metrics.
-
-# [API_KEY] is [YOUR-API-KEY], i.e [11111111-2222-3333-4444-555555555555]
-[API_KEY]
- # Default settings for this API key
-
- # You can disable the API key, by setting this to: no
- # The default (for unknown API keys) is: no
- enabled = no
-
- # A list of simple patterns matching the IPs of the servers that
- # will be pushing metrics using this API key.
- # The metrics are received via the API port, so the same IPs
- # should also be matched at netdata.conf [web].allow connections from
- allow from = *
-
- # The default history in entries, for all hosts using this API key.
- # You can also set it per host below.
- # If you don't set it here, the history size of the central netdata
- # will be used.
- default history = 3600
-
- # The default memory mode to be used for all hosts using this API key.
- # You can also set it per host below.
- # If you don't set it here, the memory mode of netdata.conf will be used.
- # Valid modes:
- # save save on exit, load on start
- # map like swap (continuously syncing to disks - you need SSD)
- # ram keep it in RAM, don't touch the disk
- # none no database at all (use this on headless proxies)
- # dbengine like a traditional database
- default memory mode = ram
-
- # Shall we enable health monitoring for the hosts using this API key?
- # 3 possible values:
- # yes enable alarms
- # no do not enable alarms
- # auto enable alarms, only when the sending netdata is connected. For ephemeral child nodes or child system restarts,
- # ensure that the netdata process on the child is gracefully stopped, to prevent invalid last_collected alarms
- # You can also set it per host, below.
- # The default is taken from [health].enabled of netdata.conf
- health enabled by default = auto
-
- # postpone alarms for a short period after the sender is connected
- default postpone alarms on connect seconds = 60
-
- # need to route metrics differently? set these.
- # the defaults are the ones at the [stream] section (above)
- #default proxy enabled = yes | no
- #default proxy destination = IP:PORT IP:PORT ...
- #default proxy api key = API_KEY
- #default proxy send charts matching = *
-
-
-# -----------------------------------------------------------------------------
-# 3. PER SENDING HOST SETTINGS, ON PARENT NETDATA
-# THIS IS OPTIONAL - YOU DON'T HAVE TO CONFIGURE IT
-
-# This section exists to give you finer control of the parent settings for each
-# child host, when the same API key is used by many netdata child nodes / proxies.
-#
-# Each netdata has a unique GUID - generated the first time netdata starts.
-# You can find it at /var/lib/netdata/registry/netdata.public.unique.id
-# (at the child).
-#
-# The host sending data will have one. If the host is not ephemeral,
-# you can give settings for each sending host here.
-
-[MACHINE_GUID]
- # enable this host: yes | no
- # When disabled, the parent will not receive metrics for this host.
- # THIS IS NOT A SECURITY MECHANISM - AN ATTACKER CAN SET ANY OTHER GUID.
- # Use only the API key for security.
- enabled = no
-
- # A list of simple patterns matching the IPs of the servers that
- # will be pushing metrics using this MACHINE GUID.
- # The metrics are received via the API port, so the same IPs
- # should also be matched at netdata.conf [web].allow connections from
- # and at stream.conf [API_KEY].allow from
- allow from = *
-
- # The number of entries in the database
- history = 3600
-
- # The memory mode of the database: save | map | ram | none | dbengine
- memory mode = save
-
- # Health / alarms control: yes | no | auto
- health enabled = yes
-
- # postpone alarms when the sender connects
- postpone alarms on connect seconds = 60
-
- # need to route metrics differently?
- # the defaults are the ones at the [API KEY] section
- #proxy enabled = yes | no
- #proxy destination = IP:PORT IP:PORT ...
- #proxy api key = API_KEY
- #proxy send charts matching = *
diff --git a/openwrt-app-actions/applications/luci-app-netdata/root/etc/uci-defaults/40_luci-app-netdata b/openwrt-app-actions/applications/luci-app-netdata/root/etc/uci-defaults/40_luci-app-netdata
deleted file mode 100755
index a6e6d8445..000000000
--- a/openwrt-app-actions/applications/luci-app-netdata/root/etc/uci-defaults/40_luci-app-netdata
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-[ -f /usr/share/netdata/webcn/dashboard.js ] && mv -f /usr/share/netdata/webcn/dashboard.js /usr/share/netdata/web/dashboard.js
-[ -f /usr/share/netdata/webcn/dashboard_info.js ] && mv -f /usr/share/netdata/webcn/dashboard_info.js /usr/share/netdata/web/dashboard_info.js
-[ -f /usr/share/netdata/webcn/main.js ] && mv -f /usr/share/netdata/webcn/dashboard.js /usr/share/netdata/web/main.js
-[ -f /usr/share/netdata/webcn/index.html ] && mv -f /usr/share/netdata/webcn/index.html /usr/share/netdata/web/index.html
-
-rm -rf /tmp/luci-modulecache /tmp/luci-indexcache*
-exit 0
diff --git a/openwrt-app-actions/applications/luci-app-netdata/root/usr/share/netdata/webcn/dashboard.js b/openwrt-app-actions/applications/luci-app-netdata/root/usr/share/netdata/webcn/dashboard.js
deleted file mode 100755
index f20f35271..000000000
--- a/openwrt-app-actions/applications/luci-app-netdata/root/usr/share/netdata/webcn/dashboard.js
+++ /dev/null
@@ -1,10378 +0,0 @@
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-// DO NOT EDIT: This file is automatically generated from the source files in src/
-
-// ----------------------------------------------------------------------------
-// You can set the following variables before loading this script:
-
-// 'use strict';
-
-/*global netdataNoDygraphs *//* boolean, disable dygraph charts
- * (default: false) */
-/*global netdataNoSparklines *//* boolean, disable sparkline charts
- * (default: false) */
-/*global netdataNoPeitys *//* boolean, disable peity charts
- * (default: false) */
-/*global netdataNoGoogleCharts *//* boolean, disable google charts
- * (default: false) */
-/*global netdataNoMorris *//* boolean, disable morris charts
- * (default: false) */
-/*global netdataNoEasyPieChart *//* boolean, disable easypiechart charts
- * (default: false) */
-/*global netdataNoGauge *//* boolean, disable gauge.js charts
- * (default: false) */
-/*global netdataNoD3 *//* boolean, disable d3 charts
- * (default: false) */
-/*global netdataNoC3 *//* boolean, disable c3 charts
- * (default: false) */
-/*global netdataNoD3pie *//* boolean, disable d3pie charts
- * (default: false) */
-/*global netdataNoBootstrap *//* boolean, disable bootstrap - disables help too
- * (default: false) */
-/*global netdataNoFontAwesome *//* boolean, disable fontawesome (do not load it)
- * (default: false) */
-/*global netdataIcons *//* object, overwrite netdata fontawesome icons
- * (default: null) */
-/*global netdataDontStart *//* boolean, do not start the thread to process the charts
- * (default: false) */
-/*global netdataErrorCallback *//* function, callback to be called when the dashboard encounters an error
- * (default: null) */
-/*global netdataRegistry:true *//* boolean, use the netdata registry
- * (default: false) */
-/*global netdataNoRegistry *//* boolean, included only for compatibility with existing custom dashboard
- * (obsolete - do not use this any more) */
-/*global netdataRegistryCallback *//* function, callback that will be invoked with one param: the URLs from the registry
- * (default: null) */
-/*global netdataShowHelp:true *//* boolean, disable charts help
- * (default: true) */
-/*global netdataShowAlarms:true *//* boolean, enable alarms checks and notifications
- * (default: false) */
-/*global netdataRegistryAfterMs:true *//* ms, delay registry use at started
- * (default: 1500) */
-/*global netdataCallback *//* function, callback to be called when netdata is ready to start
- * (default: null)
- * netdata will be running while this is called
- * (call NETDATA.pause to stop it) */
-/*global netdataPrepCallback *//* function, callback to be called before netdata does anything else
- * (default: null) */
-/*global netdataServer *//* string, the URL of the netdata server to use
- * (default: the URL the page is hosted at) */
-/*global netdataServerStatic *//* string, the URL of the netdata server to use for static files
- * (default: netdataServer) */
-/*global netdataSnapshotData *//* object, a netdata snapshot loaded
- * (default: null) */
-/*global netdataAlarmsRecipients *//* array, an array of alarm recipients to show notifications for
- * (default: null) */
-/*global netdataAlarmsRemember *//* boolen, keep our position in the alarm log at browser local storage
- * (default: true) */
-/*global netdataAlarmsActiveCallback *//* function, a hook for the alarm logs
- * (default: undefined) */
-/*global netdataAlarmsNotifCallback *//* function, a hook for alarm notifications
- * (default: undefined) */
-/*global netdataIntersectionObserver *//* boolean, enable or disable the use of intersection observer
- * (default: true) */
-/*global netdataCheckXSS *//* boolean, enable or disable checking for XSS issues
- * (default: false) */
-
-// ----------------------------------------------------------------------------
-// global namespace
-
-// Should stay var!
-var NETDATA = window.NETDATA || {};
-
-(function(window, document, $, undefined) {
-
-// *** src/dashboard.js/utils.js
-
-NETDATA.name2id = function (s) {
- return s
- .replace(/ /g, '_')
- .replace(/:/g, '_')
- .replace(/\(/g, '_')
- .replace(/\)/g, '_')
- .replace(/\./g, '_')
- .replace(/\//g, '_');
-};
-
-NETDATA.encodeURIComponent = function (s) {
- if (typeof(s) === 'string') {
- return encodeURIComponent(s);
- }
-
- return s;
-};
-
-/// A heuristic for detecting slow devices.
-let isSlowDeviceResult = undefined;
-const isSlowDevice = function () {
- if (!isSlowDeviceResult) {
- return isSlowDeviceResult;
- }
-
- try {
- let ua = navigator.userAgent.toLowerCase();
-
- let iOS = /ipad|iphone|ipod/.test(ua) && !window.MSStream;
- let android = /android/.test(ua) && !window.MSStream;
- isSlowDeviceResult = (iOS || android);
- } catch (e) {
- isSlowDeviceResult = false;
- }
-
- return isSlowDeviceResult;
-};
-
-NETDATA.guid = function () {
- function s4() {
- return Math.floor((1 + Math.random()) * 0x10000)
- .toString(16)
- .substring(1);
- }
-
- return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
-};
-
-NETDATA.zeropad = function (x) {
- if (x > -10 && x < 10) {
- return '0' + x.toString();
- } else {
- return x.toString();
- }
-};
-
-NETDATA.seconds4human = function (seconds, options) {
- let defaultOptions = {
- now: '现在',
- space: ' ',
- negative_suffix: '前',
- day: '日',
- days: '日',
- hour: '小时',
- hours: '小时',
- minute: '分钟',
- minutes: '分钟',
- second: '秒',
- seconds: '秒',
- and: '及'
- };
-
- if (typeof options !== 'object') {
- options = defaultOptions;
- } else {
- for (var x in defaultOptions) {
- if (typeof options[x] !== 'string') {
- options[x] = defaultOptions[x];
- }
- }
- }
-
- if (typeof seconds === 'string') {
- seconds = parseInt(seconds, 10);
- }
-
- if (seconds === 0) {
- return options.now;
- }
-
- let suffix = '';
- if (seconds < 0) {
- seconds = -seconds;
- if (options.negative_suffix !== '') {
- suffix = options.space + options.negative_suffix;
- }
- }
-
- let days = Math.floor(seconds / 86400);
- seconds -= (days * 86400);
-
- let hours = Math.floor(seconds / 3600);
- seconds -= (hours * 3600);
-
- let minutes = Math.floor(seconds / 60);
- seconds -= (minutes * 60);
-
- let strings = [];
-
- if (days > 1) {
- strings.push(days.toString() + options.space + options.days);
- } else if (days === 1) {
- strings.push(days.toString() + options.space + options.day);
- }
-
- if (hours > 1) {
- strings.push(hours.toString() + options.space + options.hours);
- } else if (hours === 1) {
- strings.push(hours.toString() + options.space + options.hour);
- }
-
- if (minutes > 1) {
- strings.push(minutes.toString() + options.space + options.minutes);
- } else if (minutes === 1) {
- strings.push(minutes.toString() + options.space + options.minute);
- }
-
- if (seconds > 1) {
- strings.push(Math.floor(seconds).toString() + options.space + options.seconds);
- } else if (seconds === 1) {
- strings.push(Math.floor(seconds).toString() + options.space + options.second);
- }
-
- if (strings.length === 1) {
- return strings.pop() + suffix;
- }
-
- let last = strings.pop();
- return strings.join(", ") + " " + options.and + " " + last + suffix;
-};
-
-// ----------------------------------------------------------------------------------------------------------------
-// element data attributes
-
-NETDATA.dataAttribute = function (element, attribute, def) {
- let key = 'data-' + attribute.toString();
- if (element.hasAttribute(key)) {
- let data = element.getAttribute(key);
-
- if (data === 'true') {
- return true;
- }
- if (data === 'false') {
- return false;
- }
- if (data === 'null') {
- return null;
- }
-
- // Only convert to a number if it doesn't change the string
- if (data === +data + '') {
- return +data;
- }
-
- if (/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/.test(data)) {
- return JSON.parse(data);
- }
-
- return data;
- } else {
- return def;
- }
-};
-
-NETDATA.dataAttributeBoolean = function (element, attribute, def) {
- let value = NETDATA.dataAttribute(element, attribute, def);
-
- if (value === true || value === false) // gmosx: Love this :)
- {
- return value;
- }
-
- if (typeof(value) === 'string') {
- if (value === 'yes' || value === 'on') {
- return true;
- }
-
- if (value === '' || value === 'no' || value === 'off' || value === 'null') {
- return false;
- }
-
- return def;
- }
-
- if (typeof(value) === 'number') {
- return value !== 0;
- }
-
- return def;
-};
-
-// ----------------------------------------------------------------------------------------------------------------
-// fast numbers formatting
-
-NETDATA.fastNumberFormat = {
- formattersFixed: [],
- formattersZeroBased: [],
-
- // this is the fastest and the preferred
- getIntlNumberFormat: function (min, max) {
- let key = max;
- if (min === max) {
- if (typeof this.formattersFixed[key] === 'undefined') {
- this.formattersFixed[key] = new Intl.NumberFormat(undefined, {
- // style: 'decimal',
- // minimumIntegerDigits: 1,
- // minimumSignificantDigits: 1,
- // maximumSignificantDigits: 1,
- useGrouping: true,
- minimumFractionDigits: min,
- maximumFractionDigits: max
- });
- }
-
- return this.formattersFixed[key];
- } else if (min === 0) {
- if (typeof this.formattersZeroBased[key] === 'undefined') {
- this.formattersZeroBased[key] = new Intl.NumberFormat(undefined, {
- // style: 'decimal',
- // minimumIntegerDigits: 1,
- // minimumSignificantDigits: 1,
- // maximumSignificantDigits: 1,
- useGrouping: true,
- minimumFractionDigits: min,
- maximumFractionDigits: max
- });
- }
-
- return this.formattersZeroBased[key];
- } else {
- // this is never used
- // it is added just for completeness
- return new Intl.NumberFormat(undefined, {
- // style: 'decimal',
- // minimumIntegerDigits: 1,
- // minimumSignificantDigits: 1,
- // maximumSignificantDigits: 1,
- useGrouping: true,
- minimumFractionDigits: min,
- maximumFractionDigits: max
- });
- }
- },
-
- // this respects locale
- getLocaleString: function (min, max) {
- let key = max;
- if (min === max) {
- if (typeof this.formattersFixed[key] === 'undefined') {
- this.formattersFixed[key] = {
- format: function (value) {
- return value.toLocaleString(undefined, {
- // style: 'decimal',
- // minimumIntegerDigits: 1,
- // minimumSignificantDigits: 1,
- // maximumSignificantDigits: 1,
- useGrouping: true,
- minimumFractionDigits: min,
- maximumFractionDigits: max
- });
- }
- };
- }
-
- return this.formattersFixed[key];
- } else if (min === 0) {
- if (typeof this.formattersZeroBased[key] === 'undefined') {
- this.formattersZeroBased[key] = {
- format: function (value) {
- return value.toLocaleString(undefined, {
- // style: 'decimal',
- // minimumIntegerDigits: 1,
- // minimumSignificantDigits: 1,
- // maximumSignificantDigits: 1,
- useGrouping: true,
- minimumFractionDigits: min,
- maximumFractionDigits: max
- });
- }
- };
- }
-
- return this.formattersZeroBased[key];
- } else {
- return {
- format: function (value) {
- return value.toLocaleString(undefined, {
- // style: 'decimal',
- // minimumIntegerDigits: 1,
- // minimumSignificantDigits: 1,
- // maximumSignificantDigits: 1,
- useGrouping: true,
- minimumFractionDigits: min,
- maximumFractionDigits: max
- });
- }
- };
- }
- },
-
- // the fallback
- getFixed: function (min, max) {
- let key = max;
- if (min === max) {
- if (typeof this.formattersFixed[key] === 'undefined') {
- this.formattersFixed[key] = {
- format: function (value) {
- if (value === 0) {
- return "0";
- }
- return value.toFixed(max);
- }
- };
- }
-
- return this.formattersFixed[key];
- } else if (min === 0) {
- if (typeof this.formattersZeroBased[key] === 'undefined') {
- this.formattersZeroBased[key] = {
- format: function (value) {
- if (value === 0) {
- return "0";
- }
- return value.toFixed(max);
- }
- };
- }
-
- return this.formattersZeroBased[key];
- } else {
- return {
- format: function (value) {
- if (value === 0) {
- return "0";
- }
- return value.toFixed(max);
- }
- };
- }
- },
-
- testIntlNumberFormat: function () {
- let value = 1.12345;
- let e1 = "1.12", e2 = "1,12";
- let s = "";
-
- try {
- let x = new Intl.NumberFormat(undefined, {
- useGrouping: true,
- minimumFractionDigits: 2,
- maximumFractionDigits: 2
- });
-
- s = x.format(value);
- } catch (e) {
- s = "";
- }
-
- // console.log('NumberFormat: ', s);
- return (s === e1 || s === e2);
- },
-
- testLocaleString: function () {
- let value = 1.12345;
- let e1 = "1.12", e2 = "1,12";
- let s = "";
-
- try {
- s = value.toLocaleString(undefined, {
- useGrouping: true,
- minimumFractionDigits: 2,
- maximumFractionDigits: 2
- });
- } catch (e) {
- s = "";
- }
-
- // console.log('localeString: ', s);
- return (s === e1 || s === e2);
- },
-
- // on first run we decide which formatter to use
- get: function (min, max) {
- if (this.testIntlNumberFormat()) {
- // console.log('numberformat');
- this.get = this.getIntlNumberFormat;
- } else if (this.testLocaleString()) {
- // console.log('localestring');
- this.get = this.getLocaleString;
- } else {
- // console.log('fixed');
- this.get = this.getFixed;
- }
- return this.get(min, max);
- }
-};
-
-// ----------------------------------------------------------------------------------------------------------------
-// Detect the netdata server
-
-// http://stackoverflow.com/questions/984510/what-is-my-script-src-url
-// http://stackoverflow.com/questions/6941533/get-protocol-domain-and-port-from-url
-NETDATA._scriptSource = function () {
- let script = null;
-
- if (typeof document.currentScript !== 'undefined') {
- script = document.currentScript;
- } else {
- const all_scripts = document.getElementsByTagName('script');
- script = all_scripts[all_scripts.length - 1];
- }
-
- if (typeof script.getAttribute.length !== 'undefined') {
- script = script.src;
- } else {
- script = script.getAttribute('src', -1);
- }
-
- return script;
-};
-
-// *** src/dashboard.js/server-detection.js
-
-if (typeof netdataServer !== 'undefined') {
- NETDATA.serverDefault = netdataServer;
-} else {
- let s = NETDATA._scriptSource();
- if (s) {
- NETDATA.serverDefault = s.replace(/\/dashboard.js(\?.*)?$/g, "");
- } else {
- console.log('WARNING: Cannot detect the URL of the netdata server.');
- NETDATA.serverDefault = null;
- }
-}
-
-if (NETDATA.serverDefault === null) {
- NETDATA.serverDefault = '';
-} else if (NETDATA.serverDefault.slice(-1) !== '/') {
- NETDATA.serverDefault += '/';
-}
-
-if (typeof netdataServerStatic !== 'undefined' && netdataServerStatic !== null && netdataServerStatic !== '') {
- NETDATA.serverStatic = netdataServerStatic;
- if (NETDATA.serverStatic.slice(-1) !== '/') {
- NETDATA.serverStatic += '/';
- }
-} else {
- NETDATA.serverStatic = NETDATA.serverDefault;
-}
-
-// *** src/dashboard.js/dependencies.js
-
-// default URLs for all the external files we need
-// make them RELATIVE so that the whole thing can also be
-// installed under a web server
-NETDATA.jQuery = NETDATA.serverStatic + 'lib/jquery-2.2.4.min.js';
-NETDATA.peity_js = NETDATA.serverStatic + 'lib/jquery.peity-3.2.0.min.js';
-NETDATA.sparkline_js = NETDATA.serverStatic + 'lib/jquery.sparkline-2.1.2.min.js';
-NETDATA.easypiechart_js = NETDATA.serverStatic + 'lib/jquery.easypiechart-97b5824.min.js';
-NETDATA.gauge_js = NETDATA.serverStatic + 'lib/gauge-1.3.2.min.js';
-NETDATA.dygraph_js = NETDATA.serverStatic + 'lib/dygraph-c91c859.min.js';
-NETDATA.dygraph_smooth_js = NETDATA.serverStatic + 'lib/dygraph-smooth-plotter-c91c859.js';
-// NETDATA.raphael_js = NETDATA.serverStatic + 'lib/raphael-2.2.4-min.js';
-// NETDATA.c3_js = NETDATA.serverStatic + 'lib/c3-0.4.18.min.js';
-// NETDATA.c3_css = NETDATA.serverStatic + 'css/c3-0.4.18.min.css';
-NETDATA.d3pie_js = NETDATA.serverStatic + 'lib/d3pie-0.2.1-netdata-3.js';
-NETDATA.d3_js = NETDATA.serverStatic + 'lib/d3-4.12.2.min.js';
-// NETDATA.morris_js = NETDATA.serverStatic + 'lib/morris-0.5.1.min.js';
-// NETDATA.morris_css = NETDATA.serverStatic + 'css/morris-0.5.1.css';
-NETDATA.google_js = 'https://www.google.com/jsapi';
-// Error Handling
-
-NETDATA.errorCodes = {
- 100: {message: "Cannot load chart library", alert: true},
- 101: {message: "Cannot load jQuery", alert: true},
- 402: {message: "Chart library not found", alert: false},
- 403: {message: "Chart library not enabled/is failed", alert: false},
- 404: {message: "Chart not found", alert: false},
- 405: {message: "Cannot download charts index from server", alert: true},
- 406: {message: "Invalid charts index downloaded from server", alert: true},
- 407: {message: "Cannot HELLO netdata server", alert: false},
- 408: {message: "Netdata servers sent invalid response to HELLO", alert: false},
- 409: {message: "Cannot ACCESS netdata registry", alert: false},
- 410: {message: "Netdata registry ACCESS failed", alert: false},
- 411: {message: "Netdata registry server send invalid response to DELETE ", alert: false},
- 412: {message: "Netdata registry DELETE failed", alert: false},
- 413: {message: "Netdata registry server send invalid response to SWITCH ", alert: false},
- 414: {message: "Netdata registry SWITCH failed", alert: false},
- 415: {message: "Netdata alarms download failed", alert: false},
- 416: {message: "Netdata alarms log download failed", alert: false},
- 417: {message: "Netdata registry server send invalid response to SEARCH ", alert: false},
- 418: {message: "Netdata registry SEARCH failed", alert: false}
-};
-
-NETDATA.errorLast = {
- code: 0,
- message: "",
- datetime: 0
-};
-
-NETDATA.error = function (code, msg) {
- NETDATA.errorLast.code = code;
- NETDATA.errorLast.message = msg;
- NETDATA.errorLast.datetime = Date.now();
-
- console.log("ERROR " + code + ": " + NETDATA.errorCodes[code].message + ": " + msg);
-
- let ret = true;
- if (typeof netdataErrorCallback === 'function') {
- ret = netdataErrorCallback('system', code, msg);
- }
-
- if (ret && NETDATA.errorCodes[code].alert) {
- alert("ERROR " + code + ": " + NETDATA.errorCodes[code].message + ": " + msg);
- }
-};
-
-NETDATA.errorReset = function () {
- NETDATA.errorLast.code = 0;
- NETDATA.errorLast.message = "You are doing fine!";
- NETDATA.errorLast.datetime = 0;
-};
-// *** src/dashboard.js/compatibility.js
-
-// Compatibility fixes.
-
-// fix IE issue with console
-if (!window.console) {
- window.console = {
- log: function () {
- }
- };
-}
-
-// if string.endsWith is not defined, define it
-if (typeof String.prototype.endsWith !== 'function') {
- String.prototype.endsWith = function (s) {
- if (s.length > this.length) {
- return false;
- }
- return this.slice(-s.length) === s;
- };
-}
-
-// if string.startsWith is not defined, define it
-if (typeof String.prototype.startsWith !== 'function') {
- String.prototype.startsWith = function (s) {
- if (s.length > this.length) {
- return false;
- }
- return this.slice(s.length) === s;
- };
-}
-// ----------------------------------------------------------------------------------------------------------------
-// XSS checks
-
-NETDATA.xss = {
- enabled: (typeof netdataCheckXSS === 'undefined') ? false : netdataCheckXSS,
- enabled_for_data: (typeof netdataCheckXSS === 'undefined') ? false : netdataCheckXSS,
-
- string: function (s) {
- return s.toString()
- .replace(//g, '>')
- .replace(/"/g, '"')
- .replace(/'/g, ''');
- },
-
- object: function (name, obj, ignore_regex) {
- if (typeof ignore_regex !== 'undefined' && ignore_regex.test(name)) {
- // console.log('XSS: ignoring "' + name + '"');
- return obj;
- }
-
- switch (typeof(obj)) {
- case 'string':
- const ret = this.string(obj);
- if (ret !== obj) {
- console.log('XSS protection changed string ' + name + ' from "' + obj + '" to "' + ret + '"');
- }
- return ret;
-
- case 'object':
- if (obj === null) {
- return obj;
- }
-
- if (Array.isArray(obj)) {
- // console.log('checking array "' + name + '"');
-
- let len = obj.length;
- while (len--) {
- obj[len] = this.object(name + '[' + len + ']', obj[len], ignore_regex);
- }
- } else {
- // console.log('checking object "' + name + '"');
-
- for (var i in obj) {
- if (obj.hasOwnProperty(i) === false) {
- continue;
- }
- if (this.string(i) !== i) {
- console.log('XSS protection removed invalid object member "' + name + '.' + i + '"');
- delete obj[i];
- } else {
- obj[i] = this.object(name + '.' + i, obj[i], ignore_regex);
- }
- }
- }
- return obj;
-
- default:
- return obj;
- }
- },
-
- checkOptional: function (name, obj, ignore_regex) {
- if (this.enabled) {
- //console.log('XSS: checking optional "' + name + '"...');
- return this.object(name, obj, ignore_regex);
- }
- return obj;
- },
-
- checkAlways: function (name, obj, ignore_regex) {
- //console.log('XSS: checking always "' + name + '"...');
- return this.object(name, obj, ignore_regex);
- },
-
- checkData: function (name, obj, ignore_regex) {
- if (this.enabled_for_data) {
- //console.log('XSS: checking data "' + name + '"...');
- return this.object(name, obj, ignore_regex);
- }
- return obj;
- }
-};
-NETDATA.colorHex2Rgb = function (hex) {
- // Expand shorthand form (e.g. "03F") to full form (e.g. "0033FF")
- let shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
- hex = hex.replace(shorthandRegex, function (m, r, g, b) {
- return r + r + g + g + b + b;
- });
-
- let result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
- return result ? {
- r: parseInt(result[1], 16),
- g: parseInt(result[2], 16),
- b: parseInt(result[3], 16)
- } : null;
-};
-
-NETDATA.colorLuminance = function (hex, lum) {
- // validate hex string
- hex = String(hex).replace(/[^0-9a-f]/gi, '');
- if (hex.length < 6) {
- hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
- }
-
- lum = lum || 0;
-
- // convert to decimal and change luminosity
- let rgb = "#";
- for (let i = 0; i < 3; i++) {
- let c = parseInt(hex.substr(i * 2, 2), 16);
- c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16);
- rgb += ("00" + c).substr(c.length);
- }
-
- return rgb;
-};
-NETDATA.unitsConversion = {
- keys: {}, // keys for data-common-units
- latest: {}, // latest selected units for data-common-units
-
- globalReset: function () {
- this.keys = {};
- this.latest = {};
- },
-
- scalableUnits: {
- 'packets/s': {
- 'pps': 1,
- 'Kpps': 1000,
- 'Mpps': 1000000
- },
- 'pps': {
- 'pps': 1,
- 'Kpps': 1000,
- 'Mpps': 1000000
- },
- 'kilobits/s': {
- 'bits/s': 1 / 1000,
- 'kilobits/s': 1,
- 'megabits/s': 1000,
- 'gigabits/s': 1000000,
- 'terabits/s': 1000000000
- },
- 'bytes/s': {
- 'bytes/s': 1,
- 'kilobytes/s': 1024,
- 'megabytes/s': 1024 * 1024,
- 'gigabytes/s': 1024 * 1024 * 1024,
- 'terabytes/s': 1024 * 1024 * 1024 * 1024
- },
- 'kilobytes/s': {
- 'bytes/s': 1 / 1024,
- 'kilobytes/s': 1,
- 'megabytes/s': 1024,
- 'gigabytes/s': 1024 * 1024,
- 'terabytes/s': 1024 * 1024 * 1024
- },
- 'B/s': {
- 'B/s': 1,
- 'KiB/s': 1024,
- 'MiB/s': 1024 * 1024,
- 'GiB/s': 1024 * 1024 * 1024,
- 'TiB/s': 1024 * 1024 * 1024 * 1024
- },
- 'KB/s': {
- 'B/s': 1 / 1024,
- 'KB/s': 1,
- 'MB/s': 1024,
- 'GB/s': 1024 * 1024,
- 'TB/s': 1024 * 1024 * 1024
- },
- 'KiB/s': {
- 'B/s': 1 / 1024,
- 'KiB/s': 1,
- 'MiB/s': 1024,
- 'GiB/s': 1024 * 1024,
- 'TiB/s': 1024 * 1024 * 1024
- },
- 'B': {
- 'B': 1,
- 'KiB': 1024,
- 'MiB': 1024 * 1024,
- 'GiB': 1024 * 1024 * 1024,
- 'TiB': 1024 * 1024 * 1024 * 1024,
- 'PiB': 1024 * 1024 * 1024 * 1024 * 1024
- },
- 'KB': {
- 'B': 1 / 1024,
- 'KB': 1,
- 'MB': 1024,
- 'GB': 1024 * 1024,
- 'TB': 1024 * 1024 * 1024
- },
- 'KiB': {
- 'B': 1 / 1024,
- 'KiB': 1,
- 'MiB': 1024,
- 'GiB': 1024 * 1024,
- 'TiB': 1024 * 1024 * 1024
- },
- 'MB': {
- 'B': 1 / (1024 * 1024),
- 'KB': 1 / 1024,
- 'MB': 1,
- 'GB': 1024,
- 'TB': 1024 * 1024,
- 'PB': 1024 * 1024 * 1024
- },
- 'MiB': {
- 'B': 1 / (1024 * 1024),
- 'KiB': 1 / 1024,
- 'MiB': 1,
- 'GiB': 1024,
- 'TiB': 1024 * 1024,
- 'PiB': 1024 * 1024 * 1024
- },
- 'GB': {
- 'B': 1 / (1024 * 1024 * 1024),
- 'KB': 1 / (1024 * 1024),
- 'MB': 1 / 1024,
- 'GB': 1,
- 'TB': 1024,
- 'PB': 1024 * 1024,
- 'EB': 1024 * 1024 * 1024
- },
- 'GiB': {
- 'B': 1 / (1024 * 1024 * 1024),
- 'KiB': 1 / (1024 * 1024),
- 'MiB': 1 / 1024,
- 'GiB': 1,
- 'TiB': 1024,
- 'PiB': 1024 * 1024,
- 'EiB': 1024 * 1024 * 1024
- },
- 'num': {
- 'num': 1,
- 'num (K)': 1000,
- 'num (M)': 1000000,
- 'num (G)': 1000000000,
- 'num (T)': 1000000000000
- }
- /*
- 'milliseconds': {
- 'seconds': 1000
- },
- 'seconds': {
- 'milliseconds': 0.001,
- 'seconds': 1,
- 'minutes': 60,
- 'hours': 3600,
- 'days': 86400
- }
- */
- },
-
- convertibleUnits: {
- 'Celsius': {
- 'Fahrenheit': {
- check: function (max) {
- void(max);
- return NETDATA.options.current.temperature === 'fahrenheit';
- },
- convert: function (value) {
- return value * 9 / 5 + 32;
- }
- }
- },
- 'celsius': {
- 'fahrenheit': {
- check: function (max) {
- void(max);
- return NETDATA.options.current.temperature === 'fahrenheit';
- },
- convert: function (value) {
- return value * 9 / 5 + 32;
- }
- }
- },
- 'seconds': {
- 'time': {
- check: function (max) {
- void(max);
- return NETDATA.options.current.seconds_as_time;
- },
- convert: function (seconds) {
- return NETDATA.unitsConversion.seconds2time(seconds);
- }
- }
- },
- 'milliseconds': {
- 'milliseconds': {
- check: function (max) {
- return NETDATA.options.current.seconds_as_time && max < 1000;
- },
- convert: function (milliseconds) {
- let tms = Math.round(milliseconds * 10);
- milliseconds = Math.floor(tms / 10);
-
- tms -= milliseconds * 10;
-
- return (milliseconds).toString() + '.' + tms.toString();
- }
- },
- 'seconds': {
- check: function (max) {
- return NETDATA.options.current.seconds_as_time && max >= 1000 && max < 60000;
- },
- convert: function (milliseconds) {
- milliseconds = Math.round(milliseconds);
-
- let seconds = Math.floor(milliseconds / 1000);
- milliseconds -= seconds * 1000;
-
- milliseconds = Math.round(milliseconds / 10);
-
- return seconds.toString() + '.'
- + NETDATA.zeropad(milliseconds);
- }
- },
- 'M:SS.ms': {
- check: function (max) {
- return NETDATA.options.current.seconds_as_time && max >= 60000;
- },
- convert: function (milliseconds) {
- milliseconds = Math.round(milliseconds);
-
- let minutes = Math.floor(milliseconds / 60000);
- milliseconds -= minutes * 60000;
-
- let seconds = Math.floor(milliseconds / 1000);
- milliseconds -= seconds * 1000;
-
- milliseconds = Math.round(milliseconds / 10);
-
- return minutes.toString() + ':'
- + NETDATA.zeropad(seconds) + '.'
- + NETDATA.zeropad(milliseconds);
- }
- }
- },
- 'nanoseconds': {
- 'nanoseconds': {
- check: function (max) {
- return NETDATA.options.current.seconds_as_time && max < 1000;
- },
- convert: function (nanoseconds) {
- let tms = Math.round(nanoseconds * 10);
- nanoseconds = Math.floor(tms / 10);
-
- tms -= nanoseconds * 10;
-
- return (nanoseconds).toString() + '.' + tms.toString();
- }
- },
- 'microseconds': {
- check: function (max) {
- return NETDATA.options.current.seconds_as_time
- && max >= 1000 && max < 1000 * 1000;
- },
- convert: function (nanoseconds) {
- nanoseconds = Math.round(nanoseconds);
-
- let microseconds = Math.floor(nanoseconds / 1000);
- nanoseconds -= microseconds * 1000;
-
- nanoseconds = Math.round(nanoseconds / 10 );
-
- return microseconds.toString() + '.'
- + NETDATA.zeropad(nanoseconds);
- }
- },
- 'milliseconds': {
- check: function (max) {
- return NETDATA.options.current.seconds_as_time
- && max >= 1000 * 1000 && max < 1000 * 1000 * 1000;
- },
- convert: function (nanoseconds) {
- nanoseconds = Math.round(nanoseconds);
-
- let milliseconds = Math.floor(nanoseconds / 1000 / 1000);
- nanoseconds -= milliseconds * 1000 * 1000;
-
- nanoseconds = Math.round(nanoseconds / 1000 / 10);
-
- return milliseconds.toString() + '.'
- + NETDATA.zeropad(nanoseconds);
- }
- },
- 'seconds': {
- check: function (max) {
- return NETDATA.options.current.seconds_as_time
- && max >= 1000 * 1000 * 1000;
- },
- convert: function (nanoseconds) {
- nanoseconds = Math.round(nanoseconds);
-
- let seconds = Math.floor(nanoseconds / 1000 / 1000 / 1000);
- nanoseconds -= seconds * 1000 * 1000 * 1000;
-
- nanoseconds = Math.round(nanoseconds / 1000 / 1000 / 10);
-
- return seconds.toString() + '.'
- + NETDATA.zeropad(nanoseconds);
- }
- },
- }
- },
-
- seconds2time: function (seconds) {
- seconds = Math.abs(seconds);
-
- let days = Math.floor(seconds / 86400);
- seconds -= days * 86400;
-
- let hours = Math.floor(seconds / 3600);
- seconds -= hours * 3600;
-
- let minutes = Math.floor(seconds / 60);
- seconds -= minutes * 60;
-
- seconds = Math.round(seconds);
-
- let ms_txt = '';
- /*
- let ms = seconds - Math.floor(seconds);
- seconds -= ms;
- ms = Math.round(ms * 1000);
-
- if (ms > 1) {
- if (ms < 10)
- ms_txt = '.00' + ms.toString();
- else if (ms < 100)
- ms_txt = '.0' + ms.toString();
- else
- ms_txt = '.' + ms.toString();
- }
- */
-
- return ((days > 0) ? days.toString() + 'd:' : '').toString()
- + NETDATA.zeropad(hours) + ':'
- + NETDATA.zeropad(minutes) + ':'
- + NETDATA.zeropad(seconds)
- + ms_txt;
- },
-
- // get a function that converts the units
- // + every time units are switched call the callback
- get: function (uuid, min, max, units, desired_units, common_units_name, switch_units_callback) {
- // validate the parameters
- if (typeof units === 'undefined') {
- units = 'undefined';
- }
-
- // check if we support units conversion
- if (typeof this.scalableUnits[units] === 'undefined' && typeof this.convertibleUnits[units] === 'undefined') {
- // we can't convert these units
- //console.log('DEBUG: ' + uuid.toString() + ' can\'t convert units: ' + units.toString());
- return function (value) {
- return value;
- };
- }
-
- // check if the caller wants the original units
- if (typeof desired_units === 'undefined' || desired_units === null || desired_units === 'original' || desired_units === units) {
- //console.log('DEBUG: ' + uuid.toString() + ' original units wanted');
- switch_units_callback(units);
- return function (value) {
- return value;
- };
- }
-
- // now we know we can convert the units
- // and the caller wants some kind of conversion
-
- let tunits = null;
- let tdivider = 0;
-
- if (typeof this.scalableUnits[units] !== 'undefined') {
- // units that can be scaled
- // we decide a divider
-
- // console.log('NETDATA.unitsConversion.get(' + units.toString() + ', ' + desired_units.toString() + ', function()) decide divider with min = ' + min.toString() + ', max = ' + max.toString());
-
- if (desired_units === 'auto') {
- // the caller wants to auto-scale the units
-
- // find the absolute maximum value that is rendered on the chart
- // based on this we decide the scale
- min = Math.abs(min);
- max = Math.abs(max);
- if (min > max) {
- max = min;
- }
-
- // find the smallest scale that provides integers
- // for (x in this.scalableUnits[units]) {
- // if (this.scalableUnits[units].hasOwnProperty(x)) {
- // let m = this.scalableUnits[units][x];
- // if (m <= max && m > tdivider) {
- // tunits = x;
- // tdivider = m;
- // }
- // }
- // }
- const sunit = this.scalableUnits[units];
- for (var x of Object.keys(sunit)) {
- let m = sunit[x];
- if (m <= max && m > tdivider) {
- tunits = x;
- tdivider = m;
- }
- }
-
- if (tunits === null || tdivider <= 0) {
- // we couldn't find one
- //console.log('DEBUG: ' + uuid.toString() + ' cannot find an auto-scaling candidate for units: ' + units.toString() + ' (max: ' + max.toString() + ')');
- switch_units_callback(units);
- return function (value) {
- return value;
- };
- }
-
- if (typeof common_units_name === 'string' && typeof uuid === 'string') {
- // the caller wants several charts to have the same units
- // data-common-units
-
- let common_units_key = common_units_name + '-' + units;
-
- // add our divider into the list of keys
- let t = this.keys[common_units_key];
- if (typeof t === 'undefined') {
- this.keys[common_units_key] = {};
- t = this.keys[common_units_key];
- }
- t[uuid] = {
- units: tunits,
- divider: tdivider
- };
-
- // find the max divider of all charts
- let common_units = t[uuid];
- for (var x in t) {
- if (t.hasOwnProperty(x) && t[x].divider > common_units.divider) {
- common_units = t[x];
- }
- }
-
- // save our common_max to the latest keys
- let latest = this.latest[common_units_key];
- if (typeof latest === 'undefined') {
- this.latest[common_units_key] = {};
- latest = this.latest[common_units_key];
- }
- latest.units = common_units.units;
- latest.divider = common_units.divider;
-
- tunits = latest.units;
- tdivider = latest.divider;
-
- //console.log('DEBUG: ' + uuid.toString() + ' converted units: ' + units.toString() + ' to units: ' + tunits.toString() + ' with divider ' + tdivider.toString() + ', common-units=' + common_units_name.toString() + ((t[uuid].divider !== tdivider)?' USED COMMON, mine was ' + t[uuid].units:' set common').toString());
-
- // apply it to this chart
- switch_units_callback(tunits);
- return function (value) {
- if (tdivider !== latest.divider) {
- // another chart switched our common units
- // we should switch them too
- //console.log('DEBUG: ' + uuid + ' switching units due to a common-units change, from ' + tunits.toString() + ' to ' + latest.units.toString());
- tunits = latest.units;
- tdivider = latest.divider;
- switch_units_callback(tunits);
- }
-
- return value / tdivider;
- };
- } else {
- // the caller did not give data-common-units
- // this chart auto-scales independently of all others
- //console.log('DEBUG: ' + uuid.toString() + ' converted units: ' + units.toString() + ' to units: ' + tunits.toString() + ' with divider ' + tdivider.toString() + ', autonomously');
-
- switch_units_callback(tunits);
- return function (value) {
- return value / tdivider;
- };
- }
- } else {
- // the caller wants specific units
-
- if (typeof this.scalableUnits[units][desired_units] !== 'undefined') {
- // all good, set the new units
- tdivider = this.scalableUnits[units][desired_units];
- // console.log('DEBUG: ' + uuid.toString() + ' converted units: ' + units.toString() + ' to units: ' + desired_units.toString() + ' with divider ' + tdivider.toString() + ', by reference');
- switch_units_callback(desired_units);
- return function (value) {
- return value / tdivider;
- };
- } else {
- // oops! switch back to original units
- console.log('Units conversion from ' + units.toString() + ' to ' + desired_units.toString() + ' is not supported.');
- switch_units_callback(units);
- return function (value) {
- return value;
- };
- }
- }
- } else if (typeof this.convertibleUnits[units] !== 'undefined') {
- // units that can be converted
- if (desired_units === 'auto') {
- for (var x in this.convertibleUnits[units]) {
- if (this.convertibleUnits[units].hasOwnProperty(x)) {
- if (this.convertibleUnits[units][x].check(max)) {
- //console.log('DEBUG: ' + uuid.toString() + ' converting ' + units.toString() + ' to: ' + x.toString());
- switch_units_callback(x);
- return this.convertibleUnits[units][x].convert;
- }
- }
- }
-
- // none checked ok
- //console.log('DEBUG: ' + uuid.toString() + ' no conversion available for ' + units.toString() + ' to: ' + desired_units.toString());
- switch_units_callback(units);
- return function (value) {
- return value;
- };
- } else if (typeof this.convertibleUnits[units][desired_units] !== 'undefined') {
- switch_units_callback(desired_units);
- return this.convertibleUnits[units][desired_units].convert;
- } else {
- console.log('Units conversion from ' + units.toString() + ' to ' + desired_units.toString() + ' is not supported.');
- switch_units_callback(units);
- return function (value) {
- return value;
- };
- }
- } else {
- // hm... did we forget to implement the new type?
- console.log(`Unmatched unit conversion method for units ${units.toString()}`);
- switch_units_callback(units);
- return function (value) {
- return value;
- };
- }
- }
-};
-
-NETDATA.icons = {
- left: '',
- reset: '',
- right: '',
- zoomIn: '',
- zoomOut: '',
- resize: '',
- lineChart: '',
- areaChart: '',
- noChart: '',
- loading: '',
- noData: ''
-};
-
-if (typeof netdataIcons === 'object') {
- // for (let icon in NETDATA.icons) {
- // if (NETDATA.icons.hasOwnProperty(icon) && typeof(netdataIcons[icon]) === 'string')
- // NETDATA.icons[icon] = netdataIcons[icon];
- // }
- for (var icon of Object.keys(NETDATA.icons)) {
- if (typeof(netdataIcons[icon]) === 'string') {
- NETDATA.icons[icon] = netdataIcons[icon]
- }
- }
-}
-
-if (typeof netdataSnapshotData === 'undefined') {
- netdataSnapshotData = null;
-}
-
-if (typeof netdataShowHelp === 'undefined') {
- netdataShowHelp = true;
-}
-
-if (typeof netdataShowAlarms === 'undefined') {
- netdataShowAlarms = false;
-}
-
-if (typeof netdataRegistryAfterMs !== 'number' || netdataRegistryAfterMs < 0) {
- netdataRegistryAfterMs = 0; // 1500;
-}
-
-if (typeof netdataRegistry === 'undefined') {
- // backward compatibility
- netdataRegistry = (typeof netdataNoRegistry !== 'undefined' && netdataNoRegistry === false);
-}
-
-if (netdataRegistry === false && typeof netdataRegistryCallback === 'function') {
- netdataRegistry = true;
-}
-
-// ----------------------------------------------------------------------------------------------------------------
-// the defaults for all charts
-
-// if the user does not specify any of these, the following will be used
-
-NETDATA.chartDefaults = {
- width: '100%', // the chart width - can be null
- height: '100%', // the chart height - can be null
- min_width: null, // the chart minimum width - can be null
- library: 'dygraph', // the graphing library to use
- method: 'average', // the grouping method
- before: 0, // panning
- after: -600, // panning
- pixels_per_point: 1, // the detail of the chart
- fill_luminance: 0.8 // luminance of colors in solid areas
-};
-
-// ----------------------------------------------------------------------------------------------------------------
-// global options
-
-NETDATA.options = {
- pauseCallback: null, // a callback when we are really paused
-
- pause: false, // when enabled we don't auto-refresh the charts
-
- targets: [], // an array of all the state objects that are
- // currently active (independently of their
- // viewport visibility)
-
- updated_dom: true, // when true, the DOM has been updated with
- // new elements we have to check.
-
- auto_refresher_fast_weight: 0, // this is the current time in ms, spent
- // rendering charts continuously.
- // used with .current.fast_render_timeframe
-
- page_is_visible: true, // when true, this page is visible
-
- auto_refresher_stop_until: 0, // timestamp in ms - used internally, to stop the
- // auto-refresher for some time (when a chart is
- // performing pan or zoom, we need to stop refreshing
- // all other charts, to have the maximum speed for
- // rendering the chart that is panned or zoomed).
- // Used with .current.global_pan_sync_time
-
- on_scroll_refresher_stop_until: 0, // timestamp in ms - used to stop evaluating
- // charts for some time, after a page scroll
-
- last_page_resize: Date.now(), // the timestamp of the last resize request
-
- last_page_scroll: 0, // the timestamp the last time the page was scrolled
-
- browser_timezone: 'unknown', // timezone detected by javascript
- server_timezone: 'unknown', // timezone reported by the server
-
- force_data_points: 0, // force the number of points to be returned for charts
- fake_chart_rendering: false, // when set to true, the dashboard will download data but will not render the charts
-
- passive_events: null, // true if the browser supports passive events
-
- // the current profile
- // we may have many...
- current: {
- units: 'auto', // can be 'auto' or 'original'
- temperature: 'celsius', // can be 'celsius' or 'fahrenheit'
- seconds_as_time: true, // show seconds as DDd:HH:MM:SS ?
- timezone: 'default', // the timezone to use, or 'default'
- user_set_server_timezone: 'default', // as set by the user on the dashboard
-
- legend_toolbox: true, // show the legend toolbox on charts
- resize_charts: true, // show the resize handler on charts
-
- pixels_per_point: isSlowDevice() ? 5 : 1, // the minimum pixels per point for all charts
- // increase this to speed javascript up
- // each chart library has its own limit too
- // the max of this and the chart library is used
- // the final is calculated every time, so a change
- // here will have immediate effect on the next chart
- // update
-
- idle_between_charts: 100, // ms - how much time to wait between chart updates
-
- fast_render_timeframe: 200, // ms - render continuously until this time of continuous
- // rendering has been reached
- // this setting is used to make it render e.g. 10
- // charts at once, sleep idle_between_charts time
- // and continue for another 10 charts.
-
- idle_between_loops: 500, // ms - if all charts have been updated, wait this
- // time before starting again.
-
- idle_parallel_loops: 100, // ms - the time between parallel refresher updates
-
- idle_lost_focus: 500, // ms - when the window does not have focus, check
- // if focus has been regained, every this time
-
- global_pan_sync_time: 300, // ms - when you pan or zoom a chart, the background
- // auto-refreshing of charts is paused for this amount
- // of time
-
- sync_selection_delay: 400, // ms - when you pan or zoom a chart, wait this amount
- // of time before setting up synchronized selections
- // on hover.
-
- sync_selection: true, // enable or disable selection sync
-
- pan_and_zoom_delay: 50, // when panning or zooming, how ofter to update the chart
-
- sync_pan_and_zoom: true, // enable or disable pan and zoom sync
-
- pan_and_zoom_data_padding: true, // fetch more data for the master chart when panning or zooming
-
- update_only_visible: true, // enable or disable visibility management / used for printing
-
- parallel_refresher: !isSlowDevice(), // enable parallel refresh of charts
-
- concurrent_refreshes: true, // when parallel_refresher is enabled, sync also the charts
-
- destroy_on_hide: isSlowDevice(), // destroy charts when they are not visible
-
- show_help: netdataShowHelp, // when enabled the charts will show some help
- show_help_delay_show_ms: 500,
- show_help_delay_hide_ms: 0,
-
- eliminate_zero_dimensions: true, // do not show dimensions with just zeros
-
- stop_updates_when_focus_is_lost: true, // boolean - shall we stop auto-refreshes when document does not have user focus
- stop_updates_while_resizing: 1000, // ms - time to stop auto-refreshes while resizing the charts
-
- double_click_speed: 500, // ms - time between clicks / taps to detect double click/tap
-
- smooth_plot: !isSlowDevice(), // enable smooth plot, where possible
-
- color_fill_opacity_line: 1.0,
- color_fill_opacity_area: 0.2,
- color_fill_opacity_stacked: 0.8,
-
- pan_and_zoom_factor: 0.25, // the increment when panning and zooming with the toolbox
- pan_and_zoom_factor_multiplier_control: 2.0,
- pan_and_zoom_factor_multiplier_shift: 3.0,
- pan_and_zoom_factor_multiplier_alt: 4.0,
-
- abort_ajax_on_scroll: false, // kill pending ajax page scroll
- async_on_scroll: false, // sync/async onscroll handler
- onscroll_worker_duration_threshold: 30, // time in ms, for async scroll handler
-
- retries_on_data_failures: 3, // how many retries to make if we can't fetch chart data from the server
-
- setOptionCallback: function () {
- }
- },
-
- debug: {
- show_boxes: false,
- main_loop: false,
- focus: false,
- visibility: false,
- chart_data_url: false,
- chart_errors: true, // remember to set it to false before merging
- chart_timing: false,
- chart_calls: false,
- libraries: false,
- dygraph: false,
- globalSelectionSync: false,
- globalPanAndZoom: false
- }
-};
-
-NETDATA.statistics = {
- refreshes_total: 0,
- refreshes_active: 0,
- refreshes_active_max: 0
-};
-
-// local storage options
-
-NETDATA.localStorage = {
- default: {},
- current: {},
- callback: {} // only used for resetting back to defaults
-};
-
-NETDATA.localStorageTested = -1;
-NETDATA.localStorageTest = function () {
- if (NETDATA.localStorageTested !== -1) {
- return NETDATA.localStorageTested;
- }
-
- if (typeof Storage !== "undefined" && typeof localStorage === 'object') {
- let test = 'test';
- try {
- localStorage.setItem(test, test);
- localStorage.removeItem(test);
- NETDATA.localStorageTested = true;
- } catch (e) {
- NETDATA.localStorageTested = false;
- }
- } else {
- NETDATA.localStorageTested = false;
- }
-
- return NETDATA.localStorageTested;
-};
-
-NETDATA.localStorageGet = function (key, def, callback) {
- let ret = def;
-
- if (typeof NETDATA.localStorage.default[key.toString()] === 'undefined') {
- NETDATA.localStorage.default[key.toString()] = def;
- NETDATA.localStorage.callback[key.toString()] = callback;
- }
-
- if (NETDATA.localStorageTest()) {
- try {
- // console.log('localStorage: loading "' + key.toString() + '"');
- ret = localStorage.getItem(key.toString());
- // console.log('netdata loaded: ' + key.toString() + ' = ' + ret.toString());
- if (ret === null || ret === 'undefined') {
- // console.log('localStorage: cannot load it, saving "' + key.toString() + '" with value "' + JSON.stringify(def) + '"');
- localStorage.setItem(key.toString(), JSON.stringify(def));
- ret = def;
- } else {
- // console.log('localStorage: got "' + key.toString() + '" with value "' + ret + '"');
- ret = JSON.parse(ret);
- // console.log('localStorage: loaded "' + key.toString() + '" as value ' + ret + ' of type ' + typeof(ret));
- }
- } catch (error) {
- console.log('localStorage: failed to read "' + key.toString() + '", using default: "' + def.toString() + '"');
- ret = def;
- }
- }
-
- if (typeof ret === 'undefined' || ret === 'undefined') {
- console.log('localStorage: LOADED UNDEFINED "' + key.toString() + '" as value ' + ret + ' of type ' + typeof(ret));
- ret = def;
- }
-
- NETDATA.localStorage.current[key.toString()] = ret;
- return ret;
-};
-
-NETDATA.localStorageSet = function (key, value, callback) {
- if (typeof value === 'undefined' || value === 'undefined') {
- console.log('localStorage: ATTEMPT TO SET UNDEFINED "' + key.toString() + '" as value ' + value + ' of type ' + typeof(value));
- }
-
- if (typeof NETDATA.localStorage.default[key.toString()] === 'undefined') {
- NETDATA.localStorage.default[key.toString()] = value;
- NETDATA.localStorage.current[key.toString()] = value;
- NETDATA.localStorage.callback[key.toString()] = callback;
- }
-
- if (NETDATA.localStorageTest()) {
- // console.log('localStorage: saving "' + key.toString() + '" with value "' + JSON.stringify(value) + '"');
- try {
- localStorage.setItem(key.toString(), JSON.stringify(value));
- } catch (e) {
- console.log('localStorage: failed to save "' + key.toString() + '" with value: "' + value.toString() + '"');
- }
- }
-
- NETDATA.localStorage.current[key.toString()] = value;
- return value;
-};
-
-NETDATA.localStorageGetRecursive = function (obj, prefix, callback) {
- let keys = Object.keys(obj);
- let len = keys.length;
- while (len--) {
- let i = keys[len];
-
- if (typeof obj[i] === 'object') {
- //console.log('object ' + prefix + '.' + i.toString());
- NETDATA.localStorageGetRecursive(obj[i], prefix + '.' + i.toString(), callback);
- continue;
- }
-
- obj[i] = NETDATA.localStorageGet(prefix + '.' + i.toString(), obj[i], callback);
- }
-};
-
-NETDATA.setOption = function (key, value) {
- if (key.toString() === 'setOptionCallback') {
- if (typeof NETDATA.options.current.setOptionCallback === 'function') {
- NETDATA.options.current[key.toString()] = value;
- NETDATA.options.current.setOptionCallback();
- }
- } else if (NETDATA.options.current[key.toString()] !== value) {
- let name = 'options.' + key.toString();
-
- if (typeof NETDATA.localStorage.default[name.toString()] === 'undefined') {
- console.log('localStorage: setOption() on unsaved option: "' + name.toString() + '", value: ' + value);
- }
-
- //console.log(NETDATA.localStorage);
- //console.log('setOption: setting "' + key.toString() + '" to "' + value + '" of type ' + typeof(value) + ' original type ' + typeof(NETDATA.options.current[key.toString()]));
- //console.log(NETDATA.options);
- NETDATA.options.current[key.toString()] = NETDATA.localStorageSet(name.toString(), value, null);
-
- if (typeof NETDATA.options.current.setOptionCallback === 'function') {
- NETDATA.options.current.setOptionCallback();
- }
- }
-
- return true;
-};
-
-NETDATA.getOption = function (key) {
- return NETDATA.options.current[key.toString()];
-};
-
-// read settings from local storage
-NETDATA.localStorageGetRecursive(NETDATA.options.current, 'options', null);
-
-// always start with this option enabled.
-NETDATA.setOption('stop_updates_when_focus_is_lost', true);
-
-NETDATA.resetOptions = function () {
- let keys = Object.keys(NETDATA.localStorage.default);
- let len = keys.length;
-
- while (len--) {
- let i = keys[len];
- let a = i.split('.');
-
- if (a[0] === 'options') {
- if (a[1] === 'setOptionCallback') {
- continue;
- }
- if (typeof NETDATA.localStorage.default[i] === 'undefined') {
- continue;
- }
- if (NETDATA.options.current[i] === NETDATA.localStorage.default[i]) {
- continue;
- }
-
- NETDATA.setOption(a[1], NETDATA.localStorage.default[i]);
- } else if (a[0] === 'chart_heights') {
- if (typeof NETDATA.localStorage.callback[i] === 'function' && typeof NETDATA.localStorage.default[i] !== 'undefined') {
- NETDATA.localStorage.callback[i](NETDATA.localStorage.default[i]);
- }
- }
- }
-
- NETDATA.dateTime.init(NETDATA.options.current.timezone);
-};
-
-// *** src/dashboard.js/timeout.js
-
-// TODO: Better name needed
-
-NETDATA.timeout = {
- // by default, these are just wrappers to setTimeout() / clearTimeout()
-
- step: function (callback) {
- return window.setTimeout(callback, 1000 / 60);
- },
-
- set: function (callback, delay) {
- return window.setTimeout(callback, delay);
- },
-
- clear: function (id) {
- return window.clearTimeout(id);
- },
-
- init: function () {
- let custom = true;
-
- if (window.requestAnimationFrame) {
- this.step = function (callback) {
- return window.requestAnimationFrame(callback);
- };
-
- this.clear = function (handle) {
- return window.cancelAnimationFrame(handle.value);
- };
- // } else if (window.webkitRequestAnimationFrame) {
- // this.step = function (callback) {
- // return window.webkitRequestAnimationFrame(callback);
- // };
-
- // if (window.webkitCancelAnimationFrame) {
- // this.clear = function (handle) {
- // return window.webkitCancelAnimationFrame(handle.value);
- // };
- // } else if (window.webkitCancelRequestAnimationFrame) {
- // this.clear = function (handle) {
- // return window.webkitCancelRequestAnimationFrame(handle.value);
- // };
- // }
- // } else if (window.mozRequestAnimationFrame) {
- // this.step = function (callback) {
- // return window.mozRequestAnimationFrame(callback);
- // };
-
- // this.clear = function (handle) {
- // return window.mozCancelRequestAnimationFrame(handle.value);
- // };
- // } else if (window.oRequestAnimationFrame) {
- // this.step = function (callback) {
- // return window.oRequestAnimationFrame(callback);
- // };
-
- // this.clear = function (handle) {
- // return window.oCancelRequestAnimationFrame(handle.value);
- // };
- // } else if (window.msRequestAnimationFrame) {
- // this.step = function (callback) {
- // return window.msRequestAnimationFrame(callback);
- // };
-
- // this.clear = function (handle) {
- // return window.msCancelRequestAnimationFrame(handle.value);
- // };
- } else {
- custom = false;
- }
-
- if (custom) {
- // we have installed custom .step() / .clear() functions
- // overwrite the .set() too
-
- this.set = function (callback, delay) {
- let start = Date.now(),
- handle = new Object();
-
- const loop = () => {
- let current = Date.now(),
- delta = current - start;
-
- if (delta >= delay) {
- callback.call();
- } else {
- handle.value = this.step(loop);
- }
- }
-
- handle.value = this.step(loop);
- return handle;
- };
- }
- }
-};
-
-NETDATA.timeout.init();
-// Codacy declarations
-/* global netdataTheme */
-
-NETDATA.themes = {
- white: {
- bootstrap_css: NETDATA.serverStatic + 'css/bootstrap-3.3.7.css',
- dashboard_css: NETDATA.serverStatic + 'dashboard.css?v20190902-0',
- background: '#FFFFFF',
- foreground: '#000000',
- grid: '#F0F0F0',
- axis: '#F0F0F0',
- highlight: '#F5F5F5',
- colors: ['#3366CC', '#DC3912', '#109618', '#FF9900', '#990099', '#DD4477',
- '#3B3EAC', '#66AA00', '#0099C6', '#B82E2E', '#AAAA11', '#5574A6',
- '#994499', '#22AA99', '#6633CC', '#E67300', '#316395', '#8B0707',
- '#329262', '#3B3EAC'],
- easypiechart_track: '#f0f0f0',
- easypiechart_scale: '#dfe0e0',
- gauge_pointer: '#C0C0C0',
- gauge_stroke: '#F0F0F0',
- gauge_gradient: false,
- d3pie: {
- title: '#333333',
- subtitle: '#666666',
- footer: '#888888',
- other: '#aaaaaa',
- mainlabel: '#333333',
- percentage: '#dddddd',
- value: '#aaaa22',
- tooltip_bg: '#000000',
- tooltip_fg: '#efefef',
- segment_stroke: "#ffffff",
- gradient_color: '#000000'
- }
- },
- slate: {
- bootstrap_css: NETDATA.serverStatic + 'css/bootstrap-slate-flat-3.3.7.css?v20161229-1',
- dashboard_css: NETDATA.serverStatic + 'dashboard.slate.css?v20190902-0',
- background: '#272b30',
- foreground: '#C8C8C8',
- grid: '#283236',
- axis: '#283236',
- highlight: '#383838',
- /* colors: [ '#55bb33', '#ff2222', '#0099C6', '#faa11b', '#adbce0', '#DDDD00',
- '#4178ba', '#f58122', '#a5cc39', '#f58667', '#f5ef89', '#cf93c0',
- '#a5d18a', '#b8539d', '#3954a3', '#c8a9cf', '#c7de8a', '#fad20a',
- '#a6a479', '#a66da8' ],
- */
- colors: ['#66AA00', '#FE3912', '#3366CC', '#D66300', '#0099C6', '#DDDD00',
- '#5054e6', '#EE9911', '#BB44CC', '#e45757', '#ef0aef', '#CC7700',
- '#22AA99', '#109618', '#905bfd', '#f54882', '#4381bf', '#ff3737',
- '#329262', '#3B3EFF'],
- easypiechart_track: '#373b40',
- easypiechart_scale: '#373b40',
- gauge_pointer: '#474b50',
- gauge_stroke: '#373b40',
- gauge_gradient: false,
- d3pie: {
- title: '#C8C8C8',
- subtitle: '#283236',
- footer: '#283236',
- other: '#283236',
- mainlabel: '#C8C8C8',
- percentage: '#dddddd',
- value: '#cccc44',
- tooltip_bg: '#272b30',
- tooltip_fg: '#C8C8C8',
- segment_stroke: "#283236",
- gradient_color: '#000000'
- }
- }
-};
-
-if (typeof netdataTheme !== 'undefined' && typeof NETDATA.themes[netdataTheme] !== 'undefined') {
- NETDATA.themes.current = NETDATA.themes[netdataTheme];
-} else {
- NETDATA.themes.current = NETDATA.themes.white;
-}
-
-NETDATA.colors = NETDATA.themes.current.colors;
-
-// these are the colors Google Charts are using
-// we have them here to attempt emulate their look and feel on the other chart libraries
-// http://there4.io/2012/05/02/google-chart-color-list/
-//NETDATA.colors = [ '#3366CC', '#DC3912', '#FF9900', '#109618', '#990099', '#3B3EAC', '#0099C6',
-// '#DD4477', '#66AA00', '#B82E2E', '#316395', '#994499', '#22AA99', '#AAAA11',
-// '#6633CC', '#E67300', '#8B0707', '#329262', '#5574A6', '#3B3EAC' ];
-
-// an alternative set
-// http://www.mulinblog.com/a-color-palette-optimized-for-data-visualization/
-// (blue) (red) (orange) (green) (pink) (brown) (purple) (yellow) (gray)
-//NETDATA.colors = [ '#5DA5DA', '#F15854', '#FAA43A', '#60BD68', '#F17CB0', '#B2912F', '#B276B2', '#DECF3F', '#4D4D4D' ];
-// dygraph
-
-// Codacy declarations
-/* global smoothPlotter */
-/* global Dygraph */
-
-NETDATA.dygraph = {
- smooth: false
-};
-
-NETDATA.dygraphToolboxPanAndZoom = function (state, after, before) {
- if (after < state.netdata_first) {
- after = state.netdata_first;
- }
-
- if (before > state.netdata_last) {
- before = state.netdata_last;
- }
-
- state.setMode('zoom');
- NETDATA.globalSelectionSync.stop();
- NETDATA.globalSelectionSync.delay();
- state.tmp.dygraph_user_action = true;
- state.tmp.dygraph_force_zoom = true;
- // state.log('toolboxPanAndZoom');
- state.updateChartPanOrZoom(after, before);
- NETDATA.globalPanAndZoom.setMaster(state, after, before);
-};
-
-NETDATA.dygraphSetSelection = function (state, t) {
- if (typeof state.tmp.dygraph_instance !== 'undefined') {
- let r = state.calculateRowForTime(t);
- if (r !== -1) {
- state.tmp.dygraph_instance.setSelection(r);
- return true;
- } else {
- state.tmp.dygraph_instance.clearSelection();
- state.legendShowUndefined();
- }
- }
-
- return false;
-};
-
-NETDATA.dygraphClearSelection = function (state) {
- if (typeof state.tmp.dygraph_instance !== 'undefined') {
- state.tmp.dygraph_instance.clearSelection();
- }
- return true;
-};
-
-NETDATA.dygraphSmoothInitialize = function (callback) {
- $.ajax({
- url: NETDATA.dygraph_smooth_js,
- cache: true,
- dataType: "script",
- xhrFields: {withCredentials: true} // required for the cookie
- })
- .done(function () {
- NETDATA.dygraph.smooth = true;
- smoothPlotter.smoothing = 0.3;
- })
- .fail(function () {
- NETDATA.dygraph.smooth = false;
- })
- .always(function () {
- if (typeof callback === "function") {
- return callback();
- }
- });
-};
-
-NETDATA.dygraphInitialize = function (callback) {
- if (typeof netdataNoDygraphs === 'undefined' || !netdataNoDygraphs) {
- $.ajax({
- url: NETDATA.dygraph_js,
- cache: true,
- dataType: "script",
- xhrFields: {withCredentials: true} // required for the cookie
- })
- .done(function () {
- NETDATA.registerChartLibrary('dygraph', NETDATA.dygraph_js);
- })
- .fail(function () {
- NETDATA.chartLibraries.dygraph.enabled = false;
- NETDATA.error(100, NETDATA.dygraph_js);
- })
- .always(function () {
- if (NETDATA.chartLibraries.dygraph.enabled && NETDATA.options.current.smooth_plot) {
- NETDATA.dygraphSmoothInitialize(callback);
- } else if (typeof callback === "function") {
- return callback();
- }
- });
- } else {
- NETDATA.chartLibraries.dygraph.enabled = false;
- if (typeof callback === "function") {
- return callback();
- }
- }
-};
-
-NETDATA.dygraphChartUpdate = function (state, data) {
- let dygraph = state.tmp.dygraph_instance;
-
- if (typeof dygraph === 'undefined') {
- return NETDATA.dygraphChartCreate(state, data);
- }
-
- // when the chart is not visible, and hidden
- // if there is a window resize, dygraph detects
- // its element size as 0x0.
- // this will make it re-appear properly
-
- if (state.tm.last_unhidden > state.tmp.dygraph_last_rendered) {
- dygraph.resize();
- }
-
- let options = {
- file: data.result.data,
- colors: state.chartColors(),
- labels: data.result.labels,
- //labelsDivWidth: state.chartWidth() - 70,
- includeZero: state.tmp.dygraph_include_zero,
- visibility: state.dimensions_visibility.selected2BooleanArray(state.data.dimension_names)
- };
-
- if (state.tmp.dygraph_chart_type === 'stacked') {
- if (options.includeZero && state.dimensions_visibility.countSelected() < options.visibility.length) {
- options.includeZero = 0;
- }
- }
-
- if (!NETDATA.chartLibraries.dygraph.isSparkline(state)) {
- options.ylabel = state.units_current; // (state.units_desired === 'auto')?"":state.units_current;
- }
-
- if (state.tmp.dygraph_force_zoom) {
- if (NETDATA.options.debug.dygraph || state.debug) {
- state.log('dygraphChartUpdate() forced zoom update');
- }
-
- options.dateWindow = (state.requested_padding !== null) ? [state.view_after, state.view_before] : null;
- //options.isZoomedIgnoreProgrammaticZoom = true;
- state.tmp.dygraph_force_zoom = false;
- } else if (state.current.name !== 'auto') {
- if (NETDATA.options.debug.dygraph || state.debug) {
- state.log('dygraphChartUpdate() loose update');
- }
- } else {
- if (NETDATA.options.debug.dygraph || state.debug) {
- state.log('dygraphChartUpdate() strict update');
- }
-
- options.dateWindow = (state.requested_padding !== null) ? [state.view_after, state.view_before] : null;
- //options.isZoomedIgnoreProgrammaticZoom = true;
- }
-
- options.valueRange = state.tmp.dygraph_options.valueRange;
-
- let oldMax = null, oldMin = null;
- if (state.tmp.__commonMin !== null) {
- state.data.min = state.tmp.dygraph_instance.axes_[0].extremeRange[0];
- oldMin = options.valueRange[0] = NETDATA.commonMin.get(state);
- }
- if (state.tmp.__commonMax !== null) {
- state.data.max = state.tmp.dygraph_instance.axes_[0].extremeRange[1];
- oldMax = options.valueRange[1] = NETDATA.commonMax.get(state);
- }
-
- if (state.tmp.dygraph_smooth_eligible) {
- if ((NETDATA.options.current.smooth_plot && state.tmp.dygraph_options.plotter !== smoothPlotter)
- || (NETDATA.options.current.smooth_plot === false && state.tmp.dygraph_options.plotter === smoothPlotter)) {
- NETDATA.dygraphChartCreate(state, data);
- return;
- }
- }
-
- if (netdataSnapshotData !== null && NETDATA.globalPanAndZoom.isActive() && NETDATA.globalPanAndZoom.isMaster(state) === false) {
- // pan and zoom on snapshots
- options.dateWindow = [NETDATA.globalPanAndZoom.force_after_ms, NETDATA.globalPanAndZoom.force_before_ms];
- //options.isZoomedIgnoreProgrammaticZoom = true;
- }
-
- if (NETDATA.chartLibraries.dygraph.isLogScale(state)) {
- if (Array.isArray(options.valueRange) && options.valueRange[0] <= 0) {
- options.valueRange[0] = null;
- }
- }
-
- dygraph.updateOptions(options);
-
- let redraw = false;
- if (oldMin !== null && oldMin > state.tmp.dygraph_instance.axes_[0].extremeRange[0]) {
- state.data.min = state.tmp.dygraph_instance.axes_[0].extremeRange[0];
- options.valueRange[0] = NETDATA.commonMin.get(state);
- redraw = true;
- }
- if (oldMax !== null && oldMax < state.tmp.dygraph_instance.axes_[0].extremeRange[1]) {
- state.data.max = state.tmp.dygraph_instance.axes_[0].extremeRange[1];
- options.valueRange[1] = NETDATA.commonMax.get(state);
- redraw = true;
- }
-
- if (redraw) {
- // state.log('forcing redraw to adapt to common- min/max');
- dygraph.updateOptions(options);
- }
-
- state.tmp.dygraph_last_rendered = Date.now();
- return true;
-};
-
-NETDATA.dygraphChartCreate = function (state, data) {
- if (NETDATA.options.debug.dygraph || state.debug) {
- state.log('dygraphChartCreate()');
- }
-
- state.tmp.dygraph_chart_type = NETDATA.dataAttribute(state.element, 'dygraph-type', state.chart.chart_type);
- if (state.tmp.dygraph_chart_type === 'stacked' && data.dimensions === 1) {
- state.tmp.dygraph_chart_type = 'area';
- }
- if (state.tmp.dygraph_chart_type === 'stacked' && NETDATA.chartLibraries.dygraph.isLogScale(state)) {
- state.tmp.dygraph_chart_type = 'area';
- }
-
- let highlightCircleSize = NETDATA.chartLibraries.dygraph.isSparkline(state) ? 3 : 4;
-
- let smooth = NETDATA.dygraph.smooth
- ? (NETDATA.dataAttributeBoolean(state.element, 'dygraph-smooth', (state.tmp.dygraph_chart_type === 'line' && NETDATA.chartLibraries.dygraph.isSparkline(state) === false)))
- : false;
-
- state.tmp.dygraph_include_zero = NETDATA.dataAttribute(state.element, 'dygraph-includezero', (state.tmp.dygraph_chart_type === 'stacked'));
- let drawAxis = NETDATA.dataAttributeBoolean(state.element, 'dygraph-drawaxis', true);
-
- state.tmp.dygraph_options = {
- colors: NETDATA.dataAttribute(state.element, 'dygraph-colors', state.chartColors()),
-
- // leave a few pixels empty on the right of the chart
- rightGap: NETDATA.dataAttribute(state.element, 'dygraph-rightgap', 5),
- showRangeSelector: NETDATA.dataAttributeBoolean(state.element, 'dygraph-showrangeselector', false),
- showRoller: NETDATA.dataAttributeBoolean(state.element, 'dygraph-showroller', false),
- title: NETDATA.dataAttribute(state.element, 'dygraph-title', state.title),
- titleHeight: NETDATA.dataAttribute(state.element, 'dygraph-titleheight', 19),
- legend: NETDATA.dataAttribute(state.element, 'dygraph-legend', 'always'), // we need this to get selection events
- labels: data.result.labels,
- labelsDiv: NETDATA.dataAttribute(state.element, 'dygraph-labelsdiv', state.element_legend_childs.hidden),
- //labelsDivStyles: NETDATA.dataAttribute(state.element, 'dygraph-labelsdivstyles', { 'fontSize':'1px' }),
- //labelsDivWidth: NETDATA.dataAttribute(state.element, 'dygraph-labelsdivwidth', state.chartWidth() - 70),
- labelsSeparateLines: NETDATA.dataAttributeBoolean(state.element, 'dygraph-labelsseparatelines', true),
- labelsShowZeroValues: NETDATA.chartLibraries.dygraph.isLogScale(state) ? false : NETDATA.dataAttributeBoolean(state.element, 'dygraph-labelsshowzerovalues', true),
- labelsKMB: false,
- labelsKMG2: false,
- showLabelsOnHighlight: NETDATA.dataAttributeBoolean(state.element, 'dygraph-showlabelsonhighlight', true),
- hideOverlayOnMouseOut: NETDATA.dataAttributeBoolean(state.element, 'dygraph-hideoverlayonmouseout', true),
- includeZero: state.tmp.dygraph_include_zero,
- xRangePad: NETDATA.dataAttribute(state.element, 'dygraph-xrangepad', 0),
- yRangePad: NETDATA.dataAttribute(state.element, 'dygraph-yrangepad', 1),
- valueRange: NETDATA.dataAttribute(state.element, 'dygraph-valuerange', [null, null]),
- ylabel: state.units_current, // (state.units_desired === 'auto')?"":state.units_current,
- yLabelWidth: NETDATA.dataAttribute(state.element, 'dygraph-ylabelwidth', 12),
-
- // the function to plot the chart
- plotter: null,
-
- // The width of the lines connecting data points.
- // This can be used to increase the contrast or some graphs.
- strokeWidth: NETDATA.dataAttribute(state.element, 'dygraph-strokewidth', ((state.tmp.dygraph_chart_type === 'stacked') ? 0.1 : ((smooth === true) ? 1.5 : 0.7))),
- strokePattern: NETDATA.dataAttribute(state.element, 'dygraph-strokepattern', undefined),
-
- // The size of the dot to draw on each point in pixels (see drawPoints).
- // A dot is always drawn when a point is "isolated",
- // i.e. there is a missing point on either side of it.
- // This also controls the size of those dots.
- drawPoints: NETDATA.dataAttributeBoolean(state.element, 'dygraph-drawpoints', false),
-
- // Draw points at the edges of gaps in the data.
- // This improves visibility of small data segments or other data irregularities.
- drawGapEdgePoints: NETDATA.dataAttributeBoolean(state.element, 'dygraph-drawgapedgepoints', true),
- connectSeparatedPoints: NETDATA.chartLibraries.dygraph.isLogScale(state) ? false : NETDATA.dataAttributeBoolean(state.element, 'dygraph-connectseparatedpoints', false),
- pointSize: NETDATA.dataAttribute(state.element, 'dygraph-pointsize', 1),
-
- // enabling this makes the chart with little square lines
- stepPlot: NETDATA.dataAttributeBoolean(state.element, 'dygraph-stepplot', false),
-
- // Draw a border around graph lines to make crossing lines more easily
- // distinguishable. Useful for graphs with many lines.
- strokeBorderColor: NETDATA.dataAttribute(state.element, 'dygraph-strokebordercolor', NETDATA.themes.current.background),
- strokeBorderWidth: NETDATA.dataAttribute(state.element, 'dygraph-strokeborderwidth', (state.tmp.dygraph_chart_type === 'stacked') ? 0.0 : 0.0),
- fillGraph: NETDATA.dataAttribute(state.element, 'dygraph-fillgraph', (state.tmp.dygraph_chart_type === 'area' || state.tmp.dygraph_chart_type === 'stacked')),
- fillAlpha: NETDATA.dataAttribute(state.element, 'dygraph-fillalpha',
- ((state.tmp.dygraph_chart_type === 'stacked')
- ? NETDATA.options.current.color_fill_opacity_stacked
- : NETDATA.options.current.color_fill_opacity_area)
- ),
- stackedGraph: NETDATA.dataAttribute(state.element, 'dygraph-stackedgraph', (state.tmp.dygraph_chart_type === 'stacked')),
- stackedGraphNaNFill: NETDATA.dataAttribute(state.element, 'dygraph-stackedgraphnanfill', 'none'),
- drawAxis: drawAxis,
- axisLabelFontSize: NETDATA.dataAttribute(state.element, 'dygraph-axislabelfontsize', 10),
- axisLineColor: NETDATA.dataAttribute(state.element, 'dygraph-axislinecolor', NETDATA.themes.current.axis),
- axisLineWidth: NETDATA.dataAttribute(state.element, 'dygraph-axislinewidth', 1.0),
- drawGrid: NETDATA.dataAttributeBoolean(state.element, 'dygraph-drawgrid', true),
- gridLinePattern: NETDATA.dataAttribute(state.element, 'dygraph-gridlinepattern', null),
- gridLineWidth: NETDATA.dataAttribute(state.element, 'dygraph-gridlinewidth', 1.0),
- gridLineColor: NETDATA.dataAttribute(state.element, 'dygraph-gridlinecolor', NETDATA.themes.current.grid),
- maxNumberWidth: NETDATA.dataAttribute(state.element, 'dygraph-maxnumberwidth', 8),
- sigFigs: NETDATA.dataAttribute(state.element, 'dygraph-sigfigs', null),
- digitsAfterDecimal: NETDATA.dataAttribute(state.element, 'dygraph-digitsafterdecimal', 2),
- valueFormatter: NETDATA.dataAttribute(state.element, 'dygraph-valueformatter', undefined),
- highlightCircleSize: NETDATA.dataAttribute(state.element, 'dygraph-highlightcirclesize', highlightCircleSize),
- highlightSeriesOpts: NETDATA.dataAttribute(state.element, 'dygraph-highlightseriesopts', null), // TOO SLOW: { strokeWidth: 1.5 },
- highlightSeriesBackgroundAlpha: NETDATA.dataAttribute(state.element, 'dygraph-highlightseriesbackgroundalpha', null), // TOO SLOW: (state.tmp.dygraph_chart_type === 'stacked')?0.7:0.5,
- pointClickCallback: NETDATA.dataAttribute(state.element, 'dygraph-pointclickcallback', undefined),
- visibility: state.dimensions_visibility.selected2BooleanArray(state.data.dimension_names),
- logscale: NETDATA.chartLibraries.dygraph.isLogScale(state) ? 'y' : undefined,
-
- // Expects a string in the format ":