mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-08 05:04:21 +08:00
🤞 Sync 2026-11-05 19:25:07
This commit is contained in:
1 parent
9c1c52b048
commit
45b207395d
63 files changed
+4401
-3078
No files matched your search
+2
-1
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=ariang
|
||||
PKG_VERSION:=1.3.15
|
||||
PKG_RELEASE:=6
|
||||
PKG_RELEASE:=7
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).zip
|
||||
PKG_SOURCE_URL:=https://github.com/mayswind/AriaNg/releases/download/$(PKG_VERSION)
|
||||
@@ -40,6 +40,7 @@ define Package/ariang-nginx
|
||||
$(Package/ariang/default)
|
||||
EXTRA_DEPENDS:=nginx$(if $(CONFIG_USE_APK), (>=0))
|
||||
TITLE += for nginx webserver
|
||||
CONFLICTS:=ariang
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
|
||||
+3
-3
@@ -5,11 +5,11 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=honk
|
||||
PKG_VERSION:=2026.11.04~88d470c
|
||||
PKG_RELEASE:=30
|
||||
PKG_VERSION:=2026.11.05~9e31cc0
|
||||
PKG_RELEASE:=31
|
||||
|
||||
HONK_SRC_URL:=https://github.com/daeuniverse/honk.git
|
||||
HONK_SRC_VERSION:=88d470c662e0ee7a3de3e67afc6129f67e66c1bf
|
||||
HONK_SRC_VERSION:=9e31cc0bd28825afdc0e384dc989bc3f076e69cf
|
||||
|
||||
PKG_LICENSE:=AGPL-3.0-only
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
@@ -138,7 +138,7 @@ echo "==> Building honk-core for $RUST_TARGET..."
|
||||
cargo build --release --locked \
|
||||
-p honk-core \
|
||||
--no-default-features \
|
||||
--features ebpf,rprx,clash-api,native-api,mimalloc \
|
||||
--features ebpf,rprx,clash-api,native-api,jemalloc \
|
||||
--target "$RUST_TARGET"
|
||||
|
||||
BUILT_BIN="$SRC_DIR/target/$RUST_TARGET/release/honk-core"
|
||||
|
||||
@@ -87,9 +87,10 @@ start_service() {
|
||||
hijack_resolv_conf
|
||||
|
||||
procd_open_instance "$CONF"
|
||||
# mimalloc pre-reserves a 1 GiB arena; VSZ only, but it dwarfs the real
|
||||
# footprint in ps. MIMALLOC_ARENA_RESERVE=0: grow on demand instead.
|
||||
procd_set_param env DAE_LOCATION_ASSET="/usr/share/v2ray" MIMALLOC_ARENA_RESERVE="0"
|
||||
procd_set_param env \
|
||||
DAE_LOCATION_ASSET="/usr/share/v2ray" \
|
||||
MIMALLOC_ARENA_RESERVE="0" \
|
||||
MALLOC_CONF="retain:false"
|
||||
procd_set_param command "$PROG" --config "$config_file"
|
||||
procd_set_param netdev "$HONK_HOST_IFACE" "$HONK_PEER_IFACE"
|
||||
procd_set_param limits core="unlimited"
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=isp-split
|
||||
PKG_VERSION:=0.4.0
|
||||
PKG_RELEASE:=6
|
||||
PKG_VERSION:=0.4.1
|
||||
PKG_RELEASE:=7
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
PKG_MAINTAINER:=jihebube <jihebube@users.noreply.github.com>
|
||||
|
||||
@@ -234,7 +234,13 @@ doc_mwan3_is_nft() {
|
||||
|
||||
doc_mwan3_table() {
|
||||
_doc_have nft || return 1
|
||||
nft list table inet mwan3 >/dev/null 2>&1
|
||||
nft list table inet mwan3 >/dev/null 2>&1 && return 0
|
||||
# 3.6 的 nft 端口用 inet;个别固件(Kwrt 兼容层 / iptables-nft 残留)会同时
|
||||
# 留 ip、ip6 同名表。判据是"表在不在",不能被 family 写死:只认 inet 会让
|
||||
# ip mwan3 里的 mwan3 自家规则整表落到 legacy 分支(fix38 的误报根因之一)。
|
||||
nft list table ip mwan3 >/dev/null 2>&1 && return 0
|
||||
nft list table ip6 mwan3 >/dev/null 2>&1 && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
# 版本(P10):opkg 与 apk 双分支;两者都没有 -> 空(不判"漂移",判 unknown)
|
||||
@@ -568,7 +574,9 @@ doc_p4b_table() {
|
||||
}
|
||||
|
||||
# 写者枚举(检查三/五共用):一次 awk 出 TSV,位运算留给 shell(busybox awk
|
||||
# 没有 and()/or())。字段:fam tab chain handle field form mask value comment
|
||||
# 没有 and()/or())。字段:fam tab chain handle field form mask value comment src
|
||||
# src = RHS 首个操作数的来源:meta / ct / lit / other(老夹具没有这列时为空,
|
||||
# 求值按"同字段"处理,与 fix38 行为一致)
|
||||
doc_p4_writers() {
|
||||
DOC_W=""
|
||||
[ -n "${DOC_P4:-}" ] || {
|
||||
@@ -596,7 +604,10 @@ doc_p4_writers() {
|
||||
if (p == 0) next
|
||||
field = "mark"
|
||||
if (index(line, "ct mark set") > 0) {
|
||||
field = "ctmark"; p = index(line, "ct mark set") + 13
|
||||
# "ct mark set" 是 11 字符 + 1 个空格 -> 值的起点是 index+12。
|
||||
# 旧实现写的 +13 会吃掉值的首字符:`ct mark set 0x100` 被读成
|
||||
# "x100" -> form=other -> ct 写者整条漏掉(fix38 顺带修的解析 bug)。
|
||||
field = "ctmark"; p = index(line, "ct mark set") + 12
|
||||
} else if (index(line, "meta mark set") > 0) {
|
||||
p = index(line, "meta mark set") + 14
|
||||
} else {
|
||||
@@ -607,7 +618,14 @@ doc_p4_writers() {
|
||||
q = index(rest, "# handle ")
|
||||
if (q > 0) { h = substr(rest, q + 9); rest = trim(substr(rest, 1, q - 1)) }
|
||||
sub(/[^0-9].*$/, "", h)
|
||||
form = "other"; mask = "-"; value = "-"
|
||||
form = "other"; mask = "-"; value = "-"; src = "other"
|
||||
# RHS 的首个操作数说明"这条规则读的是哪个字段":meta mark / ct mark /
|
||||
# 字面值。fix39 的掩码求值靠它区分三种形态——跨字段同步(读 A 写 B)、
|
||||
# 同字段掩码(读 B 写 B)、读向(只写 packet mark,不写 ct mark)。
|
||||
# 只认行首锚定,避免把 `ct mark & ... != ...` 的条件部分误当来源。
|
||||
if (rest ~ /^meta mark/) src = "meta"
|
||||
else if (rest ~ /^ct mark/) src = "ct"
|
||||
else if (rest ~ /^0x/) src = "lit"
|
||||
if (index(rest, "&") > 0) {
|
||||
q = index(rest, "&")
|
||||
r2 = trim(substr(rest, q + 1))
|
||||
@@ -627,38 +645,189 @@ doc_p4_writers() {
|
||||
form = "mask_clear"
|
||||
}
|
||||
} else {
|
||||
split(rest, C, " ")
|
||||
value = C[1]
|
||||
form = "set"
|
||||
# `meta mark set meta mark | 0x100`(OR 立即数):nft 打印的是
|
||||
# `|`,不是 "or",旧实现只认 & 分支会把它读成 other -> 漏掉。
|
||||
if (index(rest, "|") > 0) {
|
||||
q2 = index(rest, "|")
|
||||
split(trim(substr(rest, q2 + 1)), C, " ")
|
||||
value = C[1]
|
||||
form = "or"
|
||||
} else {
|
||||
split(rest, C, " ")
|
||||
value = C[1]
|
||||
form = "set"
|
||||
}
|
||||
}
|
||||
if (value != "-" && value != "" && substr(value, 1, 2) != "0x") {
|
||||
form = "other"; value = "-"; mask = "-"
|
||||
}
|
||||
if (fam == "" || tab == "") next
|
||||
printf "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", fam, tab, chain, (h == "" ? "-" : h), field, form, mask, value, (cm == "" ? "-" : cm)
|
||||
printf "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", fam, tab, chain, (h == "" ? "-" : h), field, form, mask, value, (cm == "" ? "-" : cm), src
|
||||
}')
|
||||
DOC_W_ROWS=$(printf '%s\n' "$DOC_W" | _doc_cnt)
|
||||
}
|
||||
|
||||
# 归属(检查五 5.2 的顺序,写死):① inet mwan3 + mwan3* 链 -> mwan3;
|
||||
# ② 同一张表里 comment 含 isp-split -> isp-split;③ 非 inet 表 -> legacy;
|
||||
# ④ 其余 -> third_party。顺序即优先级。
|
||||
# 归属(检查三/五共用,顺序即优先级):
|
||||
# ① 表名是 mwan3(任意 family:inet/ip/ip6 都算)-> 整张表连同全部子链都是
|
||||
# mwan3 自己的(iface_in_*、policy_*、mwan3_hook、dynamic、mwan3_or_ct_* 等);
|
||||
# ② 表名是 isp-split 自己的表(isptest / isp_split*)-> isp-split;
|
||||
# ③ 任何表里链名是 mwan3* / iface_in_* / iface_out_* -> mwan3(表名被改过时兜底);
|
||||
# ④ comment 含 isp-split -> isp-split;⑤ 非 inet 表 -> legacy(iptables-nft 残留);
|
||||
# ⑥ 其余 -> third_party。
|
||||
#
|
||||
# 红线(fix38):只看"表/链是谁的",不看 mark 的值。mwan3 的线路值
|
||||
# (0x100/0x200/...,掩码 mmx_mask)与 OAF 的默认 ct mark 0x100 完全撞值,
|
||||
# 值签名永远不能当归属判据——否则 mwan3 自己的线路打标会被判成第三方 DPI。
|
||||
_doc_owner_of() { # fam tab chain comment
|
||||
case "$2" in
|
||||
mwan3 | mwan3_* | mwan3-*) printf 'mwan3'; return 0 ;;
|
||||
isp_split | isp_split_* | isp-split | isp-split_* | isptest) printf 'isp-split'; return 0 ;;
|
||||
esac
|
||||
case "$3" in
|
||||
mwan3* | iface_in_* | iface_out_*) printf 'mwan3'; return 0 ;;
|
||||
esac
|
||||
case "${4:-}" in
|
||||
*isp-split*) printf 'isp-split'; return 0 ;;
|
||||
esac
|
||||
case "$1" in
|
||||
inet)
|
||||
if [ "$2" = "mwan3" ]; then
|
||||
case "$3" in
|
||||
mwan3* | "") printf 'mwan3' ;;
|
||||
*) printf 'isp-split' ;;
|
||||
esac
|
||||
return 0
|
||||
fi
|
||||
case "${4:-}" in
|
||||
*isp-split*) printf 'isp-split' ;;
|
||||
*) printf 'third_party' ;;
|
||||
inet) printf 'third_party' ;;
|
||||
*) printf 'legacy' ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 值是否整个落在 mmx_mask 位段内(mwan3 线路 mark 家族:0x100/0x200/... 或掩码本身)。
|
||||
# 只用于"这条写者是不是线路打标形态"的说明与 hint,绝不参与归属判定。
|
||||
_doc_val_in_mask() { # 0x..
|
||||
_doc_hx "${1:-}"
|
||||
[ "$HEX" -ne 0 ] || return 1
|
||||
[ "$(( HEX & DOC_MMX_MASK_DEC ))" -eq "$HEX" ]
|
||||
}
|
||||
|
||||
# 写向位求值(检查三/五共用,唯一实现):一条写 mark 的规则到底"写了哪些位"。
|
||||
#
|
||||
# nft 打印出来的写向有四种形态,旧实现把它们混在一起(mask 之外的位一律算成
|
||||
# "清掉了位段内的位"),于是 OpenWrt 自带 fwmark 同步的 OUTPUT 规则必然误报:
|
||||
# ① `ct mark set 0x100`(字面值) 覆盖位 = 值 & mmx_mask
|
||||
# ② `... set <别的字段> & 0x00ff0000`(跨字段/同步)覆盖位 = mask | orbits
|
||||
# ③ `... set <同字段> & 0xffffc1ff | 0x100`(清位+置位)写 = orbits,清 = ~mask
|
||||
# ④ `... set <别的字段>`(整值写,无掩码) 不可判定 -> 保守
|
||||
# ②的语义:规则只把来源字段的 mask 段搬进目标字段,mask 之外的位由来源字段的
|
||||
# 当时取值决定(OpenWrt 用 `ct state new` 限定,位段本身与 0x3f00 无重叠),
|
||||
# 因此判据是"mask | orbits 与 mmx_mask 是否有交集",不是"mask 之外被清了多少位"。
|
||||
#
|
||||
# 读向:`meta mark set ct mark & 0x00ff0000` 只写 packet mark、不写 ct mark,
|
||||
# 进不了 conntrack,C3 不计(断言 a 的 PREROUTING 行)。
|
||||
_doc_wr_eval() { # <field> <form> <mask> <value> <src>
|
||||
_wre_f=${1:-}
|
||||
_wre_form=${2:-other}
|
||||
_wre_msk=${3:--}
|
||||
_wre_val=${4:--}
|
||||
_wre_src=${5:-}
|
||||
WR_BITS=0 # 写进目标字段的位(可静态求值时)
|
||||
WR_CLEAR=0 # 被清 0 的位(只有同字段掩码写才算)
|
||||
WR_KNOWN=1 # 0 = 无法静态求值 -> 调用方按"整段可能被写"保守处理
|
||||
WR_KIND=""
|
||||
# 同字段(自引用)?空 src(老夹具/信息缺失)按同字段处理,保持 fix38 行为。
|
||||
_wre_own=1
|
||||
case "$_wre_src" in
|
||||
meta) [ "$_wre_f" = "mark" ] || _wre_own=0 ;;
|
||||
ct) [ "$_wre_f" = "ctmark" ] || _wre_own=0 ;;
|
||||
lit | other) _wre_own=0 ;;
|
||||
esac
|
||||
case "$_wre_form" in
|
||||
set)
|
||||
_doc_hx "$_wre_val"
|
||||
WR_BITS=$HEX
|
||||
WR_KIND=literal
|
||||
;;
|
||||
or)
|
||||
case "$_wre_src:$_wre_f" in
|
||||
ct:mark)
|
||||
WR_KIND=read_from_ct
|
||||
;;
|
||||
meta:ctmark)
|
||||
# `ct mark set meta mark | 0x100`:没有 & 的整值写,来源位未知
|
||||
WR_KNOWN=0
|
||||
WR_KIND=unevaluable
|
||||
;;
|
||||
*)
|
||||
_doc_hx "$_wre_val"
|
||||
WR_BITS=$HEX
|
||||
WR_KIND=or_literal
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*) printf 'legacy' ;;
|
||||
mask_set | mask_or | mask_clear)
|
||||
case "$_wre_src:$_wre_f" in
|
||||
ct:mark)
|
||||
WR_KIND=read_from_ct
|
||||
;;
|
||||
*)
|
||||
if [ "$_wre_own" = "1" ]; then
|
||||
# 同字段掩码写:mask 内是"写进去的位",mask 外是"清掉的位",
|
||||
# 两半都动了目标字段 -> 取并集(与 fix38 相同的保守口径)
|
||||
_doc_hx "$_wre_val"
|
||||
WR_BITS=$HEX
|
||||
_doc_hx "$_wre_msk"
|
||||
WR_CLEAR=$(( ~HEX & DOC_MMX_MASK_DEC ))
|
||||
WR_KIND=same_field_mask
|
||||
else
|
||||
# 跨字段掩码写(fwmark 同步):覆盖位 = mask | orbits
|
||||
_doc_hx "$_wre_msk"
|
||||
_wre_b=$HEX
|
||||
[ "$_wre_val" = "-" ] || {
|
||||
_doc_hx "$_wre_val"
|
||||
_wre_b=$(( _wre_b | HEX ))
|
||||
}
|
||||
WR_BITS=$_wre_b
|
||||
WR_KIND=mask_expr
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
case "$_wre_src:$_wre_f" in
|
||||
ct:mark)
|
||||
WR_KIND=read_from_ct
|
||||
;;
|
||||
ct:ctmark | meta:mark)
|
||||
# 自赋值(`ct mark set ct mark`):一个位都不改
|
||||
WR_KIND=self_noop
|
||||
;;
|
||||
*)
|
||||
# 无掩码整值写 / 无法解析的表达式:不知道会写哪些位 -> 保守
|
||||
WR_KNOWN=0
|
||||
WR_KIND=unevaluable
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# 写向规则的 RHS 文本(人读/JSON 里的判定依据,不是判据本身)
|
||||
_doc_wr_src_expr() { # <src> <field>
|
||||
case "${1:-}" in
|
||||
meta) printf 'meta mark' ;;
|
||||
ct) printf 'ct mark' ;;
|
||||
lit) printf '' ;;
|
||||
*)
|
||||
# src 缺失(老夹具):按目标字段反推自引用,显示才不会出现 "?"
|
||||
case "${2:-}" in
|
||||
mark) printf 'meta mark' ;;
|
||||
ctmark) printf 'ct mark' ;;
|
||||
*) printf '?' ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_doc_wr_expr() { # <field> <form> <mask> <value> <src>
|
||||
case "${2:-}" in
|
||||
set) printf '%s' "${4:--}" ;;
|
||||
or) printf '%s | %s' "$(_doc_wr_src_expr "${5:-}" "${1:-}")" "${4:--}" ;;
|
||||
mask_set | mask_or) printf '%s & %s | %s' "$(_doc_wr_src_expr "${5:-}" "${1:-}")" "${3:--}" "${4:--}" ;;
|
||||
mask_clear) printf '%s & %s' "$(_doc_wr_src_expr "${5:-}" "${1:-}")" "${3:--}" ;;
|
||||
*) printf '%s(整值写)' "$(_doc_wr_src_expr "${5:-}" "${1:-}")" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
@@ -675,6 +844,19 @@ _doc_guess_product() { # fam tab chain
|
||||
esac
|
||||
}
|
||||
|
||||
# 产品名的展示写法(hint 用;不改变判据)
|
||||
_doc_product_label() {
|
||||
case "$1" in
|
||||
oaf) printf 'OAF' ;;
|
||||
openclash) printf 'OpenClash' ;;
|
||||
passwall) printf 'PassWall' ;;
|
||||
tailscale) printf 'Tailscale' ;;
|
||||
mihomo) printf 'mihomo' ;;
|
||||
sing-box) printf 'sing-box' ;;
|
||||
*) printf '%s' "${1:-}" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
# P5:ip rule。无掩码规则等价掩码 0xffffffff——不补全会让位段判据全错。
|
||||
doc_p5_iprule() {
|
||||
[ "${DOC_P5_DONE:-0}" = "1" ] && return 0
|
||||
@@ -1227,48 +1409,86 @@ doc_check_mark() {
|
||||
fi
|
||||
|
||||
_c3_writers=""
|
||||
_c3_writers_n=0
|
||||
_c3_excluded=""
|
||||
_c3_excl_n=0
|
||||
_c3_excl_mw=0
|
||||
_c3_excl_own=0
|
||||
_c3_wn=0
|
||||
_c3_third=0
|
||||
_c3_overlap=0
|
||||
_c3_overlap_ordered=0
|
||||
_c3_overlap_unordered=0
|
||||
_c3_ct=0
|
||||
_c3_ct_names=""
|
||||
_c3_hint=""
|
||||
_c3_hint_conf="none"
|
||||
_c3_hint_basis="none"
|
||||
_c3_outside=""
|
||||
_c3_outside_n=0
|
||||
# 第三方重叠写者的明细,供检查五继承
|
||||
DOC_C3_OVERLAP_NAMES=""
|
||||
while IFS=" " read -r _w_fam _w_tab _w_chn _w_hnd _w_fld _w_form _w_msk _w_val _w_cm; do
|
||||
# fix39:掩码表达式求值的判定记录(facts 里给用户看"为什么没报")
|
||||
_c3_eval="" # 第三方写者的形态/覆盖位/是否重叠
|
||||
# 「无重叠(已验证)」的 info:按 表/链/位段 去重,最多 4 条
|
||||
_c3_disjoint=""
|
||||
_c3_disjoint_keys=" "
|
||||
_c3_disjoint_n=0
|
||||
_c3_readn=0
|
||||
_c3_read_txt=""
|
||||
_c3_unknown_n=0
|
||||
_c3_ct_unknown=0
|
||||
_c3_find=""
|
||||
_doc_find3() {
|
||||
_c3_find="${_c3_find}${_c3_find:+,}{\"code\":$(_doc_jstr "$1"),\"verdict\":$(_doc_jstr "$2"),\"detail\":$(_doc_jstr "$3"),\"evidence\":$(_doc_jstr "$4")}"
|
||||
}
|
||||
while IFS=" " read -r _w_fam _w_tab _w_chn _w_hnd _w_fld _w_form _w_msk _w_val _w_cm _w_src; do
|
||||
[ -n "${_w_fam:-}" ] || continue
|
||||
_c3_wn=$((_c3_wn + 1))
|
||||
_w_owner=$(_doc_owner_of "$_w_fam" "$_w_tab" "$_w_chn" "$_w_cm")
|
||||
_w_owned=0
|
||||
_w_cleared=0
|
||||
case "$_w_form" in
|
||||
set)
|
||||
_doc_hx "$_w_val"
|
||||
_w_owned=$(( HEX & _M ))
|
||||
;;
|
||||
mask_set | mask_or)
|
||||
_doc_hx "$_w_msk"
|
||||
_w_mk=$HEX
|
||||
_doc_hx "$_w_val"
|
||||
_w_owned=$(( HEX & _M ))
|
||||
_w_cleared=$(( (~_w_mk) & _M ))
|
||||
;;
|
||||
mask_clear)
|
||||
_doc_hx "$_w_msk"
|
||||
_w_mk=$HEX
|
||||
_w_cleared=$(( (~_w_mk) & _M ))
|
||||
;;
|
||||
esac
|
||||
_w_touched=$(( _w_cleared | _w_owned ))
|
||||
_w_prod=$(_doc_guess_product "$_w_fam" "$_w_tab" "$_w_chn")
|
||||
if [ "$_c3_wn" -le 40 ]; then
|
||||
_c3_writers="${_c3_writers}${_c3_writers:+,}{\"fam\":$(_doc_jstr "$_w_fam"),\"table\":$(_doc_jstr "$_w_tab"),\"chain\":$(_doc_jstr "$_w_chn"),\"handle\":$(_doc_jstr "$_w_hnd"),\"field\":$(_doc_jstr "$_w_fld"),\"form\":$(_doc_jstr "$_w_form"),\"mask\":$(_doc_jstr "$([ "$_w_msk" = "-" ] && printf '' || printf '%s' "$_w_msk")"),\"value\":$(_doc_jstr "$([ "$_w_val" = "-" ] && printf '' || printf '%s' "$_w_val")"),\"touched\":$(_doc_jstr "$(_doc_hxstr "$_w_touched")"),\"owner\":$(_doc_jstr "$_w_owner")}"
|
||||
# 写向位求值(唯一实现,检查五同源):形态 -> 覆盖位/清位/可否判定
|
||||
_doc_wr_eval "$_w_fld" "$_w_form" "$_w_msk" "$_w_val" "${_w_src:-}"
|
||||
_w_kind=$WR_KIND
|
||||
_w_known=$WR_KNOWN
|
||||
if [ "$_w_known" = "0" ]; then
|
||||
# 不可判定(整值写/无法解析):按"整段都可能被写"保守处理
|
||||
_w_touched=$_M
|
||||
else
|
||||
_w_touched=$(( WR_CLEAR | WR_BITS ))
|
||||
fi
|
||||
_w_prod=$(_doc_guess_product "$_w_fam" "$_w_tab" "$_w_chn")
|
||||
case "$_w_owner" in
|
||||
third_party | legacy)
|
||||
mwan3 | isp-split)
|
||||
# 排除清单(fix38):mwan3 自家表/链(iface_in_*、policy_*、mwan3_hook、
|
||||
# dynamic、mwan3_or_ct_* 等,任意 family)与 isp-split 自家表里的写者,
|
||||
# 都不是第三方。它们写的正是 mmx_mask 位段内的线路值——值签名不能
|
||||
# 反过来当"第三方 DPI"的证据。
|
||||
_c3_excl_n=$((_c3_excl_n + 1))
|
||||
case "$_w_owner" in
|
||||
mwan3) _c3_excl_mw=$((_c3_excl_mw + 1)) ;;
|
||||
*) _c3_excl_own=$((_c3_excl_own + 1)) ;;
|
||||
esac
|
||||
if [ "$_c3_excl_n" -le 40 ]; then
|
||||
_c3_excluded="${_c3_excluded}${_c3_excluded:+,}{\"fam\":$(_doc_jstr "$_w_fam"),\"table\":$(_doc_jstr "$_w_tab"),\"chain\":$(_doc_jstr "$_w_chn"),\"field\":$(_doc_jstr "$_w_fld"),\"form\":$(_doc_jstr "$_w_form"),\"mask\":$(_doc_jstr "$([ "$_w_msk" = "-" ] && printf '' || printf '%s' "$_w_msk")"),\"value\":$(_doc_jstr "$([ "$_w_val" = "-" ] && printf '' || printf '%s' "$_w_val")"),\"touched\":$(_doc_jstr "$(_doc_hxstr "$_w_touched")"),\"owner\":$(_doc_jstr "$_w_owner"),\"reason\":$(_doc_jstr "$([ "$_w_owner" = "mwan3" ] && printf 'mwan3_own_table' || printf 'isp_split_own')")}"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
_c3_third=$((_c3_third + 1))
|
||||
# 表达式文本只给第三方写者用(自家写者上百条,别为它们多 fork)
|
||||
_w_expr=$(_doc_wr_expr "$_w_fld" "$_w_form" "$_w_msk" "$_w_val" "${_w_src:-}")
|
||||
_w_inmask=$(( _w_touched & _M ))
|
||||
if [ "$_w_known" = "0" ]; then
|
||||
_c3_unknown_n=$((_c3_unknown_n + 1))
|
||||
[ "$_w_fld" = "ctmark" ] && _c3_ct_unknown=$((_c3_ct_unknown + 1))
|
||||
fi
|
||||
if [ "$_c3_writers_n" -lt 40 ]; then
|
||||
_c3_writers_n=$((_c3_writers_n + 1))
|
||||
_c3_writers="${_c3_writers}${_c3_writers:+,}{\"fam\":$(_doc_jstr "$_w_fam"),\"table\":$(_doc_jstr "$_w_tab"),\"chain\":$(_doc_jstr "$_w_chn"),\"handle\":$(_doc_jstr "$_w_hnd"),\"field\":$(_doc_jstr "$_w_fld"),\"form\":$(_doc_jstr "$_w_form"),\"mask\":$(_doc_jstr "$([ "$_w_msk" = "-" ] && printf '' || printf '%s' "$_w_msk")"),\"value\":$(_doc_jstr "$([ "$_w_val" = "-" ] && printf '' || printf '%s' "$_w_val")"),\"src\":$(_doc_jstr "${_w_src:-}"),\"expr\":$(_doc_jstr "$_w_expr"),\"eval\":$(_doc_jstr "$_w_kind"),\"bits\":$(_doc_jstr "$(_doc_hxstr "$WR_BITS")"),\"known\":$(_doc_jbool "$_w_known"),\"touched\":$(_doc_jstr "$(_doc_hxstr "$_w_touched")"),\"overlap\":$(_doc_jbool "$([ "$_w_inmask" -ne 0 ] && printf 1 || printf 0)"),\"owner\":$(_doc_jstr "$_w_owner"),\"product_guess\":$(_doc_jstr "$_w_prod")}"
|
||||
fi
|
||||
# 判定矩阵留痕:形态 -> 覆盖位 -> 是否与 mmx_mask 重叠
|
||||
if [ "$_c3_third" -le 40 ]; then
|
||||
_c3_eval="${_c3_eval}${_c3_eval:+,}{\"fam\":$(_doc_jstr "$_w_fam"),\"table\":$(_doc_jstr "$_w_tab"),\"chain\":$(_doc_jstr "$_w_chn"),\"handle\":$(_doc_jstr "$_w_hnd"),\"field\":$(_doc_jstr "$_w_fld"),\"form\":$(_doc_jstr "$_w_form"),\"src\":$(_doc_jstr "${_w_src:-}"),\"expr\":$(_doc_jstr "$_w_expr"),\"bits\":$(_doc_jstr "$(_doc_hxstr "$WR_BITS")"),\"known\":$(_doc_jbool "$_w_known"),\"kind\":$(_doc_jstr "$_w_kind"),\"overlap\":$(_doc_jbool "$([ "$_w_inmask" -ne 0 ] && printf 1 || printf 0)")}"
|
||||
fi
|
||||
if [ "$(( _w_touched & _M ))" -ne 0 ]; then
|
||||
_c3_overlap=$((_c3_overlap + 1))
|
||||
DOC_C3_OVERLAP_NAMES="${DOC_C3_OVERLAP_NAMES}${DOC_C3_OVERLAP_NAMES:+ }${_w_prod:-third_party}"
|
||||
@@ -1292,11 +1512,51 @@ EOF
|
||||
else
|
||||
_c3_overlap_unordered=$((_c3_overlap_unordered + 1))
|
||||
fi
|
||||
if [ "$_w_fld" = "ctmark" ]; then
|
||||
_c3_ct=$((_c3_ct + 1))
|
||||
[ "$_c3_ct" -le 3 ] &&
|
||||
_c3_ct_names="${_c3_ct_names}${_c3_ct_names:+, }${_w_fam} ${_w_tab} ${_w_chn}(${_w_expr})"
|
||||
# 产品名只是 hint:名字级证据 > 值签名(低置信度)> 未识别。
|
||||
if [ "$_c3_hint_conf" != "high" ]; then
|
||||
if [ -n "$_w_prod" ]; then
|
||||
_c3_hint=$_w_prod
|
||||
_c3_hint_conf=high
|
||||
_c3_hint_basis=name
|
||||
elif _doc_val_in_mask "$_w_val" && [ "$HEX" = "256" ]; then
|
||||
# 0x100 既可能是 OAF 的默认 ct mark,也是 mwan3 的 wan1
|
||||
# 线路值:只作低置信度猜测,绝不参与 verdict。
|
||||
_c3_hint=oaf
|
||||
_c3_hint_conf=low
|
||||
_c3_hint_basis=value_signature
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
else
|
||||
_c3_outside="${_c3_outside}${_c3_outside:+,}{\"fam\":$(_doc_jstr "$_w_fam"),\"table\":$(_doc_jstr "$_w_tab"),\"chain\":$(_doc_jstr "$_w_chn"),\"handle\":$(_doc_jstr "$_w_hnd"),\"product\":$(_doc_jstr "${_w_prod:-third_party}"),\"value\":$(_doc_jstr "$_w_val")}"
|
||||
_c3_outside="${_c3_outside}${_c3_outside:+,}{\"fam\":$(_doc_jstr "$_w_fam"),\"table\":$(_doc_jstr "$_w_tab"),\"chain\":$(_doc_jstr "$_w_chn"),\"handle\":$(_doc_jstr "$_w_hnd"),\"product\":$(_doc_jstr "${_w_prod:-third_party}"),\"form\":$(_doc_jstr "$_w_form"),\"expr\":$(_doc_jstr "$_w_expr"),\"bits\":$(_doc_jstr "$(_doc_hxstr "$WR_BITS")"),\"value\":$(_doc_jstr "$_w_val")}"
|
||||
_c3_outside_n=$((_c3_outside_n + 1))
|
||||
# fix39:求值结论 = 无重叠。必须让用户看见"为什么没报",
|
||||
# 否则一次误报修完只留下"哦现在不报了"的不信任。
|
||||
if [ "$_w_kind" = "mask_expr" ]; then
|
||||
_w_seg=$_w_msk
|
||||
[ "$_w_val" = "-" ] || _w_seg="${_w_msk} | ${_w_val}"
|
||||
_w_key="${_w_tab}/${_w_chn}/${_w_seg}"
|
||||
case "$_c3_disjoint_keys" in
|
||||
*" $_w_key "*)
|
||||
;;
|
||||
*)
|
||||
_c3_disjoint_keys="${_c3_disjoint_keys}${_w_key} "
|
||||
_c3_disjoint_n=$((_c3_disjoint_n + 1))
|
||||
if [ "$_c3_disjoint_n" -le 4 ]; then
|
||||
_c3_disjoint="${_c3_disjoint}${_w_tab} ${_w_chn} 的 fwmark 同步使用 ${_w_seg} 位段,与 mmx_mask($DOC_MMX_MASK) 无重叠(已验证)
|
||||
"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
elif [ "$_w_kind" = "read_from_ct" ]; then
|
||||
_c3_readn=$((_c3_readn + 1))
|
||||
[ -n "$_c3_read_txt" ] || _c3_read_txt="${_w_tab} ${_w_chn} 的 ${_w_expr}"
|
||||
fi
|
||||
fi
|
||||
[ "$_w_fld" = "ctmark" ] && [ "$(( _w_touched & _M ))" -ne 0 ] && _c3_ct=$((_c3_ct + 1))
|
||||
;;
|
||||
esac
|
||||
done <<EOF
|
||||
@@ -1307,6 +1567,10 @@ EOF
|
||||
_c3_readers=""
|
||||
_c3_starved=""
|
||||
_c3_starved_n=0
|
||||
# mwan3 线路 rule 家族(fwmark <线值>/<mmx_mask>):这是 mwan3 自己的读者,
|
||||
# 0x100/0x200/... 与 OAF 默认 mark 撞值也不改变归属(只做事实登记)。
|
||||
_c3_line_n=0
|
||||
_c3_line_vals=""
|
||||
while IFS=" " read -r _r_pref _r_val _r_mask _r_lk _r_iif _r_sup _r_not; do
|
||||
[ -n "${_r_pref:-}" ] || continue
|
||||
[ "$_r_val" = "-" ] && continue
|
||||
@@ -1315,6 +1579,11 @@ EOF
|
||||
_r_v=$HEX
|
||||
_doc_hx "$_r_mask"
|
||||
_r_m=$HEX
|
||||
if [ "$_r_m" -eq "$_M" ] && [ "$_r_v" -ne 0 ]; then
|
||||
_c3_line_n=$((_c3_line_n + 1))
|
||||
[ "$_c3_line_n" -le 8 ] &&
|
||||
_c3_line_vals="${_c3_line_vals}${_c3_line_vals:+,}$(_doc_jstr "$_r_val")"
|
||||
fi
|
||||
# 精确匹配(无掩码)且值的位段内有 mwan3 的位 -> mwan3 清位后这条规则失配
|
||||
if [ "$_r_m" -ne "$_M" ] && [ "$(( _r_v & _M ))" -ne 0 ]; then
|
||||
_c3_starved="${_c3_starved}${_c3_starved:+,}{\"where\":\"ip rule\",\"pref\":$(_doc_jstr "$_r_pref"),\"value\":$(_doc_jstr "$_r_val"),\"lookup\":$(_doc_jstr "$_r_lk")}"
|
||||
@@ -1346,23 +1615,30 @@ EOF
|
||||
_c3_route="null"
|
||||
fi
|
||||
|
||||
DOC_C3_FACTS="\"mmx_mask\":$(_doc_jstr "$DOC_MMX_MASK"),\"mmx_mask_source\":$(_doc_jstr "$DOC_MMX_SOURCE"),\"writers\":[$_c3_writers],\"readers\":[$_c3_readers],\"mwan3_min_pref\":$DOC_MINPREF,\"third_party_outside_mask\":[$_c3_outside],\"reader_starved\":[$_c3_starved],\"route_get_mark\":$_c3_route"
|
||||
|
||||
_c3_find=""
|
||||
_doc_find3() {
|
||||
_c3_find="${_c3_find}${_c3_find:+,}{\"code\":$(_doc_jstr "$1"),\"verdict\":$(_doc_jstr "$2"),\"detail\":$(_doc_jstr "$3"),\"evidence\":$(_doc_jstr "$4")}"
|
||||
}
|
||||
_c3_collision="null"
|
||||
if [ "$_c3_ct" -gt 0 ]; then
|
||||
_c3_collision="{\"kind\":\"ctmark\",\"count\":$_c3_ct,\"writers\":[$(_doc_jstr "$_c3_ct_names")],\"hint\":$(_doc_jstr "$_c3_hint"),\"hint_confidence\":$(_doc_jstr "$_c3_hint_conf"),\"hint_basis\":$(_doc_jstr "$_c3_hint_basis")}"
|
||||
fi
|
||||
DOC_C3_FACTS="\"mmx_mask\":$(_doc_jstr "$DOC_MMX_MASK"),\"mmx_mask_source\":$(_doc_jstr "$DOC_MMX_SOURCE"),\"writer_total\":$_c3_wn,\"writers\":[$_c3_writers],\"excluded_count\":$_c3_excl_n,\"excluded\":{\"mwan3\":$_c3_excl_mw,\"isp_split\":$_c3_excl_own},\"excluded_writers\":[$_c3_excluded],\"write_eval\":{\"rule\":\"覆盖位 = mask | orbits(跨字段);同字段按 mask 内写 + mask 外清;无掩码整值写不可判定\",\"mmx_mask\":$(_doc_jstr "$DOC_MMX_MASK"),\"writers\":[$_c3_eval],\"disjoint_count\":$_c3_disjoint_n,\"read_direction_count\":$_c3_readn,\"unevaluable_count\":$_c3_unknown_n},\"line_mark_rules\":{\"owner\":\"mwan3\",\"mask\":$(_doc_jstr "$DOC_MMX_MASK"),\"count\":$_c3_line_n,\"values\":[$_c3_line_vals]},\"readers\":[$_c3_readers],\"mwan3_min_pref\":$DOC_MINPREF,\"third_party_outside_mask\":[$_c3_outside],\"reader_starved\":[$_c3_starved],\"collision\":$_c3_collision,\"route_get_mark\":$_c3_route"
|
||||
|
||||
if [ "$DOC_P4B" != "1" ]; then
|
||||
DOC_C3_VERDICT=unknown
|
||||
_doc_find3 "" unknown "没有 table inet mwan3(mwan3-nft 未运行),无法判定位段占用" "P4b"
|
||||
_doc_find3 "" unknown "没有 mwan3 的 nft 表(inet/ip/ip6 都不存在,mwan3-nft 未运行),无法判定位段占用" "P4b"
|
||||
DOC_C3_ADVICE="先确认 mwan3(nft 版)在跑;只看 /etc/config/mwan3 无法判断运行态。"
|
||||
elif [ "$_c3_wn" -eq 0 ]; then
|
||||
DOC_C3_VERDICT=ok
|
||||
_doc_find3 "" ok "规则表里没有任何 mark 写者" "P4"
|
||||
elif [ "$_c3_ct" -gt 0 ]; then
|
||||
DOC_C3_VERDICT=conflict
|
||||
_doc_find3 "CTMARK_COLLISION" conflict "有程序在写 ct mark 的位段(OAF 类 DPI),改道语义会串" "P4 ct mark set"
|
||||
case "$_c3_hint_basis" in
|
||||
name) _c3_hint_txt="疑似 $(_doc_product_label "$_c3_hint")(表名/链名匹配,置信度高)" ;;
|
||||
value_signature) _c3_hint_txt="疑似 $(_doc_product_label "$_c3_hint")(ct mark 0x100 与 mwan3 的 wan1 线路值撞值;仅值签名,置信度低,不作判据)" ;;
|
||||
*) _c3_hint_txt="产品未识别(不建议按名字臆断)" ;;
|
||||
esac
|
||||
_c3_hint_txt_more=""
|
||||
[ "$_c3_ct_unknown" -gt 0 ] &&
|
||||
_c3_hint_txt_more=";其中 $_c3_ct_unknown 条 ct mark 写入形态无法静态求值(整值写/未加掩码),按保守口径计入"
|
||||
_doc_find3 "CTMARK_COLLISION" conflict "有第三方程序改写了 ct mark 中与 mmx_mask($DOC_MMX_MASK) 重叠的位:$_c3_ct_names;$_c3_hint_txt${_c3_hint_txt_more}" "P4 ct mark set(已排除 mwan3/isp-split 自家写者 $_c3_excl_n 条)"
|
||||
elif [ "$_c3_overlap_unordered" -gt 0 ]; then
|
||||
DOC_C3_VERDICT=conflict
|
||||
_doc_find3 "MARK_OVERLAP_UNORDERED" conflict "有 $_c3_overlap_unordered 个第三方写者落在 mmx_mask 位段内,且没有排在 mwan3 之前的 rule" "P4 + P5"
|
||||
@@ -1374,7 +1650,18 @@ EOF
|
||||
_doc_find3 "MARK_OUTSIDE" ok "第三方 mark 写者共 $_c3_outside_n 个,全部落在 mmx_mask 之外" "P4"
|
||||
else
|
||||
DOC_C3_VERDICT=ok
|
||||
_doc_find3 "" ok "标记位段只有 mwan3 自己在用" "P4"
|
||||
_doc_find3 "" ok "标记位段只有 mwan3/isp-split 自己在用($_c3_excl_n 条自家写者已按归属排除,第三方 0 条)" "P4"
|
||||
fi
|
||||
# fix39:求值结论 = 无重叠的写者,逐条记 info。判据是"覆盖位 & mmx_mask == 0",
|
||||
# 文案必须带上具体位段,否则用户只看到"现在不报了"而不知道为什么。
|
||||
while IFS= read -r _c3_note; do
|
||||
[ -n "${_c3_note:-}" ] || continue
|
||||
_doc_find3 "MARK_FWMARK_DISJOINT" info "$_c3_note" "P4 表达式求值:覆盖位 = mask | orbits;(mask|orbits) & mmx_mask($DOC_MMX_MASK) = 0"
|
||||
done <<EOF
|
||||
${_c3_disjoint}
|
||||
EOF
|
||||
if [ "$_c3_readn" -gt 0 ]; then
|
||||
_doc_find3 "MARK_READ_DIRECTION" info "有 $_c3_readn 条规则只读 ct mark、写 packet mark(读向,例如 ${_c3_read_txt}),不写 ct mark,不计入冲突" "P4 读向(ct -> packet)"
|
||||
fi
|
||||
if [ "$_c3_starved_n" -gt 0 ]; then
|
||||
[ "$DOC_C3_VERDICT" = "ok" ] && DOC_C3_VERDICT=warn
|
||||
@@ -1384,9 +1671,15 @@ EOF
|
||||
_doc_find3 "MMX_MASK_CUSTOM" ok "mmx_mask=$(printf '%s' "$DOC_MMX_MASK") 不是默认 0x3F00,本报告的阈值已按它现算" "P11"
|
||||
|
||||
case "$DOC_C3_VERDICT" in
|
||||
ok) DOC_C3_ADVICE="路由标记位段只有 mwan3 在用(或第三方全部在位段之外),分流选路正常。" ;;
|
||||
ok) DOC_C3_ADVICE="标记位段只有 mwan3/isp-split 自己(或位段之外的第三方)在用,分流选路正常。" ;;
|
||||
warn) DOC_C3_ADVICE="无需改动即可用;若要彻底消除歧义,把代理的 fwmark 移到 mmx_mask 之外(如 0x80000 段)。" ;;
|
||||
conflict) DOC_C3_ADVICE="检测到有程序直接改写与 mwan3 相同的标记位,分流可能选错线;建议把它的标记值改到位段之外,或把它排到 mwan3 之后。" ;;
|
||||
conflict)
|
||||
if [ "$_c3_ct" -gt 0 ]; then
|
||||
DOC_C3_ADVICE="检测到第三方程序改写了 mwan3 用的 ct mark 位段(mmx_mask);分流可能选错线。先把它的 mark 值移到位段之外,或让它排在 mwan3 之后;产品名只是提示,别按名字下结论。"
|
||||
else
|
||||
DOC_C3_ADVICE="检测到第三方程序改写了与 mwan3 相同的标记位,分流可能选错线;建议把它的标记值改到位段之外,或把它排到 mwan3 之后。"
|
||||
fi
|
||||
;;
|
||||
unknown) DOC_C3_ADVICE="没能读取当前 nft 规则,无法判断标记位是否被占用。" ;;
|
||||
esac
|
||||
DOC_C3_FIND="$_c3_find"
|
||||
@@ -1471,31 +1764,26 @@ doc_check_writers() {
|
||||
_c5_inmask=0
|
||||
_c5_out=0
|
||||
_c5_legacy=0
|
||||
_c5_legacy_inmask=0
|
||||
_c5_third_inmask=0
|
||||
# 清单分两段:第三方/legacy 最多 40 条(决策相关,优先展示),
|
||||
# mwan3/isp-split 自家写者最多 10 条(生产上 mwan3_or_* 有上百条,
|
||||
# 全列会把真正的第三方挤出清单)。
|
||||
_c5_list=""
|
||||
while IFS=" " read -r _w_fam _w_tab _w_chn _w_hnd _w_fld _w_form _w_msk _w_val _w_cm; do
|
||||
_c5_list_n=0
|
||||
_c5_list_mw=""
|
||||
_c5_list_mw_n=0
|
||||
while IFS=" " read -r _w_fam _w_tab _w_chn _w_hnd _w_fld _w_form _w_msk _w_val _w_cm _w_src; do
|
||||
[ -n "${_w_fam:-}" ] || continue
|
||||
_c5_total=$((_c5_total + 1))
|
||||
_w_owner=$(_doc_owner_of "$_w_fam" "$_w_tab" "$_w_chn" "$_w_cm")
|
||||
_w_owned=0
|
||||
_w_cleared=0
|
||||
case "$_w_form" in
|
||||
set)
|
||||
_doc_hx "$_w_val"
|
||||
_w_owned=$(( HEX & DOC_MMX_MASK_DEC ))
|
||||
;;
|
||||
mask_set | mask_or)
|
||||
_doc_hx "$_w_val"
|
||||
_w_owned=$(( HEX & DOC_MMX_MASK_DEC ))
|
||||
_doc_hx "$_w_msk"
|
||||
_w_cleared=$(( (~HEX) & DOC_MMX_MASK_DEC ))
|
||||
;;
|
||||
mask_clear)
|
||||
_doc_hx "$_w_msk"
|
||||
_w_cleared=$(( (~HEX) & DOC_MMX_MASK_DEC ))
|
||||
;;
|
||||
esac
|
||||
_w_touched=$(( _w_cleared | _w_owned ))
|
||||
# 与检查三同源求值(fix39):不允许两套"写了哪些位"的算法漂移
|
||||
_doc_wr_eval "$_w_fld" "$_w_form" "$_w_msk" "$_w_val" "${_w_src:-}"
|
||||
if [ "$WR_KNOWN" = "0" ]; then
|
||||
_w_touched=$DOC_MMX_MASK_DEC
|
||||
else
|
||||
_w_touched=$(( WR_CLEAR | WR_BITS ))
|
||||
fi
|
||||
_w_prod=$(_doc_guess_product "$_w_fam" "$_w_tab" "$_w_chn")
|
||||
case "$_w_owner" in
|
||||
mwan3) _c5_mw=$((_c5_mw + 1)) ;;
|
||||
@@ -1506,20 +1794,34 @@ doc_check_writers() {
|
||||
if [ "$(( _w_touched & DOC_MMX_MASK_DEC ))" -ne 0 ]; then
|
||||
_c5_inmask=$((_c5_inmask + 1))
|
||||
case "$_w_owner" in
|
||||
third_party | legacy) _c5_third_inmask=$((_c5_third_inmask + 1)) ;;
|
||||
legacy) _c5_legacy_inmask=$((_c5_legacy_inmask + 1)) ;;
|
||||
third_party) _c5_third_inmask=$((_c5_third_inmask + 1)) ;;
|
||||
esac
|
||||
else
|
||||
_c5_out=$((_c5_out + 1))
|
||||
fi
|
||||
# JSON 体积上限:清单只列前 40 条(真实机器上写者通常 < 10)
|
||||
if [ "$_c5_total" -le 40 ]; then
|
||||
_c5_list="${_c5_list}${_c5_list:+,}{\"owner\":$(_doc_jstr "$_w_owner"),\"product_guess\":$(_doc_jstr "$_w_prod"),\"fam\":$(_doc_jstr "$_w_fam"),\"table\":$(_doc_jstr "$_w_tab"),\"chain\":$(_doc_jstr "$_w_chn"),\"handle\":$(_doc_jstr "$_w_hnd"),\"field\":$(_doc_jstr "$_w_fld"),\"form\":$(_doc_jstr "$_w_form"),\"mask\":$(_doc_jstr "$([ "$_w_msk" = "-" ] && printf '' || printf '%s' "$_w_msk")"),\"value\":$(_doc_jstr "$([ "$_w_val" = "-" ] && printf '' || printf '%s' "$_w_val")"),\"touched\":$(_doc_jstr "$(_doc_hxstr "$_w_touched")")}"
|
||||
fi
|
||||
# JSON 体积上限 + 优先级:第三方最多 40 条,自家写者最多 10 条
|
||||
case "$_w_owner" in
|
||||
mwan3 | isp-split)
|
||||
if [ "$_c5_list_mw_n" -lt 10 ]; then
|
||||
_c5_list_mw_n=$((_c5_list_mw_n + 1))
|
||||
_c5_list_mw="${_c5_list_mw}${_c5_list_mw:+,}{\"owner\":$(_doc_jstr "$_w_owner"),\"product_guess\":$(_doc_jstr "$_w_prod"),\"fam\":$(_doc_jstr "$_w_fam"),\"table\":$(_doc_jstr "$_w_tab"),\"chain\":$(_doc_jstr "$_w_chn"),\"handle\":$(_doc_jstr "$_w_hnd"),\"field\":$(_doc_jstr "$_w_fld"),\"form\":$(_doc_jstr "$_w_form"),\"mask\":$(_doc_jstr "$([ "$_w_msk" = "-" ] && printf '' || printf '%s' "$_w_msk")"),\"value\":$(_doc_jstr "$([ "$_w_val" = "-" ] && printf '' || printf '%s' "$_w_val")"),\"touched\":$(_doc_jstr "$(_doc_hxstr "$_w_touched")")}"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
if [ "$_c5_list_n" -lt 40 ]; then
|
||||
_c5_list_n=$((_c5_list_n + 1))
|
||||
_c5_list="${_c5_list}${_c5_list:+,}{\"owner\":$(_doc_jstr "$_w_owner"),\"product_guess\":$(_doc_jstr "$_w_prod"),\"fam\":$(_doc_jstr "$_w_fam"),\"table\":$(_doc_jstr "$_w_tab"),\"chain\":$(_doc_jstr "$_w_chn"),\"handle\":$(_doc_jstr "$_w_hnd"),\"field\":$(_doc_jstr "$_w_fld"),\"form\":$(_doc_jstr "$_w_form"),\"mask\":$(_doc_jstr "$([ "$_w_msk" = "-" ] && printf '' || printf '%s' "$_w_msk")"),\"value\":$(_doc_jstr "$([ "$_w_val" = "-" ] && printf '' || printf '%s' "$_w_val")"),\"touched\":$(_doc_jstr "$(_doc_hxstr "$_w_touched")")}"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
done <<EOF
|
||||
${DOC_W:-}
|
||||
EOF
|
||||
|
||||
# inet mwan3 里的外来链(有人往 mwan3 表里塞规则)
|
||||
# mwan3 表里的外来链(有人往 mwan3 表里塞规则)。
|
||||
# 3.6 的自有链名并不都是 mwan3* 前缀(iface_in_*、policy_*、dynamic、mwan3_hook),
|
||||
# 只认 mwan3* 会把 mwan3 自己的子链当成"外来"(fix38 同一类误判)。
|
||||
_c5_foreign=""
|
||||
_c5_foreign_n=0
|
||||
if [ -n "${DOC_P4:-}" ]; then
|
||||
@@ -1529,7 +1831,11 @@ EOF
|
||||
_c5_foreign_n=$((_c5_foreign_n + 1))
|
||||
done <<EOF
|
||||
$(printf '%s\n' "$DOC_P4" | awk '
|
||||
/^[ \t]*table / { intab = ($2 == "inet" && $3 == "mwan3"); next }
|
||||
/^[ \t]*table / {
|
||||
intab = (($2 == "inet" || $2 == "ip" || $2 == "ip6") &&
|
||||
($3 == "mwan3" || $3 ~ /^mwan3[_-]/))
|
||||
next
|
||||
}
|
||||
{
|
||||
if (!intab) next
|
||||
tl = $0
|
||||
@@ -1537,13 +1843,16 @@ $(printf '%s\n' "$DOC_P4" | awk '
|
||||
if (index(tl, "chain ") != 1) next
|
||||
n = split(tl, A, " ")
|
||||
c = A[2]
|
||||
if (c ~ /^mwan3/) next
|
||||
if (c ~ /^mwan3/ || c ~ /^iface_(in|out)_/ || c ~ /^policy_/ || c ~ /^dynamic/ || c == "mwan3_hook") next
|
||||
print c
|
||||
}')
|
||||
EOF
|
||||
fi
|
||||
|
||||
DOC_C5_FACTS="\"counts\":{\"total\":$_c5_total,\"mwan3\":$_c5_mw,\"isp_split\":$_c5_own,\"third_party\":$_c5_third,\"legacy\":$_c5_legacy,\"in_mask\":$_c5_inmask,\"third_party_in_mask\":$_c5_third_inmask,\"outside_mask\":$_c5_out},\"writers\":[$_c5_list],\"foreign_chains_in_mwan3\":[$_c5_foreign],\"legacy_writers\":$(_doc_jbool "$([ "$_c5_legacy" -gt 0 ] && printf 1 || printf 0)")"
|
||||
_c5_writers_all="$_c5_list"
|
||||
[ -n "$_c5_list_mw" ] &&
|
||||
_c5_writers_all="${_c5_writers_all}${_c5_writers_all:+,}${_c5_list_mw}"
|
||||
DOC_C5_FACTS="\"counts\":{\"total\":$_c5_total,\"mwan3\":$_c5_mw,\"isp_split\":$_c5_own,\"third_party\":$_c5_third,\"legacy\":$_c5_legacy,\"legacy_in_mask\":$_c5_legacy_inmask,\"in_mask\":$_c5_inmask,\"third_party_in_mask\":$_c5_third_inmask,\"outside_mask\":$_c5_out},\"writers\":[$_c5_writers_all],\"foreign_chains_in_mwan3\":[$_c5_foreign],\"legacy_writers\":$(_doc_jbool "$([ "$_c5_legacy" -gt 0 ] && printf 1 || printf 0)")"
|
||||
|
||||
_c5_find=""
|
||||
_doc_find5() {
|
||||
@@ -1554,11 +1863,11 @@ EOF
|
||||
_c5_verdict=conflict
|
||||
elif [ "$_c5_foreign_n" -gt 0 ]; then
|
||||
_c5_verdict=warn
|
||||
_doc_find5 "MWAN3_TABLE_FOREIGN_CHAIN" warn "inet mwan3 表里有非 mwan3* 的链:$_c5_foreign" "P4"
|
||||
elif [ "$_c5_legacy" -gt 0 ]; then
|
||||
_doc_find5 "MWAN3_TABLE_FOREIGN_CHAIN" warn "mwan3 表里有不属于 mwan3 的链(已排除 mwan3*/iface_in_*/iface_out_*/policy_*/dynamic 等自有链名):$_c5_foreign" "P4"
|
||||
elif [ "$_c5_legacy_inmask" -gt 0 ]; then
|
||||
_c5_verdict=warn
|
||||
_doc_find5 "LEGACY_MARK_WRITER" warn "非 inet 表里有 mark 写者(iptables-nft 残留),清单里已列出" "P4 fam=ip/ip6"
|
||||
elif [ "$_c5_third" -eq 0 ]; then
|
||||
_doc_find5 "LEGACY_MARK_WRITER" warn "非 mwan3 的 ip/ip6 表里有 mark 写者落在 mmx_mask 位段内(iptables-nft 残留),清单里已列出" "P4 fam=ip/ip6"
|
||||
elif [ "$_c5_third" -eq 0 ] && [ "$_c5_legacy" -eq 0 ]; then
|
||||
_c5_verdict=ok
|
||||
_doc_find5 "" ok "规则表里没有第三方 mark 写者" "P4"
|
||||
elif [ "$_c5_third_inmask" -gt 0 ] && [ "${DOC_C3_VERDICT:-ok}" != "warn" ]; then
|
||||
@@ -1566,7 +1875,10 @@ EOF
|
||||
_doc_find5 "MARK_WRITERS_IN_MASK" warn "有写者的位段与 mmx_mask 有交集(明细见清单)" "P4 + P5"
|
||||
else
|
||||
_c5_verdict=ok
|
||||
_doc_find5 "MARK_WRITERS_OUTSIDE" ok "第三方写者共 $_c5_third 个,均不在 mmx_mask 位段内" "P4"
|
||||
_c5_out_txt="第三方写者共 $_c5_third 个,均不在 mmx_mask 位段内"
|
||||
[ "$_c5_legacy" -gt 0 ] &&
|
||||
_c5_out_txt="第三方/legacy 写者共 $((_c5_third + _c5_legacy)) 个,写入位均不在 mmx_mask 位段内(ip/ip6 表里的 $_c5_legacy 条经掩码表达式求值也不重叠)"
|
||||
_doc_find5 "MARK_WRITERS_OUTSIDE" ok "$_c5_out_txt" "P4"
|
||||
fi
|
||||
DOC_C5_VERDICT=$_c5_verdict
|
||||
DOC_C5_ADVICE="清单仅供排查;位段是否真的冲突以 mark_segment 的结论为准。"
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
# install 注册开机自启与每日更新
|
||||
# uninstall 卸载所有改动
|
||||
set -u
|
||||
ISP_VERSION="0.4.0"
|
||||
ISP_VERSION="0.4.1"
|
||||
|
||||
# 配置表里的注释行(# 开头,允许前导空白)必须在按空白展开之前整行删掉
|
||||
# (B-1)。否则 `for row in $ISP_TABLE` 会把 "#" 与后面的文字拆成两个
|
||||
|
||||
@@ -3,3 +3,7 @@
|
||||
SHA256SUMS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
dist/
|
||||
*.apk
|
||||
.ipkbuild/
|
||||
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-cf-dns-speedtest
|
||||
PKG_VERSION:=1.1.0
|
||||
PKG_RELEASE:=1
|
||||
PKG_RELEASE:=2
|
||||
PKG_LICENSE:=GPL-3.0-only
|
||||
PKG_MAINTAINER:=xiaokeikei
|
||||
|
||||
|
||||
@@ -49,3 +49,7 @@ opkg install ./luci-app-cf-dns-speedtest_1.1.0-1_x86_64.ipk
|
||||
[XIU2/CloudflareSpeedTest v2.3.5](https://github.com/XIU2/CloudflareSpeedTest/releases/tag/v2.3.5),
|
||||
该项目同样采用 GPL-3.0。Cloudflare、OpenWrt、iStoreOS、mosdns 和
|
||||
CloudflareSpeedTest 均为其各自权利人的项目或商标,本项目与其不存在官方隶属关系。
|
||||
|
||||
## OpenWrt 25.12 APK
|
||||
|
||||
MU300 / U30 Air 的 APK v3 包及构建、安装说明见 [APK 安装指南](docs/APK.md)。
|
||||
@@ -0,0 +1,18 @@
|
||||
# OpenWrt APK 安装包
|
||||
|
||||
面向 OpenWrt 25.12.5 / APK v3;MU300 / U30 Air 目标架构为 `aarch64_generic`。这不是安卓应用。保留原有 IPK 供 opkg 系统使用。
|
||||
|
||||
```sh
|
||||
apk update
|
||||
apk add --allow-untrusted ./mosdns-5.3.4-r14.apk ./luci-app-cf-dns-speedtest-*.apk
|
||||
```
|
||||
|
||||
本包未签名,仅在核对本发布页 SHA256SUMS 后安装。保留 `/etc/config` 中已有配置。
|
||||
|
||||
构建:Linux 上设置 `APK` 为 OpenWrt 25.12.5 SDK 中的 `staging_dir/host/bin/apk`,运行 `sudo --preserve-env=APK python3 tools/build_apk.py`。也可手动运行 GitHub Actions 的 Build OpenWrt APK。源文件只从 Git 跟踪清单读取,排除截图、缓存和历史安装包;源码包不含 Git 历史或本机路径。
|
||||
|
||||
验证覆盖原生 APK v3 打包与解包、逐文件内容校验及已有自动测试;未声称已在实体 U30 Air 上完成安装或联网验证。
|
||||
|
||||
APK 使用上游 XIU2/CloudflareSpeedTest v2.3.5 的 ARM64 程序,下载校验值固定在构建脚本中,并验证 ELF 架构。Git 中的 amd64 程序继续用于原有 x86_64 IPK,APK 不会使用它。程序遵循 GPL-3.0-only,源码:https://github.com/XIU2/CloudflareSpeedTest/tree/v2.3.5 。
|
||||
|
||||
官方 OpenWrt 软件源不含 mosdns,因此发布同时附带 sbwml/luci-app-mosdns v5.3.4-r14 的 aarch64_generic / OpenWrt 25.12 运行程序包。上游压缩包 SHA-256 在构建脚本中固定;只提取 mosdns APK,不安装上游 LuCI 插件、DNS 配置或地理数据库。依赖包保留上游原始文件及签名,遵循 GPL-3.0;对应构建配方与补丁:https://github.com/sbwml/luci-app-mosdns/tree/v5.3.4-r14/mosdns ,上游源码:https://github.com/IrineSistiana/mosdns/tree/v5.3.4 。
|
||||
@@ -0,0 +1,119 @@
|
||||
"""APK v3 via OpenWrt 25.12 SDK's apk mkpkg; only tracked files are input.
|
||||
Reference: openwrt/openwrt openwrt-25.12 include/package-pack.mk.
|
||||
"""
|
||||
import hashlib, io, os, pathlib, re, shutil, struct, subprocess, tarfile, tempfile, urllib.request, zipfile
|
||||
ROOT = pathlib.Path(__file__).resolve().parents[1]
|
||||
make = (ROOT / 'Makefile').read_text()
|
||||
NAME = re.search(r'PKG_NAME:=(\S+)', make)[1]
|
||||
VERSION = re.search(r'PKG_VERSION:=(\S+)', make)[1]
|
||||
RELEASE = re.search(r'PKG_RELEASE:=(\S+)', make)[1]
|
||||
APK = os.environ.get('APK', 'apk')
|
||||
OUT = ROOT / 'dist'
|
||||
FILES = subprocess.check_output(['git', '-c', f'safe.directory={ROOT}', 'ls-files', '-z'], cwd=ROOT).decode().split('\0')
|
||||
EPOCH = int(subprocess.check_output(['git', '-c', f'safe.directory={ROOT}', 'log', '-1', '--format=%ct'], cwd=ROOT))
|
||||
CF_URL = 'https://github.com/XIU2/CloudflareSpeedTest/releases/download/v2.3.5/cfst_linux_arm64.tar.gz'
|
||||
CF_SHA256 = '0ac992fcf24d4684caed33620deb9b83ce82f32d2418dc1f90be490ce5900300'
|
||||
|
||||
def allowed(f):
|
||||
return f and not f.startswith(('.git/', 'docs/images/', 'docs/screenshots/')) and pathlib.Path(f).suffix.lower() not in {'.apk', '.ipk', '.zip', '.gz', '.run', '.png', '.jpg', '.jpeg', '.webp', '.pyc'}
|
||||
|
||||
def checked(f, data):
|
||||
if b'\0' in data[:2000]:
|
||||
if f != 'root/usr/share/cf-dns-speedtest/cfst':
|
||||
raise ValueError('Unexpected binary: ' + f)
|
||||
return data
|
||||
text = data.decode('utf-8')
|
||||
if re.search(r'[A-Za-z]:[\\/]Users[\\/]|/home/[A-Za-z0-9_.-]+/|\b192\.168\.\d+\.\d+\b', text):
|
||||
raise ValueError('Private path or LAN address: ' + f)
|
||||
for mail in re.findall(r'[\w.+-]+@[\w.-]+\.[A-Za-z]{2,}', text):
|
||||
if not mail.endswith('@users.noreply.github.com'):
|
||||
raise ValueError('Personal email: ' + f)
|
||||
return data.replace(b'\r\n', b'\n')
|
||||
|
||||
def main():
|
||||
if os.geteuid() != 0:
|
||||
raise ValueError('Run with sudo to preserve root ownership in APK metadata')
|
||||
OUT.mkdir(exist_ok=True)
|
||||
if any(OUT.iterdir()):
|
||||
raise ValueError('Use an empty dist directory to avoid stale release files')
|
||||
with tempfile.TemporaryDirectory(prefix='apk-build-') as work:
|
||||
work = pathlib.Path(work)
|
||||
stage = work / 'root'
|
||||
stage.mkdir()
|
||||
prefix = 'files/' if NAME == 'luci-app-wan-latency' else 'root/'
|
||||
for f in filter(allowed, FILES):
|
||||
if not f.startswith(prefix):
|
||||
continue
|
||||
rel = f[len(prefix):]
|
||||
target = stage / rel
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
target.write_bytes(checked(f, (ROOT / f).read_bytes()))
|
||||
target.chmod(0o755 if rel.startswith(('etc/init.d/', 'usr/sbin/', 'usr/bin/', 'usr/libexec/')) else 0o644)
|
||||
os.utime(target, (EPOCH, EPOCH))
|
||||
if NAME == 'luci-app-cf-dns-speedtest':
|
||||
blob = urllib.request.urlopen(CF_URL, timeout=120).read()
|
||||
if hashlib.sha256(blob).hexdigest() != CF_SHA256:
|
||||
raise ValueError('Upstream checksum mismatch')
|
||||
with tarfile.open(fileobj=io.BytesIO(blob), mode='r:gz') as tf:
|
||||
member = next(m for m in tf if pathlib.PurePosixPath(m.name).name == 'cfst' and m.isfile())
|
||||
data = tf.extractfile(member).read()
|
||||
if data[:4] != b'\x7fELF' or struct.unpack('<H', data[18:20])[0] != 183:
|
||||
raise ValueError('Expected ARM64 ELF')
|
||||
target = stage / 'usr/share/cf-dns-speedtest/cfst'
|
||||
target.write_bytes(data)
|
||||
target.chmod(0o755)
|
||||
os.utime(target, (EPOCH, EPOCH))
|
||||
# Official OpenWrt feeds do not carry mosdns. Ship only its runtime
|
||||
# package, not luci-app-mosdns or unrelated geo databases.
|
||||
url = 'https://github.com/sbwml/luci-app-mosdns/releases/download/v5.3.4-r14/aarch64_generic-openwrt-25.12.tar.gz'
|
||||
bundle = urllib.request.urlopen(url, timeout=120).read()
|
||||
if hashlib.sha256(bundle).hexdigest() != '1c889fe6b0845c073653e9e7973ea926e90efb0669f641d2a31fcc8e107286c5':
|
||||
raise ValueError('mosdns dependency checksum mismatch')
|
||||
with tarfile.open(fileobj=io.BytesIO(bundle), mode='r:gz') as tf:
|
||||
member = next(m for m in tf if pathlib.PurePosixPath(m.name).name == 'mosdns-5.3.4-r14.apk' and m.isfile())
|
||||
(OUT / 'mosdns-5.3.4-r14.apk').write_bytes(tf.extractfile(member).read())
|
||||
arch = 'aarch64_generic' if NAME == 'luci-app-cf-dns-speedtest' else 'noarch'
|
||||
deps = re.search(r' DEPENDS:=(.*)', make)[1].replace('+', '').split()
|
||||
if NAME == 'luci-app-cpemonitor':
|
||||
deps = [d for d in deps if not d.startswith('kmod-')] + ['ip-full', 'flock']
|
||||
scripts = []
|
||||
for section, event in [('postinst', 'post-install'), ('postinst', 'post-upgrade'), ('prerm', 'pre-deinstall')]:
|
||||
match = re.search(r'define Package/' + re.escape(NAME) + '/' + section + r'\n(.*?)\nendef', make, re.S)
|
||||
if match:
|
||||
dest = work / event
|
||||
dest.write_text(match[1].replace('$$', '$') + '\n')
|
||||
scripts += ['--script', event + ':' + str(dest)]
|
||||
package = OUT / f'{NAME}-{VERSION}-r{RELEASE}-{arch}.apk'
|
||||
info = {'name': NAME, 'version': f'{VERSION}-r{RELEASE}', 'arch': arch,
|
||||
'license': 'GPL-3.0-only' if NAME.endswith('cf-dns-speedtest') else 'GPL-2.0-only',
|
||||
'description': 'LuCI ' + NAME.removeprefix('luci-app-') + ' for OpenWrt 25.12',
|
||||
'maintainer': 'Project contributors', 'depends': ' '.join(deps)}
|
||||
command = [APK, 'mkpkg']
|
||||
for key, value in info.items():
|
||||
command += ['--info', key + ':' + value]
|
||||
subprocess.run(command + scripts + ['--files', str(stage), '--output', str(package)], check=True)
|
||||
if package.read_bytes()[:3] != b'ADB':
|
||||
raise ValueError('Expected native APK v3 ADB container')
|
||||
unpack = work / 'unpacked'
|
||||
unpack.mkdir()
|
||||
subprocess.run([APK, 'extract', '--allow-untrusted', '--destination', str(unpack), str(package)], check=True)
|
||||
for source in stage.rglob('*'):
|
||||
if source.is_file():
|
||||
actual = unpack / source.relative_to(stage)
|
||||
if not actual.exists() or actual.read_bytes() != source.read_bytes() or actual.stat().st_uid != 0 or (actual.stat().st_mode & 0o777) != (source.stat().st_mode & 0o777):
|
||||
raise ValueError('Extracted payload mismatch: ' + str(source.relative_to(stage)))
|
||||
with zipfile.ZipFile(OUT / f'{NAME}-{VERSION}-{RELEASE}-source.zip', 'w', zipfile.ZIP_DEFLATED) as archive:
|
||||
for f in filter(allowed, FILES):
|
||||
if f == 'root/usr/share/cf-dns-speedtest/cfst':
|
||||
continue
|
||||
entry = zipfile.ZipInfo(NAME + '/' + f, (2026, 1, 1, 0, 0, 0))
|
||||
entry.compress_type = zipfile.ZIP_DEFLATED
|
||||
entry.external_attr = 0o100644 << 16
|
||||
archive.writestr(entry, checked(f, (ROOT / f).read_bytes()))
|
||||
shutil.copyfile(ROOT / 'docs/APK.md', OUT / 'INSTALL-APK.md')
|
||||
sums = ''.join(hashlib.sha256(p.read_bytes()).hexdigest() + ' ' + p.name + '\n' for p in sorted(OUT.iterdir()) if p.name != 'SHA256SUMS')
|
||||
(OUT / 'SHA256SUMS').write_text(sums)
|
||||
print('PASS native APK v3, exact payload round-trip, source privacy checks and SHA256SUMS')
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -1,8 +1,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-isp-split
|
||||
PKG_VERSION:=0.4.0
|
||||
PKG_RELEASE:=6
|
||||
PKG_VERSION:=0.4.1
|
||||
PKG_RELEASE:=7
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
|
||||
@@ -169,7 +169,6 @@ return view.extend({
|
||||
o.rmempty = false;
|
||||
|
||||
o = s.option(form.Value, 'def_fwmark_value', _('Default ') + _('Fwmark value'));
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.option(form.Value, 'def_tcp_interval', _('Default ') + _('TCP ') + _('keep-alive interval (seconds)'));
|
||||
o.datatype = "and(uinteger, min(1))";
|
||||
@@ -280,7 +279,10 @@ return view.extend({
|
||||
let udp_stun_host = uci.get_first(conf, 'global', 'def_udp_stun');
|
||||
let tcp_stun_host = uci.get_first(conf, 'global', 'def_tcp_stun');
|
||||
|
||||
return fs.exec('/usr/libexec/natmap/natcheck.sh', [udp_stun_host + ':3478', tcp_stun_host + ':3478', test_port, nattest_result_path])
|
||||
return fs.exec('/usr/libexec/natmap/natcheck.sh', [
|
||||
udp_stun_host + (udp_stun_host.match(/:\d+$/) ? '' : ':3478'),
|
||||
tcp_stun_host + (tcp_stun_host.match(/:\d+$/) ? '' : ':3478'),
|
||||
test_port, nattest_result_path])
|
||||
.then((res) => { return window.location = window.location.href.split('#')[0] })
|
||||
.catch((e) => { ui.addNotification(null, E('p', e.message), 'error') });
|
||||
};
|
||||
@@ -288,7 +290,7 @@ return view.extend({
|
||||
if (nattest_result.length) {
|
||||
o = s.option(form.DummyValue, '_nattest_result', ' ');
|
||||
o.rawhtml = true;
|
||||
o.cfgvalue = function(s) {
|
||||
o.cfgvalue = function(section_id) {
|
||||
return '<details><summary>' + _('Expand/Collapse result') + '</summary>' + nattest_result + '</details>';
|
||||
}
|
||||
};
|
||||
@@ -308,35 +310,28 @@ return view.extend({
|
||||
o = s.option(form.Flag, 'enable', _('Enable'));
|
||||
o.default = o.disabled;
|
||||
o.editable = true;
|
||||
o.rmempty = true;
|
||||
o.modalonly = false;
|
||||
|
||||
o = s.taboption('general', form.Value, 'interval', _('Keep-alive interval'));
|
||||
o.datatype = "and(uinteger, min(1))";
|
||||
o.rmempty = true;
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('general', form.Value, 'stun_cycle', _('STUN check cycle (once every n intervals)'), _('For UDP mode'));
|
||||
o.datatype = 'uinteger';
|
||||
o.rmempty = true;
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('general', form.Value, 'stun_server', _('STUN server'));
|
||||
o.datatype = 'or(hostname, hostport)';
|
||||
o.rmempty = true;
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('general', form.Value, 'http_server', _('HTTP server'), _('For TCP mode'));
|
||||
o.datatype = 'or(hostname, hostport)';
|
||||
o.rmempty = true;
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('general', form.Value, 'fwmark_value', _('Fwmark value'), _('Mark fwmark for STUN/HTTP outbound traffic'));
|
||||
o.rmempty = true;
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('general', form.Value, 'comment', _('Comment'));
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('general', form.ListValue, 'udp_mode', _('Protocol'));
|
||||
o.default = '0';
|
||||
@@ -380,7 +375,6 @@ return view.extend({
|
||||
o.noaliases = true;
|
||||
o.nobridges = true;
|
||||
o.nocreate = false;
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('general', form.Value, 'port', _('Bind port'),
|
||||
_('Note: After using <code>portrange</code>, the public ports will be opened in rotation</br>') +
|
||||
@@ -411,11 +405,11 @@ return view.extend({
|
||||
let cval = this.cfgvalue(section_id) || this.default;
|
||||
let i = this.keylist.indexOf(cval);
|
||||
return [this.vallist[i], cval];
|
||||
}.call(s.getOption('forward_mode'));
|
||||
}.call(this.section.getOption('forward_mode'));
|
||||
let loopback = function() {
|
||||
let cval = this.cfgvalue(section_id) || this.default;
|
||||
return (cval == this.enabled) ? ' L' : '';
|
||||
}.call(s.getOption('natloopback'));
|
||||
}.call(this.section.getOption('natloopback'));
|
||||
return (cval == this.enabled) ? mode[0] + (mode[1] === 'dnat' ? loopback : '') : _('No');
|
||||
};
|
||||
|
||||
@@ -432,7 +426,7 @@ return view.extend({
|
||||
let E = document.getElementById('widget.' + this.cbid(section_id).match(/.+\./) + 'family');
|
||||
let i = E ? E.selectedIndex : null;
|
||||
return E ? E.options[i].value : null;
|
||||
}.call(s.getOption('family'));
|
||||
}.call(this.section.getOption('family'));
|
||||
|
||||
if (value == 'dnat' && family == 'ipv6')
|
||||
return _('The DNAT method not support under IPv6');
|
||||
@@ -442,7 +436,6 @@ return view.extend({
|
||||
|
||||
o = s.taboption('forward', form.Flag, 'natloopback', _('NAT loopback'));
|
||||
o.default = o.enabled;
|
||||
o.rmempty = true;
|
||||
o.retain = true;
|
||||
o.depends('forward_mode', 'dnat');
|
||||
o.modalonly = true;
|
||||
@@ -452,14 +445,12 @@ return view.extend({
|
||||
congestions.forEach((res) => {
|
||||
o.value.apply(o, [res]);
|
||||
})
|
||||
o.rmempty = true;
|
||||
o.depends('forward_mode', 'via');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('forward', form.Value, 'forward_timeout', _('Forward timeout'), _('Port forwarding session idle timeout in seconds'));
|
||||
o.datatype = "and(uinteger, min(1))";
|
||||
o.placeholder = '300000';
|
||||
o.rmempty = true;
|
||||
o.depends('forward_mode', 'via');
|
||||
o.modalonly = true;
|
||||
|
||||
@@ -491,7 +482,7 @@ return view.extend({
|
||||
let enforward = function() {
|
||||
let cval = this.cfgvalue(section_id) || this.default;
|
||||
return (cval == this.enabled) ? true : false;
|
||||
}.call(s.getOption('forward'));
|
||||
}.call(this.section.getOption('forward'));
|
||||
return enforward ? this.vallist[i] ?? cval : _('No');
|
||||
};
|
||||
|
||||
@@ -505,16 +496,16 @@ return view.extend({
|
||||
let enforward = function() {
|
||||
let cval = this.cfgvalue(section_id) || this.default;
|
||||
return (cval == this.enabled) ? true : false;
|
||||
}.call(s.getOption('forward'));
|
||||
}.call(this.section.getOption('forward'));
|
||||
let refresh = function() {
|
||||
let cval = this.cfgvalue(section_id) || this.default;
|
||||
return (cval == this.enabled) ? true : false;
|
||||
}.call(s.getOption('refresh'));
|
||||
}.call(this.section.getOption('refresh'));
|
||||
let cltname = function() {
|
||||
let cval = this.cfgvalue(section_id) || this.default;
|
||||
let i = this.keylist.indexOf(cval);
|
||||
return this.vallist[i];
|
||||
}.call(s.getOption('clt_script'));
|
||||
}.call(this.section.getOption('clt_script'));
|
||||
return enforward ? ((cval == '0' && refresh) ? cltname : cval) : _('No');
|
||||
};
|
||||
|
||||
@@ -555,14 +546,12 @@ return view.extend({
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('forward', form.Value, 'clt_username', _('Username'));
|
||||
o.rmempty = true;
|
||||
o.retain = true;
|
||||
o.depends('refresh', '1');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('forward', form.Value, 'clt_password', _('Password'));
|
||||
o.password = true;
|
||||
o.rmempty = true;
|
||||
o.depends('refresh', '1');
|
||||
o.modalonly = true;
|
||||
|
||||
@@ -583,7 +572,6 @@ return view.extend({
|
||||
o = s.taboption('notify', form.Flag, 'notify_enable', _('EnNotify'));
|
||||
o.default = o.disabled;
|
||||
o.editable = true;
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('notify', form.ListValue, 'notify_script', _('Notify Scripts'));
|
||||
o.datatype = 'file';
|
||||
@@ -602,24 +590,20 @@ return view.extend({
|
||||
.format('https://github.com/muink/openwrt-natmapt/tree/master/files/notify/', _('<code># All external tokens required</code> Field')));
|
||||
o.datatype = 'list(string)';
|
||||
o.placeholder = 'KEY=VAL';
|
||||
o.rmempty = true;
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('notify', form.Value, 'notify_custom_domain', _('Private API Domain'));
|
||||
o.datatype = 'hostname';
|
||||
o.placeholder = 'api.example.com';
|
||||
o.rmempty = true;
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('notify', form.Value, 'notify_text', _('Text content'));
|
||||
o.placeholder = 'NATMap: <comment>: [<protocol>] <inner_ip>:<inner_port> -> <ip>:<port>';
|
||||
o.rmempty = true;
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('ddns', form.Flag, 'ddns_enable', _('EnDDNS'));
|
||||
o.default = o.disabled;
|
||||
o.editable = true;
|
||||
o.rmempty = true;
|
||||
|
||||
o = s.taboption('ddns', form.ListValue, 'ddns_script', _('DDNS Scripts'));
|
||||
o.datatype = 'file';
|
||||
@@ -638,23 +622,43 @@ return view.extend({
|
||||
.format('https://github.com/muink/openwrt-natmapt/tree/master/files/ddns/', _('<code># All external tokens required</code> Field')));
|
||||
o.datatype = 'list(string)';
|
||||
o.placeholder = 'KEY=VAL';
|
||||
o.rmempty = true;
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('ddns', form.Value, 'ddns_a', _('A Record ') + _('FQDN'));
|
||||
o.datatype = 'hostname';
|
||||
o.placeholder = 'www.example.com';
|
||||
o.rmempty = true;
|
||||
o.depends('family', 'ipv4');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('ddns', form.Value, 'ddns_aaaa', _('AAAA Record ') + _('FQDN'));
|
||||
o.datatype = 'hostname';
|
||||
o.placeholder = 'ipv6.example.com';
|
||||
o.rmempty = true;
|
||||
o.depends('family', 'ipv6');
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('ddns', form.DummyValue, '_ddns_txt_dump', _('TXT Record'));
|
||||
o.rawhtml = false;
|
||||
o.cfgvalue = function(section_id) {
|
||||
let fqdn = uci.get(conf, section_id, 'ddns_txt');
|
||||
let cont = uci.get(conf, section_id, 'ddns_txt_content');
|
||||
|
||||
if ( fqdn && cont )
|
||||
return fqdn + '. <TTL> IN TXT ' + cont;
|
||||
};
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('ddns', form.Value, 'ddns_txt', _('FQDN'));
|
||||
o.datatype = 'hostname';
|
||||
o.placeholder = 'txt.example.com';
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('ddns', form.Value, 'ddns_txt_content', _('Content'));
|
||||
o.placeholder = '"port={{port}}; target={{ip}}"';
|
||||
o.default = '"port={{port}}; target={{ip}}"';
|
||||
o.rmempty = false;
|
||||
o.depends({ ddns_txt: "", "!reverse": true })
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('ddns', form.DummyValue, '_ddns_srv_dump', _('SRV Record'));
|
||||
o.rawhtml = false;
|
||||
o.cfgvalue = function(section_id) {
|
||||
@@ -673,13 +677,13 @@ return view.extend({
|
||||
o = s.taboption('ddns', form.Value, 'ddns_srv', _('FQDN'));
|
||||
o.datatype = 'hostname';
|
||||
o.placeholder = 'mc.example.com';
|
||||
o.rmempty = true;
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('ddns', form.Value, 'ddns_srv_serv', _('Service'), _('Can refer to RFC8552'));
|
||||
o.value('http');
|
||||
o.value('minecraft');
|
||||
o.value('factorio');
|
||||
o.value('easytier');
|
||||
o.default = 'minecraft';
|
||||
o.rmempty = false;
|
||||
o.depends({ ddns_srv: "", "!reverse": true })
|
||||
@@ -689,6 +693,7 @@ return view.extend({
|
||||
o.value('tcp', _('TCP'));
|
||||
o.value('udp', _('UDP'));
|
||||
o.value('tls', _('TLS'));
|
||||
o.value('wg', _('WireGuard'));
|
||||
o.default = 'tcp';
|
||||
o.rmempty = false;
|
||||
o.depends({ ddns_srv: "", "!reverse": true })
|
||||
@@ -697,21 +702,20 @@ return view.extend({
|
||||
o = s.taboption('ddns', form.Value, 'ddns_srv_target', _('Target'));
|
||||
o.datatype = 'hostname';
|
||||
o.placeholder = 'cdn.example.com';
|
||||
o.rmempty = true;
|
||||
o.depends({ ddns_srv: "", "!reverse": true })
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('ddns', form.Value, 'ddns_srv_priority', _('Priority'));
|
||||
o.datatype = 'range(0, 65535)';
|
||||
o.default = 0;
|
||||
o.rmempty = true;
|
||||
o.rmempty = false;
|
||||
o.depends({ ddns_srv: "", "!reverse": true })
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('ddns', form.Value, 'ddns_srv_weight', _('Weight'));
|
||||
o.datatype = 'range(0, 65535)';
|
||||
o.default = 65535;
|
||||
o.rmempty = true;
|
||||
o.rmempty = false;
|
||||
o.depends({ ddns_srv: "", "!reverse": true })
|
||||
o.modalonly = true;
|
||||
|
||||
@@ -731,28 +735,27 @@ return view.extend({
|
||||
o = s.taboption('ddns', form.Value, 'ddns_https', _('FQDN'));
|
||||
o.datatype = 'hostname';
|
||||
o.placeholder = 'www.example.com';
|
||||
o.rmempty = true;
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('ddns', form.Value, 'ddns_https_target', _('Target'));
|
||||
o.datatype = "or('.', hostname)";
|
||||
o.placeholder = '. or web.example.com';
|
||||
o.default = '.';
|
||||
o.rmempty = true;
|
||||
o.rmempty = false;
|
||||
o.depends({ ddns_https: "", "!reverse": true })
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('ddns', form.Value, 'ddns_https_svcparams', _('SvcParams'));
|
||||
o.placeholder = 'alpn="h3,h3-29,h2,http/1.1" ipv4hint= ipv6hint= port=';
|
||||
o.default = 'alpn="h2,http/1.1"';
|
||||
o.rmempty = true;
|
||||
o.rmempty = false;
|
||||
o.depends({ ddns_https: "", "!reverse": true })
|
||||
o.modalonly = true;
|
||||
|
||||
o = s.taboption('ddns', form.Value, 'ddns_https_priority', _('Priority'));
|
||||
o.datatype = 'range(1, 65535)';
|
||||
o.default = 1;
|
||||
o.rmempty = true;
|
||||
o.rmempty = false;
|
||||
o.depends({ ddns_https: "", "!reverse": true })
|
||||
o.modalonly = true;
|
||||
|
||||
|
||||
@@ -42,8 +42,8 @@ msgstr ""
|
||||
msgid "Boot delay"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
msgid "Can refer to RFC8552"
|
||||
msgstr ""
|
||||
|
||||
@@ -59,8 +59,12 @@ msgstr ""
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:675
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:306
|
||||
#: htdocs/luci-static/resources/view/natmap.js:759
|
||||
#: htdocs/luci-static/resources/view/natmap.js:784
|
||||
msgid "Custom Script"
|
||||
msgstr ""
|
||||
|
||||
@@ -116,8 +120,9 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:644
|
||||
#: htdocs/luci-static/resources/view/natmap.js:651
|
||||
#: htdocs/luci-static/resources/view/natmap.js:673
|
||||
#: htdocs/luci-static/resources/view/natmap.js:731
|
||||
#: htdocs/luci-static/resources/view/natmap.js:669
|
||||
#: htdocs/luci-static/resources/view/natmap.js:696
|
||||
#: htdocs/luci-static/resources/view/natmap.js:756
|
||||
msgid "FQDN"
|
||||
msgstr ""
|
||||
|
||||
@@ -180,7 +185,7 @@ msgstr ""
|
||||
msgid "HTTP server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:718
|
||||
#: htdocs/luci-static/resources/view/natmap.js:743
|
||||
msgid "HTTPS Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -277,8 +282,8 @@ msgstr ""
|
||||
msgid "Port forwarding session idle timeout in seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:704
|
||||
#: htdocs/luci-static/resources/view/natmap.js:752
|
||||
#: htdocs/luci-static/resources/view/natmap.js:729
|
||||
#: htdocs/luci-static/resources/view/natmap.js:777
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
@@ -287,7 +292,7 @@ msgid "Private API Domain"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:341
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
#: htdocs/luci-static/resources/view/status/include/72_natmap.js:60
|
||||
msgid "Protocol"
|
||||
msgstr ""
|
||||
@@ -313,7 +318,7 @@ msgstr ""
|
||||
msgid "Restrict to address family"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
#: htdocs/luci-static/resources/view/natmap.js:681
|
||||
msgid "SRV Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -332,7 +337,7 @@ msgstr ""
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
@@ -340,12 +345,12 @@ msgstr ""
|
||||
msgid "Set 0 will follow Public port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:745
|
||||
#: htdocs/luci-static/resources/view/natmap.js:770
|
||||
msgid "SvcParams"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:174
|
||||
#: htdocs/luci-static/resources/view/natmap.js:689
|
||||
#: htdocs/luci-static/resources/view/natmap.js:713
|
||||
msgid "TCP"
|
||||
msgstr ""
|
||||
|
||||
@@ -357,12 +362,16 @@ msgstr ""
|
||||
msgid "TCP STUN"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:691
|
||||
#: htdocs/luci-static/resources/view/natmap.js:715
|
||||
msgid "TLS"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:697
|
||||
#: htdocs/luci-static/resources/view/natmap.js:737
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
msgid "TXT Record"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:722
|
||||
#: htdocs/luci-static/resources/view/natmap.js:762
|
||||
msgid "Target"
|
||||
msgstr ""
|
||||
|
||||
@@ -420,7 +429,7 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:179
|
||||
#: htdocs/luci-static/resources/view/natmap.js:184
|
||||
#: htdocs/luci-static/resources/view/natmap.js:690
|
||||
#: htdocs/luci-static/resources/view/natmap.js:714
|
||||
msgid "UDP"
|
||||
msgstr ""
|
||||
|
||||
@@ -444,10 +453,14 @@ msgstr ""
|
||||
msgid "Web UI Port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:711
|
||||
#: htdocs/luci-static/resources/view/natmap.js:736
|
||||
msgid "Weight"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:716
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:163
|
||||
msgid ""
|
||||
"https://github.com/muink/rfc5780-stun-server/blob/master/valid_hosts_rfc5780."
|
||||
@@ -469,6 +482,6 @@ msgstr ""
|
||||
msgid "luci check may not detect all conflicts."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:764
|
||||
#: htdocs/luci-static/resources/view/natmap.js:789
|
||||
msgid "⭮"
|
||||
msgstr ""
|
||||
@@ -48,8 +48,8 @@ msgstr "Bind port"
|
||||
msgid "Boot delay"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
msgid "Can refer to RFC8552"
|
||||
msgstr ""
|
||||
|
||||
@@ -65,8 +65,12 @@ msgstr ""
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:675
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:306
|
||||
#: htdocs/luci-static/resources/view/natmap.js:759
|
||||
#: htdocs/luci-static/resources/view/natmap.js:784
|
||||
msgid "Custom Script"
|
||||
msgstr ""
|
||||
|
||||
@@ -122,8 +126,9 @@ msgstr "Ekstern port"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:644
|
||||
#: htdocs/luci-static/resources/view/natmap.js:651
|
||||
#: htdocs/luci-static/resources/view/natmap.js:673
|
||||
#: htdocs/luci-static/resources/view/natmap.js:731
|
||||
#: htdocs/luci-static/resources/view/natmap.js:669
|
||||
#: htdocs/luci-static/resources/view/natmap.js:696
|
||||
#: htdocs/luci-static/resources/view/natmap.js:756
|
||||
msgid "FQDN"
|
||||
msgstr ""
|
||||
|
||||
@@ -186,7 +191,7 @@ msgstr ""
|
||||
msgid "HTTP server"
|
||||
msgstr "HTTP server"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:718
|
||||
#: htdocs/luci-static/resources/view/natmap.js:743
|
||||
msgid "HTTPS Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -283,8 +288,8 @@ msgstr ""
|
||||
msgid "Port forwarding session idle timeout in seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:704
|
||||
#: htdocs/luci-static/resources/view/natmap.js:752
|
||||
#: htdocs/luci-static/resources/view/natmap.js:729
|
||||
#: htdocs/luci-static/resources/view/natmap.js:777
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
@@ -293,7 +298,7 @@ msgid "Private API Domain"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:341
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
#: htdocs/luci-static/resources/view/status/include/72_natmap.js:60
|
||||
msgid "Protocol"
|
||||
msgstr "Protokol"
|
||||
@@ -319,7 +324,7 @@ msgstr ""
|
||||
msgid "Restrict to address family"
|
||||
msgstr "Begræns til adresse familie"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
#: htdocs/luci-static/resources/view/natmap.js:681
|
||||
msgid "SRV Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -338,7 +343,7 @@ msgstr "STUN server"
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
@@ -346,12 +351,12 @@ msgstr ""
|
||||
msgid "Set 0 will follow Public port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:745
|
||||
#: htdocs/luci-static/resources/view/natmap.js:770
|
||||
msgid "SvcParams"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:174
|
||||
#: htdocs/luci-static/resources/view/natmap.js:689
|
||||
#: htdocs/luci-static/resources/view/natmap.js:713
|
||||
msgid "TCP"
|
||||
msgstr ""
|
||||
|
||||
@@ -363,12 +368,16 @@ msgstr ""
|
||||
msgid "TCP STUN"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:691
|
||||
#: htdocs/luci-static/resources/view/natmap.js:715
|
||||
msgid "TLS"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:697
|
||||
#: htdocs/luci-static/resources/view/natmap.js:737
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
msgid "TXT Record"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:722
|
||||
#: htdocs/luci-static/resources/view/natmap.js:762
|
||||
msgid "Target"
|
||||
msgstr ""
|
||||
|
||||
@@ -426,7 +435,7 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:179
|
||||
#: htdocs/luci-static/resources/view/natmap.js:184
|
||||
#: htdocs/luci-static/resources/view/natmap.js:690
|
||||
#: htdocs/luci-static/resources/view/natmap.js:714
|
||||
msgid "UDP"
|
||||
msgstr ""
|
||||
|
||||
@@ -450,10 +459,14 @@ msgstr ""
|
||||
msgid "Web UI Port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:711
|
||||
#: htdocs/luci-static/resources/view/natmap.js:736
|
||||
msgid "Weight"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:716
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:163
|
||||
msgid ""
|
||||
"https://github.com/muink/rfc5780-stun-server/blob/master/valid_hosts_rfc5780."
|
||||
@@ -475,7 +488,7 @@ msgstr ""
|
||||
msgid "luci check may not detect all conflicts."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:764
|
||||
#: htdocs/luci-static/resources/view/natmap.js:789
|
||||
msgid "⭮"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@ msgstr "Bindungsport"
|
||||
msgid "Boot delay"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
msgid "Can refer to RFC8552"
|
||||
msgstr ""
|
||||
|
||||
@@ -65,8 +65,12 @@ msgstr ""
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:675
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:306
|
||||
#: htdocs/luci-static/resources/view/natmap.js:759
|
||||
#: htdocs/luci-static/resources/view/natmap.js:784
|
||||
msgid "Custom Script"
|
||||
msgstr ""
|
||||
|
||||
@@ -122,8 +126,9 @@ msgstr "Externer Port"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:644
|
||||
#: htdocs/luci-static/resources/view/natmap.js:651
|
||||
#: htdocs/luci-static/resources/view/natmap.js:673
|
||||
#: htdocs/luci-static/resources/view/natmap.js:731
|
||||
#: htdocs/luci-static/resources/view/natmap.js:669
|
||||
#: htdocs/luci-static/resources/view/natmap.js:696
|
||||
#: htdocs/luci-static/resources/view/natmap.js:756
|
||||
msgid "FQDN"
|
||||
msgstr ""
|
||||
|
||||
@@ -186,7 +191,7 @@ msgstr ""
|
||||
msgid "HTTP server"
|
||||
msgstr "HTTP Server"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:718
|
||||
#: htdocs/luci-static/resources/view/natmap.js:743
|
||||
msgid "HTTPS Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -283,8 +288,8 @@ msgstr ""
|
||||
msgid "Port forwarding session idle timeout in seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:704
|
||||
#: htdocs/luci-static/resources/view/natmap.js:752
|
||||
#: htdocs/luci-static/resources/view/natmap.js:729
|
||||
#: htdocs/luci-static/resources/view/natmap.js:777
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
@@ -293,7 +298,7 @@ msgid "Private API Domain"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:341
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
#: htdocs/luci-static/resources/view/status/include/72_natmap.js:60
|
||||
msgid "Protocol"
|
||||
msgstr "Protokoll"
|
||||
@@ -319,7 +324,7 @@ msgstr ""
|
||||
msgid "Restrict to address family"
|
||||
msgstr "Auf Adressfamilie beschränken"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
#: htdocs/luci-static/resources/view/natmap.js:681
|
||||
msgid "SRV Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -338,7 +343,7 @@ msgstr "STUN-Server"
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
@@ -346,12 +351,12 @@ msgstr ""
|
||||
msgid "Set 0 will follow Public port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:745
|
||||
#: htdocs/luci-static/resources/view/natmap.js:770
|
||||
msgid "SvcParams"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:174
|
||||
#: htdocs/luci-static/resources/view/natmap.js:689
|
||||
#: htdocs/luci-static/resources/view/natmap.js:713
|
||||
msgid "TCP"
|
||||
msgstr ""
|
||||
|
||||
@@ -363,12 +368,16 @@ msgstr ""
|
||||
msgid "TCP STUN"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:691
|
||||
#: htdocs/luci-static/resources/view/natmap.js:715
|
||||
msgid "TLS"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:697
|
||||
#: htdocs/luci-static/resources/view/natmap.js:737
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
msgid "TXT Record"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:722
|
||||
#: htdocs/luci-static/resources/view/natmap.js:762
|
||||
msgid "Target"
|
||||
msgstr ""
|
||||
|
||||
@@ -426,7 +435,7 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:179
|
||||
#: htdocs/luci-static/resources/view/natmap.js:184
|
||||
#: htdocs/luci-static/resources/view/natmap.js:690
|
||||
#: htdocs/luci-static/resources/view/natmap.js:714
|
||||
msgid "UDP"
|
||||
msgstr ""
|
||||
|
||||
@@ -450,10 +459,14 @@ msgstr ""
|
||||
msgid "Web UI Port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:711
|
||||
#: htdocs/luci-static/resources/view/natmap.js:736
|
||||
msgid "Weight"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:716
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:163
|
||||
msgid ""
|
||||
"https://github.com/muink/rfc5780-stun-server/blob/master/valid_hosts_rfc5780."
|
||||
@@ -475,7 +488,7 @@ msgstr ""
|
||||
msgid "luci check may not detect all conflicts."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:764
|
||||
#: htdocs/luci-static/resources/view/natmap.js:789
|
||||
msgid "⭮"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@ msgstr "Vincular puerto"
|
||||
msgid "Boot delay"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
msgid "Can refer to RFC8552"
|
||||
msgstr ""
|
||||
|
||||
@@ -65,8 +65,12 @@ msgstr ""
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:675
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:306
|
||||
#: htdocs/luci-static/resources/view/natmap.js:759
|
||||
#: htdocs/luci-static/resources/view/natmap.js:784
|
||||
msgid "Custom Script"
|
||||
msgstr ""
|
||||
|
||||
@@ -122,8 +126,9 @@ msgstr "Puerto externo"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:644
|
||||
#: htdocs/luci-static/resources/view/natmap.js:651
|
||||
#: htdocs/luci-static/resources/view/natmap.js:673
|
||||
#: htdocs/luci-static/resources/view/natmap.js:731
|
||||
#: htdocs/luci-static/resources/view/natmap.js:669
|
||||
#: htdocs/luci-static/resources/view/natmap.js:696
|
||||
#: htdocs/luci-static/resources/view/natmap.js:756
|
||||
msgid "FQDN"
|
||||
msgstr ""
|
||||
|
||||
@@ -186,7 +191,7 @@ msgstr ""
|
||||
msgid "HTTP server"
|
||||
msgstr "Servidor HTTP"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:718
|
||||
#: htdocs/luci-static/resources/view/natmap.js:743
|
||||
msgid "HTTPS Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -283,8 +288,8 @@ msgstr ""
|
||||
msgid "Port forwarding session idle timeout in seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:704
|
||||
#: htdocs/luci-static/resources/view/natmap.js:752
|
||||
#: htdocs/luci-static/resources/view/natmap.js:729
|
||||
#: htdocs/luci-static/resources/view/natmap.js:777
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
@@ -293,7 +298,7 @@ msgid "Private API Domain"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:341
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
#: htdocs/luci-static/resources/view/status/include/72_natmap.js:60
|
||||
msgid "Protocol"
|
||||
msgstr "Protocolo"
|
||||
@@ -319,7 +324,7 @@ msgstr ""
|
||||
msgid "Restrict to address family"
|
||||
msgstr "Restringir para dirigirse a la familia"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
#: htdocs/luci-static/resources/view/natmap.js:681
|
||||
msgid "SRV Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -338,7 +343,7 @@ msgstr "Servidor STUN"
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
@@ -346,12 +351,12 @@ msgstr ""
|
||||
msgid "Set 0 will follow Public port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:745
|
||||
#: htdocs/luci-static/resources/view/natmap.js:770
|
||||
msgid "SvcParams"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:174
|
||||
#: htdocs/luci-static/resources/view/natmap.js:689
|
||||
#: htdocs/luci-static/resources/view/natmap.js:713
|
||||
msgid "TCP"
|
||||
msgstr ""
|
||||
|
||||
@@ -363,12 +368,16 @@ msgstr ""
|
||||
msgid "TCP STUN"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:691
|
||||
#: htdocs/luci-static/resources/view/natmap.js:715
|
||||
msgid "TLS"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:697
|
||||
#: htdocs/luci-static/resources/view/natmap.js:737
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
msgid "TXT Record"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:722
|
||||
#: htdocs/luci-static/resources/view/natmap.js:762
|
||||
msgid "Target"
|
||||
msgstr ""
|
||||
|
||||
@@ -426,7 +435,7 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:179
|
||||
#: htdocs/luci-static/resources/view/natmap.js:184
|
||||
#: htdocs/luci-static/resources/view/natmap.js:690
|
||||
#: htdocs/luci-static/resources/view/natmap.js:714
|
||||
msgid "UDP"
|
||||
msgstr ""
|
||||
|
||||
@@ -450,10 +459,14 @@ msgstr ""
|
||||
msgid "Web UI Port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:711
|
||||
#: htdocs/luci-static/resources/view/natmap.js:736
|
||||
msgid "Weight"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:716
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:163
|
||||
msgid ""
|
||||
"https://github.com/muink/rfc5780-stun-server/blob/master/valid_hosts_rfc5780."
|
||||
@@ -475,7 +488,7 @@ msgstr ""
|
||||
msgid "luci check may not detect all conflicts."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:764
|
||||
#: htdocs/luci-static/resources/view/natmap.js:789
|
||||
msgid "⭮"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@ msgstr "Port de liaison"
|
||||
msgid "Boot delay"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
msgid "Can refer to RFC8552"
|
||||
msgstr ""
|
||||
|
||||
@@ -65,8 +65,12 @@ msgstr ""
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:675
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:306
|
||||
#: htdocs/luci-static/resources/view/natmap.js:759
|
||||
#: htdocs/luci-static/resources/view/natmap.js:784
|
||||
msgid "Custom Script"
|
||||
msgstr ""
|
||||
|
||||
@@ -122,8 +126,9 @@ msgstr "Port externe"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:644
|
||||
#: htdocs/luci-static/resources/view/natmap.js:651
|
||||
#: htdocs/luci-static/resources/view/natmap.js:673
|
||||
#: htdocs/luci-static/resources/view/natmap.js:731
|
||||
#: htdocs/luci-static/resources/view/natmap.js:669
|
||||
#: htdocs/luci-static/resources/view/natmap.js:696
|
||||
#: htdocs/luci-static/resources/view/natmap.js:756
|
||||
msgid "FQDN"
|
||||
msgstr ""
|
||||
|
||||
@@ -186,7 +191,7 @@ msgstr ""
|
||||
msgid "HTTP server"
|
||||
msgstr "Serveur HTTP"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:718
|
||||
#: htdocs/luci-static/resources/view/natmap.js:743
|
||||
msgid "HTTPS Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -283,8 +288,8 @@ msgstr ""
|
||||
msgid "Port forwarding session idle timeout in seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:704
|
||||
#: htdocs/luci-static/resources/view/natmap.js:752
|
||||
#: htdocs/luci-static/resources/view/natmap.js:729
|
||||
#: htdocs/luci-static/resources/view/natmap.js:777
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
@@ -293,7 +298,7 @@ msgid "Private API Domain"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:341
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
#: htdocs/luci-static/resources/view/status/include/72_natmap.js:60
|
||||
msgid "Protocol"
|
||||
msgstr "Protocole"
|
||||
@@ -319,7 +324,7 @@ msgstr ""
|
||||
msgid "Restrict to address family"
|
||||
msgstr "Restreindre à la famille d’adresses"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
#: htdocs/luci-static/resources/view/natmap.js:681
|
||||
msgid "SRV Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -338,7 +343,7 @@ msgstr "Serveur STUN"
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
@@ -346,12 +351,12 @@ msgstr ""
|
||||
msgid "Set 0 will follow Public port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:745
|
||||
#: htdocs/luci-static/resources/view/natmap.js:770
|
||||
msgid "SvcParams"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:174
|
||||
#: htdocs/luci-static/resources/view/natmap.js:689
|
||||
#: htdocs/luci-static/resources/view/natmap.js:713
|
||||
msgid "TCP"
|
||||
msgstr ""
|
||||
|
||||
@@ -363,12 +368,16 @@ msgstr ""
|
||||
msgid "TCP STUN"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:691
|
||||
#: htdocs/luci-static/resources/view/natmap.js:715
|
||||
msgid "TLS"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:697
|
||||
#: htdocs/luci-static/resources/view/natmap.js:737
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
msgid "TXT Record"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:722
|
||||
#: htdocs/luci-static/resources/view/natmap.js:762
|
||||
msgid "Target"
|
||||
msgstr ""
|
||||
|
||||
@@ -426,7 +435,7 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:179
|
||||
#: htdocs/luci-static/resources/view/natmap.js:184
|
||||
#: htdocs/luci-static/resources/view/natmap.js:690
|
||||
#: htdocs/luci-static/resources/view/natmap.js:714
|
||||
msgid "UDP"
|
||||
msgstr ""
|
||||
|
||||
@@ -450,10 +459,14 @@ msgstr ""
|
||||
msgid "Web UI Port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:711
|
||||
#: htdocs/luci-static/resources/view/natmap.js:736
|
||||
msgid "Weight"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:716
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:163
|
||||
msgid ""
|
||||
"https://github.com/muink/rfc5780-stun-server/blob/master/valid_hosts_rfc5780."
|
||||
@@ -475,7 +488,7 @@ msgstr ""
|
||||
msgid "luci check may not detect all conflicts."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:764
|
||||
#: htdocs/luci-static/resources/view/natmap.js:789
|
||||
msgid "⭮"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@ msgstr "collega porta"
|
||||
msgid "Boot delay"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
msgid "Can refer to RFC8552"
|
||||
msgstr ""
|
||||
|
||||
@@ -65,8 +65,12 @@ msgstr ""
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:675
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:306
|
||||
#: htdocs/luci-static/resources/view/natmap.js:759
|
||||
#: htdocs/luci-static/resources/view/natmap.js:784
|
||||
msgid "Custom Script"
|
||||
msgstr ""
|
||||
|
||||
@@ -122,8 +126,9 @@ msgstr "Porta Esterna"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:644
|
||||
#: htdocs/luci-static/resources/view/natmap.js:651
|
||||
#: htdocs/luci-static/resources/view/natmap.js:673
|
||||
#: htdocs/luci-static/resources/view/natmap.js:731
|
||||
#: htdocs/luci-static/resources/view/natmap.js:669
|
||||
#: htdocs/luci-static/resources/view/natmap.js:696
|
||||
#: htdocs/luci-static/resources/view/natmap.js:756
|
||||
msgid "FQDN"
|
||||
msgstr ""
|
||||
|
||||
@@ -186,7 +191,7 @@ msgstr ""
|
||||
msgid "HTTP server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:718
|
||||
#: htdocs/luci-static/resources/view/natmap.js:743
|
||||
msgid "HTTPS Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -283,8 +288,8 @@ msgstr ""
|
||||
msgid "Port forwarding session idle timeout in seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:704
|
||||
#: htdocs/luci-static/resources/view/natmap.js:752
|
||||
#: htdocs/luci-static/resources/view/natmap.js:729
|
||||
#: htdocs/luci-static/resources/view/natmap.js:777
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
@@ -293,7 +298,7 @@ msgid "Private API Domain"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:341
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
#: htdocs/luci-static/resources/view/status/include/72_natmap.js:60
|
||||
msgid "Protocol"
|
||||
msgstr ""
|
||||
@@ -319,7 +324,7 @@ msgstr ""
|
||||
msgid "Restrict to address family"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
#: htdocs/luci-static/resources/view/natmap.js:681
|
||||
msgid "SRV Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -338,7 +343,7 @@ msgstr ""
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
@@ -346,12 +351,12 @@ msgstr ""
|
||||
msgid "Set 0 will follow Public port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:745
|
||||
#: htdocs/luci-static/resources/view/natmap.js:770
|
||||
msgid "SvcParams"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:174
|
||||
#: htdocs/luci-static/resources/view/natmap.js:689
|
||||
#: htdocs/luci-static/resources/view/natmap.js:713
|
||||
msgid "TCP"
|
||||
msgstr ""
|
||||
|
||||
@@ -363,12 +368,16 @@ msgstr ""
|
||||
msgid "TCP STUN"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:691
|
||||
#: htdocs/luci-static/resources/view/natmap.js:715
|
||||
msgid "TLS"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:697
|
||||
#: htdocs/luci-static/resources/view/natmap.js:737
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
msgid "TXT Record"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:722
|
||||
#: htdocs/luci-static/resources/view/natmap.js:762
|
||||
msgid "Target"
|
||||
msgstr ""
|
||||
|
||||
@@ -426,7 +435,7 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:179
|
||||
#: htdocs/luci-static/resources/view/natmap.js:184
|
||||
#: htdocs/luci-static/resources/view/natmap.js:690
|
||||
#: htdocs/luci-static/resources/view/natmap.js:714
|
||||
msgid "UDP"
|
||||
msgstr ""
|
||||
|
||||
@@ -450,10 +459,14 @@ msgstr ""
|
||||
msgid "Web UI Port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:711
|
||||
#: htdocs/luci-static/resources/view/natmap.js:736
|
||||
msgid "Weight"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:716
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:163
|
||||
msgid ""
|
||||
"https://github.com/muink/rfc5780-stun-server/blob/master/valid_hosts_rfc5780."
|
||||
@@ -475,6 +488,6 @@ msgstr ""
|
||||
msgid "luci check may not detect all conflicts."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:764
|
||||
#: htdocs/luci-static/resources/view/natmap.js:789
|
||||
msgid "⭮"
|
||||
msgstr ""
|
||||
@@ -50,8 +50,8 @@ msgstr "Priskirti prievadą"
|
||||
msgid "Boot delay"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
msgid "Can refer to RFC8552"
|
||||
msgstr ""
|
||||
|
||||
@@ -67,8 +67,12 @@ msgstr ""
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:675
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:306
|
||||
#: htdocs/luci-static/resources/view/natmap.js:759
|
||||
#: htdocs/luci-static/resources/view/natmap.js:784
|
||||
msgid "Custom Script"
|
||||
msgstr ""
|
||||
|
||||
@@ -124,8 +128,9 @@ msgstr "Išorinis prievadas"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:644
|
||||
#: htdocs/luci-static/resources/view/natmap.js:651
|
||||
#: htdocs/luci-static/resources/view/natmap.js:673
|
||||
#: htdocs/luci-static/resources/view/natmap.js:731
|
||||
#: htdocs/luci-static/resources/view/natmap.js:669
|
||||
#: htdocs/luci-static/resources/view/natmap.js:696
|
||||
#: htdocs/luci-static/resources/view/natmap.js:756
|
||||
msgid "FQDN"
|
||||
msgstr ""
|
||||
|
||||
@@ -188,7 +193,7 @@ msgstr ""
|
||||
msgid "HTTP server"
|
||||
msgstr "„HTTP“ serveris"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:718
|
||||
#: htdocs/luci-static/resources/view/natmap.js:743
|
||||
msgid "HTTPS Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -285,8 +290,8 @@ msgstr ""
|
||||
msgid "Port forwarding session idle timeout in seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:704
|
||||
#: htdocs/luci-static/resources/view/natmap.js:752
|
||||
#: htdocs/luci-static/resources/view/natmap.js:729
|
||||
#: htdocs/luci-static/resources/view/natmap.js:777
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
@@ -295,7 +300,7 @@ msgid "Private API Domain"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:341
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
#: htdocs/luci-static/resources/view/status/include/72_natmap.js:60
|
||||
msgid "Protocol"
|
||||
msgstr "Protokolas"
|
||||
@@ -321,7 +326,7 @@ msgstr ""
|
||||
msgid "Restrict to address family"
|
||||
msgstr "Riboti tik adresų šeimai"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
#: htdocs/luci-static/resources/view/natmap.js:681
|
||||
msgid "SRV Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -340,7 +345,7 @@ msgstr "„STUN“ serveris"
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
@@ -348,12 +353,12 @@ msgstr ""
|
||||
msgid "Set 0 will follow Public port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:745
|
||||
#: htdocs/luci-static/resources/view/natmap.js:770
|
||||
msgid "SvcParams"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:174
|
||||
#: htdocs/luci-static/resources/view/natmap.js:689
|
||||
#: htdocs/luci-static/resources/view/natmap.js:713
|
||||
msgid "TCP"
|
||||
msgstr ""
|
||||
|
||||
@@ -365,12 +370,16 @@ msgstr ""
|
||||
msgid "TCP STUN"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:691
|
||||
#: htdocs/luci-static/resources/view/natmap.js:715
|
||||
msgid "TLS"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:697
|
||||
#: htdocs/luci-static/resources/view/natmap.js:737
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
msgid "TXT Record"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:722
|
||||
#: htdocs/luci-static/resources/view/natmap.js:762
|
||||
msgid "Target"
|
||||
msgstr ""
|
||||
|
||||
@@ -428,7 +437,7 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:179
|
||||
#: htdocs/luci-static/resources/view/natmap.js:184
|
||||
#: htdocs/luci-static/resources/view/natmap.js:690
|
||||
#: htdocs/luci-static/resources/view/natmap.js:714
|
||||
msgid "UDP"
|
||||
msgstr ""
|
||||
|
||||
@@ -452,10 +461,14 @@ msgstr ""
|
||||
msgid "Web UI Port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:711
|
||||
#: htdocs/luci-static/resources/view/natmap.js:736
|
||||
msgid "Weight"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:716
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:163
|
||||
msgid ""
|
||||
"https://github.com/muink/rfc5780-stun-server/blob/master/valid_hosts_rfc5780."
|
||||
@@ -477,7 +490,7 @@ msgstr ""
|
||||
msgid "luci check may not detect all conflicts."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:764
|
||||
#: htdocs/luci-static/resources/view/natmap.js:789
|
||||
msgid "⭮"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@ msgstr "Bind poort"
|
||||
msgid "Boot delay"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
msgid "Can refer to RFC8552"
|
||||
msgstr ""
|
||||
|
||||
@@ -65,8 +65,12 @@ msgstr ""
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:675
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:306
|
||||
#: htdocs/luci-static/resources/view/natmap.js:759
|
||||
#: htdocs/luci-static/resources/view/natmap.js:784
|
||||
msgid "Custom Script"
|
||||
msgstr ""
|
||||
|
||||
@@ -122,8 +126,9 @@ msgstr "Externe poort"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:644
|
||||
#: htdocs/luci-static/resources/view/natmap.js:651
|
||||
#: htdocs/luci-static/resources/view/natmap.js:673
|
||||
#: htdocs/luci-static/resources/view/natmap.js:731
|
||||
#: htdocs/luci-static/resources/view/natmap.js:669
|
||||
#: htdocs/luci-static/resources/view/natmap.js:696
|
||||
#: htdocs/luci-static/resources/view/natmap.js:756
|
||||
msgid "FQDN"
|
||||
msgstr ""
|
||||
|
||||
@@ -186,7 +191,7 @@ msgstr ""
|
||||
msgid "HTTP server"
|
||||
msgstr "HTTP-server"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:718
|
||||
#: htdocs/luci-static/resources/view/natmap.js:743
|
||||
msgid "HTTPS Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -283,8 +288,8 @@ msgstr ""
|
||||
msgid "Port forwarding session idle timeout in seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:704
|
||||
#: htdocs/luci-static/resources/view/natmap.js:752
|
||||
#: htdocs/luci-static/resources/view/natmap.js:729
|
||||
#: htdocs/luci-static/resources/view/natmap.js:777
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
@@ -293,7 +298,7 @@ msgid "Private API Domain"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:341
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
#: htdocs/luci-static/resources/view/status/include/72_natmap.js:60
|
||||
msgid "Protocol"
|
||||
msgstr "Protocol"
|
||||
@@ -319,7 +324,7 @@ msgstr ""
|
||||
msgid "Restrict to address family"
|
||||
msgstr "Beperken tot adres familie"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
#: htdocs/luci-static/resources/view/natmap.js:681
|
||||
msgid "SRV Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -338,7 +343,7 @@ msgstr "STUN-server"
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
@@ -346,12 +351,12 @@ msgstr ""
|
||||
msgid "Set 0 will follow Public port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:745
|
||||
#: htdocs/luci-static/resources/view/natmap.js:770
|
||||
msgid "SvcParams"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:174
|
||||
#: htdocs/luci-static/resources/view/natmap.js:689
|
||||
#: htdocs/luci-static/resources/view/natmap.js:713
|
||||
msgid "TCP"
|
||||
msgstr ""
|
||||
|
||||
@@ -363,12 +368,16 @@ msgstr ""
|
||||
msgid "TCP STUN"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:691
|
||||
#: htdocs/luci-static/resources/view/natmap.js:715
|
||||
msgid "TLS"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:697
|
||||
#: htdocs/luci-static/resources/view/natmap.js:737
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
msgid "TXT Record"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:722
|
||||
#: htdocs/luci-static/resources/view/natmap.js:762
|
||||
msgid "Target"
|
||||
msgstr ""
|
||||
|
||||
@@ -426,7 +435,7 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:179
|
||||
#: htdocs/luci-static/resources/view/natmap.js:184
|
||||
#: htdocs/luci-static/resources/view/natmap.js:690
|
||||
#: htdocs/luci-static/resources/view/natmap.js:714
|
||||
msgid "UDP"
|
||||
msgstr ""
|
||||
|
||||
@@ -450,10 +459,14 @@ msgstr ""
|
||||
msgid "Web UI Port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:711
|
||||
#: htdocs/luci-static/resources/view/natmap.js:736
|
||||
msgid "Weight"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:716
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:163
|
||||
msgid ""
|
||||
"https://github.com/muink/rfc5780-stun-server/blob/master/valid_hosts_rfc5780."
|
||||
@@ -475,7 +488,7 @@ msgstr ""
|
||||
msgid "luci check may not detect all conflicts."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:764
|
||||
#: htdocs/luci-static/resources/view/natmap.js:789
|
||||
msgid "⭮"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -49,8 +49,8 @@ msgstr "Zwiąż port"
|
||||
msgid "Boot delay"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
msgid "Can refer to RFC8552"
|
||||
msgstr ""
|
||||
|
||||
@@ -66,8 +66,12 @@ msgstr ""
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:675
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:306
|
||||
#: htdocs/luci-static/resources/view/natmap.js:759
|
||||
#: htdocs/luci-static/resources/view/natmap.js:784
|
||||
msgid "Custom Script"
|
||||
msgstr ""
|
||||
|
||||
@@ -123,8 +127,9 @@ msgstr "Port zewnętrzny"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:644
|
||||
#: htdocs/luci-static/resources/view/natmap.js:651
|
||||
#: htdocs/luci-static/resources/view/natmap.js:673
|
||||
#: htdocs/luci-static/resources/view/natmap.js:731
|
||||
#: htdocs/luci-static/resources/view/natmap.js:669
|
||||
#: htdocs/luci-static/resources/view/natmap.js:696
|
||||
#: htdocs/luci-static/resources/view/natmap.js:756
|
||||
msgid "FQDN"
|
||||
msgstr ""
|
||||
|
||||
@@ -187,7 +192,7 @@ msgstr ""
|
||||
msgid "HTTP server"
|
||||
msgstr "Serwer HTTP"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:718
|
||||
#: htdocs/luci-static/resources/view/natmap.js:743
|
||||
msgid "HTTPS Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -284,8 +289,8 @@ msgstr ""
|
||||
msgid "Port forwarding session idle timeout in seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:704
|
||||
#: htdocs/luci-static/resources/view/natmap.js:752
|
||||
#: htdocs/luci-static/resources/view/natmap.js:729
|
||||
#: htdocs/luci-static/resources/view/natmap.js:777
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
@@ -294,7 +299,7 @@ msgid "Private API Domain"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:341
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
#: htdocs/luci-static/resources/view/status/include/72_natmap.js:60
|
||||
msgid "Protocol"
|
||||
msgstr "Protokół"
|
||||
@@ -320,7 +325,7 @@ msgstr ""
|
||||
msgid "Restrict to address family"
|
||||
msgstr "Ogranicz do rodziny adresów"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
#: htdocs/luci-static/resources/view/natmap.js:681
|
||||
msgid "SRV Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -339,7 +344,7 @@ msgstr "Serwer STUN"
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
@@ -347,12 +352,12 @@ msgstr ""
|
||||
msgid "Set 0 will follow Public port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:745
|
||||
#: htdocs/luci-static/resources/view/natmap.js:770
|
||||
msgid "SvcParams"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:174
|
||||
#: htdocs/luci-static/resources/view/natmap.js:689
|
||||
#: htdocs/luci-static/resources/view/natmap.js:713
|
||||
msgid "TCP"
|
||||
msgstr ""
|
||||
|
||||
@@ -364,12 +369,16 @@ msgstr ""
|
||||
msgid "TCP STUN"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:691
|
||||
#: htdocs/luci-static/resources/view/natmap.js:715
|
||||
msgid "TLS"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:697
|
||||
#: htdocs/luci-static/resources/view/natmap.js:737
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
msgid "TXT Record"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:722
|
||||
#: htdocs/luci-static/resources/view/natmap.js:762
|
||||
msgid "Target"
|
||||
msgstr ""
|
||||
|
||||
@@ -427,7 +436,7 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:179
|
||||
#: htdocs/luci-static/resources/view/natmap.js:184
|
||||
#: htdocs/luci-static/resources/view/natmap.js:690
|
||||
#: htdocs/luci-static/resources/view/natmap.js:714
|
||||
msgid "UDP"
|
||||
msgstr ""
|
||||
|
||||
@@ -451,10 +460,14 @@ msgstr ""
|
||||
msgid "Web UI Port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:711
|
||||
#: htdocs/luci-static/resources/view/natmap.js:736
|
||||
msgid "Weight"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:716
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:163
|
||||
msgid ""
|
||||
"https://github.com/muink/rfc5780-stun-server/blob/master/valid_hosts_rfc5780."
|
||||
@@ -476,7 +489,7 @@ msgstr ""
|
||||
msgid "luci check may not detect all conflicts."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:764
|
||||
#: htdocs/luci-static/resources/view/natmap.js:789
|
||||
msgid "⭮"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@ msgstr "Porta do bind"
|
||||
msgid "Boot delay"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
msgid "Can refer to RFC8552"
|
||||
msgstr ""
|
||||
|
||||
@@ -65,8 +65,12 @@ msgstr ""
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:675
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:306
|
||||
#: htdocs/luci-static/resources/view/natmap.js:759
|
||||
#: htdocs/luci-static/resources/view/natmap.js:784
|
||||
msgid "Custom Script"
|
||||
msgstr ""
|
||||
|
||||
@@ -122,8 +126,9 @@ msgstr "Porta externa"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:644
|
||||
#: htdocs/luci-static/resources/view/natmap.js:651
|
||||
#: htdocs/luci-static/resources/view/natmap.js:673
|
||||
#: htdocs/luci-static/resources/view/natmap.js:731
|
||||
#: htdocs/luci-static/resources/view/natmap.js:669
|
||||
#: htdocs/luci-static/resources/view/natmap.js:696
|
||||
#: htdocs/luci-static/resources/view/natmap.js:756
|
||||
msgid "FQDN"
|
||||
msgstr ""
|
||||
|
||||
@@ -186,7 +191,7 @@ msgstr ""
|
||||
msgid "HTTP server"
|
||||
msgstr "Servidor HTTP"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:718
|
||||
#: htdocs/luci-static/resources/view/natmap.js:743
|
||||
msgid "HTTPS Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -283,8 +288,8 @@ msgstr ""
|
||||
msgid "Port forwarding session idle timeout in seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:704
|
||||
#: htdocs/luci-static/resources/view/natmap.js:752
|
||||
#: htdocs/luci-static/resources/view/natmap.js:729
|
||||
#: htdocs/luci-static/resources/view/natmap.js:777
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
@@ -293,7 +298,7 @@ msgid "Private API Domain"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:341
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
#: htdocs/luci-static/resources/view/status/include/72_natmap.js:60
|
||||
msgid "Protocol"
|
||||
msgstr "Protocolo"
|
||||
@@ -319,7 +324,7 @@ msgstr ""
|
||||
msgid "Restrict to address family"
|
||||
msgstr "Restringe à uma família de endereços"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
#: htdocs/luci-static/resources/view/natmap.js:681
|
||||
msgid "SRV Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -338,7 +343,7 @@ msgstr "Servidor STUN"
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
@@ -346,12 +351,12 @@ msgstr ""
|
||||
msgid "Set 0 will follow Public port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:745
|
||||
#: htdocs/luci-static/resources/view/natmap.js:770
|
||||
msgid "SvcParams"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:174
|
||||
#: htdocs/luci-static/resources/view/natmap.js:689
|
||||
#: htdocs/luci-static/resources/view/natmap.js:713
|
||||
msgid "TCP"
|
||||
msgstr ""
|
||||
|
||||
@@ -363,12 +368,16 @@ msgstr ""
|
||||
msgid "TCP STUN"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:691
|
||||
#: htdocs/luci-static/resources/view/natmap.js:715
|
||||
msgid "TLS"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:697
|
||||
#: htdocs/luci-static/resources/view/natmap.js:737
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
msgid "TXT Record"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:722
|
||||
#: htdocs/luci-static/resources/view/natmap.js:762
|
||||
msgid "Target"
|
||||
msgstr ""
|
||||
|
||||
@@ -426,7 +435,7 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:179
|
||||
#: htdocs/luci-static/resources/view/natmap.js:184
|
||||
#: htdocs/luci-static/resources/view/natmap.js:690
|
||||
#: htdocs/luci-static/resources/view/natmap.js:714
|
||||
msgid "UDP"
|
||||
msgstr ""
|
||||
|
||||
@@ -450,10 +459,14 @@ msgstr ""
|
||||
msgid "Web UI Port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:711
|
||||
#: htdocs/luci-static/resources/view/natmap.js:736
|
||||
msgid "Weight"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:716
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:163
|
||||
msgid ""
|
||||
"https://github.com/muink/rfc5780-stun-server/blob/master/valid_hosts_rfc5780."
|
||||
@@ -475,7 +488,7 @@ msgstr ""
|
||||
msgid "luci check may not detect all conflicts."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:764
|
||||
#: htdocs/luci-static/resources/view/natmap.js:789
|
||||
msgid "⭮"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@ msgstr "Porta do bind"
|
||||
msgid "Boot delay"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
msgid "Can refer to RFC8552"
|
||||
msgstr ""
|
||||
|
||||
@@ -65,8 +65,12 @@ msgstr ""
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:675
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:306
|
||||
#: htdocs/luci-static/resources/view/natmap.js:759
|
||||
#: htdocs/luci-static/resources/view/natmap.js:784
|
||||
msgid "Custom Script"
|
||||
msgstr ""
|
||||
|
||||
@@ -122,8 +126,9 @@ msgstr "Porta externa"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:644
|
||||
#: htdocs/luci-static/resources/view/natmap.js:651
|
||||
#: htdocs/luci-static/resources/view/natmap.js:673
|
||||
#: htdocs/luci-static/resources/view/natmap.js:731
|
||||
#: htdocs/luci-static/resources/view/natmap.js:669
|
||||
#: htdocs/luci-static/resources/view/natmap.js:696
|
||||
#: htdocs/luci-static/resources/view/natmap.js:756
|
||||
msgid "FQDN"
|
||||
msgstr ""
|
||||
|
||||
@@ -186,7 +191,7 @@ msgstr ""
|
||||
msgid "HTTP server"
|
||||
msgstr "Servidor HTTP"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:718
|
||||
#: htdocs/luci-static/resources/view/natmap.js:743
|
||||
msgid "HTTPS Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -283,8 +288,8 @@ msgstr ""
|
||||
msgid "Port forwarding session idle timeout in seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:704
|
||||
#: htdocs/luci-static/resources/view/natmap.js:752
|
||||
#: htdocs/luci-static/resources/view/natmap.js:729
|
||||
#: htdocs/luci-static/resources/view/natmap.js:777
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
@@ -293,7 +298,7 @@ msgid "Private API Domain"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:341
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
#: htdocs/luci-static/resources/view/status/include/72_natmap.js:60
|
||||
msgid "Protocol"
|
||||
msgstr "Protocolo"
|
||||
@@ -319,7 +324,7 @@ msgstr ""
|
||||
msgid "Restrict to address family"
|
||||
msgstr "Restringe à uma família de endereços"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
#: htdocs/luci-static/resources/view/natmap.js:681
|
||||
msgid "SRV Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -338,7 +343,7 @@ msgstr "Servidor STUN"
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
@@ -346,12 +351,12 @@ msgstr ""
|
||||
msgid "Set 0 will follow Public port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:745
|
||||
#: htdocs/luci-static/resources/view/natmap.js:770
|
||||
msgid "SvcParams"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:174
|
||||
#: htdocs/luci-static/resources/view/natmap.js:689
|
||||
#: htdocs/luci-static/resources/view/natmap.js:713
|
||||
msgid "TCP"
|
||||
msgstr ""
|
||||
|
||||
@@ -363,12 +368,16 @@ msgstr ""
|
||||
msgid "TCP STUN"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:691
|
||||
#: htdocs/luci-static/resources/view/natmap.js:715
|
||||
msgid "TLS"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:697
|
||||
#: htdocs/luci-static/resources/view/natmap.js:737
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
msgid "TXT Record"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:722
|
||||
#: htdocs/luci-static/resources/view/natmap.js:762
|
||||
msgid "Target"
|
||||
msgstr ""
|
||||
|
||||
@@ -426,7 +435,7 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:179
|
||||
#: htdocs/luci-static/resources/view/natmap.js:184
|
||||
#: htdocs/luci-static/resources/view/natmap.js:690
|
||||
#: htdocs/luci-static/resources/view/natmap.js:714
|
||||
msgid "UDP"
|
||||
msgstr ""
|
||||
|
||||
@@ -450,10 +459,14 @@ msgstr ""
|
||||
msgid "Web UI Port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:711
|
||||
#: htdocs/luci-static/resources/view/natmap.js:736
|
||||
msgid "Weight"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:716
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:163
|
||||
msgid ""
|
||||
"https://github.com/muink/rfc5780-stun-server/blob/master/valid_hosts_rfc5780."
|
||||
@@ -475,7 +488,7 @@ msgstr ""
|
||||
msgid "luci check may not detect all conflicts."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:764
|
||||
#: htdocs/luci-static/resources/view/natmap.js:789
|
||||
msgid "⭮"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -49,8 +49,8 @@ msgstr "Legați portul"
|
||||
msgid "Boot delay"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
msgid "Can refer to RFC8552"
|
||||
msgstr ""
|
||||
|
||||
@@ -66,8 +66,12 @@ msgstr ""
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:675
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:306
|
||||
#: htdocs/luci-static/resources/view/natmap.js:759
|
||||
#: htdocs/luci-static/resources/view/natmap.js:784
|
||||
msgid "Custom Script"
|
||||
msgstr ""
|
||||
|
||||
@@ -123,8 +127,9 @@ msgstr "Port extern"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:644
|
||||
#: htdocs/luci-static/resources/view/natmap.js:651
|
||||
#: htdocs/luci-static/resources/view/natmap.js:673
|
||||
#: htdocs/luci-static/resources/view/natmap.js:731
|
||||
#: htdocs/luci-static/resources/view/natmap.js:669
|
||||
#: htdocs/luci-static/resources/view/natmap.js:696
|
||||
#: htdocs/luci-static/resources/view/natmap.js:756
|
||||
msgid "FQDN"
|
||||
msgstr ""
|
||||
|
||||
@@ -187,7 +192,7 @@ msgstr ""
|
||||
msgid "HTTP server"
|
||||
msgstr "Server HTTP"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:718
|
||||
#: htdocs/luci-static/resources/view/natmap.js:743
|
||||
msgid "HTTPS Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -284,8 +289,8 @@ msgstr ""
|
||||
msgid "Port forwarding session idle timeout in seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:704
|
||||
#: htdocs/luci-static/resources/view/natmap.js:752
|
||||
#: htdocs/luci-static/resources/view/natmap.js:729
|
||||
#: htdocs/luci-static/resources/view/natmap.js:777
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
@@ -294,7 +299,7 @@ msgid "Private API Domain"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:341
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
#: htdocs/luci-static/resources/view/status/include/72_natmap.js:60
|
||||
msgid "Protocol"
|
||||
msgstr "Protocol"
|
||||
@@ -320,7 +325,7 @@ msgstr ""
|
||||
msgid "Restrict to address family"
|
||||
msgstr "Restricționarea la adresa familiei"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
#: htdocs/luci-static/resources/view/natmap.js:681
|
||||
msgid "SRV Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -339,7 +344,7 @@ msgstr "Server STUN"
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
@@ -347,12 +352,12 @@ msgstr ""
|
||||
msgid "Set 0 will follow Public port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:745
|
||||
#: htdocs/luci-static/resources/view/natmap.js:770
|
||||
msgid "SvcParams"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:174
|
||||
#: htdocs/luci-static/resources/view/natmap.js:689
|
||||
#: htdocs/luci-static/resources/view/natmap.js:713
|
||||
msgid "TCP"
|
||||
msgstr ""
|
||||
|
||||
@@ -364,12 +369,16 @@ msgstr ""
|
||||
msgid "TCP STUN"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:691
|
||||
#: htdocs/luci-static/resources/view/natmap.js:715
|
||||
msgid "TLS"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:697
|
||||
#: htdocs/luci-static/resources/view/natmap.js:737
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
msgid "TXT Record"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:722
|
||||
#: htdocs/luci-static/resources/view/natmap.js:762
|
||||
msgid "Target"
|
||||
msgstr ""
|
||||
|
||||
@@ -427,7 +436,7 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:179
|
||||
#: htdocs/luci-static/resources/view/natmap.js:184
|
||||
#: htdocs/luci-static/resources/view/natmap.js:690
|
||||
#: htdocs/luci-static/resources/view/natmap.js:714
|
||||
msgid "UDP"
|
||||
msgstr ""
|
||||
|
||||
@@ -451,10 +460,14 @@ msgstr ""
|
||||
msgid "Web UI Port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:711
|
||||
#: htdocs/luci-static/resources/view/natmap.js:736
|
||||
msgid "Weight"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:716
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:163
|
||||
msgid ""
|
||||
"https://github.com/muink/rfc5780-stun-server/blob/master/valid_hosts_rfc5780."
|
||||
@@ -476,7 +489,7 @@ msgstr ""
|
||||
msgid "luci check may not detect all conflicts."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:764
|
||||
#: htdocs/luci-static/resources/view/natmap.js:789
|
||||
msgid "⭮"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -49,8 +49,8 @@ msgstr "Порт сервера"
|
||||
msgid "Boot delay"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
msgid "Can refer to RFC8552"
|
||||
msgstr ""
|
||||
|
||||
@@ -66,8 +66,12 @@ msgstr ""
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:675
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:306
|
||||
#: htdocs/luci-static/resources/view/natmap.js:759
|
||||
#: htdocs/luci-static/resources/view/natmap.js:784
|
||||
msgid "Custom Script"
|
||||
msgstr ""
|
||||
|
||||
@@ -123,8 +127,9 @@ msgstr "Внешний порт"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:644
|
||||
#: htdocs/luci-static/resources/view/natmap.js:651
|
||||
#: htdocs/luci-static/resources/view/natmap.js:673
|
||||
#: htdocs/luci-static/resources/view/natmap.js:731
|
||||
#: htdocs/luci-static/resources/view/natmap.js:669
|
||||
#: htdocs/luci-static/resources/view/natmap.js:696
|
||||
#: htdocs/luci-static/resources/view/natmap.js:756
|
||||
msgid "FQDN"
|
||||
msgstr ""
|
||||
|
||||
@@ -187,7 +192,7 @@ msgstr ""
|
||||
msgid "HTTP server"
|
||||
msgstr "HTTP-сервер"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:718
|
||||
#: htdocs/luci-static/resources/view/natmap.js:743
|
||||
msgid "HTTPS Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -284,8 +289,8 @@ msgstr ""
|
||||
msgid "Port forwarding session idle timeout in seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:704
|
||||
#: htdocs/luci-static/resources/view/natmap.js:752
|
||||
#: htdocs/luci-static/resources/view/natmap.js:729
|
||||
#: htdocs/luci-static/resources/view/natmap.js:777
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
@@ -294,7 +299,7 @@ msgid "Private API Domain"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:341
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
#: htdocs/luci-static/resources/view/status/include/72_natmap.js:60
|
||||
msgid "Protocol"
|
||||
msgstr "Протокол"
|
||||
@@ -320,7 +325,7 @@ msgstr ""
|
||||
msgid "Restrict to address family"
|
||||
msgstr "Использовать протокол"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
#: htdocs/luci-static/resources/view/natmap.js:681
|
||||
msgid "SRV Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -339,7 +344,7 @@ msgstr "Сервер STUN"
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
@@ -347,12 +352,12 @@ msgstr ""
|
||||
msgid "Set 0 will follow Public port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:745
|
||||
#: htdocs/luci-static/resources/view/natmap.js:770
|
||||
msgid "SvcParams"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:174
|
||||
#: htdocs/luci-static/resources/view/natmap.js:689
|
||||
#: htdocs/luci-static/resources/view/natmap.js:713
|
||||
msgid "TCP"
|
||||
msgstr ""
|
||||
|
||||
@@ -364,12 +369,16 @@ msgstr ""
|
||||
msgid "TCP STUN"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:691
|
||||
#: htdocs/luci-static/resources/view/natmap.js:715
|
||||
msgid "TLS"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:697
|
||||
#: htdocs/luci-static/resources/view/natmap.js:737
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
msgid "TXT Record"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:722
|
||||
#: htdocs/luci-static/resources/view/natmap.js:762
|
||||
msgid "Target"
|
||||
msgstr ""
|
||||
|
||||
@@ -427,7 +436,7 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:179
|
||||
#: htdocs/luci-static/resources/view/natmap.js:184
|
||||
#: htdocs/luci-static/resources/view/natmap.js:690
|
||||
#: htdocs/luci-static/resources/view/natmap.js:714
|
||||
msgid "UDP"
|
||||
msgstr ""
|
||||
|
||||
@@ -451,10 +460,14 @@ msgstr ""
|
||||
msgid "Web UI Port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:711
|
||||
#: htdocs/luci-static/resources/view/natmap.js:736
|
||||
msgid "Weight"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:716
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:163
|
||||
msgid ""
|
||||
"https://github.com/muink/rfc5780-stun-server/blob/master/valid_hosts_rfc5780."
|
||||
@@ -476,7 +489,7 @@ msgstr ""
|
||||
msgid "luci check may not detect all conflicts."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:764
|
||||
#: htdocs/luci-static/resources/view/natmap.js:789
|
||||
msgid "⭮"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -42,8 +42,8 @@ msgstr ""
|
||||
msgid "Boot delay"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
msgid "Can refer to RFC8552"
|
||||
msgstr ""
|
||||
|
||||
@@ -59,8 +59,12 @@ msgstr ""
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:675
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:306
|
||||
#: htdocs/luci-static/resources/view/natmap.js:759
|
||||
#: htdocs/luci-static/resources/view/natmap.js:784
|
||||
msgid "Custom Script"
|
||||
msgstr ""
|
||||
|
||||
@@ -116,8 +120,9 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:644
|
||||
#: htdocs/luci-static/resources/view/natmap.js:651
|
||||
#: htdocs/luci-static/resources/view/natmap.js:673
|
||||
#: htdocs/luci-static/resources/view/natmap.js:731
|
||||
#: htdocs/luci-static/resources/view/natmap.js:669
|
||||
#: htdocs/luci-static/resources/view/natmap.js:696
|
||||
#: htdocs/luci-static/resources/view/natmap.js:756
|
||||
msgid "FQDN"
|
||||
msgstr ""
|
||||
|
||||
@@ -180,7 +185,7 @@ msgstr ""
|
||||
msgid "HTTP server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:718
|
||||
#: htdocs/luci-static/resources/view/natmap.js:743
|
||||
msgid "HTTPS Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -277,8 +282,8 @@ msgstr ""
|
||||
msgid "Port forwarding session idle timeout in seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:704
|
||||
#: htdocs/luci-static/resources/view/natmap.js:752
|
||||
#: htdocs/luci-static/resources/view/natmap.js:729
|
||||
#: htdocs/luci-static/resources/view/natmap.js:777
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
@@ -287,7 +292,7 @@ msgid "Private API Domain"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:341
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
#: htdocs/luci-static/resources/view/status/include/72_natmap.js:60
|
||||
msgid "Protocol"
|
||||
msgstr ""
|
||||
@@ -313,7 +318,7 @@ msgstr ""
|
||||
msgid "Restrict to address family"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
#: htdocs/luci-static/resources/view/natmap.js:681
|
||||
msgid "SRV Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -332,7 +337,7 @@ msgstr ""
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
@@ -340,12 +345,12 @@ msgstr ""
|
||||
msgid "Set 0 will follow Public port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:745
|
||||
#: htdocs/luci-static/resources/view/natmap.js:770
|
||||
msgid "SvcParams"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:174
|
||||
#: htdocs/luci-static/resources/view/natmap.js:689
|
||||
#: htdocs/luci-static/resources/view/natmap.js:713
|
||||
msgid "TCP"
|
||||
msgstr ""
|
||||
|
||||
@@ -357,12 +362,16 @@ msgstr ""
|
||||
msgid "TCP STUN"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:691
|
||||
#: htdocs/luci-static/resources/view/natmap.js:715
|
||||
msgid "TLS"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:697
|
||||
#: htdocs/luci-static/resources/view/natmap.js:737
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
msgid "TXT Record"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:722
|
||||
#: htdocs/luci-static/resources/view/natmap.js:762
|
||||
msgid "Target"
|
||||
msgstr ""
|
||||
|
||||
@@ -420,7 +429,7 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:179
|
||||
#: htdocs/luci-static/resources/view/natmap.js:184
|
||||
#: htdocs/luci-static/resources/view/natmap.js:690
|
||||
#: htdocs/luci-static/resources/view/natmap.js:714
|
||||
msgid "UDP"
|
||||
msgstr ""
|
||||
|
||||
@@ -444,10 +453,14 @@ msgstr ""
|
||||
msgid "Web UI Port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:711
|
||||
#: htdocs/luci-static/resources/view/natmap.js:736
|
||||
msgid "Weight"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:716
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:163
|
||||
msgid ""
|
||||
"https://github.com/muink/rfc5780-stun-server/blob/master/valid_hosts_rfc5780."
|
||||
@@ -469,6 +482,6 @@ msgstr ""
|
||||
msgid "luci check may not detect all conflicts."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:764
|
||||
#: htdocs/luci-static/resources/view/natmap.js:789
|
||||
msgid "⭮"
|
||||
msgstr ""
|
||||
@@ -39,8 +39,8 @@ msgstr ""
|
||||
msgid "Boot delay"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
msgid "Can refer to RFC8552"
|
||||
msgstr ""
|
||||
|
||||
@@ -56,8 +56,12 @@ msgstr ""
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:675
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:306
|
||||
#: htdocs/luci-static/resources/view/natmap.js:759
|
||||
#: htdocs/luci-static/resources/view/natmap.js:784
|
||||
msgid "Custom Script"
|
||||
msgstr ""
|
||||
|
||||
@@ -113,8 +117,9 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:644
|
||||
#: htdocs/luci-static/resources/view/natmap.js:651
|
||||
#: htdocs/luci-static/resources/view/natmap.js:673
|
||||
#: htdocs/luci-static/resources/view/natmap.js:731
|
||||
#: htdocs/luci-static/resources/view/natmap.js:669
|
||||
#: htdocs/luci-static/resources/view/natmap.js:696
|
||||
#: htdocs/luci-static/resources/view/natmap.js:756
|
||||
msgid "FQDN"
|
||||
msgstr ""
|
||||
|
||||
@@ -177,7 +182,7 @@ msgstr ""
|
||||
msgid "HTTP server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:718
|
||||
#: htdocs/luci-static/resources/view/natmap.js:743
|
||||
msgid "HTTPS Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -274,8 +279,8 @@ msgstr ""
|
||||
msgid "Port forwarding session idle timeout in seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:704
|
||||
#: htdocs/luci-static/resources/view/natmap.js:752
|
||||
#: htdocs/luci-static/resources/view/natmap.js:729
|
||||
#: htdocs/luci-static/resources/view/natmap.js:777
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
@@ -284,7 +289,7 @@ msgid "Private API Domain"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:341
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
#: htdocs/luci-static/resources/view/status/include/72_natmap.js:60
|
||||
msgid "Protocol"
|
||||
msgstr ""
|
||||
@@ -310,7 +315,7 @@ msgstr ""
|
||||
msgid "Restrict to address family"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
#: htdocs/luci-static/resources/view/natmap.js:681
|
||||
msgid "SRV Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -329,7 +334,7 @@ msgstr ""
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
@@ -337,12 +342,12 @@ msgstr ""
|
||||
msgid "Set 0 will follow Public port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:745
|
||||
#: htdocs/luci-static/resources/view/natmap.js:770
|
||||
msgid "SvcParams"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:174
|
||||
#: htdocs/luci-static/resources/view/natmap.js:689
|
||||
#: htdocs/luci-static/resources/view/natmap.js:713
|
||||
msgid "TCP"
|
||||
msgstr ""
|
||||
|
||||
@@ -354,12 +359,16 @@ msgstr ""
|
||||
msgid "TCP STUN"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:691
|
||||
#: htdocs/luci-static/resources/view/natmap.js:715
|
||||
msgid "TLS"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:697
|
||||
#: htdocs/luci-static/resources/view/natmap.js:737
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
msgid "TXT Record"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:722
|
||||
#: htdocs/luci-static/resources/view/natmap.js:762
|
||||
msgid "Target"
|
||||
msgstr ""
|
||||
|
||||
@@ -417,7 +426,7 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:179
|
||||
#: htdocs/luci-static/resources/view/natmap.js:184
|
||||
#: htdocs/luci-static/resources/view/natmap.js:690
|
||||
#: htdocs/luci-static/resources/view/natmap.js:714
|
||||
msgid "UDP"
|
||||
msgstr ""
|
||||
|
||||
@@ -441,10 +450,14 @@ msgstr ""
|
||||
msgid "Web UI Port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:711
|
||||
#: htdocs/luci-static/resources/view/natmap.js:736
|
||||
msgid "Weight"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:716
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:163
|
||||
msgid ""
|
||||
"https://github.com/muink/rfc5780-stun-server/blob/master/valid_hosts_rfc5780."
|
||||
@@ -466,6 +479,6 @@ msgstr ""
|
||||
msgid "luci check may not detect all conflicts."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:764
|
||||
#: htdocs/luci-static/resources/view/natmap.js:789
|
||||
msgid "⭮"
|
||||
msgstr ""
|
||||
@@ -42,8 +42,8 @@ msgstr ""
|
||||
msgid "Boot delay"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
msgid "Can refer to RFC8552"
|
||||
msgstr ""
|
||||
|
||||
@@ -59,8 +59,12 @@ msgstr ""
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:675
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:306
|
||||
#: htdocs/luci-static/resources/view/natmap.js:759
|
||||
#: htdocs/luci-static/resources/view/natmap.js:784
|
||||
msgid "Custom Script"
|
||||
msgstr ""
|
||||
|
||||
@@ -116,8 +120,9 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:644
|
||||
#: htdocs/luci-static/resources/view/natmap.js:651
|
||||
#: htdocs/luci-static/resources/view/natmap.js:673
|
||||
#: htdocs/luci-static/resources/view/natmap.js:731
|
||||
#: htdocs/luci-static/resources/view/natmap.js:669
|
||||
#: htdocs/luci-static/resources/view/natmap.js:696
|
||||
#: htdocs/luci-static/resources/view/natmap.js:756
|
||||
msgid "FQDN"
|
||||
msgstr ""
|
||||
|
||||
@@ -180,7 +185,7 @@ msgstr ""
|
||||
msgid "HTTP server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:718
|
||||
#: htdocs/luci-static/resources/view/natmap.js:743
|
||||
msgid "HTTPS Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -277,8 +282,8 @@ msgstr ""
|
||||
msgid "Port forwarding session idle timeout in seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:704
|
||||
#: htdocs/luci-static/resources/view/natmap.js:752
|
||||
#: htdocs/luci-static/resources/view/natmap.js:729
|
||||
#: htdocs/luci-static/resources/view/natmap.js:777
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
@@ -287,7 +292,7 @@ msgid "Private API Domain"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:341
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
#: htdocs/luci-static/resources/view/status/include/72_natmap.js:60
|
||||
msgid "Protocol"
|
||||
msgstr ""
|
||||
@@ -313,7 +318,7 @@ msgstr ""
|
||||
msgid "Restrict to address family"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
#: htdocs/luci-static/resources/view/natmap.js:681
|
||||
msgid "SRV Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -332,7 +337,7 @@ msgstr ""
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
@@ -340,12 +345,12 @@ msgstr ""
|
||||
msgid "Set 0 will follow Public port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:745
|
||||
#: htdocs/luci-static/resources/view/natmap.js:770
|
||||
msgid "SvcParams"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:174
|
||||
#: htdocs/luci-static/resources/view/natmap.js:689
|
||||
#: htdocs/luci-static/resources/view/natmap.js:713
|
||||
msgid "TCP"
|
||||
msgstr ""
|
||||
|
||||
@@ -357,12 +362,16 @@ msgstr ""
|
||||
msgid "TCP STUN"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:691
|
||||
#: htdocs/luci-static/resources/view/natmap.js:715
|
||||
msgid "TLS"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:697
|
||||
#: htdocs/luci-static/resources/view/natmap.js:737
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
msgid "TXT Record"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:722
|
||||
#: htdocs/luci-static/resources/view/natmap.js:762
|
||||
msgid "Target"
|
||||
msgstr ""
|
||||
|
||||
@@ -420,7 +429,7 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:179
|
||||
#: htdocs/luci-static/resources/view/natmap.js:184
|
||||
#: htdocs/luci-static/resources/view/natmap.js:690
|
||||
#: htdocs/luci-static/resources/view/natmap.js:714
|
||||
msgid "UDP"
|
||||
msgstr ""
|
||||
|
||||
@@ -444,10 +453,14 @@ msgstr ""
|
||||
msgid "Web UI Port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:711
|
||||
#: htdocs/luci-static/resources/view/natmap.js:736
|
||||
msgid "Weight"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:716
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:163
|
||||
msgid ""
|
||||
"https://github.com/muink/rfc5780-stun-server/blob/master/valid_hosts_rfc5780."
|
||||
@@ -469,6 +482,6 @@ msgstr ""
|
||||
msgid "luci check may not detect all conflicts."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:764
|
||||
#: htdocs/luci-static/resources/view/natmap.js:789
|
||||
msgid "⭮"
|
||||
msgstr ""
|
||||
@@ -48,8 +48,8 @@ msgstr "Cổng Bind"
|
||||
msgid "Boot delay"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
msgid "Can refer to RFC8552"
|
||||
msgstr ""
|
||||
|
||||
@@ -65,8 +65,12 @@ msgstr ""
|
||||
msgid "Comment"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:675
|
||||
msgid "Content"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:306
|
||||
#: htdocs/luci-static/resources/view/natmap.js:759
|
||||
#: htdocs/luci-static/resources/view/natmap.js:784
|
||||
msgid "Custom Script"
|
||||
msgstr ""
|
||||
|
||||
@@ -122,8 +126,9 @@ msgstr "Cổng bên ngoài"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:644
|
||||
#: htdocs/luci-static/resources/view/natmap.js:651
|
||||
#: htdocs/luci-static/resources/view/natmap.js:673
|
||||
#: htdocs/luci-static/resources/view/natmap.js:731
|
||||
#: htdocs/luci-static/resources/view/natmap.js:669
|
||||
#: htdocs/luci-static/resources/view/natmap.js:696
|
||||
#: htdocs/luci-static/resources/view/natmap.js:756
|
||||
msgid "FQDN"
|
||||
msgstr ""
|
||||
|
||||
@@ -186,7 +191,7 @@ msgstr ""
|
||||
msgid "HTTP server"
|
||||
msgstr "HTTP server"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:718
|
||||
#: htdocs/luci-static/resources/view/natmap.js:743
|
||||
msgid "HTTPS Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -283,8 +288,8 @@ msgstr ""
|
||||
msgid "Port forwarding session idle timeout in seconds"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:704
|
||||
#: htdocs/luci-static/resources/view/natmap.js:752
|
||||
#: htdocs/luci-static/resources/view/natmap.js:729
|
||||
#: htdocs/luci-static/resources/view/natmap.js:777
|
||||
msgid "Priority"
|
||||
msgstr ""
|
||||
|
||||
@@ -293,7 +298,7 @@ msgid "Private API Domain"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:341
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
#: htdocs/luci-static/resources/view/status/include/72_natmap.js:60
|
||||
msgid "Protocol"
|
||||
msgstr "Giao thức"
|
||||
@@ -319,7 +324,7 @@ msgstr ""
|
||||
msgid "Restrict to address family"
|
||||
msgstr "Giới hạn địa chỉ gia đình"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
#: htdocs/luci-static/resources/view/natmap.js:681
|
||||
msgid "SRV Record"
|
||||
msgstr ""
|
||||
|
||||
@@ -338,7 +343,7 @@ msgstr "Máy chủ STUN"
|
||||
msgid "Server"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
msgid "Service"
|
||||
msgstr ""
|
||||
|
||||
@@ -346,12 +351,12 @@ msgstr ""
|
||||
msgid "Set 0 will follow Public port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:745
|
||||
#: htdocs/luci-static/resources/view/natmap.js:770
|
||||
msgid "SvcParams"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:174
|
||||
#: htdocs/luci-static/resources/view/natmap.js:689
|
||||
#: htdocs/luci-static/resources/view/natmap.js:713
|
||||
msgid "TCP"
|
||||
msgstr ""
|
||||
|
||||
@@ -363,12 +368,16 @@ msgstr ""
|
||||
msgid "TCP STUN"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:691
|
||||
#: htdocs/luci-static/resources/view/natmap.js:715
|
||||
msgid "TLS"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:697
|
||||
#: htdocs/luci-static/resources/view/natmap.js:737
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
msgid "TXT Record"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:722
|
||||
#: htdocs/luci-static/resources/view/natmap.js:762
|
||||
msgid "Target"
|
||||
msgstr ""
|
||||
|
||||
@@ -426,7 +435,7 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:179
|
||||
#: htdocs/luci-static/resources/view/natmap.js:184
|
||||
#: htdocs/luci-static/resources/view/natmap.js:690
|
||||
#: htdocs/luci-static/resources/view/natmap.js:714
|
||||
msgid "UDP"
|
||||
msgstr ""
|
||||
|
||||
@@ -450,10 +459,14 @@ msgstr ""
|
||||
msgid "Web UI Port"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:711
|
||||
#: htdocs/luci-static/resources/view/natmap.js:736
|
||||
msgid "Weight"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:716
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:163
|
||||
msgid ""
|
||||
"https://github.com/muink/rfc5780-stun-server/blob/master/valid_hosts_rfc5780."
|
||||
@@ -475,7 +488,7 @@ msgstr ""
|
||||
msgid "luci check may not detect all conflicts."
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:764
|
||||
#: htdocs/luci-static/resources/view/natmap.js:789
|
||||
msgid "⭮"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@ msgstr "绑定端口"
|
||||
msgid "Boot delay"
|
||||
msgstr "启动延迟"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
msgid "Can refer to RFC8552"
|
||||
msgstr "可以参考 RFC8552"
|
||||
|
||||
@@ -65,8 +65,12 @@ msgstr "检测 NAT 行为"
|
||||
msgid "Comment"
|
||||
msgstr "备注"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:675
|
||||
msgid "Content"
|
||||
msgstr "内容"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:306
|
||||
#: htdocs/luci-static/resources/view/natmap.js:759
|
||||
#: htdocs/luci-static/resources/view/natmap.js:784
|
||||
msgid "Custom Script"
|
||||
msgstr "自定义脚本"
|
||||
|
||||
@@ -122,8 +126,9 @@ msgstr "外部端口"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:644
|
||||
#: htdocs/luci-static/resources/view/natmap.js:651
|
||||
#: htdocs/luci-static/resources/view/natmap.js:673
|
||||
#: htdocs/luci-static/resources/view/natmap.js:731
|
||||
#: htdocs/luci-static/resources/view/natmap.js:669
|
||||
#: htdocs/luci-static/resources/view/natmap.js:696
|
||||
#: htdocs/luci-static/resources/view/natmap.js:756
|
||||
msgid "FQDN"
|
||||
msgstr ""
|
||||
|
||||
@@ -186,7 +191,7 @@ msgstr ""
|
||||
msgid "HTTP server"
|
||||
msgstr "HTTP 服务器"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:718
|
||||
#: htdocs/luci-static/resources/view/natmap.js:743
|
||||
msgid "HTTPS Record"
|
||||
msgstr "HTTPS 记录"
|
||||
|
||||
@@ -283,8 +288,8 @@ msgstr "请检查<a href=\"%s\"><b>防火墙规则</b></a>以避免端口冲突<
|
||||
msgid "Port forwarding session idle timeout in seconds"
|
||||
msgstr "端口转发会话空闲超时 (以秒为单位)"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:704
|
||||
#: htdocs/luci-static/resources/view/natmap.js:752
|
||||
#: htdocs/luci-static/resources/view/natmap.js:729
|
||||
#: htdocs/luci-static/resources/view/natmap.js:777
|
||||
msgid "Priority"
|
||||
msgstr "优先权"
|
||||
|
||||
@@ -293,7 +298,7 @@ msgid "Private API Domain"
|
||||
msgstr "私有 API 域名"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:341
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
#: htdocs/luci-static/resources/view/status/include/72_natmap.js:60
|
||||
msgid "Protocol"
|
||||
msgstr "协议"
|
||||
@@ -319,7 +324,7 @@ msgstr "重新载入"
|
||||
msgid "Restrict to address family"
|
||||
msgstr "地址族限制"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
#: htdocs/luci-static/resources/view/natmap.js:681
|
||||
msgid "SRV Record"
|
||||
msgstr "SRV 记录"
|
||||
|
||||
@@ -338,7 +343,7 @@ msgstr "STUN 服务器"
|
||||
msgid "Server"
|
||||
msgstr "服务器"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
msgid "Service"
|
||||
msgstr "服务"
|
||||
|
||||
@@ -346,12 +351,12 @@ msgstr "服务"
|
||||
msgid "Set 0 will follow Public port"
|
||||
msgstr "设为 0 将跟随公共端口"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:745
|
||||
#: htdocs/luci-static/resources/view/natmap.js:770
|
||||
msgid "SvcParams"
|
||||
msgstr "服务参数"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:174
|
||||
#: htdocs/luci-static/resources/view/natmap.js:689
|
||||
#: htdocs/luci-static/resources/view/natmap.js:713
|
||||
msgid "TCP"
|
||||
msgstr ""
|
||||
|
||||
@@ -363,12 +368,16 @@ msgstr "TCP 拥塞控制"
|
||||
msgid "TCP STUN"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:691
|
||||
#: htdocs/luci-static/resources/view/natmap.js:715
|
||||
msgid "TLS"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:697
|
||||
#: htdocs/luci-static/resources/view/natmap.js:737
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
msgid "TXT Record"
|
||||
msgstr "TXT 记录"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:722
|
||||
#: htdocs/luci-static/resources/view/natmap.js:762
|
||||
msgid "Target"
|
||||
msgstr "目标"
|
||||
|
||||
@@ -428,7 +437,7 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:179
|
||||
#: htdocs/luci-static/resources/view/natmap.js:184
|
||||
#: htdocs/luci-static/resources/view/natmap.js:690
|
||||
#: htdocs/luci-static/resources/view/natmap.js:714
|
||||
msgid "UDP"
|
||||
msgstr ""
|
||||
|
||||
@@ -452,10 +461,14 @@ msgstr "经由 natmap"
|
||||
msgid "Web UI Port"
|
||||
msgstr "Web UI 端口"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:711
|
||||
#: htdocs/luci-static/resources/view/natmap.js:736
|
||||
msgid "Weight"
|
||||
msgstr "权重"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:716
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:163
|
||||
msgid ""
|
||||
"https://github.com/muink/rfc5780-stun-server/blob/master/valid_hosts_rfc5780."
|
||||
@@ -477,7 +490,7 @@ msgstr "keep-alive 间隔 (秒)"
|
||||
msgid "luci check may not detect all conflicts."
|
||||
msgstr "luci 检查可能无法检测到所有冲突"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:764
|
||||
#: htdocs/luci-static/resources/view/natmap.js:789
|
||||
msgid "⭮"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@ msgstr "綁定埠"
|
||||
msgid "Boot delay"
|
||||
msgstr "啟動延遲"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
msgid "Can refer to RFC8552"
|
||||
msgstr "可以參考 RFC8552"
|
||||
|
||||
@@ -65,8 +65,12 @@ msgstr "檢查 NAT 行為"
|
||||
msgid "Comment"
|
||||
msgstr "備註"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:675
|
||||
msgid "Content"
|
||||
msgstr "內容"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:306
|
||||
#: htdocs/luci-static/resources/view/natmap.js:759
|
||||
#: htdocs/luci-static/resources/view/natmap.js:784
|
||||
msgid "Custom Script"
|
||||
msgstr "自定義腳本"
|
||||
|
||||
@@ -122,8 +126,9 @@ msgstr "外部通訊埠"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:644
|
||||
#: htdocs/luci-static/resources/view/natmap.js:651
|
||||
#: htdocs/luci-static/resources/view/natmap.js:673
|
||||
#: htdocs/luci-static/resources/view/natmap.js:731
|
||||
#: htdocs/luci-static/resources/view/natmap.js:669
|
||||
#: htdocs/luci-static/resources/view/natmap.js:696
|
||||
#: htdocs/luci-static/resources/view/natmap.js:756
|
||||
msgid "FQDN"
|
||||
msgstr ""
|
||||
|
||||
@@ -186,7 +191,7 @@ msgstr ""
|
||||
msgid "HTTP server"
|
||||
msgstr "HTTP 伺服器"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:718
|
||||
#: htdocs/luci-static/resources/view/natmap.js:743
|
||||
msgid "HTTPS Record"
|
||||
msgstr "HTTPS 記錄"
|
||||
|
||||
@@ -283,8 +288,8 @@ msgstr "請檢查<a href=\"%s\"><b>防火牆規則</b></a>以避免埠衝突</br
|
||||
msgid "Port forwarding session idle timeout in seconds"
|
||||
msgstr "連接埠轉發會話空閒逾時 (以秒為單位)"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:704
|
||||
#: htdocs/luci-static/resources/view/natmap.js:752
|
||||
#: htdocs/luci-static/resources/view/natmap.js:729
|
||||
#: htdocs/luci-static/resources/view/natmap.js:777
|
||||
msgid "Priority"
|
||||
msgstr "優先權"
|
||||
|
||||
@@ -293,7 +298,7 @@ msgid "Private API Domain"
|
||||
msgstr "私有 API 域名"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:341
|
||||
#: htdocs/luci-static/resources/view/natmap.js:688
|
||||
#: htdocs/luci-static/resources/view/natmap.js:712
|
||||
#: htdocs/luci-static/resources/view/status/include/72_natmap.js:60
|
||||
msgid "Protocol"
|
||||
msgstr "協議"
|
||||
@@ -319,7 +324,7 @@ msgstr "重新載入"
|
||||
msgid "Restrict to address family"
|
||||
msgstr "限制到位址群"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
#: htdocs/luci-static/resources/view/natmap.js:681
|
||||
msgid "SRV Record"
|
||||
msgstr "SRV 記錄"
|
||||
|
||||
@@ -338,7 +343,7 @@ msgstr "STUN 伺服器"
|
||||
msgid "Server"
|
||||
msgstr "伺服器"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:679
|
||||
#: htdocs/luci-static/resources/view/natmap.js:702
|
||||
msgid "Service"
|
||||
msgstr "服務"
|
||||
|
||||
@@ -346,12 +351,12 @@ msgstr "服務"
|
||||
msgid "Set 0 will follow Public port"
|
||||
msgstr "設為 0 將遵循公共埠"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:745
|
||||
#: htdocs/luci-static/resources/view/natmap.js:770
|
||||
msgid "SvcParams"
|
||||
msgstr "服務參數"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:174
|
||||
#: htdocs/luci-static/resources/view/natmap.js:689
|
||||
#: htdocs/luci-static/resources/view/natmap.js:713
|
||||
msgid "TCP"
|
||||
msgstr ""
|
||||
|
||||
@@ -363,12 +368,16 @@ msgstr "TCP 擁塞控制"
|
||||
msgid "TCP STUN"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:691
|
||||
#: htdocs/luci-static/resources/view/natmap.js:715
|
||||
msgid "TLS"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:697
|
||||
#: htdocs/luci-static/resources/view/natmap.js:737
|
||||
#: htdocs/luci-static/resources/view/natmap.js:658
|
||||
msgid "TXT Record"
|
||||
msgstr "TXT 記錄"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:722
|
||||
#: htdocs/luci-static/resources/view/natmap.js:762
|
||||
msgid "Target"
|
||||
msgstr "目標"
|
||||
|
||||
@@ -428,7 +437,7 @@ msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:179
|
||||
#: htdocs/luci-static/resources/view/natmap.js:184
|
||||
#: htdocs/luci-static/resources/view/natmap.js:690
|
||||
#: htdocs/luci-static/resources/view/natmap.js:714
|
||||
msgid "UDP"
|
||||
msgstr ""
|
||||
|
||||
@@ -452,10 +461,14 @@ msgstr "經由 natmap"
|
||||
msgid "Web UI Port"
|
||||
msgstr "Web UI 通訊埠"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:711
|
||||
#: htdocs/luci-static/resources/view/natmap.js:736
|
||||
msgid "Weight"
|
||||
msgstr "權重"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:716
|
||||
msgid "WireGuard"
|
||||
msgstr ""
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:163
|
||||
msgid ""
|
||||
"https://github.com/muink/rfc5780-stun-server/blob/master/valid_hosts_rfc5780."
|
||||
@@ -477,7 +490,7 @@ msgstr "keep-alive 間隔 (秒)"
|
||||
msgid "luci check may not detect all conflicts."
|
||||
msgstr "luci 檢查可能無法檢測到所有衝突"
|
||||
|
||||
#: htdocs/luci-static/resources/view/natmap.js:764
|
||||
#: htdocs/luci-static/resources/view/natmap.js:789
|
||||
msgid "⭮"
|
||||
msgstr ""
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-open-box
|
||||
PKG_VERSION:=0.1.400
|
||||
PKG_RELEASE:=63
|
||||
PKG_VERSION:=0.1.405
|
||||
PKG_RELEASE:=64
|
||||
|
||||
PKG_MAINTAINER:=liandu2024
|
||||
PKG_LICENSE:=GPL-3.0-or-later
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-vantage
|
||||
PKG_VERSION:=1.0.14
|
||||
PKG_RELEASE:=24
|
||||
PKG_VERSION:=1.0.15
|
||||
PKG_RELEASE:=25
|
||||
PKG_LICENSE:=GPL-3.0-or-later
|
||||
|
||||
LUCI_TITLE:=Vantage dashboard
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -23,6 +23,16 @@ var UNSAFE_TEXT = /[\u0000-\u001f\u007f-\u009f\u00ad\u034f\u061c\u115f\u1160\u17
|
||||
return baseclass.extend({
|
||||
DASH: DASH,
|
||||
|
||||
/* N_() with English's rule where no catalogue has the string: LuCI
|
||||
picks the form by the language's rule even then, and a one-form
|
||||
language (Japanese, Korean...) would show "2 radio up" */
|
||||
N_: function(n, singular, plural, ctx) {
|
||||
var t = N_(n, singular, plural, ctx);
|
||||
if (n !== 1 && t === singular) return plural;
|
||||
if (n === 1 && t === plural) return singular;
|
||||
return t;
|
||||
},
|
||||
|
||||
/* bits per second -> { v: '372', u: 'Mbit/s' } */
|
||||
bitsParts: function(bps) {
|
||||
bps = num(bps);
|
||||
@@ -37,13 +47,31 @@ return baseclass.extend({
|
||||
return p.u ? p.v + ' ' + p.u : p.v;
|
||||
},
|
||||
|
||||
/* compact axis label: 400M, 1.5G, 20k */
|
||||
bitsShort: function(bps) {
|
||||
bps = num(bps);
|
||||
if (bps == null || bps <= 0) return '0';
|
||||
var u = [ '', 'k', 'M', 'G', 'T' ], i = 0;
|
||||
while (bps >= 1000 && i < u.length - 1) { bps /= 1000; i++; }
|
||||
return (bps >= 10 ? bps.toFixed(0) : String(+bps.toFixed(1))) + u[i];
|
||||
/* a download and upload rate for a row, as { dn, up, unit }: one
|
||||
unit for both when they read in the same one ('376', '3.4',
|
||||
'Mbit/s'), else each with its own and unit '' */
|
||||
rateParts: function(down, up) {
|
||||
var a = this.bitsParts(down), b = this.bitsParts(up);
|
||||
if (a.u && a.u === b.u) return { dn: a.v, up: b.v, unit: a.u };
|
||||
return { dn: a.u ? a.v + ' ' + a.u : a.v, up: b.u ? b.v + ' ' + b.u : b.v, unit: '' };
|
||||
},
|
||||
|
||||
/* '↓ 376 ↑ 3.4 Mbit/s', '↓ 12.3 Mbit/s ↑ 800 bit/s'; 'idle' when
|
||||
nothing moves */
|
||||
rates: function(down, up) {
|
||||
if (num(down) === 0 && num(up) === 0) return _('idle');
|
||||
var p = this.rateParts(down, up);
|
||||
return '↓ ' + p.dn + ' ↑ ' + p.up + (p.unit ? ' ' + p.unit : '');
|
||||
},
|
||||
|
||||
/* a count, its thousands set apart by a narrow no-break space (as SI
|
||||
writes them) from five digits on: 20224239 -> '20 224 239' */
|
||||
count: function(n) {
|
||||
n = num(n);
|
||||
if (n == null) return DASH;
|
||||
var s = String(Math.round(Math.abs(n)));
|
||||
if (s.length > 4) s = s.replace(/\B(?=(\d{3})+$)/g, '\u202f');
|
||||
return (n < 0 ? '−' : '') + s;
|
||||
},
|
||||
|
||||
/* binary units for memory/storage */
|
||||
@@ -115,10 +143,11 @@ return baseclass.extend({
|
||||
return /^([0-9a-f]{2}[:-]){5}[0-9a-f]{2}$/i.test(s) ? s.replace(/-/g, ':').toUpperCase() : s;
|
||||
},
|
||||
|
||||
/* last three octets: '…00:53:C1' (the distinguishing part of a MAC) */
|
||||
/* last two octets: '53:C1', what tells devices apart in a one-line
|
||||
name; '' for anything but a MAC */
|
||||
macTail: function(mac) {
|
||||
var m = this.mac(mac);
|
||||
return /^([0-9A-F]{2}:){5}[0-9A-F]{2}$/.test(m) ? '…' + m.slice(9) : m;
|
||||
return /^([0-9A-F]{2}:){5}[0-9A-F]{2}$/.test(m) ? m.slice(12) : '';
|
||||
},
|
||||
|
||||
/* Client- or radio-supplied text for display: invisible/reordering
|
||||
|
||||
@@ -245,11 +245,6 @@ function ipBytes(a) {
|
||||
return out.concat(tail);
|
||||
}
|
||||
|
||||
function ipFamily(a) {
|
||||
var b = ipBytes(a);
|
||||
return b ? (b.length === 4 ? 4 : 6) : 0;
|
||||
}
|
||||
|
||||
/* the leading one bits of a mask, -1 when they are not contiguous */
|
||||
function maskBits(m) {
|
||||
var bits = 0, zero = false;
|
||||
@@ -782,9 +777,10 @@ return baseclass.extend({
|
||||
families: fams
|
||||
};
|
||||
};
|
||||
/* the admin ports (ADMIN_PORTS) it opens to any address, [] for none */
|
||||
var admin = function(item, ports) {
|
||||
return item.from.anywhere && (item.proto[0] === 'all' || item.proto.indexOf('tcp') >= 0) &&
|
||||
ADMIN_PORTS.some(function(p) { return hasPort(ports, p); });
|
||||
if (!item.from.anywhere || !(item.proto[0] === 'all' || item.proto.indexOf('tcp') >= 0)) return [];
|
||||
return ADMIN_PORTS.filter(function(p) { return hasPort(ports, p); });
|
||||
};
|
||||
/* standard housekeeping: ping and other control messages, multicast
|
||||
membership, DHCP client replies, IPsec passed on to a host */
|
||||
@@ -848,8 +844,9 @@ return baseclass.extend({
|
||||
return;
|
||||
}
|
||||
open.push(item);
|
||||
if (admin(item, item.ports))
|
||||
warnFor(s, { level: 'warn', code: 'admin-open', kind: 'rule', name: item.name, ports: item.portText });
|
||||
var a = admin(item, item.ports);
|
||||
if (a.length)
|
||||
warnFor(s, { level: 'warn', code: 'admin-open', kind: 'rule', name: item.name, ports: item.portText, admin: a });
|
||||
});
|
||||
|
||||
of('redirect').forEach(function(s) {
|
||||
@@ -881,16 +878,17 @@ return baseclass.extend({
|
||||
var first = function(f) { return r.dest_ip.addrs.filter(function(a) { return a.family === f; })[0]; };
|
||||
item.local = !r.dest_ip ? true : (!own || !r.dest_ip.addrs) ? null
|
||||
: item.families.some(function(f) { var a = first(f); return !a || isOwn(a); });
|
||||
var a = admin(item, inner);
|
||||
if (item.local === null) {
|
||||
fwd.push(item);
|
||||
if (admin(item, inner))
|
||||
warnFor(s, { level: 'warn', code: 'admin-unsure', kind: 'redirect', name: item.name, host: item.host, ports: item.portText });
|
||||
if (a.length)
|
||||
warnFor(s, { level: 'warn', code: 'admin-unsure', kind: 'redirect', name: item.name, host: item.host, ports: item.portText, admin: a });
|
||||
return;
|
||||
}
|
||||
if (!item.local) { fwd.push(item); return; }
|
||||
open.push(item);
|
||||
if (admin(item, inner))
|
||||
warnFor(s, { level: 'warn', code: 'admin-open', kind: 'redirect', name: item.name, ports: item.portText });
|
||||
if (a.length)
|
||||
warnFor(s, { level: 'warn', code: 'admin-open', kind: 'redirect', name: item.name, ports: item.portText, admin: a });
|
||||
});
|
||||
|
||||
/* custom rules: files the firewall config names, whose rules this
|
||||
|
||||
@@ -21,7 +21,6 @@ var WEAK_DBM = -75;
|
||||
function num(v) { v = +v; return isFinite(v) ? v : 0; }
|
||||
function finite(v) { return typeof v === 'number' && isFinite(v); }
|
||||
function own(o, k) { return o != null && Object.prototype.hasOwnProperty.call(o, k); }
|
||||
function speedShort(mbps) { return mbps >= 1000 ? (mbps / 1000) + 'G' : mbps + 'M'; }
|
||||
function speedLong(mbps) { return mbps >= 1000 ? _('%s Gbit/s').format(mbps / 1000) : _('%s Mbit/s').format(mbps); }
|
||||
function rank(level) { return { err: 3, warn: 2, info: 1, ok: 0 }[level] || 0; }
|
||||
|
||||
@@ -53,10 +52,11 @@ return baseclass.extend({
|
||||
detail: _('%s negotiated only %d Mbit/s; a cable pair or port may be faulty').format(up.dev, up.speed.mbps), page: PAGES.network });
|
||||
else {
|
||||
var rate = live.uplinkRate && finite(live.uplinkRate.rx) && finite(live.uplinkRate.tx) ? live.uplinkRate : null;
|
||||
/* no-break spaces keep '↑ 2.9 Mbit/s' and '2.5G link' whole when the chip wraps */
|
||||
var link = up.speed ? _('%s link').format(speedShort(up.speed.mbps)).replace(/ /g, '\u00a0') : null;
|
||||
/* no-break spaces keep '↑ 2.9 Mbit/s' and '2.5 Gbit/s link' whole when the chip wraps */
|
||||
var link = up.speed ? _('%s link').format(speedLong(up.speed.mbps)).replace(/ /g, '\u00a0') : null;
|
||||
out.push({ id: 'uplink', level: 'ok', title: _('Uplink', 'vantage'), value: rate ? '↓ ' + fmt.bits(rate.rx) : _('Up', 'vantage'),
|
||||
reason: [ rate ? ('↑ ' + fmt.bits(rate.tx)).replace(/ /g, '\u00a0') : null, up.dev, link ].filter(Boolean).join(' · '),
|
||||
/* the device name only until there is a rate (the path names it) */
|
||||
reason: [ rate ? ('↑ ' + fmt.bits(rate.tx)).replace(/ /g, '\u00a0') : up.dev, link ].filter(Boolean).join(' · '),
|
||||
detail: (up.speed ? _('%s up at %s').format(up.dev, speedLong(up.speed.mbps)) : _('%s up').format(up.dev)) +
|
||||
(up.gateway ? ', ' + _('gateway %s').format(up.gateway) : '') +
|
||||
(rate ? '; ' + _('now %s down, %s up').format(fmt.bits(rate.rx), fmt.bits(rate.tx)) : ''),
|
||||
@@ -70,8 +70,9 @@ return baseclass.extend({
|
||||
var hot = live.temps && live.temps[0] ? fmt.celsius(live.temps[0].celsius) : null;
|
||||
if (cpu == null) out.push({ id: 'cpu', level: 'info', title: _('CPU', 'vantage'), value: fmt.DASH, reason: _('Measuring…'), detail: _('Measuring over the next poll'), page: PAGES.processes });
|
||||
else out.push({ id: 'cpu', level: cpu >= 90 ? 'err' : cpu >= 70 ? 'warn' : 'ok', title: _('CPU', 'vantage'), value: fmt.pct(cpu),
|
||||
reason: (cpu >= 70 ? _('Busy · load %s').format(fmt.load(load)) : _('Load %s · %d cores').format(fmt.load(load), cores)) + (hot ? ' · ' + hot : ''),
|
||||
detail: (cpu >= 70 ? _('Busy; load %s on %d cores; see the busiest processes').format(fmt.load(load), cores) : _('Load %s on %d cores').format(fmt.load(load), cores)) +
|
||||
reason: (cpu >= 70 ? _('Busy · load %s').format(fmt.load(load)) : fmt.N_(cores, 'Load %s · %d core', 'Load %s · %d cores').format(fmt.load(load), cores)) + (hot ? ' · ' + hot : ''),
|
||||
detail: (cpu >= 70 ? fmt.N_(cores, 'Busy; load %s on %d core; see the busiest processes', 'Busy; load %s on %d cores; see the busiest processes').format(fmt.load(load), cores)
|
||||
: fmt.N_(cores, 'Load %s on %d core', 'Load %s on %d cores').format(fmt.load(load), cores)) +
|
||||
(hot ? ' · ' + _('Temperature %s').format(hot) : ''),
|
||||
page: PAGES.processes });
|
||||
|
||||
@@ -96,33 +97,40 @@ return baseclass.extend({
|
||||
},
|
||||
|
||||
/* the Wi-Fi and Signal checks, appended to out; an SSID without
|
||||
clients is normal, not a fault */
|
||||
clients is idle, not a fault */
|
||||
wifiHealth: function(model, out) {
|
||||
var radios = model.radios || [], nSsid = (model.ssids || []).length;
|
||||
var off = radios.filter(function(r) { return r.disabled; }), down = radios.filter(function(r) { return !r.disabled && !r.up; });
|
||||
var idle = (model.ssids || []).filter(function(s) { return s.up && !s.clients; });
|
||||
if (!radios.length) out.push({ id: 'radios', level: 'info', title: _('Wi-Fi'), value: _('None'), reason: _('No radios reported'), detail: _('This device reports no radios'), page: PAGES.wireless });
|
||||
else if (down.length) out.push({ id: 'radios', level: 'err', title: _('Wi-Fi'), value: _('%d down').format(down.length), reason: _('%s is not up').format(down[0].bandLabel),
|
||||
else if (down.length) out.push({ id: 'radios', level: 'err', title: _('Wi-Fi'), value: fmt.N_(down.length, '%d radio down', '%d radios down').format(down.length), reason: _('%s is not up').format(down[0].bandLabel),
|
||||
detail: _('%s (%s) is enabled but not up').format(down[0].id, down[0].bandLabel), page: PAGES.wireless });
|
||||
else if (off.length) out.push({ id: 'radios', level: 'warn', title: _('Wi-Fi'), value: _('%d off').format(off.length), reason: _('%s is disabled').format(off[0].bandLabel),
|
||||
else if (off.length) out.push({ id: 'radios', level: 'warn', title: _('Wi-Fi'), value: fmt.N_(off.length, '%d radio off', '%d radios off').format(off.length), reason: _('%s is disabled').format(off[0].bandLabel),
|
||||
detail: _('%s (%s) is disabled').format(off[0].id, off[0].bandLabel), page: PAGES.wireless });
|
||||
else out.push({ id: 'radios', level: 'ok', title: _('Wi-Fi'), value: _('%d up').format(radios.length),
|
||||
reason: idle.length ? _('%d SSIDs · %d idle').format(nSsid, idle.length) : _('%d SSIDs on air').format(nSsid),
|
||||
detail: idle.length ? _('%d SSIDs broadcasting; %d without clients, which is fine').format(nSsid, idle.length) : _('%d SSIDs broadcasting').format(nSsid),
|
||||
else out.push({ id: 'radios', level: 'ok', title: _('Wi-Fi'), value: fmt.N_(radios.length, '%d radio up', '%d radios up').format(radios.length),
|
||||
reason: idle.length ? fmt.N_(nSsid, '%d SSID · %d idle', '%d SSIDs · %d idle').format(nSsid, idle.length) : fmt.N_(nSsid, '%d SSID on air', '%d SSIDs on air').format(nSsid),
|
||||
detail: idle.length ? fmt.N_(nSsid, '%d SSID broadcasting, %d idle', '%d SSIDs broadcasting, %d idle').format(nSsid, idle.length) : fmt.N_(nSsid, '%d SSID broadcasting', '%d SSIDs broadcasting').format(nSsid),
|
||||
page: PAGES.wireless });
|
||||
|
||||
/* signal */
|
||||
var clients = model.clients || [];
|
||||
var weak = clients.filter(function(c) { return c.signal != null && c.signal < WEAK_DBM; }).sort(function(a, b) { return a.signal - b.signal; });
|
||||
if (!clients.length) out.push({ id: 'signal', level: 'info', title: _('Signal'), value: _('No clients'), reason: _('Nobody associated'), detail: _('No stations are associated right now'), page: PAGES.wireless });
|
||||
var heard = clients.filter(function(c) { return c.signal != null; }).sort(function(a, b) { return a.signal - b.signal; });
|
||||
if (!clients.length) out.push({ id: 'signal', level: 'info', title: _('Signal'), value: _('No clients'), reason: '', detail: _('No stations are associated right now'), page: PAGES.wireless });
|
||||
else if (weak.length) out.push({ id: 'signal', level: 'warn', title: _('Signal'), value: _('%d weak').format(weak.length),
|
||||
reason: _('%s · %s').format(weak[0].name, fmt.dbm(weak[0].signal)),
|
||||
/* the level stays in one piece when the line wraps */
|
||||
reason: _('%s · %s').format(weak[0].name, fmt.dbm(weak[0].signal).replace(/ /g, '\u00a0')),
|
||||
detail: _('%s at %s; below %s roaming and throughput suffer').format(weak[0].name, fmt.dbm(weak[0].signal), fmt.dbm(WEAK_DBM)), page: PAGES.wireless,
|
||||
/* one weak client opens its details, several the list of them
|
||||
(the weakest's details where the layout hides that list) */
|
||||
client: weak[0].mac, list: weak.length > 1 ? 'weak' : null });
|
||||
else out.push({ id: 'signal', level: 'ok', title: _('Signal'), value: _('All good'), reason: _('All above %s').format(fmt.dbm(WEAK_DBM)),
|
||||
detail: _('All %d clients above %s').format(clients.length, fmt.dbm(WEAK_DBM)), page: PAGES.wireless });
|
||||
/* all fine: the weakest, which is how close the network is to a problem */
|
||||
else out.push({ id: 'signal', level: 'ok', title: _('Signal'), value: heard.length ? fmt.dbm(heard[0].signal) : fmt.DASH,
|
||||
reason: !heard.length ? _('Not reported by the driver') : heard.length === 1 ? _('The only measured client')
|
||||
: fmt.N_(heard.length, 'Weakest of %d client', 'Weakest of %d clients').format(heard.length),
|
||||
detail: !heard.length ? _('The driver reports no signal levels')
|
||||
: heard.length === 1 ? _('The one measured client is above %s').format(fmt.dbm(WEAK_DBM))
|
||||
: fmt.N_(heard.length, '%d measured client is above %s', '%d measured clients are above %s').format(heard.length, fmt.dbm(WEAK_DBM)), page: PAGES.wireless });
|
||||
},
|
||||
|
||||
/* -> { level, count (warn+err), headline } */
|
||||
@@ -248,8 +256,6 @@ return baseclass.extend({
|
||||
else if (!r.up) notes.push({ level: 'err', text: _('Radio is enabled but not up') });
|
||||
if (top === r.id && sum > 0 && (radios.length > 1)) notes.push({ level: 'info', text: _('Busiest radio: %s of Wi-Fi traffic').format(fmt.pct(v / sum * 100)) });
|
||||
if (r.legacy) notes.push({ level: 'info', text: r.legacy === 1 ? _('1 older device (Wi-Fi 4 or earlier) slows airtime') : _('%d older devices (Wi-Fi 4 or earlier) slow airtime').format(r.legacy) });
|
||||
if (r.noise == null && r.noiseRaw != null) notes.push({ level: 'muted', text: _('Noise floor not reported by the driver') });
|
||||
if (r.up && !r.clients) notes.push({ level: 'muted', text: _('No clients; idle radios are fine') });
|
||||
out[r.id] = { busiest: top === r.id && sum > 0, share: sum > 0 ? v / sum : 0, notes: notes };
|
||||
});
|
||||
return out;
|
||||
|
||||
@@ -25,7 +25,7 @@ var MIN = {
|
||||
};
|
||||
|
||||
/* tiles whose content grows to fill a taller slot */
|
||||
var FLEX = { chart: true };
|
||||
var FLEX = { chart: true, radios: true };
|
||||
|
||||
/* how far a tile stretches to line up with the tile below it */
|
||||
var SNAP = 48;
|
||||
|
||||
@@ -564,6 +564,7 @@ return baseclass.extend({
|
||||
mac: mac,
|
||||
macLabel: fmt.mac(mac),
|
||||
name: nm.name,
|
||||
plainName: nm.plain,
|
||||
nameSource: nm.source,
|
||||
nameSourceLabel: nm.sourceLabel,
|
||||
icon: nm.icon,
|
||||
@@ -625,6 +626,7 @@ return baseclass.extend({
|
||||
mac: mac,
|
||||
macLabel: fmt.mac(mac),
|
||||
name: nm.name,
|
||||
plainName: nm.plain,
|
||||
nameSource: nm.source,
|
||||
nameSourceLabel: nm.sourceLabel,
|
||||
icon: nm.icon,
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
wps the device name the station sends in its WPS element
|
||||
vendor manufacturer from the OUI of a globally unique MAC
|
||||
private "Private device" for a locally administered MAC
|
||||
mac "Device" as the last resort
|
||||
mac "Unknown device" as the last resort
|
||||
|
||||
Pure functions; names are untrusted and only ever rendered as text. */
|
||||
|
||||
@@ -238,7 +238,11 @@ return baseclass.extend({
|
||||
/* Resolve the display name of one station.
|
||||
s: { mac, alias: { name, icon }, ips: [..], rdns: { ip: name },
|
||||
mdns: { ip: name }, hint: { name }, wps, vendor }
|
||||
-> { name, source, sourceLabel, icon, secondary, isPrivate } */
|
||||
-> { name, plain, source, sourceLabel, icon, secondary, isPrivate }
|
||||
Without a name (vendor, private, mac) name is the one-line label,
|
||||
which carries the MAC's last two octets ("Private device 53:0F"),
|
||||
and plain the same without them, for where the MAC sits beside
|
||||
it; otherwise both are the name. */
|
||||
resolve: function(s) {
|
||||
s = s || {};
|
||||
var self = this, mac = this.normMac(s.mac) || str(s.mac);
|
||||
@@ -261,16 +265,18 @@ return baseclass.extend({
|
||||
if (!name && (name = fromIps(s.mdns))) source = 'mdns';
|
||||
if (!name && s.wps && (name = fmt.safeText(str(s.wps).trim(), NAME_MAX) || null)) source = 'wps';
|
||||
|
||||
var tail = fmt.macTail(mac);
|
||||
var plain = name, tail = fmt.macTail(mac);
|
||||
if (!name) {
|
||||
if (priv) { name = _('Private device') + ' · ' + tail; source = 'private'; }
|
||||
else if (s.vendor) { name = _('%s device').format(fmt.safeText(s.vendor, 32)) + ' · ' + tail; source = 'vendor'; }
|
||||
else { name = _('Device') + ' · ' + tail; source = 'mac'; }
|
||||
if (priv) { plain = _('Private device'); source = 'private'; }
|
||||
else if (s.vendor) { plain = _('%s device').format(fmt.safeText(s.vendor, 32)); source = 'vendor'; }
|
||||
else { plain = _('Unknown device', 'vantage'); source = 'mac'; }
|
||||
name = tail ? plain + ' ' + tail : plain;
|
||||
}
|
||||
|
||||
var icon = (s.alias && this.validIcon(s.alias.icon)) || this.guessIcon(source === 'vendor' ? s.vendor : name) || 'device';
|
||||
return {
|
||||
name: name,
|
||||
plain: plain,
|
||||
source: source,
|
||||
sourceLabel: SOURCES[source],
|
||||
icon: icon,
|
||||
|
||||
@@ -37,14 +37,6 @@ return baseclass.extend({
|
||||
return out.length > maxLen ? out.slice(out.length - maxLen) : out;
|
||||
},
|
||||
|
||||
/* a round axis maximum >= v: 1, 2, 2.5, 5 x 10^n */
|
||||
niceMax: function(v) {
|
||||
if (!finite(v) || v <= 0) return 1;
|
||||
var e = Math.pow(10, Math.floor(Math.log10(v))), f = v / e;
|
||||
var n = f <= 1 ? 1 : f <= 2 ? 2 : f <= 2.5 ? 2.5 : f <= 5 ? 5 : 10;
|
||||
return n * e;
|
||||
},
|
||||
|
||||
/* a round axis maximum >= v with finer steps (1, 1.5, 2, 2.5, 3, 4,
|
||||
5, 6, 8, 10 x 10^n), so a 374 Mbit/s peak gets a 400 axis, not 500 */
|
||||
niceCeil: function(v) {
|
||||
|
||||
@@ -45,7 +45,6 @@ var ICONS = {
|
||||
globe: [ 'M12 3a9 9 0 1 0 0 18a9 9 0 1 0 0-18Z', 'M3.4 9.2h17.2M3.4 14.8h17.2', 'M12 3c2.4 2.5 3.6 5.5 3.6 9s-1.2 6.5-3.6 9c-2.4-2.5-3.6-5.5-3.6-9s1.2-6.5 3.6-9Z' ],
|
||||
zones: [ 'M4 5.5h6.5v6.5H4zM13.5 5.5H20v6.5h-6.5zM8.75 15.5h6.5V22h-6.5z', 'M7.25 12v1.75h9.5V12M12 13.75v1.75' ],
|
||||
off: [ 'M12 3.5a8.5 8.5 0 1 0 0 17a8.5 8.5 0 1 0 0-17Z', 'M6 6l12 12' ],
|
||||
check: [ 'M5 12.5l4.5 4.5L19 7.5' ],
|
||||
warn: [ 'M10.3 4.6 3 17.5A2 2 0 0 0 4.7 20.5h14.6A2 2 0 0 0 21 17.5L13.7 4.6a2 2 0 0 0-3.4 0Z', 'M12 9.5v4.5', 'M12 17h.01' ],
|
||||
err: [ 'M12 3.5a8.5 8.5 0 1 0 0 17a8.5 8.5 0 1 0 0-17Z', 'M9 9l6 6M15 9l-6 6' ],
|
||||
chevron: [ 'M9.5 6l6 6-6 6' ],
|
||||
@@ -116,9 +115,16 @@ function named(item) {
|
||||
return item.kind === 'redirect' ? _('Unnamed port forward') : _('Unnamed rule', 'vantage');
|
||||
}
|
||||
|
||||
/* a zone's input policy: neutral, whatever it is, except an internet
|
||||
zone that accepts */
|
||||
function polBadge(p, risky) {
|
||||
var cls = risky ? 'is-risk' : p === 'ACCEPT' ? 'is-accept' : 'is-stop';
|
||||
return E('span', { 'class': 'vt-fg-pol ' + cls }, [ p === 'ACCEPT' ? _('accept', 'vantage') : p === 'DROP' ? _('drop', 'vantage') : _('reject', 'vantage') ]);
|
||||
return E('span', { 'class': 'vt-fg-pol' + (risky ? ' is-risk' : '') }, [ p === 'ACCEPT' ? _('accept', 'vantage') : p === 'DROP' ? _('drop', 'vantage') : _('reject', 'vantage') ]);
|
||||
}
|
||||
|
||||
/* the admin ports a warning names (fwglance ADMIN_PORTS), by service */
|
||||
function adminServices(ports) {
|
||||
var names = { 22: _('SSH (port 22)'), 23: _('Telnet (port 23)'), 80: _('HTTP (port 80)'), 443: _('HTTPS (port 443)') };
|
||||
return (ports || []).map(function(p) { return names[p] || String(p); }).join(', ');
|
||||
}
|
||||
|
||||
/* a setup fwglance does not follow (its complex) */
|
||||
@@ -139,6 +145,17 @@ function ignoredWhy(i) {
|
||||
return _('ignored: option %s has a value firewall4 refuses').format(i.bad);
|
||||
}
|
||||
|
||||
/* N_() with English's rule where no catalogue has the string (as
|
||||
vantage.fmt's, which this view doesn't load) */
|
||||
var tr = {
|
||||
N_: function(n, singular, plural, ctx) {
|
||||
var t = N_(n, singular, plural, ctx);
|
||||
if (n !== 1 && t === singular) return plural;
|
||||
if (n === 1 && t === plural) return singular;
|
||||
return t;
|
||||
}
|
||||
};
|
||||
|
||||
return view.extend({
|
||||
handleSave: null,
|
||||
handleSaveApply: null,
|
||||
@@ -219,7 +236,7 @@ return view.extend({
|
||||
}
|
||||
else {
|
||||
head = _('Nothing is open in your firewall rules');
|
||||
sub = fw.standard.length ? N_(fw.standard.length, 'Only standard housekeeping (ping, DHCP renewals and the like): %d rule', 'Only standard housekeeping (ping, DHCP renewals and the like): %d rules').format(fw.standard.length) : _('Internet-facing: %s').format(facing);
|
||||
sub = fw.standard.length ? tr.N_(fw.standard.length, 'Only standard housekeeping (ping, DHCP renewals and the like): %d rule', 'Only standard housekeeping (ping, DHCP renewals and the like): %d rules').format(fw.standard.length) : _('Internet-facing: %s').format(facing);
|
||||
}
|
||||
return this.head(fw.level, head, sub);
|
||||
},
|
||||
@@ -257,12 +274,12 @@ return view.extend({
|
||||
}
|
||||
else if (w.code === 'admin-unsure') {
|
||||
title = _('%s may open the router\'s admin').format(w.name || w.ports);
|
||||
reason = _('It forwards SSH or web ports from any address on the internet to %s. The interface list could not be read, so this page cannot tell whether that is the router itself.').format(w.host);
|
||||
reason = _('It forwards %s from any address on the internet to %s. The interface list could not be read, so this page cannot tell whether that is the router itself.').format(adminServices(w.admin), w.host);
|
||||
tab = 'forwards';
|
||||
}
|
||||
else {
|
||||
title = _('Router admin open: %s').format(w.name || w.ports);
|
||||
reason = _('SSH or the web interface answers any address on the internet. Limit the rule to the addresses you use.');
|
||||
reason = _('The firewall lets any address on the internet reach %s. Limit the rule to the addresses you use.').format(adminServices(w.admin));
|
||||
tab = w.kind === 'redirect' ? 'forwards' : 'rules';
|
||||
}
|
||||
return E('a', { 'class': 'vt-chip vt-chip-' + w.level, 'role': 'listitem', 'href': page(tab) }, [
|
||||
@@ -316,7 +333,7 @@ return view.extend({
|
||||
: _('Nothing is open in your firewall rules.') ]));
|
||||
if (fw.standard.length)
|
||||
body.push(E('details', { 'class': 'vt-fg-std' }, [
|
||||
E('summary', {}, [ N_(fw.standard.length, 'Standard housekeeping: %d rule', 'Standard housekeeping: %d rules').format(fw.standard.length) ]),
|
||||
E('summary', {}, [ tr.N_(fw.standard.length, 'Standard housekeeping: %d rule', 'Standard housekeeping: %d rules').format(fw.standard.length) ]),
|
||||
E('p', { 'class': 'vt-hint' }, [ _('Ping and other control messages, multicast, DHCP renewals and IPsec passed on to your network: what every router lets in.') ]),
|
||||
E('div', { 'class': 'vt-fg-rows' }, fw.standard.map(function(i) {
|
||||
return self.row(page('rules'), named(i), [ what(i) ]);
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -10,8 +10,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-theme-vantage
|
||||
PKG_VERSION:=1.0.14
|
||||
PKG_RELEASE:=30
|
||||
PKG_VERSION:=1.0.15
|
||||
PKG_RELEASE:=31
|
||||
PKG_LICENSE:=GPL-3.0-or-later
|
||||
|
||||
LUCI_TITLE:=Vantage theme
|
||||
|
||||
@@ -26,6 +26,10 @@ const callWirelessDevices = rpc.declare({ object: 'luci-rpc', method: 'getWirele
|
||||
const THEME_KEY = 'vantage.theme';
|
||||
const RAIL_KEY = 'vantage.rail';
|
||||
const LOGIN_KEY = 'vantage.login'; /* read by the login page's login.js */
|
||||
/* the dashboard's network path backdrop (luci-app-vantage view/vantage/overview.js),
|
||||
picked here when the dashboard is installed; the dashboard listens for BACKDROP_EVENT */
|
||||
const BACKDROP_KEY = 'vantage.backdrop.v1';
|
||||
const BACKDROP_EVENT = 'vantage:backdrop';
|
||||
|
||||
/* 24px stroke icons, drawn for this theme: constant [tag, attributes] lists,
|
||||
built with createElementNS (no markup parsing, no user data) */
|
||||
@@ -41,13 +45,12 @@ const ICONS = {
|
||||
generic: [ [ 'circle', { cx: '12', cy: '12', r: '8' } ], [ 'circle', { cx: '12', cy: '12', r: '2.2' } ] ],
|
||||
page: [ [ 'path', { d: 'M7 3.5h6.5l4.5 4.5v12.5H7z' } ], [ 'path', { d: 'M13.5 3.5V8H18' } ] ],
|
||||
caret: [ [ 'path', { d: 'm9 6 6 6-6 6' } ] ],
|
||||
enter: [ [ 'path', { d: 'M19 5v6a3 3 0 0 1-3 3H6M10 10l-4 4 4 4' } ] ],
|
||||
down: [ [ 'path', { d: 'm6 9 6 6 6-6' } ] ],
|
||||
search: [ [ 'circle', { cx: '11', cy: '11', r: '6.5' } ], [ 'path', { d: 'm16 16 4.5 4.5' } ] ],
|
||||
sun: [ [ 'circle', { cx: '12', cy: '12', r: '4' } ], [ 'path', { d: 'M12 2.5v2M12 19.5v2M4.6 4.6 6 6M18 18l1.4 1.4M2.5 12h2M19.5 12h2M4.6 19.4 6 18M18 6l1.4-1.4' } ] ],
|
||||
moon: [ [ 'path', { d: 'M19.5 14.5A7.5 7.5 0 0 1 9.5 4.5a7.5 7.5 0 1 0 10 10z' } ] ],
|
||||
auto: [ [ 'circle', { cx: '12', cy: '12', r: '8' } ], [ 'path', { d: 'M12 4a8 8 0 0 1 0 16z', 'class': 'vt-fill' } ] ],
|
||||
logout: [ [ 'path', { d: 'M14 4h4.5A1.5 1.5 0 0 1 20 5.5v13a1.5 1.5 0 0 1-1.5 1.5H14' } ], [ 'path', { d: 'M10 8l-4 4 4 4M6 12h10' } ] ],
|
||||
pin: [ [ 'path', { d: 'M4 5v14M9 12h11M15 7l5 5-5 5' } ] ],
|
||||
info: [ [ 'circle', { cx: '12', cy: '12', r: '8.5' } ], [ 'path', { d: 'M12 11v5.5' } ], [ 'circle', { cx: '12', cy: '7.75', r: '.6' } ] ],
|
||||
more: [ [ 'circle', { cx: '5.5', cy: '12', r: '.9' } ], [ 'circle', { cx: '12', cy: '12', r: '.9' } ], [ 'circle', { cx: '18.5', cy: '12', r: '.9' } ] ]
|
||||
};
|
||||
@@ -174,6 +177,54 @@ function highlight(text, idx) {
|
||||
return out;
|
||||
}
|
||||
|
||||
/* A path ("Network › Firewall") matches only on what it says: the query
|
||||
as a substring, or each of its words starting a word of the path. Not
|
||||
as letters scattered across it ("wire" in "Network › Firewall").
|
||||
null = no match. */
|
||||
function pathScore(query, path) {
|
||||
const q = query.toLowerCase().trim().replace(/\s+/g, ' ');
|
||||
const t = String(path || '').toLowerCase();
|
||||
if (!q || !t) return null;
|
||||
const at = t.indexOf(q);
|
||||
if (at >= 0) return (at === 0 || /[\s\/›\-_(.]/.test(t[at - 1])) ? 10 : 6;
|
||||
const words = t.split(/[\s\/›\-_(.]+/).filter(Boolean);
|
||||
return q.split(' ').every(w => words.some(x => x.startsWith(w))) ? 4 : null;
|
||||
}
|
||||
|
||||
/* Palette results for a query, best first: entries whose title matches,
|
||||
or only when no title does, those whose path does. Equal scores go to
|
||||
the shallower entry (Network › Wireless before a Wireless tab). */
|
||||
function rankPalette(query, pool) {
|
||||
const onTitle = [], onPath = [];
|
||||
for (const e of pool) {
|
||||
const t = fuzzy(query, e.title);
|
||||
if (t) { onTitle.push({ e, score: t.score, idx: t.idx }); continue; }
|
||||
const p = pathScore(query, e.path);
|
||||
if (p != null) onPath.push({ e, score: p, idx: [] });
|
||||
}
|
||||
const depth = r => (r.e.segs || []).length;
|
||||
return (onTitle.length ? onTitle : onPath).sort((a, b) => (b.score - a.score) || (depth(a) - depth(b)));
|
||||
}
|
||||
|
||||
/* The palette without a query: rows under their category's header, which
|
||||
a category of one row goes without. Under a header a row's path leaves
|
||||
the category out (a tab shows its page only); a row without one keeps
|
||||
its whole path. results: [ { e } ] in index order -> [ { r, head, path } ] */
|
||||
function paletteLayout(results) {
|
||||
const size = new Map();
|
||||
for (const r of results) size.set(r.e.group, (size.get(r.e.group) || 0) + 1);
|
||||
let prev = null;
|
||||
return results.map(r => {
|
||||
const g = r.e.group, headed = size.get(g) > 1;
|
||||
const head = (headed && g !== prev) ? g : null;
|
||||
prev = g;
|
||||
let path = r.e.path || '';
|
||||
if (headed && path === g) path = '';
|
||||
else if (headed && path.startsWith(g + ' › ')) path = path.slice(g.length + 3);
|
||||
return { r, head, path };
|
||||
});
|
||||
}
|
||||
|
||||
/* cells holding only addresses, counters, rates or durations get the mono stack */
|
||||
const UNITS = /(?<![A-Za-z])(?:[kKMGTP]?i?B(?:\/s)?|[kMG]?bit\/s|[kMG]?bps|dBm|dB|[kMG]?Hz|ms|us|MCS|NSS|EHT|HE|VHT|HT|pkts?|packets|bytes|min|d|h|m|s)(?![A-Za-z])/g;
|
||||
function technical(text) {
|
||||
@@ -196,6 +247,26 @@ function repeatsTrail(key, tag, trail) {
|
||||
return (tag === 'H2' ? trail.all : trail.page).has(key);
|
||||
}
|
||||
|
||||
/* The crumbs as shown: one that only repeats the crumb before it
|
||||
("System › System", a page and its tab of the same name) takes that
|
||||
crumb's place, with its own (deeper) link and level. */
|
||||
function mergeCrumbs(parts) {
|
||||
const out = [];
|
||||
for (const p of parts) {
|
||||
if (out.length && headingKey(out[out.length - 1].title) === headingKey(p.title)) out[out.length - 1] = p;
|
||||
else out.push(p);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/* LuCI renders its 404 with the deepest node it resolved (L.env.nodespec):
|
||||
a category (firstchild) or a node without an action */
|
||||
function notFound(spec) {
|
||||
if (!spec || typeof spec !== 'object') return false;
|
||||
const type = spec.action && typeof spec.action === 'object' ? spec.action.type : null;
|
||||
return !type || type === 'firstchild';
|
||||
}
|
||||
|
||||
/* Does help text carry a warning? LuCI writes them as a paragraph that
|
||||
opens with a short label and a colon ("Note:", "Warning:", "注意:",
|
||||
"Uwaga:"), whatever the language, and sometimes in bold. Line breaks
|
||||
@@ -380,7 +451,7 @@ function enhanceMemory() {
|
||||
});
|
||||
}
|
||||
|
||||
/* Storage: one thin bar per mount, "used · free of total" beside it */
|
||||
/* Storage: one thin bar per mount, "used · free · total" beside it */
|
||||
function enhanceStorage() {
|
||||
statusSections(_('Storage')).forEach(section => {
|
||||
const table = pendingTable(section);
|
||||
@@ -397,10 +468,11 @@ function enhanceStorage() {
|
||||
return E('div', { 'class': 'v-meter-row' }, [
|
||||
label,
|
||||
E('div', { 'class': 'v-meter-bar is-thin', 'role': 'img',
|
||||
'aria-label': '%s: %s %s, %s %s'.format(r.label, fmtBytes(used), _('used'), fmtBytes(size - used), _('free')) },
|
||||
'aria-label': '%s: %s %s, %s %s, %s %s'.format(r.label, fmtBytes(used), _('used'), fmtBytes(size - used), _('free'), fmtBytes(size), _('total')) },
|
||||
segment('v-seg-used' + (p >= 95 ? ' is-crit' : p >= 80 ? ' is-warn' : ''), used, size)),
|
||||
E('span', { 'class': 'v-meter-val' }, [
|
||||
E('b', {}, [ fmtBytes(used) ]), ' ' + _('used') + ' · ' + fmtBytes(size - used) + ' ' + _('free') + ' · ' + fmtBytes(size)
|
||||
/* a figure and its word stay on one line */
|
||||
E('b', {}, [ fmtBytes(used) ]), '\u00a0' + _('used') + ' · ' + fmtBytes(size - used) + '\u00a0' + _('free') + ' · ' + fmtBytes(size) + '\u00a0' + _('total')
|
||||
])
|
||||
]);
|
||||
})));
|
||||
@@ -700,7 +772,14 @@ return baseclass.extend({
|
||||
if (!admin) return;
|
||||
|
||||
this.admin = admin;
|
||||
/* Appearance opened before the menu came in lacks the network
|
||||
path's group (hasDashboard): add it now */
|
||||
if (this.appear && this.hasDashboard() && !this.appear.querySelector('input[name="vt-backdrop"]')) {
|
||||
this.appear.appendChild(this.backdropGroup());
|
||||
this.syncAppearance();
|
||||
}
|
||||
this.dp = (L.env.dispatchpath || []).slice();
|
||||
this.missing = notFound(L.env.nodespec);
|
||||
|
||||
this.cats = ui.menu.getChildren(admin)
|
||||
.filter(c => c.name !== 'logout')
|
||||
@@ -958,18 +1037,14 @@ return baseclass.extend({
|
||||
this.endSwitch();
|
||||
if (fly.getAttribute('data-cat') !== cat.name || fly.hidden) {
|
||||
fly.textContent = '';
|
||||
const total = cat.pages.length;
|
||||
fly.appendChild(E('div', { 'class': 'vt-fly-head' }, [
|
||||
svg(cat.icon, 18),
|
||||
E('span', { 'class': 'vt-fly-title', 'id': 'vt-fly-title' }, [ cat.title ]),
|
||||
E('span', { 'class': 'vt-fly-count' }, [ '%d %s'.format(total, total === 1 ? _('page') : _('pages')) ])
|
||||
E('span', { 'class': 'vt-fly-title', 'id': 'vt-fly-title' }, [ cat.title ])
|
||||
]));
|
||||
const ul = E('ul', { 'class': 'vt-fly-list', 'role': 'list' });
|
||||
for (const p of cat.pages) {
|
||||
const cur = this.dp[1] === cat.name && this.dp[2] === p.name;
|
||||
const item = E('li', {}, E('a', { 'class': 'vt-fly-link', 'href': L.url('admin', cat.name, p.name), 'aria-current': cur ? 'page' : null }, [
|
||||
E('span', {}, [ p.title ]),
|
||||
p.subs.length ? E('span', { 'class': 'vt-fly-meta' }, [ String(p.subs.length) ]) : ''
|
||||
E('span', {}, [ p.title ])
|
||||
]));
|
||||
if (p.subs.length > 1) {
|
||||
const sub = E('ul', { 'class': 'vt-fly-sub' });
|
||||
@@ -982,7 +1057,6 @@ return baseclass.extend({
|
||||
ul.appendChild(item);
|
||||
}
|
||||
fly.appendChild(ul);
|
||||
fly.appendChild(E('div', { 'class': 'vt-fly-foot' }, [ _('Press', 'vantage-theme'), ' ', E('kbd', {}, [ 'Ctrl K' ]), ' ', _('to search all pages') ]));
|
||||
fly.setAttribute('data-cat', cat.name);
|
||||
fly.setAttribute('role', 'region');
|
||||
fly.setAttribute('aria-labelledby', 'vt-fly-title');
|
||||
@@ -1032,11 +1106,8 @@ return baseclass.extend({
|
||||
this.openTimer = null;
|
||||
this.closeFlyout(false);
|
||||
fly.textContent = '';
|
||||
const total = page.subs.length;
|
||||
fly.appendChild(E('div', { 'class': 'vt-fly-head' }, [
|
||||
svg(cat.icon, 18),
|
||||
E('span', { 'class': 'vt-fly-title', 'id': 'vt-fly-title' }, [ page.title ]),
|
||||
E('span', { 'class': 'vt-fly-count' }, [ '%d %s'.format(total, total === 1 ? _('page') : _('pages')) ])
|
||||
E('span', { 'class': 'vt-fly-title', 'id': 'vt-fly-title' }, [ page.title ])
|
||||
]));
|
||||
const ul = E('ul', { 'class': 'vt-fly-list', 'role': 'list' });
|
||||
for (const s of page.subs)
|
||||
@@ -1088,28 +1159,31 @@ return baseclass.extend({
|
||||
for (let i = 1; i < this.dp.length && i <= 3; i++) {
|
||||
node = node && node.children ? node.children[this.dp[i]] : null;
|
||||
if (!node || !node.title) break;
|
||||
parts.push({ title: _(node.title), segs: [ 'admin' ].concat(this.dp.slice(1, i + 1)) });
|
||||
parts.push({ title: _(node.title), segs: [ 'admin' ].concat(this.dp.slice(1, i + 1)), level: i });
|
||||
}
|
||||
/* a 404: the crumbs lead to the category LuCI resolved, then say so */
|
||||
if (this.missing) parts.push({ title: _('Not found'), segs: null, level: 0 });
|
||||
if (!parts.length) return;
|
||||
|
||||
/* a page with page tabs: its current crumb switches between them,
|
||||
from the top bar, which stays in view while the tabs scroll away */
|
||||
const cat = this.cats.find(c => c.name === this.dp[1]);
|
||||
const page = cat && this.dp.length > 3 ? cat.pages.find(p => p.name === this.dp[2]) : null;
|
||||
const page = cat && !this.missing && this.dp.length > 3 ? cat.pages.find(p => p.name === this.dp[2]) : null;
|
||||
const siblings = page && page.subs.length > 1 ? page : null;
|
||||
|
||||
const crumbs = mergeCrumbs(parts);
|
||||
nav.textContent = '';
|
||||
parts.forEach((p, i) => {
|
||||
const last = i === parts.length - 1;
|
||||
crumbs.forEach((p, i) => {
|
||||
const last = i === crumbs.length - 1;
|
||||
if (i) nav.appendChild(E('span', { 'class': 'vt-crumb-sep', 'aria-hidden': 'true' }, [ '›' ]));
|
||||
if (last && siblings && parts.length === 3) {
|
||||
if (last && siblings && p.level === 3) {
|
||||
/* a disclosure (aria-expanded + aria-controls): the panel is a
|
||||
region of links, not a menu, so no aria-haspopup */
|
||||
const btn = E('button', {
|
||||
'type': 'button', 'class': 'vt-crumb vt-crumb-current vt-crumb-switch', 'aria-current': 'page',
|
||||
'aria-expanded': 'false', 'aria-controls': 'vt-flyout',
|
||||
'title': _('Other pages in %s').format(siblings.title)
|
||||
}, [ E('span', {}, [ p.title ]), svg('caret', 14) ]);
|
||||
}, [ E('span', {}, [ p.title ]), svg('down', 14) ]);
|
||||
btn.addEventListener('click', ev => {
|
||||
if (this.switchOpen()) this.closeFlyout(true);
|
||||
else this.openSwitch(cat, siblings, btn, ev.detail === 0);
|
||||
@@ -1134,7 +1208,7 @@ return baseclass.extend({
|
||||
|
||||
renderTabs() {
|
||||
const bar = document.getElementById('vt-tabs');
|
||||
if (!bar || this.dp.length < 3) return;
|
||||
if (!bar || this.missing || this.dp.length < 3) return;
|
||||
const cat = this.admin.children[this.dp[1]];
|
||||
const page = cat && cat.children ? cat.children[this.dp[2]] : null;
|
||||
if (!page) return;
|
||||
@@ -1161,16 +1235,19 @@ return baseclass.extend({
|
||||
const key = e.segs.join('/') + '|' + e.title;
|
||||
if (seen.has(key)) return;
|
||||
seen.add(key);
|
||||
e.hay = (e.path ? e.path + ' › ' : '') + e.title;
|
||||
this.entries.push(e);
|
||||
};
|
||||
/* pages carry no icon: their category heads them, and only actions
|
||||
have one. A tab named like its page (System Log's "System Log")
|
||||
is that page's entry already. */
|
||||
for (const c of this.cats) {
|
||||
if (c.leaf) add({ title: c.title, path: '', group: c.title, segs: [ 'admin', c.name ], icon: c.icon });
|
||||
if (c.leaf) add({ title: c.title, path: '', group: c.title, segs: [ 'admin', c.name ] });
|
||||
for (const p of c.pages) {
|
||||
add({ title: p.title, path: c.title, group: c.title, segs: [ 'admin', c.name, p.name ], icon: c.icon });
|
||||
add({ title: p.title, path: c.title, group: c.title, segs: [ 'admin', c.name, p.name ] });
|
||||
if (p.subs.length > 1)
|
||||
for (const s of p.subs)
|
||||
add({ title: s.title, path: c.title + ' › ' + p.title, group: c.title, segs: [ 'admin', c.name, p.name, s.name ], icon: 'page' });
|
||||
if (headingKey(s.title) !== headingKey(p.title))
|
||||
add({ title: s.title, path: c.title + ' › ' + p.title, group: c.title, segs: [ 'admin', c.name, p.name, s.name ] });
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1184,8 +1261,13 @@ return baseclass.extend({
|
||||
const login = this.loginPref(), names = this.loginNames();
|
||||
for (const k of [ 'grid', 'stars', 'none' ])
|
||||
if (k !== login) list.push({ title: '%s: %s'.format(_('Login background'), names[k]), path: _('Appearance', 'vantage-theme'), icon: 'page', run: () => this.setLoginPref(k) });
|
||||
if (this.hasDashboard()) {
|
||||
const bd = this.backdropPref();
|
||||
for (const k of [ 'grid', 'stars', 'none' ])
|
||||
if (k !== bd) list.push({ title: '%s: %s'.format(_('Network path background'), names[k]), path: _('Appearance', 'vantage-theme'), icon: 'page', run: () => this.setBackdropPref(k) });
|
||||
}
|
||||
list.push({ title: _('Log out'), path: _('Session'), icon: 'logout', segs: [ 'admin', 'logout' ] });
|
||||
list.forEach(a => { a.hay = a.path + ' › ' + a.title; a.group = _('Actions'); });
|
||||
list.forEach(a => { a.group = _('Actions'); });
|
||||
return list;
|
||||
},
|
||||
|
||||
@@ -1210,7 +1292,7 @@ return baseclass.extend({
|
||||
const list = E('ul', { 'class': 'vt-pal-list', 'id': 'vt-pal-list', 'role': 'listbox', 'aria-label': _('Results', 'vantage-theme') });
|
||||
const count = E('span', { 'class': 'vt-pal-count' });
|
||||
const box = E('div', { 'class': 'vt-pal', 'role': 'dialog', 'aria-modal': 'true', 'aria-label': _('Command palette') }, [
|
||||
E('div', { 'class': 'vt-pal-field' }, [ svg('search', 18), input, E('kbd', {}, [ 'Esc' ]) ]),
|
||||
E('div', { 'class': 'vt-pal-field' }, [ svg('search', 18), input ]),
|
||||
list,
|
||||
E('div', { 'class': 'vt-pal-foot' }, [
|
||||
E('span', {}, [ E('kbd', {}, [ '↑' ]), E('kbd', {}, [ '↓' ]), _('navigate') ]),
|
||||
@@ -1242,35 +1324,18 @@ return baseclass.extend({
|
||||
const pal = this.pal;
|
||||
const q = pal.input.value.trim();
|
||||
const pool = this.entries.concat(this.actions());
|
||||
let results;
|
||||
|
||||
if (!q) {
|
||||
results = pool.map(e => ({ e, idx: [] }));
|
||||
}
|
||||
else {
|
||||
results = [];
|
||||
for (const e of pool) {
|
||||
const onTitle = fuzzy(q, e.title);
|
||||
const onPath = onTitle ? null : fuzzy(q, e.hay);
|
||||
if (onTitle) results.push({ e, score: onTitle.score + 6, idx: onTitle.idx });
|
||||
else if (onPath) results.push({ e, score: onPath.score * .6, idx: [] });
|
||||
}
|
||||
results.sort((a, b) => b.score - a.score);
|
||||
results = results.slice(0, 40);
|
||||
}
|
||||
const found = q ? rankPalette(q, pool) : null;
|
||||
const results = q ? found.slice(0, 40) : pool.map(e => ({ e, idx: [] }));
|
||||
const rows = q ? results.map(r => ({ r, head: null, path: r.e.path })) : paletteLayout(results);
|
||||
|
||||
pal.list.textContent = '';
|
||||
pal.items = [];
|
||||
let group = null;
|
||||
results.forEach((r, n) => {
|
||||
if (!q && r.e.group !== group) {
|
||||
group = r.e.group;
|
||||
pal.list.appendChild(E('li', { 'class': 'vt-pal-group', 'role': 'presentation' }, [ group ]));
|
||||
}
|
||||
rows.forEach(({ r, head, path }, n) => {
|
||||
if (head) pal.list.appendChild(E('li', { 'class': 'vt-pal-group', 'role': 'presentation' }, [ head ]));
|
||||
const li = E('li', { 'class': 'vt-pal-item', 'role': 'option', 'id': 'vt-pal-opt-' + n, 'aria-selected': 'false' }, [
|
||||
svg(r.e.icon, 18),
|
||||
r.e.icon ? svg(r.e.icon, 18) : '',
|
||||
highlight(r.e.title, r.idx),
|
||||
r.e.path ? E('span', { 'class': 'vt-pal-path' }, [ r.e.path ]) : '',
|
||||
path ? E('span', { 'class': 'vt-pal-path' }, [ path ]) : '',
|
||||
E('kbd', { 'class': 'vt-pal-enter' }, [ '↵' ])
|
||||
]);
|
||||
li.addEventListener('mousemove', () => this.setPaletteActive(n, false));
|
||||
@@ -1282,7 +1347,7 @@ return baseclass.extend({
|
||||
if (!results.length)
|
||||
pal.list.appendChild(E('li', { 'class': 'vt-pal-empty', 'role': 'presentation' }, [ _('No matching pages') ]));
|
||||
|
||||
pal.count.textContent = q ? '%d / %d'.format(results.length, pool.length) : '%d %s'.format(pool.length, _('items', 'vantage-theme'));
|
||||
pal.count.textContent = q ? N_(found.length, '%d result', '%d results', 'vantage-theme').format(found.length) : '';
|
||||
this.setPaletteActive(0, true);
|
||||
},
|
||||
|
||||
@@ -1398,6 +1463,23 @@ return baseclass.extend({
|
||||
this.syncAppearance();
|
||||
},
|
||||
|
||||
/* Vantage's dashboard, where this user may open it: its network path
|
||||
takes the same backdrops as the login page */
|
||||
hasDashboard() {
|
||||
return !!(this.admin && ui.menu.getChildren(this.admin).some(c => c.name === 'dashboard' && c.action && c.action.path === 'vantage/overview'));
|
||||
},
|
||||
|
||||
backdropPref() {
|
||||
const p = storageGet(BACKDROP_KEY);
|
||||
return (p === 'stars' || p === 'none') ? p : 'grid';
|
||||
},
|
||||
|
||||
setBackdropPref(pref) {
|
||||
storageSet(BACKDROP_KEY, pref === 'grid' ? null : pref);
|
||||
window.dispatchEvent(new CustomEvent(BACKDROP_EVENT));
|
||||
this.syncAppearance();
|
||||
},
|
||||
|
||||
setupTheme() {
|
||||
const btn = document.getElementById('vt-theme');
|
||||
if (btn) {
|
||||
@@ -1415,19 +1497,20 @@ return baseclass.extend({
|
||||
if (mq && mq.addEventListener) mq.addEventListener('change', () => { if (this.themePref() === 'auto') this.applyTheme(); });
|
||||
window.addEventListener('storage', ev => {
|
||||
if (ev.key === THEME_KEY) this.applyTheme();
|
||||
else if (ev.key === LOGIN_KEY) this.syncAppearance();
|
||||
else if (ev.key === LOGIN_KEY || ev.key === BACKDROP_KEY) this.syncAppearance();
|
||||
});
|
||||
this.applyTheme();
|
||||
},
|
||||
|
||||
/* Appearance, under the colour-theme button: the colour theme and the
|
||||
login background, each a native radio group (the arrow keys move
|
||||
/* Appearance, under the colour-theme button: the colour theme, the
|
||||
login background and, with the dashboard, the network path's
|
||||
background, each a native radio group (the arrow keys move
|
||||
within it) drawn as segments. Choices apply at once and stay open;
|
||||
Escape, Tab out of either end, a click outside, resizing or
|
||||
scrolling the page close it. */
|
||||
appearanceEl() {
|
||||
if (this.appear) return this.appear;
|
||||
const group = (name, legend, opts, set) => E('fieldset', { 'class': 'vt-appear-set' }, [
|
||||
/* one of Appearance's radio groups */
|
||||
appearGroup(name, legend, opts, set) {
|
||||
return E('fieldset', { 'class': 'vt-appear-set' }, [
|
||||
E('legend', {}, [ legend ]),
|
||||
E('div', { 'class': 'vt-appear-track' }, opts.map(o => {
|
||||
const input = E('input', { 'type': 'radio', 'name': name, 'value': o[0] });
|
||||
@@ -1435,13 +1518,24 @@ return baseclass.extend({
|
||||
return E('label', { 'class': 'vt-appear-opt' }, [ input ].concat(o[2] ? [ svg(o[2], 16) ] : [], [ E('span', {}, [ o[1] ]) ]));
|
||||
}))
|
||||
]);
|
||||
},
|
||||
|
||||
/* the network path's group, once the menu says the dashboard is here */
|
||||
backdropGroup() {
|
||||
const n = this.loginNames();
|
||||
return this.appearGroup('vt-backdrop', _('Network path background'), [ [ 'grid', n.grid ], [ 'stars', n.stars ], [ 'none', n.none ] ], v => this.setBackdropPref(v));
|
||||
},
|
||||
|
||||
appearanceEl() {
|
||||
if (this.appear) return this.appear;
|
||||
const group = (name, legend, opts, set) => this.appearGroup(name, legend, opts, set);
|
||||
const login = this.loginNames();
|
||||
const box = E('div', { 'id': 'vt-appearance', 'class': 'vt-appearance', 'role': 'dialog', 'aria-label': _('Appearance', 'vantage-theme'), 'hidden': 'hidden' }, [
|
||||
group('vt-colour', _('Colour theme'), [
|
||||
[ 'auto', _('Auto', 'vantage-theme'), 'auto' ], [ 'light', _('Light', 'vantage-theme'), 'sun' ], [ 'dark', _('Dark', 'vantage-theme'), 'moon' ]
|
||||
], v => this.setTheme(v)),
|
||||
group('vt-login', _('Login background'), [ [ 'grid', login.grid ], [ 'stars', login.stars ], [ 'none', login.none ] ], v => this.setLoginPref(v))
|
||||
]);
|
||||
].concat(this.hasDashboard() ? [ this.backdropGroup() ] : []));
|
||||
box.addEventListener('keydown', ev => {
|
||||
if (ev.key === 'Escape') { ev.preventDefault(); ev.stopPropagation(); this.closeAppearance(true); }
|
||||
else if (ev.key === 'Tab') {
|
||||
@@ -1465,7 +1559,7 @@ return baseclass.extend({
|
||||
|
||||
syncAppearance() {
|
||||
if (!this.appear) return;
|
||||
const now = { 'vt-colour': this.themePref(), 'vt-login': this.loginPref() };
|
||||
const now = { 'vt-colour': this.themePref(), 'vt-login': this.loginPref(), 'vt-backdrop': this.backdropPref() };
|
||||
Array.prototype.forEach.call(this.appear.querySelectorAll('input[type="radio"]'), r => { r.checked = (now[r.name] === r.value); });
|
||||
},
|
||||
|
||||
@@ -1513,11 +1607,10 @@ return baseclass.extend({
|
||||
chip.textContent = '';
|
||||
/* device strings go in as text nodes (E() would parse a string as HTML) */
|
||||
const text = v => [ document.createTextNode(String(v)) ];
|
||||
chip.appendChild(E('b', {}, text(board.hostname)));
|
||||
if (product) {
|
||||
chip.appendChild(E('span', { 'class': 'vt-host-sep', 'aria-hidden': 'true' }, text('·')));
|
||||
chip.appendChild(E('span', {}, text(product)));
|
||||
}
|
||||
host.chipNames(board.hostname, product).forEach((name, i) => {
|
||||
if (i) chip.appendChild(E('span', { 'class': 'vt-host-sep', 'aria-hidden': 'true' }, text('·')));
|
||||
chip.appendChild(i ? E('span', {}, text(name)) : E('b', {}, text(name)));
|
||||
});
|
||||
const rel = board.release && board.release.description;
|
||||
chip.setAttribute('title', [ board.hostname, product, rel ].filter(Boolean).join('\n'));
|
||||
chip.hidden = false;
|
||||
@@ -1909,12 +2002,8 @@ return baseclass.extend({
|
||||
|
||||
/* (i) shows, and the text folds to a line, while the text needs more
|
||||
than one line. Text that is not displayed (another tab, an unmet
|
||||
dependency) measures 0 and waits for the next resize notification. */
|
||||
fitHelp(desc) {
|
||||
this.fitHelps([ desc ]);
|
||||
},
|
||||
|
||||
/* all sizes are read before any button changes: a write between two
|
||||
dependency) measures 0 and waits for the next resize notification.
|
||||
All sizes are read before any button changes: a write between two
|
||||
reads forced a layout per field (66 when the Wireless modal opened).
|
||||
Folded, the text still measures its full height. The line's end is
|
||||
set as data-v-end ("cut" at --vt-cut, or "fade"), which the CSS reads. */
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
* name ("Qualcomm Technologies, Inc. IPQ5332/RDP442/AP-MI01.3") rather than
|
||||
* the product. In that case (or when the model is missing) the product name
|
||||
* is derived from board_name ("zyxel,nwa50be" -> "Zyxel NWA50BE"): vendor
|
||||
* capitalised (or its usual spelling), model upper-cased. Pure functions,
|
||||
* no DOM, unit tested in tests/host.test.js.
|
||||
* capitalised (or its usual spelling), model upper-cased. The chip leaves
|
||||
* out a name the other one contains. Pure functions, no DOM, unit tested
|
||||
* in tests/host.test.js.
|
||||
*/
|
||||
|
||||
/* SoC vendors, reference boards and placeholders: not a product name.
|
||||
@@ -52,6 +53,22 @@ function fromBoardName(boardName) {
|
||||
return vendorName(vendor) + ' ' + model.replace(/,/g, ' ').toUpperCase();
|
||||
}
|
||||
|
||||
/* names compared for repeats: case, spaces and punctuation don't count
|
||||
("cudy-wr-3000" and "Cudy WR3000" are one name) */
|
||||
function nameKey(s) {
|
||||
return clean(s).toLowerCase().replace(/[^\p{L}\p{N}]+/gu, '');
|
||||
}
|
||||
|
||||
/* the host chip's names, hostname first: a name the other one contains
|
||||
only repeats it and is left out (the product, when they are the same) */
|
||||
function chipNames(hostname, product) {
|
||||
const h = clean(hostname), p = clean(product);
|
||||
const hk = nameKey(h), pk = nameKey(p);
|
||||
if (!p || (h && pk && hk.indexOf(pk) >= 0)) return h ? [ h ] : [];
|
||||
if (!h || (hk && pk.indexOf(hk) >= 0)) return [ p ];
|
||||
return [ h, p ];
|
||||
}
|
||||
|
||||
/* product name for a `system board` reply, '' when nothing usable */
|
||||
function productName(board) {
|
||||
if (!board || typeof board !== 'object') return '';
|
||||
@@ -62,6 +79,7 @@ function productName(board) {
|
||||
|
||||
return baseclass.extend({
|
||||
productName,
|
||||
chipNames,
|
||||
fromBoardName,
|
||||
looksLikeReference
|
||||
});
|
||||
@@ -24,7 +24,10 @@
|
||||
--fs-xl: 20px;
|
||||
--fs-2xl: 24px;
|
||||
|
||||
/* spacing: steps of 4px, with 2px and 6px for tight insides */
|
||||
--sp-0-5: 2px;
|
||||
--sp-1: 4px;
|
||||
--sp-1-5: 6px;
|
||||
--sp-2: 8px;
|
||||
--sp-3: 12px;
|
||||
--sp-4: 16px;
|
||||
@@ -32,9 +35,19 @@
|
||||
--sp-6: 24px;
|
||||
--sp-8: 32px;
|
||||
|
||||
/* font weights: four steps only (static fonts draw 620-680 as bold) */
|
||||
--fw-regular: 400;
|
||||
--fw-medium: 500;
|
||||
--fw-semibold: 600;
|
||||
--fw-bold: 700;
|
||||
|
||||
/* radii: bars, small controls, controls, cards, large icon tiles
|
||||
(pills are 999px, dots 50%) */
|
||||
--r-xs: 2px;
|
||||
--r-sm: 4px;
|
||||
--r: 6px;
|
||||
--r-lg: 8px;
|
||||
--r-xl: 12px;
|
||||
|
||||
--rail-w: 56px;
|
||||
--rail-w-pinned: 204px;
|
||||
@@ -70,6 +83,7 @@
|
||||
--err: #c42b2b;
|
||||
--err-soft: rgba(196, 43, 43, .1);
|
||||
--err-ink: #ffffff; /* text on an --err / --info fill, >= 4.5:1 */
|
||||
--warn-ink: #ffffff; /* text on a --warn fill (counts, warning tooltips); #1a1200 was 3.4:1 */
|
||||
--info: #1c64c4;
|
||||
--info-ink: #ffffff;
|
||||
--ok-text: #0a7262; /* --ok as text on control fills (s3, s4) */
|
||||
@@ -82,9 +96,9 @@
|
||||
--scrim: rgba(20, 23, 26, .38);
|
||||
--shadow-pop: 0 12px 32px rgba(20, 23, 26, .16), 0 2px 6px rgba(20, 23, 26, .08);
|
||||
--zone-mix: .22;
|
||||
--seg-bg: var(--s3); /* segmented control: track, selected segment */
|
||||
--seg-bg: var(--s3); /* segmented control: track, selected segment and its ring */
|
||||
--seg-on: var(--s2);
|
||||
--seg-on-ring: inset 0 0 0 1px var(--line); /* inset: drawn at the segment's padding edge */
|
||||
--seg-on-ring: inset 0 0 0 1px var(--accent-line); /* inset: drawn at the segment's padding edge */
|
||||
}
|
||||
|
||||
html[data-darkmode="true"] {
|
||||
@@ -116,6 +130,7 @@ html[data-darkmode="true"] {
|
||||
--err: #ff6b6b;
|
||||
--err-soft: rgba(255, 107, 107, .12);
|
||||
--err-ink: #1a0505; /* white on the light dark-mode red was 2.8:1 */
|
||||
--warn-ink: #1a1200;
|
||||
--info: #6cb4ff;
|
||||
--info-ink: #0d0e10;
|
||||
--ok-text: var(--ok);
|
||||
@@ -128,7 +143,6 @@ html[data-darkmode="true"] {
|
||||
--zone-mix: .2;
|
||||
--seg-bg: var(--bg);
|
||||
--seg-on: var(--s3);
|
||||
--seg-on-ring: inset 0 0 0 1px var(--line-2);
|
||||
}
|
||||
|
||||
/* touch: controls are sized by the pointer, not the screen width */
|
||||
@@ -153,6 +167,14 @@ html[data-darkmode="true"] {
|
||||
--v-accent: var(--accent-text); /* olive: lime is unreadable on light */
|
||||
--v-accent-ink: #ffffff;
|
||||
--v-accent-soft: var(--accent-soft);
|
||||
/* the accent by role, as the theme's own controls use it: text and
|
||||
icons; borders, rings and selection bars; the lime fill of primary
|
||||
buttons and pressed picks with its ink */
|
||||
--v-accent-text: var(--accent-text);
|
||||
--v-accent-line: var(--accent-line);
|
||||
--v-accent-fill: var(--accent);
|
||||
--v-accent-fill-hover: var(--accent-hover);
|
||||
--v-accent-fill-ink: var(--accent-ink);
|
||||
--v-ok: var(--ok);
|
||||
--v-ok-soft: var(--ok-soft);
|
||||
--v-warn: var(--warn);
|
||||
@@ -161,6 +183,34 @@ html[data-darkmode="true"] {
|
||||
--v-err-soft: var(--err-soft);
|
||||
--v-info: var(--info);
|
||||
--v-info-soft: var(--info-soft);
|
||||
/* status colours as text on their soft fill, >= 4.5:1 on a hovered row too */
|
||||
--v-ok-text: var(--ok-text);
|
||||
--v-warn-text: var(--warn-text);
|
||||
--v-err-text: var(--err-text);
|
||||
--v-info-text: var(--info-text);
|
||||
--v-focus: var(--focus); /* a focused field: border plus a 1px ring of it */
|
||||
--v-scrim: var(--scrim); /* under dialogs, drawers and sheets */
|
||||
--v-seg-bg: var(--seg-bg); /* segmented control: track, selected segment, its ring */
|
||||
--v-seg-on: var(--seg-on);
|
||||
--v-seg-on-ring: var(--seg-on-ring);
|
||||
--v-hover: color-mix(in srgb, var(--s3) 55%, transparent); /* a hovered row on a card */
|
||||
--v-surface-4: var(--s4); /* a hovered item in a menu (menus are --v-surface-2) */
|
||||
--v-meter: var(--info); /* memory and storage bars: blue (lime is download) */
|
||||
--v-card-px: var(--card-px); /* card insides: 20 / 16px, 14px on phones */
|
||||
--v-card-py: var(--card-py);
|
||||
--v-sp-0-5: var(--sp-0-5); /* spacing: 2 4 6 8 12 16 20 24 32 px */
|
||||
--v-sp-1: var(--sp-1);
|
||||
--v-sp-1-5: var(--sp-1-5);
|
||||
--v-sp-2: var(--sp-2);
|
||||
--v-sp-3: var(--sp-3);
|
||||
--v-sp-4: var(--sp-4);
|
||||
--v-sp-5: var(--sp-5);
|
||||
--v-sp-6: var(--sp-6);
|
||||
--v-sp-8: var(--sp-8);
|
||||
--v-fw-regular: var(--fw-regular); /* weights: 400 500 600 700 */
|
||||
--v-fw-medium: var(--fw-medium);
|
||||
--v-fw-semibold: var(--fw-semibold);
|
||||
--v-fw-bold: var(--fw-bold);
|
||||
--v-font: var(--font);
|
||||
--v-mono: var(--mono);
|
||||
--v-fs-micro: var(--fs-micro); /* the type scale: 10.5 12 13 14 16 20 24 px */
|
||||
@@ -170,12 +220,18 @@ html[data-darkmode="true"] {
|
||||
--v-fs-lg: var(--fs-lg);
|
||||
--v-fs-xl: var(--fs-xl);
|
||||
--v-fs-2xl: var(--fs-2xl);
|
||||
--v-r-xs: var(--r-xs); /* radii: 2 4 6 8 12 px */
|
||||
--v-r-sm: var(--r-sm);
|
||||
--v-r: var(--r);
|
||||
--v-r-lg: var(--r-lg);
|
||||
--v-r-xl: var(--r-xl);
|
||||
--v-ctl-h: var(--ctl-h); /* every control: 36px, 44px on touch */
|
||||
--v-shadow: 0 1px 2px rgba(20, 23, 26, .06), 0 1px 0 rgba(20, 23, 26, .03);
|
||||
--v-shadow-raise: 0 6px 16px rgba(20, 23, 26, .08); /* a card lifted under the pointer */
|
||||
--v-shadow-pop: var(--shadow-pop); /* lists and menus that open over the page */
|
||||
/* the dashboard's drawer and its scrim: over the rail and the top bar
|
||||
(300), under modals (1000) and menus (1100) */
|
||||
--v-z-drawer: 890;
|
||||
/* where sticky content may start: below the top bar (page tabs scroll) */
|
||||
--v-stick-top: var(--stick-top);
|
||||
|
||||
@@ -199,6 +255,7 @@ html[data-darkmode="true"] {
|
||||
--v-accent: var(--accent); /* lime signal */
|
||||
--v-accent-ink: var(--accent-ink);
|
||||
--v-shadow: 0 1px 0 rgba(0, 0, 0, .35);
|
||||
--v-shadow-raise: 0 6px 16px rgba(0, 0, 0, .4);
|
||||
|
||||
--v-chart-1: #c8f031;
|
||||
--v-chart-2: #3f8fe8;
|
||||
@@ -336,11 +393,6 @@ html[data-darkmode="true"] .vt-brand-tile { fill: #16181b; }
|
||||
text-decoration: none !important;
|
||||
}
|
||||
.vt-brand svg { flex: none; }
|
||||
.vt-brand-word {
|
||||
font-weight: 650; font-size: var(--fs-md); letter-spacing: .02em;
|
||||
white-space: nowrap; overflow: hidden;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.vt-rail-list {
|
||||
list-style: none; margin: 0; padding: var(--sp-2) 0;
|
||||
@@ -395,7 +447,6 @@ html[data-darkmode="true"] .vt-brand-tile { fill: #16181b; }
|
||||
|
||||
/* pinned rail: labels + inline accordion instead of flyouts */
|
||||
html[data-rail="pinned"] .vt-rail { width: var(--rail-w-pinned); }
|
||||
html[data-rail="pinned"] .vt-brand-word,
|
||||
html[data-rail="pinned"] .vt-rail-label { display: block; }
|
||||
html[data-rail="pinned"] .vt-rail-caret { display: block; }
|
||||
html[data-rail="pinned"] .vt-rail-item.is-expanded > .vt-rail-link .vt-rail-caret { transform: rotate(90deg); }
|
||||
@@ -436,9 +487,7 @@ html[data-rail="pinned"] .vt-frame { margin-left: var(--rail-w-pinned); }
|
||||
border-bottom: 1px solid var(--line);
|
||||
flex: none;
|
||||
}
|
||||
.vt-fly-head svg { width: 18px; height: 18px; color: var(--accent-text); }
|
||||
.vt-fly-title { font-size: var(--fs-md); font-weight: 600; }
|
||||
.vt-fly-count { margin-left: auto; font: var(--fs-micro)/1 var(--mono); color: var(--text-3); letter-spacing: .04em; }
|
||||
|
||||
.vt-fly-list { list-style: none; margin: 0; padding: var(--sp-2); overflow-y: auto; flex: 1 1 auto; }
|
||||
.vt-fly-list > li + li { margin-top: 1px; }
|
||||
@@ -451,7 +500,6 @@ html[data-rail="pinned"] .vt-frame { margin-left: var(--rail-w-pinned); }
|
||||
}
|
||||
.vt-fly-link:hover { background: var(--s3); }
|
||||
.vt-fly-link[aria-current] { background: var(--accent-soft); color: var(--accent-text); font-weight: 600; }
|
||||
.vt-fly-link .vt-fly-meta { margin-left: auto; font: var(--fs-micro)/1 var(--mono); color: var(--text-3); }
|
||||
.vt-fly-sub { list-style: none; margin: 0 0 var(--sp-1) 18px; padding: 0; border-left: 1px solid var(--line-2); }
|
||||
.vt-fly-sub a {
|
||||
display: block; padding: 4px 10px;
|
||||
@@ -461,11 +509,6 @@ html[data-rail="pinned"] .vt-frame { margin-left: var(--rail-w-pinned); }
|
||||
}
|
||||
.vt-fly-sub a:hover { color: var(--text); background: var(--s3); }
|
||||
.vt-fly-sub a[aria-current] { color: var(--accent-text); font-weight: 600; box-shadow: inset 2px 0 0 var(--accent-text); }
|
||||
.vt-fly-foot {
|
||||
flex: none; padding: var(--sp-2) var(--sp-4);
|
||||
border-top: 1px solid var(--line);
|
||||
color: var(--text-3); font-size: var(--fs-micro); letter-spacing: .06em; text-transform: uppercase;
|
||||
}
|
||||
|
||||
.vt-scrim { position: fixed; inset: 0; z-index: 280; background: var(--scrim); }
|
||||
|
||||
@@ -516,7 +559,7 @@ a.vt-crumb:hover { color: var(--text); }
|
||||
.vt-crumb-switch > svg { flex: none; width: 14px; height: 14px; color: var(--text-3); transition: transform .15s; }
|
||||
.vt-crumb-switch:hover, .vt-crumb-switch[aria-expanded="true"] { background: var(--s3); }
|
||||
.vt-crumb-switch:focus-visible { outline-offset: 0; }
|
||||
.vt-crumb-switch[aria-expanded="true"] > svg { transform: rotate(90deg); }
|
||||
.vt-crumb-switch[aria-expanded="true"] > svg { transform: rotate(180deg); }
|
||||
@media (width > 720px) {
|
||||
/* the flyout as a dropdown under the crumb (left: set from the crumb) */
|
||||
.vt-flyout.is-switch {
|
||||
@@ -593,7 +636,7 @@ a.vt-crumb:hover { color: var(--text); }
|
||||
}
|
||||
.vt-appear-opt:hover { color: var(--text); }
|
||||
.vt-appear-opt > input { position: absolute; width: 1px; height: 1px; margin: 0; opacity: 0; pointer-events: none; }
|
||||
.vt-appear-opt:has(> input:checked) { background-color: var(--seg-on); color: var(--accent-text); font-weight: 600; box-shadow: inset 0 0 0 1px var(--accent-line); }
|
||||
.vt-appear-opt:has(> input:checked) { background-color: var(--seg-on); color: var(--accent-text); font-weight: 600; box-shadow: var(--seg-on-ring); }
|
||||
.vt-appear-opt:has(> input:focus-visible) { outline: 2px solid var(--focus); outline-offset: -1px; }
|
||||
.vt-appear-opt svg { flex: none; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
|
||||
|
||||
@@ -608,7 +651,7 @@ a.vt-crumb:hover { color: var(--text); }
|
||||
font-size: var(--fs-sm);
|
||||
white-space: nowrap;
|
||||
}
|
||||
.vt-host b { color: var(--text); font-weight: 600; font-family: var(--mono); font-size: var(--fs-micro); }
|
||||
.vt-host b { color: var(--text); font-weight: 600; }
|
||||
.vt-host span { overflow: hidden; text-overflow: ellipsis; }
|
||||
.vt-host-sep { color: var(--text-3); }
|
||||
|
||||
@@ -626,31 +669,15 @@ a.vt-crumb:hover { color: var(--text); }
|
||||
}
|
||||
#indicators > span[data-clickable] { cursor: pointer; }
|
||||
#indicators > span[data-clickable]:hover { border-color: var(--text-3); color: var(--text); }
|
||||
#indicators > span[data-indicator="poll-status"][data-style="active"] { position: relative; isolation: isolate; }
|
||||
/* auto-refresh on: a still dot (the label says it, a pulse only
|
||||
distracted); paused: a square */
|
||||
#indicators > span[data-indicator="poll-status"][data-style="active"]::before {
|
||||
content: ""; width: 7px; height: 7px; border-radius: 50%;
|
||||
background: var(--accent-text);
|
||||
}
|
||||
/* the pulse is a ring of its own that scales and fades: the compositor
|
||||
runs it, where an animated box-shadow repainted the page every frame.
|
||||
It sits behind the dot (z-index -1 in the pill's isolated stack), so
|
||||
the dot never lightens, and is invisible unless animated: with reduced
|
||||
motion the one near-instant run ends on opacity 0. */
|
||||
#indicators > span[data-indicator="poll-status"][data-style="active"]::after {
|
||||
content: ""; position: absolute; z-index: -1; left: 10px; top: calc(50% - 3.5px);
|
||||
width: 7px; height: 7px; border-radius: 50%;
|
||||
background: var(--accent-line);
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
animation: vt-live 2s ease-out infinite;
|
||||
background: var(--ok);
|
||||
}
|
||||
#indicators > span[data-indicator="poll-status"][data-style="inactive"]::before {
|
||||
content: ""; width: 7px; height: 7px; border-radius: 1px; background: var(--text-3);
|
||||
}
|
||||
@keyframes vt-live {
|
||||
0% { transform: scale(1); opacity: 1; }
|
||||
70%, 100% { transform: scale(2.7); opacity: 0; }
|
||||
}
|
||||
/* "Unsaved Changes: N" -> label + prominent count (text node stays for LuCI) */
|
||||
#indicators > span[data-indicator][data-count] {
|
||||
font-size: 0; gap: 8px; padding-right: 4px;
|
||||
@@ -666,7 +693,7 @@ a.vt-crumb:hover { color: var(--text); }
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
min-width: 20px; height: 20px; padding: 0 6px;
|
||||
border-radius: 999px;
|
||||
background: var(--warn); color: #1a1200;
|
||||
background: var(--warn); color: var(--warn-ink);
|
||||
font: 700 var(--fs-micro)/1 var(--mono);
|
||||
}
|
||||
#indicators > span[data-indicator="media_error"] { color: var(--err); border-color: var(--err); background: var(--err-soft); }
|
||||
@@ -770,6 +797,11 @@ a.vt-crumb:hover { color: var(--text); }
|
||||
}
|
||||
.vt-pal-foot span { display: inline-flex; align-items: center; gap: 6px; }
|
||||
.vt-pal-foot .vt-pal-count { margin-left: auto; font-family: var(--mono); font-size: var(--fs-micro); }
|
||||
/* no keyboard, no key hints */
|
||||
/* no keyboard hints on touch; the result count stays */
|
||||
@media (hover: none) {
|
||||
.vt-pal kbd, .vt-pal-foot > span:not(.vt-pal-count) { display: none; }
|
||||
}
|
||||
|
||||
/* ------------------------------------ 5. content: map, section, options */
|
||||
|
||||
@@ -786,7 +818,7 @@ a.vt-crumb:hover { color: var(--text); }
|
||||
.cbi-map { margin-bottom: var(--sp-6); }
|
||||
.cbi-map > h2, .vt-main > h2, #view > h2, #view > div > h2:first-child, .cbi-map > h2:first-child {
|
||||
margin: 0 0 6px;
|
||||
font-size: var(--fs-2xl); font-weight: 650; line-height: 1.2;
|
||||
font-size: var(--fs-2xl); font-weight: 600; line-height: 1.2;
|
||||
letter-spacing: -.02em;
|
||||
}
|
||||
.vt-main > h2[name="content"] { margin-bottom: var(--sp-5); }
|
||||
@@ -1012,7 +1044,8 @@ legend { font-size: var(--fs-md); font-weight: 600; padding: 0; margin-bottom: v
|
||||
|
||||
/* ------------------------------------------------------------ 6. widgets */
|
||||
|
||||
input, select, textarea, button { font: inherit; color: inherit; }
|
||||
/* zero specificity, like the button rule below, which must win over it */
|
||||
:where(input, select, textarea, button) { font: inherit; color: inherit; }
|
||||
|
||||
.cbi-input-text, .cbi-input-password, .cbi-input-select, .cbi-input-textarea,
|
||||
.cbi-section-create-name, .vt-main select, .vt-main textarea,
|
||||
@@ -1709,22 +1742,24 @@ table { border-collapse: separate; border-spacing: 0; width: 100%; }
|
||||
.td.cbi-section-actions .vt-acts-more.spinning::before { margin: 0; }
|
||||
.vt-actmenu {
|
||||
position: fixed; z-index: 1100;
|
||||
display: flex; flex-direction: column; gap: 2px;
|
||||
min-width: 168px; max-width: calc(100vw - 16px); padding: 6px;
|
||||
display: flex; flex-direction: column;
|
||||
min-width: 168px; max-width: calc(100vw - 16px); padding: var(--sp-1);
|
||||
overflow-y: auto; overscroll-behavior: contain;
|
||||
border: 1px solid var(--line-2); border-radius: var(--r);
|
||||
background: var(--s2); box-shadow: var(--shadow-pop);
|
||||
}
|
||||
.vt-actmenu[hidden] { display: none; }
|
||||
/* items as .cbi-dropdown's: the pointer's on --s4, the keyboard's with the
|
||||
accent bar too */
|
||||
.vt-actmenu-item {
|
||||
display: flex; align-items: center;
|
||||
min-height: var(--ctl-h); padding: 0 12px;
|
||||
min-height: calc(var(--ctl-h) - 4px); padding: 4px 8px;
|
||||
border: 0; border-radius: var(--r-sm);
|
||||
background: transparent; color: var(--text);
|
||||
font: inherit; font-size: var(--fs-base); text-align: left; white-space: nowrap; cursor: pointer;
|
||||
font: inherit; font-size: var(--fs-base); font-weight: 400; text-align: left; white-space: nowrap; cursor: pointer;
|
||||
}
|
||||
.vt-actmenu-item:hover { background: var(--s3); }
|
||||
.vt-actmenu-item:focus-visible { background: var(--s3); outline: 2px solid var(--focus); outline-offset: -2px; }
|
||||
.vt-actmenu-item:hover { background: var(--s4); }
|
||||
.vt-actmenu-item:focus-visible { background: var(--s4); outline: none; box-shadow: inset 2px 0 0 var(--accent-text); }
|
||||
.vt-actmenu-item.is-danger { color: var(--err); }
|
||||
.vt-actmenu-item[disabled] { opacity: .5; cursor: default; }
|
||||
.vt-actmenu-item[disabled]:hover { background: none; }
|
||||
@@ -1785,7 +1820,7 @@ div.right > .btn, div.right > .cbi-button, div.right > button { margin-left: 0;
|
||||
:is(.cbi-tabmenu > li > a, .vt-pagetabs > .vt-tab):focus-visible { outline-offset: -1px; border-radius: calc(var(--r) + 3px); }
|
||||
/* the selected segment carries the signal (text and ring): white on the
|
||||
grey track alone was hard to pick out; hover keeps it */
|
||||
.cbi-tabmenu > li.cbi-tab > a, .cbi-tabmenu > li.cbi-tab > a:hover, .vt-pagetabs > .vt-tab[aria-current] { background-color: var(--seg-on); color: var(--accent-text); font-weight: 600; box-shadow: inset 0 0 0 1px var(--accent-line); }
|
||||
.cbi-tabmenu > li.cbi-tab > a, .cbi-tabmenu > li.cbi-tab > a:hover, .vt-pagetabs > .vt-tab[aria-current] { background-color: var(--seg-on); color: var(--accent-text); font-weight: 600; box-shadow: var(--seg-on-ring); }
|
||||
.cbi-tabmenu > li[data-errors] > a::after {
|
||||
content: attr(data-errors);
|
||||
display: inline-flex; align-items: center; justify-content: center;
|
||||
@@ -1867,7 +1902,7 @@ div.right > .btn, div.right > .cbi-button, div.right > button { margin-left: 0;
|
||||
:is(.ifacebox-body, .ifacebadge) > span:has(> .nowrap) > .nowrap > strong {
|
||||
color: var(--text-3);
|
||||
font: 600 var(--fs-micro)/1.55 var(--font);
|
||||
letter-spacing: .06em; text-transform: uppercase;
|
||||
letter-spacing: .08em; text-transform: uppercase;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@@ -1920,16 +1955,17 @@ div:has(> .ifacebox > .ifacebox-head.cbi-tooltip-container) > .ifacebox { width:
|
||||
.ifacebox-head.active { background: var(--accent-soft); color: var(--accent-text); }
|
||||
.ifacebox-body { padding: 8px 10px; font-size: var(--fs-sm); color: var(--text-2); }
|
||||
.ifacebox-body img { width: 18px; height: 18px; }
|
||||
/* Status -> Port status, each box: a link dot by the name (as on the
|
||||
upstream and radio cards), the speed as its figure, the zone as a bare
|
||||
bar and the counters' arrows in the dashboard's upload and download
|
||||
colours (menu-vantage.js puts them in spans). LuCI's port picture only
|
||||
repeats the link state: hidden. A port without link is muted throughout */
|
||||
/* Status -> Port status, each box: a ring by the name of a port without
|
||||
link (as on the upstream and radio cards; a port with link has none),
|
||||
the speed as its figure, the zone as a bare bar and the counters'
|
||||
arrows in the dashboard's upload and download colours (menu-vantage.js
|
||||
puts them in spans). LuCI's port picture only repeats the link state:
|
||||
hidden. A port without link is muted throughout */
|
||||
.ifacebox:has(> .ifacebox-head.cbi-tooltip-container) > .ifacebox-head:first-child {
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
padding: 10px 10px 2px;
|
||||
background: none; border-bottom: 0;
|
||||
font-family: var(--mono); font-weight: 650 !important; text-align: left;
|
||||
font-family: var(--mono); font-weight: 600 !important; text-align: left;
|
||||
}
|
||||
.ifacebox:has(> .ifacebox-head.cbi-tooltip-container) > .ifacebox-head:first-child::before {
|
||||
content: ""; flex: none;
|
||||
@@ -1937,7 +1973,7 @@ div:has(> .ifacebox > .ifacebox-head.cbi-tooltip-container) > .ifacebox { width:
|
||||
box-shadow: inset 0 0 0 1.5px var(--text-3);
|
||||
}
|
||||
.ifacebox:has(> .ifacebox-body > img[src$="_down.svg"]) > .ifacebox-head:first-child { color: var(--text-2); }
|
||||
.ifacebox:has(> .ifacebox-body > img[src$="_up.svg"]) > .ifacebox-head:first-child::before { background: var(--v-chart-1); box-shadow: 0 0 0 3px var(--accent-soft); }
|
||||
.ifacebox:has(> .ifacebox-body > img[src$="_up.svg"]) > .ifacebox-head:first-child::before { content: none; }
|
||||
.ifacebox:has(> .ifacebox-head.cbi-tooltip-container) > .ifacebox-head:first-child + .ifacebox-body { padding: 2px 10px 6px; color: var(--text-3); }
|
||||
.ifacebox:has(> .ifacebox-body > img[src$="_up.svg"]) > .ifacebox-head:first-child + .ifacebox-body { color: var(--text-2); }
|
||||
.ifacebox:has(> .ifacebox-head.cbi-tooltip-container) > .ifacebox-head:first-child + .ifacebox-body > :is(img, br) { display: none; }
|
||||
@@ -1948,7 +1984,7 @@ div:has(> .ifacebox > .ifacebox-head.cbi-tooltip-container) > .ifacebox { width:
|
||||
.ifacebox-head.cbi-tooltip-container:has(> .zonebadge) { gap: 3px; padding: 4px 10px; background: none; border-bottom: 0; }
|
||||
.ifacebox-head.cbi-tooltip-container > .zonebadge[style*="--zone-color-rgb"] {
|
||||
height: 3px !important; padding: 0;
|
||||
border: 0; border-radius: 2px; box-shadow: none;
|
||||
border: 0; border-radius: var(--r-xs); box-shadow: none;
|
||||
background-color: rgb(var(--zone-color-rgb)) !important;
|
||||
}
|
||||
.ifacebox-head.cbi-tooltip-container > .zonebadge:is([style*="--zone-color-rgb: 238, 238, 238"], [style*="--zone-color-rgb:238, 238, 238"], [style*="--zone-color-rgb:238,238,238"]) { background-color: var(--text-3) !important; }
|
||||
@@ -1968,13 +2004,15 @@ div:has(> .ifacebox > .ifacebox-head.cbi-tooltip-container) > .ifacebox { width:
|
||||
color: var(--text) !important;
|
||||
font-size: var(--fs-md); text-align: left;
|
||||
}
|
||||
.network-status-table .ifacebox-head strong { font-weight: 650; font-family: var(--mono); letter-spacing: -.01em; }
|
||||
.network-status-table .ifacebox-head strong { font-weight: 600; font-family: var(--mono); letter-spacing: -.01em; }
|
||||
/* up is the normal case and draws nothing; a box that is down (an
|
||||
upstream not connected, a radio off) gets a hollow ring */
|
||||
.network-status-table .ifacebox-head::before {
|
||||
content: ""; flex: none;
|
||||
width: 8px; height: 8px; border-radius: 50%;
|
||||
background: var(--text-3);
|
||||
box-shadow: inset 0 0 0 1.5px var(--text-3);
|
||||
}
|
||||
.network-status-table .ifacebox-head.active::before { background: var(--accent-text); box-shadow: 0 0 0 3px var(--accent-soft); }
|
||||
.network-status-table .ifacebox-head.active::before { content: none; }
|
||||
.network-status-table .ifacebox-head[data-v-band]::after {
|
||||
content: attr(data-v-band);
|
||||
margin-left: auto;
|
||||
@@ -2038,34 +2076,6 @@ div:has(> .ifacebox > .ifacebox-head.cbi-tooltip-container) > .ifacebox { width:
|
||||
.zone-forwards { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; }
|
||||
.zone-forwards > span { color: var(--text-3); }
|
||||
|
||||
/* progress bar: text only exists in title */
|
||||
.cbi-progressbar {
|
||||
position: relative;
|
||||
width: 100%; max-width: 520px;
|
||||
height: 22px;
|
||||
background: var(--s2);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--r-sm);
|
||||
overflow: hidden;
|
||||
}
|
||||
.cbi-progressbar > div {
|
||||
height: 100%;
|
||||
width: 0;
|
||||
background: linear-gradient(90deg, color-mix(in srgb, var(--accent-text) 22%, transparent), color-mix(in srgb, var(--accent-text) 48%, transparent));
|
||||
transition: width .3s ease-out;
|
||||
}
|
||||
.cbi-progressbar::before {
|
||||
content: attr(title);
|
||||
position: absolute; inset: 0;
|
||||
display: flex; align-items: center;
|
||||
padding: 0 8px;
|
||||
color: var(--text);
|
||||
font: 500 var(--fs-micro)/1 var(--mono);
|
||||
font-variant-numeric: tabular-nums;
|
||||
white-space: nowrap;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* notifications */
|
||||
.alert-message {
|
||||
position: relative;
|
||||
@@ -2128,7 +2138,7 @@ div:has(> .ifacebox > .ifacebox-head.cbi-tooltip-container) > .ifacebox { width:
|
||||
pointer-events: none;
|
||||
}
|
||||
.cbi-tooltip.error { background: var(--err); border-color: var(--err); color: var(--err-ink); }
|
||||
.cbi-tooltip.warning { background: var(--warn); border-color: var(--warn); color: #1a1200; }
|
||||
.cbi-tooltip.warning { background: var(--warn); border-color: var(--warn); color: var(--warn-ink); }
|
||||
.cbi-tooltip.info { background: var(--info); border-color: var(--info); color: var(--info-ink); }
|
||||
.cbi-tooltip-container { position: relative; cursor: help; }
|
||||
/* sized to its text, not to a narrow container such as a 100 px port box */
|
||||
@@ -2280,7 +2290,7 @@ body.modal-overlay-active #modal_overlay { display: block; }
|
||||
.uci-change-legend-label > :is(ins, del, var) {
|
||||
display: inline-flex; flex: none;
|
||||
width: 14px; height: 14px; padding: 0;
|
||||
border: 1px solid; border-radius: 3px;
|
||||
border: 1px solid; border-radius: var(--r-xs);
|
||||
font-size: 0; overflow: hidden;
|
||||
text-decoration: none; font-style: normal;
|
||||
}
|
||||
@@ -2429,7 +2439,7 @@ body[data-page^="admin-status-realtime"] #view .table:has(strong[style*="border-
|
||||
}
|
||||
body[data-page^="admin-status-realtime"] #view .table:has(strong[style*="border-bottom"]) > .tr > .td:nth-child(1) strong::before {
|
||||
content: ""; flex: none;
|
||||
width: 14px; height: 3px; border-radius: 2px;
|
||||
width: 14px; height: 3px; border-radius: var(--r-xs);
|
||||
background: var(--key);
|
||||
}
|
||||
body[data-page^="admin-status-realtime"] #view .table:has(strong[style*="border-bottom"]) > .tr > .td:is(:nth-child(3), :nth-child(5)) strong {
|
||||
@@ -2442,7 +2452,7 @@ body[data-page^="admin-status-realtime"] #view .table:has(strong[style*="border-
|
||||
white-space: nowrap;
|
||||
}
|
||||
body[data-page^="admin-status-realtime"] #view .table:has(strong[style*="border-bottom"]) > .tr > .td:is(:nth-child(2), :nth-child(4), :nth-child(6))::first-line { color: var(--v-text-2); font-size: var(--fs-sm); }
|
||||
body[data-page^="admin-status-realtime"] #view .table:has(strong[style*="border-bottom"]) > .tr > .td:nth-child(2)::first-line { color: var(--v-text); font-weight: 650; font-size: var(--fs-md); }
|
||||
body[data-page^="admin-status-realtime"] #view .table:has(strong[style*="border-bottom"]) > .tr > .td:nth-child(2)::first-line { color: var(--v-text); font-weight: 600; font-size: var(--fs-md); }
|
||||
body[data-page^="admin-status-realtime"] #view .tr:has(:is(#lb_load01_cur, #rx_bw_cur, #rssi_bw_cur, #lb_udp_cur)) { --key: var(--v-chart-1); }
|
||||
body[data-page^="admin-status-realtime"] #view .tr:has(:is(#lb_load05_cur, #tx_bw_cur, #rate_bw_cur, #lb_tcp_cur)) { --key: var(--v-chart-2); }
|
||||
body[data-page^="admin-status-realtime"] #view .tr:has(:is(#lb_load15_cur, #noise_bw_cur, #lb_otr_cur)) { --key: var(--v-chart-3); }
|
||||
@@ -2519,7 +2529,7 @@ body[data-page^="admin-status-channel_analysis"] #view [data-tab-title]:not([dat
|
||||
paint-order: stroke;
|
||||
stroke: var(--s1); stroke-width: 3px; stroke-linejoin: round;
|
||||
}
|
||||
#view div[id="channel_graph"] svg text.v-ca-label[data-v-own] { fill: var(--v-accent) !important; font-weight: 650 !important; }
|
||||
#view div[id="channel_graph"] svg text.v-ca-label[data-v-own] { fill: var(--v-accent) !important; font-weight: 600 !important; }
|
||||
#view span[data-v-series] { font-size: .75em; vertical-align: 1px; color: var(--v-chart-2) !important; }
|
||||
#view span[data-v-series="1"] { color: var(--v-chart-1) !important; }
|
||||
#view span[data-v-series="3"] { color: var(--v-chart-3) !important; }
|
||||
@@ -2549,16 +2559,10 @@ body[data-page^="admin-status-channel_analysis"] #view [data-tab-title]:not([dat
|
||||
.vt-login-page {
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
padding: var(--sp-4);
|
||||
background:
|
||||
radial-gradient(1200px 600px at 50% -10%, color-mix(in srgb, var(--accent) 6%, transparent), transparent 60%),
|
||||
linear-gradient(var(--line) 1px, transparent 1px) 0 0 / 32px 32px,
|
||||
linear-gradient(90deg, var(--line) 1px, transparent 1px) 0 0 / 32px 32px,
|
||||
var(--bg);
|
||||
background-blend-mode: normal;
|
||||
}
|
||||
html[data-darkmode="true"] .vt-login-page {
|
||||
background:
|
||||
radial-gradient(900px 520px at 50% 0%, rgba(200, 240, 49, .06), transparent 60%),
|
||||
radial-gradient(900px 520px at 50% 0%, color-mix(in srgb, var(--accent) 6%, transparent), transparent 60%),
|
||||
linear-gradient(rgba(255, 255, 255, .025) 1px, transparent 1px) 0 0 / 32px 32px,
|
||||
linear-gradient(90deg, rgba(255, 255, 255, .025) 1px, transparent 1px) 0 0 / 32px 32px,
|
||||
var(--bg);
|
||||
@@ -2569,7 +2573,7 @@ html:not([data-darkmode="true"]) .vt-login-page {
|
||||
linear-gradient(90deg, rgba(20, 23, 26, .04) 1px, transparent 1px) 0 0 / 32px 32px,
|
||||
var(--bg);
|
||||
}
|
||||
/* the starfield (login.js), between the grid and the card */
|
||||
/* the backdrop (login.js: packets or starfield), between the grid and the card */
|
||||
.vt-login-sky { position: fixed; inset: 0; width: 100%; height: 100%; pointer-events: none; }
|
||||
.vt-login {
|
||||
position: relative; width: min(380px, 100%);
|
||||
@@ -2599,19 +2603,7 @@ html:not([data-darkmode="true"]) .vt-login-page::before {
|
||||
}
|
||||
.vt-login-head { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-6); }
|
||||
.vt-login-mark { flex: none; }
|
||||
.vt-login-title { margin: 0; font-size: var(--fs-lg); font-family: var(--mono); font-weight: 600; letter-spacing: -.01em; overflow-wrap: anywhere; }
|
||||
.vt-login-sub {
|
||||
display: flex; align-items: center; gap: 6px;
|
||||
margin: 2px 0 0;
|
||||
color: var(--text-3);
|
||||
font-size: var(--fs-micro); font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
|
||||
}
|
||||
.vt-login-sub { isolation: isolate; }
|
||||
/* the ring as on the poll pill: behind the dot (the dot itself makes no
|
||||
stacking context, so z-index -1 lands under its background), opacity 0
|
||||
unless animated */
|
||||
.vt-login-dot { position: relative; width: 6px; height: 6px; border-radius: 50%; background: var(--accent-text); }
|
||||
.vt-login-dot::after { content: ""; position: absolute; z-index: -1; inset: 0; border-radius: 50%; background: var(--accent-line); opacity: 0; animation: vt-live 2s ease-out infinite; }
|
||||
.vt-login-title { margin: 0; font-size: var(--fs-lg); font-weight: 600; letter-spacing: -.01em; overflow-wrap: anywhere; }
|
||||
.vt-login-error {
|
||||
margin: 0 0 var(--sp-4);
|
||||
padding: var(--sp-2) var(--sp-3);
|
||||
@@ -2635,7 +2627,6 @@ html:not([data-darkmode="true"]) .vt-login-page::before {
|
||||
}
|
||||
.vt-field input[name="luci_username"] { font-family: var(--mono); }
|
||||
.vt-login-submit { height: var(--ctl-h); margin-top: var(--sp-2); font-size: var(--fs-md) !important; width: 100%; }
|
||||
.vt-login-foot { margin: var(--sp-4) 0 0; text-align: center; color: var(--text-3); font: var(--fs-micro)/1.4 var(--mono); letter-spacing: .03em; }
|
||||
|
||||
/* ------------------------------------------------ 9. stock page layouts */
|
||||
|
||||
@@ -2683,7 +2674,7 @@ body[data-page="admin-statistics-graphs"] p.controls > .nowrap > .cbi-button { m
|
||||
}
|
||||
[id$="-ifc-description"] > .nowrap > strong, .td[data-name="_stat"] .nowrap > strong {
|
||||
color: var(--text-3);
|
||||
font: 600 var(--fs-micro)/1.5 var(--font); letter-spacing: .06em; text-transform: uppercase;
|
||||
font: 600 var(--fs-micro)/1.5 var(--font); letter-spacing: .08em; text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* Network -> Wireless: radios as group headers, networks as rows */
|
||||
@@ -2702,21 +2693,27 @@ body[data-page="admin-statistics-graphs"] p.controls > .nowrap > .cbi-button { m
|
||||
.cbi-section-table-row:has(> .td[data-name="_stat"] big):first-child > .td { border-top: 0; }
|
||||
.cbi-section-table-row:not(:has(big)) > .td[data-name="_badge"] { padding-left: calc(var(--card-px) + 16px); }
|
||||
|
||||
/* progress bars: thin track, value text above it and in flow, so larger
|
||||
browser fonts cannot run into the heading */
|
||||
/* progress bars (their text only exists in title): a thin track, the
|
||||
value text above it and in flow, so larger browser fonts cannot run
|
||||
into the heading */
|
||||
.cbi-progressbar {
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr);
|
||||
grid-template-rows: auto 6px;
|
||||
gap: 5px;
|
||||
height: auto; margin: 0 0 2px;
|
||||
background: none;
|
||||
border: 0; border-radius: 3px;
|
||||
overflow: visible;
|
||||
width: 100%; max-width: 520px;
|
||||
margin: 0 0 2px;
|
||||
}
|
||||
.cbi-progressbar > div {
|
||||
grid-area: 2 / 1; z-index: 1;
|
||||
width: 0; height: 6px;
|
||||
border-radius: 3px;
|
||||
background: var(--accent-text);
|
||||
transition: width .3s ease-out;
|
||||
}
|
||||
.cbi-progressbar > div { grid-area: 2 / 1; height: 6px; z-index: 1; border-radius: 3px; background: var(--accent-text); }
|
||||
.cbi-progressbar::before {
|
||||
position: static; inset: auto; padding: 0;
|
||||
content: attr(title);
|
||||
display: block;
|
||||
color: var(--text-2);
|
||||
font: 500 var(--fs-micro)/1.2 var(--mono);
|
||||
@@ -2729,8 +2726,9 @@ body[data-page="admin-statistics-graphs"] p.controls > .nowrap > .cbi-button { m
|
||||
.v-meter { display: grid; gap: 10px; padding: 4px 0 6px; }
|
||||
.v-meter + .v-meter { margin-top: var(--sp-3); padding-top: var(--sp-4); border-top: 1px solid var(--line); }
|
||||
.v-meter-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; }
|
||||
.v-meter-title { color: var(--text); font-weight: 600; }
|
||||
.v-meter-big { font: 650 var(--fs-xl)/1 var(--mono); letter-spacing: -.02em; color: var(--text); }
|
||||
/* the meter's figures, as the dashboard's: the share in tabular sans, the
|
||||
amounts in monospace */
|
||||
.v-meter-big { font: 700 var(--fs-xl)/1 var(--font); font-variant-numeric: tabular-nums; letter-spacing: -.02em; color: var(--text); }
|
||||
.v-meter-big small { margin-left: 6px; font: 500 var(--fs-sm) var(--font); letter-spacing: 0; color: var(--text-2); }
|
||||
.v-meter-sub { margin-left: auto; color: var(--text-2); font: var(--fs-sm)/1.4 var(--mono); font-variant-numeric: tabular-nums; }
|
||||
.v-meter-bar {
|
||||
@@ -2738,18 +2736,19 @@ body[data-page="admin-statistics-graphs"] p.controls > .nowrap > .cbi-button { m
|
||||
display: flex;
|
||||
height: 12px;
|
||||
background: var(--s3);
|
||||
border-radius: 3px;
|
||||
border-radius: var(--r-xs);
|
||||
overflow: hidden;
|
||||
box-shadow: inset 0 0 0 1px var(--line);
|
||||
}
|
||||
.v-meter-bar.is-thin { height: 6px; }
|
||||
.v-seg { height: 100%; flex: none; transition: width .4s ease-out; }
|
||||
.v-seg + .v-seg { box-shadow: inset 1px 0 0 var(--s1); }
|
||||
.v-seg-used { background: var(--v-accent); }
|
||||
/* blue, as the dashboard's meters: lime there means download */
|
||||
.v-seg-used { background: var(--v-meter); }
|
||||
.v-seg-cache {
|
||||
background: repeating-linear-gradient(-45deg,
|
||||
color-mix(in srgb, var(--v-accent) 55%, transparent) 0 3px,
|
||||
color-mix(in srgb, var(--v-accent) 25%, transparent) 3px 6px);
|
||||
color-mix(in srgb, var(--v-meter) 55%, transparent) 0 3px,
|
||||
color-mix(in srgb, var(--v-meter) 25%, transparent) 3px 6px);
|
||||
}
|
||||
.v-seg.is-warn { background: var(--warn); }
|
||||
.v-seg.is-crit { background: var(--err); }
|
||||
@@ -2757,7 +2756,7 @@ body[data-page="admin-statistics-graphs"] p.controls > .nowrap > .cbi-button { m
|
||||
.v-meter-legend li { display: inline-flex; align-items: center; gap: 7px; }
|
||||
.v-meter-legend b { color: var(--text); font: 600 var(--fs-sm) var(--mono); font-variant-numeric: tabular-nums; }
|
||||
.v-meter-legend em { color: var(--text-3); font-style: normal; font-size: var(--fs-micro); }
|
||||
.v-key { width: 10px; height: 10px; border-radius: 2px; flex: none; }
|
||||
.v-key { width: 10px; height: 10px; border-radius: var(--r-xs); flex: none; }
|
||||
.v-key.v-seg-free { background: var(--s3); box-shadow: inset 0 0 0 1px var(--line-2); }
|
||||
.v-meter-rows { display: grid; grid-template-columns: minmax(120px, max-content) minmax(0, 1fr) max-content; gap: 14px 20px; padding: 4px 0 6px; }
|
||||
.v-meter-row { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; grid-template-areas: "label bar val"; align-items: center; }
|
||||
@@ -2766,7 +2765,6 @@ body[data-page="admin-statistics-graphs"] p.controls > .nowrap > .cbi-button { m
|
||||
.v-meter-row > .v-meter-bar { grid-area: bar; }
|
||||
.v-meter-row > .v-meter-val { grid-area: val; color: var(--text-2); font: var(--fs-sm) var(--mono); font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
|
||||
.v-meter-row > .v-meter-val b { color: var(--text); font-weight: 600; }
|
||||
.v-sr { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
|
||||
|
||||
/* Share the widest table's intrinsic width with its headings and dividers. */
|
||||
@media (width > 720px) {
|
||||
@@ -2876,16 +2874,16 @@ html[data-darkmode="true"] :is(#ban-status, #ban-report) { --ban-ok: #63c79b; --
|
||||
}
|
||||
.zone-forwards :is(.zone-src, .zone-dest) { display: inline-flex; flex-wrap: wrap; gap: 6px; }
|
||||
.zonebadge.zonebadge-empty { background: transparent !important; border-style: dashed; color: var(--text-2) !important; box-shadow: none; }
|
||||
/* zone and default policies: reject and drop in red, accept in green */
|
||||
select[id^="widget.cbid.firewall."]:has(> option:checked:is([value="REJECT"], [value="DROP"])) { color: var(--err); font-weight: 600; }
|
||||
select[id^="widget.cbid.firewall."]:has(> option:checked[value="ACCEPT"]) { color: var(--ok-text); font-weight: 600; }
|
||||
select[id^="widget.cbid.firewall."] > option { color: var(--text); font-weight: 400; }
|
||||
/* except where accept is the risk: the masquerading (internet-facing)
|
||||
zone accepting input, or forwarding into another zone. Green says
|
||||
"passes", not "safe"; these two get the warning colour instead. */
|
||||
/* zone and default policies stay plain: reject and drop are the safe
|
||||
values, accept between your own zones is normal (as on the Overview
|
||||
tab). The one policy that is a risk is coloured: the masquerading
|
||||
(internet-facing) zone accepting input, in the error colours the
|
||||
Overview tab gives it. Forwarding from it into another zone is
|
||||
outlined in the warning colour. */
|
||||
#cbi-firewall-zone .tr:has(input[data-widget-id$=".masq"]:checked) > .td[data-name="input"] select:has(> option:checked[value="ACCEPT"]) {
|
||||
color: var(--warn-text); border-color: var(--warn); background-color: var(--warn-soft);
|
||||
color: var(--err-text); border-color: var(--err); background-color: var(--err-soft); font-weight: 600;
|
||||
}
|
||||
#cbi-firewall-zone .tr:has(input[data-widget-id$=".masq"]:checked) > .td[data-name="input"] select:has(> option:checked[value="ACCEPT"]) > option { color: var(--text); font-weight: 400; }
|
||||
#cbi-firewall-zone .tr:has(input[data-widget-id$=".masq"]:checked) .zone-dest > .zonebadge:not(.zonebadge-empty) {
|
||||
outline: 2px solid var(--warn); outline-offset: 1px;
|
||||
}
|
||||
@@ -3083,7 +3081,7 @@ select[id^="widget.cbid.firewall."] > option { color: var(--text); font-weight:
|
||||
.v-nft-what-name[data-muted="true"] { color: var(--text-3); font-weight: 500; }
|
||||
/* the chain's end: one quiet line */
|
||||
.v-nft-step-end { padding: 4px 0 2px; }
|
||||
.v-nft-step-end .v-nft-n { width: 10px; height: 10px; margin: 4px 5px; border-radius: 3px; background: var(--line-2); }
|
||||
.v-nft-step-end .v-nft-n { width: 10px; height: 10px; margin: 4px 5px; border-radius: var(--r-xs); background: var(--line-2); }
|
||||
.v-nft-step-end .v-nft-what { color: var(--text-3); font-size: var(--fs-sm); }
|
||||
.v-nft-step-end .v-nft-verdict { min-height: 20px; padding: 0 8px; font-size: var(--fs-micro); }
|
||||
.v-nft-step-more { grid-template-columns: 20px auto; }
|
||||
@@ -3212,17 +3210,26 @@ body[data-page="admin-system-filemanager"] .sort-button { border-color: var(--li
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.vt-host { display: none !important; }
|
||||
/* indicators go compact (dot, count) before the crumbs get cut; the
|
||||
label stays as text for screen readers and as the title */
|
||||
/* indicators go compact (a sign, a count) before the crumbs get cut;
|
||||
the label stays as text for screen readers and as the title */
|
||||
#indicators > span[data-indicator] { height: 28px; padding: 0 8px; }
|
||||
#indicators > span[data-indicator="poll-status"] { font-size: 0; gap: 0; width: 28px; justify-content: center; padding: 0; }
|
||||
#indicators > span[data-indicator="poll-status"][data-style="active"]::after { left: calc(50% - 3.5px); }
|
||||
/* without its label the pill is the pause / resume button: a pause
|
||||
sign while it refreshes, a play sign while paused */
|
||||
#indicators > span[data-indicator="poll-status"][data-style="active"]::before {
|
||||
width: 8px; height: 10px; border-radius: 0;
|
||||
background: none; border-inline: 3px solid currentColor;
|
||||
}
|
||||
#indicators > span[data-indicator="poll-status"][data-style="inactive"]::before {
|
||||
width: 0; height: 0; margin-left: 2px; border-radius: 0;
|
||||
background: none; border-left: 9px solid currentColor; border-block: 5px solid transparent;
|
||||
}
|
||||
#indicators > span[data-indicator][data-count] { padding: 0 3px; gap: 0; }
|
||||
#indicators > span[data-indicator][data-count]::before { content: none; }
|
||||
html[data-rail="pinned"] .vt-rail { width: var(--rail-w); }
|
||||
html[data-rail="pinned"] .vt-frame { margin-left: var(--rail-w); }
|
||||
html[data-rail="pinned"] body.vt-auth .vt-shell::before { width: var(--rail-w); }
|
||||
html[data-rail="pinned"] .vt-brand-word, html[data-rail="pinned"] .vt-rail-label,
|
||||
html[data-rail="pinned"] .vt-rail-label,
|
||||
html[data-rail="pinned"] .vt-rail-caret, html[data-rail="pinned"] .vt-rail-sub { display: none !important; }
|
||||
.vt-rail-pin { display: none; }
|
||||
}
|
||||
@@ -3289,7 +3296,6 @@ body[data-page="admin-system-filemanager"] .sort-button { border-color: var(--li
|
||||
}
|
||||
.vt-fly-link { min-height: 44px; font-size: var(--fs-md); }
|
||||
.vt-fly-sub a { padding: 8px 12px; font-size: var(--fs-base); }
|
||||
.vt-fly-foot { display: none; }
|
||||
@keyframes vt-sheet-in { from { transform: translateY(16px); opacity: 0; } to { transform: none; opacity: 1; } }
|
||||
|
||||
.vt-topbar { gap: var(--sp-2); padding: 0 var(--sp-3) 0 var(--sp-4); }
|
||||
@@ -3475,7 +3481,7 @@ body[data-page="admin-system-filemanager"] .sort-button { border-color: var(--li
|
||||
/* short row buttons (Processes' Kill) at least as wide as they are high */
|
||||
.td.cbi-section-actions :is(.btn, .cbi-button):not(.drag-handle) { min-width: var(--ctl-h); }
|
||||
/* dropdown choices (Save & Apply's too) are touch targets */
|
||||
.cbi-dropdown[open] > ul.dropdown > li { min-height: var(--ctl-h); }
|
||||
.cbi-dropdown[open] > ul.dropdown > li, .vt-actmenu-item { min-height: var(--ctl-h); }
|
||||
.cbi-value { padding: 8px 0; }
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,13 @@ msgid_plural "%d more chains at this hook"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1350
|
||||
msgctxt "vantage-theme"
|
||||
msgid "%d result"
|
||||
msgid_plural "%d results"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/vantage-theme/nftflow.js:345
|
||||
msgctxt "vantage-theme"
|
||||
msgid "%d rule"
|
||||
@@ -49,7 +56,7 @@ msgctxt "vantage-theme"
|
||||
msgid "Accept"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1188
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1270
|
||||
msgid "Actions"
|
||||
msgstr ""
|
||||
|
||||
@@ -58,21 +65,22 @@ msgctxt "nft match any traffic"
|
||||
msgid "Any packet"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1181
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1182
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1183
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1186
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1439
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:81
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1258
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1259
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1260
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1263
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1267
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1533
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:84
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Appearance"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:43
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:41
|
||||
msgid "Authorization Required"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1441
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1535
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Auto"
|
||||
msgstr ""
|
||||
@@ -87,7 +95,7 @@ msgctxt "vantage-theme"
|
||||
msgid "Back to the calling chain"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:69
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:72
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Breadcrumb"
|
||||
msgstr ""
|
||||
@@ -105,17 +113,17 @@ msgctxt "vantage-theme"
|
||||
msgid "Bridged between ports"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:338
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:409
|
||||
msgid "Buffered"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:349
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:359
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:363
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:420
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:430
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:434
|
||||
msgid "Cache"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:338
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:409
|
||||
msgid "Cached"
|
||||
msgstr ""
|
||||
|
||||
@@ -134,19 +142,19 @@ msgctxt "vantage-theme"
|
||||
msgid "Chains no rule jumps to directly"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:419
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:491
|
||||
msgid "Channel"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:818
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:897
|
||||
msgid "Collapse navigation"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1440
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1534
|
||||
msgid "Colour theme"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1212
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1294
|
||||
msgid "Command palette"
|
||||
msgstr ""
|
||||
|
||||
@@ -165,7 +173,7 @@ msgctxt "vantage-theme"
|
||||
msgid "Continues in %s, then comes back here"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1441
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1535
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Dark"
|
||||
msgstr ""
|
||||
@@ -189,8 +197,8 @@ msgstr ""
|
||||
msgid "Egress"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:818
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:54
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:897
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:57
|
||||
msgid "Expand navigation"
|
||||
msgstr ""
|
||||
|
||||
@@ -207,7 +215,7 @@ msgid ""
|
||||
"their counters see only its first packets."
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1183
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1260
|
||||
msgid "Follow system theme"
|
||||
msgstr ""
|
||||
|
||||
@@ -225,17 +233,17 @@ msgid ""
|
||||
"if br_netfilter is enabled; the ruleset doesn't show that.)"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:350
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:364
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:421
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:435
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Free"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1393
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1458
|
||||
msgid "Grid packets"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:48
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:52
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Home"
|
||||
msgstr ""
|
||||
@@ -252,9 +260,9 @@ msgstr ""
|
||||
msgid "IPv6 traffic table \"%h\""
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:349
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:358
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:362
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:420
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:429
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:433
|
||||
msgctxt "vantage-theme"
|
||||
msgid "In use"
|
||||
msgstr ""
|
||||
@@ -268,11 +276,11 @@ msgctxt "vantage-theme"
|
||||
msgid "Input"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:48
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:45
|
||||
msgid "Invalid username and/or password! Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1208
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1290
|
||||
msgid "Jump to a page or action…"
|
||||
msgstr ""
|
||||
|
||||
@@ -281,27 +289,27 @@ msgctxt "vantage-theme"
|
||||
msgid "Leaves unmatched unchanged"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1441
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1535
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Light"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:23
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:60
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:57
|
||||
msgid "Log in"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1187
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:84
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1269
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:87
|
||||
msgid "Log out"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1186
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1443
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1263
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1537
|
||||
msgid "Login background"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:47
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:51
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Main navigation"
|
||||
msgstr ""
|
||||
@@ -311,13 +319,13 @@ msgctxt "vantage-theme"
|
||||
msgid "Masquerade"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:333
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:348
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:404
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:419
|
||||
msgid "Memory"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1713
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1730
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1806
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1823
|
||||
msgctxt "vantage-theme"
|
||||
msgid "More actions"
|
||||
msgstr ""
|
||||
@@ -335,12 +343,17 @@ msgstr ""
|
||||
msgid "Network device table \"%h\""
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1267
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1526
|
||||
msgid "Network path background"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/vantage-theme/nftflow.js:162
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Next rule"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1283
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1348
|
||||
msgid "No matching pages"
|
||||
msgstr ""
|
||||
|
||||
@@ -354,12 +367,17 @@ msgctxt "vantage-theme"
|
||||
msgid "No rules: %s"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1393
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1458
|
||||
msgctxt "vantage-theme"
|
||||
msgid "None"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1111
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1165
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:17
|
||||
msgid "Not found"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1185
|
||||
msgid "Other pages in %s"
|
||||
msgstr ""
|
||||
|
||||
@@ -373,7 +391,7 @@ msgctxt "vantage-theme"
|
||||
msgid "Packet path"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:90
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:93
|
||||
msgid "Page tabs"
|
||||
msgstr ""
|
||||
|
||||
@@ -387,7 +405,7 @@ msgctxt "vantage-theme"
|
||||
msgid "Passes unmatched"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:57
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:54
|
||||
msgid "Password"
|
||||
msgstr ""
|
||||
|
||||
@@ -401,11 +419,6 @@ msgctxt "vantage-theme"
|
||||
msgid "Prerouting"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:985
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Press"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/vantage-theme/nftflow.js:158
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Queue to a program"
|
||||
@@ -421,7 +434,7 @@ msgctxt "vantage-theme"
|
||||
msgid "Reject"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1210
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1292
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Results"
|
||||
msgstr ""
|
||||
@@ -441,13 +454,13 @@ msgctxt "vantage-theme"
|
||||
msgid "Rules table"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1208
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:72
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:74
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1290
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:75
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:77
|
||||
msgid "Search pages"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1187
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1269
|
||||
msgid "Session"
|
||||
msgstr ""
|
||||
|
||||
@@ -458,33 +471,33 @@ msgid_plural "Show %d more rules"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1870
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1963
|
||||
msgid "Show full description"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1859
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1952
|
||||
msgid "Show full help: %s"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:44
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:48
|
||||
msgid "Skip to content"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1393
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1458
|
||||
msgid "Starfield"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:385
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:456
|
||||
msgid "Storage"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:371
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:373
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:442
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:444
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Swap"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:338
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:409
|
||||
msgid "Swap free"
|
||||
msgstr ""
|
||||
|
||||
@@ -493,12 +506,12 @@ msgctxt "vantage-theme"
|
||||
msgid "This device"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:350
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:421
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Total"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:337
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:408
|
||||
msgid "Total Available"
|
||||
msgstr ""
|
||||
|
||||
@@ -512,19 +525,19 @@ msgctxt "vantage-theme"
|
||||
msgid "Unchanged"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1181
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1258
|
||||
msgid "Use dark theme"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1182
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1259
|
||||
msgid "Use light theme"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:337
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:408
|
||||
msgid "Used"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:53
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:50
|
||||
msgid "Username"
|
||||
msgstr ""
|
||||
|
||||
@@ -538,16 +551,16 @@ msgctxt "vantage-theme"
|
||||
msgid "View"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:412
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:484
|
||||
msgid "Wireless"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:354
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:425
|
||||
msgctxt "vantage-theme"
|
||||
msgid "available"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1218
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1300
|
||||
msgid "close"
|
||||
msgstr ""
|
||||
|
||||
@@ -561,17 +574,12 @@ msgctxt "vantage-theme"
|
||||
msgid "drops unmatched %s"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:400
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:403
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:471
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:475
|
||||
msgid "free"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1285
|
||||
msgctxt "vantage-theme"
|
||||
msgid "items"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1216
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1298
|
||||
msgid "navigate"
|
||||
msgstr ""
|
||||
|
||||
@@ -590,29 +598,19 @@ msgctxt "vantage-theme"
|
||||
msgid "on %s"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1217
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1299
|
||||
msgctxt "vantage-theme"
|
||||
msgid "open"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:965
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1039
|
||||
msgid "page"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:965
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1039
|
||||
msgid "pages"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/vantage-theme/nftflow.js:340
|
||||
msgctxt "vantage-theme"
|
||||
msgid "priority %d"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:349
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:359
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:363
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:420
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:430
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:434
|
||||
msgid "reclaimable"
|
||||
msgstr ""
|
||||
|
||||
@@ -621,11 +619,12 @@ msgctxt "vantage-theme"
|
||||
msgid "rules drop some"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:985
|
||||
msgid "to search all pages"
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:471
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:475
|
||||
msgid "total"
|
||||
msgstr ""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:400
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:403
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:471
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:475
|
||||
msgid "used"
|
||||
msgstr ""
|
||||
@@ -21,6 +21,12 @@ msgid "%d more chain at this hook"
|
||||
msgid_plural "%d more chains at this hook"
|
||||
msgstr[0] "此钩子还有 %d 条链"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1350
|
||||
msgctxt "vantage-theme"
|
||||
msgid "%d result"
|
||||
msgid_plural "%d results"
|
||||
msgstr[0] "%d 个结果"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/vantage-theme/nftflow.js:345
|
||||
msgctxt "vantage-theme"
|
||||
msgid "%d rule"
|
||||
@@ -56,7 +62,7 @@ msgctxt "vantage-theme"
|
||||
msgid "Accept"
|
||||
msgstr "接受"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1188
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1270
|
||||
msgid "Actions"
|
||||
msgstr "操作"
|
||||
|
||||
@@ -65,21 +71,22 @@ msgctxt "nft match any traffic"
|
||||
msgid "Any packet"
|
||||
msgstr "任意数据包"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1181
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1182
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1183
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1186
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1439
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:81
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1258
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1259
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1260
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1263
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1267
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1533
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:84
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Appearance"
|
||||
msgstr "外观"
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:43
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:41
|
||||
msgid "Authorization Required"
|
||||
msgstr "需要授权"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1441
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1535
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Auto"
|
||||
msgstr "自动"
|
||||
@@ -94,7 +101,7 @@ msgctxt "vantage-theme"
|
||||
msgid "Back to the calling chain"
|
||||
msgstr "返回调用链"
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:69
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:72
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Breadcrumb"
|
||||
msgstr "面包屑"
|
||||
@@ -112,17 +119,17 @@ msgctxt "vantage-theme"
|
||||
msgid "Bridged between ports"
|
||||
msgstr "端口间桥接"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:338
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:409
|
||||
msgid "Buffered"
|
||||
msgstr "已缓冲"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:349
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:359
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:363
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:420
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:430
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:434
|
||||
msgid "Cache"
|
||||
msgstr "缓存"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:338
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:409
|
||||
msgid "Cached"
|
||||
msgstr "已缓存"
|
||||
|
||||
@@ -141,19 +148,19 @@ msgctxt "vantage-theme"
|
||||
msgid "Chains no rule jumps to directly"
|
||||
msgstr "没有规则直接跳转到的链"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:419
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:491
|
||||
msgid "Channel"
|
||||
msgstr "信道"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:818
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:897
|
||||
msgid "Collapse navigation"
|
||||
msgstr "收起导航"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1440
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1534
|
||||
msgid "Colour theme"
|
||||
msgstr "颜色主题"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1212
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1294
|
||||
msgid "Command palette"
|
||||
msgstr "命令面板"
|
||||
|
||||
@@ -172,7 +179,7 @@ msgctxt "vantage-theme"
|
||||
msgid "Continues in %s, then comes back here"
|
||||
msgstr "转入 %s,随后返回此处"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1441
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1535
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Dark"
|
||||
msgstr "深色"
|
||||
@@ -196,8 +203,8 @@ msgstr "丢弃未匹配流量"
|
||||
msgid "Egress"
|
||||
msgstr "出口"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:818
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:54
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:897
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:57
|
||||
msgid "Expand navigation"
|
||||
msgstr "展开导航"
|
||||
|
||||
@@ -216,7 +223,7 @@ msgstr ""
|
||||
"流量卸载已开启:一条转发连接建立后,它的数据包可以跳过 prerouting、forward "
|
||||
"和 postrouting,因此这些链和它们的计数器只会看到该连接最初的数据包。"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1183
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1260
|
||||
msgid "Follow system theme"
|
||||
msgstr "跟随系统主题"
|
||||
|
||||
@@ -237,17 +244,17 @@ msgstr ""
|
||||
"达 input、forward 或 output 链,这里也没有桥接链会过滤它们。(启用 "
|
||||
"br_netfilter 时内核可以把它们交给 IP 链;规则集不体现这一点。)"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:350
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:364
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:421
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:435
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Free"
|
||||
msgstr "空闲"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1393
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1458
|
||||
msgid "Grid packets"
|
||||
msgstr "网格数据包"
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:48
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:52
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Home"
|
||||
msgstr "首页"
|
||||
@@ -264,9 +271,9 @@ msgstr "IPv4/IPv6 流量表 \"%h\""
|
||||
msgid "IPv6 traffic table \"%h\""
|
||||
msgstr "IPv6 流量表 \"%h\""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:349
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:358
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:362
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:420
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:429
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:433
|
||||
msgctxt "vantage-theme"
|
||||
msgid "In use"
|
||||
msgstr "已用"
|
||||
@@ -280,11 +287,11 @@ msgctxt "vantage-theme"
|
||||
msgid "Input"
|
||||
msgstr "输入"
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:48
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:45
|
||||
msgid "Invalid username and/or password! Please try again."
|
||||
msgstr "用户名或密码错误,请重试。"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1208
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1290
|
||||
msgid "Jump to a page or action…"
|
||||
msgstr "跳转到页面或操作…"
|
||||
|
||||
@@ -293,27 +300,27 @@ msgctxt "vantage-theme"
|
||||
msgid "Leaves unmatched unchanged"
|
||||
msgstr "未匹配流量保持原样"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1441
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1535
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Light"
|
||||
msgstr "浅色"
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:23
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:60
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:57
|
||||
msgid "Log in"
|
||||
msgstr "登录"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1187
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:84
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1269
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:87
|
||||
msgid "Log out"
|
||||
msgstr "退出登录"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1186
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1443
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1263
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1537
|
||||
msgid "Login background"
|
||||
msgstr "登录背景"
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:47
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:51
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Main navigation"
|
||||
msgstr "主导航"
|
||||
@@ -323,13 +330,13 @@ msgctxt "vantage-theme"
|
||||
msgid "Masquerade"
|
||||
msgstr "伪装(NAT)"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:333
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:348
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:404
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:419
|
||||
msgid "Memory"
|
||||
msgstr "内存"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1713
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1730
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1806
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1823
|
||||
msgctxt "vantage-theme"
|
||||
msgid "More actions"
|
||||
msgstr "更多操作"
|
||||
@@ -347,12 +354,17 @@ msgstr "网络"
|
||||
msgid "Network device table \"%h\""
|
||||
msgstr "网络设备表 \"%h\""
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1267
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1526
|
||||
msgid "Network path background"
|
||||
msgstr "网络路径背景"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/vantage-theme/nftflow.js:162
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Next rule"
|
||||
msgstr "下一条规则"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1283
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1348
|
||||
msgid "No matching pages"
|
||||
msgstr "没有匹配的页面"
|
||||
|
||||
@@ -366,12 +378,17 @@ msgctxt "vantage-theme"
|
||||
msgid "No rules: %s"
|
||||
msgstr "无规则:%s"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1393
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1458
|
||||
msgctxt "vantage-theme"
|
||||
msgid "None"
|
||||
msgstr "无"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1111
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1165
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:17
|
||||
msgid "Not found"
|
||||
msgstr "未找到"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1185
|
||||
msgid "Other pages in %s"
|
||||
msgstr "%s 中的其他页面"
|
||||
|
||||
@@ -385,7 +402,7 @@ msgctxt "vantage-theme"
|
||||
msgid "Packet path"
|
||||
msgstr "数据包路径"
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:90
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:93
|
||||
msgid "Page tabs"
|
||||
msgstr "页面标签页"
|
||||
|
||||
@@ -399,7 +416,7 @@ msgctxt "vantage-theme"
|
||||
msgid "Passes unmatched"
|
||||
msgstr "放行未匹配流量"
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:57
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:54
|
||||
msgid "Password"
|
||||
msgstr "密码"
|
||||
|
||||
@@ -413,11 +430,6 @@ msgctxt "vantage-theme"
|
||||
msgid "Prerouting"
|
||||
msgstr "路由前"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:985
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Press"
|
||||
msgstr "按"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/vantage-theme/nftflow.js:158
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Queue to a program"
|
||||
@@ -433,7 +445,7 @@ msgctxt "vantage-theme"
|
||||
msgid "Reject"
|
||||
msgstr "拒绝"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1210
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1292
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Results"
|
||||
msgstr "结果"
|
||||
@@ -453,13 +465,13 @@ msgctxt "vantage-theme"
|
||||
msgid "Rules table"
|
||||
msgstr "规则表"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1208
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:72
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:74
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1290
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:75
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:77
|
||||
msgid "Search pages"
|
||||
msgstr "搜索页面"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1187
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1269
|
||||
msgid "Session"
|
||||
msgstr "会话"
|
||||
|
||||
@@ -469,33 +481,33 @@ msgid "Show %d more rule"
|
||||
msgid_plural "Show %d more rules"
|
||||
msgstr[0] "再显示 %d 条规则"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1870
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1963
|
||||
msgid "Show full description"
|
||||
msgstr "显示完整描述"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1859
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1952
|
||||
msgid "Show full help: %s"
|
||||
msgstr "显示完整帮助:%s"
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:44
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/header.ut:48
|
||||
msgid "Skip to content"
|
||||
msgstr "跳至正文"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1393
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1458
|
||||
msgid "Starfield"
|
||||
msgstr "星空"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:385
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:456
|
||||
msgid "Storage"
|
||||
msgstr "存储"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:371
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:373
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:442
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:444
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Swap"
|
||||
msgstr "交换空间"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:338
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:409
|
||||
msgid "Swap free"
|
||||
msgstr "空闲交换空间"
|
||||
|
||||
@@ -504,12 +516,12 @@ msgctxt "vantage-theme"
|
||||
msgid "This device"
|
||||
msgstr "本设备"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:350
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:421
|
||||
msgctxt "vantage-theme"
|
||||
msgid "Total"
|
||||
msgstr "总计"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:337
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:408
|
||||
msgid "Total Available"
|
||||
msgstr "总可用"
|
||||
|
||||
@@ -523,19 +535,19 @@ msgctxt "vantage-theme"
|
||||
msgid "Unchanged"
|
||||
msgstr "不变"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1181
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1258
|
||||
msgid "Use dark theme"
|
||||
msgstr "使用深色主题"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1182
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1259
|
||||
msgid "Use light theme"
|
||||
msgstr "使用浅色主题"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:337
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:408
|
||||
msgid "Used"
|
||||
msgstr "已用"
|
||||
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:53
|
||||
#: luci-theme-vantage/ucode/template/themes/vantage/sysauth.ut:50
|
||||
msgid "Username"
|
||||
msgstr "用户名"
|
||||
|
||||
@@ -549,16 +561,16 @@ msgctxt "vantage-theme"
|
||||
msgid "View"
|
||||
msgstr "视图"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:412
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:484
|
||||
msgid "Wireless"
|
||||
msgstr "无线"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:354
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:425
|
||||
msgctxt "vantage-theme"
|
||||
msgid "available"
|
||||
msgstr "可用"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1218
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1300
|
||||
msgid "close"
|
||||
msgstr "关闭"
|
||||
|
||||
@@ -572,17 +584,12 @@ msgctxt "vantage-theme"
|
||||
msgid "drops unmatched %s"
|
||||
msgstr "丢弃未匹配的 %s"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:400
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:403
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:471
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:475
|
||||
msgid "free"
|
||||
msgstr "空闲"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1285
|
||||
msgctxt "vantage-theme"
|
||||
msgid "items"
|
||||
msgstr "条"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1216
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1298
|
||||
msgid "navigate"
|
||||
msgstr "移动"
|
||||
|
||||
@@ -601,29 +608,19 @@ msgctxt "vantage-theme"
|
||||
msgid "on %s"
|
||||
msgstr "接口 %s"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1217
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1299
|
||||
msgctxt "vantage-theme"
|
||||
msgid "open"
|
||||
msgstr "打开"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:965
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1039
|
||||
msgid "page"
|
||||
msgstr "页"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:965
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:1039
|
||||
msgid "pages"
|
||||
msgstr "页"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/vantage-theme/nftflow.js:340
|
||||
msgctxt "vantage-theme"
|
||||
msgid "priority %d"
|
||||
msgstr "优先级 %d"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:349
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:359
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:363
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:420
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:430
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:434
|
||||
msgid "reclaimable"
|
||||
msgstr "可回收"
|
||||
|
||||
@@ -632,15 +629,33 @@ msgctxt "vantage-theme"
|
||||
msgid "rules drop some"
|
||||
msgstr "部分规则会丢弃"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:985
|
||||
msgid "to search all pages"
|
||||
msgstr "搜索所有页面"
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:471
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:475
|
||||
msgid "total"
|
||||
msgstr "总计"
|
||||
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:400
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:403
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:471
|
||||
#: luci-theme-vantage/htdocs/luci-static/resources/menu-vantage.js:475
|
||||
msgid "used"
|
||||
msgstr "已用"
|
||||
|
||||
#~ msgctxt "vantage-theme"
|
||||
#~ msgid "Press"
|
||||
#~ msgstr "按"
|
||||
|
||||
#~ msgctxt "vantage-theme"
|
||||
#~ msgid "items"
|
||||
#~ msgstr "条"
|
||||
|
||||
#~ msgid "page"
|
||||
#~ msgstr "页"
|
||||
|
||||
#~ msgid "pages"
|
||||
#~ msgstr "页"
|
||||
|
||||
#~ msgid "to search all pages"
|
||||
#~ msgstr "搜索所有页面"
|
||||
|
||||
#~ msgid "Show full help"
|
||||
#~ msgstr "显示完整帮助"
|
||||
|
||||
|
||||
@@ -10,7 +10,11 @@
|
||||
-#}
|
||||
{%
|
||||
const authed = !!ctx.authsession;
|
||||
const page_title = (authed && dispatched?.title) ? striptags(_(dispatched.title)) : 'LuCI';
|
||||
/* LuCI renders its 404 with the deepest node it resolved: a category
|
||||
(firstchild) or a node without an action, whose title is not the
|
||||
page asked for. Visitors who are not logged in get no title at all. */
|
||||
const found = !!dispatched?.action?.type && dispatched.action.type != 'firstchild';
|
||||
const page_title = !authed ? null : !found ? _('Not found') : dispatched?.title ? striptags(_(dispatched.title)) : null;
|
||||
const lang = entityencode(dispatcher.lang ?? 'en', true);
|
||||
const boardinfo = ubus.call("system", "board");
|
||||
const hostname = striptags(boardinfo?.hostname ?? '?');
|
||||
@@ -21,7 +25,7 @@
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||
<meta name="color-scheme" content="dark light">
|
||||
<title>{{ entityencode(page_title, true) }} · LuCI</title>
|
||||
<title>{{ page_title ? entityencode(page_title, true) + ' · ' : '' }}LuCI</title>
|
||||
<script>
|
||||
(function (r) {
|
||||
var p = 'auto', rail = 'pinned';
|
||||
@@ -75,7 +79,7 @@
|
||||
<svg viewBox="0 0 32 32" width="28" height="28"><rect x="1" y="1" width="30" height="30" rx="7" class="vt-brand-tile"/><path d="M9 10.5 16 22" class="vt-brand-l"/><path d="M16 22 23 10.5" class="vt-brand-r"/><circle cx="23" cy="10.5" r="1.9" class="vt-brand-dot"/></svg>
|
||||
</span>
|
||||
{% endif %}
|
||||
<nav class="vt-crumbs" id="vt-crumbs" aria-label="{{ entityencode(_('Breadcrumb', 'vantage-theme'), true) }}"><span class="vt-crumb vt-crumb-current">{{ entityencode(page_title, true) }}</span></nav>
|
||||
<nav class="vt-crumbs" id="vt-crumbs" aria-label="{{ entityencode(_('Breadcrumb', 'vantage-theme'), true) }}"><span class="vt-crumb vt-crumb-current">{{ entityencode(page_title ?? 'LuCI', true) }}</span></nav>
|
||||
<div class="vt-top-actions">
|
||||
{% if (authed): %}
|
||||
<button type="button" class="vt-search" id="vt-search-btn" aria-haspopup="dialog" aria-keyshortcuts="Control+K /" aria-label="{{ entityencode(_('Search pages'), true) }}">
|
||||
|
||||
@@ -12,8 +12,6 @@
|
||||
if (type(tls) == 'string')
|
||||
tls = split(tls, /\s+/);
|
||||
const tls_ports = uniq(filter(map(tls, e => +(match(e, /\d+$/)?.[0] ?? 0)), p => (p > 0 && p <= 65535)));
|
||||
const boardinfo = ubus.call("system", "board");
|
||||
const hostname = striptags(boardinfo?.hostname ?? '?');
|
||||
-%}
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ entityencode(dispatcher.lang ?? 'en', true) }}" data-darkmode="true">
|
||||
@@ -47,10 +45,7 @@
|
||||
<circle cx="21.5" cy="10.5" r="1.9" class="vt-brand-dot"></circle>
|
||||
<circle cx="21.5" cy="21.5" r="1.9" class="vt-brand-dot"></circle>
|
||||
</svg>
|
||||
<div>
|
||||
<h1 class="vt-login-title">{{ hostname }}</h1>
|
||||
<p class="vt-login-sub"><span class="vt-login-dot" aria-hidden="true"></span>{{ entityencode(_('Authorization Required'), true) }}</p>
|
||||
</div>
|
||||
<h1 class="vt-login-title">{{ entityencode(_('Authorization Required'), true) }}</h1>
|
||||
</div>
|
||||
|
||||
{% if (fuser): %}
|
||||
|
||||
+2
-2
@@ -5,8 +5,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=meow
|
||||
PKG_VERSION:=0.28.0
|
||||
PKG_RELEASE:=18
|
||||
PKG_VERSION:=0.29.0
|
||||
PKG_RELEASE:=19
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/meow-rs/meow-rs/tar.gz/v$(PKG_VERSION)?
|
||||
|
||||
+2
-2
@@ -6,8 +6,8 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NPM_NAME:=pnpm
|
||||
PKG_NAME:=node-$(PKG_NPM_NAME)
|
||||
PKG_VERSION:=11.27.1
|
||||
PKG_RELEASE:=3
|
||||
PKG_VERSION:=11.28.10
|
||||
PKG_RELEASE:=4
|
||||
|
||||
PKG_SOURCE:=$(PKG_NPM_NAME)-$(PKG_VERSION).tgz
|
||||
PKG_SOURCE_URL:=https://mirrors.tencent.com/npm/$(PKG_NPM_NAME)/-/ \
|
||||
|
||||
@@ -9,7 +9,7 @@ PKG_NAME:=natmapt
|
||||
PKG_UPSTREAM_VERSION:=20260214
|
||||
PKG_UPSTREAM_GITHASH:=
|
||||
PKG_VERSION:=$(PKG_UPSTREAM_VERSION)$(if $(PKG_UPSTREAM_GITHASH),~$(call version_abbrev,$(PKG_UPSTREAM_GITHASH)))
|
||||
PKG_RELEASE:=16
|
||||
PKG_RELEASE:=17
|
||||
SCRIPTS_VERSION:=0.2026.01.24
|
||||
|
||||
PKG_SOURCE_SUBDIR:=$(PKG_UPSTREAM_NAME)-$(PKG_UPSTREAM_VERSION)
|
||||
|
||||
@@ -51,6 +51,17 @@ start() {
|
||||
http_request "$(json_dump)" "$(jsonfilter -s "$the_record" -qe '@.id')"
|
||||
fi
|
||||
|
||||
if [ -n "${txt}" ]; then
|
||||
the_record="$(jsonfilter -s "$records" -qe '@.result[*]'|grep "\"type\": \"TXT\""|grep "\"name\": \"${txt}\""|grep '"content": "\\"natmaptmgmt=.*\\""')"
|
||||
json_init
|
||||
json_add_string type "TXT"
|
||||
json_add_string name "${txt}"
|
||||
json_add_string content "$(echo "${txt_content}"|sed -E 's|^"?(natmaptmgmt=\S*\s*)?|"natmaptmgmt=; |; s|"?$|"|')"
|
||||
json_add_int ttl 1
|
||||
json_add_boolean proxied 0
|
||||
http_request "$(json_dump)" "$(jsonfilter -s "$the_record" -qe '@.id')"
|
||||
fi
|
||||
|
||||
if [ -n "${srv}" ]; then
|
||||
the_record="$(jsonfilter -s "$records" -qe '@.result[*]'|grep "\"type\": \"SRV\""|grep "\"name\": \"_${srv_serv}._${srv_proto}.${srv}\""|grep "\"priority\": ${srv_priority}"|grep "\"weight\": ${srv_weight}")"
|
||||
json_init
|
||||
@@ -85,7 +96,7 @@ start() {
|
||||
|
||||
|
||||
# All external parameters required
|
||||
ALL_PARAMS="hostype host srv srv_serv srv_proto srv_target srv_priority srv_weight ip port https https_target https_svcparams https_priority tokens"
|
||||
ALL_PARAMS="hostype host txt txt_content srv srv_serv srv_proto srv_target srv_priority srv_weight ip port https https_target https_svcparams https_priority tokens"
|
||||
eval "$(JSON_EXPORT "$1")"; shift
|
||||
# All external tokens required
|
||||
INIT_GLOBAL_VAR TOKEN ZONE_ID
|
||||
|
||||
@@ -65,12 +65,16 @@ if [ -n "$NOTIFY" ]; then
|
||||
fi
|
||||
if [ -n "$DDNS" ]; then
|
||||
_hostype="$(jsonfilter -qs "$DDNS_PARAM" -e '@["hostype"]')"
|
||||
_content="$(jsonfilter -qs "$DDNS_PARAM" -e '@["txt_content"]')"
|
||||
_svcparams="$(jsonfilter -qs "$DDNS_PARAM" -e '@["https_svcparams"]')"
|
||||
_svcparams="$(echo "$_svcparams" | sed -E "s,\s*(port=\d*|$), port=${port},")" # port
|
||||
_content="$(echo "$_content" | sed "s,{{port}},${port},")" # port
|
||||
_svcparams="$(echo "$_svcparams" | sed -E "s,\s*(port=\d*|$), port=${port},")" # port
|
||||
_content="$(echo "$_content" | sed "s,{{ip}},${ip},")" # ip
|
||||
[ "$_hostype" = A ] && _svcparams="$(echo "$_svcparams" | sed -E "s|\b(ipv4hint=)\S*|\1${ip}|")" # ipv4hint
|
||||
[ "$_hostype" = AAAA ] && _svcparams="$(echo "$_svcparams" | sed -E "s|\b(ipv6hint=)\S*|\1${ip}|")" # ipv6hint
|
||||
json_init
|
||||
json_load "$DDNS_PARAM"
|
||||
json_add_string txt_content "$_content"
|
||||
json_add_string https_svcparams "$_svcparams"
|
||||
json_add_string ip "$ip"
|
||||
json_add_int port "$port"
|
||||
|
||||
@@ -134,6 +134,8 @@ validate_section_natmap() {
|
||||
'ddns_tokens:list(string)' \
|
||||
'ddns_a:hostname' \
|
||||
'ddns_aaaa:hostname' \
|
||||
'ddns_txt:hostname' \
|
||||
'ddns_txt_content:string' \
|
||||
'ddns_srv:hostname' \
|
||||
'ddns_srv_serv:string' \
|
||||
'ddns_srv_proto:string:tcp' \
|
||||
@@ -241,6 +243,10 @@ natmap_instance() {
|
||||
json_add_string tokens "$ddns_tokens"
|
||||
[ "$family" = ipv4 ] && json_add_string hostype "A" && json_add_string host "$ddns_a"
|
||||
[ "$family" = ipv6 ] && json_add_string hostype "AAAA" && json_add_string host "$ddns_aaaa"
|
||||
[ -n "$ddns_txt" ] && {
|
||||
json_add_string txt "$ddns_txt"
|
||||
json_add_string txt_content "$ddns_txt_content"
|
||||
}
|
||||
[ -n "$ddns_srv" ] && {
|
||||
json_add_string srv "$ddns_srv"
|
||||
json_add_string srv_serv "$ddns_srv_serv"
|
||||
@@ -416,7 +422,7 @@ launcher() {
|
||||
|
||||
# review
|
||||
[ -n "$NATMAP_DEBUG" ] && {
|
||||
local v ucivv="enable interval stun_cycle stun_server http_server fwmark_value comment udp_mode proto family bind_ifname ifname bind_ip lan_addr port port_pointer forward forward_mode natloopback forward_congestion forward_timeout forward_target forward_port refresh clt_script clt_scheme clt_web_port clt_username clt_password notify_enable notify_script notify_tokens notify_custom_domain notify_text ddns_enable ddns_script ddns_tokens ddns_a ddns_aaaa ddns_srv ddns_srv_serv ddns_srv_proto ddns_srv_target ddns_srv_priority ddns_srv_weight ddns_https ddns_https_target ddns_https_svcparams ddns_https_priority custom_script"
|
||||
local v ucivv="enable interval stun_cycle stun_server http_server fwmark_value comment udp_mode proto family bind_ifname ifname bind_ip lan_addr port port_pointer forward forward_mode natloopback forward_congestion forward_timeout forward_target forward_port refresh clt_script clt_scheme clt_web_port clt_username clt_password notify_enable notify_script notify_tokens notify_custom_domain notify_text ddns_enable ddns_script ddns_tokens ddns_a ddns_aaaa ddns_txt ddns_txt_content ddns_srv ddns_srv_serv ddns_srv_proto ddns_srv_target ddns_srv_priority ddns_srv_weight ddns_https ddns_https_target ddns_https_svcparams ddns_https_priority custom_script"
|
||||
for v in $ucivv; do eval "echo $1 $v=\'\$$v\'"; done # ash not support ${!v}
|
||||
}
|
||||
[ "$error" -gt 0 ] && return 1
|
||||
|
||||
+2
-1
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=vsftpd
|
||||
PKG_VERSION:=3.0.5
|
||||
PKG_RELEASE:=3
|
||||
PKG_RELEASE:=4
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://security.appspot.com/downloads/
|
||||
@@ -43,6 +43,7 @@ endef
|
||||
define Package/vsftpd-tls
|
||||
$(call Package/vsftpd/Default)
|
||||
VARIANT:=tls
|
||||
CONFLICTS:=vsftpd
|
||||
TITLE+= (TLS)
|
||||
DEPENDS+=+libopenssl
|
||||
endef
|
||||
|
||||
+3
-3
@@ -50,12 +50,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=wwand
|
||||
PKG_VERSION:=1.8.0_pre48
|
||||
PKG_RELEASE:=87
|
||||
PKG_VERSION:=1.9.0_pre3
|
||||
PKG_RELEASE:=88
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/ddimension/wwand.git
|
||||
PKG_SOURCE_VERSION:=f2c804f06ff028088ad262bf86683b2519b1b127
|
||||
PKG_SOURCE_VERSION:=0a1f02375df53f21a105b375b9af051c36464530
|
||||
PKG_MIRROR_HASH:=skip
|
||||
|
||||
PKG_LICENSE:=GPL-2.0-only
|
||||
|
||||
Reference in new issue
Block a user