mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-03 11:43:56 +08:00
654 lines
20 KiB
JavaScript
654 lines
20 KiB
JavaScript
"use strict";
|
|
"require view";
|
|
"require dom";
|
|
"require poll";
|
|
"require rpc";
|
|
"require network";
|
|
// WARN: generated by rsbuild - do not edit
|
|
|
|
// The require scope
|
|
var __webpack_require__ = {};
|
|
|
|
// webpack/runtime/define_property_getters
|
|
(() => {
|
|
__webpack_require__.d = (exports, getters, values) => {
|
|
var define = (defs, kind) => {
|
|
for(var key in defs) {
|
|
if(__webpack_require__.o(defs, key) && !__webpack_require__.o(exports, key)) {
|
|
Object.defineProperty(exports, key, { enumerable: true, [kind]: defs[key] });
|
|
}
|
|
}
|
|
};
|
|
define(getters, "get");
|
|
define(values, "value");
|
|
};
|
|
})();
|
|
// webpack/runtime/has_own_property
|
|
(() => {
|
|
__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
|
})();
|
|
// webpack/runtime/make_namespace_object
|
|
(() => {
|
|
// define __esModule on exports
|
|
__webpack_require__.r = (exports) => {
|
|
if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
}
|
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
};
|
|
})();
|
|
var __webpack_exports__ = {};
|
|
// ESM COMPAT FLAG
|
|
__webpack_require__.r(__webpack_exports__);
|
|
|
|
// EXPORTS
|
|
__webpack_require__.d(__webpack_exports__, {
|
|
main: () => (/* binding */ main)
|
|
});
|
|
|
|
;// CONCATENATED MODULE: ../node_modules/.pnpm/@lazulikao+luci-types@https_685a81b9ead15f36368ce6e6ebcf4a27/node_modules/@lazulikao/luci-types/src/jsx/jsx-factory.ts
|
|
const Fragment = Symbol.for("jsx.fragment");
|
|
function jsx_factory_e(e, t) {
|
|
let { children: n, ...r } = null === t || "object" != typeof t || Array.isArray(t) ? {} : t, o = function e(t, n = []) {
|
|
for (let r of t)null != r && "boolean" != typeof r && (Array.isArray(r) ? e(r, n) : n.push(r instanceof Node ? r : String(r)));
|
|
return n;
|
|
}(null == n ? [] : Array.isArray(n) ? n : [
|
|
n
|
|
]);
|
|
if (e === Fragment) {
|
|
let e = document.createDocumentFragment();
|
|
return e.append(...o), e;
|
|
}
|
|
if ("function" == typeof e) {
|
|
let t = Reflect.apply(e, void 0, [
|
|
{
|
|
...r,
|
|
children: o
|
|
}
|
|
]);
|
|
if (!(t instanceof Node)) throw TypeError("JSX components must return a DOM Node");
|
|
return t;
|
|
}
|
|
if ("string" != typeof e) throw TypeError("JSX element types must be tag names or component functions");
|
|
let f = {}, l = {
|
|
...r
|
|
};
|
|
for (let [e, t] of Object.entries(l))e.startsWith("on") && "function" == typeof t ? (f[e] = t, delete l[e]) : "boolean" == typeof t && (t ? l[e] = e : delete l[e]);
|
|
let s = Object.keys(l).length > 0 ? o.length > 1 ? E(e, l, o) : E(e, l, o[0]) : o.length > 1 ? E(e, {}, o) : E(e, {}, o[0]);
|
|
for (let [e, t] of Object.entries(f)){
|
|
let n = e.slice(2).toLowerCase();
|
|
s.addEventListener(n, t);
|
|
}
|
|
return s;
|
|
}
|
|
function jsx(t, n) {
|
|
return jsx_factory_e(t, n);
|
|
}
|
|
function jsxs(t, n) {
|
|
return jsx_factory_e(t, n);
|
|
}
|
|
function jsxDEV(t, n) {
|
|
return jsx_factory_e(t, n);
|
|
}
|
|
|
|
;// CONCATENATED MODULE: ../node_modules/.pnpm/@lazulikao+luci-types@https_685a81b9ead15f36368ce6e6ebcf4a27/node_modules/@lazulikao/luci-types/src/jsx/jsx-runtime.ts
|
|
|
|
|
|
;// CONCATENATED MODULE: ./web/fluentdashboard/model.ts
|
|
function model_t(t) {
|
|
return null === t || "object" != typeof t || Array.isArray(t) ? {} : t;
|
|
}
|
|
function model_e(t) {
|
|
return "string" == typeof t ? t : "";
|
|
}
|
|
function model_r(t) {
|
|
return "number" == typeof t && Number.isFinite(t) ? t : 0;
|
|
}
|
|
function model_o(e, i = "free") {
|
|
let n = model_t(e);
|
|
return {
|
|
total: model_r(n.total),
|
|
free: model_r(n[i] ?? n.free)
|
|
};
|
|
}
|
|
function normalizeSystemSnapshot(i, n, a) {
|
|
let l = model_t(i), m = model_t(n), u = model_t(l.release), f = model_t(a), s = Array.isArray(m.load) ? m.load.map(model_r) : [];
|
|
return {
|
|
hostname: model_e(l.hostname),
|
|
model: model_e(l.model),
|
|
architecture: model_e(l.system),
|
|
target: model_e(u.target),
|
|
firmware: model_e(u.description),
|
|
kernel: model_e(l.kernel),
|
|
luciVersion: [
|
|
model_e(f.branch),
|
|
model_e(f.revision)
|
|
].filter(Boolean).join(" "),
|
|
uptime: model_r(m.uptime),
|
|
localtime: model_r(m.localtime),
|
|
load: s,
|
|
memory: model_o(m.memory, "available"),
|
|
swap: model_o(m.swap),
|
|
root: model_o(m.root),
|
|
tmp: model_o(m.tmp)
|
|
};
|
|
}
|
|
function usedPercent(t) {
|
|
return t.total <= 0 ? 0 : Math.min(100, Math.max(0, (t.total - t.free) / t.total * 100));
|
|
}
|
|
function formatBytes(t) {
|
|
if (!Number.isFinite(t) || t <= 0) return "0 B";
|
|
let e = [
|
|
"B",
|
|
"KiB",
|
|
"MiB",
|
|
"GiB",
|
|
"TiB"
|
|
], r = Math.min(Math.floor(Math.log(t) / Math.log(1024)), e.length - 1), o = t / 1024 ** r;
|
|
return `${o >= 10 || 0 === r ? o.toFixed(0) : o.toFixed(1)} ${e[r]}`;
|
|
}
|
|
function formatDuration(t) {
|
|
if (!Number.isFinite(t) || t <= 0) return "-";
|
|
let e = Math.floor(t / 86400), r = Math.floor(t % 86400 / 3600), o = Math.floor(t % 3600 / 60);
|
|
return [
|
|
e > 0 ? `${e}d` : "",
|
|
`${r}h`,
|
|
`${o}m`
|
|
].filter(Boolean).join(" ");
|
|
}
|
|
function formatLoad(t) {
|
|
return 0 === t.length ? "-" : t.slice(0, 3).map((t)=>(t / 65535).toFixed(2)).join(" / ");
|
|
}
|
|
function formatLocalTime(t) {
|
|
return !Number.isFinite(t) || t <= 0 ? "-" : new Intl.DateTimeFormat(void 0, {
|
|
dateStyle: "medium",
|
|
timeStyle: "medium",
|
|
timeZone: "UTC"
|
|
}).format(new Date(1000 * t));
|
|
}
|
|
|
|
;// CONCATENATED MODULE: ./web/fluentdashboard/index.tsx
|
|
|
|
|
|
let fluentdashboard_l = rpc.declare({
|
|
object: "system",
|
|
method: "board"
|
|
}), fluentdashboard_o = rpc.declare({
|
|
object: "system",
|
|
method: "info"
|
|
}), c = rpc.declare({
|
|
object: "luci",
|
|
method: "getVersion"
|
|
}), fluentdashboard_u = rpc.declare({
|
|
object: "luci-rpc",
|
|
method: "getDHCPLeases",
|
|
expect: {
|
|
"": {}
|
|
}
|
|
});
|
|
function fluentdashboard_h(e) {
|
|
return null === e || "object" != typeof e || Array.isArray(e) ? {} : e;
|
|
}
|
|
function fluentdashboard_m(e) {
|
|
return "string" == typeof e ? e : "";
|
|
}
|
|
function p(e) {
|
|
return "number" == typeof e && Number.isFinite(e) ? e : 0;
|
|
}
|
|
async function fluentdashboard_f(e, t) {
|
|
try {
|
|
return await e;
|
|
} catch {
|
|
return t;
|
|
}
|
|
}
|
|
function y(e, t = !1) {
|
|
let r = e.getL3Device() ?? e.getDevice();
|
|
return {
|
|
name: e.getName(),
|
|
protocol: e.getI18n(),
|
|
up: e.isUp(),
|
|
addresses: t ? e.getIP6Addrs() : e.getIPAddrs(),
|
|
gateway: t ? e.getGateway6Addr() : e.getGatewayAddr(),
|
|
uptime: e.getUptime(),
|
|
device: r?.getName() ?? "",
|
|
rx: r?.getRXBytes() ?? 0,
|
|
tx: r?.getTXBytes() ?? 0
|
|
};
|
|
}
|
|
async function g() {
|
|
await fluentdashboard_f(network.flushCache(), {});
|
|
let [e, t, r, a, s, n, d, u] = await Promise.all([
|
|
fluentdashboard_f(fluentdashboard_l(), {}),
|
|
fluentdashboard_f(fluentdashboard_o(), {}),
|
|
fluentdashboard_f(c(), {}),
|
|
fluentdashboard_f(network.getWANNetworks(), []),
|
|
fluentdashboard_f(network.getWAN6Networks(), []),
|
|
fluentdashboard_f(network.getNetworks(), []),
|
|
fluentdashboard_f(network.getWifiDevices(), []),
|
|
fluentdashboard_f(network.getWifiNetworks(), [])
|
|
]), h = u.map((e)=>{
|
|
let t = d.find((t)=>t.getName() === e.getWifiDeviceName());
|
|
return {
|
|
radio: t?.getName() ?? e.getWifiDeviceName() ?? "",
|
|
hardware: t?.getI18n() ?? "",
|
|
up: e.isUp() && !t?.isDisabled(),
|
|
ssid: e.getActiveSSID() || e.getSSID() || e.getMeshID() || "",
|
|
mode: e.getActiveModeI18n() || e.getMode(),
|
|
channel: e.getChannel(),
|
|
frequency: e.getFrequency() ?? "",
|
|
encryption: e.getActiveEncryption()
|
|
};
|
|
});
|
|
for (let e of d)h.some((t)=>t.radio === e.getName()) || h.push({
|
|
radio: e.getName(),
|
|
hardware: e.getI18n(),
|
|
up: e.isUp() && !e.isDisabled(),
|
|
ssid: "",
|
|
mode: "",
|
|
channel: null,
|
|
frequency: "",
|
|
encryption: ""
|
|
});
|
|
return {
|
|
system: normalizeSystemSnapshot(e, t, r),
|
|
wan4: a.map((e)=>y(e)),
|
|
wan6: s.map((e)=>y(e, !0)),
|
|
interfaces: n.filter((e)=>"loopback" !== e.getName()).map((e)=>y(e)),
|
|
wireless: h,
|
|
updatedAt: new Date()
|
|
};
|
|
}
|
|
async function w() {
|
|
let [e, t, r] = await Promise.all([
|
|
fluentdashboard_f(fluentdashboard_u(), {}),
|
|
fluentdashboard_f(network.getWifiNetworks(), []),
|
|
fluentdashboard_f(network.getHostHints(), null)
|
|
]), a = await Promise.all(t.map(async (e)=>({
|
|
wifi: e,
|
|
peers: await fluentdashboard_f(e.getAssocList(), [])
|
|
}))), s = [];
|
|
for (let { wifi: e, peers: t } of a)for (let a of t){
|
|
let t = r?.getHostnameByMACAddr(a.mac) || r?.getIPAddrByMACAddr(a.mac) || r?.getIP6AddrByMACAddr(a.mac) || "";
|
|
s.push({
|
|
network: e.getActiveSSID() || e.getSSID() || e.getName(),
|
|
hostname: t,
|
|
mac: a.mac,
|
|
signal: a.signal,
|
|
noise: a.noise ?? null,
|
|
rxRate: a.rx?.rate ?? 0,
|
|
txRate: a.tx?.rate ?? 0
|
|
});
|
|
}
|
|
return {
|
|
leases: function(e) {
|
|
let t = fluentdashboard_h(e), r = [];
|
|
if (Array.isArray(t.dhcp_leases)) for (let e of t.dhcp_leases){
|
|
let t = fluentdashboard_h(e);
|
|
r.push({
|
|
family: "IPv4",
|
|
hostname: fluentdashboard_m(t.hostname),
|
|
address: fluentdashboard_m(t.ipaddr),
|
|
identifier: fluentdashboard_m(t.macaddr),
|
|
expires: !1 !== t.expires && p(t.expires)
|
|
});
|
|
}
|
|
if (Array.isArray(t.dhcp6_leases)) for (let e of t.dhcp6_leases){
|
|
let t = fluentdashboard_h(e), a = Array.isArray(t.ip6addrs) ? t.ip6addrs.filter((e)=>"string" == typeof e) : [];
|
|
r.push({
|
|
family: "IPv6",
|
|
hostname: fluentdashboard_m(t.hostname),
|
|
address: a.join(", ") || fluentdashboard_m(t.ip6addr),
|
|
identifier: fluentdashboard_m(t.duid),
|
|
expires: !1 !== t.expires && p(t.expires)
|
|
});
|
|
}
|
|
return r;
|
|
}(e),
|
|
clients: s
|
|
};
|
|
}
|
|
function b(e) {
|
|
return null == e || "" === e ? "-" : String(e);
|
|
}
|
|
function v(t) {
|
|
return jsx("span", {
|
|
class: `fluent-dashboard__status fluent-dashboard__status--${t ? "up" : "down"}`,
|
|
children: t ? _("Online") : _("Offline")
|
|
});
|
|
}
|
|
function A(r, a, s, n = !1) {
|
|
return jsxs("div", {
|
|
class: `fluent-dashboard__card${n ? " fluent-dashboard__card--wide" : ""}`,
|
|
"data-dashboard-section": r,
|
|
children: [
|
|
jsx("h2", {
|
|
class: "fluent-dashboard__card-title",
|
|
children: a
|
|
}),
|
|
jsx("div", {
|
|
class: "fluent-dashboard__card-content",
|
|
children: s
|
|
})
|
|
]
|
|
});
|
|
}
|
|
function S(r, a, s) {
|
|
return jsx("div", {
|
|
class: "fluent-dashboard__table-wrap",
|
|
children: jsxs("table", {
|
|
class: "fluent-dashboard__table",
|
|
children: [
|
|
jsx("thead", {
|
|
children: jsx("tr", {
|
|
children: r.map((t)=>jsx("th", {
|
|
children: t
|
|
}))
|
|
})
|
|
}),
|
|
jsx("tbody", {
|
|
children: a.length ? a.map((t)=>jsx("tr", {
|
|
children: t.map((t)=>jsx("td", {
|
|
children: t instanceof Node ? t : b(t)
|
|
}))
|
|
})) : jsx("tr", {
|
|
children: jsx("td", {
|
|
class: "fluent-dashboard__empty",
|
|
colSpan: r.length,
|
|
children: s
|
|
})
|
|
})
|
|
})
|
|
]
|
|
})
|
|
});
|
|
}
|
|
function x(t) {
|
|
return A("system", _("System"), jsx("div", {
|
|
class: "fluent-dashboard__details",
|
|
children: [
|
|
[
|
|
_("Hostname"),
|
|
t.hostname
|
|
],
|
|
[
|
|
_("Model"),
|
|
t.model
|
|
],
|
|
[
|
|
_("Architecture"),
|
|
t.architecture
|
|
],
|
|
[
|
|
_("Target Platform"),
|
|
t.target
|
|
],
|
|
[
|
|
_("Firmware Version"),
|
|
t.firmware
|
|
],
|
|
[
|
|
_("Kernel Version"),
|
|
t.kernel
|
|
],
|
|
[
|
|
_("LuCI Version"),
|
|
t.luciVersion
|
|
],
|
|
[
|
|
_("Local Time"),
|
|
formatLocalTime(t.localtime)
|
|
],
|
|
[
|
|
_("Uptime"),
|
|
formatDuration(t.uptime)
|
|
],
|
|
[
|
|
_("Load Average"),
|
|
formatLoad(t.load)
|
|
]
|
|
].flatMap(([t, r])=>[
|
|
jsx("div", {
|
|
class: "fluent-dashboard__details-label",
|
|
children: t
|
|
}),
|
|
jsx("div", {
|
|
class: "fluent-dashboard__details-value",
|
|
children: r instanceof Node ? r : b(r)
|
|
})
|
|
])
|
|
}));
|
|
}
|
|
function I(a) {
|
|
let s = [
|
|
[
|
|
_("Memory"),
|
|
a.memory
|
|
],
|
|
[
|
|
_("Swap"),
|
|
a.swap
|
|
],
|
|
[
|
|
_("Root storage"),
|
|
a.root
|
|
],
|
|
[
|
|
_("Temporary storage"),
|
|
a.tmp
|
|
]
|
|
];
|
|
return A("resources", _("Resources"), s.map(([a, s])=>{
|
|
let n, i;
|
|
return n = Math.max(0, s.total - s.free), i = usedPercent(s), jsxs("div", {
|
|
class: "fluent-dashboard__meter",
|
|
children: [
|
|
jsxs("div", {
|
|
class: "fluent-dashboard__meter-label",
|
|
children: [
|
|
jsx("span", {
|
|
children: a
|
|
}),
|
|
jsx("span", {
|
|
children: `${formatBytes(n)} / ${formatBytes(s.total)}`
|
|
})
|
|
]
|
|
}),
|
|
jsx("div", {
|
|
class: "fluent-dashboard__meter-track",
|
|
role: "progressbar",
|
|
"aria-valuemin": 0,
|
|
"aria-valuemax": 100,
|
|
"aria-valuenow": Math.round(i),
|
|
children: jsx("span", {
|
|
class: "fluent-dashboard__meter-value",
|
|
style: `width:${i.toFixed(1)}%`
|
|
})
|
|
})
|
|
]
|
|
});
|
|
}));
|
|
}
|
|
function N(e) {
|
|
let t = [
|
|
...e.wan4.map((e)=>[
|
|
"IPv4",
|
|
e
|
|
]),
|
|
...e.wan6.map((e)=>[
|
|
"IPv6",
|
|
e
|
|
])
|
|
];
|
|
return A("internet", _("Internet"), S([
|
|
_("Family"),
|
|
_("Interface"),
|
|
_("Status"),
|
|
_("Protocol"),
|
|
_("Address"),
|
|
_("Gateway"),
|
|
_("Uptime")
|
|
], t.map(([e, t])=>[
|
|
e,
|
|
t.name,
|
|
v(t.up),
|
|
t.protocol,
|
|
t.addresses.join(", "),
|
|
t.gateway,
|
|
formatDuration(t.uptime)
|
|
]), _("No Internet connection information is available.")), !0);
|
|
}
|
|
function D(e) {
|
|
return A("interfaces", _("Interfaces"), S([
|
|
_("Interface"),
|
|
_("Device"),
|
|
_("Status"),
|
|
_("Address"),
|
|
_("Received"),
|
|
_("Transmitted")
|
|
], e.map((e)=>[
|
|
e.name,
|
|
e.device,
|
|
v(e.up),
|
|
e.addresses.join(", "),
|
|
formatBytes(e.rx),
|
|
formatBytes(e.tx)
|
|
]), _("No network interfaces were found.")), !0);
|
|
}
|
|
function k(t) {
|
|
return A("wireless", _("Wireless"), S([
|
|
_("Radio"),
|
|
_("SSID"),
|
|
_("Status"),
|
|
_("Mode"),
|
|
_("Channel"),
|
|
_("Encryption")
|
|
], t.map((t)=>[
|
|
jsx("span", {
|
|
title: t.hardware,
|
|
children: b(t.radio)
|
|
}),
|
|
t.ssid,
|
|
v(t.up),
|
|
t.mode,
|
|
null === t.channel ? "-" : t.frequency ? `${t.channel} (${t.frequency} GHz)` : t.channel,
|
|
t.encryption
|
|
]), _("No wireless radios were found.")), !0);
|
|
}
|
|
function C(e) {
|
|
return A("leases", _("Active DHCP Leases"), S([
|
|
_("Family"),
|
|
_("Hostname"),
|
|
_("Address"),
|
|
_("MAC / DUID"),
|
|
_("Expires")
|
|
], e.map((e)=>{
|
|
var t;
|
|
return [
|
|
e.family,
|
|
e.hostname,
|
|
e.address,
|
|
e.identifier,
|
|
!1 === (t = e.expires) ? _("Unlimited") : t <= 0 ? _("Expired") : formatDuration(t)
|
|
];
|
|
}), _("There are no active DHCP leases.")), !0);
|
|
}
|
|
function P(e) {
|
|
return e > 0 ? `${(e / 1000).toFixed(1)} ${_("Mbit/s")}` : "-";
|
|
}
|
|
function M(e) {
|
|
return A("clients", _("Wireless Clients"), S([
|
|
_("Network"),
|
|
_("Host"),
|
|
_("MAC address"),
|
|
_("Signal"),
|
|
_("RX / TX Rate")
|
|
], e.map((e)=>[
|
|
e.network,
|
|
e.hostname,
|
|
e.mac,
|
|
null === e.noise ? `${e.signal} dBm` : `${e.signal} / ${e.noise} dBm`,
|
|
`${P(e.rxRate)} / ${P(e.txRate)}`
|
|
]), _("No wireless clients are connected.")), !0);
|
|
}
|
|
class $ extends L.view {
|
|
handleSave = null;
|
|
handleSaveApply = null;
|
|
handleReset = null;
|
|
root = null;
|
|
load() {
|
|
return Promise.all([
|
|
g(),
|
|
w()
|
|
]);
|
|
}
|
|
replaceSection(e, t) {
|
|
this.root?.querySelector(`[data-dashboard-section="${e}"]`)?.replaceWith(t);
|
|
}
|
|
async refreshSummary() {
|
|
if (!this.root?.isConnected) return;
|
|
let e = await g();
|
|
if (!this.root?.isConnected) return;
|
|
this.replaceSection("system", x(e.system)), this.replaceSection("resources", I(e.system)), this.replaceSection("internet", N(e)), this.replaceSection("interfaces", D(e.interfaces)), this.replaceSection("wireless", k(e.wireless));
|
|
let t = this.root.querySelector("[data-dashboard-updated]");
|
|
t && (t.textContent = e.updatedAt.toLocaleTimeString());
|
|
}
|
|
async refreshDetails() {
|
|
if (!this.root?.isConnected) return;
|
|
let e = await w();
|
|
this.root?.isConnected && (this.replaceSection("leases", C(e.leases)), this.replaceSection("clients", M(e.clients)));
|
|
}
|
|
render([r, a]) {
|
|
return document.getElementById("fluent-dashboard-styles") || document.head.appendChild(jsx("link", {
|
|
id: "fluent-dashboard-styles",
|
|
rel: "stylesheet",
|
|
href: L.resource("view/fluentdashboard/index.css")
|
|
})), this.root = jsxs("div", {
|
|
class: "fluent-dashboard",
|
|
children: [
|
|
jsxs("div", {
|
|
class: "fluent-dashboard__header",
|
|
children: [
|
|
jsxs("div", {
|
|
children: [
|
|
jsx("h1", {
|
|
children: _("Fluent Dashboard")
|
|
}),
|
|
jsx("p", {
|
|
children: _("A live overview of this OpenWrt device.")
|
|
})
|
|
]
|
|
}),
|
|
jsxs("p", {
|
|
class: "fluent-dashboard__updated",
|
|
children: [
|
|
_("Updated"),
|
|
" ",
|
|
jsx("time", {
|
|
"data-dashboard-updated": "",
|
|
children: r.updatedAt.toLocaleTimeString()
|
|
})
|
|
]
|
|
})
|
|
]
|
|
}),
|
|
jsxs("div", {
|
|
class: "fluent-dashboard__grid",
|
|
children: [
|
|
x(r.system),
|
|
I(r.system),
|
|
N(r),
|
|
D(r.interfaces),
|
|
k(r.wireless),
|
|
C(a.leases),
|
|
M(a.clients)
|
|
]
|
|
})
|
|
]
|
|
}), poll.add(()=>this.refreshSummary(), 5), poll.add(()=>this.refreshDetails(), 15), this.root;
|
|
}
|
|
}
|
|
const main = $;
|
|
|
|
|
|
return main; |