From bbccdf6fb090618362b412992e39cb656964a195 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 3 Nov 2026 04:53:29 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9B=84=20Sync=202026-11-03=2004:53:29?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- luci-app-open-box/Makefile | 4 +- luci-app-pingpacket/README.md | 43 +- .../luci-app-pingpacket/Makefile | 32 + .../luasrc/controller/pingpacket.lua | 261 +++++ .../luasrc/view/pingpacket/logs.htm | 16 +- .../luasrc/view/pingpacket/status.htm | 821 +++++++++++++++ .../root/usr/bin/pingpacket.sh | 217 +++- luci-app-vantage/Makefile | 4 +- .../luci-static/resources/vantage/model.js | 37 +- .../resources/view/vantage/overview.js | 78 +- luci-app-vantage/po/templates/vantage.pot | 954 +++++++++--------- luci-app-vantage/po/zh_Hans/vantage.po | 954 +++++++++--------- .../share/rpcd/acl.d/luci-app-vantage.json | 3 +- .../root/usr/share/rpcd/ucode/luci.vantage | 134 ++- luci-theme-vantage/Makefile | 4 +- .../htdocs/luci-static/vantage/vantage.css | 5 +- xt-tls/Makefile | 4 +- 17 files changed, 2571 insertions(+), 1000 deletions(-) diff --git a/luci-app-open-box/Makefile b/luci-app-open-box/Makefile index 8ff288ded..09ca29181 100644 --- a/luci-app-open-box/Makefile +++ b/luci-app-open-box/Makefile @@ -1,8 +1,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-open-box -PKG_VERSION:=0.1.389 -PKG_RELEASE:=58 +PKG_VERSION:=0.1.390 +PKG_RELEASE:=59 PKG_MAINTAINER:=liandu2024 PKG_LICENSE:=GPL-3.0-or-later diff --git a/luci-app-pingpacket/README.md b/luci-app-pingpacket/README.md index 1d77e17cd..c4d7ea3c5 100644 --- a/luci-app-pingpacket/README.md +++ b/luci-app-pingpacket/README.md @@ -76,6 +76,24 @@ - 停止服务、重新启用服务或重启服务后,统计会重新开始 - 国内和国外分别独立累计,不合并计算 +### 丢包与时间的关系 + +监控页内置一张丢包率趋势图,用于观察网络质量随时间的变化: + +- 国内、国外两条曲线分别独立展示,带面积填充与悬浮提示 +- 支持 `日`(最近 24 小时,10 分钟粒度)、`周`(最近 7 天,1 小时粒度)、`月`(最近 30 天,6 小时粒度) +- 支持 `自定义` 时间范围,可选起点与终点,单次最多查询 90 天 +- 图表上方显示所选区间的平均丢包率、区间峰值丢包率与统计区间 +- 鼠标悬浮可查看某个时间点的丢包率、样本数与丢包数 +- 图表数据全部由本地接口生成,不依赖任何外部 CDN 或前端库 + +数据来源与保留策略: + +- 采集脚本按分钟把探测结果(样本数、丢包数、延迟合计)写入 `/etc/pingpacket/history/YYYY-MM-DD.tsv` +- 每分钟最多写一行,写盘压力很小;服务停止时会立即刷写当前分钟的数据 +- 历史文件最多保留 35 天,超期文件会被自动清理 +- 与统计卡片不同:图表记录的是历史趋势,服务重启或设备重启后仍然保留;统计卡片的累计值则会重新开始 + ### 日志页 - 显示插件运行日志 @@ -179,5 +197,28 @@ apk add --allow-untrusted ./luci-app-pingpacket_v1.0.22_all.apk 说明: - 升级时会尽量保留已有 `/etc/config/pingpacket` -- 若系统中存在历史遗留的 `/etc/config/pingpacket-opkg`,安装脚本会尽量兼容处理 +- 若系统中存在历史遗留的 `/etc/config/pingpacket-opkg`,安装脚本会用其中缺失的默认项补齐现有配置,然后删除该文件 +- 安装脚本会自动创建 `/etc/pingpacket/history` 目录用于保存丢包历史 + +## 运行文件 + +| 路径 | 说明 | 生命周期 | +| --- | --- | --- | +| `/tmp/pingpacket_status.json` | 监控状态与累计统计 | 服务停止后删除 | +| `/tmp/pingpacket.log` | 运行日志,最多 500 行 | 设备重启后丢失 | +| `/tmp/pingpacket_cpu_state` | CPU 采样缓存 | 设备重启后丢失 | +| `/var/run/pingpacket/config` | 本次运行的配置缓存 | 服务停止后删除 | +| `/var/run/pingpacket/start_time` | 本次服务启动时间 | 服务停止后删除 | +| `/etc/pingpacket/history/*.tsv` | 按分钟聚合的丢包历史 | 保留 35 天 | + +## 接口 + +| 接口 | 说明 | +| --- | --- | +| `get_data` | 返回配置、服务状态、系统资源与累计统计 | +| `get_history` | 返回丢包趋势数据,参数 `range=day\|week\|month\|custom`,自定义时附加 `from`、`to`(Unix 秒) | +| `get_logs` | 返回日志内容与元信息 | +| `clear_logs` | 清空日志文件 | +| `save_config` | 保存配置,并按启用状态重启或停止服务 | +| `restart_service` | 数据停滞时手动重启服务 | diff --git a/luci-app-pingpacket/luci-app-pingpacket/Makefile b/luci-app-pingpacket/luci-app-pingpacket/Makefile index 40f9f77bf..f68f461d2 100644 --- a/luci-app-pingpacket/luci-app-pingpacket/Makefile +++ b/luci-app-pingpacket/luci-app-pingpacket/Makefile @@ -36,6 +36,38 @@ endef define Package/$(PKG_NAME)/postinst #!/bin/sh [ -n "$${IPKG_INSTROOT}" ] && exit 0 + +# 丢包历史数据目录(按天分文件保存,最多保留 35 天) +mkdir -p /etc/pingpacket/history + +# 升级时 opkg 会把新的默认配置文件留成 pingpacket-opkg, +# 这里只补齐旧配置中缺失的选项,已有取值保持不变。 +merge_pingpacket_options() { + local source_file="/etc/config/pingpacket-opkg" + local key + local value + + [ -f "$$source_file" ] || return 0 + + if [ ! -f /etc/config/pingpacket ]; then + mv -f "$$source_file" /etc/config/pingpacket + return 0 + fi + + sed -n "s/^[[:space:]]*option[[:space:]]\+\([A-Za-z0-9_]*\)[[:space:]]\+\(.*\)$$/\1=\2/p" "$$source_file" | tr -d "'" | + while IFS='=' read -r key value; do + [ -n "$$key" ] || continue + if [ -z "$$(uci -q get "pingpacket.config.$$key")" ]; then + uci -q set "pingpacket.config.$$key=$$value" + fi + done + + uci -q commit pingpacket + rm -f "$$source_file" +} + +merge_pingpacket_options + rm -f /tmp/luci-indexcache.* rm -rf /tmp/luci-modulecache/ /etc/init.d/rpcd reload 2>/dev/null diff --git a/luci-app-pingpacket/luci-app-pingpacket/luasrc/controller/pingpacket.lua b/luci-app-pingpacket/luci-app-pingpacket/luasrc/controller/pingpacket.lua index 220a5901c..cc03493ba 100644 --- a/luci-app-pingpacket/luci-app-pingpacket/luasrc/controller/pingpacket.lua +++ b/luci-app-pingpacket/luci-app-pingpacket/luasrc/controller/pingpacket.lua @@ -92,6 +92,119 @@ local function read_start_time() return value end +local HISTORY_DIR = "/etc/pingpacket/history" +local HISTORY_MAX_SPAN = 90 * 86400 +local HISTORY_BUCKET_STEPS = { 1, 2, 5, 10, 15, 30, 60, 120, 180, 240, 360, 720, 1440 } + +local function day_start(timestamp) + local parts = os.date("*t", timestamp) + + return os.time({ + year = parts.year, + month = parts.month, + day = parts.day, + hour = 0, + min = 0, + sec = 0 + }) +end + +local function next_day_start(timestamp) + local parts = os.date("*t", timestamp) + + return os.time({ + year = parts.year, + month = parts.month, + day = parts.day + 1, + hour = 0, + min = 0, + sec = 0 + }) +end + +local function pick_bucket_minutes(span_seconds, target_points) + local ideal = (span_seconds / 60) / (target_points or 160) + + for _, step in ipairs(HISTORY_BUCKET_STEPS) do + if step >= ideal then + return step + end + end + + return 1440 +end + +local function round1(value) + return tonumber(string.format("%.1f", value)) or 0 +end + +local function bucket_label(timestamp, bucket_minutes, span_seconds) + if bucket_minutes >= 1440 then + return os.date("%m-%d", timestamp) + end + + if span_seconds > 2 * 86400 then + return os.date("%m-%d %H:%M", timestamp) + end + + return os.date("%H:%M", timestamp) +end + +local function collect_history(from_ts, to_ts, bucket_minutes) + local bucket_seconds = bucket_minutes * 60 + local total = math.floor((to_ts - from_ts) / bucket_seconds) + 1 + local buckets = {} + + for index = 1, total do + buckets[index] = { ds = 0, dl = 0, dr = 0, fs = 0, fl = 0, fr = 0 } + end + + local day_ts = day_start(from_ts) + local guard = 0 + + while day_ts <= to_ts and guard < 400 do + guard = guard + 1 + + local handle = io.open(string.format("%s/%s.tsv", HISTORY_DIR, os.date("%Y-%m-%d", day_ts)), "r") + + if handle then + for line in handle:lines() do + local clock, ds, dl, dr, fs, fl, fr = line:match("^(%d%d:%d%d)%s+(%d+)%s+(%d+)%s+([%d%.]+)%s+(%d+)%s+(%d+)%s+([%d%.]+)") + + if clock then + local hour, minute = clock:match("^(%d%d):(%d%d)") + local probe_ts = day_ts + (tonumber(hour) * 3600) + (tonumber(minute) * 60) + + if probe_ts >= from_ts and probe_ts <= to_ts then + local index = math.floor((probe_ts - from_ts) / bucket_seconds) + 1 + local bucket = buckets[index] + + if bucket then + bucket.ds = bucket.ds + (tonumber(ds) or 0) + bucket.dl = bucket.dl + (tonumber(dl) or 0) + bucket.dr = bucket.dr + (tonumber(dr) or 0) + bucket.fs = bucket.fs + (tonumber(fs) or 0) + bucket.fl = bucket.fl + (tonumber(fl) or 0) + bucket.fr = bucket.fr + (tonumber(fr) or 0) + end + end + end + end + + handle:close() + end + + local following = next_day_start(day_ts) + if following <= day_ts then + break + end + + day_ts = following + end + + return buckets, total +end + local function should_require_target(request_source, enabled) if request_source == "save" then return true @@ -312,12 +425,160 @@ function index() entry({"admin", "status", "pingpacket", "logs"}, template("pingpacket/logs"), "日志", 2).leaf = true entry({"admin", "status", "pingpacket", "status"}, alias("admin", "status", "pingpacket", "monitor")).leaf = true entry({"admin", "status", "pingpacket", "get_data"}, call("action_get_data")).leaf = true + entry({"admin", "status", "pingpacket", "get_history"}, call("action_get_history")).leaf = true entry({"admin", "status", "pingpacket", "get_logs"}, call("action_get_logs")).leaf = true entry({"admin", "status", "pingpacket", "clear_logs"}, call("action_clear_logs")).leaf = true entry({"admin", "status", "pingpacket", "save_config"}, call("action_save_config")).leaf = true entry({"admin", "status", "pingpacket", "restart_service"}, call("action_restart_service")).leaf = true end +function action_get_history() + local http = require("luci.http") + local range = trim(http.formvalue("range")) + local now = os.time() + local from_ts + local to_ts + local bucket_minutes + + if range ~= "day" and range ~= "week" and range ~= "month" and range ~= "custom" then + range = "day" + end + + if range == "custom" then + from_ts = tonumber(http.formvalue("from")) + to_ts = tonumber(http.formvalue("to")) + + if not from_ts or not to_ts then + write_json({ success = false, message = "自定义时间范围无效。" }) + return + end + + from_ts = math.floor(from_ts) + to_ts = math.floor(to_ts) + + if to_ts <= from_ts then + write_json({ success = false, message = "结束时间必须晚于开始时间。" }) + return + end + + if to_ts - from_ts > HISTORY_MAX_SPAN then + write_json({ success = false, message = "自定义时间范围最多支持 90 天。" }) + return + end + + if to_ts > now then + to_ts = now + end + + if to_ts <= from_ts then + write_json({ success = false, message = "所选时间范围内没有可展示的数据。" }) + return + end + + bucket_minutes = pick_bucket_minutes(to_ts - from_ts, 160) + else + to_ts = now + + if range == "week" then + from_ts = now - (7 * 86400) + bucket_minutes = 60 + elseif range == "month" then + from_ts = now - (30 * 86400) + bucket_minutes = 360 + else + from_ts = now - 86400 + bucket_minutes = 10 + end + end + + local bucket_seconds = bucket_minutes * 60 + + -- 将起点对齐到聚合桶边界,使图表刻度落在整点或整十分钟上 + from_ts = from_ts - (from_ts % bucket_seconds) + + local buckets, total = collect_history(from_ts, to_ts, bucket_minutes) + local span = to_ts - from_ts + local points = {} + local sum_ds, sum_dl, sum_fs, sum_fl = 0, 0, 0, 0 + local sum_dr, sum_fr = 0, 0 + local peak_d, peak_f = -1, -1 + + for index = 1, total do + local bucket = buckets[index] + local timestamp = from_ts + ((index - 1) * bucket_minutes * 60) + local d_rate, f_rate = -1, -1 + local d_avg, f_avg = -1, -1 + + if bucket.ds > 0 then + d_rate = round1(bucket.dl * 100 / bucket.ds) + sum_ds = sum_ds + bucket.ds + sum_dl = sum_dl + bucket.dl + + if bucket.dr > 0 and bucket.ds > bucket.dl then + d_avg = round1(bucket.dr / (bucket.ds - bucket.dl)) + sum_dr = sum_dr + bucket.dr + end + + if d_rate > peak_d then + peak_d = d_rate + end + end + + if bucket.fs > 0 then + f_rate = round1(bucket.fl * 100 / bucket.fs) + sum_fs = sum_fs + bucket.fs + sum_fl = sum_fl + bucket.fl + + if bucket.fr > 0 and bucket.fs > bucket.fl then + f_avg = round1(bucket.fr / (bucket.fs - bucket.fl)) + sum_fr = sum_fr + bucket.fr + end + + if f_rate > peak_f then + peak_f = f_rate + end + end + + points[index] = { + t = timestamp, + label = bucket_label(timestamp, bucket_minutes, span), + ds = bucket.ds, + dl = bucket.dl, + fs = bucket.fs, + fl = bucket.fl, + d_rate = d_rate, + f_rate = f_rate, + d_avg = d_avg, + f_avg = f_avg + } + end + + write_json({ + success = true, + range = range, + from = os.date("%Y-%m-%d %H:%M", from_ts), + to = os.date("%Y-%m-%d %H:%M", to_ts), + bucket_minutes = bucket_minutes, + points = points, + summary = { + domestic = { + samples = sum_ds, + loss = sum_dl, + rate = (sum_ds > 0) and round1(sum_dl * 100 / sum_ds) or -1, + avg = (sum_ds > sum_dl) and round1(sum_dr / (sum_ds - sum_dl)) or -1, + peak = peak_d + }, + foreign = { + samples = sum_fs, + loss = sum_fl, + rate = (sum_fs > 0) and round1(sum_fl * 100 / sum_fs) or -1, + avg = (sum_fs > sum_fl) and round1(sum_fr / (sum_fs - sum_fl)) or -1, + peak = peak_f + } + } + }) +end + function action_get_data() local uci = require("luci.model.uci").cursor() local sys = require("luci.sys") diff --git a/luci-app-pingpacket/luci-app-pingpacket/luasrc/view/pingpacket/logs.htm b/luci-app-pingpacket/luci-app-pingpacket/luasrc/view/pingpacket/logs.htm index 7a4b6183a..f4a4ab020 100644 --- a/luci-app-pingpacket/luci-app-pingpacket/luasrc/view/pingpacket/logs.htm +++ b/luci-app-pingpacket/luci-app-pingpacket/luasrc/view/pingpacket/logs.htm @@ -51,6 +51,7 @@ .pp-log-summary { min-width: 250px; padding: 16px 18px; + box-sizing: border-box; border-radius: 16px; background: rgba(255, 255, 255, 0.12); backdrop-filter: blur(6px); @@ -348,14 +349,18 @@ function updateView(payload) { var content = payload.content || ''; var output = $('logContent'); + var displayText = content || '当前暂无日志记录。'; + + if (output.textContent !== displayText) { + output.textContent = displayText; + if ($('autoRefresh').checked) { + output.scrollTop = output.scrollHeight; + } + } - output.textContent = content || '当前暂无日志记录。'; $('logUpdatedAt').textContent = payload.updated_at || '--'; $('logLineCount').textContent = String(countLines(content)); $('logSize').textContent = formatBytes(payload.size || 0); - if ($('autoRefresh').checked) { - output.scrollTop = output.scrollHeight; - } } function fetchLogs() { @@ -368,7 +373,8 @@ fetchInFlight = true; xhr = new XMLHttpRequest(); - xhr.open('GET', logsUrl, true); + xhr.open('GET', logsUrl + '?_=' + Date.now(), true); + xhr.setRequestHeader('Cache-Control', 'no-cache, no-store, must-revalidate'); xhr.onload = function() { var response = null; diff --git a/luci-app-pingpacket/luci-app-pingpacket/luasrc/view/pingpacket/status.htm b/luci-app-pingpacket/luci-app-pingpacket/luasrc/view/pingpacket/status.htm index a797395b2..7d594ae09 100644 --- a/luci-app-pingpacket/luci-app-pingpacket/luasrc/view/pingpacket/status.htm +++ b/luci-app-pingpacket/luci-app-pingpacket/luasrc/view/pingpacket/status.htm @@ -51,6 +51,7 @@ .pp-toggle-panel { min-width: 240px; padding: 16px 18px; + box-sizing: border-box; border-radius: 16px; background: rgba(255, 255, 255, 0.12); backdrop-filter: blur(6px); @@ -523,6 +524,246 @@ color: #d13d38; } +.pp-chart-panel { + margin-bottom: 18px; +} + +.pp-range-group { + display: inline-flex; + align-items: center; + gap: 4px; + padding: 4px; + border-radius: 13px; + background: #eef4fc; + border: 1px solid #dde8f6; + flex: 0 0 auto; +} + +.pp-range-btn { + min-width: 54px; + height: 32px; + padding: 0 12px; + border: none; + border-radius: 9px; + background: transparent; + color: #4a5f78; + font-size: 13px; + font-weight: 600; + white-space: nowrap; + cursor: pointer; + transition: background-color 0.18s ease, color 0.18s ease, box-shadow 0.18s ease; +} + +.pp-range-btn:hover { + background: #e2edfb; +} + +.pp-range-btn.active { + background: #fff; + color: #1256b4; + box-shadow: 0 4px 12px rgba(18, 86, 180, 0.16); +} + +.pp-custom-range { + display: flex; + align-items: flex-end; + gap: 12px; + flex-wrap: wrap; + margin-bottom: 14px; + padding: 14px 16px; + border-radius: 14px; + background: #f5f9ff; + border: 1px solid #e5eef8; +} + +.pp-custom-range.hidden { + display: none; +} + +.pp-custom-field { + display: flex; + flex-direction: column; + gap: 6px; + font-size: 12px; + color: #6d7d92; +} + +.pp-custom-field input { + height: 38px; + padding: 0 10px; + border: 1px solid #cedbeb; + border-radius: 10px; + background: #fff; + font-size: 13px; + color: #24364d; + font-family: inherit; +} + +.pp-custom-field input:focus { + outline: none; + border-color: #1d71e8; + box-shadow: 0 0 0 4px rgba(29, 113, 232, 0.12); +} + +.pp-custom-apply { + height: 38px; + padding: 0 18px; + border: none; + border-radius: 10px; + background: linear-gradient(135deg, #1d71e8, #1256b4); + color: #fff; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: transform 0.16s ease, box-shadow 0.16s ease; +} + +.pp-custom-apply:hover { + transform: translateY(-1px); + box-shadow: 0 8px 18px rgba(18, 86, 180, 0.2); +} + +.pp-chart-msg { + font-size: 12px; + line-height: 38px; + color: #d13d38; +} + +.pp-chart-summary { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); + gap: 12px; + margin-bottom: 16px; +} + +.pp-chart-chip { + padding: 12px 14px; + border-radius: 13px; + background: #f5f9ff; + border: 1px solid #e5eef8; + min-width: 0; +} + +.pp-chart-chip-label { + display: block; + margin-bottom: 6px; + font-size: 12px; + color: #70839b; +} + +.pp-chart-chip-value { + font-size: 17px; + font-weight: 700; + color: #1f3147; + font-variant-numeric: tabular-nums; + font-family: "JetBrains Mono", "Consolas", "Menlo", monospace; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.pp-chart-chip-value.domestic { + color: #1d71e8; +} + +.pp-chart-chip-value.foreign { + color: #ea580c; +} + +.pp-chart-chip-value.range-text { + font-size: 13px; + line-height: 1.45; + white-space: normal; + word-break: break-all; +} + +.pp-chart-wrap { + position: relative; + width: 100%; + border-radius: 14px; + background: linear-gradient(180deg, #fbfdff, #f7fbff); + border: 1px solid #e8f0fa; + padding: 6px 4px 2px; + box-sizing: border-box; + overflow: hidden; +} + +.pp-chart-svg { + display: block; + width: 100%; + height: auto; +} + +.pp-chart-tip { + position: absolute; + left: 0; + top: 0; + padding: 8px 11px; + border-radius: 10px; + background: rgba(16, 32, 51, 0.94); + color: #eaf3ff; + font-size: 12px; + line-height: 1.6; + white-space: nowrap; + pointer-events: none; + opacity: 0; + transform: translate(-50%, -100%); + transition: opacity 0.12s ease; + box-shadow: 0 12px 26px rgba(9, 22, 38, 0.28); + z-index: 5; +} + +.pp-chart-tip.visible { + opacity: 1; +} + +.pp-chart-empty { + position: absolute; + inset: 0; + display: flex; + align-items: center; + justify-content: center; + padding: 0 16px; + text-align: center; + font-size: 13px; + color: #8b9cb0; +} + +.pp-chart-empty.hidden { + display: none; +} + +.pp-legend { + display: flex; + align-items: center; + gap: 16px; + flex-wrap: wrap; + margin-top: 12px; + font-size: 12px; + color: #5c6f86; +} + +.pp-legend-item { + display: inline-flex; + align-items: center; + gap: 7px; +} + +.pp-legend-swatch { + width: 12px; + height: 12px; + border-radius: 4px; + flex: 0 0 auto; +} + +.pp-legend-swatch.domestic { + background: linear-gradient(135deg, #4d95f0, #1d71e8); +} + +.pp-legend-swatch.foreign { + background: linear-gradient(135deg, #fba05a, #ea580c); +} + @media (max-width: 860px) { .pp-hero, .pp-panel-head, @@ -531,6 +772,15 @@ align-items: stretch; } + .pp-range-group { + width: 100%; + justify-content: space-between; + } + + .pp-range-btn { + flex: 1 1 auto; + } + .pp-toggle-panel { width: 100%; min-width: 0; @@ -560,6 +810,19 @@ grid-template-columns: 1fr; } + .pp-chart-summary { + grid-template-columns: repeat(2, minmax(0, 1fr)); + } + + .pp-custom-field { + flex: 1 1 100%; + } + + .pp-custom-field input { + width: 100%; + box-sizing: border-box; + } + .pp-page { padding-left: 4px; padding-right: 4px; @@ -730,6 +993,65 @@ +
+
+
+

丢包与时间的关系

+
按分钟聚合探测结果,展示国内与国外目标各自的丢包率变化趋势。可切换日、周、月或自定义时间范围,鼠标悬浮可查看具体时段的样本数与丢包情况。
+
+
+ + + + +
+
+ + + +
+
+ 国内平均丢包率 +
--
+
+
+ 国外平均丢包率 +
--
+
+
+ 区间峰值丢包率 +
--
+
+
+ 统计区间 +
--
+
+
+ +
+ + +
+
+ +
+ 国内丢包率 + 国外丢包率 + +
+
+
@@ -795,6 +1117,7 @@ var apiBase = '<%=url("admin/status/pingpacket")%>'; var formToken = (window.L && L.env && L.env.token) ? L.env.token : '<%=token%>'; var dataUrl = apiBase + '/get_data'; + var historyUrl = apiBase + '/get_history'; var saveUrl = apiBase + '/save_config'; var restartUrl = apiBase + '/restart_service'; var pollTimer = null; @@ -1310,6 +1633,503 @@ ); }; + /* ---------------- 丢包与时间的关系图表 ---------------- */ + + var CHART_PAD = { left: 48, right: 18, top: 16, bottom: 28 }; + var CHART_COLORS = { domestic: '#1d71e8', foreign: '#ea580c' }; + var chartState = { + range: 'day', + payload: null, + loading: false, + layout: null, + resizeTimer: null + }; + + function pad2(value) { + return String(value).padStart(2, '0'); + } + + function formatDateTimeInput(date) { + return date.getFullYear() + '-' + pad2(date.getMonth() + 1) + '-' + pad2(date.getDate()) + + 'T' + pad2(date.getHours()) + ':' + pad2(date.getMinutes()); + } + + function setChartMessage(text) { + var node = $('chartMsg'); + if (node) { + node.textContent = text || ''; + } + } + + function formatRateText(value) { + if (typeof value !== 'number' || value < 0) { + return '--'; + } + + return value.toFixed(1) + '%'; + } + + function updateChartSummary(payload) { + var domestic = (payload.summary && payload.summary.domestic) || {}; + var foreign = (payload.summary && payload.summary.foreign) || {}; + var peak = Math.max( + typeof domestic.peak === 'number' ? domestic.peak : -1, + typeof foreign.peak === 'number' ? foreign.peak : -1 + ); + var bucket = Number(payload.bucket_minutes) || 0; + var bucketText = bucket >= 60 ? (bucket / 60) + ' 小时' : bucket + ' 分钟'; + var totalPoints = (payload.points || []).length; + + $('chartDomesticRate').textContent = formatRateText(domestic.rate); + $('chartForeignRate').textContent = formatRateText(foreign.rate); + $('chartPeak').textContent = peak < 0 ? '--' : peak.toFixed(1) + '%'; + + var fromText = String(payload.from || '--').replace(/^\d{4}-/, ''); + var toText = String(payload.to || '--').replace(/^\d{4}-/, ''); + var rangeNode = $('chartRange'); + + rangeNode.textContent = fromText + ' ~ ' + toText; + rangeNode.title = (payload.from || '--') + ' ~ ' + (payload.to || '--'); + $('chartBucketNote').textContent = '聚合粒度 ' + bucketText + ',共 ' + totalPoints + ' 个数据点'; + } + + function niceAxisMax(value) { + if (!(value > 0)) { + return 1; + } + + var steps = [0.5, 1, 2, 5, 10, 20, 25, 50, 100]; + + for (var i = 0; i < steps.length; i++) { + if (value <= steps[i]) { + return steps[i]; + } + } + + return 100; + } + + function formatAxisTick(value) { + if (value >= 10 || value % 1 === 0) { + return value.toFixed(0) + '%'; + } + + return value.toFixed(1) + '%'; + } + + function buildChartSeries(points, key, xOf, yOf, baseY) { + var segments = []; + var current = null; + + for (var i = 0; i < points.length; i++) { + var value = points[i][key]; + + if (typeof value !== 'number' || value < 0) { + if (current) { + segments.push(current); + current = null; + } + continue; + } + + if (!current) { + current = []; + } + + current.push({ x: xOf(i), y: yOf(value) }); + } + + if (current) { + segments.push(current); + } + + var line = ''; + var area = ''; + + for (var s = 0; s < segments.length; s++) { + var segment = segments[s]; + + for (var p = 0; p < segment.length; p++) { + line += (p === 0 ? 'M' : 'L') + segment[p].x.toFixed(1) + ' ' + segment[p].y.toFixed(1); + } + + area += 'M' + segment[0].x.toFixed(1) + ' ' + baseY.toFixed(1); + for (var q = 0; q < segment.length; q++) { + area += 'L' + segment[q].x.toFixed(1) + ' ' + segment[q].y.toFixed(1); + } + area += 'L' + segment[segment.length - 1].x.toFixed(1) + ' ' + baseY.toFixed(1) + 'Z'; + } + + return { line: line, area: area }; + } + + function renderChart() { + var payload = chartState.payload; + var wrap = $('chartWrap'); + var svg = $('chartSvg'); + var empty = $('chartEmpty'); + + if (!wrap || !svg || !empty) { + return; + } + + var points = (payload && payload.points) || []; + var hasData = false; + + for (var i = 0; i < points.length; i++) { + if (points[i].ds > 0 || points[i].fs > 0) { + hasData = true; + break; + } + } + + if (!hasData) { + svg.innerHTML = ''; + empty.className = 'pp-chart-empty'; + chartState.layout = null; + return; + } + + empty.className = 'pp-chart-empty hidden'; + + var width = Math.max(320, Math.round(wrap.clientWidth || 800)); + var height = width < 560 ? 220 : 300; + var pad = CHART_PAD; + var innerW = width - pad.left - pad.right; + var innerH = height - pad.top - pad.bottom; + var count = points.length; + var step = count > 1 ? innerW / (count - 1) : 0; + var baseY = pad.top + innerH; + + var maxRate = 0; + for (var j = 0; j < count; j++) { + if (points[j].d_rate > maxRate) { + maxRate = points[j].d_rate; + } + if (points[j].f_rate > maxRate) { + maxRate = points[j].f_rate; + } + } + + var yMax = niceAxisMax(maxRate); + + function xOf(index) { + return count > 1 ? pad.left + (index * step) : pad.left + (innerW / 2); + } + + function yOf(value) { + return pad.top + innerH - (Math.min(value, yMax) / yMax) * innerH; + } + + var parts = []; + + parts.push( + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + ); + + for (var g = 0; g <= 4; g++) { + var tickValue = (yMax * g) / 4; + var tickY = yOf(tickValue); + + parts.push(''); + parts.push('' + formatAxisTick(tickValue) + ''); + } + + var labelEvery = Math.max(1, Math.ceil(count / 7)); + for (var k = 0; k < count; k += labelEvery) { + parts.push('' + points[k].label + ''); + } + + if ((count - 1) % labelEvery !== 0) { + parts.push('' + points[count - 1].label + ''); + } + + var domestic = buildChartSeries(points, 'd_rate', xOf, yOf, baseY); + var foreign = buildChartSeries(points, 'f_rate', xOf, yOf, baseY); + + if (foreign.area) { + parts.push(''); + } + + if (domestic.area) { + parts.push(''); + } + + if (foreign.line) { + parts.push(''); + } + + if (domestic.line) { + parts.push(''); + } + + parts.push(''); + parts.push(''); + parts.push(''); + + svg.setAttribute('viewBox', '0 0 ' + width + ' ' + height); + svg.setAttribute('width', width); + svg.setAttribute('height', height); + svg.innerHTML = parts.join(''); + + chartState.layout = { + pad: pad, + width: width, + count: count, + step: step, + points: points, + xOf: xOf, + yOf: yOf + }; + } + + function hideChartTip() { + var tip = $('chartTip'); + var hoverLine = $('chartHoverLine'); + var domesticDot = $('chartHoverDomestic'); + var foreignDot = $('chartHoverForeign'); + + if (tip) { + tip.className = 'pp-chart-tip'; + } + if (hoverLine) { + hoverLine.setAttribute('opacity', '0'); + } + if (domesticDot) { + domesticDot.setAttribute('opacity', '0'); + } + if (foreignDot) { + foreignDot.setAttribute('opacity', '0'); + } + } + + function showChartTip(event) { + var layout = chartState.layout; + var wrap = $('chartWrap'); + var tip = $('chartTip'); + + if (!layout || !wrap || !tip) { + return; + } + + var rect = wrap.getBoundingClientRect(); + var offsetX = event.clientX - rect.left; + var offsetY = event.clientY - rect.top; + var index = layout.count > 1 ? Math.round((offsetX - layout.pad.left) / layout.step) : 0; + + if (index < 0) { + index = 0; + } + if (index > layout.count - 1) { + index = layout.count - 1; + } + + var point = layout.points[index]; + var pointX = layout.xOf(index); + var hoverLine = $('chartHoverLine'); + var domesticDot = $('chartHoverDomestic'); + var foreignDot = $('chartHoverForeign'); + + if (hoverLine) { + hoverLine.setAttribute('x1', pointX.toFixed(1)); + hoverLine.setAttribute('x2', pointX.toFixed(1)); + hoverLine.setAttribute('opacity', '1'); + } + + if (domesticDot) { + if (point.d_rate >= 0) { + domesticDot.setAttribute('cx', pointX.toFixed(1)); + domesticDot.setAttribute('cy', layout.yOf(point.d_rate).toFixed(1)); + domesticDot.setAttribute('opacity', '1'); + } else { + domesticDot.setAttribute('opacity', '0'); + } + } + + if (foreignDot) { + if (point.f_rate >= 0) { + foreignDot.setAttribute('cx', pointX.toFixed(1)); + foreignDot.setAttribute('cy', layout.yOf(point.f_rate).toFixed(1)); + foreignDot.setAttribute('opacity', '1'); + } else { + foreignDot.setAttribute('opacity', '0'); + } + } + + tip.innerHTML = + '
' + point.label + '
' + + '
国内 ' + (point.d_rate >= 0 ? point.d_rate.toFixed(1) + '%' : '无数据') + + ' · 样本 ' + point.ds + ' · 丢包 ' + point.dl + '
' + + '
国外 ' + (point.f_rate >= 0 ? point.f_rate.toFixed(1) + '%' : '无数据') + + ' · 样本 ' + point.fs + ' · 丢包 ' + point.fl + '
'; + + var tipLeft = Math.min(Math.max(pointX, 80), layout.width - 80); + var tipTop = Math.max(offsetY - 10, 46); + + tip.style.left = tipLeft + 'px'; + tip.style.top = tipTop + 'px'; + tip.className = 'pp-chart-tip visible'; + } + + function fetchHistory() { + if (chartState.loading) { + return; + } + + var url = historyUrl + '?range=' + encodeURIComponent(chartState.range) + '&_=' + Date.now(); + + if (chartState.range === 'custom') { + var fromValue = $('chartFrom').value; + var toValue = $('chartTo').value; + var fromTime = fromValue ? new Date(fromValue).getTime() : NaN; + var toTime = toValue ? new Date(toValue).getTime() : NaN; + + if (!isFinite(fromTime) || !isFinite(toTime)) { + setChartMessage('请选择完整的开始时间和结束时间。'); + return; + } + + if (toTime <= fromTime) { + setChartMessage('结束时间必须晚于开始时间。'); + return; + } + + if (toTime - fromTime > 90 * 24 * 3600 * 1000) { + setChartMessage('自定义时间范围最多支持 90 天。'); + return; + } + + url += '&from=' + Math.floor(fromTime / 1000) + '&to=' + Math.floor(toTime / 1000); + } + + chartState.loading = true; + setChartMessage(''); + + var xhr = new XMLHttpRequest(); + xhr.open('GET', url, true); + xhr.setRequestHeader('Cache-Control', 'no-cache, no-store, must-revalidate'); + xhr.onload = function() { + var response = null; + + if (xhr.status === 200) { + try { + response = JSON.parse(xhr.responseText); + } catch (e) {} + } + + chartState.loading = false; + + if (response && response.success) { + chartState.payload = response; + updateChartSummary(response); + renderChart(); + } else { + setChartMessage((response && response.message) || '历史数据加载失败,请稍后重试。'); + } + }; + xhr.onerror = function() { + chartState.loading = false; + setChartMessage('历史数据加载失败,请检查网络后重试。'); + }; + xhr.send(); + } + + function setChartRange(range) { + chartState.range = range; + + var buttons = $('rangeGroup').getElementsByTagName('button'); + + for (var i = 0; i < buttons.length; i++) { + buttons[i].className = buttons[i].getAttribute('data-range') === range ? 'pp-range-btn active' : 'pp-range-btn'; + } + + if (range === 'custom') { + $('customRange').className = 'pp-custom-range'; + + if (!$('chartFrom').value || !$('chartTo').value) { + var now = new Date(); + $('chartTo').value = formatDateTimeInput(now); + $('chartFrom').value = formatDateTimeInput(new Date(now.getTime() - 24 * 3600 * 1000)); + } + } else { + $('customRange').className = 'pp-custom-range hidden'; + } + + setChartMessage(''); + fetchHistory(); + } + + function initChart() { + var buttons = $('rangeGroup').getElementsByTagName('button'); + + for (var i = 0; i < buttons.length; i++) { + buttons[i].addEventListener('click', function() { + setChartRange(this.getAttribute('data-range')); + }); + } + + $('chartApply').addEventListener('click', function() { + if (chartState.range !== 'custom') { + setChartRange('custom'); + return; + } + + fetchHistory(); + }); + + $('chartWrap').addEventListener('mousemove', showChartTip); + $('chartWrap').addEventListener('mouseleave', hideChartTip); + + window.addEventListener('resize', function() { + if (chartState.resizeTimer) { + clearTimeout(chartState.resizeTimer); + } + + chartState.resizeTimer = setTimeout(function() { + if (chartState.payload) { + renderChart(); + } + }, 180); + }); + + var chartTick = 0; + + setInterval(function() { + chartTick += 1; + + if (document.hidden || chartState.loading) { + return; + } + + // 日视图每分钟刷新,周/月视图数据变化慢,每 5 分钟刷新一次以降低路由器压力 + if (chartTick % (chartState.range === 'day' ? 1 : 5) !== 0) { + return; + } + + fetchHistory(); + }, 60000); + + fetchHistory(); + } + $('domesticInput').addEventListener('input', function() { inputDirty.domestic = true; }); @@ -1369,6 +2189,7 @@ }); fetchData(); + initChart(); })(); diff --git a/luci-app-pingpacket/luci-app-pingpacket/root/usr/bin/pingpacket.sh b/luci-app-pingpacket/luci-app-pingpacket/root/usr/bin/pingpacket.sh index 8c797d99b..7efba67e3 100644 --- a/luci-app-pingpacket/luci-app-pingpacket/root/usr/bin/pingpacket.sh +++ b/luci-app-pingpacket/luci-app-pingpacket/root/usr/bin/pingpacket.sh @@ -6,7 +6,14 @@ LOG_FILE="/tmp/pingpacket.log" LOG_MAX_LINES=500 RUN_DIR="/var/run/pingpacket" START_TIME_FILE="$RUN_DIR/start_time" +HIST_DIR="/etc/pingpacket/history" +HIST_RETENTION_DAYS=35 + child_pids="" +probe_seq=0 +log_line_count=0 +current_minute="" + domestic_fail_count=0 foreign_fail_count=0 domestic_fault_open=0 @@ -25,15 +32,25 @@ domestic_max_rtt="" foreign_max_rtt="" domestic_last_probe_at=0 foreign_last_probe_at=0 -domestic_last_fault_probe_at=0 -foreign_last_fault_probe_at=0 -domestic_last_stats_probe_at=0 -foreign_last_stats_probe_at=0 +domestic_last_fault_seq=0 +foreign_last_fault_seq=0 +domestic_last_stats_seq=0 +foreign_last_stats_seq=0 + +hist_bucket_key="" +hist_flush_count=0 +hist_d_samples=0 +hist_d_loss=0 +hist_d_rtt_sum="0" +hist_f_samples=0 +hist_f_loss=0 +hist_f_rtt_sum="0" log_rotate() { [ -f "$LOG_FILE" ] || return 0 tail -n "$LOG_MAX_LINES" "$LOG_FILE" > "${LOG_FILE}.tmp" 2>/dev/null && \ mv -f "${LOG_FILE}.tmp" "$LOG_FILE" + log_line_count="$LOG_MAX_LINES" } log_event() { @@ -42,13 +59,95 @@ log_event() { local message="$3" local timestamp + # 日志被页面手动清除后,行数计数需要重新开始 + if [ ! -f "$LOG_FILE" ]; then + log_line_count=0 + fi + timestamp="$(date '+%Y-%m-%d %H:%M:%S')" if [ -n "$scope" ]; then printf '[%s] [%s] [%s] %s\n' "$timestamp" "$event_type" "$scope" "$message" >> "$LOG_FILE" else printf '[%s] [%s] %s\n' "$timestamp" "$event_type" "$message" >> "$LOG_FILE" fi - log_rotate + + log_line_count=$((log_line_count + 1)) + if [ "$log_line_count" -gt "$LOG_MAX_LINES" ]; then + log_rotate + fi +} + +prune_history() { + [ -d "$HIST_DIR" ] || return 0 + + find "$HIST_DIR" -type f -name '*.tsv' -mtime +"$HIST_RETENTION_DAYS" 2>/dev/null | while IFS= read -r stale_file; do + rm -f "$stale_file" 2>/dev/null + done +} + +flush_history_bucket() { + [ -n "$hist_bucket_key" ] || return 0 + + if [ "$hist_d_samples" -le 0 ] && [ "$hist_f_samples" -le 0 ]; then + hist_bucket_key="" + return 0 + fi + + local bucket_day="${hist_bucket_key% *}" + local bucket_clock="${hist_bucket_key#* }" + + mkdir -p "$HIST_DIR" 2>/dev/null + printf '%s\t%d\t%d\t%s\t%d\t%d\t%s\n' \ + "$bucket_clock" \ + "$hist_d_samples" "$hist_d_loss" "$hist_d_rtt_sum" \ + "$hist_f_samples" "$hist_f_loss" "$hist_f_rtt_sum" \ + >> "$HIST_DIR/${bucket_day}.tsv" 2>/dev/null + + hist_bucket_key="" + hist_d_samples=0 + hist_d_loss=0 + hist_d_rtt_sum="0" + hist_f_samples=0 + hist_f_loss=0 + hist_f_rtt_sum="0" + + hist_flush_count=$((hist_flush_count + 1)) + if [ "$hist_flush_count" -ge 60 ]; then + hist_flush_count=0 + prune_history + fi +} + +accumulate_history() { + local name="$1" + local success="$2" + local rtt="${3:-0}" + + [ -n "$current_minute" ] || return 0 + + if [ "$hist_bucket_key" != "$current_minute" ]; then + flush_history_bucket + hist_bucket_key="$current_minute" + fi + + case "$name" in + domestic) + hist_d_samples=$((hist_d_samples + 1)) + if [ "$success" = "1" ]; then + hist_d_rtt_sum="$(awk -v sum="$hist_d_rtt_sum" -v value="$rtt" 'BEGIN { printf "%.3f", (sum + 0) + (value + 0) }')" + else + hist_d_loss=$((hist_d_loss + 1)) + fi + ;; + foreign) + hist_f_samples=$((hist_f_samples + 1)) + if [ "$success" = "1" ]; then + hist_f_rtt_sum="$(awk -v sum="$hist_f_rtt_sum" -v value="$rtt" 'BEGIN { printf "%.3f", (sum + 0) + (value + 0) }')" + else + hist_f_loss=$((hist_f_loss + 1)) + fi + ;; + esac } kill_children() { @@ -59,6 +158,7 @@ kill_children() { } cleanup() { + flush_history_bucket kill_children exit 0 } @@ -68,17 +168,26 @@ trap cleanup INT TERM mkdir -p "$RUN_DIR" date '+%Y-%m-%d %H:%M:%S' > "$START_TIME_FILE" +if [ -f "$LOG_FILE" ]; then + log_line_count="$(wc -l < "$LOG_FILE" 2>/dev/null | tr -d ' ')" + case "$log_line_count" in + ""|*[!0-9]*) log_line_count=0 ;; + esac +fi + write_result_file() { local path="$1" local success="$2" local rtt="$3" local detail="$4" local probe_at="$5" + local seq="$6" [ -n "$probe_at" ] || probe_at="$(date '+%s' 2>/dev/null || echo 0)" + [ -n "$seq" ] || seq="0" mkdir -p "$(dirname "$path")" - printf '%s\n%s\n%s\n%s\n' "$success" "$rtt" "$detail" "$probe_at" > "$path" + printf '%s\n%s\n%s\n%s\n%s\n' "$success" "$rtt" "$detail" "$probe_at" "$seq" > "$path" } normalize_foreign_url() { @@ -264,6 +373,7 @@ resolve_target_ip() { do_ping() { local target="$1" local name="$2" + local seq="$3" local result_file="$RUN_DIR/${name}_last_result" local ping_target local result @@ -273,9 +383,9 @@ do_ping() { result="$(ping -n -c 1 -W 2 "$ping_target" 2>/dev/null)" if echo "$result" | grep -q "bytes from"; then rtt="$(echo "$result" | sed -n 's/.*time=\([0-9.]*\).*/\1/p')" - write_result_file "$result_file" "1" "${rtt:-0}" "" + write_result_file "$result_file" "1" "${rtt:-0}" "" "" "$seq" else - write_result_file "$result_file" "0" "" "ping 无响应" + write_result_file "$result_file" "0" "" "ping 无响应" "" "$seq" fi } @@ -285,6 +395,7 @@ do_proxy_curl() { local proxy_host="${3:-127.0.0.1}" local proxy_port="$4" local name="$5" + local seq="$6" local result_file="$RUN_DIR/${name}_last_result" local error_file="$RUN_DIR/${name}_curl_error" local url @@ -297,12 +408,12 @@ do_proxy_curl() { local rc if ! command -v curl >/dev/null 2>&1; then - write_result_file "$result_file" "0" "" "系统未安装 curl" + write_result_file "$result_file" "0" "" "系统未安装 curl" "" "$seq" return 0 fi if [ -z "$proxy_port" ]; then - write_result_file "$result_file" "0" "" "代理端口未配置" + write_result_file "$result_file" "0" "" "代理端口未配置" "" "$seq" return 0 fi @@ -323,11 +434,11 @@ do_proxy_curl() { if [ "$rc" -eq 0 ] && [ -n "$http_code" ] && [ -n "$time_pretransfer" ] && { [ "$http_code" = "200" ] || [ "$http_code" = "204" ]; }; then rtt_ms="$(awk -v sec="$time_pretransfer" 'BEGIN { printf "%.1f", (sec + 0) * 1000 }')" - write_result_file "$result_file" "1" "$rtt_ms" "curl 连接探测成功,HTTP ${http_code}" + write_result_file "$result_file" "1" "$rtt_ms" "curl 连接探测成功,HTTP ${http_code}" "" "$seq" else detail="$(sed -n '1p' "$error_file" 2>/dev/null)" [ -n "$detail" ] || detail="curl 退出码 ${rc},HTTP ${http_code:-000}" - write_result_file "$result_file" "0" "" "$detail" + write_result_file "$result_file" "0" "" "$detail" "" "$seq" fi rm -f "$error_file" @@ -369,46 +480,46 @@ set_target_state() { esac } -get_processed_probe_at() { +get_processed_seq() { local name="$1" local kind="$2" case "${name}:${kind}" in domestic:fault) - processed_probe_at="$domestic_last_fault_probe_at" + processed_seq="$domestic_last_fault_seq" ;; foreign:fault) - processed_probe_at="$foreign_last_fault_probe_at" + processed_seq="$foreign_last_fault_seq" ;; domestic:stats) - processed_probe_at="$domestic_last_stats_probe_at" + processed_seq="$domestic_last_stats_seq" ;; foreign:stats) - processed_probe_at="$foreign_last_stats_probe_at" + processed_seq="$foreign_last_stats_seq" ;; *) - processed_probe_at=0 + processed_seq=0 ;; esac } -set_processed_probe_at() { +set_processed_seq() { local name="$1" local kind="$2" local value="${3:-0}" case "${name}:${kind}" in domestic:fault) - domestic_last_fault_probe_at="$value" + domestic_last_fault_seq="$value" ;; foreign:fault) - foreign_last_fault_probe_at="$value" + foreign_last_fault_seq="$value" ;; domestic:stats) - domestic_last_stats_probe_at="$value" + domestic_last_stats_seq="$value" ;; foreign:stats) - foreign_last_stats_probe_at="$value" + foreign_last_stats_seq="$value" ;; esac } @@ -418,8 +529,8 @@ reset_target_state() { rm -f "$RUN_DIR/${name}_last_result" set_target_state "$name" 0 0 - set_processed_probe_at "$name" "fault" 0 - set_processed_probe_at "$name" "stats" 0 + set_processed_seq "$name" "fault" 0 + set_processed_seq "$name" "stats" 0 } update_target_faults() { @@ -430,7 +541,7 @@ update_target_faults() { local success="0" local rtt="" local detail="" - local probe_at="" + local seq="" [ -n "$target" ] || { reset_target_state "$name" @@ -443,11 +554,13 @@ update_target_faults() { success="$(sed -n '1p' "$result_file" 2>/dev/null)" rtt="$(sed -n '2p' "$result_file" 2>/dev/null)" detail="$(sed -n '3p' "$result_file" 2>/dev/null)" - probe_at="$(sed -n '4p' "$result_file" 2>/dev/null)" + seq="$(sed -n '5p' "$result_file" 2>/dev/null)" fi - get_processed_probe_at "$name" "fault" - if [ -n "$probe_at" ] && [ "$probe_at" = "$processed_probe_at" ]; then + [ -n "$seq" ] || return 0 + + get_processed_seq "$name" "fault" + if [ "$seq" = "$processed_seq" ]; then return 0 fi @@ -457,7 +570,7 @@ update_target_faults() { fi set_target_state "$name" 0 0 - set_processed_probe_at "$name" "fault" "${probe_at:-0}" + set_processed_seq "$name" "fault" "$seq" return 0 fi @@ -470,7 +583,7 @@ update_target_faults() { fault_open=1 set_target_state "$name" "$fail_count" "$fault_open" - set_processed_probe_at "$name" "fault" "${probe_at:-0}" + set_processed_seq "$name" "fault" "$seq" } calc_stats() { @@ -525,7 +638,7 @@ update_cumulative_stats() { local result_file="$RUN_DIR/${name}_last_result" local success="0" local rtt="" - local probe_at="" + local seq="" local total_samples=0 local success_count=0 local loss_count=0 @@ -535,6 +648,19 @@ update_cumulative_stats() { [ -n "$target" ] || return 0 + if [ -f "$result_file" ]; then + success="$(sed -n '1p' "$result_file" 2>/dev/null)" + rtt="$(sed -n '2p' "$result_file" 2>/dev/null)" + seq="$(sed -n '5p' "$result_file" 2>/dev/null)" + fi + + [ -n "$seq" ] || return 0 + + get_processed_seq "$name" "stats" + if [ "$seq" = "$processed_seq" ]; then + return 0 + fi + case "$name" in domestic) total_samples="$domestic_total_samples" @@ -556,17 +682,6 @@ update_cumulative_stats() { total_samples=$((total_samples + 1)) - if [ -f "$result_file" ]; then - success="$(sed -n '1p' "$result_file" 2>/dev/null)" - rtt="$(sed -n '2p' "$result_file" 2>/dev/null)" - probe_at="$(sed -n '4p' "$result_file" 2>/dev/null)" - fi - - get_processed_probe_at "$name" "stats" - if [ -n "$probe_at" ] && [ "$probe_at" = "$processed_probe_at" ]; then - return 0 - fi - if [ "$success" = "1" ]; then rtt="${rtt:-0}" success_count=$((success_count + 1)) @@ -606,7 +721,13 @@ update_cumulative_stats() { ;; esac - set_processed_probe_at "$name" "stats" "${probe_at:-0}" + set_processed_seq "$name" "stats" "$seq" + + if [ "$success" = "1" ]; then + accumulate_history "$name" "1" "${rtt:-0}" + else + accumulate_history "$name" "0" "" + fi } while true; do @@ -614,6 +735,7 @@ while true; do START_TIME="$(cat "$START_TIME_FILE" 2>/dev/null || echo "")" UPDATED_AT="$(date '+%Y-%m-%d %H:%M:%S')" NOW_TS="$(date '+%s' 2>/dev/null || echo 0)" + current_minute="$(date '+%Y-%m-%d %H:%M')" DOMESTIC_TARGET="" FOREIGN_TARGET="" FOREIGN_PROXY_TYPE="socks5h" @@ -642,7 +764,8 @@ while true; do child_pids="" if [ -n "$DOMESTIC_TARGET" ]; then if should_probe_now "$domestic_last_probe_at" "$DOMESTIC_INTERVAL" "$NOW_TS"; then - do_ping "$DOMESTIC_TARGET" "domestic" & + probe_seq=$((probe_seq + 1)) + do_ping "$DOMESTIC_TARGET" "domestic" "$probe_seq" & child_pids="$!" domestic_last_probe_at="$NOW_TS" fi @@ -653,7 +776,8 @@ while true; do if [ -n "$FOREIGN_TARGET" ]; then if should_probe_now "$foreign_last_probe_at" "$FOREIGN_INTERVAL" "$NOW_TS"; then - do_proxy_curl "$FOREIGN_TARGET" "$FOREIGN_PROXY_TYPE" "$FOREIGN_PROXY_HOST" "$FOREIGN_PROXY_PORT" "foreign" & + probe_seq=$((probe_seq + 1)) + do_proxy_curl "$FOREIGN_TARGET" "$FOREIGN_PROXY_TYPE" "$FOREIGN_PROXY_HOST" "$FOREIGN_PROXY_PORT" "foreign" "$probe_seq" & child_pids="${child_pids:+$child_pids }$!" foreign_last_probe_at="$NOW_TS" fi @@ -679,4 +803,3 @@ while true; do sleep 1 done - diff --git a/luci-app-vantage/Makefile b/luci-app-vantage/Makefile index a064bdcff..43df096b0 100644 --- a/luci-app-vantage/Makefile +++ b/luci-app-vantage/Makefile @@ -10,8 +10,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-vantage -PKG_VERSION:=1.0.12 -PKG_RELEASE:=19 +PKG_VERSION:=1.0.13 +PKG_RELEASE:=20 PKG_LICENSE:=GPL-3.0-or-later LUCI_TITLE:=Vantage dashboard 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 09b53773b..fef3cb15d 100644 --- a/luci-app-vantage/htdocs/luci-static/resources/vantage/model.js +++ b/luci-app-vantage/htdocs/luci-static/resources/vantage/model.js @@ -180,6 +180,33 @@ return baseclass.extend({ return { mbps: +m[1], duplex: m[2] === 'H' ? 'half' : (m[2] === 'F' ? 'full' : null) }; }, + /* The switch ports behind a port that is a VLAN on a swconfig switch + (eth1.1): `map` is luci.vantage wired's switches, `states` LuCI's + getSwconfigPortState replies by switch name. { name, vlan, ports: + [ { num, label, link, speed } ], up } or null; link and speed stay + null while the switch has not answered. */ + switchOf: function(map, states, port) { + var sw = typeof port === 'string' && own(map, port) ? obj(map[port]) : null; + if (!sw || typeof sw.name !== 'string' || !/^[A-Za-z0-9_.-]{1,32}$/.test(sw.name) || !finite(sw.vlan)) return null; + var state = own(states, sw.name) ? states[sw.name] : null, byNum = Object.create(null); + arr(state).slice(0, 64).forEach(function(p) { p = obj(p); if (finite(p.port)) byNum[p.port] = p; }); + var known = Array.isArray(state) && state.length > 0, up = 0; + var ports = arr(sw.ports).slice(0, 64).map(obj).filter(function(p) { return finite(p.num) && p.num >= 0 && p.num < 64; }).map(function(p) { + var s = byNum[p.num], role = typeof p.role === 'string' && /^[a-z0-9]{1,16}$/.test(p.role) ? p.role.toUpperCase() : null; + var link = known ? !!(s && s.link === true) : null; + if (link) up++; + return { + num: p.num, + /* "LAN 2" where board.json numbers the ports by role, else + swconfig's own number: four "LAN" would tell them apart */ + label: role && finite(p.index) ? role + ' ' + p.index : _('Port %d').format(p.num), + link: link, + speed: link && finite(s.speed) && s.speed > 0 ? { mbps: s.speed, duplex: s.duplex === true ? 'full' : s.duplex === false ? 'half' : null } : null + }; + }); + return { name: sw.name, vlan: sw.vlan, ports: ports, up: known ? up : null }; + }, + speedLabel: function(sp) { if (!sp) return fmt.DASH; var v = sp.mbps >= 1000 ? _('%s Gbit/s').format(sp.mbps / 1000) : _('%s Mbit/s').format(sp.mbps); @@ -587,6 +614,10 @@ return baseclass.extend({ wiredMacs.forEach(function(mac) { var p = fdb[mac].port; perPort[p] = (perPort[p] || 0) + 1; }); var wired = wiredMacs.map(function(mac) { var h = fdb[mac], d = devs[h.port], hint = hintOf(mac), ips = self.hintAddrs(hint, wiredSubnets(mac)); + /* behind a switch VLAN the port's own link is the CPU's: the + host's is a switch port's, known when only one has a link */ + var sw = self.switchOf(raw.switches, raw.switchState, h.port); + var lit = sw && sw.up === 1 ? sw.ports.filter(function(p) { return p.link; })[0] : null; var alias = raw.aliases && raw.aliases[mac]; var vendor = typeof raw.vendor === 'function' ? raw.vendor(names.ouiKey(mac)) : null; var nm = names.resolve({ mac: mac, alias: alias, ips: ips, rdns: raw.rdns, mdns: mdns, hint: hint, wps: null, vendor: vendor }); @@ -610,8 +641,10 @@ return baseclass.extend({ seen: h.seen, peers: perPort[h.port], shared: perPort[h.port] > 1, - speed: d ? self.parseSpeed(d.speed) : null, - carrier: d ? d.carrier !== false : null, + speed: sw ? (lit ? lit.speed : null) : d ? self.parseSpeed(d.speed) : null, + carrier: sw && sw.up != null ? sw.up > 0 : d ? d.carrier !== false : null, + switch: sw, + switchPort: lit ? lit.label : null, gateway: mac === gwMac }; }); 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 dde80f3ca..684d2313e 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 @@ -24,6 +24,7 @@ var WINDOW_MS = 5 * 60 * 1000; /* throughput history shown */ var HIST_MAX = 90; var GONE_KEEP_MS = 5 * 60 * 1000; /* disconnected stations stay listed */ var TALKERS = 3; /* top talkers shown; the tile keeps room for all */ +var SWITCH_MS = 30 * 1000; /* LuCI runs swconfig for each switch's link state: at most this often */ var STORE_KEY = 'vantage.hist.v1'; var SVGNS = 'http://www.w3.org/2000/svg'; var HOSTAPD_OBJ = /^[A-Za-z0-9_.-]{1,64}$/; @@ -37,8 +38,13 @@ var callDevs = rpc.declare({ object: 'network.device', method: 'status', expect: without keys or RADIUS secrets, and the validated alias write */ var callWifi = rpc.declare({ object: 'luci.vantage', method: 'wireless', expect: { '': {} } }); var callThermal = rpc.declare({ object: 'luci.vantage', method: 'thermal', expect: { zones: [] } }); -/* { hosts, crowded }: crowded when a bridge holds too many entries to list */ +/* { 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: { '': {} } }); +/* 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 */ +var callSwitchPorts = rpc.declare({ object: 'luci', method: 'getSwconfigPortState', params: [ 'switch' ], expect: { '': {} }, reject: true }); var callHints = rpc.declare({ object: 'luci-rpc', method: 'getHostHints', expect: { '': {} } }); var callIwInfo = rpc.declare({ object: 'iwinfo', method: 'info', params: [ 'device' ], expect: { '': {} } }); var callAssoc = rpc.declare({ object: 'iwinfo', method: 'assoclist', params: [ 'device' ], expect: { results: [] } }); @@ -327,6 +333,17 @@ function rateLine(down, up, cls) { ]); } +/* a switch VLAN's ports, a line each: "LAN 2 · 2.5 Gbit/s" (model.switchOf) */ +function switchLines(sw) { + return sw.ports.map(function(p) { + return p.label + ' · ' + (p.link === null ? fmt.DASH : !p.link ? _('down') : p.speed ? fmt.phyRate(p.speed.mbps * 1000) : _('link up')); + }); +} + +function switchNote(sw) { + return _('Switch ports of VLAN %d on %s: %s').format(sw.vlan, sw.name, switchLines(sw).join(', ')); +} + function kv(label, value, mono) { return E('div', { 'class': 'vt-kv' }, [ E('dt', {}, [ label ]), @@ -496,7 +513,7 @@ return view.extend({ /* one poll's worth of raw replies; missing pieces degrade to {} */ fetch: function() { - var started = Date.now(); + var started = Date.now(), self = this; return Promise.all([ L.resolveDefault(callInfo(), {}), L.resolveDefault(callRead('/proc/stat'), ''), @@ -521,6 +538,26 @@ return view.extend({ and SSID for each network (luci.vantage wireless carries configuration only) */ var per = []; + /* the link state of a switch with hosts behind it, every + SWITCH_MS: each answer runs swconfig on the device. Asked + on the side, so a slow switch holds up no poll; the answer + shows from the next one */ + var switches = (wiredReply.switches && typeof wiredReply.switches === 'object' && !Array.isArray(wiredReply.switches)) ? wiredReply.switches : {}; + var swState = self.swState || (self.swState = Object.create(null)); + var hostPorts = (Array.isArray(wiredReply.hosts) ? wiredReply.hosts : []).map(function(h) { return h && h.port; }); + var due = [], asked = Date.now(); + Object.keys(switches).forEach(function(dev) { + var n = switches[dev] && switches[dev].name; + if (typeof n === 'string' && /^[A-Za-z0-9_.-]{1,32}$/.test(n) && hostPorts.indexOf(dev) >= 0 && due.indexOf(n) < 0 && + !(swState[n] && asked - swState[n].at < SWITCH_MS)) due.push(n); + }); + due.slice(0, 4).forEach(function(n) { + swState[n] = { at: asked, ports: swState[n] ? swState[n].ports : null }; + L.resolveDefault(callSwitchPorts(n), null).then(function(v) { + /* no ports (an error, an unknown switch): not known, not down */ + swState[n] = { at: asked, ports: v && Array.isArray(v.result) && v.result.length ? v.result : null }; + }); + }); ifnames.forEach(function(ifn) { per.push(L.resolveDefault(callAssoc(ifn), []).then(function(v) { return [ 'assoc', ifn, v ]; })); per.push(hostapd(ifn, 'get_clients').then(function(v) { return [ 'hapd', ifn, v ]; })); @@ -535,8 +572,10 @@ return view.extend({ else if (p[0] === 'hapdStatus') hapdStatus[p[1]] = p[2]; else iwinfo[p[1]] = p[2]; }); + var switchState = Object.create(null); + 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, + fdb: Array.isArray(wiredReply.hosts) ? wiredReply.hosts : [], fdbCrowded: wiredReply.crowded === true, switches: switches, switchState: switchState, assoc: assoc, hapd: hapd, hapdStatus: hapdStatus, iwinfo: iwinfo, at: Date.now(), started: started }; }); }); @@ -611,6 +650,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, aliases: this.aliases, rdns: st.rdns, mdns: st.mdns, vendor: st.oui ? function(k) { return k ? st.oui.lookup(k) : null; } : null }); @@ -766,6 +806,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, aliases: this.aliases, rdns: st.rdns, mdns: st.mdns, vendor: st.oui ? function(k) { return k ? st.oui.lookup(k) : null; } : null }); @@ -1483,9 +1524,9 @@ return view.extend({ ]); var wcol = E('div', { 'class': 'vt-branch-ssids' }); ports.forEach(function(p) { - var sn = { id: 'port:' + p, port: p, name: E('span'), count: span('vt-tn') }; + var sn = { id: 'port:' + p, port: p, name: E('span'), count: span('vt-tn'), rate: span('vt-node-sub vt-tn') }; sn.el = E('button', { 'type': 'button', 'class': 'vt-node vt-node-ssid', 'click': function() { self.showWired(p); } }, [ - E('span', { 'class': 'vt-node-body' }, [ E('span', { 'class': 'vt-node-title vt-ssid-name' }, [ sn.name ]), E('span', { 'class': 'vt-node-sub' }, [ sn.count ]) ]) + E('span', { 'class': 'vt-node-body' }, [ E('span', { 'class': 'vt-node-title vt-ssid-name' }, [ sn.name ]), E('span', { 'class': 'vt-node-sub' }, [ sn.count ]), sn.rate ]) ]); wb.ssids.push(sn); wcol.appendChild(sn.el); @@ -1598,17 +1639,21 @@ return view.extend({ }, /* the Wired branch of the path: its hosts, and per port the one host - with its link speed or how many share the port */ + with its link speed or how many share the port, and the port's + traffic: all of its hosts' together, never split between them */ updateWiredBranch: function(b) { var st = this.st, hosts = this.m.wiredHosts || [], n = 0, rx = 0, tx = 0, seen = false; b.ssids.forEach(function(sn) { var on = hosts.filter(function(c) { return c.port === sn.port; }), r = st.devRates[sn.port], one = on.length === 1 ? on[0] : null; + var sw = on.length ? on[0].switch : null; n += on.length; if (r) { rx += r.rx; tx += r.tx; seen = true; } setClass(sn.el, 'vt-node vt-node-ssid' + (on.length ? '' : ' vt-node-idle')); - setTitle(sn.el, _('Show the devices on %s').format(sn.port)); + setTitle(sn.el, _('Show the devices on %s').format(sn.port) + (r ? '\n' + _('Port total: %s').format('↓ ' + fmt.bits(r.tx) + ' · ↑ ' + fmt.bits(r.rx)) : '') + + (sw ? '\n' + switchNote(sw) : '')); txt(sn.name, one ? sn.port + ' · ' + one.name : sn.port); txt(sn.count, one ? (one.speed ? fmt.phyRate(one.speed.mbps * 1000) : fmt.DASH) : on.length === 1 ? _('1 device') : _('%d devices').format(on.length)); + txt(sn.rate, r ? '↓ ' + fmt.bitsShort(r.tx) + ' ↑ ' + fmt.bitsShort(r.rx) : fmt.DASH); sn.active = !!(r && r.rx + r.tx > 50e3); }); txt(b.title, n === 1 ? _('1 device') : _('%d devices').format(n)); @@ -2561,9 +2606,11 @@ return view.extend({ var speed = c.speed ? fmt.phyRate(c.speed.mbps * 1000) : fmt.DASH; var link = E('td', { 'class': 'vt-td-link', 'data-title': _('Link', 'vantage') }, [ E('div', { 'class': 'vt-phy vt-tn' }, [ E('b', { 'class': c.carrier === false ? 'vt-t-warn' : '' }, [ c.carrier === false ? _('down') : c.shared ? _('Shared port') : speed ]) ]), - E('div', { 'class': 'vt-phy vt-phy-up vt-tn' }, [ c.shared ? _('%s · %d devices').format(c.port, c.peers) : c.port ]) + E('div', { 'class': 'vt-phy vt-phy-up vt-tn' }, [ c.shared ? _('%s · %d devices').format(c.port, c.peers) : c.switchPort ? c.port + ' · ' + c.switchPort : c.port ]) ]); - link.setAttribute('title', c.shared ? _('%s is shared by %d devices (a switch or another access point behind it); its %s link is not theirs').format(c.port, c.peers, speed) : _('Port %s').format(c.port)); + link.setAttribute('title', (c.shared ? (c.switch ? _('%s is shared by %d devices behind the switch').format(c.port, c.peers) + : _('%s is shared by %d devices (a switch or another access point behind it); its %s link is not theirs').format(c.port, c.peers, speed)) : _('Port %s').format(c.port)) + + (c.switch ? '\n' + switchNote(c.switch) : '')); return [ this.whoCell(c, tags), link, @@ -2877,7 +2924,7 @@ return view.extend({ }, drawerWired: function(c) { - var self = this, r = this.portRate(c); + var self = this, r = this.portRate(c), shared = c.shared ? this.st.devRates[c.port] : null; var title = [ avatar(c), E('div', { 'class': 'vt-drawer-titles' }, [ @@ -2895,9 +2942,14 @@ return view.extend({ this.el.renameSlot = E('div', { 'class': 'vt-rename-slot' }), this.section(_('Connection'), [ E('dl', { 'class': 'vt-kvs' }, [ kv(_('Port'), c.port, true), - kv(_('Link', 'vantage'), c.carrier === false ? _('down') : c.shared ? [ _('Shared by %d devices').format(c.peers), E('small', {}, [ _('the port: %s').format(speed) ]) ] : speed), - kv(_('Traffic'), c.shared ? E('span', { 'class': 'vt-muted' }, [ _('Not counted per device on a shared port') ]) - : r ? '↓ ' + fmt.bits(r.tx) + ' · ↑ ' + fmt.bits(r.rx) : _('measuring')), + kv(_('Link', 'vantage'), c.carrier === false ? _('down') : c.shared ? [ _('Shared by %d devices').format(c.peers), + E('small', {}, [ c.switch ? _('behind %s, VLAN %d').format(c.switch.name, c.switch.vlan) : _('the port: %s').format(speed) ]) ] + : c.switchPort ? [ speed, E('small', {}, [ _('switch port %s').format(c.switchPort) ]) ] : speed), + c.switch ? kv(_('Switch ports'), switchLines(c.switch).map(function(l) { return E('div', {}, [ l ]); })) : '', + kv(_('Traffic'), c.shared ? [ + E('span', { 'class': 'vt-muted' }, [ _('Not counted per device on a shared port') ]), + shared ? E('small', {}, [ _('the port in total: %s').format('↓ ' + fmt.bits(shared.tx) + ' · ↑ ' + fmt.bits(shared.rx)) ]) : '' + ] : r ?'↓ ' + fmt.bits(r.tx) + ' · ↑ ' + fmt.bits(r.rx) : _('measuring')), kv(_('Network'), [ c.network || c.bridge || fmt.DASH, c.vlan != null ? E('small', {}, [ _('VLAN %d').format(c.vlan) ]) : '' ]), kv(_('Last heard'), c.seen == null ? _('static entry') : fmt.ago(c.seen * 1000)) ]) ]), diff --git a/luci-app-vantage/po/templates/vantage.pot b/luci-app-vantage/po/templates/vantage.pot index f836ee321..10f4c3827 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:3045 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3097 msgid "%d MHz (%d–%d MHz)" msgstr "" @@ -21,29 +21,29 @@ msgstr "" msgid "%d SSIDs · %d idle" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1308 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1587 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2187 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1349 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1628 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2232 msgid "%d clients" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2514 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2559 msgid "%d connected" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1611 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1614 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2513 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1655 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1659 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2558 msgid "%d devices" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:105 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1686 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1731 msgid "%d down" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3089 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3090 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3141 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3142 msgid "%d errors" msgstr "" @@ -52,26 +52,26 @@ msgctxt "vantage" msgid "%d h ago" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3091 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3143 msgid "%d in · %d out" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:379 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:396 msgctxt "vantage" msgid "%d min" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/fmt.js:90 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:373 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:390 msgctxt "vantage" msgid "%d min ago" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2512 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2557 msgid "%d of %d" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1195 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1236 msgid "%d of %d columns" msgstr "" @@ -83,7 +83,7 @@ msgstr "" msgid "%d older devices (Wi-Fi 4 or earlier) slow airtime" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1650 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1695 msgid "%d on %s" msgstr "" @@ -91,22 +91,22 @@ msgstr "" msgid "%d on this router, %d into your network" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2179 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2224 msgid "%d radios" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:379 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:396 msgctxt "vantage" msgid "%d s" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/fmt.js:89 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:373 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:390 msgctxt "vantage" msgid "%d s ago" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2866 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2913 msgid "%d sent · %s retried · %s failed" msgstr "" @@ -123,11 +123,11 @@ msgstr "" msgid "%d weak" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1653 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1698 msgid "%d wired" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2198 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2243 msgid "%d–%d MHz of the %d–%d MHz band" msgstr "" @@ -145,27 +145,27 @@ msgstr "" msgid "%s (IPv%d)" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2861 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2908 msgid "%s (new this session)" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:25 -#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:185 +#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:212 msgid "%s Gbit/s" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/fmt.js:137 #: luci-app-vantage/htdocs/luci-static/resources/vantage/wifi.js:103 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2205 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2219 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2606 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3038 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2250 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2264 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2653 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3090 msgid "%s MHz" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:25 #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:52 -#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:185 +#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:212 msgid "%s Mbit/s" msgstr "" @@ -173,7 +173,7 @@ msgstr "" msgid "%s accepts every connection" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2860 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2907 msgctxt "vantage" msgid "%s ago" msgstr "" @@ -183,13 +183,13 @@ msgid "%s at %s; below %s roaming and throughput suffer" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:82 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1897 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1942 msgctxt "vantage" msgid "%s available" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2224 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3046 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2269 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3098 msgid "%s dBm" msgstr "" @@ -201,7 +201,7 @@ 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:2828 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2875 msgid "%s experience" msgstr "" @@ -217,7 +217,7 @@ msgstr "" msgid "%s has no carrier: cable unplugged or switch port down" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1162 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1203 msgid "%s hidden" msgstr "" @@ -233,7 +233,7 @@ msgstr "" msgid "%s is in no zone and accepts every connection" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1155 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1196 msgid "%s is narrower" msgstr "" @@ -241,13 +241,17 @@ msgstr "" msgid "%s is not up" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2566 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2612 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:1158 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2611 +msgid "%s is shared by %d devices behind the switch" +msgstr "" + +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1199 msgid "%s is wider" msgstr "" @@ -263,23 +267,23 @@ msgstr "" msgid "%s may open the router's admin" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1276 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1317 msgid "%s moved" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1152 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1193 msgid "%s moved down" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1143 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1184 msgid "%s moved left" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1146 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1187 msgid "%s moved right" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1149 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1190 msgid "%s moved up" msgstr "" @@ -292,9 +296,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:83 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1898 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1921 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3117 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1943 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1966 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3169 msgid "%s of %s" msgstr "" @@ -302,7 +306,7 @@ msgstr "" msgid "%s of %s available (%s in use)" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1662 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1707 msgid "%s of Wi-Fi traffic" msgstr "" @@ -319,15 +323,15 @@ msgstr "" msgid "%s of frames to the device fail; interference likely" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3115 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3167 msgid "%s over %d cores" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1983 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2028 msgid "%s radio" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1201 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1242 msgid "%s shown" msgstr "" @@ -343,11 +347,11 @@ msgstr "" msgid "%s used" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1929 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1974 msgid "%s used of %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2564 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2609 msgid "%s · %d devices" msgstr "" @@ -355,7 +359,7 @@ msgstr "" msgid "%s · %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2858 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2905 msgid "%s · channel %d · %d MHz" msgstr "" @@ -371,28 +375,28 @@ msgstr "" msgid "%s: no carrier" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3046 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3098 msgid "(configured %d dBm, limited by regulatory rules)" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1586 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2697 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1627 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2744 msgid "(hidden)" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1308 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1587 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2187 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1349 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1628 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2232 msgid "1 client" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2514 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2559 msgid "1 connected" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1611 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1614 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2513 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1655 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1659 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2558 msgid "1 device" msgstr "" @@ -400,7 +404,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:2179 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2224 msgid "1 radio" msgstr "" @@ -428,20 +432,20 @@ msgstr "" msgid "60 GHz" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2377 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2422 msgid "Active" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2870 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2906 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2917 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2958 msgid "Address type" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3082 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3134 msgid "Addresses" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2226 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2271 msgid "Airtime" msgstr "" @@ -450,8 +454,8 @@ msgctxt "vantage" msgid "Alias" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2368 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2374 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2413 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2419 msgid "All" msgstr "" @@ -488,13 +492,13 @@ msgctxt "vantage" msgid "B" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1687 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1688 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1732 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1733 msgid "Busiest network" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1662 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1664 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1707 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1709 msgid "Busiest radio" msgstr "" @@ -502,7 +506,7 @@ msgstr "" msgid "Busiest radio: %s of Wi-Fi traffic" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1863 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1908 msgid "Busy share of each CPU core" msgstr "" @@ -516,8 +520,8 @@ msgstr "" #: 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:1856 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3115 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1901 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3167 msgctxt "vantage" msgid "CPU" msgstr "" @@ -526,84 +530,84 @@ msgstr "" msgid "Cache (reclaimable)" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2981 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3033 msgid "Cancel" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2853 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2900 msgctxt "vantage" msgid "Capabilities" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3077 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3129 msgid "Carrier" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3045 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3097 msgid "Centre frequency" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2218 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2263 msgid "Ch %d" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1569 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2186 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1610 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2231 msgid "Ch %d · %d MHz" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3038 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3090 msgid "Channel" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1569 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1610 msgid "Channel —" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2250 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2295 msgctxt "vantage" msgid "Clear filter" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1362 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1403 msgid "Click any node for details" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:914 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1658 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2223 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:955 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1703 #: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2268 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2269 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2313 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2314 msgid "Clients" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3050 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3102 msgid "Clients on this radio" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2714 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2761 msgid "Close" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2621 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2668 msgid "Connected" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2591 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2638 msgid "Connected after you opened this page" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1685 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2859 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1730 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2906 msgid "Connected for" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2856 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2896 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2903 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2943 msgid "Connection" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1890 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1935 msgid "Core %d: %s" msgstr "" @@ -611,15 +615,15 @@ msgstr "" msgid "Could not read the firewall configuration" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2964 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3016 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:3088 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3140 msgid "Counters since boot" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3048 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3100 msgid "Country" msgstr "" @@ -628,13 +632,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:1297 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1338 msgid "Customize" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1107 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1108 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1296 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1148 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1149 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1337 msgid "Customize the dashboard" msgstr "" @@ -642,16 +646,16 @@ msgstr "" msgid "DHCP" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2919 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2971 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:3086 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3138 msgid "DNS" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1524 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1565 msgid "DNS %s" msgstr "" @@ -660,95 +664,95 @@ msgid "Dashboard" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:268 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2449 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2451 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2538 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3106 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2494 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2496 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2583 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3158 msgid "Device" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2948 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3000 msgid "Device name" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2977 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3029 msgid "Device type" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2527 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2572 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:1570 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2188 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2213 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3043 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1611 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2233 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2258 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3095 msgid "Disabled" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2822 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2869 msgid "Disconnected %s; shown from the last sample." msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1121 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1162 msgctxt "vantage" msgid "Done" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:46 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1570 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2188 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2213 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3043 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1611 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2233 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2258 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3095 msgctxt "vantage" msgid "Down" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1962 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2048 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2121 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2007 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2093 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2166 msgid "Download" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:325 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:331 msgid "Download (to clients)" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2864 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2911 msgctxt "vantage" msgid "Downloaded" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1182 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1223 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:1183 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1224 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:1181 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1222 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:1134 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1175 msgid "Drag to move" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3091 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3143 msgctxt "vantage" msgid "Dropped" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2677 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2724 msgid "Edit" msgstr "" @@ -766,8 +770,8 @@ msgctxt "vantage" msgid "Excellent" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2451 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2615 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2496 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2662 msgid "Experience" msgstr "" @@ -785,20 +789,20 @@ msgstr "" msgid "Fair signal %s; lower rates at range" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2247 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2439 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2292 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2484 msgid "Filter by name, address, SSID…" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2439 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2484 msgid "Filter by name, address, port…" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2248 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2293 msgid "Filter clients" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3109 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3161 msgctxt "vantage" msgid "Firmware" msgstr "" @@ -811,7 +815,7 @@ msgstr "" msgid "Forwarding is accepted by default" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2866 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2913 msgid "Frames to device" msgstr "" @@ -820,15 +824,15 @@ msgctxt "vantage" msgid "Free" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2851 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2898 msgid "From device" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2604 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2651 msgid "From device: %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3072 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3124 msgid "From network" msgstr "" @@ -838,9 +842,9 @@ msgid "" "files are not shown." msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1522 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2558 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3085 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1563 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2603 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3137 msgid "Gateway" msgstr "" @@ -853,7 +857,7 @@ msgstr "" msgid "General Settings" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2852 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2899 msgctxt "vantage" msgid "Generation" msgstr "" @@ -863,13 +867,13 @@ msgctxt "vantage" msgid "GiB" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2870 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2906 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2917 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2958 msgid "Globally unique" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2870 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2906 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2917 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2958 msgid "Globally unique · %s" msgstr "" @@ -887,7 +891,7 @@ msgstr "" msgid "Good signal %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1080 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1121 msgid "Grid packets" msgstr "" @@ -895,36 +899,36 @@ msgstr "" msgid "Half duplex" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:811 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:852 msgctxt "vantage" msgid "Health checks" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1198 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2697 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1239 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2744 msgctxt "vantage" msgid "Hidden" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1161 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1202 msgid "Hide %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2871 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2907 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2918 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2959 msgid "IP addresses" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3083 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3135 msgid "IPv4" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3084 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3136 msgid "IPv6" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2868 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2904 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2915 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2956 msgid "Identity" msgstr "" @@ -942,20 +946,20 @@ msgctxt "vantage" msgid "Input" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1548 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1589 msgid "Interface" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3080 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3132 msgid "Interface up for" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2894 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3070 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2941 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3122 msgid "Interfaces" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1522 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1563 msgid "Internet" msgstr "" @@ -981,11 +985,11 @@ msgid "" "the router itself." msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3110 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3162 msgid "Kernel" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1935 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1980 msgid "Kernel %s" msgstr "" @@ -994,58 +998,58 @@ msgctxt "vantage" msgid "KiB" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2262 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2307 msgid "Kind of client" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2860 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2907 msgctxt "vantage" msgid "Last activity" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2450 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2580 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2902 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2495 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2627 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2954 msgid "Last heard" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1119 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1160 msgid "Layout reset" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2590 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2637 msgid "Left %s" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:163 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2592 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2639 msgctxt "vantage" msgid "Legacy" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2449 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2562 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2849 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2898 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3076 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2494 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2607 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2896 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2945 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3128 msgctxt "vantage" msgid "Link" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2451 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2603 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2496 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2650 msgid "Link rate" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1316 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2449 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2451 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2571 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2608 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1357 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2494 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2496 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2618 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2655 msgid "Live" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3114 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3166 msgid "Load" msgstr "" @@ -1057,20 +1061,20 @@ msgstr "" msgid "Load %s · %d cores" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3116 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3168 msgctxt "vantage" msgid "Load average" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1844 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1889 msgid "Load average over 1, 5 and 15 minutes" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1880 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1925 msgid "Load avg %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3112 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3164 msgid "Local time" msgstr "" @@ -1086,8 +1090,8 @@ msgstr "" msgid "MAC" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2869 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2905 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2916 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2957 msgid "MAC address" msgstr "" @@ -1095,15 +1099,15 @@ msgstr "" msgid "MCS %d" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1154 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1195 msgid "Make %s narrower" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1157 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1198 msgid "Make %s wider" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2921 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2973 msgid "Manufacturer of the network adapter" msgstr "" @@ -1120,11 +1124,11 @@ msgid "Measuring…" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:82 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1867 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1912 msgid "Memory" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3117 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3169 msgid "Memory in use" msgstr "" @@ -1133,63 +1137,63 @@ msgctxt "vantage" msgid "MiB" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1068 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1109 msgid "Mirrored" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1069 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1110 msgid "Mirrored, scale per direction" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3044 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3096 msgid "Mode" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3107 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3159 msgid "Model" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1151 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1192 msgid "Move %s down" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1142 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1183 msgid "Move %s left" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1145 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1186 msgid "Move %s right" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1148 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1189 msgid "Move %s up" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1134 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1175 msgid "Move %s: drag, or use the arrow keys" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2976 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3028 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:3016 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3068 msgid "Name contains invisible or control characters" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2872 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2908 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2919 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2960 msgid "Name from" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2543 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2588 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:3017 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3069 msgid "Name is longer than %d characters" msgstr "" @@ -1197,31 +1201,31 @@ msgstr "" msgid "Name must be text" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2813 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2891 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2860 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2938 msgid "Name this device" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2449 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2451 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2570 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2600 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2857 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2901 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2494 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2496 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2617 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2647 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2904 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2953 msgid "Network" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:914 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1361 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1362 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:955 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1402 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1403 msgid "Network path" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1084 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1125 msgid "Network path background" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1686 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1731 msgid "Networks" msgstr "" @@ -1229,13 +1233,13 @@ msgstr "" msgid "Networks: %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2379 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2591 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2424 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2638 msgctxt "vantage" msgid "New" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1471 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1512 msgid "No SSIDs" msgstr "" @@ -1243,23 +1247,23 @@ msgstr "" msgid "No clients" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2529 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2574 msgid "No clients connected" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2652 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2699 msgid "No clients connected." msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2520 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2565 msgid "No clients in this view" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2520 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2565 msgid "No clients match “%s”" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3055 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3107 msgid "No clients; an idle radio is fine." msgstr "" @@ -1267,7 +1271,7 @@ msgstr "" msgid "No clients; idle radios are fine" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1523 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1564 msgctxt "vantage" msgid "No default route" msgstr "" @@ -1276,7 +1280,7 @@ msgstr "" msgid "No interface with a route" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3062 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3114 msgid "No interface with a route is up." msgstr "" @@ -1285,7 +1289,7 @@ msgid "No internet-facing zone found" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:48 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3077 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3129 msgid "No link" msgstr "" @@ -1293,7 +1297,7 @@ msgstr "" msgid "No network interface with a route is up" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1452 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1493 msgid "No other interfaces are up" msgstr "" @@ -1303,7 +1307,7 @@ msgid "No problems detected" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:104 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1475 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1516 msgid "No radios reported" msgstr "" @@ -1320,16 +1324,16 @@ msgstr "" msgid "No stations are associated right now" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2526 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2571 msgid "No wired devices heard" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2686 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2733 msgctxt "vantage" msgid "No wireless networks configured." msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2193 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2238 msgid "No wireless radios are reported by this device." msgstr "" @@ -1348,19 +1352,19 @@ msgstr "" msgid "Nobody associated" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2652 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2699 msgid "Nobody is moving data right now." msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2225 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2270 msgid "Noise" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2854 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2901 msgid "Noise / SNR" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3047 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3099 msgid "Noise floor" msgstr "" @@ -1369,21 +1373,21 @@ msgid "Noise floor not reported by the driver" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:104 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1080 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1121 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:3015 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3067 msgid "Not a station MAC address" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2795 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2842 msgid "Not connected" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2572 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2899 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2619 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2950 msgid "Not counted per device on a shared port" msgstr "" @@ -1391,15 +1395,15 @@ msgstr "" msgid "Not in effect" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1915 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1960 msgid "Not reported" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2924 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2976 msgid "Nothing better known" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2922 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2974 msgid "Nothing better known; the address is randomised" msgstr "" @@ -1420,7 +1424,7 @@ msgstr "" msgid "Older %s device" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2592 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2639 msgid "Older Wi-Fi generation than the radio; uses more airtime" msgstr "" @@ -1428,7 +1432,7 @@ msgstr "" msgid "On this router" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2451 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2496 msgctxt "vantage" msgid "Online" msgstr "" @@ -1445,7 +1449,7 @@ msgctxt "vantage" msgid "Open" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2495 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2540 msgid "Open details of %s" msgstr "" @@ -1461,7 +1465,7 @@ msgstr "" msgid "Open network" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:623 +#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:656 msgid "OpenWrt device" msgstr "" @@ -1471,11 +1475,11 @@ msgid "" "new rules: what is open is unknown." msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1066 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1107 msgid "Overlaid" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1067 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1108 msgid "Overlaid, log scale" msgstr "" @@ -1483,11 +1487,11 @@ msgstr "" msgid "Overview" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2853 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2900 msgid "PMF" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1314 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1355 msgid "Paused while hidden" msgstr "" @@ -1501,7 +1505,7 @@ msgid "" "on to your network: what every router lets in." msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3108 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3160 msgctxt "vantage" msgid "Platform" msgstr "" @@ -1511,23 +1515,31 @@ msgctxt "vantage" msgid "Poor" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2897 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2944 msgid "Port" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2566 +#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:202 +msgid "Port %d" +msgstr "" + +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2612 msgid "Port %s" msgstr "" +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1652 +msgid "Port total: %s" +msgstr "" + #: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:43 msgid "Private" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2870 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2917 msgid "Private Wi-Fi address (randomised by the device)" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2906 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2958 msgid "Private address (randomised by the device)" msgstr "" @@ -1535,26 +1547,26 @@ msgstr "" msgid "Private device" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3105 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3157 msgid "Processes" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3079 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3131 msgid "Protocol" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2257 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2259 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2302 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2304 msgid "Quick filters" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2858 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3042 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2905 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3094 msgctxt "vantage" msgid "Radio" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2214 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2259 msgid "Radio details" msgstr "" @@ -1566,62 +1578,62 @@ msgstr "" msgid "Radio is enabled but not up" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2237 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3036 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2282 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3088 msgid "Radio settings" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:914 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2166 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2168 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:955 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2211 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2213 msgid "Radios" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1524 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1565 msgid "Reachability not probed" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2559 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2604 msgid "Reached through the uplink port %s, not connected to this device" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3070 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3122 msgid "Realtime graphs" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3089 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3141 msgctxt "vantage" msgid "Received" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1315 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1356 msgctxt "vantage" msgid "Reconnecting…" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2395 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2440 msgid "Remove filter: %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2982 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3034 msgid "Remove name" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2813 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2891 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2860 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2938 msgctxt "vantage" msgid "Rename" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1120 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1161 msgid "Reset" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2917 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2969 msgid "Reverse DNS of its address" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:635 +#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:668 msgid "Root (overlay)" msgstr "" @@ -1635,20 +1647,20 @@ msgid "" "to the addresses you use." msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2974 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3026 msgid "Save" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2861 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2908 msgid "Seen since" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3090 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3142 msgctxt "vantage" msgid "Sent" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1070 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1111 msgid "Separate lanes" msgstr "" @@ -1656,57 +1668,57 @@ msgstr "" msgid "Settings to check" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2898 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2945 msgid "Shared by %d devices" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2563 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2608 msgid "Shared port" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1200 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1241 msgid "Show %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2521 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2566 msgid "Show all clients" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1853 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1898 msgid "Show or hide system details" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1362 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1403 msgid "Show or hide the network path" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2169 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2214 msgid "Show or hide the radio details" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1965 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2010 msgid "Show or hide the throughput chart" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2677 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2724 msgid "Show or hide the wireless networks" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1585 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2693 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1626 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2740 msgid "Show the clients of %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1609 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1652 msgid "Show the devices on %s" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:117 #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:118 #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:121 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2451 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2597 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2837 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2496 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2644 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2884 msgid "Signal" msgstr "" @@ -1714,7 +1726,7 @@ msgstr "" msgid "Signal not reported" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3078 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3130 msgctxt "vantage" msgid "Speed" msgstr "" @@ -1725,24 +1737,24 @@ msgid_plural "Standard housekeeping: %d rules" msgstr[0] "" msgstr[1] "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1080 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1121 msgid "Starfield" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2530 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2575 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:3043 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3095 msgid "Status" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:92 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1870 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1915 msgid "Storage" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2983 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3035 msgid "Stored on this device in /etc/config/vantage" msgstr "" @@ -1758,22 +1770,30 @@ msgstr "" msgid "Strong signal, %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1920 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1965 msgctxt "vantage" msgid "Swap" msgstr "" +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2948 +msgid "Switch ports" +msgstr "" + +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:344 +msgid "Switch ports of VLAN %d on %s: %s" +msgstr "" + #: luci-app-vantage/htdocs/luci-static/resources/view/vantage/firewall.js:383 msgid "Switched off" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:915 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1852 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1853 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:956 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1897 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1898 msgid "System" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3105 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3157 msgid "System settings" msgstr "" @@ -1782,19 +1802,19 @@ msgid "Tbit/s" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:75 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1884 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1929 msgid "Temperature %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:635 +#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:668 msgid "Temporary (RAM)" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2450 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2495 msgid "The bridge forgets a device after about five minutes without traffic" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2524 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2569 msgid "" "The bridges have learned so many addresses that listing them here would " "strain this device." @@ -1807,11 +1827,11 @@ msgid "" "reject in General Settings." msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3020 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3072 msgid "The device could not write /etc/config/vantage." msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2225 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2270 msgid "" "The driver reports a placeholder value, so no noise floor or SNR is shown" msgstr "" @@ -1826,11 +1846,11 @@ 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:2920 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2972 msgid "The name the device announces (WPS)" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2558 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2603 msgid "The router this device sends its traffic to" msgstr "" @@ -1846,7 +1866,7 @@ msgstr "" msgid "The uplinks could not be checked" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1532 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1573 msgid "This access point" msgstr "" @@ -1854,11 +1874,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:1532 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1573 msgid "This device" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3019 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3071 msgid "This device already stores %d names; remove some first." msgstr "" @@ -1872,7 +1892,7 @@ msgid "" "the firewall pages." msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3027 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3079 msgid "This radio is not reported any more." msgstr "" @@ -1880,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:2795 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2842 msgid "This station is not associated right now." msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:914 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1957 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1959 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2843 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:955 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2002 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2004 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2890 msgctxt "vantage" msgid "Throughput" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1075 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1116 msgid "Throughput chart" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1950 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1995 msgid "Throughput per link; arrow keys read the values over time" msgstr "" @@ -1905,38 +1925,38 @@ msgctxt "vantage" msgid "TiB" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2850 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2897 msgid "To device" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2577 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2612 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2665 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2624 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2659 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2712 msgid "To device %s, from device %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2604 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2651 msgid "To device: %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3073 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3125 msgid "To network" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2523 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2568 msgid "Too many devices to list" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:915 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2629 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2630 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:956 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2676 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2677 msgctxt "vantage" msgid "Top talkers" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2863 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2899 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3039 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2910 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2949 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3091 msgid "Traffic" msgstr "" @@ -1952,13 +1972,13 @@ msgid "" "networks. Set Forward to reject in General Settings." msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1660 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1684 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1705 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1729 msgid "Traffic now" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2224 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3046 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2269 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3098 msgid "Tx power" msgstr "" @@ -1968,16 +1988,16 @@ msgid "" "it runs, and those are not listed here." msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2794 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2841 msgctxt "vantage" msgid "Unknown device" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3018 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3070 msgid "Unknown device type" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3027 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3079 msgid "Unknown radio" msgstr "" @@ -1992,14 +2012,14 @@ msgid "Unnamed rule" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:58 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2213 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3043 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3077 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2258 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3095 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3129 msgctxt "vantage" msgid "Up" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1877 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1922 msgid "Up %s" msgstr "" @@ -2008,55 +2028,55 @@ msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:50 #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:52 #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:58 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1982 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3062 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2027 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3114 msgctxt "vantage" msgid "Uplink" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1982 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2027 msgid "Uplink %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3066 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3118 msgid "Uplink · %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1963 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2050 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2122 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2008 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2095 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2167 msgid "Upload" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:326 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:332 msgid "Upload (from clients)" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2865 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2912 msgctxt "vantage" msgid "Uploaded" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2559 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2604 msgid "Upstream" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3111 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3163 msgid "Uptime" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2560 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2901 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2605 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2953 msgid "VLAN %d" msgstr "" -#: luci-app-vantage/root/usr/share/rpcd/acl.d/luci-app-vantage.json:24 +#: luci-app-vantage/root/usr/share/rpcd/acl.d/luci-app-vantage.json:25 msgid "" "Vantage dashboard: client names from reverse DNS (lets the holder make the " "device send DNS PTR queries to any DNS server and port it names)" msgstr "" -#: luci-app-vantage/root/usr/share/rpcd/acl.d/luci-app-vantage.json:32 +#: luci-app-vantage/root/usr/share/rpcd/acl.d/luci-app-vantage.json:33 msgid "" "Vantage dashboard: name stations (luci.vantage set_alias: validated names " "in /etc/config/vantage only, at most 512)" @@ -2066,9 +2086,10 @@ msgstr "" 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) and the wired " -"hosts its bridges have learned (luci.vantage wired: MAC, port and when last " -"heard)" +"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 "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:43 @@ -2179,7 +2200,7 @@ msgstr "" msgid "WPS" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2873 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2920 msgid "WPS device name" msgstr "" @@ -2193,7 +2214,7 @@ msgid "Weak" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:146 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2378 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2423 msgid "Weak signal" msgstr "" @@ -2201,8 +2222,8 @@ msgstr "" msgid "Weak signal %s; may roam poorly" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1665 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1667 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1710 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1712 msgid "Weakest signal" msgstr "" @@ -2216,27 +2237,27 @@ msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:105 #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:107 #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:109 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2432 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2477 msgid "Wi-Fi" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1482 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2432 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1523 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2477 msgid "Wired" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:915 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2676 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2677 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:956 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2723 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2724 msgctxt "vantage" msgid "Wireless networks" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2823 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2870 msgid "Wireless settings" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2916 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2968 msgid "Your name for this device" msgstr "" @@ -2261,7 +2282,7 @@ msgstr "" msgid "all protocols" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1686 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1731 msgid "all up" msgstr "" @@ -2278,29 +2299,33 @@ msgstr "" msgid "any zone (default policy)" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2219 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2264 msgid "auto" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2861 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2908 msgid "before this page opened" msgstr "" +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2946 +msgid "behind %s, VLAN %d" +msgstr "" + #: luci-app-vantage/htdocs/luci-static/resources/vantage/fmt.js:30 msgctxt "vantage" msgid "bit/s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2079 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2124 msgid "collecting · %s of data" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2079 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2124 msgid "collecting · first samples" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:222 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2059 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:228 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2104 msgid "collecting…" msgstr "" @@ -2312,8 +2337,9 @@ msgstr "" msgid "dBm" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2563 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2898 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:339 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2608 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2945 msgid "down" msgstr "" @@ -2322,7 +2348,7 @@ msgctxt "vantage" msgid "drop" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2948 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3000 msgctxt "vantage" msgid "e.g. Living room TV" msgstr "" @@ -2348,7 +2374,7 @@ msgstr "" msgid "from anywhere except %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:186 +#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:213 msgid "full duplex" msgstr "" @@ -2356,11 +2382,11 @@ msgstr "" msgid "gateway %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:186 +#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:213 msgid "half duplex" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2702 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2749 msgid "idle" msgstr "" @@ -2402,86 +2428,90 @@ msgctxt "vantage" msgid "kbit/s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1862 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2078 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1907 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2123 msgid "last 5 min" msgstr "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:164 #: luci-app-vantage/htdocs/luci-static/resources/vantage/wifi.js:104 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2606 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2653 msgid "legacy" msgstr "" +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:339 +msgid "link up" +msgstr "" + #: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:42 msgid "mDNS" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2918 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2970 msgid "mDNS announcement" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1660 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1684 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2845 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2900 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1705 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1729 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2892 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2952 msgid "measuring" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2054 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2099 msgid "measuring…" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1664 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1709 msgid "no Wi-Fi traffic yet" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1667 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1712 msgid "no clients" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2038 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2083 msgctxt "vantage" msgid "no data" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1688 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1733 msgid "no traffic yet" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1530 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1685 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1571 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1730 msgid "no uplink" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1658 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1703 msgid "none connected" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2871 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2918 msgid "not known to this AP" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2907 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2959 msgid "not known to this device" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2225 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2226 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3047 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2270 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2271 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3099 msgid "not reported" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3047 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3099 msgid "not reported (driver placeholder %s)" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2854 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2901 msgid "not reported by the driver" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2075 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2860 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2120 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2907 msgctxt "vantage" msgid "now" msgstr "" @@ -2490,16 +2520,16 @@ msgstr "" msgid "now %s down, %s up" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2852 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2899 msgid "older than the radio (%s)" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2053 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2098 msgctxt "vantage" msgid "peak" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1863 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1908 msgid "per core" msgstr "" @@ -2508,11 +2538,11 @@ msgctxt "vantage" msgid "port forward" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2839 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2886 msgid "range %s … %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3072 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3124 msgid "received on %s" msgstr "" @@ -2525,7 +2555,7 @@ msgstr "" msgid "router port %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3073 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3125 msgid "sent on %s" msgstr "" @@ -2533,11 +2563,15 @@ msgstr "" msgid "short GI" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2580 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2902 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2627 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2954 msgid "static entry" msgstr "" +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2947 +msgid "switch port %s" +msgstr "" + #: luci-app-vantage/htdocs/luci-static/resources/view/vantage/firewall.js:373 msgid "switched off" msgstr "" @@ -2546,7 +2580,11 @@ msgstr "" msgid "the covered subnets of zone %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2898 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2951 +msgid "the port in total: %s" +msgstr "" + +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2946 msgid "the port: %s" msgstr "" @@ -2562,11 +2600,11 @@ msgstr "" msgid "traffic rule" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1535 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1576 msgid "up %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2630 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2677 msgid "who uses the bandwidth" msgstr "" @@ -2583,11 +2621,11 @@ msgstr "" msgid "zones %s and %s if they share a device" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1660 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1684 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1705 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1729 msgid "↑ %s · via %s" msgstr "" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2072 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2117 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 ab78a2f55..42445ff17 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:3045 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3097 msgid "%d MHz (%d–%d MHz)" msgstr "%d MHz(%d–%d MHz)" @@ -32,29 +32,29 @@ msgstr "%d 个 SSID 正在广播" msgid "%d SSIDs · %d idle" msgstr "%d 个 SSID · %d 个空闲" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1308 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1587 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2187 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1349 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1628 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2232 msgid "%d clients" msgstr "%d 个客户端" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2514 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2559 msgid "%d connected" msgstr "已连接 %d 个" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1611 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1614 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2513 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1655 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1659 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2558 msgid "%d devices" msgstr "%d 台设备" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:105 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1686 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1731 msgid "%d down" msgstr "%d 个已关闭" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3089 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3090 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3141 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3142 msgid "%d errors" msgstr "%d 个错误" @@ -63,26 +63,26 @@ msgctxt "vantage" msgid "%d h ago" msgstr "%d 小时前" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3091 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3143 msgid "%d in · %d out" msgstr "%d 入 · %d 出" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:379 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:396 msgctxt "vantage" msgid "%d min" msgstr "%d 分钟" #: luci-app-vantage/htdocs/luci-static/resources/vantage/fmt.js:90 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:373 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:390 msgctxt "vantage" msgid "%d min ago" msgstr "%d 分钟前" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2512 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2557 msgid "%d of %d" msgstr "%d/%d" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1195 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1236 msgid "%d of %d columns" msgstr "%d/%d 列" @@ -94,7 +94,7 @@ msgstr "%d 个关闭" msgid "%d older devices (Wi-Fi 4 or earlier) slow airtime" msgstr "%d 台旧设备(Wi-Fi 4 或更早)占用更多空口时间" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1650 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1695 msgid "%d on %s" msgstr "%d 个在 %s" @@ -102,22 +102,22 @@ msgstr "%d 个在 %s" msgid "%d on this router, %d into your network" msgstr "路由器上 %d 项,进入你的网络 %d 项" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2179 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2224 msgid "%d radios" msgstr "%d 个射频" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:379 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:396 msgctxt "vantage" msgid "%d s" msgstr "%d 秒" #: luci-app-vantage/htdocs/luci-static/resources/vantage/fmt.js:89 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:373 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:390 msgctxt "vantage" msgid "%d s ago" 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:2913 msgid "%d sent · %s retried · %s failed" msgstr "发送 %d · 重传 %s · 失败 %s" @@ -134,11 +134,11 @@ msgstr "%d 个已启用" msgid "%d weak" msgstr "%d 个信号弱" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1653 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1698 msgid "%d wired" msgstr "%d 个有线" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2198 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2243 msgid "%d–%d MHz of the %d–%d MHz band" msgstr "%d–%d MHz 属于 %d–%d MHz 频段" @@ -156,27 +156,27 @@ msgstr "%s(%s)已启用但未上线" msgid "%s (IPv%d)" msgstr "%s(IPv%d)" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2861 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2908 msgid "%s (new this session)" msgstr "%s(本次新增)" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:25 -#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:185 +#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:212 msgid "%s Gbit/s" msgstr "%s Gbit/s" #: luci-app-vantage/htdocs/luci-static/resources/vantage/fmt.js:137 #: luci-app-vantage/htdocs/luci-static/resources/vantage/wifi.js:103 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2205 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2219 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2606 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3038 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2250 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2264 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2653 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3090 msgid "%s MHz" msgstr "%s MHz" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:25 #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:52 -#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:185 +#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:212 msgid "%s Mbit/s" msgstr "%s Mbit/s" @@ -184,7 +184,7 @@ msgstr "%s Mbit/s" msgid "%s accepts every connection" msgstr "%s 接受所有连接" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2860 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2907 msgctxt "vantage" msgid "%s ago" msgstr "%s 前" @@ -194,13 +194,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:82 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1897 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1942 msgctxt "vantage" msgid "%s available" msgstr "可用 %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2224 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3046 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2269 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3098 msgid "%s dBm" msgstr "%s dBm" @@ -212,7 +212,7 @@ 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:2828 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2875 msgid "%s experience" msgstr "%s 体验" @@ -228,7 +228,7 @@ 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:1162 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1203 msgid "%s hidden" msgstr "%s 已隐藏" @@ -244,7 +244,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:1155 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1196 msgid "%s is narrower" msgstr "%s 已变窄" @@ -252,14 +252,18 @@ msgstr "%s 已变窄" msgid "%s is not up" msgstr "%s 未上线" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2566 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2612 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:1158 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2611 +msgid "%s is shared by %d devices behind the switch" +msgstr "%s 由交换机后的 %d 台设备共用" + +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1199 msgid "%s is wider" msgstr "%s 已加宽" @@ -275,23 +279,23 @@ msgstr "%s 链路" msgid "%s may open the router's admin" msgstr "%s 可能暴露了路由器管理界面" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1276 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1317 msgid "%s moved" msgstr "%s 已移动" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1152 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1193 msgid "%s moved down" msgstr "%s 已下移" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1143 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1184 msgid "%s moved left" msgstr "%s 已左移" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1146 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1187 msgid "%s moved right" msgstr "%s 已右移" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1149 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1190 msgid "%s moved up" msgstr "%s 已上移" @@ -304,9 +308,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:83 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1898 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1921 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3117 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1943 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1966 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3169 msgid "%s of %s" msgstr "%s / %s" @@ -314,7 +318,7 @@ msgstr "%s / %s" msgid "%s of %s available (%s in use)" msgstr "可用 %s / 共 %s(已用 %s)" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1662 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1707 msgid "%s of Wi-Fi traffic" msgstr "占 Wi-Fi 流量的 %s" @@ -331,15 +335,15 @@ 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:3115 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3167 msgid "%s over %d cores" msgstr "%s / %d 核" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1983 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2028 msgid "%s radio" msgstr "%s 射频" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1201 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1242 msgid "%s shown" msgstr "%s 已显示" @@ -355,11 +359,11 @@ msgstr "%s 已连接,速率 %s" msgid "%s used" msgstr "已用 %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1929 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1974 msgid "%s used of %s" msgstr "已用 %s / 共 %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2564 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2609 msgid "%s · %d devices" msgstr "%s · %d 台设备" @@ -367,7 +371,7 @@ msgstr "%s · %d 台设备" msgid "%s · %s" msgstr "%s · %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2858 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2905 msgid "%s · channel %d · %d MHz" msgstr "%s · 信道 %d · %d MHz" @@ -383,28 +387,28 @@ msgstr "%s · 链路较慢" msgid "%s: no carrier" msgstr "%s:无载波" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3046 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3098 msgid "(configured %d dBm, limited by regulatory rules)" msgstr "(配置 %d dBm,受管制规则限制)" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1586 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2697 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1627 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2744 msgid "(hidden)" msgstr "(隐藏)" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1308 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1587 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2187 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1349 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1628 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2232 msgid "1 client" msgstr "1 个客户端" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2514 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2559 msgid "1 connected" msgstr "已连接 1 个" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1611 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1614 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2513 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1655 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1659 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2558 msgid "1 device" msgstr "1 台设备" @@ -412,7 +416,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:2179 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2224 msgid "1 radio" msgstr "1 个射频" @@ -440,20 +444,20 @@ msgstr "6 GHz" msgid "60 GHz" msgstr "60 GHz" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2377 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2422 msgid "Active" msgstr "活跃" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2870 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2906 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2917 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2958 msgid "Address type" msgstr "地址类型" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3082 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3134 msgid "Addresses" msgstr "地址" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2226 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2271 msgid "Airtime" msgstr "空口时间" @@ -462,8 +466,8 @@ msgctxt "vantage" msgid "Alias" msgstr "别名" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2368 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2374 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2413 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2419 msgid "All" msgstr "全部" @@ -500,13 +504,13 @@ msgctxt "vantage" msgid "B" msgstr "B" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1687 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1688 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1732 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1733 msgid "Busiest network" msgstr "最繁忙网络" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1662 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1664 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1707 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1709 msgid "Busiest radio" msgstr "最繁忙射频" @@ -514,7 +518,7 @@ msgstr "最繁忙射频" msgid "Busiest radio: %s of Wi-Fi traffic" msgstr "最繁忙射频:占 Wi-Fi 流量的 %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1863 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1908 msgid "Busy share of each CPU core" msgstr "每个 CPU 核心的繁忙占比" @@ -528,8 +532,8 @@ msgstr "繁忙;负载 %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:1856 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3115 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1901 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3167 msgctxt "vantage" msgid "CPU" msgstr "CPU" @@ -538,84 +542,84 @@ msgstr "CPU" msgid "Cache (reclaimable)" msgstr "缓存(可回收)" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2981 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3033 msgid "Cancel" msgstr "取消" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2853 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2900 msgctxt "vantage" msgid "Capabilities" msgstr "能力" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3077 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3129 msgid "Carrier" msgstr "链路状态" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3045 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3097 msgid "Centre frequency" msgstr "中心频率" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2218 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2263 msgid "Ch %d" msgstr "信道 %d" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1569 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2186 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1610 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2231 msgid "Ch %d · %d MHz" msgstr "信道 %d · %d MHz" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3038 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3090 msgid "Channel" msgstr "信道" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1569 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1610 msgid "Channel —" msgstr "信道 —" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2250 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2295 msgctxt "vantage" msgid "Clear filter" msgstr "清除筛选" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1362 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1403 msgid "Click any node for details" msgstr "点击任意节点查看详情" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:914 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1658 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2223 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:955 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1703 #: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2268 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2269 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2313 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2314 msgid "Clients" msgstr "客户端" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3050 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3102 msgid "Clients on this radio" msgstr "此射频上的客户端" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2714 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2761 msgid "Close" msgstr "关闭" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2621 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2668 msgid "Connected" msgstr "已连接" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2591 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2638 msgid "Connected after you opened this page" msgstr "打开本页面后连接" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1685 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2859 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1730 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2906 msgid "Connected for" msgstr "已连接时长" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2856 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2896 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2903 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2943 msgid "Connection" msgstr "连接" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1890 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1935 msgid "Core %d: %s" msgstr "核心 %d:%s" @@ -623,15 +627,15 @@ msgstr "核心 %d:%s" msgid "Could not read the firewall configuration" msgstr "无法读取防火墙配置" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2964 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3016 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:3088 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3140 msgid "Counters since boot" msgstr "自启动以来的计数器" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3048 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3100 msgid "Country" msgstr "国家" @@ -640,13 +644,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:1297 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1338 msgid "Customize" msgstr "自定义" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1107 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1108 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1296 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1148 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1149 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1337 msgid "Customize the dashboard" msgstr "自定义仪表盘" @@ -654,16 +658,16 @@ msgstr "自定义仪表盘" msgid "DHCP" msgstr "DHCP" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2919 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2971 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:3086 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3138 msgid "DNS" msgstr "DNS" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1524 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1565 msgid "DNS %s" msgstr "DNS %s" @@ -672,96 +676,96 @@ msgid "Dashboard" msgstr "仪表盘" #: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:268 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2449 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2451 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2538 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3106 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2494 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2496 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2583 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3158 msgid "Device" msgstr "设备" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2948 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3000 msgid "Device name" msgstr "设备名" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2977 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3029 msgid "Device type" msgstr "设备类型" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2527 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2572 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:1570 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2188 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2213 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3043 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1611 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2233 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2258 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3095 msgid "Disabled" msgstr "已禁用" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2822 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2869 msgid "Disconnected %s; shown from the last sample." msgstr "断开于 %s;显示最后一次采样的数据。" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1121 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1162 msgctxt "vantage" msgid "Done" msgstr "完成" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:46 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1570 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2188 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2213 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3043 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1611 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2233 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2258 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3095 msgctxt "vantage" msgid "Down" msgstr "已下线" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1962 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2048 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2121 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2007 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2093 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2166 msgid "Download" msgstr "下载" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:325 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:331 msgid "Download (to clients)" msgstr "下载(到客户端)" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2864 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2911 msgctxt "vantage" msgid "Downloaded" msgstr "已下载" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1182 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1223 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:1183 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1224 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:1181 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1222 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:1134 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1175 msgid "Drag to move" msgstr "拖动以移动" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3091 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3143 msgctxt "vantage" msgid "Dropped" msgstr "已丢弃" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2677 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2724 msgid "Edit" msgstr "编辑" @@ -779,8 +783,8 @@ msgctxt "vantage" msgid "Excellent" msgstr "极好" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2451 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2615 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2496 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2662 msgid "Experience" msgstr "体验" @@ -798,20 +802,20 @@ msgstr "信号一般" msgid "Fair signal %s; lower rates at range" msgstr "信号一般 %s;远距离速率较低" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2247 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2439 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2292 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2484 msgid "Filter by name, address, SSID…" msgstr "按名称、地址、SSID…筛选" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2439 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2484 msgid "Filter by name, address, port…" msgstr "按名称、地址、端口…筛选" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2248 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2293 msgid "Filter clients" msgstr "筛选客户端" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3109 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3161 msgctxt "vantage" msgid "Firmware" msgstr "固件" @@ -824,7 +828,7 @@ msgstr "从 %s 转发到 %s" msgid "Forwarding is accepted by default" msgstr "默认接受转发" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2866 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2913 msgid "Frames to device" msgstr "发往设备的帧" @@ -833,15 +837,15 @@ msgctxt "vantage" msgid "Free" msgstr "空闲" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2851 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2898 msgid "From device" msgstr "来自设备" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2604 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2651 msgid "From device: %s" msgstr "来自设备:%s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3072 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3124 msgid "From network" msgstr "来自网络" @@ -851,9 +855,9 @@ msgid "" "files are not shown." msgstr "内容来自防火墙配置。由 UPnP 或自定义规则文件开放的端口不会显示。" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1522 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2558 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3085 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1563 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2603 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3137 msgid "Gateway" msgstr "网关" @@ -866,7 +870,7 @@ msgstr "Gbit/s" msgid "General Settings" msgstr "基本设置" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2852 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2899 msgctxt "vantage" msgid "Generation" msgstr "代际" @@ -876,13 +880,13 @@ msgctxt "vantage" msgid "GiB" msgstr "GiB" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2870 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2906 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2917 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2958 msgid "Globally unique" msgstr "全局唯一" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2870 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2906 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2917 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2958 msgid "Globally unique · %s" msgstr "全局唯一 · %s" @@ -900,7 +904,7 @@ msgstr "信号良好" msgid "Good signal %s" msgstr "信号良好 %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1080 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1121 msgid "Grid packets" msgstr "网格数据包" @@ -908,36 +912,36 @@ msgstr "网格数据包" msgid "Half duplex" msgstr "半双工" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:811 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:852 msgctxt "vantage" msgid "Health checks" msgstr "健康检查" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1198 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2697 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1239 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2744 msgctxt "vantage" msgid "Hidden" msgstr "隐藏" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1161 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1202 msgid "Hide %s" msgstr "隐藏 %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2871 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2907 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2918 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2959 msgid "IP addresses" msgstr "IP 地址" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3083 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3135 msgid "IPv4" msgstr "IPv4" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3084 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3136 msgid "IPv6" msgstr "IPv6" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2868 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2904 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2915 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2956 msgid "Identity" msgstr "身份" @@ -955,20 +959,20 @@ msgctxt "vantage" msgid "Input" msgstr "入站数据" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1548 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1589 msgid "Interface" msgstr "接口" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3080 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3132 msgid "Interface up for" msgstr "接口已启用时长" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2894 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3070 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2941 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3122 msgid "Interfaces" msgstr "接口" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1522 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1563 msgid "Internet" msgstr "互联网" @@ -998,11 +1002,11 @@ msgstr "" "它将来自互联网上任何地址的 SSH 或网页端口转发到 %s。无法读取接口列表,因此本" "页无法判断该地址是否为路由器本身。" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3110 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3162 msgid "Kernel" msgstr "内核" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1935 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1980 msgid "Kernel %s" msgstr "内核 %s" @@ -1011,58 +1015,58 @@ msgctxt "vantage" msgid "KiB" msgstr "KiB" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2262 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2307 msgid "Kind of client" msgstr "客户端类型" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2860 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2907 msgctxt "vantage" msgid "Last activity" msgstr "最后活动" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2450 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2580 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2902 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2495 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2627 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2954 msgid "Last heard" msgstr "最后活动" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1119 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1160 msgid "Layout reset" msgstr "布局已重置" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2590 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2637 msgid "Left %s" msgstr "离开于 %s" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:163 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2592 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2639 msgctxt "vantage" msgid "Legacy" msgstr "旧版" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2449 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2562 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2849 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2898 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3076 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2494 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2607 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2896 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2945 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3128 msgctxt "vantage" msgid "Link" msgstr "链路" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2451 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2603 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2496 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2650 msgid "Link rate" msgstr "链路速率" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1316 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2449 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2451 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2571 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2608 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1357 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2494 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2496 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2618 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2655 msgid "Live" msgstr "实时" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3114 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3166 msgid "Load" msgstr "负载" @@ -1074,20 +1078,20 @@ msgstr "负载 %s(%d 核)" msgid "Load %s · %d cores" msgstr "负载 %s · %d 核" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3116 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3168 msgctxt "vantage" msgid "Load average" msgstr "平均负载" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1844 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1889 msgid "Load average over 1, 5 and 15 minutes" msgstr "1、5、15 分钟平均负载" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1880 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1925 msgid "Load avg %s" msgstr "平均负载 %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3112 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3164 msgid "Local time" msgstr "本地时间" @@ -1103,8 +1107,8 @@ msgstr "链路速率低于信号预期" msgid "MAC" msgstr "MAC" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2869 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2905 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2916 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2957 msgid "MAC address" msgstr "MAC 地址" @@ -1112,15 +1116,15 @@ msgstr "MAC 地址" msgid "MCS %d" msgstr "MCS %d" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1154 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1195 msgid "Make %s narrower" msgstr "使 %s 变窄" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1157 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1198 msgid "Make %s wider" msgstr "使 %s 加宽" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2921 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2973 msgid "Manufacturer of the network adapter" msgstr "网卡制造商" @@ -1137,11 +1141,11 @@ msgid "Measuring…" msgstr "测量中…" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:82 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1867 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1912 msgid "Memory" msgstr "内存" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3117 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3169 msgid "Memory in use" msgstr "已用内存" @@ -1150,63 +1154,63 @@ msgctxt "vantage" msgid "MiB" msgstr "MiB" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1068 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1109 msgid "Mirrored" msgstr "镜像" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1069 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1110 msgid "Mirrored, scale per direction" msgstr "镜像,每个方向单独刻度" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3044 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3096 msgid "Mode" msgstr "模式" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3107 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3159 msgid "Model" msgstr "型号" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1151 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1192 msgid "Move %s down" msgstr "下移 %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1142 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1183 msgid "Move %s left" msgstr "左移 %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1145 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1186 msgid "Move %s right" msgstr "右移 %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1148 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1189 msgid "Move %s up" msgstr "上移 %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1134 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1175 msgid "Move %s: drag, or use the arrow keys" msgstr "移动 %s:拖动或使用方向键" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2976 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3028 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:3016 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3068 msgid "Name contains invisible or control characters" msgstr "名称包含不可见或控制字符" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2872 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2908 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2919 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2960 msgid "Name from" msgstr "名称来源" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2543 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2588 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:3017 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3069 msgid "Name is longer than %d characters" msgstr "名称超过 %d 个字符" @@ -1214,31 +1218,31 @@ msgstr "名称超过 %d 个字符" msgid "Name must be text" msgstr "名称必须是文本" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2813 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2891 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2860 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2938 msgid "Name this device" msgstr "命名此设备" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2449 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2451 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2570 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2600 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2857 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2901 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2494 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2496 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2617 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2647 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2904 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2953 msgid "Network" msgstr "网络" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:914 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1361 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1362 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:955 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1402 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1403 msgid "Network path" msgstr "网络路径" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1084 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1125 msgid "Network path background" msgstr "网络路径背景" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1686 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1731 msgid "Networks" msgstr "网络" @@ -1246,13 +1250,13 @@ msgstr "网络" msgid "Networks: %s" msgstr "网络:%s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2379 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2591 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2424 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2638 msgctxt "vantage" msgid "New" msgstr "新增" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1471 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1512 msgid "No SSIDs" msgstr "无 SSID" @@ -1260,23 +1264,23 @@ msgstr "无 SSID" msgid "No clients" msgstr "无客户端" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2529 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2574 msgid "No clients connected" msgstr "无客户端连接" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2652 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2699 msgid "No clients connected." msgstr "没有客户端连接。" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2520 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2565 msgid "No clients in this view" msgstr "此视图中没有客户端" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2520 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2565 msgid "No clients match “%s”" msgstr "没有匹配“%s”的客户端" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3055 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3107 msgid "No clients; an idle radio is fine." msgstr "无客户端;射频空闲属正常。" @@ -1284,7 +1288,7 @@ msgstr "无客户端;射频空闲属正常。" msgid "No clients; idle radios are fine" msgstr "无客户端;射频空闲属正常" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1523 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1564 msgctxt "vantage" msgid "No default route" msgstr "无默认路由" @@ -1293,7 +1297,7 @@ msgstr "无默认路由" msgid "No interface with a route" msgstr "没有带路由的接口" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3062 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3114 msgid "No interface with a route is up." msgstr "没有带路由的接口处于启用状态。" @@ -1302,7 +1306,7 @@ msgid "No internet-facing zone found" msgstr "未找到面向互联网的区域" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:48 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3077 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3129 msgid "No link" msgstr "无链路" @@ -1310,7 +1314,7 @@ msgstr "无链路" msgid "No network interface with a route is up" msgstr "没有带路由的网络接口处于启用状态" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1452 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1493 msgid "No other interfaces are up" msgstr "没有其他接口处于启用状态" @@ -1320,7 +1324,7 @@ msgid "No problems detected" msgstr "未检测到问题" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:104 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1475 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1516 msgid "No radios reported" msgstr "未报告射频" @@ -1337,16 +1341,16 @@ msgstr "无信号" msgid "No stations are associated right now" msgstr "当前没有站点关联" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2526 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2571 msgid "No wired devices heard" msgstr "未发现有线设备" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2686 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2733 msgctxt "vantage" msgid "No wireless networks configured." msgstr "未配置无线网络。" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2193 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2238 msgid "No wireless radios are reported by this device." msgstr "此设备未报告任何无线射频。" @@ -1367,19 +1371,19 @@ msgstr "尚未配置区域。" msgid "Nobody associated" msgstr "无关联站点" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2652 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2699 msgid "Nobody is moving data right now." msgstr "当前没有设备在传输数据。" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2225 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2270 msgid "Noise" msgstr "噪声" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2854 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2901 msgid "Noise / SNR" msgstr "噪声 / 信噪比" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3047 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3099 msgid "Noise floor" msgstr "底噪" @@ -1388,21 +1392,21 @@ msgid "Noise floor not reported by the driver" msgstr "驱动未报告底噪" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:104 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1080 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1121 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:3015 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3067 msgid "Not a station MAC address" msgstr "不是站点 MAC 地址" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2795 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2842 msgid "Not connected" msgstr "未连接" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2572 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2899 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2619 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2950 msgid "Not counted per device on a shared port" msgstr "共用端口不按设备统计" @@ -1410,15 +1414,15 @@ msgstr "共用端口不按设备统计" msgid "Not in effect" msgstr "未生效" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1915 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1960 msgid "Not reported" msgstr "未报告" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2924 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2976 msgid "Nothing better known" msgstr "无更多信息" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2922 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2974 msgid "Nothing better known; the address is randomised" msgstr "无更多信息;地址已随机化" @@ -1439,7 +1443,7 @@ msgstr "OWE" msgid "Older %s device" msgstr "较旧的 %s 设备" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2592 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2639 msgid "Older Wi-Fi generation than the radio; uses more airtime" msgstr "比射频支持的 Wi-Fi 代际更旧;占用更多空口时间" @@ -1447,7 +1451,7 @@ msgstr "比射频支持的 Wi-Fi 代际更旧;占用更多空口时间" msgid "On this router" msgstr "在此路由器上" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2451 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2496 msgctxt "vantage" msgid "Online" msgstr "在线" @@ -1463,7 +1467,7 @@ msgctxt "vantage" msgid "Open" msgstr "开放" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2495 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2540 msgid "Open details of %s" msgstr "打开 %s 的详情" @@ -1479,7 +1483,7 @@ msgstr "对互联网开放:%d" msgid "Open network" msgstr "开放网络" -#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:623 +#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:656 msgid "OpenWrt device" msgstr "OpenWrt 设备" @@ -1491,11 +1495,11 @@ msgstr "" "基本设置中的选项 %s 的值被 firewall4 拒绝,因此不会加载新规则:无法确定开放了" "哪些内容。" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1066 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1107 msgid "Overlaid" msgstr "叠加" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1067 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1108 msgid "Overlaid, log scale" msgstr "叠加,对数刻度" @@ -1503,11 +1507,11 @@ msgstr "叠加,对数刻度" msgid "Overview" msgstr "概览" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2853 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2900 msgid "PMF" msgstr "PMF" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1314 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1355 msgid "Paused while hidden" msgstr "页面隐藏时暂停" @@ -1523,7 +1527,7 @@ msgstr "" "Ping 和其他控制消息、组播、DHCP 续租以及转发到你网络的 IPsec:每台路由器都会" "放行的流量。" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3108 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3160 msgctxt "vantage" msgid "Platform" msgstr "平台" @@ -1533,23 +1537,31 @@ msgctxt "vantage" msgid "Poor" msgstr "较差" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2897 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2944 msgid "Port" msgstr "端口" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2566 +#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:202 +msgid "Port %d" +msgstr "端口 %d" + +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2612 msgid "Port %s" msgstr "端口 %s" +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1652 +msgid "Port total: %s" +msgstr "端口合计:%s" + #: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:43 msgid "Private" msgstr "私有" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2870 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2917 msgid "Private Wi-Fi address (randomised by the device)" msgstr "私有 Wi-Fi 地址(设备随机化)" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2906 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2958 msgid "Private address (randomised by the device)" msgstr "私有地址(设备随机化)" @@ -1557,26 +1569,26 @@ msgstr "私有地址(设备随机化)" msgid "Private device" msgstr "私有设备" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3105 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3157 msgid "Processes" msgstr "进程" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3079 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3131 msgid "Protocol" msgstr "协议" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2257 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2259 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2302 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2304 msgid "Quick filters" msgstr "快速筛选" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2858 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3042 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2905 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3094 msgctxt "vantage" msgid "Radio" msgstr "射频" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2214 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2259 msgid "Radio details" msgstr "射频详情" @@ -1588,62 +1600,62 @@ msgstr "射频已禁用" msgid "Radio is enabled but not up" msgstr "射频已启用但未上线" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2237 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3036 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2282 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3088 msgid "Radio settings" msgstr "射频设置" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:914 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2166 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2168 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:955 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2211 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2213 msgid "Radios" msgstr "射频" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1524 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1565 msgid "Reachability not probed" msgstr "未探测可达性" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2559 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2604 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:3070 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3122 msgid "Realtime graphs" msgstr "实时图表" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3089 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3141 msgctxt "vantage" msgid "Received" msgstr "已接收" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1315 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1356 msgctxt "vantage" msgid "Reconnecting…" msgstr "重新连接中…" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2395 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2440 msgid "Remove filter: %s" msgstr "移除筛选:%s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2982 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3034 msgid "Remove name" msgstr "移除名称" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2813 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2891 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2860 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2938 msgctxt "vantage" msgid "Rename" msgstr "重命名" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1120 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1161 msgid "Reset" msgstr "重置" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2917 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2969 msgid "Reverse DNS of its address" msgstr "其地址的反向 DNS" -#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:635 +#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:668 msgid "Root (overlay)" msgstr "Root(overlay)" @@ -1658,20 +1670,20 @@ msgid "" msgstr "" "SSH 或网页管理界面会响应互联网上的任何地址。请将此规则限制为你使用的地址。" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2974 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3026 msgid "Save" msgstr "保存" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2861 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2908 msgid "Seen since" msgstr "首次出现" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3090 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3142 msgctxt "vantage" msgid "Sent" msgstr "已发送" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1070 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1111 msgid "Separate lanes" msgstr "分开显示" @@ -1679,57 +1691,57 @@ msgstr "分开显示" msgid "Settings to check" msgstr "待检查的设置" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2898 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2945 msgid "Shared by %d devices" msgstr "%d 台设备共用" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2563 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2608 msgid "Shared port" msgstr "共用端口" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1200 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1241 msgid "Show %s" msgstr "显示 %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2521 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2566 msgid "Show all clients" msgstr "显示全部客户端" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1853 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1898 msgid "Show or hide system details" msgstr "显示/隐藏系统详情" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1362 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1403 msgid "Show or hide the network path" msgstr "显示/隐藏网络路径" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2169 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2214 msgid "Show or hide the radio details" msgstr "显示/隐藏射频详情" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1965 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2010 msgid "Show or hide the throughput chart" msgstr "显示/隐藏吞吐量图表" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2677 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2724 msgid "Show or hide the wireless networks" msgstr "显示/隐藏无线网络" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1585 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2693 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1626 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2740 msgid "Show the clients of %s" msgstr "显示 %s 的客户端" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1609 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1652 msgid "Show the devices on %s" msgstr "显示 %s 上的设备" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:117 #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:118 #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:121 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2451 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2597 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2837 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2496 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2644 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2884 msgid "Signal" msgstr "信号强度" @@ -1737,7 +1749,7 @@ msgstr "信号强度" msgid "Signal not reported" msgstr "未报告信号" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3078 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3130 msgctxt "vantage" msgid "Speed" msgstr "速率" @@ -1747,24 +1759,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:1080 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1121 msgid "Starfield" msgstr "星空" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2530 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2575 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:3043 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3095 msgid "Status" msgstr "状态" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:92 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1870 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1915 msgid "Storage" msgstr "存储" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2983 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3035 msgid "Stored on this device in /etc/config/vantage" msgstr "保存在本设备 /etc/config/vantage 中" @@ -1780,22 +1792,30 @@ msgstr "信号强 %s,链路 %s" msgid "Strong signal, %s" msgstr "信号强,%s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1920 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1965 msgctxt "vantage" msgid "Swap" msgstr "交换分区" +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2948 +msgid "Switch ports" +msgstr "交换机端口" + +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:344 +msgid "Switch ports of VLAN %d on %s: %s" +msgstr "VLAN %d(%s)的交换机端口:%s" + #: luci-app-vantage/htdocs/luci-static/resources/view/vantage/firewall.js:383 msgid "Switched off" msgstr "已关闭" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:915 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1852 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1853 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:956 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1897 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1898 msgid "System" msgstr "系统" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3105 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3157 msgid "System settings" msgstr "系统设置" @@ -1804,19 +1824,19 @@ msgid "Tbit/s" msgstr "Tbit/s" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:75 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1884 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1929 msgid "Temperature %s" msgstr "温度 %s" -#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:635 +#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:668 msgid "Temporary (RAM)" msgstr "临时(RAM)" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2450 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2495 msgid "The bridge forgets a device after about five minutes without traffic" msgstr "设备约五分钟无流量后,网桥会将其遗忘" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2524 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2569 msgid "" "The bridges have learned so many addresses that listing them here would " "strain this device." @@ -1831,11 +1851,11 @@ msgstr "" "该处适用默认入站数据策略且为接受,因此互联网上的任何主机都能访问路由器本身。" "请将其加入 wan 区域,或在基本设置中将入站数据设为拒绝。" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3020 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3072 msgid "The device could not write /etc/config/vantage." msgstr "设备无法写入 /etc/config/vantage。" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2225 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2270 msgid "" "The driver reports a placeholder value, so no noise floor or SNR is shown" msgstr "驱动报告的是占位值,不显示底噪与信噪比" @@ -1852,11 +1872,11 @@ msgstr "" "无法读取接口列表,且默认入站数据策略为接受:不属于任何区域的上行接口将会开" "放。请在基本设置中将入站数据设为拒绝。" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2920 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2972 msgid "The name the device announces (WPS)" msgstr "设备广播的名称(WPS)" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2558 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2603 msgid "The router this device sends its traffic to" msgstr "此设备发送流量所经的路由器" @@ -1872,7 +1892,7 @@ msgstr "保存的名称包含无效的配置节 ID" msgid "The uplinks could not be checked" msgstr "无法检查上行接口" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1532 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1573 msgid "This access point" msgstr "此接入点" @@ -1880,11 +1900,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:1532 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1573 msgid "This device" msgstr "此设备" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3019 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3071 msgid "This device already stores %d names; remove some first." msgstr "此设备已存储 %d 个名称;请先移除部分。" @@ -1898,7 +1918,7 @@ msgid "" "the firewall pages." msgstr "本页无法判断开放了哪些内容。请重新加载;如果仍无效,请检查防火墙页面。" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3027 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3079 msgid "This radio is not reported any more." msgstr "驱动不再报告此射频。" @@ -1906,23 +1926,23 @@ msgstr "驱动不再报告此射频。" msgid "This setup is beyond what this overview checks" msgstr "此配置超出本概览的检查范围" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2795 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2842 msgid "This station is not associated right now." msgstr "此站点当前未关联。" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:914 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1957 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1959 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2843 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:955 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2002 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2004 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2890 msgctxt "vantage" msgid "Throughput" msgstr "吞吐量" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1075 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1116 msgid "Throughput chart" msgstr "吞吐量图表" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1950 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1995 msgid "Throughput per link; arrow keys read the values over time" msgstr "每条链路的吞吐量;方向键可查看历史值" @@ -1931,38 +1951,38 @@ msgctxt "vantage" msgid "TiB" msgstr "TiB" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2850 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2897 msgid "To device" msgstr "到设备" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2577 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2612 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2665 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2624 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2659 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2712 msgid "To device %s, from device %s" msgstr "到设备 %s,来自设备 %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2604 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2651 msgid "To device: %s" msgstr "到设备:%s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3073 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3125 msgid "To network" msgstr "发往网络" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2523 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2568 msgid "Too many devices to list" msgstr "设备过多,无法列出" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:915 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2629 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2630 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:956 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2676 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2677 msgctxt "vantage" msgid "Top talkers" msgstr "流量大户" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2863 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2899 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3039 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2910 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2949 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3091 msgid "Traffic" msgstr "流量" @@ -1980,13 +2000,13 @@ msgstr "" "未被任何转发覆盖的互联网流量仍会到达你的其他网络。请在基本设置中将转发设为拒" "绝。" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1660 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1684 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1705 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1729 msgid "Traffic now" msgstr "当前流量" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2224 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3046 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2269 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3098 msgid "Tx power" msgstr "发射功率" @@ -1997,16 +2017,16 @@ msgid "" msgstr "" "已安装 UPnP:它运行时,你网络中的设备可以自行开放端口,这些端口不会在此列出。" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2794 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2841 msgctxt "vantage" msgid "Unknown device" msgstr "未知设备" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3018 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3070 msgid "Unknown device type" msgstr "未知设备类型" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3027 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3079 msgid "Unknown radio" msgstr "未知射频" @@ -2021,14 +2041,14 @@ msgid "Unnamed rule" msgstr "未命名的规则" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:58 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2213 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3043 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3077 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2258 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3095 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3129 msgctxt "vantage" msgid "Up" msgstr "已上线" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1877 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1922 msgid "Up %s" msgstr "已运行 %s" @@ -2037,49 +2057,49 @@ msgstr "已运行 %s" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:50 #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:52 #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:58 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1982 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3062 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2027 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3114 msgctxt "vantage" msgid "Uplink" msgstr "上行链路" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1982 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2027 msgid "Uplink %s" msgstr "上行链路 %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3066 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3118 msgid "Uplink · %s" msgstr "上行链路 · %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1963 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2050 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2122 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2008 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2095 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2167 msgid "Upload" msgstr "上传" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:326 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:332 msgid "Upload (from clients)" msgstr "上传(来自客户端)" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2865 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2912 msgctxt "vantage" msgid "Uploaded" msgstr "已上传" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2559 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2604 msgid "Upstream" msgstr "上游" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3111 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3163 msgid "Uptime" msgstr "运行时间" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2560 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2901 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2605 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2953 msgid "VLAN %d" msgstr "VLAN %d" -#: luci-app-vantage/root/usr/share/rpcd/acl.d/luci-app-vantage.json:24 +#: luci-app-vantage/root/usr/share/rpcd/acl.d/luci-app-vantage.json:25 msgid "" "Vantage dashboard: client names from reverse DNS (lets the holder make the " "device send DNS PTR queries to any DNS server and port it names)" @@ -2087,7 +2107,7 @@ msgstr "" "Vantage 仪表盘:来自反向 DNS 的客户端名称(持有者可使设备向其指定的任意 DNS " "服务器和端口发送 DNS PTR 查询)" -#: luci-app-vantage/root/usr/share/rpcd/acl.d/luci-app-vantage.json:32 +#: luci-app-vantage/root/usr/share/rpcd/acl.d/luci-app-vantage.json:33 msgid "" "Vantage dashboard: name stations (luci.vantage set_alias: validated names " "in /etc/config/vantage only, at most 512)" @@ -2099,9 +2119,10 @@ msgstr "" 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) and the wired " -"hosts its bridges have learned (luci.vantage wired: MAC, port and when last " -"heard)" +"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 "" #: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:43 @@ -2212,7 +2233,7 @@ msgstr "WPA3 个人版" msgid "WPS" msgstr "WPS" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2873 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2920 msgid "WPS device name" msgstr "WPS 设备名称" @@ -2226,7 +2247,7 @@ msgid "Weak" msgstr "弱" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:146 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2378 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2423 msgid "Weak signal" msgstr "信号弱" @@ -2234,8 +2255,8 @@ msgstr "信号弱" msgid "Weak signal %s; may roam poorly" msgstr "信号弱 %s;漫游可能不佳" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1665 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1667 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1710 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1712 msgid "Weakest signal" msgstr "最弱信号" @@ -2249,27 +2270,27 @@ msgstr "开放内容取决于 firewall4 如何处理 %s,本页无法跟踪。 #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:105 #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:107 #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:109 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2432 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2477 msgid "Wi-Fi" msgstr "Wi-Fi" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1482 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2432 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1523 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2477 msgid "Wired" msgstr "有线" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:915 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2676 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2677 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:956 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2723 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2724 msgctxt "vantage" msgid "Wireless networks" msgstr "无线网络" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2823 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2870 msgid "Wireless settings" msgstr "无线设置" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2916 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2968 msgid "Your name for this device" msgstr "你为此设备设置的名称" @@ -2294,7 +2315,7 @@ msgstr "除 %s 以外的所有端口" msgid "all protocols" msgstr "所有协议" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1686 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1731 msgid "all up" msgstr "全部启用" @@ -2311,29 +2332,33 @@ msgstr "任意区域" msgid "any zone (default policy)" msgstr "任意区域(默认策略)" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2219 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2264 msgid "auto" msgstr "自动" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2861 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2908 msgid "before this page opened" msgstr "打开本页之前" +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2946 +msgid "behind %s, VLAN %d" +msgstr "位于 %s 之后,VLAN %d" + #: luci-app-vantage/htdocs/luci-static/resources/vantage/fmt.js:30 msgctxt "vantage" msgid "bit/s" msgstr "bit/s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2079 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2124 msgid "collecting · %s of data" msgstr "采集中 · 已采集 %s 数据" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2079 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2124 msgid "collecting · first samples" msgstr "采集中 · 首个样本" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:222 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2059 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:228 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2104 msgid "collecting…" msgstr "采集中…" @@ -2345,8 +2370,9 @@ msgstr "自定义规则文件" msgid "dBm" msgstr "dBm" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2563 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2898 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:339 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2608 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2945 msgid "down" msgstr "已断开" @@ -2355,7 +2381,7 @@ msgctxt "vantage" msgid "drop" msgstr "丢弃" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2948 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3000 msgctxt "vantage" msgid "e.g. Living room TV" msgstr "例如:客厅电视" @@ -2381,7 +2407,7 @@ msgstr "来自任意地址" msgid "from anywhere except %s" msgstr "来自除 %s 外的任意地址" -#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:186 +#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:213 msgid "full duplex" msgstr "全双工" @@ -2389,11 +2415,11 @@ msgstr "全双工" msgid "gateway %s" msgstr "网关 %s" -#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:186 +#: luci-app-vantage/htdocs/luci-static/resources/vantage/model.js:213 msgid "half duplex" msgstr "半双工" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2702 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2749 msgid "idle" msgstr "空闲" @@ -2435,86 +2461,90 @@ msgctxt "vantage" msgid "kbit/s" msgstr "kbit/s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1862 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2078 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1907 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2123 msgid "last 5 min" msgstr "最近 5 分钟" #: luci-app-vantage/htdocs/luci-static/resources/vantage/insight.js:164 #: luci-app-vantage/htdocs/luci-static/resources/vantage/wifi.js:104 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2606 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2653 msgid "legacy" msgstr "旧版" +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:339 +msgid "link up" +msgstr "已连接" + #: luci-app-vantage/htdocs/luci-static/resources/vantage/names.js:42 msgid "mDNS" msgstr "mDNS" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2918 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2970 msgid "mDNS announcement" msgstr "mDNS 广播" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1660 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1684 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2845 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2900 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1705 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1729 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2892 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2952 msgid "measuring" msgstr "测量中" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2054 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2099 msgid "measuring…" msgstr "测量中…" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1664 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1709 msgid "no Wi-Fi traffic yet" msgstr "尚无 Wi-Fi 流量" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1667 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1712 msgid "no clients" msgstr "无客户端" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2038 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2083 msgctxt "vantage" msgid "no data" msgstr "无数据" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1688 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1733 msgid "no traffic yet" msgstr "尚无流量" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1530 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1685 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1571 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1730 msgid "no uplink" msgstr "无上行链路" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1658 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1703 msgid "none connected" msgstr "无连接" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2871 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2918 msgid "not known to this AP" msgstr "此 AP 未识别" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2907 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2959 msgid "not known to this device" msgstr "此设备未识别" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2225 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2226 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3047 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2270 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2271 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3099 msgid "not reported" msgstr "未报告" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3047 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3099 msgid "not reported (driver placeholder %s)" msgstr "未报告(驱动占位值 %s)" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2854 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2901 msgid "not reported by the driver" msgstr "驱动未报告" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2075 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2860 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2120 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2907 msgctxt "vantage" msgid "now" msgstr "现在" @@ -2523,16 +2553,16 @@ msgstr "现在" msgid "now %s down, %s up" msgstr "当前下行 %s,上行 %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2852 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2899 msgid "older than the radio (%s)" msgstr "比射频支持的标准更旧(%s)" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2053 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2098 msgctxt "vantage" msgid "peak" msgstr "峰值" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1863 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1908 msgid "per core" msgstr "每核" @@ -2541,11 +2571,11 @@ msgctxt "vantage" msgid "port forward" msgstr "端口转发" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2839 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2886 msgid "range %s … %s" msgstr "范围 %s … %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3072 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3124 msgid "received on %s" msgstr "在 %s 上接收" @@ -2558,7 +2588,7 @@ msgstr "拒绝" msgid "router port %s" msgstr "路由器端口 %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3073 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:3125 msgid "sent on %s" msgstr "在 %s 上发送" @@ -2566,11 +2596,15 @@ msgstr "在 %s 上发送" msgid "short GI" msgstr "短 GI" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2580 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2902 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2627 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2954 msgid "static entry" msgstr "静态条目" +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2947 +msgid "switch port %s" +msgstr "交换机端口 %s" + #: luci-app-vantage/htdocs/luci-static/resources/view/vantage/firewall.js:373 msgid "switched off" msgstr "已关闭" @@ -2579,7 +2613,11 @@ msgstr "已关闭" msgid "the covered subnets of zone %s" msgstr "区域 %s 覆盖的子网" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2898 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2951 +msgid "the port in total: %s" +msgstr "该端口合计:%s" + +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2946 msgid "the port: %s" msgstr "端口:%s" @@ -2595,11 +2633,11 @@ msgstr "此路由器" msgid "traffic rule" msgstr "通信规则" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1535 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1576 msgid "up %s" msgstr "已运行 %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2630 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2677 msgid "who uses the bandwidth" msgstr "带宽使用者" @@ -2616,12 +2654,12 @@ 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:1660 -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1684 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1705 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:1729 msgid "↑ %s · via %s" msgstr "↑ %s · 经 %s" -#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2072 +#: luci-app-vantage/htdocs/luci-static/resources/view/vantage/overview.js:2117 msgid "−%d min" msgstr "−%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 ac9464f63..a217afac3 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) and the wired hosts its bridges have learned (luci.vantage wired: MAC, port and when last heard)", + "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)", "read": { "file": { "/proc/stat": [ "read" ] @@ -11,6 +11,7 @@ "network.interface": [ "dump" ], "network.device": [ "status" ], "luci-rpc": [ "getHostHints" ], + "luci": [ "getSwconfigPortState" ], "luci.vantage": [ "thermal", "wired", "wireless" ], "iwinfo": [ "assoclist", "info" ], "hostapd.*": [ "get_clients", "get_status" ], 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 644ad8771..39844b496 100644 --- a/luci-app-vantage/root/usr/share/rpcd/ucode/luci.vantage +++ b/luci-app-vantage/root/usr/share/rpcd/ucode/luci.vantage @@ -19,7 +19,13 @@ // when the bridges hold FDB_LIMIT entries or more between // them, counted first through sysfs without reading further: a flood of // made-up addresses must not make rpcd build the whole -// table. Read group luci-app-vantage. +// table. Where a port is a VLAN on a swconfig switch +// (eth1.1), also which switch ports that VLAN has +// (switches): from /etc/board.json (the CPU port's network +// device, the ports' roles) and the switch_vlan sections of +// /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. // 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 @@ -49,6 +55,10 @@ const MAX_PER_PORT = 128; // of them on one port (the uplink's would tak 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 +const NETWORK = 'network'; // read only, by switches(): switch_vlan sections +const BOARD = '/etc/board.json'; +const BOARD_MAX = 65536; // bytes read of it +const MAX_SWITCH_VLANS = 64; /* ------------------------------------------------------------ helpers */ @@ -468,6 +478,120 @@ function wired() { 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; +} + +// the network devices a switch VLAN reaches this device as (each CPU +// port's device in it, with .vid where that port is tagged) and its other +// ports, from a port list such as '0 1 2 3 5t'; null without a CPU port +function vlan_ports(sw, list, vid) { + let devs = [], members = []; + + for (let t in split(list, /\s+/)) { + let m = match(t, /^([0-9]{1,2})([t*]?)$/); + let num = m ? switch_port(+m[1]) : null; + + if (num == null || length(members) >= 64) + continue; + + if (sw.cpu[num] != null) { + let dev = netdev((m[2] == 't') ? sw.cpu[num] + '.' + vid : sw.cpu[num]); + + if (dev && index(devs, dev) < 0) + push(devs, dev); + } + else + push(members, sw.ports[num] ?? { num, role: null, index: null }); + } + + return length(devs) ? { devs, members } : null; +} + +// { 'eth1.1': { name: 'switch0', vlan: 1, ports: [ { num, role, index } ] } } +// for each VLAN of a swconfig switch: the network device it reaches this +// device as and its other ports, as LuCI's switch page lays them out. +// From the switch_vlan sections of the network config, or for a switch +// they give no VLAN, from the roles board.json gives it (the first boot's +// layout). Only switches /etc/board.json describes; {} without one, so a +// device whose ports are all Linux ports (DSA) loads no network config. +function switches() { + let board = null, known = {}, used = {}, out = {}, n = 0; + + try { board = json(readfile(BOARD, BOARD_MAX) ?? 'null'); } + catch (e) { return out; } + + for (let name, sw in ((type(board?.switch) == 'object') ? board.switch : {})) { + if (!match(name, /^[A-Za-z0-9_.-]{1,32}$/) || type(sw?.ports) != 'array') + continue; + + let ports = {}, cpu = {}; + + for (let p in sw.ports) { + let num = switch_port(p?.num); + + if (num == null) + continue; + + if (netdev(p.device)) + cpu[num] = p.device; + else + ports[num] = { + num, + role: (type(p.role) == 'string' && match(p.role, /^[a-z0-9]{1,16}$/)) ? p.role : null, + index: (type(p.index) == 'int' && p.index >= 0 && p.index < 100) ? p.index : null + }; + } + + if (length(cpu)) + known[name] = { ports, cpu, roles: (type(sw.roles) == 'array') ? slice(sw.roles, 0, 16) : [] }; + } + + if (!length(known)) + return out; + + let nw = cursor(); + + if (nw.load(NETWORK)) + nw.foreach(NETWORK, 'switch_vlan', (s) => { + let sw = (type(s.device) == 'string') ? known[s.device] : null; + let id = s.vid ?? s.vlan; + let vid = (type(id) == 'string' && match(id, /^[0-9]{1,4}$/)) ? +id : null; + + if (!sw || vid == null || vid > 4094 || type(s.ports) != 'string') + return; + + if (++n > MAX_SWITCH_VLANS) + return false; + + let v = vlan_ports(sw, s.ports, vid); + + for (let dev in (v?.devs ?? [])) { + if (!out[dev]) + out[dev] = { name: s.device, vlan: vid, ports: v.members }; + + used[s.device] = true; + } + }); + + for (let name, sw in known) { + if (used[name]) + continue; + + for (let r in sw.roles) { + let m = (type(r?.device) == 'string' && type(r.ports) == 'string') ? match(r.device, /^[A-Za-z0-9_-]{1,10}\.([0-9]{1,4})$/) : null; + let vid = m ? +m[1] : null; + let v = (vid != null && vid <= 4094) ? vlan_ports(sw, r.ports, vid) : null; + + if (v && index(v.devs, r.device) >= 0 && !out[r.device]) + out[r.device] = { name, vlan: vid, ports: v.members }; + } + } + + return out; +} + /* ------------------------------------------------------------ methods */ const methods = { @@ -497,9 +621,13 @@ const methods = { wired: { call: function() { - let hosts = wired(); + let hosts = wired(), sw = switches(); + let reply = (hosts == null) ? { hosts: [], crowded: true } : { hosts }; - return (hosts == null) ? { hosts: [], crowded: true } : { hosts }; + if (length(sw)) + reply.switches = sw; + + return reply; } }, diff --git a/luci-theme-vantage/Makefile b/luci-theme-vantage/Makefile index 4922fe052..5d3e34fd9 100644 --- a/luci-theme-vantage/Makefile +++ b/luci-theme-vantage/Makefile @@ -10,8 +10,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-theme-vantage -PKG_VERSION:=1.0.12 -PKG_RELEASE:=27 +PKG_VERSION:=1.0.13 +PKG_RELEASE:=28 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 01684d33e..bdaf0fb72 100644 --- a/luci-theme-vantage/htdocs/luci-static/vantage/vantage.css +++ b/luci-theme-vantage/htdocs/luci-static/vantage/vantage.css @@ -2556,9 +2556,6 @@ html:not([data-darkmode="true"]) .vt-login-page { position: relative; width: min(380px, 100%); z-index: 1; } -.vt-login-page{ - background:none !important; -} .vt-login-page::before { content: ""; position: absolute; @@ -2569,7 +2566,7 @@ html:not([data-darkmode="true"]) .vt-login-page { opacity: 0.4; } html:not([data-darkmode="true"]) .vt-login-page::before { - opacity: 0.7; + opacity: 0.6; } #packages { width: 100% !important; diff --git a/xt-tls/Makefile b/xt-tls/Makefile index eb49e0a37..a168f4afa 100644 --- a/xt-tls/Makefile +++ b/xt-tls/Makefile @@ -5,13 +5,13 @@ include $(INCLUDE_DIR)/kernel.mk # The name and version of your package are used to define the variable to point to the build directory of your package: $(PKG_BUILD_DIR) PKG_NAME:=xt_tls PKG_VERSION:=0.3.5 -PKG_RELEASE:=2 +PKG_RELEASE:=3 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://github.com/Lochnair/xt_tls.git PKG_SOURCE_PROTO:=git PKG_SOURCE_SUBDIR=$(PKG_NAME)-$(PKG_VERSION) -PKG_SOURCE_VERSION:=137644fe539dd910c63ce527f6456ab38f148e3f +PKG_SOURCE_VERSION:=00f905ace4ce5e6d24c0a2122f92b166455e99b4 PKG_MAINTAINER:=Nils Andreas Svee PKG_LICENSE=GPL-3.0