diff --git a/luci-app-vantage/Makefile b/luci-app-vantage/Makefile
index fcc20bed2..6cb0dc3cf 100644
--- a/luci-app-vantage/Makefile
+++ b/luci-app-vantage/Makefile
@@ -11,7 +11,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-vantage
PKG_VERSION:=1.0.15
-PKG_RELEASE:=25
+PKG_RELEASE:=26
PKG_LICENSE:=GPL-3.0-or-later
LUCI_TITLE:=Vantage dashboard
diff --git a/luci-app-vantage/htdocs/luci-static/resources/vantage/app.css b/luci-app-vantage/htdocs/luci-static/resources/vantage/app.css
index e566259c9..59a48dac3 100644
--- a/luci-app-vantage/htdocs/luci-static/resources/vantage/app.css
+++ b/luci-app-vantage/htdocs/luci-static/resources/vantage/app.css
@@ -110,6 +110,7 @@
--vt-b60: var(--vt-text-2);
--vt-band-ink: 60%; /* band colour in a chip's text: 4.5:1 on light surfaces */
--vt-series-up: var(--vt-chart-1);
+ --vt-tunnel: var(--vt-chart-4); /* a VPN's pipe on the line: apart from the accent, which the packets in it keep */
/* throughput directions: download keeps the uplink colour, upload
takes one that no band uses */
--vt-dir-dn: var(--vt-chart-1);
@@ -818,6 +819,44 @@ h2, h3{
.vt-app .vt-link-up .vt-ico { color: var(--vt-text-3); }
.vt-app .vt-link-meta { font-size: var(--vt-fs-micro); color: var(--vt-text-3); font-family: var(--vt-mono); white-space: nowrap; margin-top: 2px;
padding: 0 6px; border-radius: 6px; background: var(--vt-surface); }
+/* a full-tunnel VPN over the main line: its wire drawn as a pipe in its
+ own colour around the traffic, the tunnel named under the line's rates */
+.vt-app .vt-wire-tunnel { stroke-width: 9; stroke-linecap: round; stroke: color-mix(in oklab, var(--vt-tunnel) 24%, transparent); }
+.vt-app .vt-wire-tunnel.vt-wire-on { stroke: color-mix(in oklab, var(--vt-tunnel) 36%, transparent); }
+.vt-app .vt-link-tunnel {
+ display: inline-flex; align-items: center; gap: 4px; max-width: 100%; margin-top: 4px; padding: 1px 6px;
+ border: 1px solid color-mix(in oklab, var(--vt-tunnel) 60%, var(--vt-line)); border-radius: 6px;
+ background: var(--vt-surface); color: var(--vt-text-2); font-size: var(--vt-fs-micro); white-space: nowrap;
+}
+.vt-app .vt-link-tunnel[hidden] { display: none; }
+.vt-app .vt-link-tunnel .vt-ico { width: 11px; height: 11px; flex: none; color: var(--vt-tunnel); stroke-width: 2; }
+.vt-app .vt-link-tunnel-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; font-weight: var(--vt-fw-semibold); }
+.vt-app .vt-link-tunnel-proto { flex: none; color: var(--vt-text-3); text-transform: uppercase; letter-spacing: .04em; }
+.vt-app .vt-link-tunnel-proto:empty { display: none; }
+
+/* more than one line to the internet (failover, mwan3): the main line,
+ its rates and the device in one row as with one, the other lines
+ under the main one, each wired into the device's bottom edge
+ (wires.line). The branches span every row; the rows above and below
+ take what a tall branch column leaves, so the lines stay together. */
+.vt-app .vt-path-lines { grid-template-rows: 1fr auto auto 1fr; }
+.vt-app .vt-path-lines > .vt-node-gw { grid-area: 2 / 1; }
+.vt-app .vt-path-lines > .vt-link-label { grid-area: 2 / 2; }
+.vt-app .vt-path-lines > .vt-node-ap { grid-area: 2 / 3; }
+.vt-app .vt-path-lines > .vt-branches { grid-area: 1 / 4 / -1 / 5; }
+.vt-app .vt-lines { grid-area: 3 / 1; align-self: start; display: flex; flex-direction: column; gap: 12px; padding: 14px 0 6px; min-width: 0; }
+.vt-app .vt-lines > .vt-node { align-self: stretch; }
+.vt-app .vt-node-rates { flex-wrap: wrap; column-gap: .3em; row-gap: 0; }
+.vt-app .vt-node-rates > span:empty { display: none; }
+/* a line's name ellipsized; the tag goes under it when they don't fit */
+.vt-app .vt-node-kicker-tag { flex-wrap: wrap; row-gap: 2px; }
+.vt-app .vt-node-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
+/* the main line among others: the default route the kernel takes */
+.vt-app .vt-node-tag {
+ display: inline-flex; align-items: center; height: 16px; padding: 0 5px; border-radius: 4px;
+ text-transform: none; letter-spacing: 0; font-weight: var(--vt-fw-medium);
+ background: var(--vt-accent-soft); color: var(--vt-accent-text);
+}
/* the branches spread over the height the tile gets from its row, so a
tall neighbour leaves no empty band above or below the diagram */
@@ -836,6 +875,13 @@ h2, h3{
.vt-app .vt-branch > .vt-node { justify-self: start; min-width: 200px; }
.vt-app .vt-branch-ssids { padding-left: 34px; }
.vt-app .vt-branch-ssids .vt-node { max-width: none; align-self: stretch; }
+ /* one column: the main line, its rates, the other lines set in (their
+ wires join the main line's drop into the device), the device */
+ .vt-app .vt-path-lines { grid-template-rows: none; }
+ .vt-app .vt-path-lines > .vt-node-gw, .vt-app .vt-path-lines > .vt-link-label, .vt-app .vt-path-lines > .vt-node-ap,
+ .vt-app .vt-path-lines > .vt-branches, .vt-app .vt-lines { grid-area: auto; }
+ .vt-app .vt-lines { gap: 8px; padding: 0 0 0 34px; }
+ .vt-app .vt-lines > .vt-node { align-self: flex-start; min-width: 200px; max-width: 100%; }
}
/* ------------------------------------------------------------ 6. system */
diff --git a/luci-app-vantage/htdocs/luci-static/resources/vantage/model.js b/luci-app-vantage/htdocs/luci-static/resources/vantage/model.js
index c1b924e2b..23e562f05 100644
--- a/luci-app-vantage/htdocs/luci-static/resources/vantage/model.js
+++ b/luci-app-vantage/htdocs/luci-static/resources/vantage/model.js
@@ -23,6 +23,159 @@ function own(o, k) { return o != null && Object.prototype.hasOwnProperty.call(o,
function obj(v) { return (v && typeof v === 'object' && !Array.isArray(v)) ? v : {}; }
function arr(v) { return Array.isArray(v) ? v : []; }
+/* ------------------------------------------------------ default routes */
+
+/* lines to the internet the path and the chart show beside the main one;
+ any further one stays a network */
+var MAX_LINES = 4;
+
+/* netifd protocols, and kernel device types, of tunnels that ride over
+ another line: a full-tunnel VPN is not a second way out. PPTP and L2TP
+ are left out: some ISPs give their access through them. */
+var TUNNEL = /^(wireguard|openvpn|openconnect|openfortivpn|vpnc|sstp|gre|gretap|grev6|grev6tap|vti|vtiv6|xfrm|ipip|6in4|6to4|6rd|vxlan|vxlan6)$/;
+var TUNNEL_DEV = /^(wireguard|tun|tap|ipip|ip6tnl|sit|gre|gretap|ip6gre|ip6gretap|vti|vti6|xfrm|vxlan)$/;
+
+/* netifd lists a route's metric only when the route sets one; the
+ interface's metric applies otherwise. The kernel stores an IPv6
+ metric of 0 as 1024. */
+function metric(i, r) {
+ var m = r.metric != null ? +r.metric : +i.metric;
+ m = isFinite(m) ? m : 0;
+ return r.target === '::' && m === 0 ? 1024 : m;
+}
+/* a default in another table (policy routing: a VPN's own table) is
+ not the one ordinary traffic takes */
+function mainTable(i, r) {
+ var t = r.table != null ? r.table : i[r.target === '::' ? 'ip6table' : 'ip4table'];
+ return t == null || t === '' || t === 'main' || +t === 254;
+}
+/* the interface's best default route in the main table, IPv4 first */
+function defRoute(i) {
+ return arr(i.route).filter(function(r) {
+ return r && +r.mask === 0 && (r.target === '0.0.0.0' || r.target === '::') && mainTable(i, r);
+ }).sort(function(a, b) {
+ return (a.target === '::') - (b.target === '::') || metric(i, a) - metric(i, b);
+ })[0] || null;
+}
+function wanRank(i) {
+ return /^wan$/.test(i.interface) ? 0 : /^wan6$/.test(i.interface) ? 1 : /wan/i.test(i.interface) ? 2 : 3;
+}
+function upIfaces(ifaces) {
+ return arr(ifaces).filter(function(i) {
+ return i && i.up && i.interface !== 'loopback' && (i.l3_device || i.device);
+ });
+}
+function isTunnel(i, devs) {
+ var d = devs[i.l3_device || i.device];
+ return TUNNEL.test(i.proto || '') || !!(d && (TUNNEL_DEV.test(d.devtype || '') || d.type === 'tunnel'));
+}
+/* the interfaces with a default route, the line first: real lines
+ before tunnels (a full-tunnel VPN rides over a line, see ridingTunnel),
+ IPv4 before IPv6 (a softwire's IPv4 route among the IPv4 ones), then
+ the lowest metric, wan/wan6/*wan* on a tie, then the order netifd lists
+ them */
+function rankRouted(up, devs) {
+ return up.map(function(i, n) {
+ var r = defRoute(i);
+ /* a softwire's device is a tunnel's (ip6tnl), but it carries the line's IPv4, not a VPN */
+ var sw = SOFTWIRE.test(i.proto || '');
+ return r ? { i: i, tunnel: !sw && isTunnel(i, devs), softwire: sw, family: r.target === '::' ? 1 : 0,
+ metric: metric(i, r), wan: wanRank(i), n: n } : null;
+ }).filter(Boolean).sort(function(a, b) {
+ return a.tunnel - b.tunnel || a.family - b.family || a.metric - b.metric || a.wan - b.wan || a.n - b.n;
+ });
+}
+/* A full-tunnel VPN over the line: the tunnel holding the default route
+ that ordinary traffic takes, IPv4's whenever there is one, else IPv6's
+ (an IPv4 VPN over an IPv6-only line rides it too). `kernel` is the
+ kernel's own answer (luci.vantage routes: [ { family, dev, metric } ],
+ the route it takes to the internet, at most one a family), which
+ decides: of two routes with the same metric the kernel keeps the one
+ added last, which netifd's list cannot tell, and a VPN daemon may add
+ its own (OpenVPN's tun0) that netifd never lists. Over several next
+ hops (dev null), no tunnel. Without it, only a tunnel whose metric is
+ below that family's best line's, or the family's only default.
+ -> { i, metric } of the tunnel, or null */
+function ridingTunnel(ifaces, ranked, devs, kernel) {
+ if (Array.isArray(kernel)) {
+ var pick = function(fam) { return kernel.filter(function(x) { return x && x.family === fam && finite(x.metric); })[0]; };
+ var k = pick(4) || pick(6);
+ if (!k || typeof k.dev !== 'string') return null;
+ var i = upIfaces(ifaces).filter(function(x) {
+ return (x.l3_device || x.device) === k.dev && !SOFTWIRE.test(x.proto || '') && isTunnel(x, devs);
+ })[0];
+ return i ? { i: i, metric: k.metric } : null;
+ }
+ var fam = ranked.some(function(r) { return r.family === 0; }) ? 0 : 1;
+ var of = ranked.filter(function(r) { return r.family === fam; });
+ var t = of.filter(function(r) { return r.tunnel; })[0], line = of.filter(function(r) { return !r.tunnel; })[0];
+ return t && (!line || t.metric < line.metric) ? { i: t.i, metric: t.metric } : null;
+}
+
+/* The lines to the internet, the main one first: { r, members, metric }
+ with the interfaces each is made of. A softwire (DS-Lite, MAP-E,
+ 464XLAT) that wins carries IPv4 over the IPv6 line, so that line is
+ the main one, at the softwire's metric; it is never a line of its own,
+ nor a tunnel unless nothing else has a default. One line per L3
+ device: wan6 on wan's device (or an @wan alias) is part of wan's, and
+ so is an IPv6 interface on the device a PPPoE line runs over (its
+ counters hold the PPP session's). Two IPv4 lines that only share a
+ parent device (two PPPoE sessions on eth0) stay two. The main line
+ carries the full-tunnel VPN over it, if any (tunnel; ridingTunnel). */
+function groupLines(ifaces, devs, kernel) {
+ var ranked = rankRouted(upIfaces(ifaces), devs), main = ranked[0], groups = [];
+ if (!main) return groups;
+ var at = main.metric, rider = main.tunnel ? null : ridingTunnel(ifaces, ranked, devs, kernel);
+ if (main.softwire)
+ main = ranked.filter(function(r) { return !r.tunnel && !r.softwire && r.family === 1; })[0] || main;
+ /* l3: the members' L3 devices; dev4: the devices their IPv4 runs over */
+ function add(g, r) {
+ g.members.push(r.i);
+ g.l3.push(r.i.l3_device || r.i.device);
+ if (r.family === 0 && typeof r.i.device === 'string') g.dev4.push(r.i.device);
+ }
+ function start(r, m) {
+ var g = { r: r, members: [], metric: m, l3: [], dev4: [] };
+ add(g, r);
+ groups.push(g);
+ }
+ start(main, at);
+ groups[0].tunnel = rider;
+ ranked.forEach(function(r) {
+ if (r === main || r.softwire || r.tunnel) return;
+ var l3 = r.i.l3_device || r.i.device;
+ var g = groups.filter(function(x) { return x.l3.indexOf(l3) >= 0 || (r.family === 1 && x.dev4.indexOf(l3) >= 0); })[0];
+ if (g) add(g, r);
+ else start(r, r.metric);
+ });
+ return groups;
+}
+function cidrs(list) {
+ return arr(list).map(function(a) { return a && a.address ? a.address + '/' + a.mask : null; }).filter(Boolean);
+}
+/* a line's other interfaces add their addresses and DNS to it (wan6's
+ IPv6 on wan's line) */
+function absorb(x, g) {
+ function more(list, add) { add.forEach(function(v) { if (list.indexOf(v) < 0) list.push(v); }); }
+ g.members.slice(1).forEach(function(i) {
+ more(x.ipv4, cidrs(i['ipv4-address']));
+ more(x.ipv6, cidrs(i['ipv6-address']));
+ more(x.dns, arr(i['dns-server']).filter(function(v) { return typeof v === 'string'; }));
+ });
+ x.metric = g.metric;
+ x.ifaces = g.members.map(function(i) { return i.interface; });
+ return x;
+}
+/* Two lines on DSA ports of one switch: the conduit carries both (and
+ the other ports), so each keeps its own port's counters. */
+function ownConduits(lines) {
+ var shared = lines.map(function(x, k) {
+ return x.statsDev !== x.dev && lines.some(function(y, j) { return j !== k && (y.statsDev === x.statsDev || y.dev === x.statsDev); });
+ });
+ lines.forEach(function(x, k) { if (shared[k]) x.statsDev = x.dev; });
+ return lines;
+}
+
return baseclass.extend({
/* the highest rate a sample may carry; above it a counter was reset */
MAX_BPS: MAX_BPS,
@@ -213,67 +366,70 @@ return baseclass.extend({
return v + (sp.duplex === 'full' ? ' · ' + _('full duplex') : sp.duplex === 'half' ? ' · ' + _('half duplex') : '');
},
+ /* lines beside the main one that the model lists (m.uplinks) */
+ MAX_LINES: MAX_LINES,
+
/* Pick the interface carrying traffic in/out of this device, and the
physical device its counters live on. Prefer interfaces with a default
- route in the main table, as the kernel picks among them: IPv4 before IPv6, then the
- lowest metric (multi-WAN: the backup uplink has the higher one), with
+ route in the main table, as the kernel picks among them (groupLines):
+ real lines before tunnels, IPv4 before IPv6, then the lowest metric
+ (multi-WAN: the backup uplink has the higher one), with
wan/wan6/*wan* priority only on a tie. A softwire (DS-Lite, MAP-E,
- 464XLAT) carries IPv4 over the IPv6 uplink, so it ranks after IPv6:
- the uplink shown is the line, not the tunnel. Fall back to WAN names, then
+ 464XLAT) carries IPv4 over the IPv6 uplink: the uplink shown is
+ the line, not the tunnel. Fall back to WAN names, then
the first up interface. A bridge, or a VLAN on one (br-lan.10), is
followed to its wired member (wireless members skipped): the port
given as `via` (where the bridge learned the gateway), else one with
a link, netifd 'ethernet' preferred. `port` is the member known to lead to the
gateway: `via`, or the bridge's only wired member; null when it has
several and the gateway's port is unknown. DSA with hardware
- offload uses the conduit's counters. */
- resolveUplink: function(ifaces, devs, wirelessNames, via) {
- var self = this;
- ifaces = arr(ifaces);
+ offload uses the conduit's counters. `kernel`: the kernel's
+ default routes (luci.vantage routes), or null; with a full-tunnel
+ VPN over the line, `tunnel` names it (ridingTunnel). */
+ resolveUplink: function(ifaces, devs, wirelessNames, via, kernel) {
devs = obj(devs);
-
- var up = ifaces.filter(function(i) {
- return i && i.up && i.interface !== 'loopback' && (i.l3_device || i.device);
- });
- function named(list, re) { return list.filter(function(i) { return re.test(i.interface); })[0]; }
- function preferredWan(list) {
- return named(list, /^wan$/) || named(list, /^wan6$/) || named(list, /wan/i);
+ var g = groupLines(ifaces, devs, kernel)[0], up = upIfaces(ifaces);
+ if (g) {
+ var x = absorb(this.line(g.r.i, devs, wirelessNames, via), g), t = g.tunnel && g.tunnel.i;
+ x.tunnel = t ? { iface: t.interface, proto: t.proto && t.proto !== 'none' ? t.proto : null, dev: t.l3_device || t.device, metric: g.tunnel.metric } : null;
+ return x;
}
- function wanRank(i) {
- return /^wan$/.test(i.interface) ? 0 : /^wan6$/.test(i.interface) ? 1 : /wan/i.test(i.interface) ? 2 : 3;
- }
- /* netifd lists a route's metric only when the route sets one; the
- interface's metric applies otherwise. The kernel stores an IPv6
- metric of 0 as 1024. */
- function metric(i, r) {
- var m = r.metric != null ? +r.metric : +i.metric;
- m = isFinite(m) ? m : 0;
- return r.target === '::' && m === 0 ? 1024 : m;
- }
- /* a default in another table (policy routing: a VPN's own table) is
- not the one ordinary traffic takes */
- function mainTable(i, r) {
- var t = r.table != null ? r.table : i[r.target === '::' ? 'ip6table' : 'ip4table'];
- return t == null || t === '' || t === 'main' || +t === 254;
- }
- function defRoute(i) {
- return arr(i.route).filter(function(r) {
- return r && +r.mask === 0 && (r.target === '0.0.0.0' || r.target === '::') && mainTable(i, r);
- }).sort(function(a, b) {
- return (a.target === '::') - (b.target === '::') || metric(i, a) - metric(i, b);
- })[0] || null;
- }
-
+ function named(re) { return up.filter(function(i) { return re.test(i.interface); })[0]; }
/* An AP may retain an up, unmanaged WAN port without any routes. */
- var routed = up.map(function(i, n) {
- var r = defRoute(i);
- return r ? { i: i, family: SOFTWIRE.test(i.proto) ? 2 : r.target === '::' ? 1 : 0, metric: metric(i, r), wan: wanRank(i), n: n } : null;
- }).filter(Boolean).sort(function(a, b) {
- return a.family - b.family || a.metric - b.metric || a.wan - b.wan || a.n - b.n;
- });
- var pick = routed.length ? routed[0].i : preferredWan(up) || up[0];
- if (!pick) return null;
+ var pick = named(/^wan$/) || named(/^wan6$/) || named(/wan/i) || up[0];
+ return pick ? this.line(pick, devs, wirelessNames, via) : null;
+ },
+ /* The other lines to the internet beside `main` (resolveUplink's):
+ every other up interface with a default route in the main table
+ (failover by metric, mwan3), in the kernel's order, as groupLines
+ makes them: a softwire or a tunnel (WireGuard, OpenVPN, GRE,
+ 6in4, ...) rides over another line and is not one of its own; a
+ default in another table (policy routing) is not ordinary
+ traffic's. A WAN that is down has no route: it stays a network
+ until it comes up. On a bridge, `viaOf(next hop)` names the port
+ the bridge learned that gateway on; without it a bridge with
+ several wired ports keeps its own counters.
+ -> [ line, ... ] as resolveUplink's, without main */
+ extraUplinks: function(ifaces, devs, wirelessNames, main, viaOf) {
+ var self = this;
+ if (!main) return [];
+ devs = obj(devs);
+ return groupLines(ifaces, devs).slice(1).filter(function(g) {
+ return g.l3.indexOf(main.l3dev) < 0 && !g.members.some(function(i) { return i.interface === main.iface; });
+ }).map(function(g) {
+ var r = defRoute(g.r.i), hop = r && r.nexthop;
+ return absorb(self.line(g.r.i, devs, wirelessNames, hop && typeof viaOf === 'function' ? viaOf(hop) : null, true), g);
+ });
+ },
+
+ /* one line: the interface, the device its counters live on (see
+ resolveUplink), its addresses and its default route. `own`: on a
+ bridge with several wired ports and the gateway's port unknown,
+ the bridge's (or its VLAN's) own counters, not a guessed port's. */
+ line: function(pick, devs, wirelessNames, via, own) {
+ var self = this;
+ devs = obj(devs);
var l3 = pick.l3_device || pick.device, dev = l3, d = devs[dev], port = dev;
var isBridge = function(x) { return !!x && (x.type === 'bridge' || x.devtype === 'bridge') && Array.isArray(x['bridge-members']); };
var vlanOf = /^(.+)\.\d{1,4}$/.exec(dev);
@@ -284,16 +440,19 @@ return baseclass.extend({
var eth = wired.filter(function(m) { return devs[m] && devs[m].devtype === 'ethernet'; });
var lit = function(m) { return devs[m] && devs[m].carrier === true; };
var known = typeof via === 'string' && wired.indexOf(via) >= 0 ? via : null;
- var next = known || eth.filter(lit)[0] || wired.filter(lit)[0] || eth[0] || wired[0] || members[0];
- if (next) { dev = next; d = devs[dev] || null; }
- port = known || (wired.length === 1 ? wired[0] : null);
+ if (!known && own && wired.length > 1) port = null;
+ else {
+ var next = known || eth.filter(lit)[0] || wired.filter(lit)[0] || eth[0] || wired[0] || members[0];
+ if (next) { dev = next; d = devs[dev] || null; }
+ port = known || (wired.length === 1 ? wired[0] : null);
+ }
}
var statsDev = dev;
if (d && d.devtype === 'dsa' && d['hw-tc-offload'] && d.conduit && devs[d.conduit])
statsDev = d.conduit;
- var route = defRoute(pick), via = route && route.nexthop;
+ var route = defRoute(pick), hop = route && route.nexthop;
return {
iface: pick.interface,
l3dev: l3,
@@ -306,22 +465,28 @@ return baseclass.extend({
up: !!pick.up,
carrier: d ? d.carrier !== false : null,
speed: d ? this.parseSpeed(d.speed) : null,
- ipv4: arr(pick['ipv4-address']).map(function(a) { return a && a.address ? a.address + '/' + a.mask : null; }).filter(Boolean),
- ipv6: arr(pick['ipv6-address']).map(function(a) { return a && a.address ? a.address + '/' + a.mask : null; }).filter(Boolean),
- gateway: via && via !== '0.0.0.0' && via !== '::' ? via : null,
+ ipv4: cidrs(pick['ipv4-address']),
+ ipv6: cidrs(pick['ipv6-address']),
+ gateway: hop && hop !== '0.0.0.0' && hop !== '::' ? hop : null,
/* a tunnel's default route has no next hop: routed, without a gateway address */
defaultRoute: !!route,
+ metric: route ? metric(pick, route) : null,
dns: arr(pick['dns-server']).filter(function(s) { return typeof s === 'string'; }),
+ /* the interfaces the line is made of (wan, wan6) */
+ ifaces: [ pick.interface ],
stats: d && d.statistics ? d.statistics : null
};
},
/* The device's other networks (lan, guest, a VPN, ...): every
- interface except loopback and the uplink (wan6 shares wan's device).
- One entry per device, by interface name.
+ interface except loopback and the uplinks shown (a line or a list
+ of them, with the interfaces each is made of; wan6 shares wan's
+ device) and the full-tunnel VPN drawn on the main one. One entry
+ per device, by interface name.
-> [ { name, proto, dev, up, ipv4 } ] */
- networks: function(ifaces, uplink) {
+ networks: function(ifaces, uplinks) {
var seen = Object.create(null);
+ uplinks = arr(Array.isArray(uplinks) ? uplinks : [ uplinks ]).filter(Boolean);
return arr(ifaces).filter(function(i) {
return i && typeof i.interface === 'string' && i.interface !== 'loopback';
}).sort(function(a, b) {
@@ -337,7 +502,10 @@ return baseclass.extend({
ipv4: a4 ? a4.address + '/' + a4.mask : null
};
}).filter(function(n) {
- if (uplink && (n.name === uplink.iface || (n.dev && n.dev === uplink.l3dev))) return false;
+ if (uplinks.some(function(u) {
+ return n.name === u.iface || arr(u.ifaces).indexOf(n.name) >= 0 || (n.dev && n.dev === u.l3dev) ||
+ !!(u.tunnel && (n.name === u.tunnel.iface || (n.dev && n.dev === u.tunnel.dev)));
+ })) return false;
if (n.dev && seen[n.dev]) return false;
if (n.dev) seen[n.dev] = true;
return true;
@@ -407,6 +575,7 @@ return baseclass.extend({
assoc: { ifname: [ station ] }, hapd: { ifname: { clients } },
hapdStatus: { ifname: status }, hints, aliases, rdns, mdns,
fdb: [ luci.vantage wired host ] (-> wiredHosts),
+ routes: [ luci.vantage routes route ] or null,
vendor: fn(mac) -> name|null } */
build: function(raw) {
raw = raw || {};
@@ -491,7 +660,8 @@ return baseclass.extend({
radios.push(radio);
});
- var uplink = this.resolveUplink(raw.ifaces, devs, wlNames);
+ var kernel = Array.isArray(raw.routes) ? raw.routes : null;
+ var uplink = this.resolveUplink(raw.ifaces, devs, wlNames, null, kernel);
var subnets = uplink ? uplink.ipv4 : [];
function hintOf(mac) { return obj(hints[mac.toUpperCase()] || hints[mac]); }
@@ -517,17 +687,25 @@ return baseclass.extend({
if (!prev) wiredMacs.push(mac);
fdb[mac] = { port: h.port, bridge: typeof h.bridge === 'string' ? h.bridge : null, vlan: finite(h.vlan) ? h.vlan : null, seen: seen };
});
- /* the gateway, by the address the host hints give it; on a bridge
- with several ports the uplink is the port it was learned on */
- var gwMac = null;
- if (uplink && uplink.gateway) Object.keys(hints).forEach(function(k) {
- var mac = names.normMac(k);
- if (mac && arr(obj(hints[k]).ipaddrs).concat(arr(obj(hints[k]).ip6addrs)).indexOf(uplink.gateway) >= 0) gwMac = mac;
- });
+ /* a gateway, by the address the host hints give it; on a bridge
+ with several ports a line is the port it was learned on */
+ function macOf(addr) {
+ var found = null;
+ if (addr) Object.keys(hints).forEach(function(k) {
+ var mac = names.normMac(k);
+ if (mac && arr(obj(hints[k]).ipaddrs).concat(arr(obj(hints[k]).ip6addrs)).indexOf(addr) >= 0) found = mac;
+ });
+ return found;
+ }
+ var gwMac = uplink ? macOf(uplink.gateway) : null;
if (uplink && gwMac && fdb[gwMac] && uplink.port !== fdb[gwMac].port) {
- var via = this.resolveUplink(raw.ifaces, devs, wlNames, fdb[gwMac].port);
+ var via = this.resolveUplink(raw.ifaces, devs, wlNames, fdb[gwMac].port, kernel);
if (via && via.port === fdb[gwMac].port) uplink = via;
}
+ var uplinks = uplink ? ownConduits([ uplink ].concat(this.extraUplinks(raw.ifaces, devs, wlNames, uplink, function(hop) {
+ var mac = macOf(hop);
+ return mac && fdb[mac] ? fdb[mac].port : null;
+ }).slice(0, MAX_LINES))) : [];
/* the network on each bridge (or bridge VLAN: br-lan.10), and its
IPv4 subnets for the hosts' addresses */
var lans = Object.create(null);
@@ -670,7 +848,10 @@ return baseclass.extend({
storage: [ this.mount(info.root, _('Root (overlay)')), this.mount(info.tmp, _('Temporary (RAM)')) ].filter(Boolean)
},
uplink: uplink,
- networks: this.networks(raw.ifaces, uplink),
+ /* the main line first, then up to MAX_LINES others to the
+ internet; networks leaves out only these */
+ uplinks: uplinks,
+ networks: this.networks(raw.ifaces, uplinks),
radios: radios,
ssids: ssids,
clients: clients,
diff --git a/luci-app-vantage/htdocs/luci-static/resources/vantage/wires.js b/luci-app-vantage/htdocs/luci-static/resources/vantage/wires.js
index d4175a9b3..0a6d2e4aa 100644
--- a/luci-app-vantage/htdocs/luci-static/resources/vantage/wires.js
+++ b/luci-app-vantage/htdocs/luci-static/resources/vantage/wires.js
@@ -11,6 +11,7 @@
A box is { l, r, t, b, cy } relative to the path element. */
var STEPS = 32; /* points per curve before resampling */
+var LANE = 10; /* px between the main line's drop and the other lines', stacked */
var GAP = 16; /* px between dots, as the old dash pattern */
var STRIDE = 32; /* px a dot travels per period */
var PERIOD = { 1: 1600, 2: 1050, 3: 600 }; /* ms per STRIDE by speed */
@@ -50,6 +51,48 @@ return baseclass.extend({
return { d: 'M' + f1(x1) + ' ' + f1(y1) + 'V' + f1(y2 - rad) + 'Q' + f1(x1) + ' ' + f1(y2) + ' ' + f1(x1 + rad) + ' ' + f1(y2) + 'H' + f1(x2), pts: pts };
},
+ /* from another line to the internet (a, the k-th beside the main
+ one) into the device (b), clear of the main line's rates: side by
+ side and below the device, along a's middle and up into b's bottom
+ edge, each further line 14 px further in, so the wires nest
+ without crossing; stacked (a phone), from a's left edge down a lane
+ of their own beside the main line's drop (LANE px to its right, so
+ no line runs inside another's wire or a tunnel's pipe) into b's top
+ edge. Otherwise as curve(). */
+ line: function(a, b, k) {
+ var x1, y1, x2, y2, rad, i, s, v, pts = [];
+ if (b.l >= a.r - 2 && a.cy > b.b) {
+ x1 = a.r; y1 = a.cy; y2 = b.b;
+ x2 = Math.min(b.l + 18 + 14 * (k || 0), (b.l + b.r) / 2);
+ rad = Math.min(8, y1 - y2, x2 - x1);
+ if (rad > 0) {
+ pts.push([ x1, y1 ]);
+ for (i = 0; i <= 8; i++) {
+ /* quadratic corner from (x2 - rad, y1) via (x2, y1) to (x2, y1 - rad) */
+ s = i / 8; v = 1 - s;
+ pts.push([ v * v * (x2 - rad) + 2 * v * s * x2 + s * s * x2, v * v * y1 + 2 * v * s * y1 + s * s * (y1 - rad) ]);
+ }
+ pts.push([ x2, y2 ]);
+ return { d: 'M' + f1(x1) + ' ' + f1(y1) + 'H' + f1(x2 - rad) + 'Q' + f1(x2) + ' ' + f1(y1) + ' ' + f1(x2) + ' ' + f1(y1 - rad) + 'V' + f1(y2), pts: pts };
+ }
+ }
+ if (b.l < a.r - 2 && a.b <= b.t) {
+ x1 = a.l; y1 = a.cy; x2 = b.l + 18 + LANE; y2 = b.t;
+ rad = Math.min(8, x1 - x2, y2 - y1);
+ if (rad > 0) {
+ pts.push([ x1, y1 ]);
+ for (i = 0; i <= 8; i++) {
+ /* quadratic corner from (x2 + rad, y1) via (x2, y1) to (x2, y1 + rad) */
+ s = i / 8; v = 1 - s;
+ pts.push([ v * v * (x2 + rad) + 2 * v * s * x2 + s * s * x2, v * v * y1 + 2 * v * s * y1 + s * s * (y1 + rad) ]);
+ }
+ pts.push([ x2, y2 ]);
+ return { d: 'M' + f1(x1) + ' ' + f1(y1) + 'H' + f1(x2 + rad) + 'Q' + f1(x2) + ' ' + f1(y1) + ' ' + f1(x2) + ' ' + f1(y1 + rad) + 'V' + f1(y2), pts: pts };
+ }
+ }
+ return this.curve(a, b);
+ },
+
/* points at equal distances along a polyline, about `step` px apart,
each with the direction of travel in degrees (unwrapped, so the
keyframes never turn the long way round); { pts: [[x, y, deg]], len } */
diff --git a/luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js b/luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js
index f078ca458..5ec983d92 100644
--- a/luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js
+++ b/luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js
@@ -47,6 +47,9 @@ var callThermal = rpc.declare({ object: 'luci.vantage', method: 'thermal', expec
/* { hosts, crowded, switches }: crowded when a bridge holds too many
entries to list; switches, the swconfig switch ports behind a port */
var callWired = rpc.declare({ object: 'luci.vantage', method: 'wired', expect: { '': {} } });
+/* the route the kernel takes to the internet: which one it kept of two
+ with one metric; { routes: null } when it could not be asked */
+var callRoutes = rpc.declare({ object: 'luci.vantage', method: 'routes', expect: { '': {} } });
/* LuCI's own (its switch page's): link and speed of a switch's ports, in
result. The whole reply, and a failed call rejected: a default [] would
read as every port down */
@@ -296,6 +299,12 @@ var CHECK_ICONS = { uplink: 'port', cpu: 'cpu', memory: 'memory', radios: 'wifi'
function txt(el, s) { s = (s == null ? '' : String(s)); if (el.textContent !== s) el.textContent = s; return el; }
function setClass(el, c) { if (el.getAttribute('class') !== c) el.setAttribute('class', c); }
function setTitle(el, v) { if (el.getAttribute('title') !== v) el.setAttribute('title', v); }
+/* the throughput history of a line to the internet, the main one too,
+ by its interface: a failover starts the new main line's own history
+ instead of continuing the old one's. ':' keeps it apart from a radio's
+ (a uci section name). */
+function lineKey(x) { return 'up:' + x.iface; }
+function histMax(key) { return key.indexOf('up:') === 0 ? HIST_FAST : HIST_MAX; }
/* an element's own tag and attributes, or a text node's text */
function nodeSig(n) {
@@ -616,7 +625,9 @@ return view.extend({
L.resolveDefault(callWifi(), null),
L.resolveDefault(callHints(), {}),
L.resolveDefault(callThermal(), []),
- L.resolveDefault(callWired(), {})
+ L.resolveDefault(callWired(), {}),
+ /* null when the call fails (an older plugin): netifd's metrics decide */
+ L.resolveDefault(callRoutes(), null)
]).then(function(r) {
var wifiDevs = (r[4] && typeof r[4] === 'object') ? r[4] : null;
var wiredReply = (r[7] && typeof r[7] === 'object') ? r[7] : {};
@@ -669,6 +680,9 @@ return view.extend({
Object.keys(swState).forEach(function(n) { switchState[n] = swState[n].ports; });
return { info: r[0] || {}, stat: r[1] || '', ifaces: r[2] || [], devs: r[3] || {}, wifi: wifiDevs, hints: r[5] || {}, thermal: r[6] || [],
fdb: Array.isArray(wiredReply.hosts) ? wiredReply.hosts : [], fdbCrowded: wiredReply.crowded === true, switches: switches, switchState: switchState,
+ /* no answer (an older plugin, a lookup not sent, a failed call)
+ keeps the last one: no tunnel blinking off */
+ routes: r[8] && Array.isArray(r[8].routes) ? (self.kernelRoutes = r[8].routes) : (self.kernelRoutes || null),
assoc: assoc, hapd: hapd, hapdStatus: hapdStatus, iwinfo: iwinfo, at: Date.now(), started: started };
});
});
@@ -682,7 +696,8 @@ return view.extend({
var net = Object.create(null);
if (stored.net && typeof stored.net === 'object')
Object.keys(stored.net).forEach(function(k) {
- if (/^[A-Za-z0-9_.:-]{1,40}$/.test(k)) net[k] = series.valid(stored.net[k], 3, k === 'uplink' ? HIST_FAST : HIST_MAX, now, model.MAX_BPS);
+ /* 'uplink' (before #88) belongs to an interface nobody noted */
+ if (/^[A-Za-z0-9_.:-]{1,40}$/.test(k) && k !== 'uplink') net[k] = series.valid(stored.net[k], 3, histMax(k), now, model.MAX_BPS);
});
var clientHist = Object.create(null);
if (stored.clients && typeof stored.clients === 'object')
@@ -757,7 +772,7 @@ return view.extend({
var m = model.build({
board: this.board, info: raw.info, ifaces: raw.ifaces, devs: raw.devs, wifi: raw.wifi, iwinfo: raw.iwinfo,
assoc: raw.assoc, hapd: raw.hapd, hapdStatus: raw.hapdStatus, hints: raw.hints, fdb: raw.fdb,
- switches: raw.switches, switchState: raw.switchState,
+ switches: raw.switches, switchState: raw.switchState, routes: raw.routes,
aliases: this.aliases, rdns: st.rdns, mdns: st.mdns,
vendor: st.oui ? function(k) { return k ? st.oui.lookup(k) : null; } : null
});
@@ -790,7 +805,16 @@ return view.extend({
st.uplinkRate = upRate || null;
/* throughput history (only for ticks that produced a rate) */
- if (upRate && !upFast) this.pushNet('uplink', at, upRate);
+ if (upRate && !upFast) this.pushNet(lineKey(m.uplink), at, upRate);
+ /* the other lines to the internet: this poll's (the fast lane
+ samples the main one only) */
+ this.extraLines(m).forEach(function(x) { var r = st.devRates[x.statsDev]; if (r) self.pushNet(lineKey(x), at, r); });
+ /* a line gone for longer than the chart shows leaves no history */
+ var lineKeys = m.uplinks.map(lineKey);
+ Object.keys(st.hist.net).forEach(function(k) {
+ var h = st.hist.net[k];
+ if (/^up:/.test(k) && lineKeys.indexOf(k) < 0 && !(h.length && h[h.length - 1][0] > at - WINDOW_MS)) delete st.hist.net[k];
+ });
m.radios.forEach(function(r) { if (st.radioRates[r.id]) self.pushNet(r.id, at, st.radioRates[r.id]); });
/* station counters, per-station history */
@@ -863,7 +887,7 @@ return view.extend({
pushNet: function(key, at, r) {
var h = this.st.hist.net[key] || (this.st.hist.net[key] = []);
- series.push(h, [ at, r.rx, r.tx ], WINDOW_MS, key === 'uplink' ? HIST_FAST : HIST_MAX);
+ series.push(h, [ at, r.rx, r.tx ], WINDOW_MS, histMax(key));
},
/* ------------------------------------------------------- fast lane */
@@ -901,7 +925,7 @@ return view.extend({
if (dev && s) counters[dev] = { rx: s.rx_bytes, tx: s.tx_bytes };
var dr = model.rates(st.fastPrev, counters, now);
st.fastPrev = dr.next;
- if (dev && dr.rates[dev]) { st.uplinkRate = dr.rates[dev]; self.pushNet('uplink', at, st.uplinkRate); changed = true; }
+ if (dev && dr.rates[dev]) { st.uplinkRate = dr.rates[dev]; self.pushNet(lineKey(up), at, st.uplinkRate); changed = true; }
/* both answered: the full poll leaves CPU and the uplink to this lane */
if (stat && (!dev || s)) st.fastAt = now;
if (changed) self.paintFast();
@@ -972,7 +996,7 @@ return view.extend({
var m = model.build({
board: this.board, info: raw.info, ifaces: raw.ifaces, devs: raw.devs, wifi: raw.wifi, iwinfo: raw.iwinfo,
assoc: raw.assoc, hapd: raw.hapd, hapdStatus: raw.hapdStatus, hints: raw.hints, fdb: raw.fdb,
- switches: raw.switches, switchState: raw.switchState,
+ switches: raw.switches, switchState: raw.switchState, routes: raw.routes,
aliases: this.aliases, rdns: st.rdns, mdns: st.mdns,
vendor: st.oui ? function(k) { return k ? st.oui.lookup(k) : null; } : null
});
@@ -1608,7 +1632,7 @@ return view.extend({
the card's bottom edge; CPU scaled to at least 20 % so a quiet
device still shows its shape */
case 'uplink':
- return [ sparkline(st.hist.net.uplink || [], [ 1 ], 0, 'vt-spark-up', { min: 1000, quiet: true, bare: true }) ];
+ return [ sparkline((this.m && this.m.uplink && st.hist.net[lineKey(this.m.uplink)]) || [], [ 1 ], 0, 'vt-spark-up', { min: 1000, quiet: true, bare: true }) ];
case 'cpu':
return [ sparkline(st.hist.cpu || [], [ 1 ], 0, 'vt-spark-cpu', { min: 20, quiet: true, bare: true }) ];
case 'memory':
@@ -1698,26 +1722,38 @@ return view.extend({
/* the nodes the path shows: rebuilt only when this changes (a radio,
SSID or network comes or goes); a poll updates text in place */
heroKey: function() {
- var m = this.m;
- if (m.wired) return 'w\n' + m.networks.filter(function(n) { return n.up; }).slice(0, 8).map(function(n) { return n.name; }).join('\n');
+ var m = this.m, lines = '\nlines=' + this.extraLines().map(function(x) { return x.iface; }).join(',');
+ if (m.wired) return 'w\n' + m.networks.filter(function(n) { return n.up; }).slice(0, 8).map(function(n) { return n.name; }).join('\n') + lines;
return 'r\n' + m.radios.map(function(r) {
return r.id + '=' + m.ssids.filter(function(s) { return s.radio === r.id; }).map(function(s) { return s.id; }).join(',');
- }).join('\n') + '\nwired=' + this.wiredPorts().join(',');
+ }).join('\n') + '\nwired=' + this.wiredPorts().join(',') + lines;
+ },
+
+ /* the lines to the internet beside the main one (failover, mwan3;
+ at most model.MAX_LINES) */
+ extraLines: function(m) {
+ m = m || this.m;
+ return ((m && m.uplinks) || []).slice(1);
},
/* the ports with wired hosts downstream of this device, at most 8:
- hosts on the uplink's port are the way to the gateway, not clients
+ hosts on a line's port are the way to its gateway, not clients
(on a bridge with several ports whose gateway port is unknown, only
the gateway is left out) */
wiredPorts: function() {
- var m = this.m, up = m.uplink, out = [];
+ var m = this.m, out = [], self = this;
(m.wiredHosts || []).forEach(function(c) {
- if (c.gateway || (up && up.port && c.port === up.port)) return;
+ if (c.gateway || self.linePort(c.port)) return;
if (out.indexOf(c.port) < 0) out.push(c.port);
});
return out.sort().slice(0, 8);
},
+ /* the port is one a line to the internet leaves through */
+ linePort: function(port) {
+ return ((this.m && this.m.uplinks) || []).some(function(x) { return x.port && x.port === port; });
+ },
+
/* the Clients tile on its wired list, on one port's hosts or all */
showWired: function(port) {
this.ui.kind = 'wired';
@@ -1759,18 +1795,40 @@ return view.extend({
if (c !== self.el.wires && c !== self.el.flows) path.removeChild(c);
});
- h.gwKicker = span('vt-node-kicker'); h.gwTitle = span('vt-node-title'); h.gwSub = span('vt-node-sub');
- h.gw = E('button', { 'type': 'button', 'class': 'vt-node vt-node-gw', 'click': function() { self.openDrawer('uplink', 'uplink'); } }, [
+ /* more than one line to the internet: each by its interface, the
+ main one (the default route the kernel takes) marked */
+ var extra = this.extraLines();
+ h.gwKicker = span(extra.length ? 'vt-node-name' : 'vt-node-kicker'); h.gwTitle = span('vt-node-title'); h.gwSub = span('vt-node-sub');
+ h.gwTag = extra.length ? E('span', { 'class': 'vt-node-tag' }, [ _('default route') ]) : null;
+ h.gw = E('button', { 'type': 'button', 'class': 'vt-node vt-node-gw', 'click': function() { self.openDrawer('uplink', ''); } }, [
E('span', { 'class': 'vt-node-ico' }, [ icon('globe') ]),
- E('span', { 'class': 'vt-node-body' }, [ h.gwKicker, h.gwTitle, h.gwSub ])
+ E('span', { 'class': 'vt-node-body' }, [
+ h.gwTag ? E('span', { 'class': 'vt-node-kicker vt-node-kicker-tag' }, [ h.gwKicker, h.gwTag ]) : h.gwKicker,
+ h.gwTitle, h.gwSub
+ ])
]);
+ h.lines = extra.map(function(x) {
+ /* its rates as two items, so a narrow node wraps them rather than cut them */
+ var ln = { id: x.iface, kicker: span('vt-node-name'), title: span('vt-node-title'), dn: E('span'), up: E('span') };
+ ln.el = E('button', { 'type': 'button', 'class': 'vt-node vt-node-gw vt-node-line', 'click': function() { self.openDrawer('uplink', ln.id); } }, [
+ E('span', { 'class': 'vt-node-ico' }, [ icon('globe') ]),
+ E('span', { 'class': 'vt-node-body' }, [ E('span', { 'class': 'vt-node-kicker' }, [ ln.kicker ]), ln.title, E('span', { 'class': 'vt-node-sub vt-node-rates vt-tn' }, [ ln.dn, ln.up ]) ])
+ ]);
+ return ln;
+ });
+ h.linesEl = extra.length ? E('div', { 'class': 'vt-lines' }, h.lines.map(function(ln) { return ln.el; })) : null;
+ setClass(path, 'vt-path' + (extra.length ? ' vt-path-lines' : ''));
h.dnVal = E('b'); h.dnUnit = E('small'); h.upVal = E('b'); h.upUnit = E('small'); h.linkMeta = span('vt-link-meta');
+ /* a full-tunnel VPN over the line: named on the link it runs through */
+ h.tunName = span('vt-link-tunnel-name'); h.tunProto = span('vt-link-tunnel-proto');
+ h.tunnel = E('span', { 'class': 'vt-link-tunnel', 'hidden': '' }, [ icon('lock'), h.tunName, h.tunProto ]);
h.link = E('div', { 'class': 'vt-link-label' }, [
E('span', { 'class': 'vt-link-rate vt-link-down' }, [ icon('down'), h.dnVal, h.dnUnit ]),
E('span', { 'class': 'vt-link-below' }, [
E('span', { 'class': 'vt-link-rate vt-link-up' }, [ icon('up'), h.upVal, h.upUnit ]),
- h.linkMeta
+ h.linkMeta,
+ h.tunnel
])
]);
@@ -1782,6 +1840,7 @@ return view.extend({
h.branches = E('div', { 'class': 'vt-branches' });
h.watch = [ path, h.gw, h.link, h.ap, h.branches ];
+ h.lines.forEach(function(ln) { h.watch.push(ln.el); });
if (m.wired) {
m.networks.filter(function(n) { return n.up; }).slice(0, 8).forEach(function(n) {
var b = { id: n.name, ssids: [], kicker: span('vt-node-kicker'), title: span('vt-node-title'), addr: span('vt-node-sub vt-mono'), sub: span('vt-node-sub vt-tn') };
@@ -1844,6 +1903,8 @@ return view.extend({
path.insertBefore(h.gw, this.el.wires);
path.insertBefore(h.link, this.el.wires);
+ /* after the main line's rates: on a phone they stay with it */
+ if (h.linesEl) path.insertBefore(h.linesEl, this.el.wires);
path.insertBefore(h.ap, this.el.wires);
path.insertBefore(h.branches, this.el.wires);
this.hero = h;
@@ -1861,7 +1922,7 @@ return view.extend({
name once one is known beyond its vendor */
var gwHost = (m.wiredHosts || []).filter(function(c) { return c.gateway; })[0];
var gwName = gwHost && /^(alias|dhcp|mdns|dns)$/.test(gwHost.nameSource) ? gwHost.name : null;
- txt(h.gwKicker, up && up.isWan ? _('Internet') : _('Gateway'));
+ txt(h.gwKicker, h.lines.length && up ? up.iface : up && up.isWan ? _('Internet') : _('Gateway'));
txt(h.gwTitle, gwName || (up && up.gateway ? up.gateway : up && up.defaultRoute ? up.l3dev : _('No default route', 'vantage')));
txt(h.gwSub, gwName ? up.gateway : up && up.dns.length ? _('DNS %s').format(up.dns[0]) : _('Reachability not probed'));
@@ -1870,6 +1931,13 @@ return view.extend({
txt(h.upVal, upR ? fmt.bitsParts(upR.tx).v : fmt.DASH);
txt(h.upUnit, upR ? fmt.bitsParts(upR.tx).u : '');
txt(h.linkMeta, up ? [ up.dev, up.speed ? (up.speed.mbps >= 1000 ? (up.speed.mbps / 1000) + 'G' : up.speed.mbps + 'M') + (up.speed.duplex === 'full' ? ' FD' : up.speed.duplex === 'half' ? ' HD' : '') : null ].filter(Boolean).join(' · ') : _('no uplink'));
+ var tun = up && up.tunnel, tunR = tun ? st.devRates[tun.dev] : null;
+ if (h.tunnel.hidden !== !tun) h.tunnel.hidden = !tun;
+ txt(h.tunName, tun ? tun.iface : '');
+ txt(h.tunProto, tun && tun.proto ? tun.proto : '');
+ setTitle(h.tunnel, tun ? _('Traffic to the internet goes through %s, a tunnel over this line').format(tun.iface) +
+ (tunR ? ' · ↓ ' + fmt.bits(tunR.rx) + ' · ↑ ' + fmt.bits(tunR.tx) : '') : '');
+ if (h.gwTag) txt(h.gwTag, tun ? _('default route via %s').format(tun.iface) : _('default route'));
txt(h.apKicker, m.wired ? _('This device') : _('This access point'));
txt(h.apTitle, d.model);
@@ -1879,6 +1947,22 @@ return view.extend({
h.upRate = upR ? upR.rx + upR.tx : 0;
if (this.backdrop) this.backdrop.update({ down: upR ? upR.rx : null, up: upR ? upR.tx : null, origin: h.ap });
+ var lines = Object.create(null);
+ this.extraLines().forEach(function(x) { lines[x.iface] = x; });
+ h.lines.forEach(function(ln) {
+ var x = lines[ln.id], r = x ? st.devRates[x.statsDev] : null;
+ if (!x) return;
+ setTitle(ln.el, [ x.iface, x.dev, x.speed ? model.speedLabel(x.speed) : null ].filter(Boolean).join(' · '));
+ setClass(ln.el, 'vt-node vt-node-gw vt-node-line' + (x.carrier === false ? ' vt-node-off' : ''));
+ txt(ln.kicker, x.iface);
+ txt(ln.title, x.gateway || x.l3dev);
+ var p = r && !(r.rx === 0 && r.tx === 0) ? fmt.rateParts(r.rx, r.tx) : null;
+ txt(ln.dn, p ? '↓ ' + p.dn : r ? _('idle') : fmt.DASH);
+ txt(ln.up, p ? '↑ ' + p.up + (p.unit ? ' ' + p.unit : '') : '');
+ ln.active = !!(r && r.rx + r.tx > 50e3);
+ ln.rate = r ? r.rx + r.tx : 0;
+ });
+
if (m.wired) {
var nets = Object.create(null);
m.networks.forEach(function(n) { if (n.up && !nets[n.name]) nets[n.name] = n; });
@@ -1976,7 +2060,8 @@ return view.extend({
wireList: function() {
var h = this.hero, out = [];
if (!h) return out;
- out.push({ key: 'gw', from: h.gw, to: h.ap, active: h.upActive, speed: wires.speed(h.upRate), main: true });
+ out.push({ key: 'gw', from: h.gw, to: h.ap, active: h.upActive, speed: wires.speed(h.upRate), main: true, tunnel: !!(this.m && this.m.uplink && this.m.uplink.tunnel) });
+ h.lines.forEach(function(ln, k) { out.push({ key: 'l:' + ln.id, from: ln.el, to: h.ap, active: ln.active, speed: wires.speed(ln.rate), line: k }); });
h.radios.forEach(function(b) {
out.push({ key: 'r:' + b.id, from: h.ap, to: b.el, active: b.active, speed: wires.speed(b.rate) });
b.ssids.forEach(function(sn) { out.push({ key: 's:' + b.id + ':' + sn.id, from: b.el, to: sn.el, active: sn.active, speed: 1 }); });
@@ -2023,7 +2108,7 @@ return view.extend({
svg.appendChild(g.flow);
self.el.flows.appendChild(g.fw);
}
- var c = wires.curve(rect(w.from), rect(w.to));
+ var c = w.line != null ? wires.line(rect(w.from), rect(w.to), w.line) : wires.curve(rect(w.from), rect(w.to));
if (g.d !== c.d) {
g.base.setAttribute('d', c.d);
g.flow.setAttribute('d', c.d);
@@ -2052,7 +2137,7 @@ return view.extend({
this.wireList().forEach(function(w) {
var g = map[w.key];
if (!g) return;
- setClass(g.base, 'vt-wire' + (w.main ? ' vt-wire-main' : '') + (w.active ? ' vt-wire-on' : ''));
+ setClass(g.base, 'vt-wire' + (w.main ? ' vt-wire-main' : '') + (w.tunnel ? ' vt-wire-tunnel' : '') + (w.active ? ' vt-wire-on' : ''));
setClass(g.flow, 'vt-flow vt-flow-' + w.speed + (w.active ? ' vt-flow-on' : ''));
self.syncFlow(g, !!(w.active && !still && g.d), w.speed);
});
@@ -2253,7 +2338,8 @@ return view.extend({
]));
},
- /* one small multiple per link: the uplink, then each radio, each with
+ /* one small multiple per link: the uplink, the other lines to the
+ internet, then each radio, each with
its own y scale (a busy uplink would flatten an idle radio), on a
shared time axis and crosshair. Download (towards the clients) and
upload each keep their direction's colour; how they share the plot
@@ -2262,7 +2348,8 @@ return view.extend({
download, a radio sends it. */
chartSeries: function() {
var m = this.m;
- var list = [ { key: 'uplink', label: m.uplink ? _('Uplink %s').format(m.uplink.dev) : _('Uplink', 'vantage'), dn: 1, up: 2 } ];
+ var list = [ { key: m.uplink ? lineKey(m.uplink) : 'uplink', label: m.uplink ? _('Uplink %s').format(m.uplink.dev) : _('Uplink', 'vantage'), dn: 1, up: 2 } ];
+ this.extraLines().forEach(function(x) { list.push({ key: lineKey(x), label: _('Uplink %s').format(x.dev), dn: 1, up: 2 }); });
m.radios.forEach(function(r) { list.push({ key: r.id, label: _('%s radio').format(r.bandLabel), dn: 2, up: 1 }); });
return list;
},
@@ -2278,7 +2365,10 @@ return view.extend({
start part way across and the minute labels stay where they are
(a span that grew with the history moved them every poll, #71) */
var dm = series.domain(list.map(function(s) { return net[s.key]; }), now, WINDOW_MS, WINDOW_MS);
- dm.full = dm.age >= WINDOW_MS - 1000;
+ /* history keeps only samples newer than the window, so its oldest is
+ up to one poll short of five minutes: allow two polls, or the
+ subtitle flips to "collecting" with a full history */
+ dm.full = dm.age >= WINDOW_MS - POLL_S * 2000;
var ticks = [];
for (var k = 1; k * 60000 < dm.span - 20000; k++) ticks.push(k);
var rows = [], samples = 0;
@@ -2857,9 +2947,8 @@ return view.extend({
var bar = E('span', { 'class': 'vt-mini-fill' });
setW(bar, maxRate > 0 ? total / maxRate * 100 : 0);
var tags = [];
- var up = this.m && this.m.uplink;
if (c.gateway) tags.push(pill(_('Gateway'), 'accent', _('The router this device sends its traffic to')));
- else if (up && up.port && c.port === up.port) tags.push(pill(_('Upstream'), 'muted', _('Reached through the uplink port %s, not connected to this device').format(c.port)));
+ else if (this.linePort(c.port)) tags.push(pill(_('Upstream'), 'muted', _('Reached through the uplink port %s, not connected to this device').format(c.port)));
if (c.vlan != null) tags.push(pill(_('VLAN %d').format(c.vlan), 'muted'));
var speed = c.speed ? fmt.phyRate(c.speed.mbps * 1000) : fmt.DASH;
var link = E('td', { 'class': 'vt-td-link', 'data-title': _('Link', 'vantage') }, [
@@ -3033,7 +3122,7 @@ return view.extend({
this.ui.editing = null;
/* the address names what is shown, also when the open drawer
moves on (from a radio to one of its clients) */
- try { history.replaceState(null, '', '#' + kind + '=' + encodeURIComponent(id)); } catch (e) {}
+ try { history.replaceState(null, '', '#' + kind + (kind === 'uplink' && !id ? '' : '=' + encodeURIComponent(id))); } catch (e) {}
if (!el.drawer.hidden) { this.paintDrawer(); this.paintClients(); return; }
this.lastFocus = document.activeElement;
el.drawer.hidden = false;
@@ -3056,16 +3145,19 @@ return view.extend({
},
/* A deep link names an existing thing or nothing: a client by a
- station MAC, a radio this device reports; uplink and device take no
- id. Anything else is dropped from the address bar, so a crafted link
- cannot put its own text in the drawer title. */
+ station MAC, a radio this device reports, a line to the internet by
+ its interface (#uplink alone: the main one, whichever it is); the
+ device takes no id. Anything else is dropped from the address bar,
+ so a crafted link cannot put its own text in the drawer title. */
openFromHash: function() {
var hash = location.hash || '', m = /^#(client|radio|uplink|device)=(.{1,128})$/.exec(hash), id = null;
+ if (hash === '#uplink') { this.openDrawer('uplink', ''); return; }
if (m) {
try { id = decodeURIComponent(m[2]); } catch (e) { id = null; }
if (id == null) { /* malformed escape */ }
else if (m[1] === 'client') id = names.normMac(id);
else if (m[1] === 'radio') id = this.m && this.m.radios.some(function(r) { return r.id === id; }) ? id : null;
+ else if (m[1] === 'uplink') id = ((this.m && this.m.uplinks) || []).some(function(x) { return x.iface === id; }) ? id : '';
else id = m[1];
}
if (id != null) { this.openDrawer(m[1], id); return; }
@@ -3081,7 +3173,7 @@ return view.extend({
var content;
if (d.kind === 'client') content = this.drawerClient(d.id);
else if (d.kind === 'radio') content = this.drawerRadio(d.id);
- else if (d.kind === 'uplink') content = this.drawerUplink();
+ else if (d.kind === 'uplink') content = this.drawerUplink(d.id);
else content = this.drawerDevice();
dom.content(el.drawerTitle, content.title);
dom.content(el.drawerBody, content.body);
@@ -3368,9 +3460,26 @@ return view.extend({
};
},
- drawerUplink: function() {
- var up = this.m.uplink, r = this.st.uplinkRate;
+ /* the main line (id ''), whichever interface it is, or one line by
+ its interface: still that one after a failover makes it the main
+ line, and said to be down when it is no line any more (never
+ another interface under its name) */
+ drawerUplink: function(id) {
+ var m = this.m, st = this.st, lines = m.uplinks || [];
+ var up = id ? lines.filter(function(x) { return x.iface === id; })[0] : m.uplink;
+ var r = up && up === m.uplink ? st.uplinkRate : up ? st.devRates[up.statsDev] || null : null;
+ var hist = up ? st.hist.net[lineKey(up)] : null, several = lines.length > 1;
+ var tunR = up && up.tunnel ? st.devRates[up.tunnel.dev] || null : null;
function errors(n) { return fmt.N_(n, '%s error', '%s errors').format(fmt.count(n)); }
+ if (id && !up) return {
+ title: [ E('span', { 'class': 'vt-drawer-ico' }, [ icon('globe') ]), E('div', { 'class': 'vt-drawer-titles' }, [
+ E('div', { 'class': 'vt-drawer-name' }, [ _('Uplink · %s').format(id) ])
+ ]) ],
+ body: [
+ E('div', { 'class': 'vt-dactions' }, [ pageLink(insight.PAGES.network, _('Interfaces')) ]),
+ E('p', { 'class': 'vt-empty-inline' }, [ _('This line is down or has no default route now.') ])
+ ]
+ };
if (!up) return { title: [ E('span', { 'class': 'vt-drawer-name' }, [ _('Uplink', 'vantage') ]) ], body: [ E('p', { 'class': 'vt-empty-inline' }, [ _('No interface with a route is up.') ]) ] };
var s = up.stats || {};
return {
@@ -3384,17 +3493,22 @@ return view.extend({
E('div', { 'class': 'vt-dcard' }, [ E('div', { 'class': 'vt-dcard-label' }, [ _('From network') ]), E('div', { 'class': 'vt-dcard-value' }, [ r ? fmt.bits(r.rx) : fmt.DASH ]), E('div', { 'class': 'vt-dcard-sub' }, [ _('received on %s').format(up.dev) ]) ]),
E('div', { 'class': 'vt-dcard' }, [ E('div', { 'class': 'vt-dcard-label' }, [ _('To network') ]), E('div', { 'class': 'vt-dcard-value' }, [ r ? fmt.bits(r.tx) : fmt.DASH ]), E('div', { 'class': 'vt-dcard-sub' }, [ _('sent on %s').format(up.dev) ]) ])
]),
- E('div', { 'class': 'vt-dspark' }, [ sparkline(this.st.hist.net.uplink || [], [ 1, 2 ], 0, 'vt-spark-up', { min: 1000, scale: bitsLabel }) ]),
+ E('div', { 'class': 'vt-dspark' }, [ sparkline(hist || [], [ 1, 2 ], 0, 'vt-spark-up', { min: 1000, scale: bitsLabel }) ]),
this.section(_('Link', 'vantage'), [ E('dl', { 'class': 'vt-kvs' }, [
kv(_('Carrier'), up.carrier === false ? _('No link') : _('Up', 'vantage')),
kv(_('Speed', 'vantage'), model.speedLabel(up.speed)),
kv(_('Protocol'), up.proto || fmt.DASH),
- kv(_('Interface up for'), up.uptime != null ? fmt.duration(up.uptime) : fmt.DASH)
+ kv(_('Interface up for'), up.uptime != null ? fmt.duration(up.uptime) : fmt.DASH),
+ /* a full-tunnel VPN over this line: ordinary traffic goes through it */
+ up.tunnel ? kv(_('Tunnel'), up.tunnel.iface + (up.tunnel.proto ? ' · ' + up.tunnel.proto : '')) : '',
+ up.tunnel ? kv(_('In the tunnel'), tunR ? '↓ ' + fmt.bits(tunR.rx) + ' · ↑ ' + fmt.bits(tunR.tx) : fmt.DASH) : ''
]) ]),
this.section(_('Addresses'), [ E('dl', { 'class': 'vt-kvs' }, [
kv(_('IPv4'), up.ipv4.join('\n') || fmt.DASH, true),
kv(_('IPv6'), up.ipv6.join('\n') || fmt.DASH, true),
kv(_('Gateway'), up.gateway || fmt.DASH, true),
+ /* beside other lines, the metric says which one the kernel takes */
+ several ? kv(_('Route metric'), up.metric != null ? String(up.metric) : fmt.DASH, true) : '',
kv(_('DNS'), up.dns.join('\n') || fmt.DASH, true)
]) ]),
this.section(_('Counters since boot'), [ E('dl', { 'class': 'vt-kvs' }, [
diff --git a/luci-app-vantage/po/templates/vantage.pot b/luci-app-vantage/po/templates/vantage.pot
index 5968746d3..5e94bf2dc 100644
--- a/luci-app-vantage/po/templates/vantage.pot
+++ b/luci-app-vantage/po/templates/vantage.pot
@@ -1,7 +1,7 @@
msgid ""
msgstr "Content-Type: text/plain; charset=UTF-8"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3354
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3446
msgid "%d MHz (%d–%d MHz)"
msgstr ""
@@ -29,19 +29,19 @@ msgid_plural "%d SSIDs · %d idle"
msgstr[0] ""
msgstr[1] ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1523
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1931
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2476
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1547
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2015
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2566
msgid "%d clients"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2813
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2903
msgid "%d connected"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1958
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1962
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2812
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2042
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2046
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2902
msgid "%d devices"
msgstr ""
@@ -56,22 +56,22 @@ msgid_plural "%d measured clients are above %s"
msgstr[0] ""
msgstr[1] ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:449
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:458
msgctxt "vantage"
msgid "%d min"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/fmt.js:118
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:443
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:452
msgctxt "vantage"
msgid "%d min ago"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2811
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2901
msgid "%d of %d"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1410
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1434
msgid "%d of %d columns"
msgstr ""
@@ -101,17 +101,17 @@ msgid_plural "%d radios up"
msgstr[0] ""
msgstr[1] ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2468
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2558
msgid "%d radios"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:449
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:458
msgctxt "vantage"
msgid "%d s"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/fmt.js:117
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:443
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:452
msgctxt "vantage"
msgid "%d s ago"
msgstr ""
@@ -125,7 +125,7 @@ msgstr ""
msgid "%d weak"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2487
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2577
msgid "%d–%d MHz of the %d–%d MHz band"
msgstr ""
@@ -143,27 +143,27 @@ msgstr ""
msgid "%s (IPv%d)"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3176
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3268
msgid "%s (new this session)"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:24
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:212
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:365
msgid "%s Gbit/s"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/fmt.js:166
#: luci-app-vantage/htdocs/luci-static/resources/vantage/wifi.js:103
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2494
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2508
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2911
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3347
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2584
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2598
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3000
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3439
msgid "%s MHz"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:24
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:51
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:212
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:365
msgid "%s Mbit/s"
msgstr ""
@@ -176,13 +176,13 @@ msgid "%s at %s; below %s roaming and throughput suffer"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:83
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2174
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2259
msgctxt "vantage"
msgid "%s available"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2514
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3355
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2604
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3447
msgid "%s dBm"
msgstr ""
@@ -194,13 +194,13 @@ msgstr ""
msgid "%s device on a newer radio; uses more airtime per byte"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3373
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3473
msgid "%s error"
msgid_plural "%s errors"
msgstr[0] ""
msgstr[1] ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3143
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3235
msgid "%s experience"
msgstr ""
@@ -216,11 +216,11 @@ msgstr ""
msgid "%s has no carrier: cable unplugged or switch port down"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1377
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1401
msgid "%s hidden"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3403
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3517
msgid "%s in · %s out"
msgstr ""
@@ -236,7 +236,7 @@ msgstr ""
msgid "%s is in no zone and accepts every connection"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1370
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1394
msgid "%s is narrower"
msgstr ""
@@ -244,17 +244,17 @@ msgstr ""
msgid "%s is not up"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2870
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2959
msgid ""
"%s is shared by %d devices (a switch or another access point behind it); its "
"%s link is not theirs"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2869
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2958
msgid "%s is shared by %d devices behind the switch"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1373
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1397
msgid "%s is wider"
msgstr ""
@@ -270,23 +270,23 @@ msgstr ""
msgid "%s may open the router's admin"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1491
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1515
msgid "%s moved"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1367
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1391
msgid "%s moved down"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1358
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1382
msgid "%s moved left"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1361
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1385
msgid "%s moved right"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1364
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1388
msgid "%s moved up"
msgstr ""
@@ -299,9 +299,9 @@ msgid "%s negotiated only %d Mbit/s; a cable pair or port may be faulty"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:84
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2175
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2204
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3429
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2260
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2289
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3543
msgid "%s of %s"
msgstr ""
@@ -322,21 +322,21 @@ msgstr ""
msgid "%s of frames to the device fail; interference likely"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3427
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3541
msgid "%s over %d core"
msgid_plural "%s over %d cores"
msgstr[0] ""
msgstr[1] ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2266
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2353
msgid "%s radio"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3181
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3273
msgid "%s sent · %s retried · %s failed"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1416
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1440
msgid "%s shown"
msgstr ""
@@ -352,11 +352,11 @@ msgstr ""
msgid "%s used"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2212
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2297
msgid "%s used of %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2867
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2956
msgid "%s · %d devices"
msgstr ""
@@ -364,7 +364,7 @@ msgstr ""
msgid "%s · %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3173
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3265
msgid "%s · channel %d · %d MHz"
msgstr ""
@@ -380,27 +380,27 @@ msgstr ""
msgid "%s: no carrier"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3355
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3447
msgid "(configured %d dBm, limited by regulatory rules)"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1930
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3003
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2014
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3092
msgid "(hidden)"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1523
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1931
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2476
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1547
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2015
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2566
msgid "1 client"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2813
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2903
msgid "1 connected"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1962
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2812
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2046
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2902
msgid "1 device"
msgstr ""
@@ -408,7 +408,7 @@ msgstr ""
msgid "1 older device (Wi-Fi 4 or earlier) slows airtime"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2468
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2558
msgid "1 radio"
msgstr ""
@@ -436,20 +436,20 @@ msgstr ""
msgid "60 GHz"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2676
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2766
msgid "Active"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3185
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3217
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3277
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3309
msgid "Address type"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3394
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3506
msgid "Addresses"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2516
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2606
msgid "Airtime"
msgstr ""
@@ -458,8 +458,8 @@ msgctxt "vantage"
msgid "Alias"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2667
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2673
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2757
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2763
msgid "All"
msgstr ""
@@ -488,7 +488,7 @@ msgstr ""
msgid "Busiest radio: %s of Wi-Fi traffic"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2139
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2224
msgid "Busy share of each CPU core"
msgstr ""
@@ -504,88 +504,88 @@ msgstr[1] ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:71
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:72
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2132
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3427
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2217
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3541
msgctxt "vantage"
msgid "CPU"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:97
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:250
msgid "Cache (reclaimable)"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3290
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3382
msgid "Cancel"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3168
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3260
msgctxt "vantage"
msgid "Capabilities"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3389
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3498
msgid "Carrier"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3354
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3446
msgid "Centre frequency"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2507
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2597
msgid "Ch %d"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1911
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2475
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1995
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2565
msgid "Ch %d · %d MHz"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3347
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3439
msgid "Channel"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1911
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1995
msgid "Channel —"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2540
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2630
msgctxt "vantage"
msgid "Clear filter"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1125
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2513
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2558
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2559
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1149
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2603
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2648
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2649
msgid "Clients"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3361
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3453
msgid "Clients on this radio"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3020
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3109
msgid "Close"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2926
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3015
msgid "Connected"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2896
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2985
msgid "Connected after you opened this page"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3174
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3266
msgid "Connected for"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3171
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3202
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3263
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3294
msgid "Connection"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2166
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2251
msgid "Core %d: %s"
msgstr ""
@@ -593,15 +593,15 @@ msgstr ""
msgid "Could not read the firewall configuration"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3273
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3365
msgid "Could not save the name (no permission or the device refused it)."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3400
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3514
msgid "Counters since boot"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3359
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3451
msgid "Country"
msgstr ""
@@ -610,13 +610,13 @@ msgid ""
"Custom rule files are configured (%s); rules in them are not listed here."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1512
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1536
msgid "Customize"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1322
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1323
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1511
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1346
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1347
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1535
msgid "Customize the dashboard"
msgstr ""
@@ -624,16 +624,16 @@ msgstr ""
msgid "DHCP"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3230
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3322
msgid "DHCP hostname"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:42
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3398
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3512
msgid "DNS"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1866
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1927
msgid "DNS %s"
msgstr ""
@@ -642,95 +642,95 @@ msgstr ""
msgid "Dashboard"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2748
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2750
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2838
#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2840
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3418
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2930
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3532
msgid "Device"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3257
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3349
msgid "Device name"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3286
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3378
msgid "Device type"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2826
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2916
msgid ""
"Devices on the Ethernet ports appear here once they send traffic; the bridge "
"forgets quiet ones after about five minutes."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1912
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2477
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2502
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3352
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1996
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2567
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2592
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3444
msgid "Disabled"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3137
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3229
msgid "Disconnected %s; shown from the last sample."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1336
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1360
msgctxt "vantage"
msgid "Done"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:45
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1912
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2477
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2502
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3352
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1996
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2567
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2592
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3444
msgctxt "vantage"
msgid "Down"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2245
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2335
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2410
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2330
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2425
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2500
msgid "Download"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:368
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:377
msgid "Download (to clients)"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3179
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3271
msgctxt "vantage"
msgid "Downloaded"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1397
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1421
msgid ""
"Drag a tile by its handle or use its buttons. Saved in this browser for "
"medium screens."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1398
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1422
msgid ""
"Drag a tile by its handle or use its buttons. Saved in this browser for "
"narrow screens."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1396
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1420
msgid ""
"Drag a tile by its handle or use its buttons. Saved in this browser for wide "
"screens."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1349
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1373
msgid "Drag to move"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3403
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3517
msgctxt "vantage"
msgid "Dropped"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2982
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3071
msgid "Edit"
msgstr ""
@@ -738,7 +738,7 @@ msgstr ""
msgid "Enhanced Open (OWE)"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1575
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1599
msgid "Error"
msgstr ""
@@ -752,8 +752,8 @@ msgctxt "vantage"
msgid "Excellent"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2750
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2920
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2840
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3009
msgid "Experience"
msgstr ""
@@ -771,20 +771,20 @@ msgstr ""
msgid "Fair signal %s; lower rates at range"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2537
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2738
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2627
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2828
msgid "Filter by name, address, SSID…"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2738
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2828
msgid "Filter by name, address, port…"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2538
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2628
msgid "Filter clients"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3421
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3535
msgctxt "vantage"
msgid "Firmware"
msgstr ""
@@ -797,24 +797,24 @@ msgstr ""
msgid "Forwarding is accepted by default"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3181
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3273
msgid "Frames to device"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:98
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:251
msgctxt "vantage"
msgid "Free"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3166
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3258
msgid "From device"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2909
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2998
msgid "From device: %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3384
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3493
msgid "From network"
msgstr ""
@@ -824,9 +824,9 @@ msgid ""
"files are not shown."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1864
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2861
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3397
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1925
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2950
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3509
msgid "Gateway"
msgstr ""
@@ -839,7 +839,7 @@ msgstr ""
msgid "General Settings"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3167
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3259
msgctxt "vantage"
msgid "Generation"
msgstr ""
@@ -849,13 +849,13 @@ msgctxt "vantage"
msgid "GiB"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3185
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3217
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3277
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3309
msgid "Globally unique"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3185
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3217
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3277
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3309
msgid "Globally unique · %s"
msgstr ""
@@ -873,7 +873,7 @@ msgstr ""
msgid "Good signal %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1293
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1317
msgid "Grid packets"
msgstr ""
@@ -889,36 +889,36 @@ msgstr ""
msgid "Half duplex"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1021
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1045
msgctxt "vantage"
msgid "Health checks"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1413
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3003
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1437
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3092
msgctxt "vantage"
msgid "Hidden"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1376
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1400
msgid "Hide %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3186
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3218
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3278
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3310
msgid "IP addresses"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3395
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3507
msgid "IPv4"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3396
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3508
msgid "IPv6"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3183
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3215
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3275
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3307
msgid "Identity"
msgstr ""
@@ -926,7 +926,11 @@ msgstr ""
msgid "In no zone: the default policies apply."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:96
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3504
+msgid "In the tunnel"
+msgstr ""
+
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:249
msgctxt "vantage"
msgid "In use"
msgstr ""
@@ -936,20 +940,21 @@ msgctxt "vantage"
msgid "Input"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1890
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1974
msgid "Interface"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3392
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3501
msgid "Interface up for"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3200
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3382
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3292
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3479
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3491
msgid "Interfaces"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1864
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1925
msgid "Internet"
msgstr ""
@@ -975,11 +980,11 @@ msgid ""
"itself."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3422
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3536
msgid "Kernel"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2218
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2303
msgid "Kernel %s"
msgstr ""
@@ -988,58 +993,58 @@ msgctxt "vantage"
msgid "KiB"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2552
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2642
msgid "Kind of client"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3175
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3267
msgctxt "vantage"
msgid "Last activity"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2749
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2885
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3213
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2839
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2974
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3305
msgid "Last heard"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1334
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1358
msgid "Layout reset"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2895
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2984
msgid "Left %s"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:174
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2897
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2986
msgctxt "vantage"
msgid "Legacy"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2748
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2865
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3164
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3204
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3388
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2838
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2954
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3256
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3296
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3497
msgctxt "vantage"
msgid "Link"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2750
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2908
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2840
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2997
msgid "Link rate"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1543
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2748
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2750
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2876
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2913
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1567
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2838
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2840
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2965
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3002
msgid "Live"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3426
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3540
msgid "Load"
msgstr ""
@@ -1055,20 +1060,20 @@ msgid_plural "Load %s · %d cores"
msgstr[0] ""
msgstr[1] ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3428
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3542
msgctxt "vantage"
msgid "Load average"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2120
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2205
msgid "Load average over 1, 5 and 15 minutes"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2156
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2241
msgid "Load avg %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3424
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3538
msgid "Local time"
msgstr ""
@@ -1084,8 +1089,8 @@ msgstr ""
msgid "MAC"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3184
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3216
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3276
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3308
msgid "MAC address"
msgstr ""
@@ -1093,11 +1098,11 @@ msgstr ""
msgid "MCS %d"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1369
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1393
msgid "Make %s narrower"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1372
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1396
msgid "Make %s wider"
msgstr ""
@@ -1114,11 +1119,11 @@ msgid "Measuring…"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:83
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2143
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2228
msgid "Memory"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3429
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3543
msgid "Memory in use"
msgstr ""
@@ -1127,63 +1132,63 @@ msgctxt "vantage"
msgid "MiB"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1279
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1303
msgid "Mirrored"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1280
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1304
msgid "Mirrored, scale per direction"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3353
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3445
msgid "Mode"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3419
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3533
msgid "Model"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1366
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1390
msgid "Move %s down"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1357
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1381
msgid "Move %s left"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1360
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1384
msgid "Move %s right"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1363
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1387
msgid "Move %s up"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1349
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1373
msgid "Move %s: drag, or use the arrow keys"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3285
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3377
msgid "Name"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:134
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3325
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3417
msgid "Name contains invisible or control characters"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3187
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3219
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3279
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3311
msgid "Name from"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2845
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2935
msgid "Name from: %s"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:132
#: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:137
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3326
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3418
msgid "Name is longer than %d characters"
msgstr ""
@@ -1191,27 +1196,27 @@ msgstr ""
msgid "Name must be text"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3128
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3197
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3220
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3289
msgid "Name this device"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2748
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2750
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2875
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2905
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3172
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3212
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2838
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2840
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2964
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2994
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3264
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3304
msgid "Network"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1125
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1689
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1690
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1149
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1713
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1714
msgid "Network path"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1298
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1322
msgid "Network path background"
msgstr ""
@@ -1219,13 +1224,13 @@ msgstr ""
msgid "Networks: %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2678
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2896
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2768
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2985
msgctxt "vantage"
msgid "New"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1813
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1872
msgid "No SSIDs"
msgstr ""
@@ -1233,24 +1238,24 @@ msgstr ""
msgid "No clients"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2828
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3366
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2918
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3458
msgid "No clients connected"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2957
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3046
msgid "No clients connected."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2819
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2909
msgid "No clients in this view"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2819
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2909
msgid "No clients match “%s”"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1865
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1926
msgctxt "vantage"
msgid "No default route"
msgstr ""
@@ -1259,7 +1264,7 @@ msgstr ""
msgid "No interface with a route"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3374
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3483
msgid "No interface with a route is up."
msgstr ""
@@ -1268,7 +1273,7 @@ msgid "No internet-facing zone found"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:47
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3389
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3498
msgid "No link"
msgstr ""
@@ -1276,7 +1281,7 @@ msgstr ""
msgid "No network interface with a route is up"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1794
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1853
msgid "No other interfaces are up"
msgstr ""
@@ -1286,7 +1291,7 @@ msgid "No problems detected"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:105
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1817
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1876
msgid "No radios reported"
msgstr ""
@@ -1303,16 +1308,16 @@ msgstr ""
msgid "No stations are associated right now"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2825
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2915
msgid "No wired devices heard"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2991
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3080
msgctxt "vantage"
msgid "No wireless networks configured."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2482
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2572
msgid "No wireless radios are reported by this device."
msgstr ""
@@ -1327,39 +1332,39 @@ msgstr ""
msgid "No zones are configured."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2957
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3046
msgid "Nobody is moving data right now."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2515
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2605
msgid "Noise"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3169
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3261
msgid "Noise / SNR"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3357
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3358
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3449
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3450
msgid "Noise floor"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:105
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1293
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1317
msgid "None"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:150
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3324
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3416
msgid "Not a station MAC address"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3119
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3211
msgid "Not connected"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2877
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3209
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2966
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3301
msgid "Not counted per device on a shared port"
msgstr ""
@@ -1367,7 +1372,7 @@ msgstr ""
msgid "Not in effect"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2193
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2278
msgid "Not reported"
msgstr ""
@@ -1375,7 +1380,7 @@ msgstr ""
msgid "Not reported by the driver"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3233
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3325
msgid "Nothing better known"
msgstr ""
@@ -1396,7 +1401,7 @@ msgstr ""
msgid "Older %s device"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2897
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2986
msgid "Older Wi-Fi generation than the radio; uses more airtime"
msgstr ""
@@ -1404,7 +1409,7 @@ msgstr ""
msgid "On this router"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2750
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2840
msgctxt "vantage"
msgid "Online"
msgstr ""
@@ -1421,7 +1426,7 @@ msgctxt "vantage"
msgid "Open"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2794
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2884
msgid "Open details of %s"
msgstr ""
@@ -1437,7 +1442,7 @@ msgstr ""
msgid "Open network"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:658
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:836
msgid "OpenWrt device"
msgstr ""
@@ -1447,11 +1452,11 @@ msgid ""
"new rules: what is open is unknown."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1277
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1301
msgid "Overlaid"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1278
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1302
msgid "Overlaid, log scale"
msgstr ""
@@ -1459,11 +1464,11 @@ msgstr ""
msgid "Overview"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3168
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3260
msgid "PMF"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1541
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1565
msgid "Paused while hidden"
msgstr ""
@@ -1477,7 +1482,7 @@ msgid ""
"on to your network: what every router lets in."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3420
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3534
msgctxt "vantage"
msgid "Platform"
msgstr ""
@@ -1487,19 +1492,19 @@ msgctxt "vantage"
msgid "Poor"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3203
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3295
msgid "Port"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:202
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:355
msgid "Port %d"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2870
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2959
msgid "Port %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1955
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2039
msgid "Port total: %s"
msgstr ""
@@ -1507,11 +1512,11 @@ msgstr ""
msgid "Private"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3185
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3277
msgid "Private Wi-Fi address (randomised by the device)"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3217
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3309
msgid "Private address (randomised by the device)"
msgstr ""
@@ -1519,26 +1524,26 @@ msgstr ""
msgid "Private device"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3417
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3531
msgid "Processes"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3391
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3500
msgid "Protocol"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2547
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2549
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2637
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2639
msgid "Quick filters"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3173
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3351
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3265
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3443
msgctxt "vantage"
msgid "Radio"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2503
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2593
msgid "Radio details"
msgstr ""
@@ -1550,65 +1555,69 @@ msgstr ""
msgid "Radio is enabled but not up"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2527
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3345
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2617
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3437
msgid "Radio settings"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1125
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2455
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2457
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1149
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2545
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2547
msgid "Radios"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1866
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1927
msgid "Reachability not probed"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2862
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2951
msgid "Reached through the uplink port %s, not connected to this device"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3382
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3491
msgid "Realtime graphs"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3401
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3515
msgctxt "vantage"
msgid "Received"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1542
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1566
msgctxt "vantage"
msgid "Reconnecting…"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2694
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2784
msgid "Remove filter: %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3291
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3383
msgid "Remove name"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3128
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3197
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3220
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3289
msgctxt "vantage"
msgid "Rename"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1335
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1359
msgid "Reset"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3228
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3320
msgid "Reverse DNS of its address"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:670
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:848
msgid "Root (overlay)"
msgstr ""
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3511
+msgid "Route metric"
+msgstr ""
+
#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/firewall.js:281
msgid "Router admin open: %s"
msgstr ""
@@ -1617,20 +1626,20 @@ msgstr ""
msgid "SSH (port 22)"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3283
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3375
msgid "Save"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3176
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3268
msgid "Seen since"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3402
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3516
msgctxt "vantage"
msgid "Sent"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1281
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1305
msgid "Separate lanes"
msgstr ""
@@ -1638,57 +1647,57 @@ msgstr ""
msgid "Settings to check"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3204
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3296
msgid "Shared by %d devices"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2866
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2955
msgid "Shared port"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1415
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1439
msgid "Show %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2820
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2910
msgid "Show all clients"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2129
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2214
msgid "Show or hide system details"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1690
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1714
msgid "Show or hide the network path"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2458
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2548
msgid "Show or hide the radio details"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2248
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2333
msgid "Show or hide the throughput chart"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2982
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3071
msgid "Show or hide the wireless networks"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1929
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3000
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2013
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3089
msgid "Show the clients of %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1955
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2039
msgid "Show the devices on %s"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:119
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:120
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:128
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2750
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2902
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3152
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2840
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2991
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3244
msgid "Signal"
msgstr ""
@@ -1696,7 +1705,7 @@ msgstr ""
msgid "Signal not reported"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3390
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3499
msgctxt "vantage"
msgid "Speed"
msgstr ""
@@ -1707,24 +1716,24 @@ msgid_plural "Standard housekeeping: %d rules"
msgstr[0] ""
msgstr[1] ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1293
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1317
msgid "Starfield"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2829
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2919
msgid "Stations appear here as soon as they associate with one of the SSIDs."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3352
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3444
msgid "Status"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:93
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2146
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2231
msgid "Storage"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3292
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3384
msgid "Stored on this device in /etc/config/vantage"
msgstr ""
@@ -1740,16 +1749,16 @@ msgstr ""
msgid "Strong signal, %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2203
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2288
msgctxt "vantage"
msgid "Swap"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3207
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3299
msgid "Switch ports"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:381
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:390
msgid "Switch ports of VLAN %d on %s: %s"
msgstr ""
@@ -1757,13 +1766,13 @@ msgstr ""
msgid "Switched off"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1126
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2128
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2129
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1150
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2213
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2214
msgid "System"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3417
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3531
msgid "System settings"
msgstr ""
@@ -1776,19 +1785,19 @@ msgid "Telnet (port 23)"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:76
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2160
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2245
msgid "Temperature %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:670
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:848
msgid "Temporary (RAM)"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2749
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2839
msgid "The bridge forgets a device after about five minutes without traffic"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2823
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2913
msgid ""
"The bridges have learned so many addresses that listing them here would "
"strain this device."
@@ -1801,7 +1810,7 @@ msgid ""
"reject in General Settings."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3329
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3421
msgid "The device could not write /etc/config/vantage."
msgstr ""
@@ -1825,7 +1834,7 @@ msgid ""
"an uplink in no zone would be open. Set Input to reject in General Settings."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3231
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3323
msgid "The name the device announces (WPS)"
msgstr ""
@@ -1837,7 +1846,7 @@ msgstr ""
msgid "The only measured client"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2861
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2950
msgid "The router this device sends its traffic to"
msgstr ""
@@ -1853,7 +1862,7 @@ msgstr ""
msgid "The uplinks could not be checked"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1874
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1942
msgid "This access point"
msgstr ""
@@ -1861,11 +1870,11 @@ msgstr ""
msgid "This address family is in no zone: the default policies apply."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1874
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1942
msgid "This device"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3328
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3420
msgid "This device already stores %d names; remove some first."
msgstr ""
@@ -1873,13 +1882,17 @@ msgstr ""
msgid "This device reports no radios"
msgstr ""
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3480
+msgid "This line is down or has no default route now."
+msgstr ""
+
#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/firewall.js:183
msgid ""
"This page cannot tell what is open. Reload it; if that does not help, check "
"the firewall pages."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3336
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3428
msgid "This radio is not reported any more."
msgstr ""
@@ -1887,23 +1900,23 @@ msgstr ""
msgid "This setup is beyond what this overview checks"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3119
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3211
msgid "This station is not associated right now."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1125
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2240
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2242
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3158
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1149
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2325
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2327
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3250
msgctxt "vantage"
msgid "Throughput"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1286
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1310
msgid "Throughput chart"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2233
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2318
msgid "Throughput per link; arrow keys read the values over time"
msgstr ""
@@ -1912,38 +1925,38 @@ msgctxt "vantage"
msgid "TiB"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3165
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3257
msgid "To device"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2882
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2917
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2970
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2971
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3006
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3059
msgid "To device %s, from device %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2909
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2998
msgid "To device: %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3385
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3494
msgid "To network"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2822
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2912
msgid "Too many devices to list"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1126
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2934
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2935
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1150
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3023
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3024
msgctxt "vantage"
msgid "Top talkers"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3178
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3208
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3348
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3270
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3300
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3440
msgid "Traffic"
msgstr ""
@@ -1959,8 +1972,16 @@ msgid ""
"networks. Set Forward to reject in General Settings."
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2514
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3355
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1938
+msgid "Traffic to the internet goes through %s, a tunnel over this line"
+msgstr ""
+
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3503
+msgid "Tunnel"
+msgstr ""
+
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2604
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3447
msgid "Tx power"
msgstr ""
@@ -1971,16 +1992,16 @@ msgid ""
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:272
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3118
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3210
msgctxt "vantage"
msgid "Unknown device"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3327
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3419
msgid "Unknown device type"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3336
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3428
msgid "Unknown radio"
msgstr ""
@@ -1995,14 +2016,14 @@ msgid "Unnamed rule"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:57
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2502
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3352
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3389
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2592
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3444
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3498
msgctxt "vantage"
msgid "Up"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2153
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2238
msgid "Up %s"
msgstr ""
@@ -2011,45 +2032,47 @@ msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:49
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:51
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:57
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2265
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3374
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2351
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3483
msgctxt "vantage"
msgid "Uplink"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2265
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2351
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2352
msgid "Uplink %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3378
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3476
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3487
msgid "Uplink · %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2246
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2337
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2411
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2331
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2427
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2501
msgid "Upload"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:369
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:378
msgid "Upload (from clients)"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3180
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3272
msgctxt "vantage"
msgid "Uploaded"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2862
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2951
msgid "Upstream"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3423
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3537
msgid "Uptime"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2863
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3212
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2952
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3304
msgid "VLAN %d"
msgstr ""
@@ -2071,8 +2094,9 @@ msgid ""
"stations (wireless configuration without keys, through luci.vantage "
"wireless), its temperature sensors (luci.vantage thermal), the wired hosts "
"its bridges have learned (luci.vantage wired: MAC, port and when last heard, "
-"and which switch ports a port's VLAN has) and the link state of those switch "
-"ports (luci getSwconfigPortState)"
+"and which switch ports a port's VLAN has), the link state of those switch "
+"ports (luci getSwconfigPortState) and the default route the kernel takes to "
+"the internet (luci.vantage routes: family, device and metric, no gateways)"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:43
@@ -2183,11 +2207,11 @@ msgstr ""
msgid "WPS"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3188
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3280
msgid "WPS device name"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1575
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1599
msgid "Warning"
msgstr ""
@@ -2201,7 +2225,7 @@ msgid "Weak"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:157
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2677
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2767
msgid "Weak signal"
msgstr ""
@@ -2225,27 +2249,27 @@ msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:106
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:108
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:110
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2731
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2821
msgid "Wi-Fi"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1824
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2731
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1883
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2821
msgid "Wired"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1126
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2981
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2982
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1150
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3070
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3071
msgctxt "vantage"
msgid "Wireless networks"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3138
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3230
msgid "Wireless settings"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3227
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3319
msgid "Your name for this device"
msgstr ""
@@ -2283,15 +2307,15 @@ msgstr ""
msgid "any zone (default policy)"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2508
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2598
msgid "auto"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3176
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3268
msgid "before this page opened"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3205
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3297
msgid "behind %s, VLAN %d"
msgstr ""
@@ -2300,16 +2324,16 @@ msgctxt "vantage"
msgid "bit/s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2369
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2459
msgid "collecting · %s of data"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2369
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2459
msgid "collecting · first samples"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:248
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2349
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:251
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2439
msgid "collecting…"
msgstr ""
@@ -2321,9 +2345,18 @@ msgstr ""
msgid "dBm"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:376
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2866
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3204
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1802
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1940
+msgid "default route"
+msgstr ""
+
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1940
+msgid "default route via %s"
+msgstr ""
+
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:385
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2955
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3296
msgid "down"
msgstr ""
@@ -2332,7 +2365,7 @@ msgctxt "vantage"
msgid "drop"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3257
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3349
msgctxt "vantage"
msgid "e.g. Living room TV"
msgstr ""
@@ -2358,7 +2391,7 @@ msgstr ""
msgid "from anywhere except %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:213
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:366
msgid "full duplex"
msgstr ""
@@ -2366,12 +2399,13 @@ msgstr ""
msgid "gateway %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:213
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:366
msgid "half duplex"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/fmt.js:62
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3008
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1960
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3097
msgid "idle"
msgstr ""
@@ -2413,18 +2447,18 @@ msgctxt "vantage"
msgid "kbit/s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2138
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2368
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2223
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2458
msgid "last 5 min"
msgstr ""
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:175
#: luci-app-vantage/htdocs/luci-static/resources/vantage/wifi.js:104
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2911
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3000
msgid "legacy"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:376
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:385
msgid "link up"
msgstr ""
@@ -2432,45 +2466,45 @@ msgstr ""
msgid "mDNS"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3229
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3321
msgid "mDNS announcement"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3160
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3211
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3252
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3303
msgid "measuring"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2344
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2434
msgid "measuring…"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2325
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2415
msgctxt "vantage"
msgid "no data"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1872
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1933
msgid "no uplink"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3186
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3278
msgid "not known to this AP"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3218
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3310
msgid "not known to this device"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3358
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3450
msgid "not reported (driver placeholder %s)"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3169
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3261
msgid "not reported by the driver"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2365
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2455
msgctxt "vantage"
msgid "now"
msgstr ""
@@ -2479,16 +2513,16 @@ msgstr ""
msgid "now %s down, %s up"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3167
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3259
msgid "older than the radio (%s)"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2342
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2432
msgctxt "vantage"
msgid "peak"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2139
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2224
msgid "per core"
msgstr ""
@@ -2497,11 +2531,11 @@ msgctxt "vantage"
msgid "port forward"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3154
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3246
msgid "range %s … %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3384
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3493
msgid "received on %s"
msgstr ""
@@ -2514,7 +2548,7 @@ msgstr ""
msgid "router port %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3385
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3494
msgid "sent on %s"
msgstr ""
@@ -2522,12 +2556,12 @@ msgstr ""
msgid "short GI"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2885
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3213
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2974
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3305
msgid "static entry"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3206
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3298
msgid "switch port %s"
msgstr ""
@@ -2539,11 +2573,11 @@ msgstr ""
msgid "the covered subnets of zone %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3210
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3302
msgid "the port in total: %s"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3205
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3297
msgid "the port: %s"
msgstr ""
@@ -2559,7 +2593,7 @@ msgstr ""
msgid "traffic rule"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1877
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1945
msgid "up %s"
msgstr ""
@@ -2576,6 +2610,6 @@ msgstr ""
msgid "zones %s and %s if they share a device"
msgstr ""
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2362
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2452
msgid "−%d min"
msgstr ""
diff --git a/luci-app-vantage/po/zh_Hans/vantage.po b/luci-app-vantage/po/zh_Hans/vantage.po
index bd907e175..8b04f71ba 100644
--- a/luci-app-vantage/po/zh_Hans/vantage.po
+++ b/luci-app-vantage/po/zh_Hans/vantage.po
@@ -12,7 +12,7 @@ msgstr ""
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3354
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3446
msgid "%d MHz (%d–%d MHz)"
msgstr "%d MHz(%d–%d MHz)"
@@ -36,19 +36,19 @@ msgid "%d SSID · %d idle"
msgid_plural "%d SSIDs · %d idle"
msgstr[0] "%d 个 SSID · %d 个空闲"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1523
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1931
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2476
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1547
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2015
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2566
msgid "%d clients"
msgstr "%d 个客户端"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2813
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2903
msgid "%d connected"
msgstr "已连接 %d 个"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1958
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1962
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2812
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2042
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2046
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2902
msgid "%d devices"
msgstr "%d 台设备"
@@ -62,22 +62,22 @@ msgid "%d measured client is above %s"
msgid_plural "%d measured clients are above %s"
msgstr[0] "%d 个已测客户端高于 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:449
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:458
msgctxt "vantage"
msgid "%d min"
msgstr "%d 分钟"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/fmt.js:118
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:443
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:452
msgctxt "vantage"
msgid "%d min ago"
msgstr "%d 分钟前"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2811
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2901
msgid "%d of %d"
msgstr "%d/%d"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1410
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1434
msgid "%d of %d columns"
msgstr "%d/%d 列"
@@ -104,17 +104,17 @@ msgid "%d radio up"
msgid_plural "%d radios up"
msgstr[0] "%d 个射频已上线"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2468
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2558
msgid "%d radios"
msgstr "%d 个射频"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:449
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:458
msgctxt "vantage"
msgid "%d s"
msgstr "%d 秒"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/fmt.js:117
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:443
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:452
msgctxt "vantage"
msgid "%d s ago"
msgstr "%d 秒前"
@@ -128,7 +128,7 @@ msgstr "%d 项需要关注"
msgid "%d weak"
msgstr "%d 个信号弱"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2487
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2577
msgid "%d–%d MHz of the %d–%d MHz band"
msgstr "%d–%d MHz 属于 %d–%d MHz 频段"
@@ -146,27 +146,27 @@ msgstr "%s(%s)已启用但未上线"
msgid "%s (IPv%d)"
msgstr "%s(IPv%d)"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3176
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3268
msgid "%s (new this session)"
msgstr "%s(本次新增)"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:24
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:212
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:365
msgid "%s Gbit/s"
msgstr "%s Gbit/s"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/fmt.js:166
#: luci-app-vantage/htdocs/luci-static/resources/vantage/wifi.js:103
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2494
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2508
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2911
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3347
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2584
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2598
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3000
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3439
msgid "%s MHz"
msgstr "%s MHz"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:24
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:51
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:212
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:365
msgid "%s Mbit/s"
msgstr "%s Mbit/s"
@@ -179,13 +179,13 @@ msgid "%s at %s; below %s roaming and throughput suffer"
msgstr "%s(%s);低于 %s 时漫游和吞吐量会受影响"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:83
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2174
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2259
msgctxt "vantage"
msgid "%s available"
msgstr "可用 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2514
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3355
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2604
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3447
msgid "%s dBm"
msgstr "%s dBm"
@@ -197,12 +197,12 @@ msgstr "%s 设备"
msgid "%s device on a newer radio; uses more airtime per byte"
msgstr "%s 设备连接在较新的射频上,每字节占用更多空口时间"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3373
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3473
msgid "%s error"
msgid_plural "%s errors"
msgstr[0] "%s 个错误"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3143
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3235
msgid "%s experience"
msgstr "%s 体验"
@@ -218,11 +218,11 @@ msgstr "overlay 空闲 %s(已用 %s)"
msgid "%s has no carrier: cable unplugged or switch port down"
msgstr "%s 无载波:网线未插或交换机端口关闭"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1377
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1401
msgid "%s hidden"
msgstr "%s 已隐藏"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3403
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3517
msgid "%s in · %s out"
msgstr "%s 入 · %s 出"
@@ -238,7 +238,7 @@ msgstr "%s 被转发到 %s"
msgid "%s is in no zone and accepts every connection"
msgstr "%s 不属于任何区域,接受所有连接"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1370
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1394
msgid "%s is narrower"
msgstr "%s 已变窄"
@@ -246,18 +246,18 @@ msgstr "%s 已变窄"
msgid "%s is not up"
msgstr "%s 未上线"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2870
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2959
msgid ""
"%s is shared by %d devices (a switch or another access point behind it); its "
"%s link is not theirs"
msgstr ""
"%s 由 %d 台设备共用(其后接有交换机或另一个接入点);%s 的链路不属于这些设备"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2869
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2958
msgid "%s is shared by %d devices behind the switch"
msgstr "%s 由交换机后的 %d 台设备共用"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1373
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1397
msgid "%s is wider"
msgstr "%s 已加宽"
@@ -273,23 +273,23 @@ msgstr "%s 链路"
msgid "%s may open the router's admin"
msgstr "%s 可能暴露了路由器管理界面"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1491
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1515
msgid "%s moved"
msgstr "%s 已移动"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1367
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1391
msgid "%s moved down"
msgstr "%s 已下移"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1358
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1382
msgid "%s moved left"
msgstr "%s 已左移"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1361
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1385
msgid "%s moved right"
msgstr "%s 已右移"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1364
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1388
msgid "%s moved up"
msgstr "%s 已上移"
@@ -302,9 +302,9 @@ msgid "%s negotiated only %d Mbit/s; a cable pair or port may be faulty"
msgstr "%s 仅协商到 %d Mbit/s;网线线对或端口可能有故障"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:84
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2175
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2204
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3429
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2260
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2289
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3543
msgid "%s of %s"
msgstr "%s / %s"
@@ -325,20 +325,20 @@ msgstr "发往设备的帧失败率:%s"
msgid "%s of frames to the device fail; interference likely"
msgstr "发往设备的帧失败率:%s,可能存在干扰"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3427
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3541
msgid "%s over %d core"
msgid_plural "%s over %d cores"
msgstr[0] "%s / %d 核"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2266
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2353
msgid "%s radio"
msgstr "%s 射频"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3181
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3273
msgid "%s sent · %s retried · %s failed"
msgstr "发送 %s · 重传 %s · 失败 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1416
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1440
msgid "%s shown"
msgstr "%s 已显示"
@@ -354,11 +354,11 @@ msgstr "%s 已连接,速率 %s"
msgid "%s used"
msgstr "已用 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2212
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2297
msgid "%s used of %s"
msgstr "已用 %s / 共 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2867
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2956
msgid "%s · %d devices"
msgstr "%s · %d 台设备"
@@ -366,7 +366,7 @@ msgstr "%s · %d 台设备"
msgid "%s · %s"
msgstr "%s · %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3173
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3265
msgid "%s · channel %d · %d MHz"
msgstr "%s · 信道 %d · %d MHz"
@@ -382,27 +382,27 @@ msgstr "%s · 链路较慢"
msgid "%s: no carrier"
msgstr "%s:无载波"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3355
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3447
msgid "(configured %d dBm, limited by regulatory rules)"
msgstr "(配置 %d dBm,受管制规则限制)"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1930
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3003
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2014
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3092
msgid "(hidden)"
msgstr "(隐藏)"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1523
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1931
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2476
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1547
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2015
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2566
msgid "1 client"
msgstr "1 个客户端"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2813
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2903
msgid "1 connected"
msgstr "已连接 1 个"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1962
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2812
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2046
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2902
msgid "1 device"
msgstr "1 台设备"
@@ -410,7 +410,7 @@ msgstr "1 台设备"
msgid "1 older device (Wi-Fi 4 or earlier) slows airtime"
msgstr "1 台旧设备(Wi-Fi 4 或更早)占用更多空口时间"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2468
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2558
msgid "1 radio"
msgstr "1 个射频"
@@ -438,20 +438,20 @@ msgstr "6 GHz"
msgid "60 GHz"
msgstr "60 GHz"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2676
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2766
msgid "Active"
msgstr "活跃"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3185
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3217
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3277
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3309
msgid "Address type"
msgstr "地址类型"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3394
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3506
msgid "Addresses"
msgstr "地址"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2516
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2606
msgid "Airtime"
msgstr "空口时间"
@@ -460,8 +460,8 @@ msgctxt "vantage"
msgid "Alias"
msgstr "别名"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2667
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2673
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2757
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2763
msgid "All"
msgstr "全部"
@@ -490,7 +490,7 @@ msgstr "B"
msgid "Busiest radio: %s of Wi-Fi traffic"
msgstr "最繁忙射频:占 Wi-Fi 流量的 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2139
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2224
msgid "Busy share of each CPU core"
msgstr "每个 CPU 核心的繁忙占比"
@@ -505,88 +505,88 @@ msgstr[0] "繁忙;负载 %s(%d 核);查看最繁忙进程"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:71
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:72
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2132
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3427
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2217
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3541
msgctxt "vantage"
msgid "CPU"
msgstr "CPU"
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:97
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:250
msgid "Cache (reclaimable)"
msgstr "缓存(可回收)"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3290
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3382
msgid "Cancel"
msgstr "取消"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3168
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3260
msgctxt "vantage"
msgid "Capabilities"
msgstr "能力"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3389
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3498
msgid "Carrier"
msgstr "链路状态"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3354
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3446
msgid "Centre frequency"
msgstr "中心频率"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2507
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2597
msgid "Ch %d"
msgstr "信道 %d"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1911
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2475
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1995
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2565
msgid "Ch %d · %d MHz"
msgstr "信道 %d · %d MHz"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3347
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3439
msgid "Channel"
msgstr "信道"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1911
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1995
msgid "Channel —"
msgstr "信道 —"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2540
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2630
msgctxt "vantage"
msgid "Clear filter"
msgstr "清除筛选"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1125
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2513
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2558
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2559
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1149
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2603
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2648
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2649
msgid "Clients"
msgstr "客户端"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3361
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3453
msgid "Clients on this radio"
msgstr "此射频上的客户端"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3020
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3109
msgid "Close"
msgstr "关闭"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2926
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3015
msgid "Connected"
msgstr "已连接"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2896
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2985
msgid "Connected after you opened this page"
msgstr "打开本页面后连接"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3174
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3266
msgid "Connected for"
msgstr "已连接时长"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3171
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3202
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3263
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3294
msgid "Connection"
msgstr "连接"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2166
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2251
msgid "Core %d: %s"
msgstr "核心 %d:%s"
@@ -594,15 +594,15 @@ msgstr "核心 %d:%s"
msgid "Could not read the firewall configuration"
msgstr "无法读取防火墙配置"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3273
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3365
msgid "Could not save the name (no permission or the device refused it)."
msgstr "无法保存名称(无权限或设备拒绝)。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3400
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3514
msgid "Counters since boot"
msgstr "自启动以来的计数器"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3359
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3451
msgid "Country"
msgstr "国家"
@@ -611,13 +611,13 @@ msgid ""
"Custom rule files are configured (%s); rules in them are not listed here."
msgstr "已配置自定义规则文件(%s);其中的规则不会在此列出。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1512
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1536
msgid "Customize"
msgstr "自定义"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1322
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1323
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1511
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1346
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1347
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1535
msgid "Customize the dashboard"
msgstr "自定义仪表盘"
@@ -625,16 +625,16 @@ msgstr "自定义仪表盘"
msgid "DHCP"
msgstr "DHCP"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3230
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3322
msgid "DHCP hostname"
msgstr "DHCP 主机名"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:42
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3398
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3512
msgid "DNS"
msgstr "DNS"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1866
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1927
msgid "DNS %s"
msgstr "DNS %s"
@@ -643,96 +643,96 @@ msgstr "DNS %s"
msgid "Dashboard"
msgstr "仪表盘"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2748
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2750
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2838
#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2840
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3418
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2930
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3532
msgid "Device"
msgstr "设备"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3257
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3349
msgid "Device name"
msgstr "设备名"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3286
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3378
msgid "Device type"
msgstr "设备类型"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2826
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2916
msgid ""
"Devices on the Ethernet ports appear here once they send traffic; the bridge "
"forgets quiet ones after about five minutes."
msgstr ""
"以太网端口上的设备发送流量后会显示在这里;网桥会在约五分钟无流量后忘记它们。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1912
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2477
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2502
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3352
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1996
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2567
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2592
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3444
msgid "Disabled"
msgstr "已禁用"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3137
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3229
msgid "Disconnected %s; shown from the last sample."
msgstr "断开于 %s;显示最后一次采样的数据。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1336
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1360
msgctxt "vantage"
msgid "Done"
msgstr "完成"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:45
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1912
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2477
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2502
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3352
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1996
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2567
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2592
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3444
msgctxt "vantage"
msgid "Down"
msgstr "已下线"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2245
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2335
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2410
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2330
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2425
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2500
msgid "Download"
msgstr "下载"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:368
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:377
msgid "Download (to clients)"
msgstr "下载(到客户端)"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3179
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3271
msgctxt "vantage"
msgid "Downloaded"
msgstr "已下载"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1397
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1421
msgid ""
"Drag a tile by its handle or use its buttons. Saved in this browser for "
"medium screens."
msgstr "拖动卡片手柄或使用其按钮移动。中屏布局保存在此浏览器中。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1398
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1422
msgid ""
"Drag a tile by its handle or use its buttons. Saved in this browser for "
"narrow screens."
msgstr "拖动卡片手柄或使用其按钮移动。窄屏布局保存在此浏览器中。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1396
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1420
msgid ""
"Drag a tile by its handle or use its buttons. Saved in this browser for wide "
"screens."
msgstr "拖动卡片手柄或使用其按钮移动。宽屏布局保存在此浏览器中。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1349
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1373
msgid "Drag to move"
msgstr "拖动以移动"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3403
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3517
msgctxt "vantage"
msgid "Dropped"
msgstr "已丢弃"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2982
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3071
msgid "Edit"
msgstr "编辑"
@@ -740,7 +740,7 @@ msgstr "编辑"
msgid "Enhanced Open (OWE)"
msgstr "增强开放 (OWE)"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1575
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1599
msgid "Error"
msgstr "错误"
@@ -754,8 +754,8 @@ msgctxt "vantage"
msgid "Excellent"
msgstr "极好"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2750
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2920
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2840
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3009
msgid "Experience"
msgstr "体验"
@@ -773,20 +773,20 @@ msgstr "信号一般"
msgid "Fair signal %s; lower rates at range"
msgstr "信号一般 %s;远距离速率较低"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2537
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2738
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2627
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2828
msgid "Filter by name, address, SSID…"
msgstr "按名称、地址、SSID…筛选"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2738
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2828
msgid "Filter by name, address, port…"
msgstr "按名称、地址、端口…筛选"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2538
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2628
msgid "Filter clients"
msgstr "筛选客户端"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3421
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3535
msgctxt "vantage"
msgid "Firmware"
msgstr "固件"
@@ -799,24 +799,24 @@ msgstr "从 %s 转发到 %s"
msgid "Forwarding is accepted by default"
msgstr "默认接受转发"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3181
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3273
msgid "Frames to device"
msgstr "发往设备的帧"
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:98
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:251
msgctxt "vantage"
msgid "Free"
msgstr "空闲"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3166
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3258
msgid "From device"
msgstr "来自设备"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2909
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2998
msgid "From device: %s"
msgstr "来自设备:%s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3384
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3493
msgid "From network"
msgstr "来自网络"
@@ -826,9 +826,9 @@ msgid ""
"files are not shown."
msgstr "内容来自防火墙配置。由 UPnP 或自定义规则文件开放的端口不会显示。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1864
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2861
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3397
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1925
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2950
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3509
msgid "Gateway"
msgstr "网关"
@@ -841,7 +841,7 @@ msgstr "Gbit/s"
msgid "General Settings"
msgstr "基本设置"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3167
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3259
msgctxt "vantage"
msgid "Generation"
msgstr "代际"
@@ -851,13 +851,13 @@ msgctxt "vantage"
msgid "GiB"
msgstr "GiB"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3185
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3217
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3277
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3309
msgid "Globally unique"
msgstr "全局唯一"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3185
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3217
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3277
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3309
msgid "Globally unique · %s"
msgstr "全局唯一 · %s"
@@ -875,7 +875,7 @@ msgstr "信号良好"
msgid "Good signal %s"
msgstr "信号良好 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1293
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1317
msgid "Grid packets"
msgstr "网格数据包"
@@ -891,36 +891,36 @@ msgstr "HTTPS(端口 443)"
msgid "Half duplex"
msgstr "半双工"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1021
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1045
msgctxt "vantage"
msgid "Health checks"
msgstr "健康检查"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1413
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3003
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1437
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3092
msgctxt "vantage"
msgid "Hidden"
msgstr "隐藏"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1376
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1400
msgid "Hide %s"
msgstr "隐藏 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3186
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3218
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3278
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3310
msgid "IP addresses"
msgstr "IP 地址"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3395
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3507
msgid "IPv4"
msgstr "IPv4"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3396
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3508
msgid "IPv6"
msgstr "IPv6"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3183
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3215
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3275
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3307
msgid "Identity"
msgstr "身份"
@@ -928,7 +928,11 @@ msgstr "身份"
msgid "In no zone: the default policies apply."
msgstr "不属于任何区域:适用默认策略。"
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:96
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3504
+msgid "In the tunnel"
+msgstr "隧道内"
+
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:249
msgctxt "vantage"
msgid "In use"
msgstr "已用"
@@ -938,20 +942,21 @@ msgctxt "vantage"
msgid "Input"
msgstr "入站数据"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1890
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1974
msgid "Interface"
msgstr "接口"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3392
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3501
msgid "Interface up for"
msgstr "接口已启用时长"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3200
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3382
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3292
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3479
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3491
msgid "Interfaces"
msgstr "接口"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1864
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1925
msgid "Internet"
msgstr "互联网"
@@ -981,11 +986,11 @@ msgstr ""
"它将来自互联网上任何地址的 %s 转发到 %s。无法读取接口列表,因此本页无法判断该"
"地址是否为路由器本身。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3422
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3536
msgid "Kernel"
msgstr "内核"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2218
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2303
msgid "Kernel %s"
msgstr "内核 %s"
@@ -994,58 +999,58 @@ msgctxt "vantage"
msgid "KiB"
msgstr "KiB"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2552
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2642
msgid "Kind of client"
msgstr "客户端类型"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3175
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3267
msgctxt "vantage"
msgid "Last activity"
msgstr "最后活动"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2749
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2885
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3213
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2839
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2974
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3305
msgid "Last heard"
msgstr "最后活动"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1334
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1358
msgid "Layout reset"
msgstr "布局已重置"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2895
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2984
msgid "Left %s"
msgstr "离开于 %s"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:174
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2897
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2986
msgctxt "vantage"
msgid "Legacy"
msgstr "旧版"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2748
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2865
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3164
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3204
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3388
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2838
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2954
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3256
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3296
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3497
msgctxt "vantage"
msgid "Link"
msgstr "链路"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2750
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2908
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2840
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2997
msgid "Link rate"
msgstr "链路速率"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1543
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2748
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2750
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2876
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2913
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1567
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2838
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2840
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2965
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3002
msgid "Live"
msgstr "实时"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3426
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3540
msgid "Load"
msgstr "负载"
@@ -1059,20 +1064,20 @@ msgid "Load %s · %d core"
msgid_plural "Load %s · %d cores"
msgstr[0] "负载 %s · %d 核"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3428
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3542
msgctxt "vantage"
msgid "Load average"
msgstr "平均负载"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2120
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2205
msgid "Load average over 1, 5 and 15 minutes"
msgstr "1、5、15 分钟平均负载"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2156
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2241
msgid "Load avg %s"
msgstr "平均负载 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3424
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3538
msgid "Local time"
msgstr "本地时间"
@@ -1088,8 +1093,8 @@ msgstr "链路速率低于信号预期"
msgid "MAC"
msgstr "MAC"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3184
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3216
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3276
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3308
msgid "MAC address"
msgstr "MAC 地址"
@@ -1097,11 +1102,11 @@ msgstr "MAC 地址"
msgid "MCS %d"
msgstr "MCS %d"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1369
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1393
msgid "Make %s narrower"
msgstr "使 %s 变窄"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1372
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1396
msgid "Make %s wider"
msgstr "使 %s 加宽"
@@ -1118,11 +1123,11 @@ msgid "Measuring…"
msgstr "测量中…"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:83
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2143
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2228
msgid "Memory"
msgstr "内存"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3429
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3543
msgid "Memory in use"
msgstr "已用内存"
@@ -1131,63 +1136,63 @@ msgctxt "vantage"
msgid "MiB"
msgstr "MiB"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1279
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1303
msgid "Mirrored"
msgstr "镜像"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1280
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1304
msgid "Mirrored, scale per direction"
msgstr "镜像,每个方向单独刻度"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3353
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3445
msgid "Mode"
msgstr "模式"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3419
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3533
msgid "Model"
msgstr "型号"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1366
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1390
msgid "Move %s down"
msgstr "下移 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1357
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1381
msgid "Move %s left"
msgstr "左移 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1360
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1384
msgid "Move %s right"
msgstr "右移 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1363
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1387
msgid "Move %s up"
msgstr "上移 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1349
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1373
msgid "Move %s: drag, or use the arrow keys"
msgstr "移动 %s:拖动或使用方向键"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3285
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3377
msgid "Name"
msgstr "名称"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:134
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3325
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3417
msgid "Name contains invisible or control characters"
msgstr "名称包含不可见或控制字符"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3187
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3219
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3279
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3311
msgid "Name from"
msgstr "名称来源"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2845
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2935
msgid "Name from: %s"
msgstr "名称来源:%s"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:132
#: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:137
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3326
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3418
msgid "Name is longer than %d characters"
msgstr "名称超过 %d 个字符"
@@ -1195,27 +1200,27 @@ msgstr "名称超过 %d 个字符"
msgid "Name must be text"
msgstr "名称必须是文本"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3128
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3197
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3220
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3289
msgid "Name this device"
msgstr "命名此设备"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2748
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2750
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2875
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2905
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3172
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3212
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2838
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2840
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2964
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2994
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3264
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3304
msgid "Network"
msgstr "网络"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1125
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1689
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1690
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1149
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1713
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1714
msgid "Network path"
msgstr "网络路径"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1298
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1322
msgid "Network path background"
msgstr "网络路径背景"
@@ -1223,13 +1228,13 @@ msgstr "网络路径背景"
msgid "Networks: %s"
msgstr "网络:%s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2678
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2896
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2768
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2985
msgctxt "vantage"
msgid "New"
msgstr "新增"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1813
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1872
msgid "No SSIDs"
msgstr "无 SSID"
@@ -1237,24 +1242,24 @@ msgstr "无 SSID"
msgid "No clients"
msgstr "无客户端"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2828
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3366
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2918
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3458
msgid "No clients connected"
msgstr "无客户端连接"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2957
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3046
msgid "No clients connected."
msgstr "没有客户端连接。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2819
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2909
msgid "No clients in this view"
msgstr "此视图中没有客户端"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2819
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2909
msgid "No clients match “%s”"
msgstr "没有匹配“%s”的客户端"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1865
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1926
msgctxt "vantage"
msgid "No default route"
msgstr "无默认路由"
@@ -1263,7 +1268,7 @@ msgstr "无默认路由"
msgid "No interface with a route"
msgstr "没有带路由的接口"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3374
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3483
msgid "No interface with a route is up."
msgstr "没有带路由的接口处于启用状态。"
@@ -1272,7 +1277,7 @@ msgid "No internet-facing zone found"
msgstr "未找到面向互联网的区域"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:47
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3389
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3498
msgid "No link"
msgstr "无链路"
@@ -1280,7 +1285,7 @@ msgstr "无链路"
msgid "No network interface with a route is up"
msgstr "没有带路由的网络接口处于启用状态"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1794
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1853
msgid "No other interfaces are up"
msgstr "没有其他接口处于启用状态"
@@ -1290,7 +1295,7 @@ msgid "No problems detected"
msgstr "未检测到问题"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:105
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1817
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1876
msgid "No radios reported"
msgstr "未报告射频"
@@ -1307,16 +1312,16 @@ msgstr "无信号"
msgid "No stations are associated right now"
msgstr "当前没有站点关联"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2825
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2915
msgid "No wired devices heard"
msgstr "未发现有线设备"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2991
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3080
msgctxt "vantage"
msgid "No wireless networks configured."
msgstr "未配置无线网络。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2482
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2572
msgid "No wireless radios are reported by this device."
msgstr "此设备未报告任何无线射频。"
@@ -1333,39 +1338,39 @@ msgstr ""
msgid "No zones are configured."
msgstr "尚未配置区域。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2957
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3046
msgid "Nobody is moving data right now."
msgstr "当前没有设备在传输数据。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2515
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2605
msgid "Noise"
msgstr "噪声"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3169
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3261
msgid "Noise / SNR"
msgstr "噪声 / 信噪比"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3357
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3358
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3449
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3450
msgid "Noise floor"
msgstr "底噪"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:105
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1293
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1317
msgid "None"
msgstr "无"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:150
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3324
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3416
msgid "Not a station MAC address"
msgstr "不是站点 MAC 地址"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3119
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3211
msgid "Not connected"
msgstr "未连接"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2877
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3209
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2966
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3301
msgid "Not counted per device on a shared port"
msgstr "共用端口不按设备统计"
@@ -1373,7 +1378,7 @@ msgstr "共用端口不按设备统计"
msgid "Not in effect"
msgstr "未生效"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2193
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2278
msgid "Not reported"
msgstr "未报告"
@@ -1381,7 +1386,7 @@ msgstr "未报告"
msgid "Not reported by the driver"
msgstr "驱动未报告"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3233
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3325
msgid "Nothing better known"
msgstr "无更多信息"
@@ -1402,7 +1407,7 @@ msgstr "OWE"
msgid "Older %s device"
msgstr "较旧的 %s 设备"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2897
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2986
msgid "Older Wi-Fi generation than the radio; uses more airtime"
msgstr "比射频支持的 Wi-Fi 代际更旧;占用更多空口时间"
@@ -1410,7 +1415,7 @@ msgstr "比射频支持的 Wi-Fi 代际更旧;占用更多空口时间"
msgid "On this router"
msgstr "在此路由器上"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2750
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2840
msgctxt "vantage"
msgid "Online"
msgstr "在线"
@@ -1426,7 +1431,7 @@ msgctxt "vantage"
msgid "Open"
msgstr "开放"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2794
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2884
msgid "Open details of %s"
msgstr "打开 %s 的详情"
@@ -1442,7 +1447,7 @@ msgstr "对互联网开放:%d"
msgid "Open network"
msgstr "开放网络"
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:658
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:836
msgid "OpenWrt device"
msgstr "OpenWrt 设备"
@@ -1454,11 +1459,11 @@ msgstr ""
"基本设置中的选项 %s 的值被 firewall4 拒绝,因此不会加载新规则:无法确定开放了"
"哪些内容。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1277
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1301
msgid "Overlaid"
msgstr "叠加"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1278
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1302
msgid "Overlaid, log scale"
msgstr "叠加,对数刻度"
@@ -1466,11 +1471,11 @@ msgstr "叠加,对数刻度"
msgid "Overview"
msgstr "概览"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3168
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3260
msgid "PMF"
msgstr "PMF"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1541
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1565
msgid "Paused while hidden"
msgstr "页面隐藏时暂停"
@@ -1486,7 +1491,7 @@ msgstr ""
"Ping 和其他控制消息、组播、DHCP 续租以及转发到你网络的 IPsec:每台路由器都会"
"放行的流量。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3420
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3534
msgctxt "vantage"
msgid "Platform"
msgstr "平台"
@@ -1496,19 +1501,19 @@ msgctxt "vantage"
msgid "Poor"
msgstr "较差"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3203
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3295
msgid "Port"
msgstr "端口"
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:202
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:355
msgid "Port %d"
msgstr "端口 %d"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2870
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2959
msgid "Port %s"
msgstr "端口 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1955
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2039
msgid "Port total: %s"
msgstr "端口合计:%s"
@@ -1516,11 +1521,11 @@ msgstr "端口合计:%s"
msgid "Private"
msgstr "私有"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3185
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3277
msgid "Private Wi-Fi address (randomised by the device)"
msgstr "私有 Wi-Fi 地址(设备随机化)"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3217
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3309
msgid "Private address (randomised by the device)"
msgstr "私有地址(设备随机化)"
@@ -1528,26 +1533,26 @@ msgstr "私有地址(设备随机化)"
msgid "Private device"
msgstr "私有设备"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3417
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3531
msgid "Processes"
msgstr "进程"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3391
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3500
msgid "Protocol"
msgstr "协议"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2547
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2549
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2637
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2639
msgid "Quick filters"
msgstr "快速筛选"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3173
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3351
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3265
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3443
msgctxt "vantage"
msgid "Radio"
msgstr "射频"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2503
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2593
msgid "Radio details"
msgstr "射频详情"
@@ -1559,65 +1564,69 @@ msgstr "射频已禁用"
msgid "Radio is enabled but not up"
msgstr "射频已启用但未上线"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2527
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3345
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2617
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3437
msgid "Radio settings"
msgstr "射频设置"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1125
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2455
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2457
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1149
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2545
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2547
msgid "Radios"
msgstr "射频"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1866
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1927
msgid "Reachability not probed"
msgstr "未探测可达性"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2862
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2951
msgid "Reached through the uplink port %s, not connected to this device"
msgstr "经由上行端口 %s 到达,并未连接到本设备"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3382
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3491
msgid "Realtime graphs"
msgstr "实时图表"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3401
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3515
msgctxt "vantage"
msgid "Received"
msgstr "已接收"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1542
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1566
msgctxt "vantage"
msgid "Reconnecting…"
msgstr "重新连接中…"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2694
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2784
msgid "Remove filter: %s"
msgstr "移除筛选:%s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3291
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3383
msgid "Remove name"
msgstr "移除名称"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3128
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3197
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3220
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3289
msgctxt "vantage"
msgid "Rename"
msgstr "重命名"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1335
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1359
msgid "Reset"
msgstr "重置"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3228
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3320
msgid "Reverse DNS of its address"
msgstr "其地址的反向 DNS"
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:670
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:848
msgid "Root (overlay)"
msgstr "Root(overlay)"
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3511
+msgid "Route metric"
+msgstr "路由跃点数"
+
#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/firewall.js:281
msgid "Router admin open: %s"
msgstr "路由器管理界面已开放:%s"
@@ -1626,20 +1635,20 @@ msgstr "路由器管理界面已开放:%s"
msgid "SSH (port 22)"
msgstr "SSH(端口 22)"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3283
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3375
msgid "Save"
msgstr "保存"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3176
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3268
msgid "Seen since"
msgstr "首次出现"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3402
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3516
msgctxt "vantage"
msgid "Sent"
msgstr "已发送"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1281
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1305
msgid "Separate lanes"
msgstr "分开显示"
@@ -1647,57 +1656,57 @@ msgstr "分开显示"
msgid "Settings to check"
msgstr "待检查的设置"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3204
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3296
msgid "Shared by %d devices"
msgstr "%d 台设备共用"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2866
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2955
msgid "Shared port"
msgstr "共用端口"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1415
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1439
msgid "Show %s"
msgstr "显示 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2820
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2910
msgid "Show all clients"
msgstr "显示全部客户端"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2129
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2214
msgid "Show or hide system details"
msgstr "显示/隐藏系统详情"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1690
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1714
msgid "Show or hide the network path"
msgstr "显示/隐藏网络路径"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2458
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2548
msgid "Show or hide the radio details"
msgstr "显示/隐藏射频详情"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2248
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2333
msgid "Show or hide the throughput chart"
msgstr "显示/隐藏吞吐量图表"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2982
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3071
msgid "Show or hide the wireless networks"
msgstr "显示/隐藏无线网络"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1929
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3000
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2013
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3089
msgid "Show the clients of %s"
msgstr "显示 %s 的客户端"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1955
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2039
msgid "Show the devices on %s"
msgstr "显示 %s 上的设备"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:119
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:120
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:128
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2750
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2902
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3152
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2840
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2991
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3244
msgid "Signal"
msgstr "信号强度"
@@ -1705,7 +1714,7 @@ msgstr "信号强度"
msgid "Signal not reported"
msgstr "未报告信号"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3390
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3499
msgctxt "vantage"
msgid "Speed"
msgstr "速率"
@@ -1715,24 +1724,24 @@ msgid "Standard housekeeping: %d rule"
msgid_plural "Standard housekeeping: %d rules"
msgstr[0] "标准常规规则:%d 条"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1293
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1317
msgid "Starfield"
msgstr "星空"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2829
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2919
msgid "Stations appear here as soon as they associate with one of the SSIDs."
msgstr "站点一旦关联到任一 SSID 便会显示在这里。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3352
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3444
msgid "Status"
msgstr "状态"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:93
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2146
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2231
msgid "Storage"
msgstr "存储"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3292
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3384
msgid "Stored on this device in /etc/config/vantage"
msgstr "保存在本设备 /etc/config/vantage 中"
@@ -1748,16 +1757,16 @@ msgstr "信号强 %s,链路 %s"
msgid "Strong signal, %s"
msgstr "信号强,%s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2203
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2288
msgctxt "vantage"
msgid "Swap"
msgstr "交换分区"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3207
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3299
msgid "Switch ports"
msgstr "交换机端口"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:381
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:390
msgid "Switch ports of VLAN %d on %s: %s"
msgstr "VLAN %d(%s)的交换机端口:%s"
@@ -1765,13 +1774,13 @@ msgstr "VLAN %d(%s)的交换机端口:%s"
msgid "Switched off"
msgstr "已关闭"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1126
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2128
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2129
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1150
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2213
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2214
msgid "System"
msgstr "系统"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3417
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3531
msgid "System settings"
msgstr "系统设置"
@@ -1784,19 +1793,19 @@ msgid "Telnet (port 23)"
msgstr "Telnet(端口 23)"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:76
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2160
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2245
msgid "Temperature %s"
msgstr "温度 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:670
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:848
msgid "Temporary (RAM)"
msgstr "临时(RAM)"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2749
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2839
msgid "The bridge forgets a device after about five minutes without traffic"
msgstr "设备约五分钟无流量后,网桥会将其遗忘"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2823
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2913
msgid ""
"The bridges have learned so many addresses that listing them here would "
"strain this device."
@@ -1811,7 +1820,7 @@ msgstr ""
"该处适用默认入站数据策略且为接受,因此互联网上的任何主机都能访问路由器本身。"
"请将其加入 wan 区域,或在基本设置中将入站数据设为拒绝。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3329
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3421
msgid "The device could not write /etc/config/vantage."
msgstr "设备无法写入 /etc/config/vantage。"
@@ -1837,7 +1846,7 @@ msgstr ""
"无法读取接口列表,且默认入站数据策略为接受:不属于任何区域的上行接口将会开"
"放。请在基本设置中将入站数据设为拒绝。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3231
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3323
msgid "The name the device announces (WPS)"
msgstr "设备广播的名称(WPS)"
@@ -1849,7 +1858,7 @@ msgstr "唯一已测客户端高于 %s"
msgid "The only measured client"
msgstr "唯一已测客户端"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2861
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2950
msgid "The router this device sends its traffic to"
msgstr "此设备发送流量所经的路由器"
@@ -1865,7 +1874,7 @@ msgstr "保存的名称包含无效的配置节 ID"
msgid "The uplinks could not be checked"
msgstr "无法检查上行接口"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1874
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1942
msgid "This access point"
msgstr "此接入点"
@@ -1873,11 +1882,11 @@ msgstr "此接入点"
msgid "This address family is in no zone: the default policies apply."
msgstr "此地址族不属于任何区域:适用默认策略。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1874
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1942
msgid "This device"
msgstr "此设备"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3328
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3420
msgid "This device already stores %d names; remove some first."
msgstr "此设备已存储 %d 个名称;请先移除部分。"
@@ -1885,13 +1894,17 @@ msgstr "此设备已存储 %d 个名称;请先移除部分。"
msgid "This device reports no radios"
msgstr "此设备未报告任何射频"
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3480
+msgid "This line is down or has no default route now."
+msgstr "此线路已断开,或当前没有默认路由。"
+
#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/firewall.js:183
msgid ""
"This page cannot tell what is open. Reload it; if that does not help, check "
"the firewall pages."
msgstr "本页无法判断开放了哪些内容。请重新加载;如果仍无效,请检查防火墙页面。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3336
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3428
msgid "This radio is not reported any more."
msgstr "驱动不再报告此射频。"
@@ -1899,23 +1912,23 @@ msgstr "驱动不再报告此射频。"
msgid "This setup is beyond what this overview checks"
msgstr "此配置超出本概览的检查范围"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3119
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3211
msgid "This station is not associated right now."
msgstr "此站点当前未关联。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1125
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2240
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2242
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3158
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1149
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2325
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2327
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3250
msgctxt "vantage"
msgid "Throughput"
msgstr "吞吐量"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1286
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1310
msgid "Throughput chart"
msgstr "吞吐量图表"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2233
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2318
msgid "Throughput per link; arrow keys read the values over time"
msgstr "每条链路的吞吐量;方向键可查看历史值"
@@ -1924,38 +1937,38 @@ msgctxt "vantage"
msgid "TiB"
msgstr "TiB"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3165
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3257
msgid "To device"
msgstr "到设备"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2882
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2917
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2970
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2971
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3006
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3059
msgid "To device %s, from device %s"
msgstr "到设备 %s,来自设备 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2909
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2998
msgid "To device: %s"
msgstr "到设备:%s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3385
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3494
msgid "To network"
msgstr "发往网络"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2822
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2912
msgid "Too many devices to list"
msgstr "设备过多,无法列出"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1126
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2934
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2935
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1150
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3023
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3024
msgctxt "vantage"
msgid "Top talkers"
msgstr "流量大户"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3178
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3208
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3348
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3270
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3300
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3440
msgid "Traffic"
msgstr "流量"
@@ -1973,8 +1986,16 @@ msgstr ""
"未被任何转发覆盖的互联网流量仍会到达你的其他网络。请在基本设置中将转发设为拒"
"绝。"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2514
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3355
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1938
+msgid "Traffic to the internet goes through %s, a tunnel over this line"
+msgstr "去往互联网的流量经过 %s,一条在此线路上运行的隧道"
+
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3503
+msgid "Tunnel"
+msgstr "隧道"
+
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2604
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3447
msgid "Tx power"
msgstr "发射功率"
@@ -1986,16 +2007,16 @@ msgstr ""
"已安装 UPnP:它运行时,你网络中的设备可以自行开放端口,这些端口不会在此列出。"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:272
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3118
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3210
msgctxt "vantage"
msgid "Unknown device"
msgstr "未知设备"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3327
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3419
msgid "Unknown device type"
msgstr "未知设备类型"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3336
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3428
msgid "Unknown radio"
msgstr "未知射频"
@@ -2010,14 +2031,14 @@ msgid "Unnamed rule"
msgstr "未命名的规则"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:57
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2502
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3352
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3389
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2592
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3444
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3498
msgctxt "vantage"
msgid "Up"
msgstr "已上线"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2153
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2238
msgid "Up %s"
msgstr "已运行 %s"
@@ -2026,45 +2047,47 @@ msgstr "已运行 %s"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:49
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:51
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:57
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2265
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3374
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2351
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3483
msgctxt "vantage"
msgid "Uplink"
msgstr "上行链路"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2265
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2351
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2352
msgid "Uplink %s"
msgstr "上行链路 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3378
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3476
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3487
msgid "Uplink · %s"
msgstr "上行链路 · %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2246
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2337
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2411
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2331
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2427
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2501
msgid "Upload"
msgstr "上传"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:369
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:378
msgid "Upload (from clients)"
msgstr "上传(来自客户端)"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3180
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3272
msgctxt "vantage"
msgid "Uploaded"
msgstr "已上传"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2862
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2951
msgid "Upstream"
msgstr "上游"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3423
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3537
msgid "Uptime"
msgstr "运行时间"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2863
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3212
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2952
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3304
msgid "VLAN %d"
msgstr "VLAN %d"
@@ -2090,14 +2113,16 @@ msgid ""
"stations (wireless configuration without keys, through luci.vantage "
"wireless), its temperature sensors (luci.vantage thermal), the wired hosts "
"its bridges have learned (luci.vantage wired: MAC, port and when last heard, "
-"and which switch ports a port's VLAN has) and the link state of those switch "
-"ports (luci getSwconfigPortState)"
+"and which switch ports a port's VLAN has), the link state of those switch "
+"ports (luci getSwconfigPortState) and the default route the kernel takes to "
+"the internet (luci.vantage routes: family, device and metric, no gateways)"
msgstr ""
"Vantage 仪表盘:设备、上行链路、射频与站点的只读状态(经 luci.vantage "
"wireless 读取无线配置,不含密钥),温度传感器(luci.vantage thermal),网桥已"
"学习到的有线主机(luci.vantage wired:MAC、端口、最后一次收到的时间,以及某端"
-"口的 VLAN 包含哪些交换机端口),以及这些交换机端口的链路状态(luci "
-"getSwconfigPortState)"
+"口的 VLAN 包含哪些交换机端口),这些交换机端口的链路状态(luci "
+"getSwconfigPortState),以及内核去往互联网所走的默认路由(luci.vantage "
+"routes:协议族、设备和跃点数,不含网关)"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:43
msgid "Vendor"
@@ -2207,11 +2232,11 @@ msgstr "WPA3 个人版"
msgid "WPS"
msgstr "WPS"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3188
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3280
msgid "WPS device name"
msgstr "WPS 设备名称"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1575
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1599
msgid "Warning"
msgstr "警告"
@@ -2225,7 +2250,7 @@ msgid "Weak"
msgstr "弱"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:157
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2677
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2767
msgid "Weak signal"
msgstr "信号弱"
@@ -2248,27 +2273,27 @@ msgstr "开放内容取决于 firewall4 如何处理 %s,本页无法跟踪。
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:106
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:108
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:110
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2731
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2821
msgid "Wi-Fi"
msgstr "Wi-Fi"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1824
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2731
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1883
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2821
msgid "Wired"
msgstr "有线"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1126
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2981
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2982
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1150
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3070
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3071
msgctxt "vantage"
msgid "Wireless networks"
msgstr "无线网络"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3138
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3230
msgid "Wireless settings"
msgstr "无线设置"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3227
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3319
msgid "Your name for this device"
msgstr "你为此设备设置的名称"
@@ -2306,15 +2331,15 @@ msgstr "任意区域"
msgid "any zone (default policy)"
msgstr "任意区域(默认策略)"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2508
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2598
msgid "auto"
msgstr "自动"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3176
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3268
msgid "before this page opened"
msgstr "打开本页之前"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3205
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3297
msgid "behind %s, VLAN %d"
msgstr "位于 %s 之后,VLAN %d"
@@ -2323,16 +2348,16 @@ msgctxt "vantage"
msgid "bit/s"
msgstr "bit/s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2369
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2459
msgid "collecting · %s of data"
msgstr "采集中 · 已采集 %s 数据"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2369
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2459
msgid "collecting · first samples"
msgstr "采集中 · 首个样本"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:248
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2349
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:251
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2439
msgid "collecting…"
msgstr "采集中…"
@@ -2344,9 +2369,18 @@ msgstr "自定义规则文件"
msgid "dBm"
msgstr "dBm"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:376
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2866
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3204
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1802
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1940
+msgid "default route"
+msgstr "默认路由"
+
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1940
+msgid "default route via %s"
+msgstr "默认路由经由 %s"
+
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:385
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2955
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3296
msgid "down"
msgstr "已断开"
@@ -2355,7 +2389,7 @@ msgctxt "vantage"
msgid "drop"
msgstr "丢弃"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3257
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3349
msgctxt "vantage"
msgid "e.g. Living room TV"
msgstr "例如:客厅电视"
@@ -2381,7 +2415,7 @@ msgstr "来自任意地址"
msgid "from anywhere except %s"
msgstr "来自除 %s 外的任意地址"
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:213
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:366
msgid "full duplex"
msgstr "全双工"
@@ -2389,12 +2423,13 @@ msgstr "全双工"
msgid "gateway %s"
msgstr "网关 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:213
+#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:366
msgid "half duplex"
msgstr "半双工"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/fmt.js:62
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3008
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1960
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3097
msgid "idle"
msgstr "空闲"
@@ -2436,18 +2471,18 @@ msgctxt "vantage"
msgid "kbit/s"
msgstr "kbit/s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2138
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2368
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2223
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2458
msgid "last 5 min"
msgstr "最近 5 分钟"
#: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:175
#: luci-app-vantage/htdocs/luci-static/resources/vantage/wifi.js:104
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2911
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3000
msgid "legacy"
msgstr "旧版"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:376
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:385
msgid "link up"
msgstr "已连接"
@@ -2455,45 +2490,45 @@ msgstr "已连接"
msgid "mDNS"
msgstr "mDNS"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3229
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3321
msgid "mDNS announcement"
msgstr "mDNS 广播"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3160
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3211
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3252
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3303
msgid "measuring"
msgstr "测量中"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2344
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2434
msgid "measuring…"
msgstr "测量中…"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2325
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2415
msgctxt "vantage"
msgid "no data"
msgstr "无数据"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1872
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1933
msgid "no uplink"
msgstr "无上行链路"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3186
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3278
msgid "not known to this AP"
msgstr "此 AP 未识别"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3218
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3310
msgid "not known to this device"
msgstr "此设备未识别"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3358
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3450
msgid "not reported (driver placeholder %s)"
msgstr "未报告(驱动占位值 %s)"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3169
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3261
msgid "not reported by the driver"
msgstr "驱动未报告"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2365
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2455
msgctxt "vantage"
msgid "now"
msgstr "现在"
@@ -2502,16 +2537,16 @@ msgstr "现在"
msgid "now %s down, %s up"
msgstr "当前下行 %s,上行 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3167
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3259
msgid "older than the radio (%s)"
msgstr "比射频支持的标准更旧(%s)"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2342
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2432
msgctxt "vantage"
msgid "peak"
msgstr "峰值"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2139
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2224
msgid "per core"
msgstr "每核"
@@ -2520,11 +2555,11 @@ msgctxt "vantage"
msgid "port forward"
msgstr "端口转发"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3154
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3246
msgid "range %s … %s"
msgstr "范围 %s … %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3384
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3493
msgid "received on %s"
msgstr "在 %s 上接收"
@@ -2537,7 +2572,7 @@ msgstr "拒绝"
msgid "router port %s"
msgstr "路由器端口 %s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3385
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3494
msgid "sent on %s"
msgstr "在 %s 上发送"
@@ -2545,12 +2580,12 @@ msgstr "在 %s 上发送"
msgid "short GI"
msgstr "短 GI"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2885
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3213
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2974
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3305
msgid "static entry"
msgstr "静态条目"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3206
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3298
msgid "switch port %s"
msgstr "交换机端口 %s"
@@ -2562,11 +2597,11 @@ msgstr "已关闭"
msgid "the covered subnets of zone %s"
msgstr "区域 %s 覆盖的子网"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3210
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3302
msgid "the port in total: %s"
msgstr "该端口合计:%s"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3205
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3297
msgid "the port: %s"
msgstr "端口:%s"
@@ -2582,7 +2617,7 @@ msgstr "此路由器"
msgid "traffic rule"
msgstr "通信规则"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1877
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1945
msgid "up %s"
msgstr "已运行 %s"
@@ -2599,10 +2634,41 @@ msgstr "区域转发"
msgid "zones %s and %s if they share a device"
msgstr "区域 %s 和 %s(若两者共用设备)"
-#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2362
+#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2452
msgid "−%d min"
msgstr "−%d 分钟"
+#~ msgid ""
+#~ "Vantage dashboard: read-only status of the device, uplink, radios and "
+#~ "stations (wireless configuration without keys, through luci.vantage "
+#~ "wireless), its temperature sensors (luci.vantage thermal), the wired "
+#~ "hosts its bridges have learned (luci.vantage wired: MAC, port and when "
+#~ "last heard, and which switch ports a port's VLAN has), the link state of "
+#~ "those switch ports (luci getSwconfigPortState) and the kernel's default "
+#~ "routes in the main table (luci.vantage routes: family, device and metric "
+#~ "of each, no gateways)"
+#~ msgstr ""
+#~ "Vantage 仪表盘:设备、上行链路、射频与站点的只读状态(经 luci.vantage "
+#~ "wireless 读取无线配置,不含密钥),温度传感器(luci.vantage thermal),网"
+#~ "桥已学习到的有线主机(luci.vantage wired:MAC、端口、最后一次收到的时间,"
+#~ "以及某端口的 VLAN 包含哪些交换机端口),这些交换机端口的链路状态(luci "
+#~ "getSwconfigPortState),以及内核主路由表中的默认路由(luci.vantage "
+#~ "routes:每条的协议族、设备和跃点数,不含网关)"
+
+#~ msgid ""
+#~ "Vantage dashboard: read-only status of the device, uplink, radios and "
+#~ "stations (wireless configuration without keys, through luci.vantage "
+#~ "wireless), its temperature sensors (luci.vantage thermal), the wired "
+#~ "hosts its bridges have learned (luci.vantage wired: MAC, port and when "
+#~ "last heard, and which switch ports a port's VLAN has) and the link state "
+#~ "of those switch ports (luci getSwconfigPortState)"
+#~ msgstr ""
+#~ "Vantage 仪表盘:设备、上行链路、射频与站点的只读状态(经 luci.vantage "
+#~ "wireless 读取无线配置,不含密钥),温度传感器(luci.vantage thermal),网"
+#~ "桥已学习到的有线主机(luci.vantage wired:MAC、端口、最后一次收到的时间,"
+#~ "以及某端口的 VLAN 包含哪些交换机端口),以及这些交换机端口的链路状态"
+#~ "(luci getSwconfigPortState)"
+
#~ msgid "%d client"
#~ msgid_plural "Weakest of %d clients"
#~ msgstr[0] "%d 个客户端中最弱"
diff --git a/luci-app-vantage/root/usr/share/rpcd/acl.d/luci-app-vantage.json b/luci-app-vantage/root/usr/share/rpcd/acl.d/luci-app-vantage.json
index a217afac3..791863ee1 100644
--- a/luci-app-vantage/root/usr/share/rpcd/acl.d/luci-app-vantage.json
+++ b/luci-app-vantage/root/usr/share/rpcd/acl.d/luci-app-vantage.json
@@ -1,6 +1,6 @@
{
"luci-app-vantage": {
- "description": "Vantage dashboard: read-only status of the device, uplink, radios and stations (wireless configuration without keys, through luci.vantage wireless), its temperature sensors (luci.vantage thermal), the wired hosts its bridges have learned (luci.vantage wired: MAC, port and when last heard, and which switch ports a port's VLAN has) and the link state of those switch ports (luci getSwconfigPortState)",
+ "description": "Vantage dashboard: read-only status of the device, uplink, radios and stations (wireless configuration without keys, through luci.vantage wireless), its temperature sensors (luci.vantage thermal), the wired hosts its bridges have learned (luci.vantage wired: MAC, port and when last heard, and which switch ports a port's VLAN has), the link state of those switch ports (luci getSwconfigPortState) and the default route the kernel takes to the internet (luci.vantage routes: family, device and metric, no gateways)",
"read": {
"file": {
"/proc/stat": [ "read" ]
@@ -12,7 +12,7 @@
"network.device": [ "status" ],
"luci-rpc": [ "getHostHints" ],
"luci": [ "getSwconfigPortState" ],
- "luci.vantage": [ "thermal", "wired", "wireless" ],
+ "luci.vantage": [ "routes", "thermal", "wired", "wireless" ],
"iwinfo": [ "assoclist", "info" ],
"hostapd.*": [ "get_clients", "get_status" ],
"umdns": [ "hosts" ],
diff --git a/luci-app-vantage/root/usr/share/rpcd/ucode/luci.vantage b/luci-app-vantage/root/usr/share/rpcd/ucode/luci.vantage
index 39844b496..ca95e045f 100644
--- a/luci-app-vantage/root/usr/share/rpcd/ucode/luci.vantage
+++ b/luci-app-vantage/root/usr/share/rpcd/ucode/luci.vantage
@@ -26,6 +26,18 @@
// /etc/config/network (device, vlan, vid and ports, nothing
// else), or board.json's roles for a switch those give no
// VLAN. Read group luci-app-vantage.
+// routes the route the kernel takes to the internet, IPv4 and IPv6:
+// a read-only lookup of each family (as `ip route get
+// fibmatch`) of a documentation address no network uses, so
+// the answer is the default route ordinary traffic takes.
+// For each family whose answer is a unicast default route in
+// the main table: its family (4 or 6), the device it leaves by
+// (null over several next hops) and its metric; no gateways.
+// netifd lists the routes it asked for; of two with the same
+// metric the kernel keeps the one added last. routes is null
+// when a lookup could not be sent. One lookup a family, so
+// the work does not grow with the routing table. Read group
+// luci-app-vantage.
// set_alias { mac, name, icon }: name one station, or remove its name
// with name ''. Validated here, whatever the browser did, and
// written to /etc/config/vantage only. Write group
@@ -52,6 +64,8 @@ const THERMAL = '/sys/class/thermal';
const MAX_ZONES = 16;
const MAX_HOSTS = 512; // wired hosts per reply
const MAX_PER_PORT = 128; // of them on one port (the uplink's would take them all)
+const PROBE4 = '198.51.100.1'; // routes: looked up, never sent to (documentation ranges)
+const PROBE6 = '2001:db8::1';
const NET = '/sys/class/net';
const FDB_LIMIT = 4096; // forwarding entries, all bridges together, before wired() lists none
const FDB_ENTRY = 16; // sizeof(struct __fdb_entry), brforward's record
@@ -478,6 +492,31 @@ function wired() {
return out;
}
+// [ { family, dev, metric } ] for the families whose lookup answers with
+// a unicast default route in the main table (no dst), IPv4 then IPv6; dev
+// null over several next hops (multipath, no single oif). null when a
+// lookup could not be sent; false is the kernel's error, for a lookup that
+// there is no route (ENETUNREACH), so that family is left out.
+function routes() {
+ let out = [];
+
+ for (let q in [ { family: rtnl.const.AF_INET, dst: PROBE4 }, { family: rtnl.const.AF_INET6, dst: PROBE6 } ]) {
+ let r = rtnl.request(rtnl.const.RTM_GETROUTE, 0, { family: q.family, dst: q.dst, flags: rtnl.const.RTM_F_FIB_MATCH });
+
+ if (r === null)
+ return null;
+
+ if (type(r) != 'object' || r.family != q.family || r.dst != null || r.table != rtnl.const.RT_TABLE_MAIN || r.type != rtnl.const.RTN_UNICAST)
+ continue;
+
+ let m = r.priority ?? 0;
+
+ push(out, { family: (q.family == rtnl.const.AF_INET) ? 4 : 6, dev: netdev(r.oif), metric: (type(m) == 'int' && m >= 0) ? m : 0 });
+ }
+
+ return out;
+}
+
// a switch port's number (0..63), or null
function switch_port(v) {
return (type(v) == 'int' && v >= 0 && v < 64) ? v : null;
@@ -631,6 +670,12 @@ const methods = {
}
},
+ routes: {
+ call: function() {
+ return { routes: routes() };
+ }
+ },
+
set_alias: {
args: { mac: 'mac', name: 'name', icon: 'icon' },
call: function(request) {
diff --git a/luci-theme-vantage/Makefile b/luci-theme-vantage/Makefile
index 86b043847..cfe690611 100644
--- a/luci-theme-vantage/Makefile
+++ b/luci-theme-vantage/Makefile
@@ -11,7 +11,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-theme-vantage
PKG_VERSION:=1.0.15
-PKG_RELEASE:=32
+PKG_RELEASE:=33
PKG_LICENSE:=GPL-3.0-or-later
LUCI_TITLE:=Vantage theme
diff --git a/luci-theme-vantage/htdocs/luci-static/vantage/vantage.css b/luci-theme-vantage/htdocs/luci-static/vantage/vantage.css
index 7037bec02..f865357ea 100644
--- a/luci-theme-vantage/htdocs/luci-static/vantage/vantage.css
+++ b/luci-theme-vantage/htdocs/luci-static/vantage/vantage.css
@@ -2594,6 +2594,9 @@ html:not([data-darkmode="true"]) .vt-login-page::before {
#packages {
width: 100% !important;
}
+vt-brand-word {
+ margin:0;
+}
.vt-login-card {
padding: var(--sp-6);
background: var(--s1);
diff --git a/luci-theme-vantage/ucode/template/themes/vantage/header.ut b/luci-theme-vantage/ucode/template/themes/vantage/header.ut
index aa56c23f4..5166f0b13 100644
--- a/luci-theme-vantage/ucode/template/themes/vantage/header.ut
+++ b/luci-theme-vantage/ucode/template/themes/vantage/header.ut
@@ -60,7 +60,7 @@